Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2023-08-14 07:19:18 -04:00
301 changed files with 20348 additions and 13677 deletions

View File

@@ -540,12 +540,25 @@ then
# Attempt to install dependencies.
sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log
# Stop if no port version activation errors were found.
# Check for port activation errors.
stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10)
[ -z $stuck_dep ] && break
if [ -n "$stuck_dep" ]
then
# Deactivate the stuck dependency and try again.
sudo "$macports/bin/port" -f deactivate "$stuck_dep"
continue
fi
# Deactivate the stuck dependency and try again.
sudo "$macports/bin/port" -f deactivate $stuck_dep
stuck_dep=$(grep " Please deactivate this port first, or " macports.log | cut -d" " -f5 | tr -d :)
if [ -n "$stuck_dep" ]
then
# Activate the stuck dependency and try again.
sudo "$macports/bin/port" -f activate "$stuck_dep"
continue
fi
# Stop if no errors were found.
break
done
# Remove MacPorts error detection log.

View File

@@ -9,5 +9,6 @@ zlib
libpng
rtmidi
libslirp
fluidsynth
qt5-static
qt5-translations

21
.gitattributes vendored Normal file
View File

@@ -0,0 +1,21 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.cc text
*.cpp text
*.h text
*.hpp text
*.rc text
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.ico binary
*.png binary
*.jpg binary
*.dat

View File

@@ -115,7 +115,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-
@@ -234,7 +234,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >
@@ -341,7 +341,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-
@@ -427,7 +427,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-

View File

@@ -14,8 +14,8 @@
#
# Define our flags
string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition")
string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing")
string(APPEND CMAKE_C_FLAGS_INIT " -std=c99 -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition")
string(APPEND CMAKE_CXX_FLAGS_INIT " -std=c++11 -fomit-frame-pointer -Wall -fno-strict-aliasing")
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3")
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3")
string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og")

View File

@@ -918,11 +918,15 @@ pc_init_modules(void)
#ifdef USE_DYNAREC
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(0);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(0);
}
# endif
codegen_init();
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(1);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(1);
}
# endif
#endif
@@ -1048,19 +1052,9 @@ pc_reset_hard_init(void)
/* Initialize the actual machine and its basic modules. */
machine_init();
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
fdc_card_init();
fdd_reset();
/* Reset some basic devices. */
speaker_init();
shadowbios = 0;
/*
* Once the machine has been initialized, all that remains
@@ -1071,10 +1065,20 @@ pc_reset_hard_init(void)
* that will be a call to device_reset_all() later !
*/
/* Reset some basic devices. */
speaker_init();
if (joystick_type)
gameport_update_joystick_type();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Reset and reconfigure the Network Card layer. */
network_reset();
lpt_devices_init();
shadowbios = 0;
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/*
* Reset the mouse, this will attach it to any port needed.
@@ -1084,25 +1088,30 @@ pc_reset_hard_init(void)
/* Reset the Hard Disk Controller module. */
hdc_reset();
fdc_card_init();
fdd_reset();
/* Reset the CD-ROM Controller module. */
cdrom_interface_reset();
/* Reset and reconfigure the SCSI layer. */
scsi_card_init();
cdrom_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
cdrom_hard_reset();
mo_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
/* Reset and reconfigure the Network Card layer. */
network_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
if (joystick_type)
gameport_update_joystick_type();
/* Initialize the Voodoo cards here inorder to minmize
the chances of the SCSI controller ending up on the bridge. */
video_voodoo_init();
ui_sb_update_panes();
@@ -1119,6 +1128,11 @@ pc_reset_hard_init(void)
if (postcard_enabled)
device_add(&postcard_device);
if (IS_ARCH(machine, MACHINE_BUS_PCI)) {
pci_register_cards();
device_reset_all(DEVICE_PCI);
}
/* Reset the CPU module. */
resetx86();
dma_reset();
@@ -1273,10 +1287,12 @@ pc_run(void)
startblit();
cpu_exec(cpu_s->rspeed / 100);
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
// if (gdbstub_step == GDBSTUB_EXEC)
if (gdbstub_step == GDBSTUB_EXEC) {
#endif
#if 0
mouse_process();
if (!mouse_timed)
mouse_process();
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
}
#endif
joystick_process();
endblit();

View File

@@ -124,18 +124,18 @@ acpi_update_irq(acpi_t *dev)
if (sci_level) {
if (dev->irq_mode == 1)
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_set_mirq(5, dev->mirq_is_level);
pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_set_mirq(0xf0 | dev->irq_line, 1);
pci_set_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
} else {
if (dev->irq_mode == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_clear_mirq(5, dev->mirq_is_level);
pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_clear_mirq(0xf0 | dev->irq_line, 1);
pci_clear_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
}
acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS));
@@ -1657,6 +1657,9 @@ acpi_reset(void *priv)
dev->regs.pmsts |= 0x8000;
acpi_rtc_status = 0;
acpi_update_irq(dev);
dev->irq_state = 0;
}
static void

View File

@@ -652,9 +652,7 @@ cdi_cue_get_buffer(char *str, char **line, int up)
done = 1;
break;
}
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
default:
if (up && islower((int) *s))

View File

@@ -331,7 +331,7 @@ viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries
}
/* Check if this filename is unique, and add a tail if required, while also adding the extension. */
char tail[8];
char tail[16];
for (int i = force_tail; i <= 999999; i++) {
/* Add tail to the filename if this is not the first run. */
int tail_len = -1;
@@ -429,7 +429,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
or way too far into 64-bit space (Linux). Fall back to epoch. */
time_t epoch = 0;
time_s = localtime(&epoch);
if (!time_s)
if (UNLIKELY(!time_s))
fatal("VISO: localtime(0) = NULL\n");
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
@@ -636,12 +636,8 @@ pad_susp:
break;
}
if ((p - data) > 255)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry);
#else
fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry);
#endif
if (UNLIKELY((p - data) > 255))
fatal("VISO: Directory record overflow (%" PRIuPTR ") on entry %08" PRIXPTR "\n", (uintptr_t) (p - data), (uintptr_t) entry);
data[0] = p - data; /* length */
return data[0];

View File

@@ -324,9 +324,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
break;
case 5:
dev->readmsf = 0;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 4:
case 3:
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);

View File

@@ -13,13 +13,14 @@
# Copyright 2020-2021 David Hrdlička.
#
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c
ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c
intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c
opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c
via_pipc.c vl82c480.c wd76c10.c)
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c
sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c
via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
if(OLIVETTI)
target_sources(chipset PRIVATE olivetti_eva.c)

View File

@@ -46,11 +46,12 @@
typedef struct ali_1435_t {
uint8_t index;
uint8_t cfg_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[16];
uint8_t pci_regs[256];
} ali1435_t;
#define ENABLE_ALI1435_LOG 1
#ifdef ENABLE_ALI1435_LOG
int ali1435_do_log = ENABLE_ALI1435_LOG;
@@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x23:
#if 0
#ifdef ENABLE_ALI1435_LOG
if (dev->index != 0x03)
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
#endif
if (dev->index == 0x03)
dev->cfg_locked = (val != 0x69);
#ifdef ENABLE_ALI1435_LOG
else
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
if (!dev->cfg_locked) {
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
/* PCI Mechanism select? */
case 0x00:
dev->regs[dev->index] = val;
pclog("PMC = %i\n", val != 0xc8);
pci_set_pmc(val != 0xc8);
ali1435_log("PMC = %i\n", val != 0xc8);
pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00);
break;
/* ???? */
@@ -253,8 +250,6 @@ ali1435_reset(void *priv)
dev->regs[0x00] = 0xff;
pci_set_pmc(0);
dev->cfg_locked = 1;
memset(dev->pci_regs, 0, 256);
@@ -298,17 +293,10 @@ ali1435_init(UNUSED(const device_t *info))
*/
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot);
ali1435_reset(dev);
#if 0
pci_set_irq_level(PCI_INTA, 0);
pci_set_irq_level(PCI_INTB, 0);
pci_set_irq_level(PCI_INTC, 0);
pci_set_irq_level(PCI_INTD, 0);
#endif
return dev;
}

View File

@@ -622,7 +622,7 @@ ali1489_init(UNUSED(const device_t *info))
io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
/* Dummy M1489 PCI device */
dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot);
device_add(&ide_pci_2ch_device);

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1531_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -374,7 +379,7 @@ ali1531_init(UNUSED(const device_t *info))
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
memset(dev, 0, sizeof(ali1531_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1541_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -641,7 +646,7 @@ ali1541_init(UNUSED(const device_t *info))
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
memset(dev, 0, sizeof(ali1541_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -47,6 +47,7 @@
#include <86box/chipset.h>
typedef struct ali1543_t {
uint8_t mirq_states[8];
uint8_t pci_conf[256];
uint8_t pmu_conf[256];
uint8_t usb_conf[256];
@@ -1474,12 +1475,12 @@ ali7101_read(int func, int addr, void *priv)
static void
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
{
const ali1543_t *dev = (ali1543_t *) priv;
ali1543_t *dev = (ali1543_t *) priv;
if (usb->irq_level)
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
else
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
}
static void
@@ -1595,16 +1596,16 @@ ali1543_init(const device_t *info)
memset(dev, 0, sizeof(ali1543_t));
/* Device 02: M1533 Southbridge */
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot);
/* Device 0B: M5229 IDE Controller*/
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev, &dev->ide_slot);
/* Device 0C: M7101 Power Managment Controller */
dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev, &dev->pmu_slot);
/* Device 0F: M5237 USB */
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev, &dev->usb_slot);
/* ACPI */
dev->acpi = device_add(&acpi_ali_device);

View File

@@ -36,6 +36,11 @@
#include <86box/chipset.h>
typedef struct ali1621_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram[2];
@@ -109,9 +114,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
switch (val & 0x30) {
case 0x10: /* Open. */
access_normal = ACCESS_SMRAM_RX;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_R;
break;
@@ -124,9 +127,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
switch (val & 0x30) {
case 0x10: /* Open. */
access_normal |= ACCESS_SMRAM_W;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_W;
break;
@@ -671,7 +672,7 @@ ali1621_init(UNUSED(const device_t *info))
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
memset(dev, 0, sizeof(ali1621_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot);
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -234,9 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
case 0x12:
val &= 0xf7;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x14:
case 0x15:

767
src/chipset/compaq_386.c Normal file
View File

@@ -0,0 +1,767 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Compaq 386 memory controller.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/machine.h>
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
#define RAM_DIAG_L_BASE_MEM_INV 0x10
#define RAM_DIAG_L_BASE_MEM_512KB 0x20
#define RAM_DIAG_L_BASE_MEM_256KB 0x30
#define RAM_DIAG_L_BASE_MEM_MASK 0x30
#define RAM_DIAG_L_PERMA_BITS 0x80
#define RAM_DIAG_H_SYS_RAM_4MB 0x01
#define RAM_DIAG_H_SYS_RAM_1MB 0x02
#define RAM_DIAG_H_SYS_RAM_NONE 0x03
#define RAM_DIAG_H_SYS_RAM_MASK 0x03
#define RAM_DIAG_H_MOD_A_RAM_4MB 0x04
#define RAM_DIAG_H_MOD_A_RAM_1MB 0x08
#define RAM_DIAG_H_MOD_A_RAM_NONE 0x0c
#define RAM_DIAG_H_MOD_A_RAM_MASK 0x0c
#define RAM_DIAG_H_MOD_B_RAM_4MB 0x10
#define RAM_DIAG_H_MOD_B_RAM_1MB 0x20
#define RAM_DIAG_H_MOD_B_RAM_NONE 0x30
#define RAM_DIAG_H_MOD_B_RAM_MASK 0x30
#define RAM_DIAG_H_MOD_C_RAM_4MB 0x40
#define RAM_DIAG_H_MOD_C_RAM_1MB 0x80
#define RAM_DIAG_H_MOD_C_RAM_NONE 0xc0
#define RAM_DIAG_H_MOD_C_RAM_MASK 0xc0
#define MEM_STATE_BUS 0x00
#define MEM_STATE_SYS 0x01
#define MEM_STATE_SYS_RELOC 0x02
#define MEM_STATE_MOD_A 0x04
#define MEM_STATE_MOD_B 0x08
#define MEM_STATE_MOD_C 0x10
#define MEM_STATE_MASK (MEM_STATE_SYS | MEM_STATE_MOD_A | MEM_STATE_MOD_B | MEM_STATE_MOD_C)
#define MEM_STATE_WP 0x20
typedef struct cpq_ram_t {
uint8_t wp;
uint32_t phys_base;
uint32_t virt_base;
mem_mapping_t mapping;
} cpq_ram_t;
typedef struct cpq_386_t {
uint8_t regs[8];
uint8_t old_state[256];
uint8_t mem_state[256];
uint32_t ram_bases[4];
uint32_t ram_sizes[4];
uint32_t ram_map_sizes[4];
cpq_ram_t ram[4][64];
cpq_ram_t high_ram[16];
mem_mapping_t regs_mapping;
} cpq_386_t;
static uint8_t
cpq_read_ram(uint32_t addr, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint8_t ret = 0xff;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_ram(addr, priv);
return ret;
}
static uint16_t
cpq_read_ramw(uint32_t addr, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint16_t ret = 0xffff;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_ramw(addr, priv);
return ret;
}
static uint32_t
cpq_read_raml(uint32_t addr, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint32_t ret = 0xffffffff;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_raml(addr, priv);
return ret;
}
static void
cpq_write_ram(uint32_t addr, uint8_t val, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_ram(addr, val, priv);
}
static void
cpq_write_ramw(uint32_t addr, uint16_t val, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_ramw(addr, val, priv);
}
static void
cpq_write_raml(uint32_t addr, uint32_t val, void *priv)
{
cpq_ram_t *dev = (cpq_ram_t *) priv;
uint32_t old = addr;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_raml(addr, val, priv);
}
static uint8_t
cpq_read_regs(uint32_t addr, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
uint8_t ret = 0xff;
addr &= 0x00000fff;
switch (addr) {
case 0x00000000:
case 0x00000001:
/* RAM Diagnostics (Read Only) */
case 0x00000002:
case 0x00000003:
/* RAM Setup Port (Read/Write) */
ret = dev->regs[addr];
break;
}
return ret;
}
static uint16_t
cpq_read_regsw(uint32_t addr, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
uint16_t ret = 0xffff;
ret = cpq_read_regs(addr, priv);
ret |= (((uint16_t) cpq_read_regs(addr + 1, priv)) << 8);
return ret;
}
static uint32_t
cpq_read_regsl(uint32_t addr, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
uint32_t ret = 0xffffffff;
ret = cpq_read_regsw(addr, priv);
ret |= (((uint32_t) cpq_read_regsw(addr + 2, priv)) << 16);
return ret;
}
static void
cpq_recalc_state(cpq_386_t *dev, uint8_t i)
{
uint32_t addr;
addr = ((uint32_t) i) << 16;
if (dev->mem_state[i] == 0x00)
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
else if (dev->mem_state[i] == MEM_STATE_WP)
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
else if (dev->mem_state[i] & MEM_STATE_WP)
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
dev->old_state[i] = dev->mem_state[i];
}
static void
cpq_recalc_states(cpq_386_t *dev)
{
/* Recalculate the entire 16 MB space. */
for (uint16_t i = 0; i < 256; i++) {
if (dev->mem_state[i] != dev->old_state[i])
cpq_recalc_state(dev, i);
}
flushmmucache_nopc();
}
static void
cpq_recalc_cache(cpq_386_t *dev)
{
cpu_cache_ext_enabled = (dev->regs[0x00000002] & 0x40);
cpu_update_waitstates();
}
static void
cpq_recalc_ram(cpq_386_t *dev)
{
uint8_t sys_ram = (dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK) & 0x01;
uint8_t setup_port = dev->regs[0x00000002] & 0x0f;
uint8_t sys_min_high = sys_ram ? 0xfa : 0xf4;
uint8_t ram_states[4] = { MEM_STATE_SYS, MEM_STATE_MOD_A,
MEM_STATE_MOD_B, MEM_STATE_MOD_C };
uint8_t ram_bases[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } },
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20,
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } },
{ { 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60,
0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00 },
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x90, 0x00, 0x00, 0xc0, 0xc0, 0xc0 } } };
uint8_t ram_sizes[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x30, 0x00, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 } },
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x10, 0x10,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40,
0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
0x00, 0x10, 0x10, 0x30, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x00, 0x00 },
{ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x20, 0x30 } } };
uint8_t size;
uint8_t start;
uint8_t end;
uint8_t k;
uint32_t virt_base;
uint32_t virt_addr;
uint32_t phys_addr;
cpq_ram_t *cram;
for (uint16_t i = 0x10; i < sys_min_high; i++)
dev->mem_state[i] &= ~MEM_STATE_MASK;
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 0; j <= 64; j++) {
if ((i >= 1) || (j >= 0x10))
mem_mapping_disable(&dev->ram[i][j].mapping);
}
}
for (uint8_t i = 0; i < 4; i++) {
size = ram_sizes[i][sys_ram][setup_port];
if (size > 0x00) {
start = ram_bases[i][sys_ram][setup_port];
end = start + (size - 1);
virt_base = ((uint32_t) start) << 16;
for (uint16_t j = start; j <= end; j++) {
k = j - start;
if (i == 0)
k += 0x10;
cram = &(dev->ram[i][k]);
dev->mem_state[j] |= ram_states[i];
cram->virt_base = ((uint32_t) j) << 16;
cram->phys_base = cram->virt_base - virt_base + dev->ram_bases[i];
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
}
}
}
/* Recalculate the entire 16 MB space. */
cpq_recalc_states(dev);
}
static void
cpq_write_regs(uint32_t addr, uint8_t val, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
addr &= 0x00000fff;
switch (addr) {
case 0x00000000:
case 0x00000001:
/* RAM Relocation (Write Only) */
dev->regs[addr + 4] = val;
if (addr == 0x00000000) {
dev->mem_state[0x0e] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
dev->mem_state[0x0f] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
dev->mem_state[0xfe] &= ~MEM_STATE_WP;
dev->mem_state[0xff] &= ~MEM_STATE_WP;
if (!(val & 0x01)) {
dev->mem_state[0x0e] |= MEM_STATE_SYS;
dev->mem_state[0x0f] |= MEM_STATE_SYS;
}
if (!(val & 0x02)) {
dev->mem_state[0x0e] |= MEM_STATE_WP;
dev->mem_state[0x0f] |= MEM_STATE_WP;
dev->mem_state[0xfe] |= MEM_STATE_WP;
dev->mem_state[0xff] |= MEM_STATE_WP;
}
cpq_recalc_state(dev, 0x0e);
cpq_recalc_state(dev, 0x0f);
cpq_recalc_state(dev, 0xfe);
cpq_recalc_state(dev, 0xff);
flushmmucache_nopc();
}
break;
case 0x00000002:
case 0x00000003:
/* RAM Setup Port (Read/Write) */
dev->regs[addr] = val;
if (addr == 0x00000002) {
cpq_recalc_ram(dev);
cpq_recalc_cache(dev);
}
break;
}
}
static void
cpq_write_regsw(uint32_t addr, uint16_t val, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
cpq_write_regs(addr, val & 0xff, priv);
cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv);
}
static void
cpq_write_regsl(uint32_t addr, uint32_t val, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
cpq_write_regsw(addr, val & 0xff, priv);
cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv);
}
static void
compaq_ram_init(cpq_ram_t *dev)
{
mem_mapping_add(&dev->mapping,
0x00000000,
0x00010000,
cpq_read_ram,
cpq_read_ramw,
cpq_read_raml,
cpq_write_ram,
cpq_write_ramw,
cpq_write_raml,
NULL,
MEM_MAPPING_INTERNAL,
dev);
mem_mapping_disable(&dev->mapping);
}
static void
compaq_ram_diags_parse(cpq_386_t *dev)
{
uint8_t val = dev->regs[0x00000001];
uint32_t accum = 0x00100000;
val;
for (uint8_t i = 0; i < 4; i++) {
dev->ram_bases[i] = accum;
switch (val & 0x03) {
case RAM_DIAG_H_SYS_RAM_1MB:
dev->ram_sizes[i] = 0x00100000;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
dev->ram_sizes[i] = 0x00400000;
break;
}
if (i == 0)
dev->ram_sizes[i] -= 0x00100000;
dev->ram_map_sizes[i] = dev->ram_sizes[i];
accum += dev->ram_sizes[i];
if (accum >= (mem_size << 10)) {
dev->ram_sizes[i] = (mem_size << 10) - dev->ram_bases[i];
break;
}
val >>= 2;
}
}
static void
compaq_recalc_base_ram(cpq_386_t *dev)
{
uint8_t base_mem = dev->regs[0x00000000] & RAM_DIAG_L_BASE_MEM_MASK;
uint8_t sys_ram = dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK;
uint8_t low_start = 0x00;
uint8_t low_end = 0x00;
uint8_t high_start = 0x00;
uint8_t high_end = 0x00;
uint32_t phys_addr = 0x00000000;
uint32_t virt_addr = 0x00000000;
cpq_ram_t *cram;
switch (base_mem) {
case RAM_DIAG_L_BASE_MEM_256KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x03;
high_start = 0xf4;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x03;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
case RAM_DIAG_L_BASE_MEM_512KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x07;
high_start = 0xf8;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x07;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
case RAM_DIAG_L_BASE_MEM_640KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x09;
high_start = 0xfa;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x09;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
if (mem_size < 1024)
dev->regs[0x00000002] = 0x01;
else if (mem_size == 8192)
dev->regs[0x00000002] = 0x09;
else if (mem_size >= 11264)
dev->regs[0x00000002] = 0x0d;
else
dev->regs[0x00000002] = (mem_size >> 10);
break;
case RAM_DIAG_H_SYS_RAM_4MB:
if (mem_size < 4096)
dev->regs[0x00000002] = 0x04;
else if (mem_size == 11264)
dev->regs[0x00000002] = 0x0c;
else if (mem_size >= 16384)
dev->regs[0x00000002] = 0x00;
else if (mem_size > 13312)
dev->regs[0x00000002] = 0x0d;
else
dev->regs[0x00000002] = (mem_size >> 10);
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X\n", sys_ram);
return;
}
/* The base 640 kB. */
for (uint8_t i = low_start; i <= low_end; i++) {
cram = &(dev->ram[0][i]);
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
dev->mem_state[i] |= MEM_STATE_SYS;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
cpq_recalc_state(dev, i);
}
/* The relocated 128 kB. */
for (uint8_t i = 0x0e; i <= 0x0f; i++) {
cram = &(dev->ram[0][i]);
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
}
/* Blocks FA-FF. */
for (uint16_t i = high_start; i <= high_end; i++) {
cram = &(dev->high_ram[i & 0x0f]);
cram->phys_base = ((uint32_t) (i & 0x0f)) << 16;
cram->virt_base = ((uint32_t) i) << 16;
dev->mem_state[i] |= MEM_STATE_SYS;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
cpq_recalc_state(dev, i);
}
}
static void
compaq_386_close(void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
free(dev);
}
static void *
compaq_386_init(const device_t *info)
{
cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t));
mem_mapping_add(&dev->regs_mapping,
0x80c00000,
0x00001000,
cpq_read_regs,
cpq_read_regsw,
cpq_read_regsl,
cpq_write_regs,
cpq_write_regsw,
cpq_write_regsl,
NULL,
MEM_MAPPING_INTERNAL,
dev);
mem_set_mem_state(0x80c00000, 0x00001000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
dev->regs[0x00000000] = RAM_DIAG_L_PERMA_BITS;
if (mem_size >= 640)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_640KB;
else if (mem_size >= 512)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_512KB;
else if (mem_size >= 256)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_256KB;
else
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_INV;
/* Indicate no parity error. */
dev->regs[0x00000000] |= 0x0f;
if (mem_size >= 1024) {
switch (mem_size) {
case 1024:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 2048:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 3072:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 4096:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 5120:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 6144:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 7168:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 8192:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 9216:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 10240:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 11264:
case 12288:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 13312:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 14336:
case 15360:
case 16384:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB;
break;
}
} else
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
dev->regs[0x00000003] = 0xfc;
dev->regs[0x00000004] = dev->regs[0x00000005] = 0xff;
compaq_ram_diags_parse(dev);
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping);
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
/* Should never be the case, but you never know what a user may set. */
if (mem_size > 1048576)
mem_mapping_disable(&ram_2gb_mapping);
#endif
/* Initialize in reverse order for memory mapping precedence
reasons. */
for (int8_t i = 3; i >= 0; i--) {
for (uint8_t j = 0; j < 64; j++)
compaq_ram_init(&(dev->ram[i][j]));
}
for (uint8_t i = 0; i < 16; i++)
compaq_ram_init(&(dev->high_ram[i]));
/* First, set the entire 256 MB of space to invalid states. */
for (uint16_t i = 0; i < 256; i++)
dev->old_state[i] = 0xff;
/* Then, recalculate the base RAM mappings. */
compaq_recalc_base_ram(dev);
/* Enable the external cache. */
dev->regs[0x00000002] |= 0x40;
cpq_recalc_cache(dev);
/* Recalculate the rest of the RAM mapping. */
cpq_recalc_ram(dev);
return dev;
}
const device_t compaq_386_device = {
.name = "Compaq 386 Memory Control",
.internal_name = "opti391",
.flags = 0,
.local = 0,
.init = compaq_386_init,
.close = compaq_386_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -122,6 +122,9 @@
typedef struct ims8848_t {
uint8_t idx;
uint8_t access_data;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint8_t pci_conf[256];
@@ -392,7 +395,7 @@ ims8848_init(UNUSED(const device_t *info))
PCI Device 0: IMS 8849 Dummy for compatibility reasons
*/
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev, &dev->pci_slot);
dev->smram = smram_add();
smram_set_separate_smram(1);

View File

@@ -52,6 +52,9 @@
typedef struct i420ex_t {
uint8_t has_ide;
uint8_t smram_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint16_t timer_base;
@@ -534,7 +537,7 @@ i420ex_init(const device_t *info)
dev->smram = smram_add();
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev, &dev->pci_slot);
dev->has_ide = info->local;

View File

@@ -57,6 +57,9 @@ typedef struct i4x0_t {
uint8_t max_drb;
uint8_t drb_unit;
uint8_t drb_default;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint8_t regs_locked[256];
uint8_t mem_state[256];
@@ -1241,12 +1244,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_440FX:
regs[0x93] = (val & 0x0f);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
case INTEL_440LX:
case INTEL_440EX:
regs[0x93] = (val & 0x0e);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
default:
break;
@@ -1518,7 +1521,7 @@ i4x0_read(int func, int addr, void *priv)
/* Special behavior for 440FX register 0x93 which is basically TRC in PCI space
with the addition of bits 3 and 0. */
if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)))
ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06);
ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06);
}
return ret;
@@ -1910,7 +1913,7 @@ i4x0_init(const device_t *info)
(dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev);
}
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot);
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) {
device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device);

View File

@@ -62,11 +62,15 @@ i450kx_log(const char *fmt, ...)
typedef struct i450kx_t {
smram_t *smram[2];
uint8_t bus_index;
uint8_t pb_slot;
uint8_t mc_slot;
uint8_t pad;
uint8_t pb_pci_conf[256];
uint8_t mc_pci_conf[256];
uint8_t mem_state[2][256];
uint8_t bus_index;
uint8_t mem_state[2][256];
} i450kx_t;
static void
@@ -801,8 +805,8 @@ i450kx_init(UNUSED(const device_t *info))
{
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
memset(dev, 0, sizeof(i450kx_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -66,7 +66,7 @@ typedef struct _piix_ {
uint8_t max_func;
uint8_t pci_slot;
uint8_t no_mirq0;
uint8_t pad;
uint8_t usb_irq_state;
uint8_t regs[4][256];
uint8_t readout_regs[256];
uint8_t board_config[2];
@@ -1446,12 +1446,12 @@ piix_fast_off_count(void *priv)
static void
piix_usb_update_interrupt(usb_t* usb, void *priv)
{
const piix_t *dev = (piix_t *) priv;
piix_t *dev = (piix_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->pci_slot, PCI_INTD);
pci_set_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
else
pci_clear_irq(dev->pci_slot, PCI_INTD);
pci_clear_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
}
static void
@@ -1574,7 +1574,7 @@ piix_init(const device_t *info)
dev->no_mirq0 = (info->local >> 12) & 0x0f;
dev->func0_id = info->local >> 16;
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);

View File

@@ -37,6 +37,10 @@
typedef struct sio_t {
uint8_t id;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint16_t timer_base;
@@ -507,7 +511,7 @@ sio_init(const device_t *info)
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
memset(dev, 0, sizeof(sio_t));
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -229,9 +229,7 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
case 0x14:
reset_on_hlt = !!(val & 0x40);
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x11:
case 0x12:
case 0x13:

View File

@@ -43,6 +43,10 @@
typedef struct opti822_t {
uint8_t irq_convert;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_regs[256];
} opti822_t;
@@ -393,7 +397,7 @@ opti822_init(UNUSED(const device_t *info))
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
memset(dev, 0, sizeof(opti822_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot);
opti822_reset(dev);

View File

@@ -155,6 +155,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->idx] = val;
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
switch (dev->idx) {
case 0x21:
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
@@ -213,12 +214,14 @@ opti895_read(uint16_t addr, void *priv)
ret = dev->regs[dev->idx];
break;
case 0x24:
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
ret = dev->regs[dev->idx];
if (dev->idx == 0xe0)
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
}
break;
case 0xe1:
case 0xe2:
ret = dev->scratch[addr - 0xe1];

View File

@@ -66,13 +66,15 @@ sis_5511_log(const char *fmt, ...)
#endif
typedef struct sis_5511_t {
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t regs[16];
int nb_pci_slot;
int sb_pci_slot;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
sff8038i_t *ide_drive[2];
smram_t *smram;
@@ -713,8 +715,8 @@ sis_5511_reset(void *priv)
dev->pci_conf_sb[1][0x0a] = 1;
dev->pci_conf_sb[1][0x0b] = 1;
dev->pci_conf_sb[1][0x0e] = 0x80;
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
}
@@ -734,8 +736,8 @@ sis_5511_init(UNUSED(const device_t *info))
sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t));
memset(dev, 0, sizeof(sis_5511_t));
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev); /* Device 0: SiS 5511 */
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev); /* Device 1: SiS 5513 */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 0: SiS 5511 */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); /* Device 1: SiS 5513 */
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */
/* MIRQ */

View File

@@ -75,12 +75,14 @@ sis_5571_log(const char *fmt, ...)
#endif
typedef struct sis_5571_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t usb_irq_state;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[3][256];
int nb_pci_slot;
int sb_pci_slot;
port_92_t *port_92;
sff8038i_t *ide_drive[2];
smram_t *smram;
@@ -670,7 +672,7 @@ pci_isa_bridge_read(int func, int addr, void *priv)
static void
sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
{
const sis_5571_t *dev = (sis_5571_t *) priv;
sis_5571_t *dev = (sis_5571_t *) priv;
if (dev->pci_conf_sb[0][0x68] & 0x80) {
/* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */
@@ -691,9 +693,9 @@ sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
}
} else {
if (usb->irq_level)
pci_set_irq(dev->sb_pci_slot, PCI_INTA);
pci_set_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
else
pci_clear_irq(dev->sb_pci_slot, PCI_INTA);
pci_clear_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
}
}
@@ -739,8 +741,8 @@ sis_5571_reset(void *priv)
dev->pci_conf_sb[1][0x0b] = 0x01;
dev->pci_conf_sb[1][0x0e] = 0x80;
dev->pci_conf_sb[1][0x4a] = 0x06;
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
@@ -773,8 +775,8 @@ sis_5571_init(UNUSED(const device_t *info))
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
memset(dev, 0x00, sizeof(sis_5571_t));
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev);
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
/* MIRQ */
pci_enable_mirq(0);

View File

@@ -45,9 +45,13 @@
typedef struct sis_85c496_t {
uint8_t cur_reg;
uint8_t rmsmiblk_count;
uint8_t pci_slot;
uint8_t pad;
#ifndef USE_DRB_HACK
uint8_t drb_default;
uint8_t drb_bits;
uint8_t pad0;
uint8_t pad1;
#endif
uint8_t regs[127];
uint8_t pci_conf[256];
@@ -648,7 +652,7 @@ static void
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
dev->pci_conf[0xd1] = 0xff;
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev, &dev->pci_slot);
#if 0
sis_85c497_isa_reset(dev);

View File

@@ -59,6 +59,10 @@ sis_85c50x_log(const char *fmt, ...)
typedef struct sis_85c50x_t {
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[256];
uint8_t regs[256];
@@ -426,10 +430,10 @@ sis_85c50x_init(UNUSED(const device_t *info))
memset(dev, 0x00, sizeof(sis_85c50x_t));
/* 501/502 (Northbridge) */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot);
/* 503 (Southbridge) */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev, &dev->sb_slot);
io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
dev->smram[0] = smram_add();

View File

@@ -45,6 +45,11 @@
#define STPC_CLIENT 0x100e55cc
typedef struct stpc_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t ide_slot;
uint8_t usb_slot;
uint32_t local;
/* Main registers (port 22h/23h) */
@@ -54,19 +59,19 @@ typedef struct stpc_t {
/* Host bus interface */
uint16_t host_base;
uint8_t host_offset;
uint8_t usb_irq_state;
uint8_t host_regs[256];
/* Local bus */
uint16_t localbus_base;
uint8_t localbus_offset;
uint8_t pad0;
uint8_t localbus_regs[256];
/* PCI devices */
uint8_t pci_conf[4][256];
smram_t *smram;
usb_t *usb;
int ide_slot;
int usb_slot;
sff8038i_t *bm[2];
/* Miscellaneous */
@@ -896,12 +901,12 @@ stpc_setup(stpc_t *dev)
static void
stpc_usb_update_interrupt(usb_t* usb, void* priv)
{
const stpc_t *dev = (stpc_t *) priv;
stpc_t *dev = (stpc_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->usb_slot, PCI_INTA);
pci_set_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
else
pci_clear_irq(dev->usb_slot, PCI_INTA);
pci_clear_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
}
static void
@@ -926,16 +931,16 @@ stpc_init(const device_t *info)
dev->local = info->local;
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev);
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
if (dev->local == STPC_ATLAS) {
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
dev->usb_params.parent_priv = dev;
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
}
dev->bm[0] = device_add_inst(&sff8038i_device, 1);

View File

@@ -121,8 +121,13 @@ umc_8886_log(const char *fmt, ...)
#define SB_ID dev->sb_id
typedef struct umc_8886_t {
uint8_t max_func; /* Last function number */
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint8_t max_func; /* Last function number */
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint16_t sb_id; /* Southbridge Revision */
int has_ide; /* Check if Southbridge Revision is AF or F */
} umc_8886_t;
@@ -371,7 +376,7 @@ umc_8886_init(const device_t *info)
memset(dev, 0, sizeof(umc_8886_t));
dev->has_ide = !!(info->local == 0x886a);
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */
/* Add IDE if UM8886AF variant */
if (HAS_IDE)

View File

@@ -146,6 +146,8 @@ typedef struct hb4_t {
uint8_t shadow;
uint8_t shadow_read;
uint8_t shadow_write;
uint8_t pci_slot;
uint8_t pci_conf[256]; /* PCI Registers */
int mem_state[9];
smram_t *smram[3]; /* SMRAM Handlers */
@@ -393,7 +395,7 @@ hb4_init(UNUSED(const device_t *info))
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
memset(dev, 0, sizeof(hb4_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */
/* Port 92 */
device_add(&port_92_pci_device);

View File

@@ -45,10 +45,15 @@
#define VIA_8601 0x86010500
typedef struct via_apollo_t {
uint32_t id;
uint8_t drb_unit;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
uint32_t id;
smram_t *smram;
agpgart_t *agpgart;
} via_apollo_t;
@@ -715,7 +720,7 @@ via_apollo_init(const device_t *info)
if (dev->id != VIA_8601)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -117,9 +117,10 @@ typedef struct {
} pipc_io_trap_t;
typedef struct _pipc_ {
uint32_t local;
uint8_t max_func;
uint8_t max_pcs;
uint8_t pci_slot;
uint8_t pad;
uint8_t pci_isa_regs[256];
uint8_t ide_regs[256];
@@ -129,10 +130,11 @@ typedef struct _pipc_ {
uint8_t fmnmi_regs[4];
uint8_t fmnmi_status;
uint32_t local;
sff8038i_t *bm[2];
nvr_t *nvr;
int nvr_enabled;
int slot;
ddma_t *ddma;
smbus_piix4_t *smbus;
usb_t *usb[2];
@@ -1094,7 +1096,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x47:
if (val & 0x01)
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL);
pic_set_shadow(!!(val & 0x10));
pic_elcr_io_handler(!!(val & 0x20));
dev->pci_isa_regs[0x47] = val & 0xfe;
@@ -1475,9 +1477,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0xd2:
if (dev->local == VIA_PIPC_686B)
smbus_piix4_setclock(dev->smbus, (val & 0x04) ? 65536 : 16384);
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x90:
case 0x91:
@@ -1620,6 +1620,14 @@ pipc_reset(void *priv)
pipc_write(0, 0x44, 0x00, priv);
pipc_write(0, 0x77, 0x00, priv);
sff_set_slot(dev->bm[0], dev->pci_slot);
sff_set_slot(dev->bm[1], dev->pci_slot);
if (dev->local >= VIA_PIPC_686A)
ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC);
if (dev->acpi)
acpi_set_slot(dev->acpi, dev->pci_slot);
}
static void *
@@ -1631,16 +1639,14 @@ pipc_init(const device_t *info)
pipc_log("PIPC: init()\n");
dev->local = info->local;
dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot);
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
sff_set_slot(dev->bm[0], dev->slot);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_pin(dev->bm[0], PCI_INTA);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
sff_set_slot(dev->bm[1], dev->slot);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_pin(dev->bm[1], PCI_INTA);
@@ -1665,7 +1671,6 @@ pipc_init(const device_t *info)
dev->usb[1] = device_add_inst(&usb_device, 2);
dev->ac97 = device_add(&ac97_via_device);
ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC);
dev->sb = device_add_inst(&sb_pro_compat_device, 2);
sound_add_handler(pipc_sb_get_buffer, dev);
@@ -1695,7 +1700,6 @@ pipc_init(const device_t *info)
dev->ddma = device_add(&ddma_device);
if (dev->acpi) {
acpi_set_slot(dev->acpi, dev->slot);
acpi_set_nvr(dev->acpi, dev->nvr);
acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f);

View File

@@ -32,6 +32,10 @@
typedef struct vt82c505_t {
uint8_t index;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
} vt82c505_t;
@@ -203,7 +207,7 @@ vt82c505_init(UNUSED(const device_t *info))
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
memset(dev, 0, sizeof(vt82c505_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot);
dev->pci_conf[0x00] = 0x06;
dev->pci_conf[0x01] = 0x11;

View File

@@ -1,5 +1,6 @@
#if defined __aarch64__ || defined _M_ARM64
# include <inttypes.h>
# include <stdint.h>
# include <86box/86box.h>
# include "cpu.h"
@@ -340,7 +341,7 @@ host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm
} 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);
fatal("ADD_IMM_X %016" PRIu64 "\n", imm_data);
}
void
host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
@@ -662,7 +663,7 @@ host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_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);
fatal("CMNX_IMM %016" PRIx64 "\n", imm_data);
}
void
@@ -683,7 +684,7 @@ host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_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);
fatal("CMPX_IMM %08" PRIu64 "\n", imm_data);
}
void

View File

@@ -553,7 +553,7 @@ codegen_FABS(codeblock_t *block, uop_t *uop)
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);
fatal("codegen_FABS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@@ -566,7 +566,7 @@ codegen_FCHS(codeblock_t *block, uop_t *uop)
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);
fatal("codegen_FCHS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@@ -579,7 +579,7 @@ codegen_FSQRT(codeblock_t *block, uop_t *uop)
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);
fatal("codegen_FSQRT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@@ -1548,7 +1548,7 @@ codegen_PF2ID(codeblock_t *block, uop_t *uop)
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);
fatal("PF2ID %02x\n", uop->dest_reg_a_real);
return 0;
}
@@ -1655,7 +1655,7 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop)
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);
fatal("PFRCP %02x\n", uop->dest_reg_a_real);
return 0;
}
@@ -1672,7 +1672,7 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop)
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);
fatal("PFRSQRT %02x\n", uop->dest_reg_a_real);
return 0;
}
@@ -1698,7 +1698,7 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop)
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);
fatal("PI2FD %02x\n", uop->dest_reg_a_real);
return 0;
}

View File

@@ -1,3 +1,4 @@
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -305,7 +306,7 @@ add_to_block_list(codeblock_t *block)
#ifndef RELEASE_BUILD
if (!block->page_mask)
fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2);
fatal("add_to_block_list - mask = 0 %" PRIx64 " %" PRIx64 "\n", block->page_mask, block->page_mask2);
#endif
if (block_prev_nr) {

View File

@@ -12,17 +12,22 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include <86box/io.h>
#include <86box/nmi.h>
#include <86box/mem.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/machine.h>
#include <86box/gdbstub.h>
#ifndef OPS_286_386
# define OPS_286_386
#endif
#include "386_common.h"
#ifdef USE_NEW_DYNAREC
# include "codegen.h"
@@ -33,54 +38,7 @@
extern int codegen_flags_changed;
int tempc, oldcpl, optype, inttype, oddeven = 0;
int timetolive;
uint16_t oldcs;
uint32_t oldds, oldss, olddslimit, oldsslimit,
olddslimitw, oldsslimitw;
uint32_t oxpc;
uint32_t rmdat32;
uint32_t backupregs[16];
x86seg _oldds;
#if 1
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
#else
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x2x */
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x3x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
3, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
#endif
static int fpu_cycles = 0;
#ifdef ENABLE_386_LOG
int x386_do_log = ENABLE_386_LOG;
@@ -103,9 +61,6 @@ x386_log(const char *fmt, ...)
#undef CPU_BLOCK_END
#define CPU_BLOCK_END()
#include "x86_flags.h"
/*
#define getbytef() \
((uint8_t) (fetchdat)); \
cpu_state.pc++
@@ -118,40 +73,169 @@ x386_log(const char *fmt, ...)
#define getword2f() \
((uint16_t) (fetchdat >> 8)); \
cpu_state.pc += 2
*/
#define OP_TABLE(name) ops_##name
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;
#if 0
# define CLOCK_CYCLES(c) \
{ \
if (fpu_cycles > 0) { \
fpu_cycles -= (c); \
if (fpu_cycles < 0) { \
cycles += fpu_cycles; \
} \
} else { \
cycles -= (c); \
} \
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);
}
}
# 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)
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);
}
}
#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"
#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_FLUSH() prefetch_flush()
#ifndef FPU_CYCLES
# define FPU_CYCLES
#endif
#define OP_TABLE(name) ops_2386_##name
#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_ALWAYS(c) cycles -= (c)
#include "x86_ops.h"
#include "386_ops.h"
void
exec386(int cycs)
exec386_2386(int cycs)
{
int vector, tempi, cycdiff, oldcyc;
int cycle_period, ins_cycles;
int vector;
int tempi;
int cycdiff;
int oldcyc;
int cycle_period;
int ins_cycles;
uint32_t addr;
cycles += cycs;
@@ -184,7 +268,7 @@ exec386(int cycs)
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG
if (in_smm)
x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;

View File

@@ -26,6 +26,7 @@
#include "386_common.h"
#include "x86_flags.h"
#include "x86seg.h"
#include <86box/plat_unused.h>
#ifdef USE_DYNAREC
# include "codegen.h"
@@ -34,19 +35,26 @@
# define CPU_BLOCK_END()
#endif
x86seg gdt, ldt, idt, tr;
x86seg gdt;
x86seg ldt;
x86seg idt;
x86seg tr;
uint32_t cr2, cr3, cr4;
uint32_t cr2;
uint32_t cr3;
uint32_t cr4;
uint32_t dr[8];
uint32_t use32;
int stack32;
uint32_t *eal_r, *eal_w;
uint32_t *eal_r;
uint32_t *eal_w;
int nmi_enable = 1;
int alt_access, cpl_override = 0;
int alt_access;
int cpl_override = 0;
#ifdef USE_NEW_DYNAREC
uint16_t cpu_cur_status = 0;
@@ -59,16 +67,60 @@ extern uint8_t *pccache2;
extern int optype;
extern uint32_t pccache;
int in_sys = 0, unmask_a20_in_smm = 0;
uint32_t old_rammask = 0xffffffff;
int in_sys = 0;
int unmask_a20_in_smm = 0;
uint32_t old_rammask = 0xffffffff;
int soft_reset_mask = 0;
int smi_latched = 0;
int smm_in_hlt = 0, smi_block = 0;
int smm_in_hlt = 0;
int smi_block = 0;
uint32_t addr64, addr64_2;
uint32_t addr64a[8], addr64a_2[8];
int prefetch_prefixes = 0;
int tempc;
int oldcpl;
int optype;
int inttype;
int oddeven = 0;
int timetolive;
uint16_t oldcs;
uint32_t oldds;
uint32_t oldss;
uint32_t olddslimit;
uint32_t oldsslimit;
uint32_t olddslimitw;
uint32_t oldsslimitw;
uint32_t oxpc;
uint32_t rmdat32;
uint32_t backupregs[16];
x86seg _oldds;
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
uint32_t addr64;
uint32_t addr64_2;
uint32_t addr64a[8];
uint32_t addr64a_2[8];
static pc_timer_t *cpu_fast_off_timer = NULL;
static double cpu_fast_off_period = 0.0;
@@ -321,6 +373,77 @@ x386_common_log(const char *fmt, ...)
# define x386_common_log(fmt, ...)
#endif
/*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
from the total cycles taken
- Any remaining cycles are used to refill the prefetch queue.
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;
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;
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);
}
}
/* 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;
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;
}
void
prefetch_flush(void)
{
prefetch_bytes = 0;
}
static __inline void
set_stack32(int s)
{
@@ -391,12 +514,10 @@ smm_seg_load(x86seg *s)
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;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l;
if (in_hlt)
@@ -485,9 +606,7 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt)
static void
smram_restore_state_p5(uint32_t *saved_state)
{
int n = 0;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n];
if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff)
@@ -598,12 +717,10 @@ smram_restore_state_p5(uint32_t *saved_state)
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;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l;
if (in_hlt)
@@ -684,9 +801,7 @@ smram_save_state_p6(uint32_t *saved_state, int in_hlt)
static void
smram_restore_state_p6(uint32_t *saved_state)
{
int n = 0;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n];
if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff)
@@ -791,12 +906,10 @@ smram_restore_state_p6(uint32_t *saved_state)
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;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l;
if (in_hlt)
@@ -876,9 +989,7 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt)
static void
smram_restore_state_amd_k(uint32_t *saved_state)
{
int n = 0;
for (n = 0; n < 8; n++)
for (uint8_t n = 0; n < 8; n++)
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n];
if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff)
@@ -977,7 +1088,7 @@ smram_restore_state_amd_k(uint32_t *saved_state)
}
static void
smram_save_state_cyrix(uint32_t *saved_state, int in_hlt)
smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
{
saved_state[0] = dr[7];
saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16);
@@ -1001,7 +1112,7 @@ smram_restore_state_cyrix(uint32_t *saved_state)
void
enter_smm(int in_hlt)
{
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE];
uint32_t smram_state = smbase + 0x10000;
/* If it's a CPU on which SMM is not supported, do nothing. */
@@ -1053,13 +1164,13 @@ enter_smm(int in_hlt)
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
if (is_cxsmm) /* Cx6x86 */
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 */
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) */
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
smram_save_state_p6(saved_state, in_hlt);
cr0 &= ~0x8000000d;
@@ -1128,7 +1239,7 @@ enter_smm(int in_hlt)
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++) {
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
writememl(0, smram_state, saved_state[n]);
}
@@ -1188,7 +1299,7 @@ enter_smm_check(int in_hlt)
void
leave_smm(void)
{
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE];
uint32_t smram_state = smbase + 0x10000;
/* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */
@@ -1209,7 +1320,7 @@ leave_smm(void)
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++) {
for (uint8_t 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);
@@ -1224,13 +1335,13 @@ leave_smm(void)
}
x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]);
if (is_cxsmm) /* Cx6x86 */
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 */
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) */
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
smram_restore_state_p6(saved_state);
in_smm = 0;
@@ -1380,7 +1491,8 @@ int
x86_int_sw_rm(int num)
{
uint32_t addr;
uint16_t new_pc, new_cs;
uint16_t new_pc;
uint16_t new_cs;
flags_rebuild();
cycles -= timing_int;
@@ -1468,8 +1580,10 @@ checkio(uint32_t port, int mask)
int
divl(uint32_t val)
{
uint64_t num, quo;
uint32_t rem, quo32;
uint64_t num;
uint64_t quo;
uint32_t rem;
uint32_t quo32;
if (val == 0) {
divexcp();
@@ -1495,8 +1609,10 @@ divl(uint32_t val)
int
idivl(int32_t val)
{
int64_t num, quo;
int32_t rem, quo32;
int64_t num;
int64_t quo;
int32_t rem;
int32_t quo32;
if (val == 0) {
divexcp();

View File

@@ -20,83 +20,112 @@
#define _386_COMMON_H_
#include <stddef.h>
#include <inttypes.h>
#include <inttypes.h>
#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))))
#ifdef OPS_286_386
# define readmemb_n(s, a, b) readmembl_no_mmut_2386((s) + (a), b)
# define readmemw_n(s, a, b) readmemwl_no_mmut_2386((s) + (a), b)
# define readmeml_n(s, a, b) readmemll_no_mmut_2386((s) + (a), b)
# define readmemb(s, a) readmembl_2386((s) + (a))
# define readmemw(s, a) readmemwl_2386((s) + (a))
# define readmeml(s, a) readmemll_2386((s) + (a))
# define readmemq(s, a) readmemql_2386((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) writemembl_no_mmut_2386((s) + (a), b, v)
# define writememw_n(s, a, b, v) writememwl_no_mmut_2386((s) + (a), b, v)
# define writememl_n(s, a, b, v) writememll_no_mmut_2386((s) + (a), b, v)
# define writememb(s, a, v) writemembl_2386((s) + (a), v)
# define writememw(s, a, v) writememwl_2386((s) + (a), v)
# define writememl(s, a, v) writememll_2386((s) + (a), v)
# define writememq(s, a, v) writememql_2386((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_rb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0)
# define do_mmut_rw(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0)
# define do_mmut_rl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0)
# define do_mmut_rb2(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0)
# define do_mmut_rw2(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0)
# define do_mmut_rl2(s, a, b) do_mmutranslate_2386((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_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1)
# define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1)
# define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1)
#else
# 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 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)
#endif
int checkio(uint32_t port, int mask);
@@ -191,27 +220,47 @@ int checkio(uint32_t port, int mask);
return 1; \
}
#ifdef OPS_286_386
/* TODO: Introduce functions to read exec. */
static __inline uint8_t
fastreadb(uint32_t a)
{
return readmembl(a);
}
static __inline uint16_t
fastreadw(uint32_t a)
{
return readmemwl(a);
}
static __inline uint32_t
fastreadl(uint32_t a)
{
return readmemll(a);
}
#else
static __inline uint8_t
fastreadb(uint32_t a)
{
uint8_t *t;
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint8_t *) &pccache2[a]);
#endif
# endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint8_t *) &pccache2[a]);
#endif
# endif
}
static __inline uint16_t
@@ -225,22 +274,22 @@ fastreadw(uint32_t a)
return val;
}
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint16_t *) &pccache2[a]);
#endif
# endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint16_t *) &pccache2[a]);
#endif
# endif
}
static __inline uint32_t
@@ -256,16 +305,17 @@ fastreadl(uint32_t a)
pccache2 = t;
pccache = a >> 12;
}
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint32_t *) &pccache2[a]);
#endif
# endif
}
val = fastreadw(a);
val |= (fastreadw(a + 2) << 16);
return val;
}
#endif
static __inline void *
get_ram_ptr(uint32_t a)
@@ -288,6 +338,37 @@ get_ram_ptr(uint32_t a)
extern int opcode_length[256];
#ifdef OPS_286_386
static __inline uint16_t
fastreadw_fetch(uint32_t a)
{
uint16_t val;
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
if (opcode_length[val & 0xff] > 1)
val |= (fastreadb(a + 1) << 8);
return val;
}
return readmemwl(a);
}
static __inline uint32_t
fastreadl_fetch(uint32_t a)
{
uint32_t val;
if ((a & 0xFFF) > 0xFFC) {
val = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2)
val |= (fastreadw(a + 2) << 16);
return val;
}
return readmemll(a);
}
#else
static __inline uint16_t
fastreadw_fetch(uint32_t a)
{
@@ -300,22 +381,22 @@ fastreadw_fetch(uint32_t a)
return val;
}
if ((a >> 12) == pccache)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint16_t *) &pccache2[a]);
#endif
# endif
t = getpccache(a);
if (cpu_state.abrt)
return 0;
pccache = a >> 12;
pccache2 = t;
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint16_t *) &pccache2[a]);
#endif
# endif
}
static __inline uint32_t
@@ -331,17 +412,18 @@ fastreadl_fetch(uint32_t a)
pccache2 = t;
pccache = a >> 12;
}
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
#else
# else
return *((uint32_t *) &pccache2[a]);
#endif
# endif
}
val = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2)
val |= (fastreadw(a + 2) << 16);
return val;
}
#endif
static __inline uint8_t
getbyte(void)
@@ -371,6 +453,93 @@ getquad(void)
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
}
#ifdef OPS_286_386
static __inline uint8_t
geteab(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;
return readmemb(easeg, cpu_state.eaaddr);
}
static __inline uint16_t
geteaw(void)
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
return readmemw(easeg, cpu_state.eaaddr);
}
static __inline uint32_t
geteal(void)
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
return readmeml(easeg, cpu_state.eaaddr);
}
static __inline uint64_t
geteaq(void)
{
return readmemq(easeg, cpu_state.eaaddr);
}
static __inline uint8_t
geteab_mem(void)
{
return readmemb(easeg, cpu_state.eaaddr);
}
static __inline uint16_t
geteaw_mem(void)
{
return readmemw(easeg, cpu_state.eaaddr);
}
static __inline uint32_t
geteal_mem(void)
{
return readmeml(easeg, cpu_state.eaaddr);
}
static __inline int
seteaq_cwc(void)
{
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
return 0;
}
static __inline void
seteaq(uint64_t v)
{
if (seteaq_cwc())
return;
writememql(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); \
writemembl_2386(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); \
writememwl_2386(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); \
writememll_2386(easeg + cpu_state.eaaddr, v); \
} else \
cpu_state.regs[cpu_rm].l = v
# define seteab_mem(v) writemembl_2386(easeg + cpu_state.eaaddr, v);
# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v);
# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v);
#else
static __inline uint8_t
geteab(void)
{
@@ -444,51 +613,52 @@ seteaq(uint64_t v)
writememql(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; \
# 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 \
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
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 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_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);
#endif
#define getbytef() \
((uint8_t) (fetchdat)); \

View File

@@ -46,7 +46,8 @@
#define CPU_BLOCK_END() cpu_block_end = 1
int inrecomp = 0, cpu_block_end = 0;
int inrecomp = 0;
int cpu_block_end = 0;
int cpu_end_block_after_ins = 0;
#ifdef ENABLE_386_DYNAREC_LOG
@@ -183,78 +184,6 @@ fetch_ea_16_long(uint32_t rmdat)
#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
from the total cycles taken
- Any remaining cycles are used to refill the prefetch queue.
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_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)
{
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;
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;
}
/* 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;
}
prefetch_prefixes = 0;
if (prefetch_bytes > 16)
prefetch_bytes = 16;
}
static void
prefetch_flush(void)
{
prefetch_bytes = 0;
}
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
do { \
if (cpu_prefetch_cycles) \
@@ -406,8 +335,9 @@ exec386_dynarec_int(void)
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);
uint32_t start_pc = 0;
uint32_t phys_addr = get_phys(cs + cpu_state.pc);
int hash = HASH(phys_addr);
# ifdef USE_NEW_DYNAREC
codeblock_t *block = &codeblock[codeblock_hash[hash]];
# else
@@ -556,7 +486,9 @@ exec386_dynarec_dyn(void)
x86_was_reset = 0;
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(0);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(0);
}
# endif
codegen_block_start_recompile(block);
codegen_in_recompile = 1;
@@ -640,7 +572,9 @@ exec386_dynarec_dyn(void)
codegen_in_recompile = 0;
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(1);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(1);
}
# endif
} else if (!cpu_state.abrt) {
/* Mark block but do not recompile */
@@ -742,10 +676,13 @@ exec386_dynarec_dyn(void)
void
exec386_dynarec(int cycs)
{
int vector, tempi;
int vector;
int tempi;
int cycdiff;
int oldcyc, oldcyc2;
uint64_t oldtsc, delta;
int oldcyc;
int oldcyc2;
uint64_t oldtsc;
uint64_t delta;
int cyc_period = cycs / 2000; /*5us*/
@@ -858,3 +795,160 @@ exec386_dynarec(int cycs)
}
}
#endif
void
exec386(int cycs)
{
int vector;
int tempi;
int cycdiff;
int oldcyc;
int cycle_period;
int ins_cycles;
uint32_t addr;
cycles += cycs;
while (cycles > 0) {
cycle_period = (timer_target - (uint32_t) tsc) + 1;
x86_was_reset = 0;
cycdiff = 0;
oldcyc = cycles;
while (cycdiff < cycle_period) {
ins_cycles = cycles;
#ifndef USE_NEW_DYNAREC
oldcs = CS;
oldcpl = CPL;
#endif
cpu_state.oldpc = cpu_state.pc;
cpu_state.op32 = use32;
#ifndef USE_NEW_DYNAREC
x86_was_reset = 0;
#endif
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG
if (in_smm)
x386_dynarec_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
break;
}
#ifdef ENABLE_386_LOG
else if (in_smm)
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
#endif
#ifndef USE_NEW_DYNAREC
if (!use32)
cpu_state.pc &= 0xffff;
#endif
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;
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;
#ifndef USE_NEW_DYNAREC
CS = oldcs;
#endif
cpu_state.pc = cpu_state.oldpc;
x386_dynarec_log("Double fault\n");
pmodeint(8, 0);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
#ifdef ENABLE_386_LOG
x386_dynarec_log("Triple fault - reset\n");
#endif
}
}
} else if (trap) {
flags_rebuild();
trap = 0;
#ifndef USE_NEW_DYNAREC
oldcs = CS;
#endif
cpu_state.oldpc = cpu_state.pc;
dr[6] |= 0x4000;
x86_int(1);
}
if (smi_line)
enter_smm_check(0);
else if (nmi && nmi_enable && nmi_mask) {
#ifndef USE_NEW_DYNAREC
oldcs = CS;
#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 && !cpu_end_block_after_ins) {
vector = picinterrupt();
if (vector != -1) {
flags_rebuild();
if (msw & 1)
pmodeint(vector, 0);
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;
addr = (vector << 2) + idt.base;
cpu_state.flags &= ~I_FLAG;
cpu_state.flags &= ~T_FLAG;
cpu_state.pc = readmemw(0, addr);
loadcs(readmemw(0, addr + 2));
}
}
}
ins_cycles -= cycles;
tsc += ins_cycles;
cycdiff = oldcyc - cycles;
if (timetolive) {
timetolive--;
if (!timetolive)
fatal("Life expired\n");
}
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
timer_process_inline();
#ifdef USE_GDBSTUB
if (gdbstub_instruction())
return;
#endif
}
}
}

View File

@@ -21,6 +21,7 @@
#include <86box/pic.h>
#include <86box/gdbstub.h>
#include "codegen.h"
#include <86box/plat_unused.h>
#define CPU_BLOCK_END() cpu_block_end = 1
@@ -31,7 +32,7 @@
#include "386_common.h"
static __inline void
fetch_ea_32_long(uint32_t rmdat)
fetch_ea_32_long(UNUSED(uint32_t rmdat))
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -45,7 +46,7 @@ fetch_ea_32_long(uint32_t rmdat)
}
static __inline void
fetch_ea_16_long(uint32_t rmdat)
fetch_ea_16_long(UNUSED(uint32_t rmdat))
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;

View File

@@ -179,7 +179,9 @@ extern void x386_dynarec_log(const char *fmt, ...);
#include "x86_ops_bcd.h"
#include "x86_ops_bit.h"
#include "x86_ops_bitscan.h"
#include "x86_ops_cyrix.h"
#ifndef OPS_286_386
# include "x86_ops_cyrix.h"
#endif
#include "x86_ops_flag.h"
#include "x86_ops_fpu.h"
#include "x86_ops_inc_dec.h"
@@ -188,38 +190,53 @@ extern void x386_dynarec_log(const char *fmt, ...);
#include "x86_ops_jump.h"
#include "x86_ops_misc.h"
#include "x87_ops.h"
#include "x86_ops_i686.h"
#include "x86_ops_mmx.h"
#include "x86_ops_mmx_arith.h"
#include "x86_ops_mmx_cmp.h"
#include "x86_ops_mmx_logic.h"
#include "x86_ops_mmx_mov.h"
#include "x86_ops_mmx_pack.h"
#include "x86_ops_mmx_shift.h"
#ifndef OPS_286_386
# include "x86_ops_i686.h"
# include "x86_ops_mmx.h"
# include "x86_ops_mmx_arith.h"
# include "x86_ops_mmx_cmp.h"
# include "x86_ops_mmx_logic.h"
# include "x86_ops_mmx_mov.h"
# include "x86_ops_mmx_pack.h"
# include "x86_ops_mmx_shift.h"
#endif
#include "x86_ops_mov.h"
#include "x86_ops_mov_ctrl.h"
#include "x86_ops_mov_seg.h"
#include "x86_ops_movx.h"
#include "x86_ops_msr.h"
#ifndef OPS_286_386
# include "x86_ops_msr.h"
#endif
#include "x86_ops_mul.h"
#include "x86_ops_pmode.h"
#include "x86_ops_prefix.h"
#ifdef IS_DYNAREC
# include "x86_ops_rep_dyn.h"
#else
# include "x86_ops_rep.h"
# ifdef OPS_286_386
# include "x86_ops_rep_2386.h"
# else
# include "x86_ops_rep.h"
# endif
#endif
#include "x86_ops_ret.h"
#include "x86_ops_set.h"
#include "x86_ops_stack.h"
#include "x86_ops_string.h"
#ifdef OPS_286_386
# include "x86_ops_string_2386.h"
#else
# include "x86_ops_string.h"
#endif
#include "x86_ops_xchg.h"
#include "x86_ops_call.h"
#include "x86_ops_shift.h"
#include "x86_ops_amd.h"
#include "x86_ops_3dnow.h"
#ifndef OPS_286_386
# include "x86_ops_amd.h"
# include "x86_ops_3dnow.h"
#endif
#include <time.h>
#ifndef OPS_286_386
static int
opVPCEXT(uint32_t fetchdat)
{
@@ -331,7 +348,54 @@ opVPCEXT(uint32_t fetchdat)
return 1;
}
#endif
#ifdef OPS_286_386
static int
op0F_w_a16(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
fopcode = opcode;
cpu_state.pc++;
PREFETCH_PREFIX();
return x86_2386_opcodes_0f[opcode](fetchdat >> 8);
}
static int
op0F_l_a16(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
fopcode = opcode;
cpu_state.pc++;
PREFETCH_PREFIX();
return x86_2386_opcodes_0f[opcode | 0x100](fetchdat >> 8);
}
static int
op0F_w_a32(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
fopcode = opcode;
cpu_state.pc++;
PREFETCH_PREFIX();
return x86_2386_opcodes_0f[opcode | 0x200](fetchdat >> 8);
}
static int
op0F_l_a32(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
fopcode = opcode;
cpu_state.pc++;
PREFETCH_PREFIX();
return x86_2386_opcodes_0f[opcode | 0x300](fetchdat >> 8);
}
#else
static int
op0F_w_a16(uint32_t fetchdat)
{
@@ -376,6 +440,7 @@ op0F_l_a32(uint32_t fetchdat)
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
}
#endif
const OpFn OP_TABLE(186_0f)[1024] = {
// clang-format off
@@ -745,6 +810,7 @@ const OpFn OP_TABLE(486_0f)[1024] = {
// clang-format on
};
#ifndef OPS_286_386
const OpFn OP_TABLE(c486_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -928,6 +994,7 @@ const OpFn OP_TABLE(stpc_0f)[1024] = {
/*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(ibm486_0f)[1024] = {
// clang-format off
@@ -1021,6 +1088,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = {
// clang-format on
};
#ifndef OPS_286_386
const OpFn OP_TABLE(winchip_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1297,7 +1365,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = {
// clang-format on
};
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
const OpFn OP_TABLE(c6x86_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1389,7 +1457,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = {
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
// clang-format on
};
#endif
# endif
const OpFn OP_TABLE(pentiummmx_0f)[1024] = {
// clang-format off
@@ -1667,7 +1735,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = {
// clang-format on
};
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1759,7 +1827,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*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
# endif
const OpFn OP_TABLE(pentiumpro_0f)[1024] = {
// clang-format off
@@ -2036,6 +2104,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = {
/*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(186)[1024] = {
// clang-format off

View File

@@ -19,15 +19,21 @@
#include <86box/timer.h>
#include <86box/i8080.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
static int completed = 1;
static int in_rep = 0, repeating = 0, rep_c_flag = 0;
static int oldc, cycdiff;
static int completed = 1;
static int in_rep = 0;
static int repeating = 0;
static int rep_c_flag = 0;
static int oldc;
static int cycdiff;
#ifdef UNUSED_8080_VARS
static int prefetching = 1;
static int refresh = 0, clear_lock = 0;
static int refresh = 0;
static int clear_lock = 0;
static uint32_t cpu_src = 0, cpu_dest = 0;
static uint32_t cpu_src = 0;
static uint32_t cpu_dest = 0;
static uint32_t cpu_data = 0;
#endif
@@ -43,7 +49,7 @@ 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. */
tsc += (uint64_t) diff * (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();
}
@@ -237,7 +243,7 @@ setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val)
}
void
interpret_exec8080(i8080 *cpu, uint8_t opcode)
interpret_exec8080(UNUSED(i8080 *cpu), uint8_t opcode)
{
switch (opcode) {
case 0x00:

View File

@@ -35,6 +35,8 @@
#include <86box/ppi.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
/* Is the CPU 8088 or 8086. */
int is8086 = 0;
@@ -46,7 +48,8 @@ uint32_t custom_nmi_vector = 0x00000000;
static uint8_t pfq[6];
/* Variables to aid with the prefetch queue operation. */
static int biu_cycles = 0, pfq_pos = 0;
static int biu_cycles = 0;
static int pfq_pos = 0;
/* The IP equivalent of the current prefetch queue position. */
static uint16_t pfq_ip;
@@ -57,43 +60,50 @@ static x86seg *_opseg[4];
static int noint = 0;
static int in_lock = 0;
static int cpu_alu_op, pfq_size;
static int cpu_alu_op;
static int pfq_size;
static uint32_t cpu_src = 0, cpu_dest = 0;
static uint32_t cpu_src = 0;
static uint32_t cpu_dest = 0;
static uint32_t cpu_data = 0;
static uint16_t last_addr = 0x0000;
static uint32_t *ovr_seg = NULL;
static int prefetching = 1, completed = 1;
static int in_rep = 0, repeating = 0, rep_c_flag = 0;
static int oldc, clear_lock = 0;
static int refresh = 0, cycdiff;
static int prefetching = 1;
static int completed = 1;
static int in_rep = 0;
static int repeating = 0;
static int rep_c_flag = 0;
static int oldc;
static int clear_lock = 0;
static int refresh = 0;
static int cycdiff;
static int access_code = 0;
static int hlda = 0;
static int not_ready = 0;
static int bus_request_type = 0;
static int pic_data = -1;
static int last_was_code = 0;
static uint16_t mem_data = 0;
static uint32_t mem_seg = 0;
static uint16_t mem_addr = 0;
static int schedule_fetch = 1;
static int pasv = 0;
static int access_code = 0;
static int hlda = 0;
static int not_ready = 0;
static int bus_request_type = 0;
static int pic_data = -1;
static int last_was_code = 0;
static uint16_t mem_data = 0;
static uint32_t mem_seg = 0;
static uint16_t mem_addr = 0;
static int schedule_fetch = 1;
static int pasv = 0;
#define BUS_OUT 1
#define BUS_HIGH 2
#define BUS_WIDE 4
#define BUS_CODE 8
#define BUS_IO 16
#define BUS_MEM 32
#define BUS_PIC 64
#define BUS_OUT 1
#define BUS_HIGH 2
#define BUS_WIDE 4
#define BUS_CODE 8
#define BUS_IO 16
#define BUS_MEM 32
#define BUS_PIC 64
#define BUS_ACCESS_TYPE (BUS_CODE | BUS_IO | BUS_MEM | BUS_PIC)
#define BUS_CYCLE (biu_cycles & 3)
#define BUS_CYCLE_T1 biu_cycles = 0
#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3
#define BUS_CYCLE (biu_cycles & 3)
#define BUS_CYCLE_T1 biu_cycles = 0
#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3
enum {
BUS_T1 = 0,
@@ -204,14 +214,14 @@ 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. */
tsc += ((uint64_t) diff * (xt_cpu_multi >> 32ULL)); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
timer_process();
}
static void
process_timers(void)
{
{
clock_end();
clock_start();
}
@@ -248,7 +258,7 @@ bus_outw(uint16_t port, uint16_t val)
static uint8_t
bus_inb(uint16_t port)
{
int old_cycles = cycles;
int old_cycles = cycles;
uint8_t ret;
cycles--;
@@ -261,7 +271,7 @@ bus_inb(uint16_t port)
static uint16_t
bus_inw(uint16_t port)
{
int old_cycles = cycles;
int old_cycles = cycles;
uint16_t ret;
cycles--;
@@ -367,7 +377,7 @@ run_bus_cycle(int io_type)
not_ready = 0;
}
switch(BUS_CYCLE) {
switch (BUS_CYCLE) {
case BUS_T1:
access_code = !!(io_type & BUS_CODE);
break;
@@ -384,7 +394,7 @@ run_bus_cycle(int io_type)
bus_do_mem(io_type);
break;
case BUS_PIC:
pic_data = pic_irq_ack();
pic_data = pic_irq_ack();
last_was_code = 0;
break;
default:
@@ -423,9 +433,7 @@ run_dma_cycle(int idle)
static void
cycles_idle(int c)
{
int d;
for (d = 0; d < c; d++) {
for (int d = 0; d < c; d++) {
x808x_log("[%04X:%04X] %02X TI\n", CS, cpu_state.pc, opcode);
cycles_forward(1);
@@ -447,17 +455,20 @@ cycles_biu(int bus, int init)
switch (BUS_CYCLE) {
case BUS_T1:
case BUS_T2:
BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */
BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */
break;
case BUS_T3:
case BUS_T4:
cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */
BUS_CYCLE_T1; /* Abort the prefetch. */
cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */
BUS_CYCLE_T1; /* Abort the prefetch. */
break;
default:
break;
}
schedule_fetch = 0;
access_code = 0;
access_code = 0;
}
}
@@ -500,14 +511,12 @@ bus_init(void)
static void
wait(int c, int bus)
{
int d;
if (c < 0)
pclog("Negative cycles: %i!\n", c);
x808x_log("[%04X:%04X] %02X %i cycles (%i)\n", CS, cpu_state.pc, opcode, c, bus);
for (d = 0; d < c; d++) {
for (int d = 0; d < c; d++) {
x808x_log("[%04X:%04X] %02X cycle %i BIU\n", CS, cpu_state.pc, opcode, d);
cycles_biu(bus, !d);
x808x_log("[%04X:%04X] %02X cycle %i EU\n", CS, cpu_state.pc, opcode, d);
@@ -530,12 +539,12 @@ sub_cycles(int c)
void
resub_cycles(int old_cycles)
{
int i, cyc_diff = 0;
int cyc_diff = 0;
if (old_cycles > cycles) {
cyc_diff = old_cycles - cycles;
for (i = 0; i < cyc_diff; i++) {
for (int i = 0; i < cyc_diff; i++) {
if (not_ready > 0)
not_ready--;
}
@@ -564,7 +573,7 @@ cpu_io(int bits, int out, uint16_t port)
} else {
bus_request_type = BUS_IO | BUS_OUT;
wait(4, 1);
schedule_fetch = 0;
schedule_fetch = 0;
bus_request_type = BUS_IO | BUS_OUT | BUS_HIGH;
wait(4, 1);
}
@@ -580,7 +589,7 @@ cpu_io(int bits, int out, uint16_t port)
} else {
bus_request_type = BUS_IO;
wait(4, 1);
schedule_fetch = 0;
schedule_fetch = 0;
bus_request_type = BUS_IO | BUS_HIGH;
wait(4, 1);
}
@@ -603,11 +612,11 @@ readmemb(uint32_t s, uint16_t a)
bus_init();
#endif
mem_seg = s;
mem_addr = a;
mem_seg = s;
mem_addr = a;
bus_request_type = BUS_MEM;
wait(4, 1);
ret = mem_data & 0xff;
ret = mem_data & 0xff;
bus_request_type = 0;
return ret;
@@ -637,7 +646,7 @@ readmemw(uint32_t s, uint16_t a)
bus_init();
#endif
mem_seg = s;
mem_seg = s;
mem_addr = a;
if (is8086 && !(a & 1)) {
bus_request_type = BUS_MEM | BUS_WIDE;
@@ -645,11 +654,11 @@ readmemw(uint32_t s, uint16_t a)
} else {
bus_request_type = BUS_MEM | BUS_HIGH;
wait(4, 1);
schedule_fetch = 0;
schedule_fetch = 0;
bus_request_type = BUS_MEM;
wait(4, 1);
}
ret = mem_data;
ret = mem_data;
bus_request_type = 0;
return ret;
@@ -710,9 +719,9 @@ writememb(uint32_t s, uint32_t a, uint8_t v)
bus_init();
#endif
mem_seg = s;
mem_addr = a;
mem_data = v;
mem_seg = s;
mem_addr = a;
mem_data = v;
bus_request_type = BUS_MEM | BUS_OUT;
wait(4, 1);
bus_request_type = 0;
@@ -731,7 +740,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
bus_init();
#endif
mem_seg = s;
mem_seg = s;
mem_addr = a;
mem_data = v;
if (is8086 && !(a & 1)) {
@@ -740,7 +749,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
} else {
bus_request_type = BUS_MEM | BUS_OUT | BUS_HIGH;
wait(4, 1);
schedule_fetch = 0;
schedule_fetch = 0;
bus_request_type = BUS_MEM | BUS_OUT;
wait(4, 1);
}
@@ -785,13 +794,13 @@ pfq_write(void)
free in the queue. */
tempw = readmemwf(pfq_ip);
*(uint16_t *) &(pfq[pfq_pos]) = tempw;
pfq_ip = (pfq_ip + 2) & 0xffff;
pfq_ip = (pfq_ip + 2) & 0xffff;
pfq_pos += 2;
} else if (!fetch_word && (pfq_pos < pfq_size)) {
/* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte
free in the queue. */
pfq[pfq_pos] = readmembf(pfq_ip);
pfq_ip = (pfq_ip + 1) & 0xffff;
pfq_ip = (pfq_ip + 1) & 0xffff;
pfq_pos++;
}
@@ -884,8 +893,8 @@ pfq_add(void)
static void
pfq_clear(void)
{
pfq_pos = 0;
prefetching = 0;
pfq_pos = 0;
prefetching = 0;
schedule_fetch = 0;
BUS_CYCLE_T1;
@@ -894,8 +903,8 @@ pfq_clear(void)
static void
pfq_suspend(void)
{
pfq_clear();
cycles_idle(3);
pfq_clear();
cycles_idle(3);
}
static void
@@ -934,7 +943,7 @@ reset_808x(int hard)
_opseg[2] = &cpu_state.seg_ss;
_opseg[3] = &cpu_state.seg_ds;
pfq_size = (is8086) ? 6 : 4;
pfq_size = is8086 ? 6 : 4;
pfq_clear();
}
@@ -949,20 +958,20 @@ reset_808x(int hard)
schedule_fetch = 1;
pasv = 0;
cpu_alu_op = 0;
cpu_alu_op = 0;
use_custom_nmi_vector = 0x00;
custom_nmi_vector = 0x00000000;
access_code = 0;
hlda = 0;
not_ready = 0;
bus_request_type = 0;
pic_data = -1;
last_was_code = 0;
mem_data = 0;
mem_seg = 0;
mem_addr = 0;
access_code = 0;
hlda = 0;
not_ready = 0;
bus_request_type = 0;
pic_data = -1;
last_was_code = 0;
mem_data = 0;
mem_seg = 0;
mem_addr = 0;
}
static void
@@ -970,7 +979,7 @@ set_ip(uint16_t new_ip)
{
pfq_ip = cpu_state.pc = new_ip;
prefetching = 1;
schedule_fetch = prefetching && (pfq_pos < pfq_size);
schedule_fetch = prefetching && (pfq_pos < pfq_size);
}
/* Memory refresh read - called by reads and writes on DMA channel 0. */
@@ -1019,16 +1028,20 @@ do_mod_rm(void)
easeg = ovr_seg ? *ovr_seg : ds;
wait(2, 0);
return;
} else switch (cpu_rm) {
case 0:
case 3:
wait(2, 0);
break;
case 1:
case 2:
wait(3, 0);
break;
}
} else
switch (cpu_rm) {
case 0:
case 3:
wait(2, 0);
break;
case 1:
case 2:
wait(3, 0);
break;
default:
break;
}
cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm];
switch (rmdat & 0xc0) {
@@ -1042,6 +1055,8 @@ do_mod_rm(void)
cpu_state.eaaddr += pfq_fetchw();
wait(1, 0);
break;
default:
break;
}
cpu_state.eaaddr &= 0xffff;
wait(2, 0);
@@ -1205,18 +1220,20 @@ pop(void)
static void
interrupt(uint16_t addr)
{
uint16_t old_cs, old_ip;
uint16_t new_cs, new_ip;
uint16_t old_cs;
uint16_t old_ip;
uint16_t new_cs;
uint16_t new_ip;
uint16_t tempf;
addr <<= 2;
cpu_state.eaaddr = addr;
old_cs = CS;
new_ip = readmemw(0, cpu_state.eaaddr);
new_ip = readmemw(0, cpu_state.eaaddr);
wait(1, 0);
cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff;
new_cs = readmemw(0, cpu_state.eaaddr);
prefetching = 0;
new_cs = readmemw(0, cpu_state.eaaddr);
prefetching = 0;
pfq_clear();
ovr_seg = NULL;
wait(2, 0);
@@ -1242,8 +1259,10 @@ interrupt_808x(uint16_t addr)
static void
custom_nmi(void)
{
uint16_t old_cs, old_ip;
uint16_t new_cs, new_ip;
uint16_t old_cs;
uint16_t old_ip;
uint16_t new_cs;
uint16_t new_ip;
uint16_t tempf;
cpu_state.eaaddr = 0x0002;
@@ -1286,7 +1305,7 @@ bus_pic_ack(void)
{
int old_in_lock = in_lock;
in_lock = 1;
in_lock = 1;
bus_request_type = BUS_PIC;
wait(4, 1);
in_lock = old_in_lock;
@@ -1366,7 +1385,7 @@ rep_interrupt(void)
return 0;
}
completed = 1;
CX = tmpc;
CX = tmpc;
pfq_clear();
if (is_nec && (ovr_seg != NULL))
set_ip(cpu_state.pc - 3);
@@ -1376,7 +1395,7 @@ rep_interrupt(void)
}
static int
rep_action(int bits)
rep_action(UNUSED(int bits))
{
uint16_t t;
@@ -1562,14 +1581,14 @@ alu_op(int bits)
case 2:
if (cpu_state.flags & C_FLAG)
cpu_src++;
/* Fall through. */
fallthrough;
case 0:
add(bits);
break;
case 3:
if (cpu_state.flags & C_FLAG)
cpu_src++;
/* Fall through. */
fallthrough;
case 5:
case 7:
sub(bits);
@@ -1580,6 +1599,9 @@ alu_op(int bits)
case 6:
bitwise(bits, (cpu_dest ^ cpu_src));
break;
default:
break;
}
}
@@ -1600,10 +1622,11 @@ mul(uint16_t a, uint16_t b)
{
int negate = 0;
int bit_count = 8;
int carry, i;
int carry;
uint16_t high_bit = 0x80;
uint16_t size_mask;
uint16_t c, r;
uint16_t c;
uint16_t r;
size_mask = (1 << bit_count) - 1;
@@ -1644,7 +1667,7 @@ mul(uint16_t a, uint16_t b)
a &= size_mask;
carry = (a & 1) != 0;
a >>= 1;
for (i = 0; i < bit_count; ++i) {
for (int i = 0; i < bit_count; ++i) {
wait(7, 0);
if (carry) {
cpu_src = c;
@@ -1705,7 +1728,7 @@ set_pzs(int bits)
}
static void
set_co_mul(int bits, int carry)
set_co_mul(UNUSED(int bits), int carry)
{
set_cf(carry);
set_of(carry);
@@ -1718,10 +1741,11 @@ set_co_mul(int bits, int carry)
static int
x86_div(uint16_t l, uint16_t h)
{
int b, bit_count = 8;
int bit_count = 8;
int negative = 0;
int dividend_negative = 0;
int size_mask, carry;
int size_mask;
int carry;
uint16_t r;
if (opcode & 1) {
@@ -1765,7 +1789,7 @@ x86_div(uint16_t l, uint16_t h)
wait(1, 0);
wait(2, 0);
carry = 1;
for (b = 0; b < bit_count; ++b) {
for (int b = 0; b < bit_count; ++b) {
r = (l << 1) + (carry ? 1 : 0);
carry = top_bit(l, bit_count);
l = r;
@@ -1948,20 +1972,46 @@ cpu_outw(uint16_t port, uint16_t val)
void
execx86(int cycs)
{
uint8_t temp = 0, temp2, old_af, nests;
uint8_t temp_val, temp_al, bit, handled = 0;
uint8_t odd, zero, nibbles_count, destcmp;
uint8_t destbyte, srcbyte, nibble_result, bit_length;
uint8_t temp = 0;
uint8_t temp2;
uint8_t old_af;
uint8_t nests;
uint8_t temp_val;
uint8_t temp_al;
uint8_t bit;
uint8_t handled = 0;
uint8_t odd;
uint8_t zero;
uint8_t nibbles_count;
uint8_t destcmp;
uint8_t destbyte;
uint8_t srcbyte;
uint8_t nibble_result;
uint8_t bit_length;
uint8_t bit_offset;
int8_t nibble_result_s;
uint16_t addr, tempw, new_cs, new_ip;
uint16_t tempw_int, size, tempbp, lowbound;
uint16_t highbound, regval, orig_sp, wordtopush;
uint16_t immediate, old_flags;
uint16_t tmpa;
uint16_t addr;
uint16_t tempw;
uint16_t new_cs;
uint16_t new_ip;
uint16_t tempw_int;
uint16_t size;
uint16_t tempbp;
uint16_t lowbound;
uint16_t highbound;
uint16_t regval;
uint16_t orig_sp;
uint16_t wordtopush;
uint16_t immediate;
uint16_t old_flags;
uint16_t tmpa;
int bits;
uint32_t dest_seg, i, carry, nibble;
uint32_t srcseg, byteaddr;
uint32_t dest_seg;
uint32_t i;
uint32_t carry;
uint32_t nibble;
uint32_t srcseg;
uint32_t byteaddr;
cycles += cycs;
@@ -1970,10 +2020,12 @@ execx86(int cycs)
if (!repeating) {
cpu_state.oldpc = cpu_state.pc;
// opcode = pfq_fetchb();
opcode = pfq_fetchb_common();
handled = 0;
oldc = cpu_state.flags & C_FLAG;
#if 0
opcode = pfq_fetchb();
#endif
opcode = pfq_fetchb_common();
handled = 0;
oldc = cpu_state.flags & C_FLAG;
if (clear_lock) {
in_lock = 0;
clear_lock = 0;
@@ -2233,6 +2285,9 @@ execx86(int cycs)
set_af(0);
set_pzs(bits);
break;
default:
break;
}
if ((opcode & 2) != 0)
wait(4, 0);
@@ -2247,6 +2302,9 @@ execx86(int cycs)
BP = pop();
handled = 1;
break;
default:
break;
}
}
if (!handled) {
@@ -2498,7 +2556,7 @@ execx86(int cycs)
}
for (i = 0; i < bit_length; i++) {
byteaddr = (es) + DI;
writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << (bit_offset))) | ((!!(AX & (1 << i))) << bit_offset));
writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << bit_offset)) | ((!!(AX & (1 << i))) << bit_offset));
bit_offset++;
if (bit_offset == 8) {
DI++;
@@ -2547,7 +2605,7 @@ execx86(int cycs)
break;
default:
opcode = orig_opcode;
opcode = orig_opcode;
cpu_state.pc = (cpu_state.pc - 1) & 0xffff;
break;
}
@@ -3063,7 +3121,7 @@ execx86(int cycs)
bits = 8 << (opcode & 1);
wait(2, 0);
cpu_state.eaaddr = pfq_fetchw();
set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds)));
set_accum(bits, readmem(ovr_seg ? *ovr_seg : ds));
break;
case 0xA2:
case 0xA3:
@@ -3125,7 +3183,7 @@ execx86(int cycs)
wait(2, 0);
cpu_state.eaaddr = DI;
cpu_data = readmem(es);
DI = string_increment(bits);
DI = string_increment(bits);
cpu_src = cpu_data;
cpu_dest = tmpa;
sub(bits);
@@ -3392,6 +3450,9 @@ execx86(int cycs)
set_af(0);
set_pzs(bits);
break;
default:
break;
}
if ((opcode & 2) != 0)
wait(4, 0);
@@ -3453,55 +3514,61 @@ execx86(int cycs)
if (fpu_softfloat) {
switch (opcode) {
case 0xD8:
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
break;
case 0xD9:
ops_sf_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat);
break;
case 0xDA:
ops_sf_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_da[rmdat & 0xff](rmdat);
break;
case 0xDB:
ops_sf_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_db[rmdat & 0xff](rmdat);
break;
case 0xDC:
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
break;
case 0xDD:
ops_sf_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat);
break;
case 0xDE:
ops_sf_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_de[rmdat & 0xff](rmdat);
break;
case 0xDF:
ops_sf_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
ops_sf_fpu_8087_df[rmdat & 0xff](rmdat);
break;
default:
break;
}
} else {
switch (opcode) {
case 0xD8:
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
break;
case 0xD9:
ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_d9[rmdat & 0xff](rmdat);
break;
case 0xDA:
ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_da[rmdat & 0xff](rmdat);
break;
case 0xDB:
ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_db[rmdat & 0xff](rmdat);
break;
case 0xDC:
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
break;
case 0xDD:
ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_dd[rmdat & 0xff](rmdat);
break;
case 0xDE:
ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_de[rmdat & 0xff](rmdat);
break;
case 0xDF:
ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
ops_fpu_8087_df[rmdat & 0xff](rmdat);
break;
default:
break;
}
}
@@ -3531,6 +3598,9 @@ execx86(int cycs)
if (!(cpu_state.flags & Z_FLAG))
oldc = 0;
break;
default:
break;
}
} else
oldc = (CX == 0);
@@ -3542,7 +3612,7 @@ execx86(int cycs)
case 0xE5:
bits = 8 << (opcode & 1);
wait(1, 0);
cpu_data = pfq_fetchb();
cpu_data = pfq_fetchb();
cpu_state.eaaddr = cpu_data;
wait(1, 0);
cpu_io(bits, 0, cpu_state.eaaddr);
@@ -3551,16 +3621,16 @@ execx86(int cycs)
case 0xE7:
bits = 8 << (opcode & 1);
wait(1, 0);
cpu_data = pfq_fetchb();
cpu_data = pfq_fetchb();
cpu_state.eaaddr = cpu_data;
cpu_data = (bits == 16) ? AX : AL;
cpu_data = (bits == 16) ? AX : AL;
wait(2, 0);
cpu_io(bits, 1, cpu_state.eaaddr);
break;
case 0xEC:
case 0xED:
bits = 8 << (opcode & 1);
cpu_data = DX;
bits = 8 << (opcode & 1);
cpu_data = DX;
cpu_state.eaaddr = cpu_data;
wait(1, 0);
cpu_io(bits, 0, cpu_state.eaaddr);
@@ -3569,9 +3639,9 @@ execx86(int cycs)
case 0xEF:
bits = 8 << (opcode & 1);
wait(2, 0);
cpu_data = DX;
cpu_data = DX;
cpu_state.eaaddr = cpu_data;
cpu_data = (bits == 16) ? AX : AL;
cpu_data = (bits == 16) ? AX : AL;
cpu_io(bits, 1, cpu_state.eaaddr);
wait(1, 0);
break;
@@ -3703,6 +3773,9 @@ execx86(int cycs)
if (x86_div(AL, AH))
wait(1, 0);
break;
default:
break;
}
break;
@@ -3800,7 +3873,10 @@ execx86(int cycs)
if (cpu_mod != 3)
wait(1, 0);
wait(4, 0);
push((uint16_t *) &(cpu_data));
push((uint16_t *) &cpu_data);
break;
default:
break;
}
break;

View File

@@ -15,6 +15,7 @@
* Copyright 2023 gloriouscow.
* Copyright 2023 Miran Grca.
*/
#include <inttypes.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
@@ -41,12 +42,13 @@
/* TODO: Move to cpu.h so this can eventually be reused for 286+ as well. */
#define QUEUE_MAX 6
typedef struct queue_t
{
size_t size;
size_t len;
size_t back;
size_t front;
/* NOTE: When porting from Rust to C, please use uintptr_t and not size_t,
so it can be printed with PRIuPTR. */
typedef struct queue_t {
uintptr_t size;
uintptr_t len;
uintptr_t back;
uintptr_t front;
uint8_t q[QUEUE_MAX];
uint16_t preload;
queue_delay_t delay;
@@ -73,15 +75,15 @@ queue_log(const char *fmt, ...)
#endif
void
queue_set_size(size_t size)
queue_set_size(uintptr_t size)
{
if (size > QUEUE_MAX)
fatal("Requested prefetch queue of %i bytes is too big\n", size);
fatal("Requested prefetch queue of %" PRIuPTR " bytes is too big\n", size);
queue.size = size;
}
size_t
uintptr_t
queue_get_len(void)
{
return queue.len;

View File

@@ -17,27 +17,26 @@
#ifndef EMU_QUEUE_H
#define EMU_QUEUE_H
typedef enum queue_delay_t
{
typedef enum queue_delay_t {
DELAY_READ,
DELAY_WRITE,
DELAY_NONE
} queue_delay_t;
#define FLAG_PRELOADED 0x8000
#define FLAG_PRELOADED 0x8000
extern void queue_set_size(size_t size);
extern size_t queue_get_len(void);
extern int queue_is_full(void);
extern uint16_t queue_get_preload(void);
extern int queue_has_preload(void);
extern void queue_set_preload(void);
extern void queue_push8(uint8_t byte);
extern void queue_push16(uint16_t word);
extern uint8_t queue_pop(void);
extern queue_delay_t queue_get_delay(void);
extern void queue_flush(void);
extern void queue_set_size(uintptr_t size);
extern uintptr_t queue_get_len(void);
extern int queue_is_full(void);
extern uint16_t queue_get_preload(void);
extern int queue_has_preload(void);
extern void queue_set_preload(void);
extern void queue_push8(uint8_t byte);
extern void queue_push16(uint16_t word);
extern uint8_t queue_pop(void);
extern queue_delay_t queue_get_delay(void);
extern void queue_flush(void);
extern void queue_init(void);
extern void queue_init(void);
#endif /*EMU_QUEUE_H*/

View File

@@ -3,8 +3,10 @@
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/mem.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
@@ -12,11 +14,11 @@
#include "codegen_ops.h"
#include "codegen_timing_common.h"
#define CYCLES(c) (int *)c
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
static int *opcode_timings[256] =
{
static int *opcode_timings[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
@@ -36,10 +38,11 @@ static int *opcode_timings[256] =
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
// clang-format on
};
static int *opcode_timings_mod3[256] =
{
static int *opcode_timings_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
@@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] =
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
// clang-format on
};
static int *opcode_timings_0f[256] =
{
static int *opcode_timings_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] =
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
static int *opcode_timings_0f_mod3[256] =
{
static int *opcode_timings_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -104,60 +109,69 @@ static int *opcode_timings_0f_mod3[256] =
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
// clang-format on
};
static int *opcode_timings_shift[8] =
{
static int *opcode_timings_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
};
static int *opcode_timings_shift_mod3[8] =
{
static int *opcode_timings_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
static int *opcode_timings_f6[8] =
{
static int *opcode_timings_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f6_mod3[8] =
{
static int *opcode_timings_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f7[8] =
{
static int *opcode_timings_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_f7_mod3[8] =
{
static int *opcode_timings_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
};
static int *opcode_timings_ff[8] =
{
static int *opcode_timings_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
};
static int *opcode_timings_ff_mod3[8] =
{
static int *opcode_timings_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_d8[8] =
{
static int *opcode_timings_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_d8_mod3[8] =
{
static int *opcode_timings_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_d9[8] =
{
static int *opcode_timings_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
static int *opcode_timings_d9_mod3[64] =
{
static int *opcode_timings_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
/*FXCH*/
@@ -174,26 +188,29 @@ static int *opcode_timings_d9_mod3[64] =
CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3),
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257)
// clang-format on
};
static int *opcode_timings_da[8] =
{
static int *opcode_timings_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_da_mod3[8] =
{
static int *opcode_timings_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
static int *opcode_timings_db[8] =
{
static int *opcode_timings_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6)
// clang-format on
};
static int *opcode_timings_db_mod3[64] =
{
static int *opcode_timings_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -203,219 +220,242 @@ static int *opcode_timings_db_mod3[64] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};
static int *opcode_timings_dc[8] =
{
static int *opcode_timings_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_dc_mod3[8] =
{
static int *opcode_timings_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_dd[8] =
{
static int *opcode_timings_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3)
// clang-format on
};
static int *opcode_timings_dd_mod3[8] =
{
static int *opcode_timings_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
static int *opcode_timings_de[8] =
{
static int *opcode_timings_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_de_mod3[8] =
{
static int *opcode_timings_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_df[8] =
{
static int *opcode_timings_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28)
// clang-format on
};
static int *opcode_timings_df_mod3[8] =
{
static int *opcode_timings_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
static int *opcode_timings_8x[8] =
{
static int *opcode_timings_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_8x_mod3[8] =
{
static int *opcode_timings_8x_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_81[8] =
{
static int *opcode_timings_81[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_81_mod3[8] =
{
static int *opcode_timings_81_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int timing_count;
static uint8_t last_prefix;
static int timing_count;
static uint8_t last_prefix;
static uint32_t regmask_modified;
static inline int COUNT(int *c, int op_32)
static inline int
COUNT(int *c, int op_32)
{
if ((uintptr_t)c <= 10000)
return (int)(uintptr_t)c;
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
{
if (op_32 & 0x100)
return ((uintptr_t)c >> 8) & 0xff;
return (uintptr_t)c & 0xff;
}
return *c;
if ((uintptr_t) c <= 10000)
return (int) (uintptr_t) c;
if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) {
if (op_32 & 0x100)
return ((uintptr_t) c >> 8) & 0xff;
return (uintptr_t) c & 0xff;
}
return *c;
}
void codegen_timing_486_block_start(void)
void
codegen_timing_486_block_start(void)
{
regmask_modified = 0;
regmask_modified = 0;
}
void codegen_timing_486_start(void)
void
codegen_timing_486_start(void)
{
timing_count = 0;
last_prefix = 0;
timing_count = 0;
last_prefix = 0;
}
void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
void
codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
{
timing_count += COUNT(opcode_timings[prefix], 0);
last_prefix = prefix;
timing_count += COUNT(opcode_timings[prefix], 0);
last_prefix = prefix;
}
void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
void
codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
{
int **timings;
uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
int **timings;
const uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
switch (last_prefix)
{
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
default:
switch (opcode) {
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
case 0xc0:
case 0xc1:
case 0xd0:
case 0xd1:
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
switch (opcode)
{
case 0x80: case 0x82: case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
}
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
timing_count += COUNT(timings[opcode], op_32);
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
timing_count++; /*AGI stall*/
codegen_block_cycles += timing_count;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
}
timing_count += COUNT(timings[opcode], op_32);
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
timing_count++; /*AGI stall*/
codegen_block_cycles += timing_count;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
}
void codegen_timing_486_block_end(void)
void
codegen_timing_486_block_end(void)
{
//
}
codegen_timing_t codegen_timing_486 =
{
codegen_timing_486_start,
codegen_timing_486_prefix,
codegen_timing_486_opcode,
codegen_timing_486_block_start,
codegen_timing_486_block_end,
NULL
codegen_timing_t codegen_timing_486 = {
codegen_timing_486_start,
codegen_timing_486_prefix,
codegen_timing_486_opcode,
codegen_timing_486_block_start,
codegen_timing_486_block_end,
NULL
};

View File

@@ -13,8 +13,10 @@
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/mem.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
@@ -22,7 +24,7 @@
#include "codegen_timing_common.h"
/*Instruction has different execution time for 16 and 32 bit data. Does not pair */
#define CYCLES_HAS_MULTI (1 << 31)
#define CYCLES_HAS_MULTI (1 << 31)
#define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8))
@@ -31,39 +33,39 @@
/*Instruction follows either register timing, read-modify, or read-modify-write.
May be pairable*/
#define CYCLES_REG (1 << 0)
#define CYCLES_RM (1 << 0)
#define CYCLES_RMW (1 << 0)
#define CYCLES_REG (1 << 0)
#define CYCLES_RM (1 << 0)
#define CYCLES_RMW (1 << 0)
#define CYCLES_BRANCH (1 << 0)
#define CYCLES_MASK ((1 << 7) - 1)
#define CYCLES_MASK ((1 << 7) - 1)
/*Instruction does not pair*/
#define PAIR_NP (0 << 29)
/*Instruction pairs in X pipe only*/
#define PAIR_X (1 << 29)
#define PAIR_X (1 << 29)
/*Instruction pairs in X pipe only, and can not pair with a following instruction*/
#define PAIR_X_BRANCH (2 << 29)
#define PAIR_X_BRANCH (2 << 29)
/*Instruction pairs in both X and Y pipes*/
#define PAIR_XY (3 << 29)
#define PAIR_XY (3 << 29)
#define PAIR_MASK (3 << 29)
#define INVALID 0
#define INVALID 0
static int prev_full;
static uint32_t prev_opcode;
static int prev_full;
static uint32_t prev_opcode;
static uint32_t *prev_timings;
static uint32_t prev_op_32;
static uint32_t prev_regmask;
static uint32_t prev_op_32;
static uint32_t prev_regmask;
static uint64_t *prev_deps;
static uint32_t prev_fetchdat;
static uint32_t prev_fetchdat;
static uint32_t last_regmask_modified;
static uint32_t regmask_modified;
static uint32_t opcode_timings[256] =
{
static uint32_t opcode_timings[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
/* ADD ADD PUSH ES POP ES*/
@@ -196,10 +198,11 @@ static uint32_t opcode_timings[256] =
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7),
/* CLD STD INCDEC*/
PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_RMW, INVALID
// clang-format on
};
static uint32_t opcode_timings_mod3[256] =
{
static uint32_t opcode_timings_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
/* ADD ADD PUSH ES POP ES*/
@@ -333,10 +336,11 @@ static uint32_t opcode_timings_mod3[256] =
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7),
/* CLD STD INCDEC*/
PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_REG, INVALID
// clang-format on
};
static uint32_t opcode_timings_0f[256] =
{
static uint32_t opcode_timings_0f[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID,
@@ -416,9 +420,10 @@ static uint32_t opcode_timings_0f[256] =
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
// clang-format on
};
static uint32_t opcode_timings_0f_mod3[256] =
{
static uint32_t opcode_timings_0f_mod3[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID,
@@ -497,106 +502,122 @@ static uint32_t opcode_timings_0f_mod3[256] =
INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID,
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
// clang-format on
};
static uint32_t opcode_timings_shift[8] =
{
static uint32_t opcode_timings_shift[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
static uint32_t opcode_timings_shift_mod3[8] =
{
static uint32_t opcode_timings_shift_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
static uint32_t opcode_timings_shift_imm[8] =
{
static uint32_t opcode_timings_shift_imm[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
static uint32_t opcode_timings_shift_imm_mod3[8] =
{
static uint32_t opcode_timings_shift_imm_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
static uint32_t opcode_timings_shift_cl[8] =
{
static uint32_t opcode_timings_shift_cl[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
static uint32_t opcode_timings_shift_cl_mod3[8] =
{
static uint32_t opcode_timings_shift_cl_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
static uint32_t opcode_timings_f6[8] =
{
static uint32_t opcode_timings_f6[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
/* MUL IMUL DIV IDIV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
static uint32_t opcode_timings_f6_mod3[8] =
{
static uint32_t opcode_timings_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
/* MUL IMUL DIV IDIV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
static uint32_t opcode_timings_f7[8] =
{
static uint32_t opcode_timings_f7[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
/* MUL IMUL DIV IDIV*/
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
static uint32_t opcode_timings_f7_mod3[8] =
{
static uint32_t opcode_timings_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
/* MUL IMUL DIV IDIV*/
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
static uint32_t opcode_timings_ff[8] =
{
static uint32_t opcode_timings_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5),
/* JMP JMP far PUSH*/
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID
// clang-format on
};
static uint32_t opcode_timings_ff_mod3[8] =
{
static uint32_t opcode_timings_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
/* JMP JMP far PUSH*/
PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID
// clang-format on
};
static uint32_t opcode_timings_d8[8] =
{
static uint32_t opcode_timings_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
/* FSUBs FSUBRs FDIVs FDIVRs*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_d8_mod3[8] =
{
static uint32_t opcode_timings_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
/* FSUB FSUBR FDIV FDIVR*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_d9[8] =
{
static uint32_t opcode_timings_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
/* FLDENV FLDCW FSTENV FSTCW*/
PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5)
// clang-format on
};
static uint32_t opcode_timings_d9_mod3[64] =
{
static uint32_t opcode_timings_d9_mod3[64] = {
// clang-format off
/*FLD*/
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -625,31 +646,34 @@ static uint32_t opcode_timings_d9_mod3[64] =
PAIR_X | CYCLES(91), INVALID, PAIR_X | CYCLES(60), PAIR_X | CYCLES(161),
/* opFRNDINT opFSCALE opFSIN opFCOS*/
PAIR_X | CYCLES(20), PAIR_X | CYCLES(14), PAIR_X | CYCLES(140), PAIR_X | CYCLES(141)
// clang-format on
};
static uint32_t opcode_timings_da[8] =
{
static uint32_t opcode_timings_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48)
// clang-format on
};
static uint32_t opcode_timings_da_mod3[8] =
{
static uint32_t opcode_timings_da_mod3[8] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
INVALID, PAIR_X | CYCLES(5), INVALID, INVALID
// clang-format on
};
static uint32_t opcode_timings_db[8] =
{
static uint32_t opcode_timings_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
/* FLDe FSTPe*/
INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_db_mod3[64] =
{
static uint32_t opcode_timings_db_mod3[64] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -675,383 +699,387 @@ static uint32_t opcode_timings_db_mod3[64] =
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
// clang-format on
};
static uint32_t opcode_timings_dc[8] =
{
static uint32_t opcode_timings_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7),
/* FSUBd FSUBRd FDIVd FDIVRd*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_dc_mod3[8] =
{
static uint32_t opcode_timings_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID,
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_dd[8] =
{
static uint32_t opcode_timings_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
/* FRSTOR FSAVE FSTSW*/
PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_dd_mod3[8] =
{
static uint32_t opcode_timings_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
/* FUCOM FUCOMP*/
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID
// clang-format on
};
static uint32_t opcode_timings_de[8] =
{
static uint32_t opcode_timings_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38)
};
static uint32_t opcode_timings_de_mod3[8] =
{
static uint32_t opcode_timings_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7),
/* FSUB FSUBR FDIV FDIVR*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_df[8] =
{
static uint32_t opcode_timings_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13),
/* FILDiq FBSTP FISTPiq*/
INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13)
// clang-format on
};
static uint32_t opcode_timings_df_mod3[8] =
{
static uint32_t opcode_timings_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
PAIR_X | CYCLES(6), INVALID, INVALID, INVALID
// clang-format on
};
static uint32_t opcode_timings_8x[8] =
{
static uint32_t opcode_timings_8x[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
static uint32_t opcode_timings_8x_mod3[8] =
{
static uint32_t opcode_timings_8x_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
// clang-format on
};
static uint32_t opcode_timings_81[8] =
{
static uint32_t opcode_timings_81[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
static uint32_t opcode_timings_81_mod3[8] =
{
static uint32_t opcode_timings_81_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
// clang-format on
};
static int decode_delay;
static int decode_delay;
static uint8_t last_prefix;
static inline int COUNT(uint32_t c, int op_32)
static inline int
COUNT(uint32_t c, int op_32)
{
if (c & CYCLES_HAS_MULTI)
{
if (op_32 & 0x100)
return ((uintptr_t)c >> 8) & 0xff;
return (uintptr_t)c & 0xff;
}
if (!(c & PAIR_MASK))
return c & 0xffff;
if (c & CYCLES_HAS_MULTI) {
if (op_32 & 0x100)
return ((uintptr_t) c >> 8) & 0xff;
return (uintptr_t) c & 0xff;
}
if (!(c & PAIR_MASK))
return c & 0xffff;
return c & CYCLES_MASK;
return c & CYCLES_MASK;
}
void codegen_timing_686_block_start(void)
void
codegen_timing_686_block_start(void)
{
prev_full = decode_delay = 0;
regmask_modified = last_regmask_modified = 0;
prev_full = decode_delay = 0;
regmask_modified = last_regmask_modified = 0;
}
void codegen_timing_686_start(void)
void
codegen_timing_686_start(void)
{
decode_delay = 0;
last_prefix = 0;
decode_delay = 0;
last_prefix = 0;
}
void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
void
codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
{
if ((prefix & 0xf8) == 0xd8)
{
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
{
/*0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;
return;
}
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
either instruction has more than one prefix then decode is delayed by
one cycle for each additional prefix*/
decode_delay++;
if ((prefix & 0xf8) == 0xd8) {
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) {
/*0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;
return;
}
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
either instruction has more than one prefix then decode is delayed by
one cycle for each additional prefix*/
decode_delay++;
last_prefix = prefix;
}
static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
static int
check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
{
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
if (addr_regmask & IMPL_ESP)
addr_regmask |= (1 << REG_ESP);
if (addr_regmask & IMPL_ESP)
addr_regmask |= (1 << REG_ESP);
if (regmask_modified & addr_regmask)
{
regmask_modified = 0;
return 2;
}
if (regmask_modified & addr_regmask) {
regmask_modified = 0;
return 2;
}
if (last_regmask_modified & addr_regmask)
return 1;
if (last_regmask_modified & addr_regmask)
return 1;
return 0;
return 0;
}
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
void
codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
{
uint32_t *timings;
uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
uint32_t *timings;
uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
switch (last_prefix)
{
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
default:
switch (opcode) {
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
case 0xc0:
case 0xc1:
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd0:
case 0xd1:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
switch (opcode)
{
case 0x80: case 0x82: case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
}
case 0xc0: case 0xc1:
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
/*One prefix per instruction is free*/
decode_delay--;
if (decode_delay < 0)
decode_delay = 0;
case 0xd0: case 0xd1:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
if (prev_full) {
uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32);
int agi_stall = 0;
case 0xd2: case 0xd3:
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
if (regmask & IMPL_ESP)
regmask |= SRCDEP_ESP | DSTDEP_ESP;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
/*Second instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP) {
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
} else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X) {
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
} else if (prev_regmask & regmask) {
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
} else {
int t1 = COUNT(prev_timings[prev_opcode], prev_op_32);
int t2 = COUNT(timings[opcode], op_32);
int t_pair = (t1 > t2) ? t1 : t2;
if (!t_pair)
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += t_pair + agi_stall;
decode_delay = (-t_pair) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
prev_full = 0;
return;
}
}
/*One prefix per instruction is free*/
decode_delay--;
if (decode_delay < 0)
decode_delay = 0;
if (!prev_full) {
/*First instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) {
/*Instruction not pairable*/
int agi_stall = 0;
if (prev_full)
{
uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32);
int agi_stall = 0;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
if (regmask & IMPL_ESP)
regmask |= SRCDEP_ESP | DSTDEP_ESP;
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
/*Second instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP)
{
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X)
{
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (prev_regmask & regmask)
{
/*Instruction can not pair with previous*/
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else
{
int t1 = COUNT(prev_timings[prev_opcode], prev_op_32);
int t2 = COUNT(timings[opcode], op_32);
int t_pair = (t1 > t2) ? t1 : t2;
if (!t_pair)
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += t_pair + agi_stall;
decode_delay = (-t_pair) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
prev_full = 0;
return;
}
}
if (!prev_full)
{
/*First instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
{
/*Instruction not pairable*/
int agi_stall = 0;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
}
else
{
/*Instruction might pair with next*/
prev_full = 1;
prev_opcode = opcode;
prev_timings = timings;
prev_op_32 = op_32;
prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
if (prev_regmask & IMPL_ESP)
prev_regmask |= SRCDEP_ESP | DSTDEP_ESP;
prev_deps = deps;
prev_fetchdat = fetchdat;
return;
}
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
} else {
/*Instruction might pair with next*/
prev_full = 1;
prev_opcode = opcode;
prev_timings = timings;
prev_op_32 = op_32;
prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
if (prev_regmask & IMPL_ESP)
prev_regmask |= SRCDEP_ESP | DSTDEP_ESP;
prev_deps = deps;
prev_fetchdat = fetchdat;
return;
}
}
}
void codegen_timing_686_block_end(void)
void
codegen_timing_686_block_end(void)
{
if (prev_full)
{
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
prev_full = 0;
}
if (prev_full) {
/*Run previous now*/
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
prev_full = 0;
}
}
codegen_timing_t codegen_timing_686 =
{
codegen_timing_686_start,
codegen_timing_686_prefix,
codegen_timing_686_opcode,
codegen_timing_686_block_start,
codegen_timing_686_block_end,
NULL
codegen_timing_t codegen_timing_686 = {
codegen_timing_686_start,
codegen_timing_686_prefix,
codegen_timing_686_opcode,
codegen_timing_686_block_start,
codegen_timing_686_block_end,
NULL
};

View File

@@ -8,8 +8,8 @@
#include "codegen_timing_common.h"
uint64_t opcode_deps[256] =
{
uint64_t opcode_deps[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
/* ADD ADD PUSH ES POP ES*/
@@ -140,10 +140,11 @@ uint64_t opcode_deps[256] =
0, 0, 0, 0,
/* CLD STD INCDEC*/
0, 0, MODRM, 0
// clang-format on
};
uint64_t opcode_deps_mod3[256] =
{
uint64_t opcode_deps_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
/* ADD ADD PUSH ES POP ES*/
@@ -274,10 +275,11 @@ uint64_t opcode_deps_mod3[256] =
0, 0, 0, 0,
/* CLD STD INCDEC*/
0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0
// clang-format on
};
uint64_t opcode_deps_0f[256] =
{
uint64_t opcode_deps_0f[256] = {
// clang-format off
/*00*/ MODRM, MODRM, MODRM, MODRM,
0, 0, 0, 0,
0, 0, 0, 0,
@@ -357,9 +359,10 @@ uint64_t opcode_deps_0f[256] =
0, MODRM | MMX_MULTIPLY, 0, 0,
MODRM, MODRM, MODRM, 0,
MODRM, MODRM, MODRM, 0,
// clang-format on
};
uint64_t opcode_deps_0f_mod3[256] =
{
uint64_t opcode_deps_0f_mod3[256] = {
// clang-format off
/*00*/ MODRM, MODRM, MODRM, MODRM,
0, 0, 0, 0,
0, 0, 0, 0,
@@ -439,10 +442,11 @@ uint64_t opcode_deps_0f_mod3[256] =
0, MODRM | MMX_MULTIPLY, 0, 0,
MODRM, MODRM, MODRM, 0,
MODRM, MODRM, MODRM, 0,
// clang-format on
};
uint64_t opcode_deps_0f0f[256] =
{
uint64_t opcode_deps_0f0f[256] = {
// clang-format off
/*00*/ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
@@ -522,9 +526,10 @@ uint64_t opcode_deps_0f0f[256] =
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// clang-format on
};
uint64_t opcode_deps_0f0f_mod3[256] =
{
uint64_t opcode_deps_0f0f_mod3[256] = {
// clang-format off
/*00*/ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
@@ -604,97 +609,111 @@ uint64_t opcode_deps_0f0f_mod3[256] =
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// clang-format on
};
uint64_t opcode_deps_shift[8] =
{
uint64_t opcode_deps_shift[8] = {
// clang-format off
MODRM, MODRM, MODRM, MODRM,
MODRM, MODRM, MODRM, MODRM,
// clang-format on
};
uint64_t opcode_deps_shift_mod3[8] =
{
uint64_t opcode_deps_shift_mod3[8] = {
// clang-format off
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
// clang-format on
};
uint64_t opcode_deps_shift_cl[8] =
{
uint64_t opcode_deps_shift_cl[8] = {
// clang-format off
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
// clang-format on
};
uint64_t opcode_deps_shift_cl_mod3[8] =
{
uint64_t opcode_deps_shift_cl_mod3[8] = {
// clang-format off
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
// clang-format on
};
uint64_t opcode_deps_f6[8] =
{
uint64_t opcode_deps_f6[8] = {
// clang-format off
/* TST NOT NEG*/
MODRM, 0, MODRM, MODRM,
/* MUL IMUL DIV IDIV*/
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
// clang-format on
};
uint64_t opcode_deps_f6_mod3[8] =
{
uint64_t opcode_deps_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
/* MUL IMUL DIV IDIV*/
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
// clang-format on
};
uint64_t opcode_deps_f7[8] =
{
uint64_t opcode_deps_f7[8] = {
// clang-format off
/* TST NOT NEG*/
MODRM, 0, MODRM, MODRM,
/* MUL IMUL DIV IDIV*/
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
// clang-format on
};
uint64_t opcode_deps_f7_mod3[8] =
{
uint64_t opcode_deps_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
/* MUL IMUL DIV IDIV*/
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
// clang-format on
};
uint64_t opcode_deps_ff[8] =
{
uint64_t opcode_deps_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
MODRM, MODRM, MODRM | IMPL_ESP, MODRM,
/* JMP JMP far PUSH*/
MODRM, MODRM, MODRM | IMPL_ESP, 0
// clang-format on
};
uint64_t opcode_deps_ff_mod3[8] =
{
uint64_t opcode_deps_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM,
/* JMP JMP far PUSH*/
SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0
// clang-format on
};
uint64_t opcode_deps_d8[8] =
{
uint64_t opcode_deps_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM,
/* FSUBs FSUBRs FDIVs FDIVRs*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
// clang-format on
};
uint64_t opcode_deps_d8_mod3[8] =
{
uint64_t opcode_deps_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG,
/* FSUB FSUBR FDIV FDIVR*/
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG
// clang-format on
};
uint64_t opcode_deps_d9[8] =
{
uint64_t opcode_deps_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM,
/* FLDENV FLDCW FSTENV FSTCW*/
MODRM, MODRM, MODRM, MODRM
// clang-format on
};
uint64_t opcode_deps_d9_mod3[64] =
{
uint64_t opcode_deps_d9_mod3[64] = {
// clang-format off
/*FLD*/
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
@@ -722,32 +741,35 @@ uint64_t opcode_deps_d9_mod3[64] =
0, 0, 0, 0,
/* opFRNDINT opFSCALE opFSIN opFCOS*/
0, 0, 0, 0
// clang-format on
};
uint64_t opcode_deps_da[8] =
{
uint64_t opcode_deps_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
// clang-format on
};
uint64_t opcode_deps_da_mod3[8] =
{
uint64_t opcode_deps_da_mod3[8] = {
// clang-format off
0, 0, 0, 0,
/* FCOMPP*/
0, FPU_POP2, 0, 0
// clang-format on
};
uint64_t opcode_deps_db[8] =
{
uint64_t opcode_deps_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FLDe FSTPe*/
0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM
// clang-format on
};
uint64_t opcode_deps_db_mod3[64] =
{
uint64_t opcode_deps_db_mod3[64] = {
// clang-format off
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -767,84 +789,97 @@ uint64_t opcode_deps_db_mod3[64] =
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// clang-format on
};
uint64_t opcode_deps_dc[8] =
{
uint64_t opcode_deps_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FSUBd FSUBRd FDIVd FDIVRd*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
// clang-format on
};
uint64_t opcode_deps_dc_mod3[8] =
{
uint64_t opcode_deps_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0,
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG
// clang-format on
};
uint64_t opcode_deps_dd[8] =
{
uint64_t opcode_deps_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FRSTOR FSAVE FSTSW*/
MODRM, 0, MODRM, MODRM
// clang-format on
};
uint64_t opcode_deps_dd_mod3[8] =
{
uint64_t opcode_deps_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
/* FUCOM FUCOMP*/
FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0
// clang-format on
};
uint64_t opcode_deps_de[8] =
{
uint64_t opcode_deps_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
// clang-format on
};
uint64_t opcode_deps_de_mod3[8] =
{
uint64_t opcode_deps_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2,
/* FSUBP FSUBRP FDIVP FDIVRP*/
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP
// clang-format on
};
uint64_t opcode_deps_df[8] =
{
uint64_t opcode_deps_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
/* FILDiq FBSTP FISTPiq*/
0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM
// clang-format on
};
uint64_t opcode_deps_df_mod3[8] =
{
uint64_t opcode_deps_df_mod3[8] = {
// clang-format off
0, 0, 0, 0,
/* FSTSW AX*/
0, 0, 0, 0
// clang-format on
};
uint64_t opcode_deps_81[8] =
{
uint64_t opcode_deps_81[8] = {
// clang-format off
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632,
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632
// clang-format on
};
uint64_t opcode_deps_81_mod3[8] =
{
uint64_t opcode_deps_81_mod3[8] = {
// clang-format off
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632,
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632
// clang-format on
};
uint64_t opcode_deps_8x[8] =
{
uint64_t opcode_deps_8x[8] = {
// clang-format off
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8,
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8
// clang-format on
};
uint64_t opcode_deps_8x_mod3[8] =
{
uint64_t opcode_deps_8x_mod3[8] = {
// clang-format off
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8,
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8
// clang-format on
};

View File

@@ -1,79 +1,79 @@
#include "codegen_ops.h"
/*Instruction has input dependency on register in REG field*/
#define SRCDEP_REG (1ull << 0)
#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)
#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
/*Instruction has input dependency on given register*/
#define SRCDEP_EAX (1ull << 4)
#define SRCDEP_ECX (1ull << 5)
#define SRCDEP_EDX (1ull << 6)
#define SRCDEP_EBX (1ull << 7)
#define SRCDEP_ESP (1ull << 8)
#define SRCDEP_EBP (1ull << 9)
#define SRCDEP_ESI (1ull << 10)
#define SRCDEP_EDI (1ull << 11)
#define SRCDEP_EAX (1ULL << 4)
#define SRCDEP_ECX (1ULL << 5)
#define SRCDEP_EDX (1ULL << 6)
#define SRCDEP_EBX (1ULL << 7)
#define SRCDEP_ESP (1ULL << 8)
#define SRCDEP_EBP (1ULL << 9)
#define SRCDEP_ESI (1ULL << 10)
#define SRCDEP_EDI (1ULL << 11)
/*Instruction modifies given register*/
#define DSTDEP_EAX (1ull << 12)
#define DSTDEP_ECX (1ull << 13)
#define DSTDEP_EDX (1ull << 14)
#define DSTDEP_EBX (1ull << 15)
#define DSTDEP_ESP (1ull << 16)
#define DSTDEP_EBP (1ull << 17)
#define DSTDEP_ESI (1ull << 18)
#define DSTDEP_EDI (1ull << 19)
#define DSTDEP_EAX (1ULL << 12)
#define DSTDEP_ECX (1ULL << 13)
#define DSTDEP_EDX (1ULL << 14)
#define DSTDEP_EBX (1ULL << 15)
#define DSTDEP_ESP (1ULL << 16)
#define DSTDEP_EBP (1ULL << 17)
#define DSTDEP_ESI (1ULL << 18)
#define DSTDEP_EDI (1ULL << 19)
/*Instruction has ModR/M byte*/
#define MODRM (1ull << 20)
#define MODRM (1ULL << 20)
/*Instruction implicitly uses ESP*/
#define IMPL_ESP (1ull << 21)
#define IMPL_ESP (1ULL << 21)
/*Instruction is MMX shift or pack/unpack instruction*/
#define MMX_SHIFTPACK (1ull << 22)
#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)
#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_SHIFTPACK (1 << 9)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,19 +4,21 @@
#include <wchar.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include <86box/mem.h>
#include "codegen.h"
#include "codegen_ops.h"
#include "codegen_timing_common.h"
#define CYCLES(c) (int *)c
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
static int *opcode_timings[256] =
{
static int *opcode_timings[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
@@ -36,10 +38,11 @@ static int *opcode_timings[256] =
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
// clang-format on
};
static int *opcode_timings_mod3[256] =
{
static int *opcode_timings_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
@@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] =
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
// clang-format on
};
static int *opcode_timings_0f[256] =
{
static int *opcode_timings_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] =
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
static int *opcode_timings_0f_mod3[256] =
{
static int *opcode_timings_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -104,60 +109,72 @@ static int *opcode_timings_0f_mod3[256] =
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
// clang-format on
};
static int *opcode_timings_shift[8] =
{
static int *opcode_timings_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
// clang-format on
};
static int *opcode_timings_shift_mod3[8] =
{
static int *opcode_timings_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
static int *opcode_timings_f6[8] =
{
static int *opcode_timings_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f6_mod3[8] =
{
static int *opcode_timings_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f7[8] =
{
static int *opcode_timings_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_f7_mod3[8] =
{
static int *opcode_timings_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_ff[8] =
{
static int *opcode_timings_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_ff_mod3[8] =
{
static int *opcode_timings_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_d8[8] =
{
static int *opcode_timings_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_d8_mod3[8] =
{
static int *opcode_timings_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_d9[8] =
{
static int *opcode_timings_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
static int *opcode_timings_d9_mod3[64] =
{
static int *opcode_timings_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
/*FXCH*/
@@ -174,26 +191,29 @@ static int *opcode_timings_d9_mod3[64] =
CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3),
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474)
// clang-format on
};
static int *opcode_timings_da[8] =
{
static int *opcode_timings_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_da_mod3[8] =
{
static int *opcode_timings_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
static int *opcode_timings_db[8] =
{
static int *opcode_timings_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8)
// clang-format on
};
static int *opcode_timings_db_mod3[64] =
{
static int *opcode_timings_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -203,54 +223,63 @@ static int *opcode_timings_db_mod3[64] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// clang-format on
};
static int *opcode_timings_dc[8] =
{
static int *opcode_timings_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74)
// clang-format on
};
static int *opcode_timings_dc_mod3[8] =
{
static int *opcode_timings_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_dd[8] =
{
static int *opcode_timings_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5)
// clang-format on
};
static int *opcode_timings_dd_mod3[8] =
{
static int *opcode_timings_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
static int *opcode_timings_de[8] =
{
static int *opcode_timings_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_de_mod3[8] =
{
static int *opcode_timings_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_df[8] =
{
static int *opcode_timings_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8)
// clang-format on
};
static int *opcode_timings_df_mod3[8] =
{
static int *opcode_timings_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
static int *opcode_timings_8x[8] =
{
static int *opcode_timings_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
static int *opcode_timings_8x_mod3[8] =
@@ -264,158 +293,169 @@ static int *opcode_timings_81[8] =
static int *opcode_timings_81_mod3[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int timing_count;
static uint8_t last_prefix;
static int timing_count;
static uint8_t last_prefix;
static uint32_t regmask_modified;
static inline int COUNT(int *c, int op_32)
static inline int
COUNT(int *c, int op_32)
{
if ((uintptr_t)c <= 10000)
return (int)(uintptr_t)c;
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
{
if (op_32 & 0x100)
return ((uintptr_t)c >> 8) & 0xff;
return (uintptr_t)c & 0xff;
}
return *c;
if ((uintptr_t) c <= 10000)
return (int) (uintptr_t) c;
if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) {
if (op_32 & 0x100)
return ((uintptr_t) c >> 8) & 0xff;
return (uintptr_t) c & 0xff;
}
return *c;
}
void codegen_timing_winchip_block_start(void)
void
codegen_timing_winchip_block_start(void)
{
regmask_modified = 0;
regmask_modified = 0;
}
void codegen_timing_winchip_start(void)
void
codegen_timing_winchip_start(void)
{
timing_count = 0;
last_prefix = 0;
timing_count = 0;
last_prefix = 0;
}
void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
void
codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
{
timing_count += COUNT(opcode_timings[prefix], 0);
last_prefix = prefix;
timing_count += COUNT(opcode_timings[prefix], 0);
last_prefix = prefix;
}
void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
void
codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
{
int **timings;
uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
int **timings;
const uint64_t *deps;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
switch (last_prefix)
{
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
default:
switch (opcode) {
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
case 0xc0:
case 0xc1:
case 0xd0:
case 0xd1:
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
switch (opcode)
{
case 0x80: case 0x82: case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
}
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
timing_count += COUNT(timings[opcode], op_32);
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
timing_count++; /*AGI stall*/
codegen_block_cycles += timing_count;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
}
timing_count += COUNT(timings[opcode], op_32);
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
timing_count++; /*AGI stall*/
codegen_block_cycles += timing_count;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
}
void codegen_timing_winchip_block_end(void)
void
codegen_timing_winchip_block_end(void)
{
//
}
codegen_timing_t codegen_timing_winchip =
{
codegen_timing_winchip_start,
codegen_timing_winchip_prefix,
codegen_timing_winchip_opcode,
codegen_timing_winchip_block_start,
codegen_timing_winchip_block_end,
NULL
codegen_timing_t codegen_timing_winchip = {
codegen_timing_winchip_start,
codegen_timing_winchip_prefix,
codegen_timing_winchip_opcode,
codegen_timing_winchip_block_start,
codegen_timing_winchip_block_end,
NULL
};

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
* Copyright 2016-2020 Miran Grca.
* Copyright 2018-2021 Fred N. van Kempen.
*/
#include <inttypes.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
@@ -37,6 +38,9 @@
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#ifdef USE_DYNAREC
# include "codegen.h"
#endif
@@ -125,6 +129,27 @@ const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
const OpFn *x86_opcodes_3DNOW;
const OpFn *x86_2386_opcodes;
const OpFn *x86_2386_opcodes_0f;
const OpFn *x86_2386_opcodes_d8_a16;
const OpFn *x86_2386_opcodes_d8_a32;
const OpFn *x86_2386_opcodes_d9_a16;
const OpFn *x86_2386_opcodes_d9_a32;
const OpFn *x86_2386_opcodes_da_a16;
const OpFn *x86_2386_opcodes_da_a32;
const OpFn *x86_2386_opcodes_db_a16;
const OpFn *x86_2386_opcodes_db_a32;
const OpFn *x86_2386_opcodes_dc_a16;
const OpFn *x86_2386_opcodes_dc_a32;
const OpFn *x86_2386_opcodes_dd_a16;
const OpFn *x86_2386_opcodes_dd_a32;
const OpFn *x86_2386_opcodes_de_a16;
const OpFn *x86_2386_opcodes_de_a32;
const OpFn *x86_2386_opcodes_df_a16;
const OpFn *x86_2386_opcodes_df_a32;
const OpFn *x86_2386_opcodes_REPE;
const OpFn *x86_2386_opcodes_REPNE;
uint16_t cpu_fast_off_count;
uint16_t cpu_fast_off_val;
uint16_t temp_seg_data[4] = { 0, 0, 0, 0 };
@@ -216,7 +241,7 @@ uint32_t cache_index = 0;
uint8_t _cache[2048];
uint64_t cpu_CR4_mask;
uint64_t tsc = 0;
uint64_t tsc = 0;
uint64_t pmc[2] = { 0, 0 };
double cpu_dmulti;
@@ -229,7 +254,7 @@ cyrix_t cyrix;
cpu_family_t *cpu_f;
CPU *cpu_s;
uint8_t do_translate = 0;
uint8_t do_translate = 0;
uint8_t do_translate2 = 0;
void (*cpu_exec)(int cycs);
@@ -455,7 +480,7 @@ SF_FPU_reset(void)
fpu_state.fcs = 0;
fpu_state.fds = 0;
fpu_state.fdp = 0;
memset(fpu_state.st_space, 0, sizeof(floatx80)*8);
memset(fpu_state.st_space, 0, sizeof(floatx80) * 8);
}
}
@@ -541,9 +566,12 @@ cpu_set(void)
#else
x86_setopcodes(ops_386, ops_386_0f);
#endif
x86_opcodes_REPE = ops_REPE;
x86_opcodes_REPNE = ops_REPNE;
x86_opcodes_3DNOW = ops_3DNOW;
x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f);
x86_opcodes_REPE = ops_REPE;
x86_opcodes_REPNE = ops_REPNE;
x86_2386_opcodes_REPE = ops_2386_REPE;
x86_2386_opcodes_REPNE = ops_2386_REPNE;
x86_opcodes_3DNOW = ops_3DNOW;
#ifdef USE_DYNAREC
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
@@ -605,6 +633,23 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_sf_fpu_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_df_a32;
x86_2386_opcodes_d8_a16 = ops_2386_sf_fpu_d8_a16;
x86_2386_opcodes_d8_a32 = ops_2386_sf_fpu_d8_a32;
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_df_a32;
} else {
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_fpu_d8_a32;
@@ -622,6 +667,23 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_fpu_de_a32;
x86_opcodes_df_a16 = ops_fpu_df_a16;
x86_opcodes_df_a32 = ops_fpu_df_a32;
x86_2386_opcodes_d8_a16 = ops_2386_fpu_d8_a16;
x86_2386_opcodes_d8_a32 = ops_2386_fpu_d8_a32;
x86_2386_opcodes_d9_a16 = ops_2386_fpu_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_fpu_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_fpu_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_fpu_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_fpu_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_fpu_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_fpu_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_fpu_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_fpu_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_fpu_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_fpu_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_fpu_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_fpu_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_fpu_df_a32;
}
} else {
#ifdef USE_DYNAREC
@@ -658,6 +720,23 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_nofpu_a32;
x86_opcodes_df_a16 = ops_nofpu_a16;
x86_opcodes_df_a32 = ops_nofpu_a32;
x86_2386_opcodes_d8_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_d8_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_d9_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_d9_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_da_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_da_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_db_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_db_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_dc_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_dc_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_dd_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_dd_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_de_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_de_a32 = ops_2386_nofpu_a32;
x86_2386_opcodes_df_a16 = ops_2386_nofpu_a16;
x86_2386_opcodes_df_a32 = ops_2386_nofpu_a32;
}
#ifdef USE_DYNAREC
@@ -684,6 +763,7 @@ cpu_set(void)
#else
x86_setopcodes(ops_186, ops_186_0f);
#endif
x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f);
break;
case CPU_286:
@@ -692,6 +772,7 @@ cpu_set(void)
#else
x86_setopcodes(ops_286, ops_286_0f);
#endif
x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f);
if (fpu_type == FPU_287) {
#ifdef USE_DYNAREC
@@ -742,6 +823,21 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32;
} else {
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
@@ -757,6 +853,21 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32;
}
}
@@ -799,11 +910,13 @@ cpu_set(void)
#else
x86_setopcodes(ops_386, ops_ibm486_0f);
#endif
x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f);
cpu_features = CPU_FEATURE_MSR;
/* FALLTHROUGH */
fallthrough;
case CPU_386SX:
case CPU_386DX:
if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */
/* In case we get Deskpro 386 emulation */
if (fpu_type == FPU_287) {
#ifdef USE_DYNAREC
if (fpu_softfloat) {
x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16;
@@ -852,6 +965,21 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32;
} else {
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
@@ -867,6 +995,21 @@ cpu_set(void)
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16;
x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32;
x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16;
x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32;
x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16;
x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32;
x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16;
x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32;
x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16;
x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32;
x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16;
x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32;
x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16;
x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32;
}
}
@@ -913,6 +1056,7 @@ cpu_set(void)
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
timing_rm = 3; /* register dest - memory src */
@@ -952,6 +1096,7 @@ cpu_set(void)
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
timing_rm = 3; /* register dest - memory src */
@@ -990,7 +1135,7 @@ cpu_set(void)
case CPU_i486DX_SLENH:
cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
/* FALLTHROUGH */
fallthrough;
case CPU_RAPIDCAD:
case CPU_i486SX:
case CPU_i486DX:
@@ -1004,6 +1149,7 @@ cpu_set(void)
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1302,7 +1448,9 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
else
x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f);
// x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
# if 0
x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
# endif
# else
if (cpu_s->cpu_type == CPU_Cx6x86MX)
x86_setopcodes(ops_386, ops_c6x86mx_0f);
@@ -1310,7 +1458,9 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentium_0f);
else
x86_setopcodes(ops_386, ops_c6x86mx_0f);
// x86_setopcodes(ops_386, ops_c6x86_0f);
# if 0
x86_setopcodes(ops_386, ops_c6x86_0f);
# endif
# endif
timing_rr = 1; /* register dest - register src */
@@ -1615,7 +1765,7 @@ cpu_set(void)
break;
default:
fatal("cpu_set : unknown CPU type %llu\n", cpu_s->cpu_type);
fatal("cpu_set : unknown CPU type %" PRIu64 "\n", cpu_s->cpu_type);
}
switch (fpu_type) {
@@ -1647,9 +1797,13 @@ cpu_set(void)
cpu_exec = exec386_dynarec;
else
#endif
cpu_exec = exec386;
/* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */
if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC))
cpu_exec = exec386;
else
cpu_exec = exec386_2386;
} else if (cpu_s->cpu_type >= CPU_286)
cpu_exec = exec386;
cpu_exec = exec386_2386;
else
cpu_exec = execx86;
mmx_init();
@@ -2324,7 +2478,7 @@ cpu_ven_reset(void)
case CPU_K6_3:
case CPU_K6_2C:
msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL;
/* FALLTHROUGH */
fallthrough;
case CPU_K6_2:
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
case CPU_K5:
@@ -2338,7 +2492,6 @@ cpu_ven_reset(void)
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
msr.mtrr_cap = 0x00000508ULL;
/* FALLTHROUGH */
break;
}
}
@@ -2741,6 +2894,10 @@ amd_k_invalid_rdmsr:
EAX = msr.ecx187 & 0xffffffff;
EDX = msr.ecx187 >> 32;
break;
case 0x1d9:
EAX = msr.debug_ctl & 0xffffffff;
EDX = msr.debug_ctl >> 32;
break;
case 0x1e0:
EAX = msr.ecx1e0 & 0xffffffff;
EDX = msr.ecx1e0 >> 32;
@@ -3121,7 +3278,9 @@ amd_k_invalid_wrmsr:
break;
case 0x1b:
cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX);
// msr.apic_base = EAX | ((uint64_t) EDX << 32);
#if 0
msr.apic_base = EAX | ((uint64_t) EDX << 32);
#endif
break;
case 0x2a:
break;
@@ -3192,6 +3351,9 @@ amd_k_invalid_wrmsr:
case 0x187:
msr.ecx187 = EAX | ((uint64_t) EDX << 32);
break;
case 0x1d9:
msr.debug_ctl = EAX | ((uint64_t) EDX << 32);
break;
case 0x1e0:
msr.ecx1e0 = EAX | ((uint64_t) EDX << 32);
break;
@@ -3300,7 +3462,7 @@ i686_invalid_wrmsr:
}
static void
cpu_write(uint16_t addr, uint8_t val, void *priv)
cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
{
if (addr == 0xf0) {
/* Writes to F0 clear FPU error and deassert the interrupt. */
@@ -3382,7 +3544,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv)
}
static uint8_t
cpu_read(uint16_t addr, void *priv)
cpu_read(uint16_t addr, UNUSED(void *priv))
{
if (addr == 0xf007)
return 0x7f;
@@ -3438,11 +3600,18 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
#else
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
#endif
void
x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f)
{
x86_2386_opcodes = opcodes;
x86_2386_opcodes_0f = opcodes_0f;
}
void
cpu_update_waitstates(void)
{

View File

@@ -280,11 +280,12 @@ typedef struct {
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */
uint64_t ecx186; /* 0x00000186, 0x00000187 */
uint64_t ecx187; /* 0x00000186, 0x00000187 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx186; /* 0x00000186, 0x00000187 */
uint64_t ecx187; /* 0x00000186, 0x00000187 */
uint64_t ecx1e0; /* 0x000001e0 */
uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */
uint64_t ecx1e0; /* 0x000001e0 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also
on the VIA Cyrix III */
@@ -393,8 +394,13 @@ typedef struct {
MMX_REG MM[8];
#ifdef USE_NEW_DYNAREC
# if defined(__APPLE__) && defined(__aarch64__)
uint64_t old_fp_control;
uint64_t new_fp_control;
# else
uint32_t old_fp_control;
uint32_t new_fp_control;
# endif
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
uint16_t old_fp_control2;
uint16_t new_fp_control2;
@@ -426,15 +432,15 @@ typedef struct {
} cpu_state_t;
typedef struct {
uint16_t cwd;
uint16_t swd;
uint16_t tag;
uint16_t foo;
uint32_t fip;
uint32_t fdp;
uint16_t fcs;
uint16_t fds;
floatx80 st_space[8];
uint16_t cwd;
uint16_t swd;
uint16_t tag;
uint16_t foo;
uint32_t fip;
uint32_t fdp;
uint16_t fcs;
uint16_t fds;
floatx80 st_space[8];
unsigned char tos;
unsigned char align1;
unsigned char align2;
@@ -444,7 +450,7 @@ typedef struct {
#define in_smm cpu_state._in_smm
#define smi_line cpu_state._smi_line
#define smbase cpu_state._smbase
#define smbase cpu_state._smbase
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
to be valid*/
@@ -454,9 +460,9 @@ typedef struct {
#define CPU_STATUS_V86 (1 << 3)
#define CPU_STATUS_SMM (1 << 4)
#ifdef USE_NEW_DYNAREC
#define CPU_STATUS_FLAGS 0xff
# define CPU_STATUS_FLAGS 0xff
#else
#define CPU_STATUS_FLAGS 0xffff
# define CPU_STATUS_FLAGS 0xffff
#endif
/*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status.
@@ -615,8 +621,8 @@ extern uint64_t star;
#define FPU_CW_Reserved_Bits (0xe0c0)
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2;
extern uint32_t cr3;
extern uint32_t cr4;
@@ -720,8 +726,8 @@ extern void loadseg_dynarec(uint16_t seg, x86seg *s);
extern int loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
#else
extern void loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
extern void loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
#endif
extern char *cpu_current_pc(char *bufp);
@@ -748,6 +754,7 @@ extern void execx86(int cycs);
extern void enter_smm(int in_hlt);
extern void enter_smm_check(int in_hlt);
extern void leave_smm(void);
extern void exec386_2386(int cycs);
extern void exec386(int cycs);
extern void exec386_dynarec(int cycs);
extern int idivl(int32_t val);
@@ -758,11 +765,11 @@ extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
#else
extern void loadcscall(uint16_t seg);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
extern void loadcscall(uint16_t seg);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
#endif
extern void resetmcr(void);
extern void resetx86(void);
@@ -831,6 +838,8 @@ extern int hlt_reset_pending;
extern cyrix_t cyrix;
extern int prefetch_prefixes;
extern uint8_t use_custom_nmi_vector;
extern uint32_t custom_nmi_vector;
@@ -851,9 +860,12 @@ extern void cpu_fast_off_reset(void);
extern void smi_raise(void);
extern void nmi_raise(void);
extern MMX_REG *MMP[8];
extern MMX_REG *MMP[8];
extern uint16_t *MMEP[8];
extern void mmx_init(void);
extern void prefetch_flush(void);
extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32);
#endif /*EMU_CPU_H*/

View File

@@ -59,10 +59,12 @@ uint32_t rmdat;
uint64_t xt_cpu_multi;
/* Variables for handling the non-maskable interrupts. */
int nmi = 0, nmi_auto_clear = 0;
int nmi = 0;
int nmi_auto_clear = 0;
/* Was the CPU ever reset? */
int x86_was_reset = 0, soft_reset_pci = 0;
int x86_was_reset = 0;
int soft_reset_pci = 0;
/* Is the TRAP flag on? */
int trap = 0;
@@ -71,7 +73,8 @@ int trap = 0;
uint32_t easeg;
/* This is for the OPTI 283 special reset handling mode. */
int reset_on_hlt, hlt_reset_pending;
int reset_on_hlt;
int hlt_reset_pending;
#ifdef ENABLE_X86_LOG
void dumpregs(int);
@@ -171,7 +174,10 @@ makemod1table(void)
static void
makeznptable(void)
{
int c, d, e;
int c;
int d;
int e;
for (c = 0; c < 256; c++) {
d = 0;
for (e = 0; e < 8; e++) {
@@ -267,7 +273,7 @@ reset_common(int hard)
loadcs(0xF000);
cpu_state.pc = 0xFFF0;
if (hard) {
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
if (is6117)
rammask |= 0x03000000;
mem_a20_key = mem_a20_alt = mem_a20_state = 0;

View File

@@ -9,30 +9,44 @@
that we don't end up with an unnecessarily short block*/
#define ABRT_EXPECTED 0x80
extern uint8_t opcode, opcode2;
extern uint8_t opcode;
extern uint8_t 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;
extern uint16_t oldcs;
extern uint16_t lastcs;
extern uint16_t lastpc;
extern uint16_t *mod1add[2][8];
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 x86_was_reset;
extern int trap;
extern int codegen_flat_ss;
extern int codegen_flat_ds;
extern int timetolive;
extern int keyboardtimer;
extern int trap;
extern int optype;
extern int stack32;
extern int oldcpl;
extern int cgate32;
extern int cpl_override;
extern int nmi_enable;
extern int oddeven, inttype;
extern int oddeven;
extern int inttype;
extern uint32_t use32;
extern uint32_t rmdat, easeg;
extern uint32_t oxpc, flags_zn;
extern uint32_t rmdat;
extern uint32_t easeg;
extern uint32_t oxpc;
extern uint32_t flags_zn;
extern uint32_t abrt_error;
extern uint32_t backupregs[16];
extern uint32_t *mod1seg[8];
extern uint32_t *eal_r, *eal_w;
extern uint32_t *eal_r;
extern uint32_t *eal_w;
#define fetchdat rmdat
@@ -68,13 +82,13 @@ extern uint32_t *eal_r, *eal_w;
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. */
ABRT_GEN = 1,
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);

View File

@@ -44,9 +44,9 @@
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);
extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
const OpFn *dynarec_opcodes,
const OpFn *dynarec_opcodes_0f);
extern const OpFn *x86_dynarec_opcodes;
extern const OpFn *x86_dynarec_opcodes_0f;
@@ -187,10 +187,9 @@ extern const OpFn dynarec_ops_REPNE[1024];
extern const OpFn dynarec_ops_3DNOW[256];
extern const OpFn dynarec_ops_3DNOWE[256];
#else
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
#endif
extern const OpFn *x86_opcodes;
extern const OpFn *x86_opcodes_0f;
extern const OpFn *x86_opcodes_d8_a16;
@@ -330,6 +329,111 @@ extern const OpFn ops_REPNE[1024];
extern const OpFn ops_3DNOW[256];
extern const OpFn ops_3DNOWE[256];
extern void x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f);
extern const OpFn *x86_2386_opcodes;
extern const OpFn *x86_2386_opcodes_0f;
extern const OpFn *x86_2386_opcodes_d8_a16;
extern const OpFn *x86_2386_opcodes_d8_a32;
extern const OpFn *x86_2386_opcodes_d9_a16;
extern const OpFn *x86_2386_opcodes_d9_a32;
extern const OpFn *x86_2386_opcodes_da_a16;
extern const OpFn *x86_2386_opcodes_da_a32;
extern const OpFn *x86_2386_opcodes_db_a16;
extern const OpFn *x86_2386_opcodes_db_a32;
extern const OpFn *x86_2386_opcodes_dc_a16;
extern const OpFn *x86_2386_opcodes_dc_a32;
extern const OpFn *x86_2386_opcodes_dd_a16;
extern const OpFn *x86_2386_opcodes_dd_a32;
extern const OpFn *x86_2386_opcodes_de_a16;
extern const OpFn *x86_2386_opcodes_de_a32;
extern const OpFn *x86_2386_opcodes_df_a16;
extern const OpFn *x86_2386_opcodes_df_a32;
extern const OpFn *x86_2386_opcodes_REPE;
extern const OpFn *x86_2386_opcodes_REPNE;
extern const OpFn ops_2386_186[1024];
extern const OpFn ops_2386_186_0f[1024];
extern const OpFn ops_2386_286[1024];
extern const OpFn ops_2386_286_0f[1024];
extern const OpFn ops_2386_386[1024];
extern const OpFn ops_2386_386_0f[1024];
extern const OpFn ops_2386_486_0f[1024];
extern const OpFn ops_2386_ibm486_0f[1024];
extern const OpFn ops_2386_sf_fpu_287_d9_a16[256];
extern const OpFn ops_2386_sf_fpu_287_d9_a32[256];
extern const OpFn ops_2386_sf_fpu_287_da_a16[256];
extern const OpFn ops_2386_sf_fpu_287_da_a32[256];
extern const OpFn ops_2386_sf_fpu_287_db_a16[256];
extern const OpFn ops_2386_sf_fpu_287_db_a32[256];
extern const OpFn ops_2386_sf_fpu_287_dc_a16[32];
extern const OpFn ops_2386_sf_fpu_287_dc_a32[32];
extern const OpFn ops_2386_sf_fpu_287_dd_a16[256];
extern const OpFn ops_2386_sf_fpu_287_dd_a32[256];
extern const OpFn ops_2386_sf_fpu_287_de_a16[256];
extern const OpFn ops_2386_sf_fpu_287_de_a32[256];
extern const OpFn ops_2386_sf_fpu_287_df_a16[256];
extern const OpFn ops_2386_sf_fpu_287_df_a32[256];
extern const OpFn ops_2386_sf_fpu_d8_a16[32];
extern const OpFn ops_2386_sf_fpu_d8_a32[32];
extern const OpFn ops_2386_sf_fpu_d9_a16[256];
extern const OpFn ops_2386_sf_fpu_d9_a32[256];
extern const OpFn ops_2386_sf_fpu_da_a16[256];
extern const OpFn ops_2386_sf_fpu_da_a32[256];
extern const OpFn ops_2386_sf_fpu_db_a16[256];
extern const OpFn ops_2386_sf_fpu_db_a32[256];
extern const OpFn ops_2386_sf_fpu_dc_a16[32];
extern const OpFn ops_2386_sf_fpu_dc_a32[32];
extern const OpFn ops_2386_sf_fpu_dd_a16[256];
extern const OpFn ops_2386_sf_fpu_dd_a32[256];
extern const OpFn ops_2386_sf_fpu_de_a16[256];
extern const OpFn ops_2386_sf_fpu_de_a32[256];
extern const OpFn ops_2386_sf_fpu_df_a16[256];
extern const OpFn ops_2386_sf_fpu_df_a32[256];
extern const OpFn ops_2386_fpu_287_d9_a16[256];
extern const OpFn ops_2386_fpu_287_d9_a32[256];
extern const OpFn ops_2386_fpu_287_da_a16[256];
extern const OpFn ops_2386_fpu_287_da_a32[256];
extern const OpFn ops_2386_fpu_287_db_a16[256];
extern const OpFn ops_2386_fpu_287_db_a32[256];
extern const OpFn ops_2386_fpu_287_dc_a16[32];
extern const OpFn ops_2386_fpu_287_dc_a32[32];
extern const OpFn ops_2386_fpu_287_dd_a16[256];
extern const OpFn ops_2386_fpu_287_dd_a32[256];
extern const OpFn ops_2386_fpu_287_de_a16[256];
extern const OpFn ops_2386_fpu_287_de_a32[256];
extern const OpFn ops_2386_fpu_287_df_a16[256];
extern const OpFn ops_2386_fpu_287_df_a32[256];
extern const OpFn ops_2386_fpu_d8_a16[32];
extern const OpFn ops_2386_fpu_d8_a32[32];
extern const OpFn ops_2386_fpu_d9_a16[256];
extern const OpFn ops_2386_fpu_d9_a32[256];
extern const OpFn ops_2386_fpu_da_a16[256];
extern const OpFn ops_2386_fpu_da_a32[256];
extern const OpFn ops_2386_fpu_db_a16[256];
extern const OpFn ops_2386_fpu_db_a32[256];
extern const OpFn ops_2386_fpu_dc_a16[32];
extern const OpFn ops_2386_fpu_dc_a32[32];
extern const OpFn ops_2386_fpu_dd_a16[256];
extern const OpFn ops_2386_fpu_dd_a32[256];
extern const OpFn ops_2386_fpu_de_a16[256];
extern const OpFn ops_2386_fpu_de_a32[256];
extern const OpFn ops_2386_fpu_df_a16[256];
extern const OpFn ops_2386_fpu_df_a32[256];
extern const OpFn ops_2386_nofpu_a16[256];
extern const OpFn ops_2386_nofpu_a32[256];
extern const OpFn ops_2386_REPE[1024];
extern const OpFn ops_2386_REPNE[1024];
extern const OpFn ops_2386_3DNOW[256];
#define C0 (1 << 8)
#define C1 (1 << 9)
#define C2 (1 << 10)

View File

@@ -35,7 +35,7 @@ opFEMMS(uint32_t fetchdat)
static int
opPAVGUSB(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -56,7 +56,7 @@ opPAVGUSB(uint32_t fetchdat)
static int
opPF2ID(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -71,7 +71,7 @@ opPF2ID(uint32_t fetchdat)
static int
opPF2IW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -86,9 +86,9 @@ opPF2IW(uint32_t fetchdat)
static int
opPFACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
float tempf;
MMX_GETSRC();
@@ -103,9 +103,9 @@ opPFACC(uint32_t fetchdat)
static int
opPFNACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
float tempf;
MMX_GETSRC();
@@ -120,9 +120,9 @@ opPFNACC(uint32_t fetchdat)
static int
opPFPNACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
float tempf;
MMX_GETSRC();
@@ -137,9 +137,10 @@ opPFPNACC(uint32_t fetchdat)
static int
opPSWAPD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf, tempf2;
float tempf;
float tempf2;
MMX_GETSRC();
@@ -156,7 +157,7 @@ opPSWAPD(uint32_t fetchdat)
static int
opPFADD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -171,7 +172,7 @@ opPFADD(uint32_t fetchdat)
static int
opPFCMPEQ(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -186,7 +187,7 @@ opPFCMPEQ(uint32_t fetchdat)
static int
opPFCMPGE(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -201,7 +202,7 @@ opPFCMPGE(uint32_t fetchdat)
static int
opPFCMPGT(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -216,7 +217,7 @@ opPFCMPGT(uint32_t fetchdat)
static int
opPFMAX(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -233,7 +234,7 @@ opPFMAX(uint32_t fetchdat)
static int
opPFMIN(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -250,7 +251,7 @@ opPFMIN(uint32_t fetchdat)
static int
opPFMUL(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -294,7 +295,7 @@ opPFRCP(uint32_t fetchdat)
static int
opPFRCPIT1(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -309,7 +310,7 @@ opPFRCPIT1(uint32_t fetchdat)
static int
opPFRCPIT2(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -363,7 +364,7 @@ opPFRSQIT1(uint32_t fetchdat)
static int
opPFSUB(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -378,7 +379,7 @@ opPFSUB(uint32_t fetchdat)
static int
opPFSUBR(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -393,7 +394,7 @@ opPFSUBR(uint32_t fetchdat)
static int
opPI2FD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -408,7 +409,7 @@ opPI2FD(uint32_t fetchdat)
static int
opPI2FW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
@@ -423,7 +424,7 @@ opPI2FW(uint32_t fetchdat)
static int
opPMULHRW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {

View File

@@ -340,6 +340,7 @@ 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);
@@ -359,6 +360,7 @@ 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);
@@ -379,6 +381,7 @@ 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);
@@ -398,6 +401,7 @@ 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);
@@ -418,6 +422,7 @@ 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);
@@ -437,6 +442,7 @@ 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);
@@ -457,6 +463,7 @@ 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);
@@ -472,6 +479,7 @@ 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);
@@ -488,6 +496,7 @@ 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);
@@ -503,6 +512,7 @@ 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);
@@ -519,6 +529,7 @@ 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);
@@ -534,6 +545,7 @@ 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);
@@ -550,6 +562,7 @@ 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);
@@ -560,6 +573,7 @@ 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);
@@ -570,6 +584,7 @@ static int
opCMP_EAX_imm(uint32_t fetchdat)
{
uint32_t src = getlong();
if (cpu_state.abrt)
return 1;
setsub32(EAX, src);
@@ -581,7 +596,9 @@ opCMP_EAX_imm(uint32_t fetchdat)
static int
opTEST_b_a16(uint32_t fetchdat)
{
uint8_t temp, temp2;
uint8_t temp;
uint8_t temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -601,7 +618,9 @@ opTEST_b_a16(uint32_t fetchdat)
static int
opTEST_b_a32(uint32_t fetchdat)
{
uint8_t temp, temp2;
uint8_t temp;
uint8_t temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -622,7 +641,9 @@ opTEST_b_a32(uint32_t fetchdat)
static int
opTEST_w_a16(uint32_t fetchdat)
{
uint16_t temp, temp2;
uint16_t temp;
uint16_t temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -642,7 +663,9 @@ opTEST_w_a16(uint32_t fetchdat)
static int
opTEST_w_a32(uint32_t fetchdat)
{
uint16_t temp, temp2;
uint16_t temp;
uint16_t temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -663,7 +686,9 @@ opTEST_w_a32(uint32_t fetchdat)
static int
opTEST_l_a16(uint32_t fetchdat)
{
uint32_t temp, temp2;
uint32_t temp;
uint32_t temp2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -683,7 +708,9 @@ opTEST_l_a16(uint32_t fetchdat)
static int
opTEST_l_a32(uint32_t fetchdat)
{
uint32_t temp, temp2;
uint32_t temp;
uint32_t temp2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -803,7 +830,8 @@ opTEST_EAX(uint32_t fetchdat)
static int
op80_a16(uint32_t fetchdat)
{
uint8_t src, dst;
uint8_t src;
uint8_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -823,7 +851,8 @@ op80_a16(uint32_t fetchdat)
static int
op80_a32(uint32_t fetchdat)
{
uint8_t src, dst;
uint8_t src;
uint8_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -843,7 +872,8 @@ op80_a32(uint32_t fetchdat)
static int
op81_w_a16(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -863,7 +893,8 @@ op81_w_a16(uint32_t fetchdat)
static int
op81_w_a32(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -883,7 +914,8 @@ op81_w_a32(uint32_t fetchdat)
static int
op81_l_a16(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -903,7 +935,8 @@ op81_l_a16(uint32_t fetchdat)
static int
op81_l_a32(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -924,7 +957,8 @@ op81_l_a32(uint32_t fetchdat)
static int
op83_w_a16(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -946,7 +980,8 @@ op83_w_a16(uint32_t fetchdat)
static int
op83_w_a32(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -969,7 +1004,8 @@ op83_w_a32(uint32_t fetchdat)
static int
op83_l_a16(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -991,7 +1027,8 @@ op83_l_a16(uint32_t fetchdat)
static int
op83_l_a32(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)

View File

@@ -1,7 +1,9 @@
static int
opCMPXCHG_b_a16(uint32_t fetchdat)
{
uint8_t temp, temp2 = AL;
uint8_t temp;
uint8_t temp2 = AL;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
@@ -20,7 +22,9 @@ opCMPXCHG_b_a16(uint32_t fetchdat)
static int
opCMPXCHG_b_a32(uint32_t fetchdat)
{
uint8_t temp, temp2 = AL;
uint8_t temp;
uint8_t temp2 = AL;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab();
@@ -40,7 +44,9 @@ opCMPXCHG_b_a32(uint32_t fetchdat)
static int
opCMPXCHG_w_a16(uint32_t fetchdat)
{
uint16_t temp, temp2 = AX;
uint16_t temp;
uint16_t temp2 = AX;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
@@ -59,7 +65,9 @@ opCMPXCHG_w_a16(uint32_t fetchdat)
static int
opCMPXCHG_w_a32(uint32_t fetchdat)
{
uint16_t temp, temp2 = AX;
uint16_t temp;
uint16_t temp2 = AX;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw();
@@ -79,7 +87,9 @@ opCMPXCHG_w_a32(uint32_t fetchdat)
static int
opCMPXCHG_l_a16(uint32_t fetchdat)
{
uint32_t temp, temp2 = EAX;
uint32_t temp;
uint32_t temp2 = EAX;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
@@ -98,7 +108,9 @@ opCMPXCHG_l_a16(uint32_t fetchdat)
static int
opCMPXCHG_l_a32(uint32_t fetchdat)
{
uint32_t temp, temp2 = EAX;
uint32_t temp;
uint32_t temp2 = EAX;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
@@ -115,10 +127,15 @@ opCMPXCHG_l_a32(uint32_t fetchdat)
return 0;
}
#ifndef OPS_286_386
static int
opCMPXCHG8B_a16(uint32_t fetchdat)
{
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
uint32_t temp;
uint32_t temp_hi;
uint32_t temp2 = EAX;
uint32_t temp2_hi = EDX;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
@@ -145,7 +162,11 @@ opCMPXCHG8B_a16(uint32_t fetchdat)
static int
opCMPXCHG8B_a32(uint32_t fetchdat)
{
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
uint32_t temp;
uint32_t temp_hi;
uint32_t temp2 = EAX;
uint32_t temp2_hi = EDX;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal();
@@ -169,13 +190,16 @@ opCMPXCHG8B_a32(uint32_t fetchdat)
cycles -= (cpu_mod == 3) ? 6 : 10;
return 0;
}
#endif
/* dest = eab, src = r8 */
static int
opXADD_b_a16(uint32_t fetchdat)
{
uint8_t temp;
uint8_t src, dest;
uint8_t src;
uint8_t dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getr8(cpu_reg);
@@ -195,7 +219,9 @@ static int
opXADD_b_a32(uint32_t fetchdat)
{
uint8_t temp;
uint8_t src, dest;
uint8_t src;
uint8_t dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getr8(cpu_reg);
@@ -216,7 +242,9 @@ static int
opXADD_w_a16(uint32_t fetchdat)
{
uint16_t temp;
uint16_t src, dest;
uint16_t src;
uint16_t dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = cpu_state.regs[cpu_reg].w;
@@ -236,7 +264,9 @@ static int
opXADD_w_a32(uint32_t fetchdat)
{
uint16_t temp;
uint16_t src, dest;
uint16_t src;
uint16_t dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = cpu_state.regs[cpu_reg].w;
@@ -257,7 +287,9 @@ static int
opXADD_l_a16(uint32_t fetchdat)
{
uint32_t temp;
uint32_t src, dest;
uint32_t src;
uint32_t dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = cpu_state.regs[cpu_reg].l;
@@ -277,7 +309,9 @@ static int
opXADD_l_a32(uint32_t fetchdat)
{
uint32_t temp;
uint32_t src, dest;
uint32_t src;
uint32_t dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
src = cpu_state.regs[cpu_reg].l;

View File

@@ -19,6 +19,7 @@ static int
opAAD(uint32_t fetchdat)
{
int base = getbytef();
if (!cpu_isintel)
base = 10;
AL = (AH * base) + AL;
@@ -33,6 +34,7 @@ static int
opAAM(uint32_t fetchdat)
{
int base = getbytef();
if (!base || !cpu_isintel)
base = 10;
AH = AL / base;
@@ -63,7 +65,9 @@ opAAS(uint32_t fetchdat)
static int
opDAA(uint32_t fetchdat)
{
uint16_t tempw, old_AL, old_CF;
uint16_t tempw;
uint16_t old_AL;
uint16_t old_CF;
flags_rebuild();
old_AL = AL;
@@ -98,7 +102,9 @@ opDAA(uint32_t fetchdat)
static int
opDAS(uint32_t fetchdat)
{
uint16_t tempw, old_AL, old_CF;
uint16_t tempw;
uint16_t old_AL;
uint16_t old_CF;
flags_rebuild();
old_AL = AL;

View File

@@ -201,13 +201,17 @@ opBT_l_r_a32(uint32_t fetchdat)
return 0; \
}
// clang-format off
opBT(C, ^=)
opBT(R, &= ~)
opBT(S, |=)
opBT(R, &= ~)
opBT(S, |=)
// clang-format on
static int opBA_w_a16(uint32_t fetchdat)
static int
opBA_w_a16(uint32_t fetchdat)
{
int tempc, count;
int tempc;
int count;
uint16_t temp;
fetch_ea_16(fetchdat);
@@ -258,7 +262,8 @@ opBT(C, ^=)
static int
opBA_w_a32(uint32_t fetchdat)
{
int tempc, count;
int tempc;
int count;
uint16_t temp;
fetch_ea_32(fetchdat);
@@ -310,7 +315,8 @@ opBA_w_a32(uint32_t fetchdat)
static int
opBA_l_a16(uint32_t fetchdat)
{
int tempc, count;
int tempc;
int count;
uint32_t temp;
fetch_ea_16(fetchdat);
@@ -361,7 +367,8 @@ opBA_l_a16(uint32_t fetchdat)
static int
opBA_l_a32(uint32_t fetchdat)
{
int tempc, count;
int tempc;
int count;
uint32_t temp;
fetch_ea_32(fetchdat);

View File

@@ -189,8 +189,10 @@
static int
opCALL_far_w(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint16_t new_cs, new_pc;
uint32_t old_cs;
uint32_t old_pc;
uint16_t new_cs;
uint16_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);
@@ -209,8 +211,10 @@ opCALL_far_w(uint32_t fetchdat)
static int
opCALL_far_l(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint32_t new_cs, new_pc;
uint32_t old_cs;
uint32_t old_pc;
uint32_t new_cs;
uint32_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);
@@ -230,8 +234,10 @@ opCALL_far_l(uint32_t fetchdat)
static int
opFF_w_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
uint16_t old_cs;
uint16_t new_cs;
uint32_t old_pc;
uint32_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);
@@ -392,8 +398,10 @@ opFF_w_a16(uint32_t fetchdat)
static int
opFF_w_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
uint16_t old_cs;
uint16_t new_cs;
uint32_t old_pc;
uint32_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);
@@ -555,8 +563,10 @@ opFF_w_a32(uint32_t fetchdat)
static int
opFF_l_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
uint16_t old_cs;
uint16_t new_cs;
uint32_t old_pc;
uint32_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);
@@ -717,8 +727,10 @@ opFF_l_a16(uint32_t fetchdat)
static int
opFF_l_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
uint16_t old_cs;
uint16_t new_cs;
uint32_t old_pc;
uint32_t new_pc;
int cycles_old = cycles;
UN_USED(cycles_old);

View File

@@ -97,7 +97,9 @@ opWAIT(uint32_t fetchdat)
return 1;
}
// if (!cpu_use_dynarec && fpu_softfloat) {
#if 0
if (!cpu_use_dynarec && fpu_softfloat) {
#endif
if (fpu_softfloat) {
if (fpu_state.swd & FPU_SW_Summary) {
if (cr0 & 0x20) {

View File

@@ -46,10 +46,10 @@ opSYSEXIT(uint32_t fetchdat)
static int
sf_fx_save_stor_common(uint32_t fetchdat, int bits)
{
uint8_t fxinst = 0;
uint32_t tag_byte;
unsigned index;
floatx80 reg;
uint8_t fxinst = 0;
uint32_t tag_byte;
unsigned index;
floatx80 reg;
if (CPUID < 0x650)
return ILLEGAL(fetchdat);
@@ -129,33 +129,33 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
writememw(easeg, cpu_state.eaaddr + 6, fpu_state.foo);
/*
* x87 FPU IP Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32/64 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit IP offset
* + 32-bit mode - 32-bit IP offset
* + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved.
* x87 CS FPU IP Selector
* + 16 bit, in 16/32 bit mode only
*/
/*
* x87 FPU IP Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32/64 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit IP offset
* + 32-bit mode - 32-bit IP offset
* + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved.
* x87 CS FPU IP Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip);
writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs);
/*
* x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit offset
* + 32-bit mode - 32-bit offset
* + 16-bit mode - low 16 bits are offset; high 16 bits are reserved.
* x87 DS FPU Instruction Operand (Data) Pointer Selector
* + 16 bit, in 16/32 bit mode only
*/
/*
* x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit offset
* + 32-bit mode - 32-bit offset
* + 16-bit mode - low 16 bits are offset; high 16 bits are reserved.
* x87 DS FPU Instruction Operand (Data) Pointer Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp);
writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds);
/* store i387 register file */
/* store i387 register file */
for (index = 0; index < 8; index++) {
const floatx80 fp = FPU_read_regi(index);
@@ -172,70 +172,72 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
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;
int i, mmx_tags = 0;
uint16_t exp = 0x0000;
uint64_t mant = 0x0000000000000000ULL;
uint64_t fraction;
uint8_t jm, valid;
/* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent
----------------------------------------------+------ */
uint8_t ftw_table_idx;
uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */
0x02, /* 0 0 0 0 0 1 | 0x01 */
0x03, /* 0 0 0 0 0 0 | 0x02 */
0x02, /* 0 0 0 0 1 1 | 0x03 */
0x03, /* 0 0 0 1 0 0 | 0x04 */
0x00, /* 0 0 0 1 0 1 | 0x05 */
0x03, /* 0 0 0 1 1 0 | 0x06 */
0x00, /* 0 0 0 1 1 1 | 0x07 */
0x03, /* 0 0 1 0 0 0 | 0x08 */
0x02, /* 0 0 1 0 0 1 | 0x09 */
0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */
0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */
0x03, /* 0 0 1 1 0 0 | 0x0c */
0x02, /* 0 0 1 1 0 1 | 0x0d */
0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */
0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */
0x03, /* 0 1 0 0 0 0 | 0x10 */
0x02, /* 0 1 0 0 0 1 | 0x11 */
0x03, /* 0 1 0 0 1 0 | 0x12 */
0x02, /* 0 1 0 0 1 1 | 0x13 */
0x03, /* 0 1 0 1 0 0 | 0x14 */
0x02, /* 0 1 0 1 0 1 | 0x15 */
0x03, /* 0 1 0 1 1 0 | 0x16 */
0x02, /* 0 1 0 1 1 1 | 0x17 */
0x03, /* 0 1 1 0 0 0 | 0x18 */
0x01, /* 0 1 1 0 0 1 | 0x19 */
0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */
0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */
0x03, /* 0 1 1 1 0 0 | 0x1c */
0x01, /* 0 1 1 1 0 1 | 0x1d */
0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */
0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */
0x03, /* 1 0 0 0 0 0 | 0x20 */
0x02, /* 1 0 0 0 0 1 | 0x21 */
0x03, /* 1 0 0 0 1 0 | 0x22 */
0x02, /* 1 0 0 0 1 1 | 0x23 */
0x03, /* 1 0 0 1 0 0 | 0x24 */
0x02, /* 1 0 0 1 0 1 | 0x25 */
0x03, /* 1 0 0 1 1 0 | 0x26 */
0x02, /* 1 0 0 1 1 1 | 0x27 */
0x03, /* 1 0 1 0 0 0 | 0x28 */
0x02, /* 1 0 1 0 0 1 | 0x29 */
0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */
0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */
0x03, /* 1 0 1 1 0 0 | 0x2c */
0x02, /* 1 0 1 1 0 1 | 0x2d */
0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */
0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */
/* M is the most significant bit of the franction, so it is impossible
for M to o be 1 when the fraction is all 0's. */
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;
int i;
int mmx_tags = 0;
uint16_t exp = 0x0000;
uint64_t mant = 0x0000000000000000ULL;
uint64_t fraction;
uint8_t jm;
uint8_t valid;
/* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent
----------------------------------------------+------ */
uint8_t ftw_table_idx;
uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */
0x02, /* 0 0 0 0 0 1 | 0x01 */
0x03, /* 0 0 0 0 0 0 | 0x02 */
0x02, /* 0 0 0 0 1 1 | 0x03 */
0x03, /* 0 0 0 1 0 0 | 0x04 */
0x00, /* 0 0 0 1 0 1 | 0x05 */
0x03, /* 0 0 0 1 1 0 | 0x06 */
0x00, /* 0 0 0 1 1 1 | 0x07 */
0x03, /* 0 0 1 0 0 0 | 0x08 */
0x02, /* 0 0 1 0 0 1 | 0x09 */
0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */
0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */
0x03, /* 0 0 1 1 0 0 | 0x0c */
0x02, /* 0 0 1 1 0 1 | 0x0d */
0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */
0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */
0x03, /* 0 1 0 0 0 0 | 0x10 */
0x02, /* 0 1 0 0 0 1 | 0x11 */
0x03, /* 0 1 0 0 1 0 | 0x12 */
0x02, /* 0 1 0 0 1 1 | 0x13 */
0x03, /* 0 1 0 1 0 0 | 0x14 */
0x02, /* 0 1 0 1 0 1 | 0x15 */
0x03, /* 0 1 0 1 1 0 | 0x16 */
0x02, /* 0 1 0 1 1 1 | 0x17 */
0x03, /* 0 1 1 0 0 0 | 0x18 */
0x01, /* 0 1 1 0 0 1 | 0x19 */
0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */
0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */
0x03, /* 0 1 1 1 0 0 | 0x1c */
0x01, /* 0 1 1 1 0 1 | 0x1d */
0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */
0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */
0x03, /* 1 0 0 0 0 0 | 0x20 */
0x02, /* 1 0 0 0 0 1 | 0x21 */
0x03, /* 1 0 0 0 1 0 | 0x22 */
0x02, /* 1 0 0 0 1 1 | 0x23 */
0x03, /* 1 0 0 1 0 0 | 0x24 */
0x02, /* 1 0 0 1 0 1 | 0x25 */
0x03, /* 1 0 0 1 1 0 | 0x26 */
0x02, /* 1 0 0 1 1 1 | 0x27 */
0x03, /* 1 0 1 0 0 0 | 0x28 */
0x02, /* 1 0 1 0 0 1 | 0x29 */
0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */
0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */
0x03, /* 1 0 1 1 0 0 | 0x2c */
0x02, /* 1 0 1 1 0 1 | 0x2d */
0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */
0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */
/* M is the most significant bit of the franction, so it is impossible
for M to o be 1 when the fraction is all 0's. */
if (CPUID < 0x650)
return ILLEGAL(fetchdat);
@@ -285,11 +287,11 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
for (i = 0; i <= 7; i++) {
cpu_state.eaaddr = old_eaaddr + 32 + (i << 4);
mant = readmemq(easeg, cpu_state.eaaddr);
fraction = mant & 0x7fffffffffffffffULL;
exp = readmemw(easeg, cpu_state.eaaddr + 8);
jm = (mant >> 62) & 0x03;
valid = !(ftwb & (1 << i));
mant = readmemq(easeg, cpu_state.eaaddr);
fraction = mant & 0x7fffffffffffffffULL;
exp = readmemw(easeg, cpu_state.eaaddr + 8);
jm = (mant >> 62) & 0x03;
valid = !(ftwb & (1 << i));
ftw_table_idx = (!!(exp == 0x1111)) << 5;
ftw_table_idx |= (!!(exp == 0x0000)) << 4;
@@ -379,7 +381,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
static int
opFXSAVESTOR_a16(uint32_t fetchdat)
{
if (fpu_softfloat)
if (fpu_softfloat)
return sf_fx_save_stor_common(fetchdat, 16);
return fx_save_stor_common(fetchdat, 16);

View File

@@ -86,9 +86,10 @@ opJ(L)
opJ(NL)
opJ(LE)
opJ(NLE)
// clang-format on
// clang-format on
static int opLOOPNE_w(uint32_t fetchdat)
static int
opLOOPNE_w(uint32_t fetchdat)
{
int8_t offset = (int8_t) getbytef();
CX--;
@@ -271,8 +272,10 @@ opJMP_r32(uint32_t fetchdat)
static int
opJMP_far_a16(uint32_t fetchdat)
{
uint16_t addr, seg;
uint16_t addr;
uint16_t seg;
uint32_t old_pc;
addr = getwordf();
seg = getword();
if (cpu_state.abrt)
@@ -289,7 +292,9 @@ static int
opJMP_far_a32(uint32_t fetchdat)
{
uint16_t seg;
uint32_t addr, old_pc;
uint32_t addr;
uint32_t old_pc;
addr = getlong();
seg = getword();
if (cpu_state.abrt)
@@ -307,6 +312,7 @@ static int
opCALL_r16(uint32_t fetchdat)
{
int16_t addr = (int16_t) getwordf();
PUSH_W(cpu_state.pc);
cpu_state.pc += addr;
cpu_state.pc &= 0xffff;
@@ -320,6 +326,7 @@ static int
opCALL_r32(uint32_t fetchdat)
{
int32_t addr = getlong();
if (cpu_state.abrt)
return 1;
PUSH_L(cpu_state.pc);

View File

@@ -55,7 +55,8 @@ opF6_a16(uint32_t fetchdat)
int tempws2 = 0;
uint16_t tempw = 0;
uint16_t src16;
uint8_t src, dst;
uint8_t src;
uint8_t dst;
int8_t temps;
fetch_ea_16(fetchdat);
@@ -173,7 +174,8 @@ opF6_a32(uint32_t fetchdat)
int tempws2 = 0;
uint16_t tempw = 0;
uint16_t src16;
uint8_t src, dst;
uint8_t src;
uint8_t dst;
int8_t temps;
fetch_ea_32(fetchdat);
@@ -287,7 +289,7 @@ static int
opF7_w_a16(uint32_t fetchdat)
{
uint32_t templ;
uint32_t templ2 = 0;
uint32_t templ2 = 0;
int tempws;
int tempws2 = 0;
int16_t temps16;
@@ -400,11 +402,12 @@ static int
opF7_w_a32(uint32_t fetchdat)
{
uint32_t templ;
uint32_t templ2 = 0;
uint32_t templ2 = 0;
int tempws;
int tempws2 = 1;
int16_t temps16;
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -514,7 +517,8 @@ static int
opF7_l_a16(uint32_t fetchdat)
{
uint64_t temp64;
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -606,7 +610,8 @@ static int
opF7_l_a32(uint32_t fetchdat)
{
uint64_t temp64;
uint32_t src, dst;
uint32_t src;
uint32_t dst;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -739,7 +744,8 @@ opLOCK(uint32_t fetchdat)
static int
opBOUND_w_a16(uint32_t fetchdat)
{
int16_t low, high;
int16_t low;
int16_t high;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -761,7 +767,8 @@ opBOUND_w_a16(uint32_t fetchdat)
static int
opBOUND_w_a32(uint32_t fetchdat)
{
int16_t low, high;
int16_t low;
int16_t high;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -784,7 +791,8 @@ opBOUND_w_a32(uint32_t fetchdat)
static int
opBOUND_l_a16(uint32_t fetchdat)
{
int32_t low, high;
int32_t low;
int32_t high;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -806,7 +814,8 @@ opBOUND_l_a16(uint32_t fetchdat)
static int
opBOUND_l_a32(uint32_t fetchdat)
{
int32_t low, high;
int32_t low;
int32_t high;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);

View File

@@ -27,7 +27,7 @@
#include "x86_flags.h"
#include "x86seg.h"
MMX_REG *MMP[8];
MMX_REG *MMP[8];
uint16_t *MMEP[8];
static uint16_t MME[8];
@@ -40,10 +40,10 @@ mmx_init(void)
for (uint8_t i = 0; i < 8; i++) {
if (fpu_softfloat) {
MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction;
MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction;
MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp;
} else {
MMP[i] = &(cpu_state.MM[i]);
MMP[i] = &(cpu_state.MM[i]);
MMEP[i] = &(MME[i]);
}
}

View File

@@ -1,12 +1,12 @@
#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val)))
#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val)))
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val)))
#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val)))
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
#define MMX_GETREGP(r) MMP[r]
#define MMX_GETREG(r) *(MMP[r])
#define MMX_GETREG(r) *(MMP[r])
#define MMX_SETEXP(r) \
#define MMX_SETEXP(r) \
*(MMEP[r]) = 0xffff
#define MMX_GETSRC() \

View File

@@ -1,7 +1,7 @@
static int
opPADDB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -27,7 +27,7 @@ opPADDB_a16(uint32_t fetchdat)
static int
opPADDB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -54,7 +54,7 @@ opPADDB_a32(uint32_t fetchdat)
static int
opPADDW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -76,7 +76,7 @@ opPADDW_a16(uint32_t fetchdat)
static int
opPADDW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -99,7 +99,7 @@ opPADDW_a32(uint32_t fetchdat)
static int
opPADDD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -119,7 +119,7 @@ opPADDD_a16(uint32_t fetchdat)
static int
opPADDD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -140,7 +140,7 @@ opPADDD_a32(uint32_t fetchdat)
static int
opPADDSB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -166,7 +166,7 @@ opPADDSB_a16(uint32_t fetchdat)
static int
opPADDSB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -193,7 +193,7 @@ opPADDSB_a32(uint32_t fetchdat)
static int
opPADDUSB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -219,7 +219,7 @@ opPADDUSB_a16(uint32_t fetchdat)
static int
opPADDUSB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -246,7 +246,7 @@ opPADDUSB_a32(uint32_t fetchdat)
static int
opPADDSW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -268,7 +268,7 @@ opPADDSW_a16(uint32_t fetchdat)
static int
opPADDSW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -291,7 +291,7 @@ opPADDSW_a32(uint32_t fetchdat)
static int
opPADDUSW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -313,7 +313,7 @@ opPADDUSW_a16(uint32_t fetchdat)
static int
opPADDUSW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -336,7 +336,7 @@ opPADDUSW_a32(uint32_t fetchdat)
static int
opPMADDWD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -363,7 +363,7 @@ opPMADDWD_a16(uint32_t fetchdat)
static int
opPMADDWD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -391,7 +391,7 @@ opPMADDWD_a32(uint32_t fetchdat)
static int
opPMULLW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -422,7 +422,7 @@ opPMULLW_a16(uint32_t fetchdat)
static int
opPMULLW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -454,7 +454,7 @@ opPMULLW_a32(uint32_t fetchdat)
static int
opPMULHW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -485,7 +485,7 @@ opPMULHW_a16(uint32_t fetchdat)
static int
opPMULHW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -517,7 +517,7 @@ opPMULHW_a32(uint32_t fetchdat)
static int
opPSUBB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -543,7 +543,7 @@ opPSUBB_a16(uint32_t fetchdat)
static int
opPSUBB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -570,7 +570,7 @@ opPSUBB_a32(uint32_t fetchdat)
static int
opPSUBW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -592,7 +592,7 @@ opPSUBW_a16(uint32_t fetchdat)
static int
opPSUBW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -615,7 +615,7 @@ opPSUBW_a32(uint32_t fetchdat)
static int
opPSUBD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -635,7 +635,7 @@ opPSUBD_a16(uint32_t fetchdat)
static int
opPSUBD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -656,7 +656,7 @@ opPSUBD_a32(uint32_t fetchdat)
static int
opPSUBSB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -682,7 +682,7 @@ opPSUBSB_a16(uint32_t fetchdat)
static int
opPSUBSB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -709,7 +709,7 @@ opPSUBSB_a32(uint32_t fetchdat)
static int
opPSUBUSB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -735,7 +735,7 @@ opPSUBUSB_a16(uint32_t fetchdat)
static int
opPSUBUSB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -762,7 +762,7 @@ opPSUBUSB_a32(uint32_t fetchdat)
static int
opPSUBSW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -784,7 +784,7 @@ opPSUBSW_a16(uint32_t fetchdat)
static int
opPSUBSW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -807,7 +807,7 @@ opPSUBSW_a32(uint32_t fetchdat)
static int
opPSUBUSW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -829,7 +829,7 @@ opPSUBUSW_a16(uint32_t fetchdat)
static int
opPSUBUSW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();

View File

@@ -1,7 +1,7 @@
static int
opPCMPEQB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -27,7 +27,7 @@ opPCMPEQB_a16(uint32_t fetchdat)
static int
opPCMPEQB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -54,7 +54,7 @@ opPCMPEQB_a32(uint32_t fetchdat)
static int
opPCMPGTB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -80,7 +80,7 @@ opPCMPGTB_a16(uint32_t fetchdat)
static int
opPCMPGTB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -107,7 +107,7 @@ opPCMPGTB_a32(uint32_t fetchdat)
static int
opPCMPEQW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -129,7 +129,7 @@ opPCMPEQW_a16(uint32_t fetchdat)
static int
opPCMPEQW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -152,7 +152,7 @@ opPCMPEQW_a32(uint32_t fetchdat)
static int
opPCMPGTW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -174,7 +174,7 @@ opPCMPGTW_a16(uint32_t fetchdat)
static int
opPCMPGTW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -197,7 +197,7 @@ opPCMPGTW_a32(uint32_t fetchdat)
static int
opPCMPEQD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -217,7 +217,7 @@ opPCMPEQD_a16(uint32_t fetchdat)
static int
opPCMPEQD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -238,7 +238,7 @@ opPCMPEQD_a32(uint32_t fetchdat)
static int
opPCMPGTD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -258,7 +258,7 @@ opPCMPGTD_a16(uint32_t fetchdat)
static int
opPCMPGTD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();

View File

@@ -1,7 +1,7 @@
static int
opPAND_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -20,7 +20,7 @@ opPAND_a16(uint32_t fetchdat)
static int
opPAND_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -40,7 +40,7 @@ opPAND_a32(uint32_t fetchdat)
static int
opPANDN_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -59,7 +59,7 @@ opPANDN_a16(uint32_t fetchdat)
static int
opPANDN_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -79,7 +79,7 @@ opPANDN_a32(uint32_t fetchdat)
static int
opPOR_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -98,7 +98,7 @@ opPOR_a16(uint32_t fetchdat)
static int
opPOR_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -118,7 +118,7 @@ opPOR_a32(uint32_t fetchdat)
static int
opPXOR_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -137,7 +137,7 @@ opPXOR_a16(uint32_t fetchdat)
static int
opPXOR_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();

View File

@@ -115,7 +115,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat)
static int
opMOVD_mm_l_a16_cx(uint32_t fetchdat)
{
MMX_REG *op;
const MMX_REG *op;
if (in_smm)
return opSMINT(fetchdat);
@@ -144,7 +144,7 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat)
static int
opMOVD_mm_l_a32_cx(uint32_t fetchdat)
{
MMX_REG *op;
const MMX_REG *op;
if (in_smm)
return opSMINT(fetchdat);
@@ -176,14 +176,14 @@ static int
opMOVQ_q_mm_a16(uint32_t fetchdat)
{
uint64_t dst;
MMX_REG src;
MMX_REG src;
MMX_REG *op;
MMX_ENTER();
fetch_ea_16(fetchdat);
src = MMX_GETREG(cpu_rm);
op = MMX_GETREGP(cpu_reg);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
op->q = src.q;
@@ -206,14 +206,14 @@ static int
opMOVQ_q_mm_a32(uint32_t fetchdat)
{
uint64_t dst;
MMX_REG src;
MMX_REG src;
MMX_REG *op;
MMX_ENTER();
fetch_ea_32(fetchdat);
src = MMX_GETREG(cpu_rm);
op = MMX_GETREGP(cpu_reg);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
op->q = src.q;
@@ -236,7 +236,7 @@ opMOVQ_q_mm_a32(uint32_t fetchdat)
static int
opMOVQ_mm_q_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -266,7 +266,7 @@ opMOVQ_mm_q_a16(uint32_t fetchdat)
static int
opMOVQ_mm_q_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();

View File

@@ -2,7 +2,7 @@ static int
opPUNPCKLDQ_a16(uint32_t fetchdat)
{
uint32_t usrc;
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -32,7 +32,7 @@ static int
opPUNPCKLDQ_a32(uint32_t fetchdat)
{
uint32_t usrc;
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -62,7 +62,7 @@ opPUNPCKLDQ_a32(uint32_t fetchdat)
static int
opPUNPCKHDQ_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -82,7 +82,7 @@ opPUNPCKHDQ_a16(uint32_t fetchdat)
static int
opPUNPCKHDQ_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -103,7 +103,7 @@ opPUNPCKHDQ_a32(uint32_t fetchdat)
static int
opPUNPCKLBW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -129,7 +129,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat)
static int
opPUNPCKLBW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -156,7 +156,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat)
static int
opPUNPCKHBW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -182,7 +182,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat)
static int
opPUNPCKHBW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -209,7 +209,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat)
static int
opPUNPCKLWD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -231,7 +231,7 @@ opPUNPCKLWD_a16(uint32_t fetchdat)
static int
opPUNPCKLWD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -254,7 +254,7 @@ opPUNPCKLWD_a32(uint32_t fetchdat)
static int
opPUNPCKHWD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -276,7 +276,7 @@ opPUNPCKHWD_a16(uint32_t fetchdat)
static int
opPUNPCKHWD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -299,7 +299,7 @@ opPUNPCKHWD_a32(uint32_t fetchdat)
static int
opPACKSSWB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -325,7 +325,7 @@ opPACKSSWB_a16(uint32_t fetchdat)
static int
opPACKSSWB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -352,7 +352,7 @@ opPACKSSWB_a32(uint32_t fetchdat)
static int
opPACKUSWB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -378,7 +378,7 @@ opPACKUSWB_a16(uint32_t fetchdat)
static int
opPACKUSWB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
@@ -405,14 +405,14 @@ opPACKUSWB_a32(uint32_t fetchdat)
static int
opPACKSSDW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_REG dst2;
MMX_REG dst2;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
dst = MMX_GETREGP(cpu_reg);
dst2 = *dst;
MMX_GETSRC();
@@ -429,14 +429,14 @@ opPACKSSDW_a16(uint32_t fetchdat)
static int
opPACKSSDW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG src;
MMX_REG *dst;
MMX_REG dst2;
MMX_REG dst2;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
dst = MMX_GETREGP(cpu_reg);
dst2 = *dst;
MMX_GETSRC();

View File

@@ -13,9 +13,9 @@
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;
MMX_REG *dst;
cpu_state.pc += 2;
@@ -67,7 +67,7 @@ static int
opPSLLW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -94,7 +94,7 @@ static int
opPSLLW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -122,7 +122,7 @@ static int
opPSRLW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -149,7 +149,7 @@ static int
opPSRLW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -177,7 +177,7 @@ static int
opPSRAW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -203,7 +203,7 @@ static int
opPSRAW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -229,9 +229,9 @@ opPSRAW_a32(uint32_t fetchdat)
static int
opPSxxD_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;
MMX_REG *dst;
cpu_state.pc += 2;
@@ -278,7 +278,7 @@ static int
opPSLLD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -303,7 +303,7 @@ static int
opPSLLD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -329,7 +329,7 @@ static int
opPSRLD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -354,7 +354,7 @@ static int
opPSRLD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -380,7 +380,7 @@ static int
opPSRAD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -404,7 +404,7 @@ static int
opPSRAD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -428,9 +428,9 @@ opPSRAD_a32(uint32_t fetchdat)
static int
opPSxxQ_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;
MMX_REG *dst;
cpu_state.pc += 2;
@@ -474,7 +474,7 @@ static int
opPSLLQ_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -497,7 +497,7 @@ static int
opPSLLQ_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -521,7 +521,7 @@ static int
opPSRLQ_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();
@@ -544,7 +544,7 @@ static int
opPSRLQ_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
int shift;
MMX_ENTER();

View File

@@ -769,83 +769,84 @@ opMOV_r_l_a32(uint32_t fetchdat)
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; \
}
#ifndef OPS_286_386
# define opCMOV(condition) \
static int opCMOV##condition##_w_a16(uint32_t fetchdat) \
{ \
fetch_ea_16(fetchdat); \
if (cond_##condition) { \
if (cpu_mod == 3) \
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
else { \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
temp = geteaw(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = temp; \
} \
} \
CLOCK_CYCLES(1); \
return 0; \
} \
static int opCMOV##condition##_w_a32(uint32_t fetchdat) \
{ \
fetch_ea_32(fetchdat); \
if (cond_##condition) { \
if (cpu_mod == 3) \
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
else { \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
temp = geteaw(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = temp; \
} \
} \
CLOCK_CYCLES(1); \
return 0; \
} \
static int opCMOV##condition##_l_a16(uint32_t fetchdat) \
{ \
fetch_ea_16(fetchdat); \
if (cond_##condition) { \
if (cpu_mod == 3) \
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
else { \
uint32_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
temp = geteal(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = temp; \
} \
} \
CLOCK_CYCLES(1); \
return 0; \
} \
static int opCMOV##condition##_l_a32(uint32_t fetchdat) \
{ \
fetch_ea_32(fetchdat); \
if (cond_##condition) { \
if (cpu_mod == 3) \
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
else { \
uint32_t temp; \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
SEG_CHECK_READ(cpu_state.ea_seg); \
temp = geteal(); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = temp; \
} \
} \
CLOCK_CYCLES(1); \
return 0; \
}
// clang-format off
opCMOV(O)
@@ -865,3 +866,4 @@ opCMOV(NL)
opCMOV(LE)
opCMOV(NLE)
// clang-format on
#endif

View File

@@ -251,12 +251,17 @@ opMOV_DRx_r_a32(uint32_t fetchdat)
static void
opMOV_r_TRx(void)
{
// uint32_t base;
#if 0
uint32_t base;
base = _tr[4] & 0xfffff800;
#endif
// base = _tr[4] & 0xfffff800;
switch (cpu_reg) {
case 3:
// pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
#if 0
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
#endif
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
cache_index = (cache_index + 4) & 0xf;
break;
@@ -293,42 +298,57 @@ static void
opMOV_TRx_r(void)
{
uint32_t base;
int i, ctl;
int i;
int 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]);
#if 0
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
#endif
*(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);
#if 0
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
#endif
break;
case 5:
// pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
#if 0
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
#endif
if (!(_tr[5] & (1 << 19))) {
switch (ctl) {
case 0:
// pclog(" Cache fill or read...\n", base);
#if 0
pclog(" Cache fill or read...\n", base);
#endif
break;
case 1:
base += (_tr[5] & 0x7f0);
// pclog(" Writing 16 bytes to %08X...\n", base);
#if 0
pclog(" Writing 16 bytes to %08X...\n", base);
#endif
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);
#if 0
pclog(" Reading 16 bytes from %08X...\n", base);
#endif
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);
#if 0
pclog(" Cache invalidate/flush...\n", base);
#endif
break;
}
}

View File

@@ -258,7 +258,8 @@ opMOV_seg_w_a32(uint32_t fetchdat)
static int
opLDS_w_a16(uint32_t fetchdat)
{
uint16_t addr, seg;
uint16_t addr;
uint16_t seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -280,7 +281,8 @@ opLDS_w_a16(uint32_t fetchdat)
static int
opLDS_w_a32(uint32_t fetchdat)
{
uint16_t addr, seg;
uint16_t addr;
uint16_t seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -349,7 +351,8 @@ opLDS_l_a32(uint32_t fetchdat)
static int
opLSS_w_a16(uint32_t fetchdat)
{
uint16_t addr, seg;
uint16_t addr;
uint16_t seg;
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -371,7 +374,8 @@ opLSS_w_a16(uint32_t fetchdat)
static int
opLSS_w_a32(uint32_t fetchdat)
{
uint16_t addr, seg;
uint16_t addr;
uint16_t seg;
fetch_ea_32(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
@@ -532,4 +536,4 @@ opLSS_l_a32(uint32_t fetchdat)
opLsel(ES, cpu_state.seg_es)
opLsel(FS, cpu_state.seg_fs)
opLsel(GS, cpu_state.seg_gs)
// clang-format on
// clang-format on

View File

@@ -2,7 +2,8 @@ static int
opIMUL_w_iw_a16(uint32_t fetchdat)
{
int32_t templ;
int16_t tempw, tempw2;
int16_t tempw;
int16_t tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -31,7 +32,8 @@ static int
opIMUL_w_iw_a32(uint32_t fetchdat)
{
int32_t templ;
int16_t tempw, tempw2;
int16_t tempw;
int16_t tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -61,7 +63,8 @@ static int
opIMUL_l_il_a16(uint32_t fetchdat)
{
int64_t temp64;
int32_t templ, templ2;
int32_t templ;
int32_t templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -90,7 +93,8 @@ static int
opIMUL_l_il_a32(uint32_t fetchdat)
{
int64_t temp64;
int32_t templ, templ2;
int32_t templ;
int32_t templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -120,7 +124,8 @@ static int
opIMUL_w_ib_a16(uint32_t fetchdat)
{
int32_t templ;
int16_t tempw, tempw2;
int16_t tempw;
int16_t tempw2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -151,7 +156,8 @@ static int
opIMUL_w_ib_a32(uint32_t fetchdat)
{
int32_t templ;
int16_t tempw, tempw2;
int16_t tempw;
int16_t tempw2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -183,7 +189,8 @@ static int
opIMUL_l_ib_a16(uint32_t fetchdat)
{
int64_t temp64;
int32_t templ, templ2;
int32_t templ;
int32_t templ2;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -214,7 +221,8 @@ static int
opIMUL_l_ib_a32(uint32_t fetchdat)
{
int64_t temp64;
int32_t templ, templ2;
int32_t templ;
int32_t templ2;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)

View File

@@ -179,10 +179,16 @@ opLAR(w_a16, fetch_ea_16, 0, 0)
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;
int valid;
int granularity;
uint32_t addr;
uint32_t base;
uint32_t limit;
uint16_t desc;
uint16_t sel;
uint8_t access;
uint8_t ar_high;
switch (rmdat & 0x38) {
case 0x00: /*SLDT*/
@@ -356,7 +362,9 @@ static int
op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
{
uint32_t base;
uint16_t limit, tempw;
uint16_t limit;
uint16_t tempw;
switch (rmdat & 0x38) {
case 0x00: /*SGDT*/
if (cpu_mod != 3)

View File

@@ -88,9 +88,10 @@ 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
// 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)

863
src/cpu/x86_ops_rep_2386.h Normal file
View File

@@ -0,0 +1,863 @@
#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, 1); \
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, 2); \
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, 4); \
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, 1); \
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, 2); \
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, 4); \
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); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
high_page = 0; \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
if (cpu_state.abrt) \
break; \
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); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
high_page = 0; \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) \
break; \
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); \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
high_page = 0; \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) \
break; \
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); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
high_page = uncached = 0; \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
if (cpu_state.abrt) \
return 1; \
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; \
temp2 = readmemb_n(es, DEST_REG, addr64_2); \
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 ? 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); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
high_page = uncached = 0; \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) \
return 1; \
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; \
temp2 = readmemw_n(es, DEST_REG, addr64a_2); \
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 ? 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); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
high_page = uncached = 0; \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) \
return 1; \
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; \
temp2 = readmeml_n(es, DEST_REG, addr64a_2); \
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 ? 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(a32_NE, ECX, ESI, EDI, 0)
REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
static int
opREPNE(uint32_t fetchdat)
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}
static int
opREPE(uint32_t fetchdat)
{
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt)
return 1;
cpu_state.pc++;
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
}

View File

@@ -190,7 +190,9 @@ opIRET(uint32_t fetchdat)
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
if (cr4 & CR4_VME) {
uint16_t new_pc, new_cs, new_flags;
uint16_t new_pc;
uint16_t new_cs;
uint16_t new_flags;
new_pc = readmemw(ss, SP);
new_cs = readmemw(ss, ((SP + 2) & 0xffff));

View File

@@ -36,4 +36,4 @@ opSET(L)
opSET(NL)
opSET(LE)
opSET(NLE)
// clang-format on
// clang-format on

View File

@@ -605,7 +605,8 @@ opC0_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -624,7 +625,8 @@ opC0_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -643,7 +645,8 @@ opC1_w_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -662,7 +665,8 @@ opC1_w_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -681,7 +685,8 @@ opC1_l_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -700,7 +705,8 @@ opC1_l_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -720,7 +726,8 @@ opD0_a16(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -736,7 +743,8 @@ opD0_a32(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -752,7 +760,8 @@ opD1_w_a16(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -768,7 +777,8 @@ opD1_w_a32(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -784,7 +794,8 @@ opD1_l_a16(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -800,7 +811,8 @@ opD1_l_a32(uint32_t fetchdat)
{
int c = 1;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -817,7 +829,8 @@ opD2_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -834,7 +847,8 @@ opD2_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint8_t temp, temp2 = 0;
uint8_t temp;
uint8_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -851,7 +865,8 @@ opD3_w_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -868,7 +883,8 @@ opD3_w_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint16_t temp, temp2 = 0;
uint16_t temp;
uint16_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -885,7 +901,8 @@ opD3_l_a16(uint32_t fetchdat)
{
int c;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -902,7 +919,8 @@ opD3_l_a32(uint32_t fetchdat)
{
int c;
int tempc;
uint32_t temp, temp2 = 0;
uint32_t temp;
uint32_t temp2 = 0;
fetch_ea_32(fetchdat);
if (cpu_mod != 3)
@@ -1053,4 +1071,4 @@ opSHxD(SHLD_w)
opSHxD(SHLD_l)
opSHxD(SHRD_w)
opSHxD(SHRD_l)
// clang-format on
// clang-format on

View File

@@ -189,22 +189,50 @@ 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;
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;
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);
@@ -379,9 +407,13 @@ opENTER_w(uint32_t fetchdat)
{
uint16_t offset;
int count;
uint32_t tempEBP, tempESP, frame_ptr;
uint32_t tempEBP;
uint32_t tempESP;
uint32_t frame_ptr;
#ifndef IS_DYNAREC
int reads = 0, writes = 1, instr_cycles = 0;
int reads = 0;
int writes = 1;
int instr_cycles = 0;
#endif
uint16_t tempw;
@@ -448,9 +480,13 @@ opENTER_l(uint32_t fetchdat)
{
uint16_t offset;
int count;
uint32_t tempEBP, tempESP, frame_ptr;
uint32_t tempEBP;
uint32_t tempESP;
uint32_t frame_ptr;
#ifndef IS_DYNAREC
int reads = 0, writes = 1, instr_cycles = 0;
int reads = 0;
int writes = 1;
int instr_cycles = 0;
#endif
uint32_t templ;

View File

@@ -219,7 +219,8 @@ opMOVSL_a32(uint32_t fetchdat)
static int
opCMPSB_a16(uint32_t fetchdat)
{
uint8_t src, dst;
uint8_t src;
uint8_t dst;
addr64 = addr64_2 = 0x00000000;
@@ -259,7 +260,8 @@ opCMPSB_a16(uint32_t fetchdat)
static int
opCMPSB_a32(uint32_t fetchdat)
{
uint8_t src, dst;
uint8_t src;
uint8_t dst;
addr64 = addr64_2 = 0x00000000;
@@ -300,7 +302,8 @@ opCMPSB_a32(uint32_t fetchdat)
static int
opCMPSW_a16(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
addr64a[0] = addr64a[1] = 0x00000000;
addr64a_2[0] = addr64a_2[1] = 0x00000000;
@@ -341,7 +344,8 @@ opCMPSW_a16(uint32_t fetchdat)
static int
opCMPSW_a32(uint32_t fetchdat)
{
uint16_t src, dst;
uint16_t src;
uint16_t dst;
addr64a[0] = addr64a[1] = 0x00000000;
addr64a_2[0] = addr64a_2[1] = 0x00000000;
@@ -383,7 +387,8 @@ opCMPSW_a32(uint32_t fetchdat)
static int
opCMPSL_a16(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;
@@ -424,7 +429,8 @@ opCMPSL_a16(uint32_t fetchdat)
static int
opCMPSL_a32(uint32_t fetchdat)
{
uint32_t src, dst;
uint32_t src;
uint32_t dst;
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;

File diff suppressed because it is too large Load Diff

View File

@@ -275,4 +275,4 @@ opBSWAP(ESI)
opBSWAP(EDI)
opBSWAP(EBP)
opBSWAP(ESP)
// clang-format on
// clang-format on

View File

@@ -31,13 +31,17 @@
#include <86box/machine.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#include "x86.h"
#include "x86_flags.h"
#include "386_common.h"
uint8_t opcode2;
int cgate16, cgate32;
int cgate16;
int cgate32;
int intgatesize;
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
@@ -157,7 +161,7 @@ x86_doabrt(int x86_abrt)
}
void
x86de(char *s, uint16_t error)
x86de(UNUSED(char *s), UNUSED(uint16_t error))
{
#ifdef BAD_CODE
cpu_state.abrt = ABRT_DE;
@@ -168,35 +172,35 @@ x86de(char *s, uint16_t error)
}
void
x86gpf(char *s, uint16_t error)
x86gpf(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF;
abrt_error = error;
}
void
x86gpf_expected(char *s, uint16_t error)
x86gpf_expected(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
abrt_error = error;
}
void
x86ss(char *s, uint16_t error)
x86ss(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_SS;
abrt_error = error;
}
void
x86ts(char *s, uint16_t error)
x86ts(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_TS;
abrt_error = error;
}
void
x86np(char *s, uint16_t error)
x86np(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_NP;
abrt_error = error;
@@ -272,9 +276,9 @@ do_seg_v86_init(x86seg *s)
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;
const x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt;
if (((s->seg & 0xfff8UL) + 7UL) > dt->limit)
valid = 0;
@@ -334,10 +338,11 @@ void
#endif
loadseg(uint16_t seg, x86seg *s)
{
uint16_t segdat[4];
uint32_t addr, *segdat32 = (uint32_t *) segdat;
int dpl;
x86seg *dt;
uint16_t segdat[4];
uint32_t addr;
uint32_t *segdat32 = (uint32_t *) segdat;
int dpl;
const x86seg *dt;
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
if (!(seg & 0xfffc)) {
@@ -531,9 +536,10 @@ loadseg(uint16_t seg, x86seg *s)
void
loadcs(uint16_t seg)
{
uint16_t segdat[4];
uint32_t addr, *segdat32 = (uint32_t *) segdat;
x86seg *dt;
uint16_t segdat[4];
uint32_t addr;
uint32_t *segdat32 = (uint32_t *) segdat;
const x86seg *dt;
x86seg_log("Load CS %04X\n", seg);
@@ -619,11 +625,13 @@ loadcs(uint16_t seg)
void
loadcsjmp(uint16_t seg, uint32_t old_pc)
{
uint16_t type, seg2;
uint16_t segdat[4];
uint32_t addr, newpc;
uint32_t *segdat32 = (uint32_t *) segdat;
x86seg *dt;
uint16_t type;
uint16_t seg2;
uint16_t segdat[4];
uint32_t addr;
uint32_t newpc;
uint32_t *segdat32 = (uint32_t *) segdat;
const x86seg *dt;
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
if (!(seg & 0xfffc)) {
@@ -743,7 +751,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc);
return;
}
/*FALLTHROUGH*/
fallthrough;
case 0x1c00:
case 0x1d00:
case 0x1e00:
@@ -890,16 +898,24 @@ 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;
uint32_t *segdat232 = (uint32_t *) segdat2;
int count, type;
uint32_t oldss, oldsp, newsp, oldsp2;
uint16_t tempw;
x86seg *dt;
uint16_t seg2;
uint16_t newss;
uint16_t segdat[4];
uint16_t segdat2[4];
uint32_t addr;
uint32_t oldssbase = ss;
uint32_t oaddr;
uint32_t newpc;
uint32_t *segdat32 = (uint32_t *) segdat;
uint32_t *segdat232 = (uint32_t *) segdat2;
int count;
int type;
uint32_t oldss;
uint32_t oldsp;
uint32_t newsp;
uint32_t oldsp2;
uint16_t tempw;
const x86seg *dt;
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
x86seg_log("Protected mode CS load! %04X\n", seg);
@@ -1174,7 +1190,7 @@ loadcscall(uint16_t seg)
x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc);
return;
}
/*FALLTHROUGH*/
fallthrough;
case 0x1c00:
case 0x1d00:
case 0x1e00:
@@ -1237,12 +1253,18 @@ loadcscall(uint16_t seg)
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;
uint32_t *segdat232 = (uint32_t *) segdat2;
x86seg *dt;
uint16_t segdat[4];
uint16_t segdat2[4];
uint16_t seg;
uint16_t newss;
uint32_t newpc;
uint32_t newsp;
uint32_t addr;
uint32_t oaddr;
uint32_t oldsp = ESP;
uint32_t *segdat32 = (uint32_t *) segdat;
uint32_t *segdat232 = (uint32_t *) segdat2;
const x86seg *dt;
x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags);
if (is32) {
@@ -1467,17 +1489,22 @@ pmoderetf(int is32, uint16_t off)
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;
uint32_t *segdat232 = (uint32_t *) segdat2;
uint32_t *segdat332 = (uint32_t *) segdat3;
x86seg *dt;
uint16_t segdat[4];
uint16_t segdat2[4];
uint16_t segdat3[4];
uint16_t newss;
uint16_t seg = 0;
int type;
int new_cpl;
uint32_t addr;
uint32_t oaddr;
uint32_t oldss;
uint32_t oldsp;
uint32_t newsp;
uint32_t *segdat32 = (uint32_t *) segdat;
uint32_t *segdat232 = (uint32_t *) segdat2;
uint32_t *segdat332 = (uint32_t *) segdat3;
const x86seg *dt;
if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) {
x86seg_log("V86 banned int\n");
@@ -1661,7 +1688,7 @@ pmodeint(int num, int soft)
x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc);
return;
}
/*FALLTHROUGH*/
fallthrough;
case 0x1c00:
case 0x1d00:
case 0x1e00:
@@ -1750,16 +1777,21 @@ pmodeint(int num, int soft)
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;
uint32_t *segdat232 = (uint32_t *) segdat2;
x86seg *dt;
uint16_t newss;
uint16_t seg = 0;
uint16_t segdat[4];
uint16_t segdat2[4];
uint16_t segs[4];
uint32_t tempflags;
uint32_t flagmask;
uint32_t newpc;
uint32_t newsp;
uint32_t addr;
uint32_t oaddr;
uint32_t oldsp = ESP;
uint32_t *segdat32 = (uint32_t *) segdat;
uint32_t *segdat232 = (uint32_t *) segdat2;
const x86seg *dt;
if (is386 && (cpu_state.eflags & VM_FLAG)) {
if (IOPL != 3) {
@@ -2058,15 +2090,32 @@ pmodeiret(int is32)
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;
uint32_t *segdat232 = (uint32_t *) segdat2;
x86seg *dt;
uint16_t tempw;
uint16_t new_ldt;
uint16_t new_es;
uint16_t new_cs;
uint16_t new_ss;
uint16_t new_ds;
uint16_t new_fs;
uint16_t new_gs;
uint16_t segdat2[4];
uint32_t base;
uint32_t limit;
uint32_t templ;
uint32_t new_cr3 = 0;
uint32_t new_eax;
uint32_t new_ebx;
uint32_t new_ecx;
uint32_t new_edx;
uint32_t new_esp;
uint32_t new_ebp;
uint32_t new_esi;
uint32_t new_edi;
uint32_t new_pc;
uint32_t new_flags;
uint32_t addr;
uint32_t *segdat232 = (uint32_t *) segdat2;
const x86seg *dt;
base = segdat[1] | ((segdat[2] & 0x00ff) << 16);
limit = segdat[0];
@@ -2447,7 +2496,8 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
void
cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
{
uint16_t segdat[4], selector;
uint16_t segdat[4];
uint16_t selector;
segdat[0] = readmemw(0, addr);
segdat[1] = readmemw(0, addr + 2);

View File

@@ -17,8 +17,10 @@
#include "386_common.h"
#include "softfloat/softfloat-specialize.h"
uint32_t x87_pc_off, x87_op_off;
uint16_t x87_pc_seg, x87_op_seg;
uint32_t x87_pc_off;
uint32_t x87_op_off;
uint16_t x87_pc_seg;
uint16_t x87_op_seg;
#ifdef ENABLE_FPU_LOG
int fpu_do_log = ENABLE_FPU_LOG;
@@ -43,9 +45,8 @@ uint16_t
x87_gettag(void)
{
uint16_t ret = 0;
int c;
for (c = 0; c < 8; c++) {
for (uint8_t 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)
@@ -62,9 +63,7 @@ x87_gettag(void)
void
x87_settag(uint16_t new_tag)
{
int c;
for (c = 0; c < 8; c++) {
for (uint8_t c = 0; c < 8; c++) {
int tag = (new_tag >> (c * 2)) & 3;
if (tag == X87_TAG_EMPTY)
@@ -106,7 +105,6 @@ x87_settag(uint16_t new_tag)
}
#endif
static floatx80
FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct float_status_t *status)
{
@@ -119,24 +117,27 @@ FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct fl
// propagate QNaN to SNaN
a = propagateFloatx80NaNOne(a, status);
if (aIsNaN & !bIsNaN) return a;
if (aIsNaN & !bIsNaN)
return a;
// float32 is NaN so conversion will propagate SNaN to QNaN and raise
// appropriate exception flags
floatx80 b = float32_to_floatx80(b32, status);
if (aIsSignalingNaN) {
if (bIsSignalingNaN) goto returnLargerSignificand;
if (bIsSignalingNaN)
goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if (aIsNaN) {
if (bIsSignalingNaN) return a;
returnLargerSignificand:
if (a.fraction < b.fraction) return b;
if (b.fraction < a.fraction) return a;
} else if (aIsNaN) {
if (bIsSignalingNaN)
return a;
returnLargerSignificand:
if (a.fraction < b.fraction)
return b;
if (b.fraction < a.fraction)
return a;
return (a.exp < b.exp) ? a : b;
}
else {
} else {
return b;
}
}
@@ -152,7 +153,8 @@ FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *stat
return 1;
}
int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b);
int aIsNaN = floatx80_is_nan(a);
int bIsNaN = float32_is_nan(b);
if (aIsNaN | bIsNaN) {
*r = FPU_handle_NaN32_Func(a, aIsNaN, b, bIsNaN, status);
return 1;
@@ -172,24 +174,27 @@ FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct fl
// propagate QNaN to SNaN
a = propagateFloatx80NaNOne(a, status);
if (aIsNaN & !bIsNaN) return a;
if (aIsNaN & !bIsNaN)
return a;
// float64 is NaN so conversion will propagate SNaN to QNaN and raise
// appropriate exception flags
floatx80 b = float64_to_floatx80(b64, status);
if (aIsSignalingNaN) {
if (bIsSignalingNaN) goto returnLargerSignificand;
if (bIsSignalingNaN)
goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if (aIsNaN) {
if (bIsSignalingNaN) return a;
returnLargerSignificand:
if (a.fraction < b.fraction) return b;
if (b.fraction < a.fraction) return a;
} else if (aIsNaN) {
if (bIsSignalingNaN)
return a;
returnLargerSignificand:
if (a.fraction < b.fraction)
return b;
if (b.fraction < a.fraction)
return a;
return (a.exp < b.exp) ? a : b;
}
else {
} else {
return b;
}
}
@@ -205,7 +210,8 @@ FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *stat
return 1;
}
int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b);
int aIsNaN = floatx80_is_nan(a);
int bIsNaN = float64_is_nan(b);
if (aIsNaN | bIsNaN) {
*r = FPU_handle_NaN64_Func(a, aIsNaN, b, bIsNaN, status);
return 1;
@@ -217,7 +223,7 @@ struct float_status_t
i387cw_to_softfloat_status_word(uint16_t control_word)
{
struct float_status_t status;
int precision = control_word & FPU_CW_PC;
int precision = control_word & FPU_CW_PC;
switch (precision) {
case FPU_PR_32_BITS:
@@ -230,24 +236,23 @@ i387cw_to_softfloat_status_word(uint16_t control_word)
status.float_rounding_precision = 80;
break;
default:
/* With the precision control bits set to 01 "(reserved)", a
real CPU behaves as if the precision control bits were
set to 11 "80 bits" */
/* With the precision control bits set to 01 "(reserved)", a
real CPU behaves as if the precision control bits were
set to 11 "80 bits" */
status.float_rounding_precision = 80;
break;
}
status.float_exception_flags = 0; // clear exceptions before execution
status.float_nan_handling_mode = float_first_operand_nan;
status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10;
status.flush_underflow_to_zero = 0;
status.float_exception_flags = 0; // clear exceptions before execution
status.float_nan_handling_mode = float_first_operand_nan;
status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10;
status.flush_underflow_to_zero = 0;
status.float_suppress_exception = 0;
status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask;
status.denormals_are_zeros = 0;
status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask;
status.denormals_are_zeros = 0;
return status;
}
int
FPU_status_word_flags_fpu_compare(int float_relation)
{
@@ -256,16 +261,16 @@ FPU_status_word_flags_fpu_compare(int float_relation)
return (C0 | C2 | C3);
case float_relation_greater:
return (0);
return 0;
case float_relation_less:
return (C0);
return C0;
case float_relation_equal:
return (C3);
return C3;
}
return (-1); // should never get here
return (-1); // should never get here
}
void
@@ -280,11 +285,11 @@ FPU_write_eflags_fpu_compare(int float_relation)
break;
case float_relation_less:
cpu_state.flags |= (C_FLAG);
cpu_state.flags |= C_FLAG;
break;
case float_relation_equal:
cpu_state.flags |= (Z_FLAG);
cpu_state.flags |= Z_FLAG;
break;
default:
@@ -319,9 +324,9 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store)
fpu_state.swd |= exceptions;
if (exceptions & FPU_SW_Stack_Fault) {
if (!(exceptions & C1)) {
/* This bit distinguishes over- from underflow for a stack fault,
and roundup from round-down for precision loss. */
fpu_state.swd &= ~C1;
/* This bit distinguishes over- from underflow for a stack fault,
and roundup from round-down for precision loss. */
fpu_state.swd &= ~C1;
}
}
return unmasked;
@@ -354,8 +359,8 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store)
if (exceptions & FPU_EX_Precision) {
if (!(exceptions & C1)) {
/* This bit distinguishes over- from underflow for a stack fault,
and roundup from round-down for precision loss. */
/* This bit distinguishes over- from underflow for a stack fault,
and roundup from round-down for precision loss. */
fpu_state.swd &= ~C1;
}
}
@@ -444,14 +449,22 @@ pack_FPU_TW(uint16_t twd)
{
uint8_t tag_byte = 0;
if ((twd & 0x0003) != 0x0003) tag_byte |= 0x01;
if ((twd & 0x000c) != 0x000c) tag_byte |= 0x02;
if ((twd & 0x0030) != 0x0030) tag_byte |= 0x04;
if ((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08;
if ((twd & 0x0300) != 0x0300) tag_byte |= 0x10;
if ((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20;
if ((twd & 0x3000) != 0x3000) tag_byte |= 0x40;
if ((twd & 0xc000) != 0xc000) tag_byte |= 0x80;
if ((twd & 0x0003) != 0x0003)
tag_byte |= 0x01;
if ((twd & 0x000c) != 0x000c)
tag_byte |= 0x02;
if ((twd & 0x0030) != 0x0030)
tag_byte |= 0x04;
if ((twd & 0x00c0) != 0x00c0)
tag_byte |= 0x08;
if ((twd & 0x0300) != 0x0300)
tag_byte |= 0x10;
if ((twd & 0x0c00) != 0x0c00)
tag_byte |= 0x20;
if ((twd & 0x3000) != 0x3000)
tag_byte |= 0x40;
if ((twd & 0xc000) != 0xc000)
tag_byte |= 0x80;
return tag_byte;
}
@@ -461,45 +474,45 @@ unpack_FPU_TW(uint16_t tag_byte)
{
uint32_t twd = 0;
/* FTW
*
* Note that the original format for FTW can be recreated from the stored
* FTW valid bits and the stored 80-bit FP data (assuming the stored data
* was not the contents of MMX registers) using the following table:
/* FTW
*
* Note that the original format for FTW can be recreated from the stored
* FTW valid bits and the stored 80-bit FP data (assuming the stored data
* was not the contents of MMX registers) using the following table:
| Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW |
| all 1s | all 0s | all 0s | | | |
-------------------------------------------------------------------
| 0 | 0 | 0 | 0x | 1 | S 10 |
| 0 | 0 | 0 | 1x | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 0 | 1 | 00 | 1 | S 10 |
| 0 | 0 | 1 | 10 | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 1 | 0 | 0x | 1 | S 10 |
| 0 | 1 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 0 | 1 | 1 | 00 | 1 | Z 01 |
| 0 | 1 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 0 | 1x | 1 | S 10 |
| 1 | 0 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 1 | 00 | 1 | S 10 |
| 1 | 0 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| all combinations above | 0 | E 11 |
| Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW |
| all 1s | all 0s | all 0s | | | |
-------------------------------------------------------------------
| 0 | 0 | 0 | 0x | 1 | S 10 |
| 0 | 0 | 0 | 1x | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 0 | 1 | 00 | 1 | S 10 |
| 0 | 0 | 1 | 10 | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 1 | 0 | 0x | 1 | S 10 |
| 0 | 1 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 0 | 1 | 1 | 00 | 1 | Z 01 |
| 0 | 1 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 0 | 1x | 1 | S 10 |
| 1 | 0 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 1 | 00 | 1 | S 10 |
| 1 | 0 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| all combinations above | 0 | E 11 |
*
* The J-bit is defined to be the 1-bit binary integer to the left of
* the decimal place in the significand.
*
* The M-bit is defined to be the most significant bit of the fractional
* portion of the significand (i.e., the bit immediately to the right of
* the decimal place). When the M-bit is the most significant bit of the
* fractional portion of the significand, it must be 0 if the fraction
* is all 0's.
*/
*
* The J-bit is defined to be the 1-bit binary integer to the left of
* the decimal place in the significand.
*
* The M-bit is defined to be the most significant bit of the fractional
* portion of the significand (i.e., the bit immediately to the right of
* the decimal place). When the M-bit is the most significant bit of the
* fractional portion of the significand, it must be 0 if the fraction
* is all 0's.
*/
for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) {
if (tag_byte & 0x80) {

View File

@@ -3,8 +3,10 @@
#define X87_TAG_INVALID 2
#define X87_TAG_EMPTY 3
extern uint32_t x87_pc_off, x87_op_off;
extern uint16_t x87_pc_seg, x87_op_seg;
extern uint32_t x87_pc_off;
extern uint32_t x87_op_off;
extern uint16_t x87_pc_seg;
extern uint16_t x87_op_seg;
static __inline void
x87_set_mmx(void)
@@ -14,9 +16,9 @@ x87_set_mmx(void)
fpu_state.tag = 0;
fpu_state.tos = 0; /* reset FPU Top-Of-Stack */
} else {
cpu_state.TOP = 0;
p = (uint64_t *) cpu_state.tag;
*p = 0x0101010101010101ull;
cpu_state.TOP = 0;
p = (uint64_t *) cpu_state.tag;
*p = 0x0101010101010101ULL;
}
cpu_state.ismmx = 1;
}
@@ -29,8 +31,8 @@ x87_emms(void)
fpu_state.tag = 0xffff;
fpu_state.tos = 0; /* reset FPU Top-Of-Stack */
} else {
p = (uint64_t *) cpu_state.tag;
*p = 0;
p = (uint64_t *) cpu_state.tag;
*p = 0;
}
cpu_state.ismmx = 0;
}
@@ -58,81 +60,87 @@ void x87_settag(uint16_t new_tag);
void codegen_set_rounding_mode(int mode);
/* Status Word */
#define FPU_SW_Backward (0x8000) /* backward compatibility */
#define FPU_SW_C3 (0x4000) /* condition bit 3 */
#define FPU_SW_Top (0x3800) /* top of stack */
#define FPU_SW_C2 (0x0400) /* condition bit 2 */
#define FPU_SW_C1 (0x0200) /* condition bit 1 */
#define FPU_SW_C0 (0x0100) /* condition bit 0 */
#define FPU_SW_Summary (0x0080) /* exception summary */
#define FPU_SW_Stack_Fault (0x0040) /* stack fault */
#define FPU_SW_Precision (0x0020) /* loss of precision */
#define FPU_SW_Underflow (0x0010) /* underflow */
#define FPU_SW_Overflow (0x0008) /* overflow */
#define FPU_SW_Zero_Div (0x0004) /* divide by zero */
#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */
#define FPU_SW_Invalid (0x0001) /* invalid operation */
#define FPU_SW_Backward (0x8000) /* backward compatibility */
#define FPU_SW_C3 (0x4000) /* condition bit 3 */
#define FPU_SW_Top (0x3800) /* top of stack */
#define FPU_SW_C2 (0x0400) /* condition bit 2 */
#define FPU_SW_C1 (0x0200) /* condition bit 1 */
#define FPU_SW_C0 (0x0100) /* condition bit 0 */
#define FPU_SW_Summary (0x0080) /* exception summary */
#define FPU_SW_Stack_Fault (0x0040) /* stack fault */
#define FPU_SW_Precision (0x0020) /* loss of precision */
#define FPU_SW_Underflow (0x0010) /* underflow */
#define FPU_SW_Overflow (0x0008) /* overflow */
#define FPU_SW_Zero_Div (0x0004) /* divide by zero */
#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */
#define FPU_SW_Invalid (0x0001) /* invalid operation */
#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 FPU_SW_CC (C0 | C1 | C2 | C3)
#define FPU_SW_CC (C0 | C1 | C2 | C3)
#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */
#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */
/* Exception flags: */
#define FPU_EX_Precision (0x0020) /* loss of precision */
#define FPU_EX_Underflow (0x0010) /* underflow */
#define FPU_EX_Overflow (0x0008) /* overflow */
#define FPU_EX_Zero_Div (0x0004) /* divide by zero */
#define FPU_EX_Denormal (0x0002) /* denormalized operand */
#define FPU_EX_Invalid (0x0001) /* invalid operation */
#define FPU_EX_Precision (0x0020) /* loss of precision */
#define FPU_EX_Underflow (0x0010) /* underflow */
#define FPU_EX_Overflow (0x0008) /* overflow */
#define FPU_EX_Zero_Div (0x0004) /* divide by zero */
#define FPU_EX_Denormal (0x0002) /* denormalized operand */
#define FPU_EX_Invalid (0x0001) /* invalid operation */
/* Special exceptions: */
#define FPU_EX_Stack_Overflow (0x0041| C1) /* stack overflow */
#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */
#define FPU_EX_Stack_Overflow (0x0041 | C1) /* stack overflow */
#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */
/* precision control */
#define FPU_EX_Precision_Lost_Up (EX_Precision | C1)
#define FPU_EX_Precision_Lost_Dn (EX_Precision)
#define FPU_EX_Precision_Lost_Up (EX_Precision | C1)
#define FPU_EX_Precision_Lost_Dn (EX_Precision)
#define setcc(cc) \
fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) & FPU_SW_CC)
#define setcc(cc) \
fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) &FPU_SW_CC)
#define clear_C1() { fpu_state.swd &= ~C1; }
#define clear_C2() { fpu_state.swd &= ~C2; }
#define clear_C1() \
{ \
fpu_state.swd &= ~C1; \
}
#define clear_C2() \
{ \
fpu_state.swd &= ~C2; \
}
/* ************ */
/* Control Word */
/* ************ */
#define FPU_CW_Inf (0x1000) /* infinity control, legacy */
#define FPU_CW_Inf (0x1000) /* infinity control, legacy */
#define FPU_CW_RC (0x0C00) /* rounding control */
#define FPU_CW_PC (0x0300) /* precision control */
#define FPU_CW_RC (0x0C00) /* rounding control */
#define FPU_CW_PC (0x0300) /* precision control */
#define FPU_RC_RND (0x0000) /* rounding control */
#define FPU_RC_DOWN (0x0400)
#define FPU_RC_UP (0x0800)
#define FPU_RC_CHOP (0x0C00)
#define FPU_RC_RND (0x0000) /* rounding control */
#define FPU_RC_DOWN (0x0400)
#define FPU_RC_UP (0x0800)
#define FPU_RC_CHOP (0x0C00)
#define FPU_CW_Precision (0x0020) /* loss of precision mask */
#define FPU_CW_Underflow (0x0010) /* underflow mask */
#define FPU_CW_Overflow (0x0008) /* overflow mask */
#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */
#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */
#define FPU_CW_Invalid (0x0001) /* invalid operation mask */
#define FPU_CW_Precision (0x0020) /* loss of precision mask */
#define FPU_CW_Underflow (0x0010) /* underflow mask */
#define FPU_CW_Overflow (0x0008) /* overflow mask */
#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */
#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */
#define FPU_CW_Invalid (0x0001) /* invalid operation mask */
#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */
#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */
/* Precision control bits affect only the following:
ADD, SUB(R), MUL, DIV(R), and SQRT */
#define FPU_PR_32_BITS (0x000)
#define FPU_PR_RESERVED_BITS (0x100)
#define FPU_PR_64_BITS (0x200)
#define FPU_PR_80_BITS (0x300)
#define FPU_PR_32_BITS (0x000)
#define FPU_PR_RESERVED_BITS (0x100)
#define FPU_PR_64_BITS (0x200)
#define FPU_PR_80_BITS (0x300)
#include "softfloat/softfloatx80.h"
@@ -143,16 +151,16 @@ is_IA_masked(void)
}
struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word);
uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store);
int FPU_status_word_flags_fpu_compare(int float_relation);
void FPU_write_eflags_fpu_compare(int float_relation);
void FPU_stack_overflow(uint32_t fetchdat);
void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack);
int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status);
int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status);
int FPU_tagof(const floatx80 reg);
uint8_t pack_FPU_TW(uint16_t twd);
uint16_t unpack_FPU_TW(uint16_t tag_byte);
uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store);
int FPU_status_word_flags_fpu_compare(int float_relation);
void FPU_write_eflags_fpu_compare(int float_relation);
void FPU_stack_overflow(uint32_t fetchdat);
void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack);
int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status);
int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status);
int FPU_tagof(const floatx80 reg);
uint8_t pack_FPU_TW(uint16_t twd);
uint16_t unpack_FPU_TW(uint16_t tag_byte);
static __inline uint16_t
i387_get_control_word(void)
@@ -179,7 +187,7 @@ static __inline void
FPU_settagi_valid(int stnr)
{
int regnr = (stnr + fpu_state.tos) & 7;
fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00
fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00
}
static __inline void
@@ -226,16 +234,15 @@ FPU_save_regi_tag(floatx80 reg, int tag, int stnr)
FPU_settagi(tag, stnr);
}
#define FPU_check_pending_exceptions() \
do { \
if (fpu_state.swd & FPU_SW_Summary) { \
if (cr0 & 0x20) { \
x86_int(16); \
return 1; \
} else { \
picint(1 << 13); \
return 1; \
} \
} \
} while (0)
#define FPU_check_pending_exceptions() \
do { \
if (fpu_state.swd & FPU_SW_Summary) { \
if (cr0 & 0x20) { \
x86_int(16); \
return 1; \
} else { \
picint(1 << 13); \
return 1; \
} \
} \
} while (0)

Some files were not shown because too many files have changed in this diff Show More