From 0fa576d8bb84db8696fb8ca237bf2ec0061ad0e7 Mon Sep 17 00:00:00 2001
From: Cacodemon345
Date: Sat, 16 Mar 2024 01:45:23 +0600
Subject: [PATCH 001/567] Compile fixes for Qt6 on Windows
---
src/qt/qt_main.cpp | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp
index f87f8b6a93..1523d9a62f 100644
--- a/src/qt/qt_main.cpp
+++ b/src/qt/qt_main.cpp
@@ -17,6 +17,10 @@
* Copyright 2021-2022 Cacodemon345
* Copyright 2021-2022 Teemu Korhonen
*/
+
+#ifdef _WIN32
+#define UNICODE 1
+#endif
#include
#include
#include
@@ -220,13 +224,13 @@ main(int argc, char *argv[])
#ifdef Q_OS_WINDOWS
# if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624)
- HWND winbox = FindWindow("TWinBoxMain", NULL);
+ HWND winbox = FindWindow(L"TWinBoxMain", NULL);
if (winbox &&
- FindWindowEx(winbox, NULL, "TToolBar", NULL) &&
- FindWindowEx(winbox, NULL, "TListBox", NULL) &&
- FindWindowEx(winbox, NULL, "TStatusBar", NULL) &&
- (winbox = FindWindowEx(winbox, NULL, "TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */
- FindWindowEx(winbox, NULL, "TTabSheet", NULL))
+ FindWindowEx(winbox, NULL, L"TToolBar", NULL) &&
+ FindWindowEx(winbox, NULL, L"TListBox", NULL) &&
+ FindWindowEx(winbox, NULL, L"TStatusBar", NULL) &&
+ (winbox = FindWindowEx(winbox, NULL, L"TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */
+ FindWindowEx(winbox, NULL, L"TTabSheet", NULL))
# endif
{
QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("WinBox is no longer supported"),
From 7afe30205465fdeada5ecdf5961a177e2e804c14 Mon Sep 17 00:00:00 2001
From: Dimitar Angelov
Date: Tue, 2 Apr 2024 11:22:31 +0200
Subject: [PATCH 002/567] Adding Pravetz-16S definition
---
src/include/86box/machine.h | 1 +
src/machine/m_xt.c | 15 ++++++++++++++
src/machine/machine_table.c | 39 +++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index f97d1a37c2..7253a56568 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -918,6 +918,7 @@ extern int machine_xt_v20xt_init(const machine_t *);
extern int machine_xt_iskra3104_init(const machine_t *);
extern int machine_xt_pravetz16_imko4_init(const machine_t *);
+extern int machine_xt_pravetz16s_cpu12_init(const machine_t *);
extern int machine_xt_micoms_xl7turbo_init(const machine_t *);
/* m_xt_compaq.c */
diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c
index 9a0b39a89d..7baaa4ef30 100644
--- a/src/machine/m_xt.c
+++ b/src/machine/m_xt.c
@@ -368,6 +368,21 @@ machine_xt_pravetz16_imko4_init(const machine_t *model)
return ret;
}
+int
+machine_xt_pravetz16s_cpu12_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_linear("roms/machines/pravetz16s/PR16S.BIN",
+ 0x000fe000, 8192, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_xt_init_ex(model);
+ return ret;
+}
+
int
machine_xt_micoms_xl7turbo_init(const machine_t *model)
{
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index c2bb3925b2..6238bcbb55 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -1339,6 +1339,45 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
+ {
+ .name = "[8088] Pravetz 16S / CPU12",
+ .internal_name = "pravetz16s",
+ .type = MACHINE_TYPE_8088,
+ .chipset = MACHINE_CHIPSET_DISCRETE,
+ .init = machine_xt_pravetz16s_cpu12_init,
+ .p1_handler = NULL,
+ .gpio_handler = NULL,
+ .available_flag = MACHINE_AVAILABLE,
+ .gpio_acpi_handler = NULL,
+ .cpu = {
+ .package = CPU_PKG_8088,
+ .block = CPU_BLOCK_NONE,
+ .min_bus = 0,
+ .max_bus = 0,
+ .min_voltage = 0,
+ .max_voltage = 0,
+ .min_multi = 0,
+ .max_multi = 0
+ },
+ .bus_flags = MACHINE_PC,
+ .flags = MACHINE_FLAGS_NONE,
+ .ram = {
+ .min = 64,
+ .max = 640,
+ .step = 64
+ },
+ .nvrmask = 0,
+ .kbc_device = &keyboard_xt_device,
+ .kbc_p1 = 0xff,
+ .gpio = 0xffffffff,
+ .gpio_acpi = 0xffffffff,
+ .device = NULL,
+ .fdc_device = NULL,
+ .sio_device = NULL,
+ .vid_device = NULL,
+ .snd_device = NULL,
+ .net_device = NULL
+ },
{
.name = "[8088] Sanyo SX-16",
.internal_name = "sansx16",
From b9a39d07f865d730d712860ec12e0685c6805348 Mon Sep 17 00:00:00 2001
From: Dimitar Angelov
Date: Tue, 2 Apr 2024 15:44:57 +0200
Subject: [PATCH 003/567] Update of min/max bus and min/max RAM
---
src/machine/machine_table.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 6238bcbb55..4ac38f607f 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -1340,7 +1340,7 @@ const machine_t machines[] = {
.net_device = NULL
},
{
- .name = "[8088] Pravetz 16S / CPU12",
+ .name = "[8088] Pravetz 16S / CPU12+",
.internal_name = "pravetz16s",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
@@ -1352,8 +1352,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_8088,
.block = CPU_BLOCK_NONE,
- .min_bus = 0,
- .max_bus = 0,
+ .min_bus = 4772728,
+ .max_bus = 12000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -1362,9 +1362,9 @@ const machine_t machines[] = {
.bus_flags = MACHINE_PC,
.flags = MACHINE_FLAGS_NONE,
.ram = {
- .min = 64,
- .max = 640,
- .step = 64
+ .min = 512,
+ .max = 1024,
+ .step = 128
},
.nvrmask = 0,
.kbc_device = &keyboard_xt_device,
From 7aa3728c3f49c9f196601f2811c439ac376fe4ce Mon Sep 17 00:00:00 2001
From: Dimitar Angelov
Date: Tue, 2 Apr 2024 17:02:26 +0200
Subject: [PATCH 004/567] Corrected for CPU12 Plus
---
src/include/86box/machine.h | 2 +-
src/machine/m_xt.c | 2 +-
src/machine/machine_table.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index 7253a56568..6690a46c22 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -918,7 +918,7 @@ extern int machine_xt_v20xt_init(const machine_t *);
extern int machine_xt_iskra3104_init(const machine_t *);
extern int machine_xt_pravetz16_imko4_init(const machine_t *);
-extern int machine_xt_pravetz16s_cpu12_init(const machine_t *);
+extern int machine_xt_pravetz16s_cpu12p_init(const machine_t *);
extern int machine_xt_micoms_xl7turbo_init(const machine_t *);
/* m_xt_compaq.c */
diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c
index 7baaa4ef30..3c1539016a 100644
--- a/src/machine/m_xt.c
+++ b/src/machine/m_xt.c
@@ -369,7 +369,7 @@ machine_xt_pravetz16_imko4_init(const machine_t *model)
}
int
-machine_xt_pravetz16s_cpu12_init(const machine_t *model)
+machine_xt_pravetz16s_cpu12p_init(const machine_t *model)
{
int ret;
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 4ac38f607f..9f084d7231 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -1340,11 +1340,11 @@ const machine_t machines[] = {
.net_device = NULL
},
{
- .name = "[8088] Pravetz 16S / CPU12+",
+ .name = "[8088] Pravetz 16S / CPU12 Plus",
.internal_name = "pravetz16s",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
- .init = machine_xt_pravetz16s_cpu12_init,
+ .init = machine_xt_pravetz16s_cpu12p_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
From 072a6c5a05198f51fd1f69ee34f65e467b9b77f4 Mon Sep 17 00:00:00 2001
From: jbs
Date: Tue, 16 Apr 2024 11:50:53 -0300
Subject: [PATCH 005/567] For Qt5 add Gui Private Include Header. Fix C++ union
initializer syntax in src/sound/snd_opl_ymfm.cpp
---
src/qt/CMakeLists.txt | 6 +++++-
src/sound/snd_opl_ymfm.cpp | 8 ++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt
index 422989a443..b5204e7245 100644
--- a/src/qt/CMakeLists.txt
+++ b/src/qt/CMakeLists.txt
@@ -41,8 +41,12 @@ endif()
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
find_package(Threads REQUIRED)
-find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets Network OpenGL REQUIRED)
+find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets Network OpenGL Gui REQUIRED)
find_package(Qt${QT_MAJOR}LinguistTools REQUIRED NO_CMAKE_FIND_ROOT_PATH)
+if(NOT USE_QT6)
+ # For in src/qt/qt_mainwindow.cpp
+ include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
+endif ()
# TODO: Is this the correct way to do this, and is it required on any
# other platforms or with Qt 5?
diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp
index 55e7f19843..a08aac92b8 100644
--- a/src/sound/snd_opl_ymfm.cpp
+++ b/src/sound/snd_opl_ymfm.cpp
@@ -433,7 +433,7 @@ const device_t ym3812_ymfm_device = {
.init = ymfm_drv_init,
.close = ymfm_drv_close,
.reset = NULL,
- { .available = NULL },
+ .available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -447,7 +447,7 @@ const device_t ymf262_ymfm_device = {
.init = ymfm_drv_init,
.close = ymfm_drv_close,
.reset = NULL,
- { .available = NULL },
+ .available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -461,7 +461,7 @@ const device_t ymf289b_ymfm_device = {
.init = ymfm_drv_init,
.close = ymfm_drv_close,
.reset = NULL,
- { .available = NULL },
+ .available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -475,7 +475,7 @@ const device_t ymf278b_ymfm_device = {
.init = ymfm_drv_init,
.close = ymfm_drv_close,
.reset = NULL,
- { .available = NULL },
+ .available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
From 2ac3d289e624c85dc08fd00b79acc6af06974146 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Wed, 29 May 2024 20:47:22 +0200
Subject: [PATCH 006/567] Video changes part 1 for 4.2
1. Corrected the ATI 1881x clocks for use with the ATI Mach8/32 and VGA Wonder chips. The CPU slowdowns should now be gone.
2. Merged I/O ports common to both the ATI and IBM 8514/A compatible chips where they have identical code (extended behavior is still separate). Code duplication is now less than before.
3. Fixed a general polygon pattern issue in the Mach8/32 affecting calc.exe in Win3.x and other stuff.
4. Mode changes are, once again, changed (ATI and IBM), as close as possible to the real thing without destroying existing resolutions.
5. The 8514/A Vertical Counter has been extended to 0xfff so that it can take 1280x1024 resolutions well offered by the Mach32 as well as a better way to change the IBM/ATI modes through a callback swap where approprietate.
6. in 8514/A mode, reads from the 0x3c6-0x3c9 ramdac range is redirected to the 8514/A RAMDAC (0x2ea-0x2ed).
7. LFB access in the Mach32 now no longer takes account of the SVGA derived rops. Fixes Mach32 display on NeXTSTEP/OPENSTEP 3.x/4.x
8. Reworked the Display Sense Status and Subsystem Status ports so that they're not copycats from MAME and instead follow the datasheet.
---
src/include/86box/vid_8514a.h | 3 +-
src/include/86box/vid_ati_mach8.h | 1 +
src/include/86box/vid_svga.h | 38 +-
src/video/vid_8514a.c | 388 +++++++-------
src/video/vid_ati_mach8.c | 836 ++++++++++++------------------
src/video/vid_ics2494.c | 97 ++--
src/video/vid_svga.c | 15 +-
7 files changed, 632 insertions(+), 746 deletions(-)
diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h
index ac4085089b..def3f0f2ba 100644
--- a/src/include/86box/vid_8514a.h
+++ b/src/include/86box/vid_8514a.h
@@ -41,10 +41,10 @@ typedef union {
typedef struct ibm8514_t {
rom_t bios_rom;
- rom_t bios_rom2;
hwcursor8514_t hwcursor;
hwcursor8514_t hwcursor_latch;
uint8_t pos_regs[8];
+ char *rom_path;
int force_old_addr;
int type;
@@ -56,6 +56,7 @@ typedef struct ibm8514_t {
uint32_t vram_size;
uint32_t vram_mask;
uint32_t pallook[512];
+ uint32_t bios_addr;
PALETTE vgapal;
uint8_t hwcursor_oddeven;
diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h
index 7b5862f35e..a254329201 100644
--- a/src/include/86box/vid_ati_mach8.h
+++ b/src/include/86box/vid_ati_mach8.h
@@ -74,6 +74,7 @@ typedef struct mach_t {
uint16_t shadow_set;
uint16_t shadow_cntl;
int ext_on[2];
+ int extended_mode;
int compat_mode;
struct {
diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h
index 9eecebf2c3..3d68c1a34f 100644
--- a/src/include/86box/vid_svga.h
+++ b/src/include/86box/vid_svga.h
@@ -78,6 +78,7 @@ typedef struct svga_t {
uint8_t overlay_oddeven;
uint8_t fcr;
uint8_t hblank_overscan;
+ uint8_t vidsys_ena;
int dac_addr;
int dac_pos;
@@ -199,6 +200,7 @@ typedef struct svga_t {
void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr);
float (*getclock)(int clock, void *priv);
+ float (*getclock8514)(int clock, void *priv);
/* Called when VC=R18 and friends. If this returns zero then MA resetting
is skipped. Matrox Mystique in Power mode reuses this counter for
@@ -288,26 +290,32 @@ typedef struct svga_t {
void * dev8514;
void * ext8514;
+ void * clock_gen8514;
void * xga;
} svga_t;
-extern int vga_on;
-
-extern void ibm8514_poll(void *priv);
-extern void ibm8514_recalctimings(svga_t *svga);
-extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv);
-extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv);
-extern int ibm8514_cpu_src(svga_t *svga);
-extern int ibm8514_cpu_dest(svga_t *svga);
-extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len);
-extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
-extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
+extern int vga_on;
+
+extern void ibm8514_poll(void *priv);
+extern void ibm8514_recalctimings(svga_t *svga);
+extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv);
+extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv);
+extern void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len);
+extern void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len);
+extern uint16_t ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len);
+extern uint8_t ibm8514_accel_in(uint16_t port, svga_t *svga);
+extern int ibm8514_cpu_src(svga_t *svga);
+extern int ibm8514_cpu_dest(svga_t *svga);
+extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len);
+extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
+extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
#ifdef ATI_8514_ULTRA
-extern void ati8514_recalctimings(svga_t *svga);
-extern uint8_t ati8514_mca_read(int port, void *priv);
-extern void ati8514_mca_write(int port, uint8_t val, void *priv);
-extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514);
+extern void ati8514_recalctimings(svga_t *svga);
+extern uint8_t ati8514_mca_read(int port, void *priv);
+extern void ati8514_mca_write(int port, uint8_t val, void *priv);
+extern void ati8514_pos_write(uint16_t port, uint8_t val, void *priv);
+extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514);
#endif
extern void xga_poll(void *priv, svga_t *svga);
diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c
index ff14701649..fc205dacfe 100644
--- a/src/video/vid_8514a.c
+++ b/src/video/vid_8514a.c
@@ -44,6 +44,8 @@
#ifdef ATI_8514_ULTRA
#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN"
+
+static video_timings_t timing_8514ultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
#endif
static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv);
@@ -469,7 +471,7 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in
}
}
-static void
+void
ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
@@ -500,8 +502,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
break;
case 0x86e9:
case 0xc6e9:
- if (len == 1)
+ if (len == 1) {
dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8);
+ }
break;
case 0x8ae8:
@@ -548,6 +551,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
if (len != 1)
dev->test = val;
fallthrough;
+
case 0xd2e8:
if (len == 1)
dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val;
@@ -577,9 +581,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
break;
case 0x96e9:
case 0xd6e9:
- if (len == 1) {
+ if (len == 1)
dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8);
- }
break;
case 0x9ae8:
@@ -624,7 +627,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
dev->accel.cy = dev->accel.cur_y;
if (dev->accel.cur_x >= 0x600)
dev->accel.cx |= ~0x5ff;
-
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
@@ -646,9 +648,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
dev->accel.cy = dev->accel.cur_y;
if (dev->accel.cur_x >= 0x600)
dev->accel.cx |= ~0x5ff;
-
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
+
if (dev->accel.cmd & 0x1000) {
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len);
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len);
@@ -883,7 +885,7 @@ ibm8514_io_set(svga_t *svga)
io_sethandler(0xfee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga);
}
-static void
+void
ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
@@ -894,88 +896,89 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
else {
switch (port) {
case 0x2e8:
- case 0x2e9:
+ case 0x6e9:
WRITE8(port, dev->htotal, val);
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): htotal=0x%02x.\n", port, val);
+ svga_recalctimings(svga);
break;
case 0x6e8:
- case 0x6e9:
- if (!(port & 1)) {
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
- dev->hdisped = val;
- dev->hdisp = (dev->hdisped + 1) << 3;
- }
+ /*In preparation to switch from VGA to 8514/A mode*/
+ if (!dev->on[0] || !dev->on[1]) {
+ dev->hdisped = val;
+ dev->hdisp = (dev->hdisped + 1) << 3;
}
- ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4);
+ ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val);
+ svga_recalctimings(svga);
break;
case 0xae8:
- case 0xae9:
- if (!(port & 1)) {
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
- dev->hsync_start = val;
- dev->hblankstart = (dev->hsync_start & 0x07);
- }
- }
- ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1);
+ dev->hsync_start = val;
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_start=%d.\n", port, val, (val + 1) << 3);
+ svga_recalctimings(svga);
break;
case 0xee8:
- case 0xee9:
- if (!(port & 1)) {
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
- dev->hsync_width = val;
- dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f;
- }
- }
- ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
+ dev->hsync_width = val;
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20);
+ svga_recalctimings(svga);
break;
case 0x12e8:
case 0x12e9:
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
- WRITE8(port, dev->v_total_reg, val);
- dev->v_total_reg &= 0x1fff;
- dev->vtotal = dev->v_total_reg;
- dev->vtotal++;
- }
+ /*In preparation to switch from VGA to 8514/A mode*/
+ WRITE8(port, dev->v_total_reg, val);
+ dev->v_total_reg &= 0x1fff;
+ dev->v_total = dev->v_total_reg + 1;
+ if (dev->interlace)
+ dev->v_total >>= 1;
+
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): vtotal=0x%02x.\n", port, val);
+ svga_recalctimings(svga);
break;
case 0x16e8:
case 0x16e9:
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
+ /*In preparation to switch from VGA to 8514/A mode*/
+ if (!dev->on[0] || !dev->on[1]) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
- dev->vdisp = dev->v_disp;
- dev->vdisp >>= 1;
- dev->vdisp++;
+ dev->vdisp = (dev->v_disp + 1) >> 1;
}
- ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp);
+ ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp);
+ ibm8514_log("IBM 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val);
+ svga_recalctimings(svga);
break;
case 0x1ae8:
case 0x1ae9:
- if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
- WRITE8(port, dev->v_sync_start, val);
- dev->v_sync_start &= 0x1fff;
- dev->vsyncstart = dev->v_sync_start;
- dev->vsyncstart++;
- }
+ /*In preparation to switch from VGA to 8514/A mode*/
+ WRITE8(port, dev->v_sync_start, val);
+ dev->v_sync_start &= 0x1fff;
+ dev->v_syncstart = dev->v_sync_start + 1;
+ if (dev->interlace)
+ dev->v_syncstart >>= 1;
+
+ ibm8514_log("IBM 8514/A compatible: V_SYNCSTART write 1AE8 = %d\n", dev->v_syncstart);
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncstart=0x%02x.\n", port, val);
+ svga_recalctimings(svga);
break;
case 0x1ee8:
case 0x1ee9:
- ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val);
+ ibm8514_log("IBM 8514/A compatible: V_SYNC_WID write 1EE8 = %02x\n", val);
+ ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncwidth=0x%02x.\n", port, val);
+ svga_recalctimings(svga);
break;
case 0x22e8:
- dev->disp_cntl = val & 0x7e;
- dev->interlace = !!(val & 0x10);
- ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace);
+ dev->disp_cntl = val;
+ dev->interlace = !!(dev->disp_cntl & 0x10);
+ ibm8514_log("IBM 8514/A compatible: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace);
+ svga_recalctimings(svga);
break;
case 0x42e8:
- old = dev->subsys_stat;
if (val & 1)
dev->subsys_stat &= ~1;
if (val & 2)
@@ -1004,11 +1007,11 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01;
vga_on = !dev->on[port & 1];
dev->vendor_mode[port & 1] = 0;
- ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4);
+ ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp);
+ ibm8514_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480");
svga_recalctimings(svga);
break;
-
default:
break;
}
@@ -1031,73 +1034,14 @@ ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv)
ibm8514_accel_out(port, val, svga, 2);
}
-static uint32_t
-ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
+uint16_t
+ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len)
{
- ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
- uint32_t temp = 0;
- int cmd;
- int vpos = 0;
- int vblankend = svga->vblankstart + svga->crtc[0x16];
+ ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
+ uint16_t temp = 0;
+ int cmd = 0;
switch (port) {
- case 0x2e8:
- vpos = dev->vc & 0x7ff;
- if (vblankend > dev->v_total) {
- vblankend -= dev->v_total;
- if ((vpos >= svga->vblankstart) || (vpos <= vblankend))
- temp |= 2;
- } else {
- if ((vpos >= svga->vblankstart) && (vpos <= vblankend))
- temp |= 2;
- }
- break;
-
- case 0x6e8:
- temp = dev->hdisped;
- break;
-
- case 0x22e8:
- temp = dev->disp_cntl;
- break;
-
- case 0x26e8:
- if (len == 1)
- temp = dev->htotal & 0xff;
- else
- temp = dev->htotal;
- break;
- case 0x26e9:
- if (len == 1)
- temp = dev->htotal >> 8;
- break;
-
- case 0x2ee8:
- temp = dev->subsys_cntl;
- break;
-
- case 0x42e8:
- cmd = dev->accel.cmd >> 13;
- vpos = dev->vc & 0x7ff;
- if (vblankend > dev->v_total) {
- vblankend -= dev->v_total;
- if (vpos >= svga->vblankstart || vpos <= vblankend)
- dev->subsys_stat |= 1;
- } else {
- if (vpos >= svga->vblankstart && vpos <= vblankend)
- dev->subsys_stat |= 1;
- }
- if (len != 1) {
- temp = dev->subsys_stat | 0xa0 | 0x8000;
- } else
- temp = dev->subsys_stat | 0xa0;
- break;
-
- case 0x42e9:
- if (len == 1)
- temp |= 0x80;
- break;
-
case 0x82e8:
case 0xc2e8:
if (len != 1)
@@ -1115,6 +1059,11 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
temp = dev->test;
break;
+ case 0x96e8:
+ if (len != 1)
+ temp = dev->accel.maj_axis_pcnt;
+ break;
+
case 0x9ae8:
case 0xdae8:
if (len != 1) {
@@ -1143,26 +1092,82 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
case 0xe2e8:
case 0xe6e8:
if (ibm8514_cpu_dest(svga)) {
- if (len == 1) {
- ; // READ_PIXTRANS_BYTE_IO(0)
- } else {
+ if (len != 1) {
cmd = (dev->accel.cmd >> 13);
- READ_PIXTRANS_WORD(dev->accel.cx, 0)
+ READ_PIXTRANS_WORD(dev->accel.cx, 0);
if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) {
temp &= ~0xff00;
temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8);
}
+ ibm8514_accel_out_pixtrans(svga, port, temp, len);
}
- ibm8514_accel_out_pixtrans(svga, port, temp, len);
}
break;
- case 0xe2e9:
- case 0xe6e9:
- if (ibm8514_cpu_dest(svga)) {
- if (len == 1) {
- ; // READ_PIXTRANS_BYTE_IO(1)
- ibm8514_accel_out_pixtrans(svga, port, temp, len);
- }
+
+ default:
+ break;
+ }
+ return temp;
+}
+
+uint8_t
+ibm8514_accel_in(uint16_t port, svga_t *svga)
+{
+ ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
+ uint8_t temp = 0;
+ uint16_t clip_b_ibm = dev->accel.multifunc[3];
+ uint16_t clip_r_ibm = dev->accel.multifunc[4];
+ int cmd = (dev->accel.cmd >> 13);
+
+ switch (port) {
+ case 0x2e8:
+ if (dev->vc == dev->v_syncstart)
+ temp |= 2;
+
+ ibm8514_log("0x2E8 read: Display Status=%02x.\n", temp);
+ break;
+
+ case 0x6e8:
+ temp = dev->hdisped;
+ break;
+
+ case 0x22e8:
+ temp = dev->disp_cntl;
+ break;
+
+ case 0x26e8:
+ case 0x26e9:
+ READ8(port, dev->htotal);
+ break;
+
+ case 0x2ee8:
+ temp = dev->subsys_cntl;
+ break;
+ case 0x2ee9:
+ temp = 0xff;
+ break;
+
+ case 0x42e8:
+ case 0x42e9:
+ if (dev->vc == dev->v_syncstart)
+ dev->subsys_stat |= 1;
+
+ if (cmd == 6) {
+ if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm))
+ temp |= 2;
+ } else {
+ if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm))
+ temp |= 2;
+ }
+
+ if (!dev->force_busy)
+ temp |= 8;
+
+ if (port & 1)
+ temp = 0x80;
+ else {
+ temp |= (dev->subsys_stat | 0x80);
+ temp |= 0x20;
}
break;
@@ -1176,16 +1181,29 @@ static uint8_t
ibm8514_accel_inb(uint16_t port, void *priv)
{
svga_t *svga = (svga_t *) priv;
+ uint8_t temp;
- return ibm8514_accel_in(port, svga, 1);
+ if (port & 0x8000)
+ temp = ibm8514_accel_in_fifo(svga, port, 1);
+ else
+ temp = ibm8514_accel_in(port, svga);
+
+ return temp;
}
static uint16_t
ibm8514_accel_inw(uint16_t port, void *priv)
{
svga_t *svga = (svga_t *) priv;
+ uint16_t temp;
- return ibm8514_accel_in(port, svga, 2);
+ if (port & 0x8000)
+ temp = ibm8514_accel_in_fifo(svga, port, 2);
+ else {
+ temp = ibm8514_accel_in(port, svga);
+ temp |= (ibm8514_accel_in(port + 1, svga) << 8);
+ }
+ return temp;
}
void
@@ -2285,7 +2303,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
WRITE(dev->accel.dest + dev->accel.cx, dest_dat);
}
}
-
mix_dat <<= 1;
mix_dat |= 1;
if (dev->bpp)
@@ -2448,6 +2465,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
}
}
}
+
mix_dat <<= 1;
mix_dat |= 1;
@@ -2525,6 +2543,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
}
}
}
+
mix_dat <<= 1;
mix_dat |= 1;
if (dev->bpp)
@@ -3385,6 +3404,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
+
mix_dat >>= 1;
if (dev->bpp)
cpu_dat >>= 16;
@@ -3452,7 +3472,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
} else {
while (count-- && (dev->accel.sy >= 0)) {
if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) {
-
if (pixcntl == 3) {
if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) {
READ(dev->accel.src + dev->accel.cx, mix_dat);
@@ -3496,6 +3515,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
+
mix_dat <<= 1;
mix_dat |= 1;
if (dev->bpp)
@@ -3655,6 +3675,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
+
dev->accel.temp_cnt--;
mix_dat >>= 1;
@@ -3779,6 +3800,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
}
}
}
+
mix_dat <<= 1;
mix_dat |= 1;
@@ -4147,7 +4169,7 @@ ibm8514_poll(void *priv)
dev->hwcursor_oddeven = 1;
}
- timer_advance_u64(&svga->timer8514, dev->dispofftime);
+ timer_advance_u64(&svga->timer, dev->dispofftime);
svga->cgastat |= 1;
dev->linepos = 1;
@@ -4192,7 +4214,7 @@ ibm8514_poll(void *priv)
if (dev->displine > 1500)
dev->displine = 0;
} else {
- timer_advance_u64(&svga->timer8514, dev->dispontime);
+ timer_advance_u64(&svga->timer, dev->dispontime);
if (dev->dispon)
svga->cgastat &= ~1;
dev->hdisp_on = 0;
@@ -4215,7 +4237,7 @@ ibm8514_poll(void *priv)
}
dev->vc++;
- dev->vc &= 0x7ff;
+ dev->vc &= 0xfff;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
@@ -4290,43 +4312,37 @@ ibm8514_recalctimings(svga_t *svga)
#endif
{
if (dev->on[0] || dev->on[1]) {
- dev->h_disp = dev->hdisp;
- dev->h_total = dev->htotal + 1;
- dev->h_blankstart = dev->hblankstart;
- dev->h_blank_end_val = dev->hblank_end_val;
- dev->v_total = dev->vtotal;
- dev->v_syncstart = dev->vsyncstart;
- dev->dispend = dev->vdisp;
- dev->rowcount = !!(dev->disp_cntl & 0x08);
+ dev->h_total = dev->htotal + 1;
+ dev->rowcount = !!(dev->disp_cntl & 0x08);
- if (dev->dispend == 766)
- dev->dispend += 2;
-
- if (dev->accel.advfunc_cntl & 4) {
- dev->pitch = 1024;
- if (!dev->h_disp) {
- dev->h_disp = 1024;
- dev->dispend = 768;
- }
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
- } else {
- dev->pitch = 640;
- if (!dev->h_disp) {
+ if (dev->accel.advfunc_cntl & 0x01) {
+ if (dev->accel.advfunc_cntl & 0x04) {
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
+ } else {
dev->h_disp = 640;
dev->dispend = 480;
}
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
+ } else {
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
}
- if (dev->interlace) {
+ if (dev->accel.advfunc_cntl & 0x04)
+ svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
+ else
+ svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
+
+ if (dev->interlace)
dev->dispend >>= 1;
- dev->v_syncstart >>= 2;
- dev->v_total >>= 2;
- } else {
- dev->v_syncstart >>= 1;
- dev->v_total >>= 1;
- }
+ if (dev->dispend == 766)
+ dev->dispend += 2;
+
+ if (dev->dispend == 478)
+ dev->dispend += 2;
+
+ dev->pitch = 1024;
dev->rowoffset = 0x80;
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
@@ -4378,7 +4394,12 @@ ibm8514_mca_reset(void *priv)
dev->on[0] = 0;
dev->on[1] = 0;
vga_on = 1;
- ibm8514_mca_write(0x102, 0, svga);
+#ifdef ATI_8514_ULTRA
+ if (dev->extensions)
+ ati8514_mca_write(0x102, 0, svga);
+ else
+#endif
+ ibm8514_mca_write(0x102, 0, svga);
}
static void *
@@ -4409,27 +4430,28 @@ ibm8514_init(const device_t *info)
switch (dev->extensions) {
case 1:
if (rom_present(BIOS_MACH8_ROM_PATH)) {
- mach = (mach_t *) calloc(1, sizeof(mach_t));
+ mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t));
svga->ext8514 = mach;
- ati8514_init(svga, svga->ext8514, svga->dev8514);
if (dev->type & DEVICE_MCA) {
rom_init(&dev->bios_rom,
- BIOS_MACH8_ROM_PATH,
- 0xc6800, 0x1000, 0x0fff,
- 0x0800, MEM_MAPPING_EXTERNAL);
- mem_mapping_disable(&dev->bios_rom.mapping);
+ BIOS_MACH8_ROM_PATH,
+ 0xc6000, 0x2000, 0x1fff,
+ 0, MEM_MAPPING_EXTERNAL);
dev->pos_regs[0] = 0x88;
dev->pos_regs[1] = 0x80;
mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0);
+ mem_mapping_disable(&dev->bios_rom.mapping);
} else {
rom_init(&dev->bios_rom,
- BIOS_MACH8_ROM_PATH,
- 0xd0000, 0x1000, 0x0fff,
- 0x0800, MEM_MAPPING_EXTERNAL);
+ BIOS_MACH8_ROM_PATH,
+ 0xd0000, 0x2000, 0x1fff,
+ 0, MEM_MAPPING_EXTERNAL);
ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0);
+ dev->bios_addr = dev->bios_rom.mapping.base;
}
+ ati8514_init(svga, svga->ext8514, svga->dev8514);
break;
}
fallthrough;
@@ -4454,8 +4476,6 @@ ibm8514_init(const device_t *info)
}
#endif
- timer_add(&svga->timer8514, ibm8514_poll, svga, 1);
-
return svga;
}
@@ -4526,7 +4546,7 @@ static const device_config_t ext8514_config[] = {
// clang-format off
const device_t gen8514_isa_device = {
- .name = "Generic 8514/A clone (ISA)",
+ .name = "IBM 8514/A clone (ISA)",
.internal_name = "8514_isa",
.flags = DEVICE_AT | DEVICE_ISA,
.local = 0,
@@ -4536,7 +4556,11 @@ const device_t gen8514_isa_device = {
{ .available = NULL },
.speed_changed = ibm8514_speed_changed,
.force_redraw = ibm8514_force_redraw,
+#ifdef ATI_8514_ULTRA
+ .config = ext8514_config
+#else
.config = NULL
+#endif
};
const device_t ibm8514_mca_device = {
@@ -4550,7 +4574,11 @@ const device_t ibm8514_mca_device = {
{ .available = NULL },
.speed_changed = ibm8514_speed_changed,
.force_redraw = ibm8514_force_redraw,
+#ifdef ATI_8514_ULTRA
+ .config = ext8514_config
+#else
.config = NULL
+#endif
};
diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c
index be2c5d5472..83edb4355b 100644
--- a/src/video/vid_ati_mach8.c
+++ b/src/video/vid_ati_mach8.c
@@ -315,8 +315,6 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
bkgd_sel = (mach->accel.dp_config >> 7) & 3;
mono_src = (mach->accel.dp_config >> 5) & 3;
- mach->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16));
-
if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) {
mach->force_busy = 1;
dev->force_busy = 1;
@@ -817,7 +815,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
if (dev->accel.cur_y >= 0x600)
dev->accel.dy |= ~0x5ff;
- if ((mach->accel.dp_config == 0x5211) || (mach->accel.dp_config == 0x3251)) {
+ if (mach->accel.dp_config == 0x5211) {
if (mach->accel.dest_x_end == 1024) {
goto skip_dx;
}
@@ -1008,6 +1006,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
if (cpu_input) {
if (mach->accel.dp_config == 0x3251) {
+ mach_log("DPCONFIG 3251: monosrc=%d, frgdsel=%d, bkgdsel=%d, pitch=%d.\n", mono_src, frgd_sel, bkgd_sel, dev->pitch);
if (dev->accel.sy == mach->accel.height)
return;
}
@@ -1386,15 +1385,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
}
}
- if (mach->accel.linedraw_opt & 0x04) {
- if (count) {
- if (dev->bpp) {
- WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- } else {
- WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- }
- }
- } else {
+ if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) {
if (dev->bpp) {
WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
} else {
@@ -1647,20 +1638,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
}
if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) {
- if (mach->accel.linedraw_opt & 0x04) {
- if (count) {
- if (dev->bpp) {
- WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- } else {
- WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- }
- }
+ if (dev->bpp) {
+ WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
} else {
- if (dev->bpp) {
- WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- } else {
- WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
- }
+ WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat);
}
}
} else
@@ -2374,6 +2355,9 @@ mach_in(uint16_t addr, void *priv)
if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1))
addr ^= 0x60;
+ if ((addr >= 0x3c6) && (addr <= 0x3c9) && (dev->on[0] || dev->on[1]))
+ addr -= 0xdc;
+
switch (addr) {
case 0x1ce:
temp = mach->index;
@@ -2399,9 +2383,9 @@ mach_in(uint16_t addr, void *priv)
}
break;
case 0xb7:
- temp = mach->regs[0xb7] & ~8;
+ temp = mach->regs[0xb7] & ~0x08;
if (ati_eeprom_read(&mach->eeprom))
- temp |= 8;
+ temp |= 0x08;
break;
case 0xbd:
@@ -2429,21 +2413,6 @@ mach_in(uint16_t addr, void *priv)
temp = svga_in(addr, svga);
break;
- case 0x3C6:
- case 0x3C7:
- case 0x3C8:
- case 0x3C9:
- rs2 = !!(mach->regs[0xa0] & 0x20);
- rs3 = !!(mach->regs[0xa0] & 0x40);
- if ((dev->local & 0xff) >= 0x02) {
- if (mach->pci_bus && !mach->ramdac_type)
- temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga);
- else
- temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga);
- } else
- temp = svga_in(addr, svga);
- break;
-
case 0x3D4:
temp = svga->crtcreg;
break;
@@ -2466,7 +2435,7 @@ mach_in(uint16_t addr, void *priv)
static void
ati8514_out(uint16_t addr, uint8_t val, void *priv)
{
- mach_log("ADDON OUT addr=%03x, val=%02x.\n", addr, val);
+ mach_log("[%04X:%08X]: ADDON OUT addr=%03x, val=%02x.\n", CS, cpu_state.pc, addr, val);
svga_out(addr, val, priv);
}
@@ -2477,55 +2446,56 @@ ati8514_in(uint16_t addr, void *priv)
temp = svga_in(addr, priv);
- mach_log("ADDON IN addr=%03x, temp=%02x.\n", addr, temp);
+ mach_log("[%04X:%08X]: ADDON IN addr=%03x, temp=%02x.\n", CS, cpu_state.pc, addr, temp);
return temp;
}
void
ati8514_recalctimings(svga_t *svga)
{
- const mach_t *mach = (mach_t *) svga->ext8514;
+ mach_t *mach = (mach_t *) svga->ext8514;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp);
if (dev->on[0] || dev->on[1]) {
- dev->h_disp = dev->hdisp;
+ mach_log("8514/A ON.\n");
dev->h_total = dev->htotal + 1;
- dev->h_blankstart = dev->hblankstart;
- dev->h_blank_end_val = dev->hblank_end_val;
- dev->v_total = dev->vtotal;
- dev->v_syncstart = dev->vsyncstart;
dev->rowcount = !!(dev->disp_cntl & 0x08);
- dev->dispend = dev->vdisp;
+ dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16));
+ mach->accel.ge_offset = dev->accel.ge_offset;
- if (dev->dispend == 766)
- dev->dispend += 2;
-
- if (dev->dispend == 598)
- dev->dispend += 2;
-
- if (dev->accel.advfunc_cntl & 4) {
- if (dev->h_disp != 800) {
- dev->h_disp = 1024;
- dev->dispend = 768;
+ mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe);
+ if (dev->accel.advfunc_cntl & 0x01) {
+ if (dev->accel.advfunc_cntl & 0x04) {
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
+ } else {
+ dev->h_disp = 640;
+ dev->dispend = 480;
}
- svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
- svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
}
- if (dev->interlace) {
- dev->dispend >>= 1;
- dev->v_syncstart >>= 2;
- dev->v_total >>= 2;
+ if (dev->accel.advfunc_cntl & 0x04) {
+ svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
- dev->v_syncstart >>= 1;
- dev->v_total >>= 1;
+ svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
+ if (dev->dispend == 766)
+ dev->dispend += 2;
+
+ if (dev->dispend == 598)
+ dev->dispend += 2;
+
+ if (dev->dispend == 478)
+ dev->dispend += 2;
+
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
- mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3);
+ mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
} else {
@@ -2598,26 +2568,34 @@ mach_recalctimings(svga_t *svga)
if (dev->on[0] || dev->on[1]) {
mach_log("8514/A ON.\n");
dev->h_total = dev->htotal + 1;
- dev->v_total = dev->v_total_reg + 1;
- dev->v_syncstart = dev->v_sync_start + 1;
dev->rowcount = !!(dev->disp_cntl & 0x08);
-
- mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04);
- if ((dev->hdisp != 1024) || dev->bpp) {
- /*For VESA/ATI modes in 8514/A mode.*/
- dev->h_disp = dev->hdisp;
- dev->dispend = dev->vdisp;
- } else {
- /*Default modes for 8514/A mode*/
- if (dev->accel.advfunc_cntl & 0x04) {
- dev->h_disp = 1024;
- dev->dispend = 768;
+ dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16));
+ mach->accel.ge_offset = dev->accel.ge_offset;
+
+ mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe);
+ if (!dev->bpp) {
+ if (dev->accel.advfunc_cntl & 0x01) {
+ if (dev->accel.advfunc_cntl & 0x04) {
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
+ } else {
+ dev->h_disp = 640;
+ dev->dispend = 480;
+ }
} else {
- dev->h_disp = 640;
- dev->dispend = 480;
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
}
+ } else {
+ dev->h_disp = dev->hdisp;
+ dev->dispend = dev->vdisp;
}
+ svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
+
+ if (dev->interlace)
+ dev->dispend >>= 1;
+
if (dev->dispend == 766)
dev->dispend += 2;
@@ -2628,27 +2606,6 @@ mach_recalctimings(svga_t *svga)
dev->dispend += 2;
if ((dev->local & 0xff) >= 0x02) {
- if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
- if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
- else
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
- } else {
- if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
- else
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
- }
-
- if (dev->interlace) {
- dev->dispend >>= 1;
- dev->v_syncstart >>= 2;
- dev->v_total >>= 2;
- } else {
- dev->v_syncstart >>= 1;
- dev->v_total >>= 1;
- }
-
mach_log("HDISP=%d.\n", dev->h_disp);
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
@@ -2696,58 +2653,38 @@ mach_recalctimings(svga_t *svga)
break;
}
}
- switch (mach->regs[0xb8] & 0xc0) {
- case 0x40:
- svga->clock8514 *= 2;
- break;
- case 0x80:
- svga->clock8514 *= 3;
- break;
- case 0xc0:
- svga->clock8514 *= 4;
- break;
-
- default:
- break;
- }
} else {
- if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
- if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
- else
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
- } else {
- if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
- else
- svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
- }
-
- if (dev->interlace) {
- dev->dispend >>= 1;
- dev->v_syncstart >>= 2;
- dev->v_total >>= 2;
- } else {
- dev->v_syncstart >>= 1;
- dev->v_total >>= 1;
- }
-
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
- mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace);
+ mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
- if (mach->regs[0xb8] & 0x40)
- svga->clock8514 *= 2;
}
}
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) {
- mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80);
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
- if (mach->regs[0xa7] & 0x80)
- svga->clock *= 3;
+ mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80);
+ if ((dev->local & 0xff) >= 0x02) {
+ if (mach->regs[0xb8] & 0x40)
+ svga->clock *= 2;
+ } else {
+ switch (mach->regs[0xb8] & 0xc0) {
+ case 0x40:
+ svga->clock *= 2;
+ break;
+ case 0x80:
+ svga->clock *= 3;
+ break;
+ case 0xc0:
+ svga->clock *= 4;
+ break;
+
+ default:
+ break;
+ }
+ }
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->seqregs[1] & 8) /*Low res (320)*/
@@ -2799,114 +2736,56 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
switch (port) {
case 0x82e8:
- case 0xc2e8:
- case 0xf6ee:
- if (len == 1)
- dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val;
- else
- dev->accel.cur_y = val & 0x7ff;
- break;
case 0x82e9:
- case 0xc2e9:
- case 0xf6ef:
- if (len == 1)
- dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8);
- break;
-
case 0x86e8:
- case 0xc6e8:
- if (len == 1)
- dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val;
- else
- dev->accel.cur_x = val & 0x7ff;
- break;
case 0x86e9:
+ case 0xc2e8:
+ case 0xc2e9:
+ case 0xc6e8:
case 0xc6e9:
- if (len == 1) {
- dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8);
- }
+ ibm8514_accel_out_fifo(svga, port, val, len);
+ break;
+ case 0xf6ee:
+ ibm8514_accel_out_fifo(svga, 0x82e8, val, len);
+ break;
+ case 0xf6ef:
+ ibm8514_accel_out_fifo(svga, 0x82e9, val, len);
break;
case 0x8ae8:
case 0xcae8:
- if (len == 1)
- dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val;
- else {
- mach->accel.src_y = val;
- dev->accel.desty = val & 0x07ff;
- dev->accel.desty_axstp = val & 0x3fff;
- if (val & 0x2000)
- dev->accel.desty_axstp |= ~0x1fff;
- }
+ ibm8514_accel_out_fifo(svga, port, val, len);
+ if (len != 1)
+ mach->accel.src_y = val;
break;
case 0x8ae9:
+ case 0x8ee9:
case 0xcae9:
- if (len == 1) {
- dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8);
- if (val & 0x20)
- dev->accel.desty_axstp |= ~0x1fff;
- }
+ case 0xcee9:
+ ibm8514_accel_out_fifo(svga, port, val, len);
break;
case 0x8ee8:
case 0xcee8:
- if (len == 1)
- dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val;
- else {
- mach->accel.src_x = val;
- dev->accel.destx = val & 0x07ff;
- dev->accel.destx_distp = val & 0x3fff;
- if (val & 0x2000)
- dev->accel.destx_distp |= ~0x1fff;
- }
- break;
- case 0x8ee9:
- case 0xcee9:
- if (len == 1) {
- dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8);
- if (val & 0x20)
- dev->accel.destx_distp |= ~0x1fff;
- }
+ ibm8514_accel_out_fifo(svga, port, val, len);
+ if (len != 1)
+ mach->accel.src_x = val;
break;
case 0x92e8:
- if (len != 1)
- dev->test = val;
- fallthrough;
-
- case 0xd2e8:
- if (len == 1)
- dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val;
- else {
- dev->accel.err_term = val & 0x3fff;
- if (val & 0x2000)
- dev->accel.err_term |= ~0x1fff;
- }
- break;
case 0x92e9:
+ case 0x96e9:
+ case 0xd2e8:
case 0xd2e9:
- if (len == 1) {
- dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8);
- if (val & 0x20)
- dev->accel.err_term |= ~0x1fff;
- }
+ case 0xd6e9:
+ ibm8514_accel_out_fifo(svga, port, val, len);
break;
case 0x96e8:
case 0xd6e8:
- if (len == 1)
- dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val;
- else {
- mach->accel.test = val & 0x1fff;
- dev->accel.maj_axis_pcnt = val & 0x07ff;
- dev->accel.maj_axis_pcnt_no_limit = val;
- }
- break;
- case 0x96e9:
- case 0xd6e9:
- if (len == 1) {
- dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8);
- }
+ ibm8514_accel_out_fifo(svga, port, val, len);
+ if (len != 1)
+ mach->accel.test = val & 0x1fff;
break;
case 0x9ae8:
@@ -2952,12 +2831,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
dev->accel.cx = dev->accel.cur_x;
dev->accel.cy = dev->accel.cur_y;
- if (dev->accel.cur_x >= 0x600) {
+ if (dev->accel.cur_x >= 0x600)
dev->accel.cx |= ~0x5ff;
- }
- if (dev->accel.cur_y >= 0x600) {
+
+ if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
- }
if (dev->accel.cmd & 0x1000) {
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len);
@@ -3163,56 +3041,22 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
break;
case 0xaae8:
- case 0xeae8:
- if (len == 1)
- dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val;
- else {
- dev->accel.wrt_mask = val;
- mach_log("WrtMask=%04x.\n", val);
- }
- break;
case 0xaae9:
- case 0xeae9:
- if (len == 1)
- dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8);
- break;
-
case 0xaee8:
- case 0xeee8:
- if (len == 1)
- dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val;
- else {
- dev->accel.rd_mask = val;
- mach_log("ReadMask=%04x.\n", val);
- }
- break;
case 0xaee9:
- case 0xeee9:
- if (len == 1)
- dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8);
- break;
-
case 0xb2e8:
- case 0xf2e8:
- if (len == 1)
- dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val;
- else
- dev->accel.color_cmp = val;
- break;
case 0xb2e9:
- case 0xf2e9:
- if (len == 1)
- dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8);
- break;
-
case 0xb6e8:
- case 0xf6e8:
- dev->accel.bkgd_mix = val & 0xff;
- break;
-
case 0xbae8:
+ case 0xeae8:
+ case 0xeae9:
+ case 0xeee8:
+ case 0xeee9:
+ case 0xf2e8:
+ case 0xf2e9:
+ case 0xf6e8:
case 0xfae8:
- dev->accel.frgd_mix = val & 0xff;
+ ibm8514_accel_out_fifo(svga, port, val, len);
break;
case 0xbee8:
@@ -3274,9 +3118,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
break;
case 0x8eee:
- if (len == 1) {
+ if (len == 1)
mach->accel.patt_data[mach->accel.patt_data_idx] = val;
- } else {
+ else {
mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff;
mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff;
if (mach->accel.mono_pattern_enable)
@@ -3359,9 +3203,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
}
break;
case 0xa2ef:
- if (len == 1) {
+ if (len == 1)
mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8);
- }
break;
case 0xa6ee:
@@ -3378,9 +3221,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
case 0xaaee:
if (len == 1)
mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val;
- else {
+ else
mach->accel.dest_x_end = val & 0x7ff;
- }
break;
case 0xaaef:
if (len == 1)
@@ -3435,9 +3277,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
case 0xbeee:
if (len == 1)
mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val;
- else {
+ else
mach->accel.src_x_end = val & 0x7ff;
- }
break;
case 0xbeef:
if (len == 1)
@@ -3490,20 +3331,18 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
}
break;
case 0xceef:
- if (len == 1) {
+ if (len == 1)
mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8);
- }
break;
case 0xd2ee:
mach->accel.patt_len = val & 0x1f;
mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val);
mach->accel.mono_pattern_enable = !!(val & 0x80);
- if (len != 1) {
+ if (len != 1)
mach->accel.patt_len_reg = val;
- } else {
+ else
mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val;
- }
break;
case 0xd2ef:
if (len == 1)
@@ -3519,9 +3358,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("DAEE (extclipl) write val = %d\n", val);
if (len == 1)
dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val;
- else {
+ else
dev->accel.clip_left = val & 0x7ff;
- }
break;
case 0xdaef:
if (len == 1)
@@ -3532,9 +3370,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("DEEE (extclipt) write val = %d\n", val);
if (len == 1)
dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val;
- else {
+ else
dev->accel.clip_top = val & 0x7ff;
- }
break;
case 0xdeef:
if (len == 1)
@@ -3545,9 +3382,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("E2EE (extclipr) write val = %d\n", val);
if (len == 1)
dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val;
- else {
+ else
dev->accel.multifunc[4] = val & 0x7ff;
- }
break;
case 0xe2ef:
if (len == 1)
@@ -3558,9 +3394,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("E6EE (extclipb) write val = %d\n", val);
if (len == 1)
dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val;
- else {
+ else
dev->accel.multifunc[3] = val & 0x7ff;
- }
break;
case 0xe6ef:
if (len == 1)
@@ -3624,45 +3459,27 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
switch (port) {
case 0x2e8:
case 0x6e9:
- if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01))
- dev->htotal = val;
-
- svga_recalctimings(svga);
- break;
-
- case 0x6e8:
- /*In preparation to switch from VGA to 8514/A mode*/
- if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01))
- dev->hdisped = val;
-
- mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01);
- mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val);
- svga_recalctimings(svga);
- break;
-
case 0xae8:
- if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01))
- dev->hsync_start = val;
-
- mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_start=%d.\n", port, val, (val + 1) << 3);
- svga_recalctimings(svga);
- break;
-
case 0xee8:
- if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01))
- dev->hsync_width = val;
-
- mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20);
- svga_recalctimings(svga);
- break;
-
case 0x12e8:
case 0x12e9:
+ case 0x1ae8:
+ case 0x1ae9:
+ case 0x1ee8:
+ case 0x1ee9:
+ case 0x22e8:
+ case 0x42e8:
+ case 0x42e9:
+ ibm8514_accel_out(port, val, svga, 2);
+ break;
+
+ case 0x6e8:
/*In preparation to switch from VGA to 8514/A mode*/
if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) {
- WRITE8(port, dev->v_total_reg, val);
- dev->v_total_reg &= 0x1fff;
+ dev->hdisped = val;
+ dev->hdisp = (dev->hdisped + 1) << 3;
}
+ mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val);
svga_recalctimings(svga);
break;
@@ -3672,59 +3489,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
+ dev->vdisp = (dev->v_disp + 1) >> 1;
}
- dev->modechange = dev->accel.advfunc_cntl & 0x04;
- mach->compat_mode = mach->shadow_set & 0x03;
mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp);
mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val);
svga_recalctimings(svga);
break;
- case 0x1ae8:
- case 0x1ae9:
- /*In preparation to switch from VGA to 8514/A mode*/
- if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) {
- WRITE8(port, dev->v_sync_start, val);
- dev->v_sync_start &= 0x1fff;
- }
- svga_recalctimings(svga);
- break;
-
- case 0x1ee8:
- case 0x1ee9:
- mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val);
- break;
-
- case 0x22e8:
- dev->disp_cntl = val;
- dev->interlace = !!(val & 0x10);
- mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace);
- break;
-
- case 0x42e8:
- old = dev->subsys_stat;
- if (val & 1)
- dev->subsys_stat &= ~1;
- if (val & 2)
- dev->subsys_stat &= ~2;
- if (val & 4)
- dev->subsys_stat &= ~4;
- if (val & 8)
- dev->subsys_stat &= ~8;
- break;
- case 0x42e9:
- old = dev->subsys_cntl;
- dev->subsys_cntl = val;
- if ((old ^ val) & 1)
- dev->subsys_stat |= 1;
- if ((old ^ val) & 2)
- dev->subsys_stat |= 2;
- if ((old ^ val) & 4)
- dev->subsys_stat |= 4;
- if ((old ^ val) & 8)
- dev->subsys_stat |= 8;
- break;
-
case 0x4ae8:
case 0x4ae9:
WRITE8(port, dev->accel.advfunc_cntl, val);
@@ -3736,9 +3507,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
mach->ext_on[port & 1] = dev->on[port & 1];
mach32_updatemapping(mach, svga);
dev->vendor_mode[port & 1] = 0;
- dev->hdisp = (dev->hdisped + 1) << 3;
- dev->vdisp = (dev->v_disp >> 1) + 1;
- mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp);
+ mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp);
mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480");
svga_recalctimings(svga);
break;
@@ -3817,7 +3586,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
else
dev->ext_crt_pitch <<= 1;
}
- mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val);
+ mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val);
svga_recalctimings(svga);
break;
@@ -3857,20 +3626,18 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0x46ee:
case 0x46ef:
WRITE8(port, mach->shadow_cntl, val);
- mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
+ mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val);
break;
case 0x4aee:
case 0x4aef:
WRITE8(port, mach->accel.clock_sel, val);
dev->on[port & 1] = mach->accel.clock_sel & 0x01;
- mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp);
+ mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d, val=0x%02x.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp, val & 0xfe);
mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480");
mach->ext_on[port & 1] = dev->on[port & 1];
vga_on = !dev->on[port & 1];
dev->vendor_mode[port & 1] = 1;
- dev->hdisp = (dev->hdisped + 1) << 3;
- dev->vdisp = (dev->v_disp >> 1) + 1;
svga_recalctimings(svga);
break;
@@ -3889,13 +3656,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0x5aee:
case 0x5aef:
WRITE8(port, mach->shadow_set, val);
- mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val);
+ mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val);
if ((mach->shadow_set & 0x03) == 0x00)
mach_log("Primary CRT register set.\n");
else if ((mach->shadow_set & 0x03) == 0x01)
- mach_log("Shadow Set 1: 640x480.\n");
+ mach_log("CRT Shadow Set 1: 640x480.\n");
else if ((mach->shadow_set & 0x03) == 0x02)
- mach_log("Shadow Set 2: 1024x768.\n");
+ mach_log("CRT Shadow Set 2: 1024x768.\n");
break;
case 0x5eee:
@@ -3924,20 +3691,21 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0x6eee:
case 0x6eef:
WRITE8(port, mach->accel.ge_offset_lo, val);
- dev->accel.ge_offset = mach->accel.ge_offset_lo;
+ svga_recalctimings(svga);
break;
case 0x72ee:
case 0x72ef:
WRITE8(port, mach->accel.ge_offset_hi, val);
- dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16);
+ mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset);
+ svga_recalctimings(svga);
break;
case 0x76ee:
case 0x76ef:
WRITE8(port, mach->accel.ge_pitch, val);
dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3);
- mach_log("ATI 8514/A: (0x%04x) val=%04x, extpitch=%d.\n", port, val, dev->ext_pitch);
+ mach_log("ATI 8514/A: (0x%04x) val=0x%02x, extpitch=%d.\n", port, val, dev->ext_pitch);
svga_recalctimings(svga);
break;
@@ -3973,15 +3741,14 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val);
svga_recalctimings(svga);
} else {
- if (mach->accel.ext_ge_config & 0x8080)
- ati_eeprom_write(&mach->eeprom, mach->accel.ext_ge_config & 0x4040, mach->accel.ext_ge_config & 0x2020, mach->accel.ext_ge_config & 0x1010);
+ ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x4040), !!(mach->accel.ext_ge_config & 0x2020), !!(mach->accel.ext_ge_config & 0x1010));
}
break;
case 0x7eee:
case 0x7eef:
WRITE8(port, mach->accel.eeprom_control, val);
- ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 8, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1);
+ ati_eeprom_write(&mach->eeprom, !!(mach->accel.eeprom_control & 8), !!(mach->accel.eeprom_control & 2), !!(mach->accel.eeprom_control & 1));
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
break;
@@ -4012,25 +3779,12 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
switch (port) {
case 0x82e8:
- case 0xc2e8:
- if (len != 1)
- temp = dev->accel.cur_y;
- break;
-
case 0x86e8:
- case 0xc6e8:
- if (len != 1)
- temp = dev->accel.cur_x;
- break;
-
case 0x92e8:
- if (len != 1)
- temp = dev->test;
- break;
-
case 0x96e8:
- if (len != 1)
- temp = dev->accel.maj_axis_pcnt;
+ case 0xc2e8:
+ case 0xc6e8:
+ temp = ibm8514_accel_in_fifo(svga, port, len);
break;
case 0x9ae8:
@@ -4254,16 +4008,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0x96ee:
if (len == 1)
- temp = dev->accel.maj_axis_pcnt & 0xff;
- else {
- temp = dev->accel.maj_axis_pcnt;
- if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa))
- temp = mach->accel.test;
- }
+ temp = mach->accel.test & 0xff;
+ else
+ temp = mach->accel.test;
break;
case 0x96ef:
if (len == 1)
- temp = dev->accel.maj_axis_pcnt >> 8;
+ temp = mach->accel.test >> 8;
break;
case 0xa2ee:
@@ -4375,23 +4126,29 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0xfaee:
if (len != 1) {
- if (mach->pci_bus)
- temp = 0x0017;
- else
- temp = 0x22f7;
+ if ((dev->local & 0xff) >= 0x02) {
+ if (mach->pci_bus)
+ temp = 0x0017;
+ else
+ temp = 0x22f7;
+ }
} else {
- if (mach->pci_bus)
- temp = 0x17;
- else
- temp = 0xf7;
+ if ((dev->local & 0xff) >= 0x02) {
+ if (mach->pci_bus)
+ temp = 0x17;
+ else
+ temp = 0xf7;
+ }
}
break;
case 0xfaef:
if (len == 1) {
- if (mach->pci_bus)
- temp = 0x00;
- else
- temp = 0x22;
+ if ((dev->local & 0xff) >= 0x02) {
+ if (mach->pci_bus)
+ temp = 0x00;
+ else
+ temp = 0x22;
+ }
}
break;
@@ -4407,64 +4164,57 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
static uint8_t
mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
{
- uint8_t temp = 0;
- uint16_t vpos = 0;
- uint16_t vblankend = svga->vblankstart + svga->crtc[0x16];
+ uint8_t temp = 0;
+ uint16_t clip_b_ibm = dev->accel.multifunc[3];
+ uint16_t clip_r_ibm = dev->accel.multifunc[4];
+ int16_t clip_l = dev->accel.clip_left & 0x7ff;
+ int16_t clip_t = dev->accel.clip_top & 0x7ff;
+ int16_t clip_r = dev->accel.multifunc[4] & 0x7ff;
+ int16_t clip_b = dev->accel.multifunc[3] & 0x7ff;
+ int cmd = (dev->accel.cmd >> 13);
switch (port) {
case 0x2e8:
- vpos = dev->vc & 0x7ff;
- if (vblankend > dev->v_total) {
- vblankend -= dev->v_total;
- if ((vpos >= svga->vblankstart) || (vpos <= vblankend))
- temp |= 2;
- } else {
- if ((vpos >= svga->vblankstart) && (vpos <= vblankend))
- temp |= 2;
- }
- break;
-
case 0x6e8:
- temp = dev->hdisped;
- break;
-
case 0x22e8:
- temp = dev->disp_cntl;
- break;
-
case 0x26e8:
- temp = dev->htotal;
- break;
-
+ case 0x26e9:
case 0x2ee8:
- temp = dev->subsys_cntl;
- break;
case 0x2ee9:
- temp = 0xff;
+ temp = ibm8514_accel_in(port, svga);
break;
case 0x42e8:
case 0x42e9:
- vpos = dev->vc & 0x7ff;
- if (vblankend > dev->v_total) {
- vblankend -= dev->v_total;
- if ((vpos >= svga->vblankstart) || (vpos <= vblankend))
- dev->subsys_stat |= 1;
+ if (dev->vc == dev->v_syncstart)
+ dev->subsys_stat |= 1;
+
+ if (mach->accel.cmd_type >= 0) {
+ if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b))
+ temp |= 2;
} else {
- if ((vpos >= svga->vblankstart) && (vpos <= vblankend))
- dev->subsys_stat |= 1;
+ if (cmd == 6) {
+ if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm))
+ temp |= 2;
+ } else {
+ if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm))
+ temp |= 2;
+ }
}
+ if (!dev->force_busy)
+ temp |= 8;
+
if (port & 1)
temp = 0x80;
else {
- temp = dev->subsys_stat | 0x80;
+ temp |= (dev->subsys_stat | 0x80);
if (mach->accel.ext_ge_config & 0x08)
temp |= ((mach->accel.ext_ge_config & 0x07) << 4);
else
temp |= 0x20;
}
- mach_log("Subsystem Status=%04x, 4ae8 shadow set=%02x.\n", temp, dev->accel.advfunc_cntl & 4);
+ mach_log("0x%04x read: Subsystem Status=%02x.\n", port, temp);
break;
/*ATI Mach8/32 specific registers*/
@@ -4478,6 +4228,11 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
READ8(port, mach->config2);
break;
+ case 0x1aee:
+ case 0x1aef:
+ temp = 0x00;
+ break;
+
case 0x22ee:
if (mach->pci_bus)
temp = mach->pci_cntl_reg;
@@ -4541,11 +4296,14 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
temp = dev->pos_regs[5];
}
} else {
- if (!(port & 1)) {
- if (svga->ext8514 != NULL) {
- temp = 0x20 | 0x80;
+ if (svga->ext8514 != NULL) {
+ temp = ((dev->bios_addr >> 7) - 0x1000) >> 4;
+ if (port & 1) {
+ temp &= ~0x80;
+ temp |= 0x01;
}
- }
+ } else
+ temp = 0x00;
}
#endif
break;
@@ -4574,6 +4332,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
mach->force_busy = 0;
if (ati_eeprom_read(&mach->eeprom))
temp |= 0x40;
+
mach_log("Mach busy temp=%02x.\n", temp);
break;
@@ -4860,9 +4619,8 @@ mach32_decode_addr(svga_t *svga, uint32_t addr, int write)
}
static __inline void
-mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach)
+mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t *svga)
{
- svga_t *svga = &mach->svga;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
int writemask2 = svga->writemask;
int reset_wm = 0;
@@ -5003,29 +4761,59 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach)
svga->gdcreg[8] = wm;
}
+#ifdef ATI_8514_ULTRA
+static void
+ati8514_write(uint32_t addr, uint8_t val, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ mach32_write_common(addr, val, 0, mach, svga);
+}
+
+static void
+ati8514_writew(uint32_t addr, uint16_t val, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ mach32_write_common(addr, val & 0xff, 0, mach, svga);
+ mach32_write_common(addr + 1, val >> 8, 0, mach, svga);
+}
+
+static void
+ati8514_writel(uint32_t addr, uint32_t val, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ mach32_write_common(addr, val & 0xff, 0, mach, svga);
+ mach32_write_common(addr + 1, val >> 8, 0, mach, svga);
+ mach32_write_common(addr + 2, val >> 16, 0, mach, svga);
+ mach32_write_common(addr + 3, val >> 24, 0, mach, svga);
+}
+#endif
+
static void
mach32_write(uint32_t addr, uint8_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
- mach32_write_common(addr, val, 0, mach);
+ mach32_write_common(addr, val, 0, mach, &mach->svga);
}
static void
mach32_writew(uint32_t addr, uint16_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
- mach32_write_common(addr, val & 0xff, 0, mach);
- mach32_write_common(addr + 1, val >> 8, 0, mach);
+ mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga);
+ mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga);
}
static void
mach32_writel(uint32_t addr, uint32_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
- mach32_write_common(addr, val & 0xff, 0, mach);
- mach32_write_common(addr + 1, val >> 8, 0, mach);
- mach32_write_common(addr + 2, val >> 16, 0, mach);
- mach32_write_common(addr + 3, val >> 24, 0, mach);
+ mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga);
+ mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga);
+ mach32_write_common(addr + 2, val >> 16, 0, mach, &mach->svga);
+ mach32_write_common(addr + 3, val >> 24, 0, mach, &mach->svga);
}
static __inline void
@@ -5061,9 +4849,8 @@ mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach)
}
static __inline uint8_t
-mach32_read_common(uint32_t addr, int linear, mach_t *mach)
+mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga)
{
- svga_t *svga = &mach->svga;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint32_t latch_addr = 0;
int readplane = svga->readplane;
@@ -5153,13 +4940,52 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach)
return ret;
}
+#ifdef ATI_8514_ULTRA
+static uint8_t
+ati8514_read(uint32_t addr, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ uint8_t ret;
+
+ ret = mach32_read_common(addr, 0, mach, svga);
+ return ret;
+}
+
+static uint16_t
+ati8514_readw(uint32_t addr, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ uint16_t ret;
+
+ ret = mach32_read_common(addr, 0, mach, svga);
+ ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8);
+ return ret;
+}
+
+static uint32_t
+ati8514_readl(uint32_t addr, void *priv)
+{
+ svga_t *svga = (svga_t *) priv;
+ mach_t *mach = (mach_t *) svga->ext8514;
+ uint32_t ret;
+
+ ret = mach32_read_common(addr, 0, mach, svga);
+ ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8);
+ ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16);
+ ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 24);
+ return ret;
+}
+#endif
+
static uint8_t
mach32_read(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
uint8_t ret;
- ret = mach32_read_common(addr, 0, mach);
+ ret = mach32_read_common(addr, 0, mach, &mach->svga);
return ret;
}
@@ -5169,8 +4995,8 @@ mach32_readw(uint32_t addr, void *priv)
mach_t *mach = (mach_t *) priv;
uint16_t ret;
- ret = mach32_read_common(addr, 0, mach);
- ret |= (mach32_read_common(addr + 1, 0, mach) << 8);
+ ret = mach32_read_common(addr, 0, mach, &mach->svga);
+ ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8);
return ret;
}
@@ -5180,10 +5006,10 @@ mach32_readl(uint32_t addr, void *priv)
mach_t *mach = (mach_t *) priv;
uint32_t ret;
- ret = mach32_read_common(addr, 0, mach);
- ret |= (mach32_read_common(addr + 1, 0, mach) << 8);
- ret |= (mach32_read_common(addr + 2, 0, mach) << 16);
- ret |= (mach32_read_common(addr + 3, 0, mach) << 24);
+ ret = mach32_read_common(addr, 0, mach, &mach->svga);
+ ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8);
+ ret |= (mach32_read_common(addr + 2, 0, mach, &mach->svga) << 16);
+ ret |= (mach32_read_common(addr + 3, 0, mach, &mach->svga) << 24);
return ret;
}
@@ -5237,7 +5063,7 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv)
} else {
mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val);
if (dev->on[0] || dev->on[1])
- mach32_write_common(addr, val, 1, mach);
+ mach32_write_common(addr, val, 1, mach, svga);
else
svga_write_linear(addr, val, svga);
}
@@ -5314,7 +5140,7 @@ mach32_ap_readb(uint32_t addr, void *priv)
temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach);
} else {
if (dev->on[0] || dev->on[1])
- temp = mach32_read_common(addr, 1, mach);
+ temp = mach32_read_common(addr, 1, mach, svga);
else
temp = svga_read_linear(addr, svga);
@@ -5434,10 +5260,18 @@ mach32_updatemapping(mach_t *mach, svga_t *svga)
mach->ap_size = 4;
mem_mapping_disable(&mach->mmio_linear_mapping);
}
- if (((dev->local & 0xff) >= 0x02) && (dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) {
+ if ((dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) {
mach_log("ExtON.\n");
- mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
- mem_mapping_set_p(&svga->mapping, mach);
+#ifdef ATI_8514_ULTRA
+ if (svga->ext8514 != NULL) {
+ mem_mapping_set_handler(&svga->mapping, ati8514_read, ati8514_readw, ati8514_readl, ati8514_write, ati8514_writew, ati8514_writel);
+ mem_mapping_set_p(&svga->mapping, svga);
+ } else
+#endif
+ {
+ mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
+ mem_mapping_set_p(&svga->mapping, mach);
+ }
} else {
mach_log("ExtOFF.\n");
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
@@ -5534,6 +5368,7 @@ ati8514_io_set(svga_t *svga)
io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
+ io_sethandler(0x46e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
@@ -5650,6 +5485,7 @@ mach_io_set(mach_t *mach)
io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
+ io_sethandler(0x46e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
@@ -5747,6 +5583,7 @@ mach_io_set(mach_t *mach)
io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
+ io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
}
@@ -5828,6 +5665,12 @@ ati8514_mca_write(int port, uint8_t val, void *priv)
if (dev->pos_regs[2] & 0x01)
mem_mapping_enable(&dev->bios_rom.mapping);
}
+
+void
+ati8514_pos_write(uint16_t port, uint8_t val, void *priv)
+{
+ ati8514_mca_write(port, val, priv);
+}
#endif
static uint8_t
@@ -6084,8 +5927,8 @@ mach8_init(const device_t *info)
mach->config2 = 0x02;
svga->clock_gen = device_add(&ati18810_device);
}
- dev->bpp = 0;
- svga->getclock = ics2494_getclock;
+ dev->bpp = 0;
+ svga->getclock = ics2494_getclock;
dev->on[0] = 0;
dev->on[1] = 0;
@@ -6107,7 +5950,6 @@ mach8_init(const device_t *info)
mach->cursor_col_1 = 0xff;
mach->ext_cur_col_1_r = 0xff;
mach->ext_cur_col_1_g = 0xff;
- io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
if (mach->vlb_bus)
ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1);
else if (mach->mca_bus) {
@@ -6134,8 +5976,6 @@ mach8_init(const device_t *info)
} else
ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr");
- timer_add(&svga->timer8514, ibm8514_poll, svga, 1);
-
return mach;
}
@@ -6143,8 +5983,8 @@ mach8_init(const device_t *info)
void
ati8514_init(svga_t *svga, void *ext8514, void *dev8514)
{
- mach_t *mach = (mach_t *)ext8514;
- ibm8514_t *dev = (ibm8514_t *)dev8514;
+ mach_t *mach = (mach_t *) ext8514;
+ ibm8514_t *dev = (ibm8514_t *) dev8514;
dev->on[0] = 0;
dev->on[1] = 0;
diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c
index 309d07966b..e85b4539ef 100644
--- a/src/video/vid_ics2494.c
+++ b/src/video/vid_ics2494.c
@@ -56,6 +56,7 @@ ics2494_getclock(int clock, void *priv)
if (clock > 15)
clock = 15;
+ ics2494_log("Clock=%d, freq=%f.\n", clock, ics2494->freq[clock]);
return ics2494->freq[clock];
}
@@ -68,60 +69,60 @@ ics2494_init(const device_t *info)
switch (info->local) {
case 10:
/* ATI 18810 for ATI 28800 */
- ics2494->freq[0x0] = 30240000.0;
- ics2494->freq[0x1] = 32000000.0;
- ics2494->freq[0x2] = 37500000.0;
- ics2494->freq[0x3] = 39000000.0;
- ics2494->freq[0x4] = 42954000.0;
- ics2494->freq[0x5] = 48771000.0;
- ics2494->freq[0x6] = 16657000.0;
- ics2494->freq[0x7] = 36000000.0;
- ics2494->freq[0x8] = 40000000.0;
- ics2494->freq[0x9] = 56644000.0;
- ics2494->freq[0xa] = 75000000.0;
- ics2494->freq[0xb] = 65000000.0;
- ics2494->freq[0xc] = 50350000.0;
- ics2494->freq[0xd] = 56640000.0;
- ics2494->freq[0xe] = 28322000.0;
- ics2494->freq[0xf] = 44900000.0;
+ ics2494->freq[0x0] = 42954000.0;
+ ics2494->freq[0x1] = 48771000.0;
+ ics2494->freq[0x2] = 0.0;
+ ics2494->freq[0x3] = 36000000.0;
+ ics2494->freq[0x4] = 50350000.0;
+ ics2494->freq[0x5] = 56640000.0;
+ ics2494->freq[0x6] = 0.0;
+ ics2494->freq[0x7] = 44900000.0;
+ ics2494->freq[0x8] = 30240000.0;
+ ics2494->freq[0x9] = 32000000.0;
+ ics2494->freq[0xa] = 37500000.0;
+ ics2494->freq[0xb] = 39000000.0;
+ ics2494->freq[0xc] = 40000000.0;
+ ics2494->freq[0xd] = 56644000.0;
+ ics2494->freq[0xe] = 75000000.0;
+ ics2494->freq[0xf] = 65000000.0;
break;
case 110:
/* ATI 18811-0 for ATI Mach32 */
- ics2494->freq[0x0] = 30240000.0;
- ics2494->freq[0x1] = 32000000.0;
- ics2494->freq[0x2] = 110000000.0;
- ics2494->freq[0x3] = 80000000.0;
- ics2494->freq[0x4] = 42954000.0;
- ics2494->freq[0x5] = 48771000.0;
- ics2494->freq[0x6] = 92400000.0;
- ics2494->freq[0x7] = 36000000.0;
- ics2494->freq[0x8] = 39910000.0;
- ics2494->freq[0x9] = 44900000.0;
- ics2494->freq[0xa] = 75000000.0;
- ics2494->freq[0xb] = 65000000.0;
- ics2494->freq[0xc] = 50350000.0;
- ics2494->freq[0xd] = 56640000.0;
- ics2494->freq[0xe] = 0.0;
- ics2494->freq[0xf] = 44900000.0;
+ ics2494->freq[0x0] = 42954000.0;
+ ics2494->freq[0x1] = 48771000.0;
+ ics2494->freq[0x2] = 92400000.0;
+ ics2494->freq[0x3] = 36000000.0;
+ ics2494->freq[0x4] = 50350000.0;
+ ics2494->freq[0x5] = 56640000.0;
+ ics2494->freq[0x6] = 0.0;
+ ics2494->freq[0x7] = 44900000.0;
+ ics2494->freq[0x8] = 30240000.0;
+ ics2494->freq[0x9] = 32000000.0;
+ ics2494->freq[0xa] = 110000000.0;
+ ics2494->freq[0xb] = 80000000.0;
+ ics2494->freq[0xc] = 39910000.0;
+ ics2494->freq[0xd] = 44900000.0;
+ ics2494->freq[0xe] = 75000000.0;
+ ics2494->freq[0xf] = 65000000.0;
break;
case 111:
/* ATI 18811-1 for ATI Mach32 MCA */
- ics2494->freq[0x0] = 135000000.0;
- ics2494->freq[0x1] = 32000000.0;
- ics2494->freq[0x2] = 110000000.0;
- ics2494->freq[0x3] = 80000000.0;
- ics2494->freq[0x4] = 100000000.0;
- ics2494->freq[0x5] = 126000000.0;
- ics2494->freq[0x6] = 92400000.0;
- ics2494->freq[0x7] = 36000000.0;
- ics2494->freq[0x8] = 39910000.0;
- ics2494->freq[0x9] = 44900000.0;
- ics2494->freq[0xa] = 75000000.0;
- ics2494->freq[0xb] = 65000000.0;
- ics2494->freq[0xc] = 50350000.0;
- ics2494->freq[0xd] = 56640000.0;
- ics2494->freq[0xe] = 0.0;
- ics2494->freq[0xf] = 44900000.0;
+ ics2494->freq[0x0] = 100000000.0;
+ ics2494->freq[0x1] = 126000000.0;
+ ics2494->freq[0x2] = 92400000.0;
+ ics2494->freq[0x3] = 36000000.0;
+ ics2494->freq[0x4] = 50350000.0;
+ ics2494->freq[0x5] = 56640000.0;
+ ics2494->freq[0x6] = 0.0;
+ ics2494->freq[0x7] = 44900000.0;
+ ics2494->freq[0x8] = 135000000.0;
+ ics2494->freq[0x9] = 32000000.0;
+ ics2494->freq[0xa] = 110000000.0;
+ ics2494->freq[0xb] = 80000000.0;
+ ics2494->freq[0xc] = 39910000.0;
+ ics2494->freq[0xd] = 44900000.0;
+ ics2494->freq[0xe] = 75000000.0;
+ ics2494->freq[0xf] = 65000000.0;
break;
case 305:
/* ICS2494A(N)-205 for S3 86C924 */
diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c
index 4632ab85e9..307f455c34 100644
--- a/src/video/vid_svga.c
+++ b/src/video/vid_svga.c
@@ -46,6 +46,7 @@
#include <86box/vid_xga_device.h>
void svga_doblit(int wx, int wy, svga_t *svga);
+void svga_poll(void *priv);
svga_t *svga_8514;
@@ -121,6 +122,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed))
return;
+ if (addr >= 0x3c6 && addr <= 0x3c9)
+ svga_log("VGA OUT addr=%03x, val=%02x.\n", addr, val);
+
switch (addr) {
case 0x2ea:
dev->dac_mask = val;
@@ -528,6 +532,9 @@ svga_in(uint16_t addr, void *priv)
break;
}
+ if ((addr >= 0x3c6) && (addr <= 0x3c9))
+ svga_log("VGA IN addr=%03x, temp=%02x.\n", addr, ret);
+
return ret;
}
@@ -935,11 +942,11 @@ svga_recalctimings(svga_t *svga)
if (dev->dispofftime < TIMER_USEC)
dev->dispofftime = TIMER_USEC;
- timer_disable(&svga->timer);
- timer_set_delay_u64(&svga->timer8514, TIMER_USEC);
+ svga_log("IBM 8514/A poll.\n");
+ timer_set_callback(&svga->timer, ibm8514_poll);
} else {
- timer_disable(&svga->timer8514);
- timer_set_delay_u64(&svga->timer, TIMER_USEC);
+ svga_log("SVGA Poll.\n");
+ timer_set_callback(&svga->timer, svga_poll);
}
}
From 6d2ea183c221c480ed5f35a3cbe9d895513217ac Mon Sep 17 00:00:00 2001
From: OBattler
Date: Wed, 29 May 2024 23:18:43 +0200
Subject: [PATCH 007/567] PAS Plus: Fix ID.
---
src/sound/snd_pas16.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c
index 243332257b..d88a498d57 100644
--- a/src/sound/snd_pas16.c
+++ b/src/sound/snd_pas16.c
@@ -823,7 +823,7 @@ pas16_in(uint16_t port, void *priv)
- 2 = FM (1 = stereo, 0 = mono);
- 3 = Code (1 = 16-bit, 0 = 8-bit).
*/
- ret = pas16->type ? pas16->type : 0x06;
+ ret = pas16->type ? pas16->type : 0x07;
break;
case 0xf000:
From ff5d5273ed3ea8d957e02c05d5605786181b47e5 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Wed, 29 May 2024 23:45:00 +0200
Subject: [PATCH 008/567] Video changes part 2
1. Added the Diamond Stealth 64 Video VRAM 968-based card.
2. Removed the useless VLB-based Phoenix 868 and 968 cards.
3. The Diamond Stealth 64 Video VRAM specific drivers apparently use 0x83ca-0x83cb as aliases of the RAMDAC ports 0x83c6-0x83c7 (New MMIO mode). This makes the hardware cursor visible in those drivers on win3.1 using the IBM RGB RAMDAC.
4. A few more logs and sanity checks around LFB access and MMIO as well.
---
src/include/86box/video.h | 4 +-
src/video/vid_s3.c | 149 +++++++++++++++++++++++++-------------
src/video/vid_table.c | 4 +-
3 files changed, 104 insertions(+), 53 deletions(-)
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index 1c8b610153..e1a1a75025 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -507,15 +507,15 @@ extern const device_t s3_phoenix_vision864_pci_device;
extern const device_t s3_phoenix_vision864_vlb_device;
extern const device_t s3_9fx_531_pci_device;
extern const device_t s3_phoenix_vision868_pci_device;
-extern const device_t s3_phoenix_vision868_vlb_device;
extern const device_t s3_diamond_stealth64_pci_device;
extern const device_t s3_diamond_stealth64_vlb_device;
extern const device_t s3_diamond_stealth64_964_pci_device;
extern const device_t s3_diamond_stealth64_964_vlb_device;
+extern const device_t s3_diamond_stealth64_968_pci_device;
+extern const device_t s3_diamond_stealth64_968_vlb_device;
extern const device_t s3_mirovideo_40sv_ergo_968_pci_device;
extern const device_t s3_9fx_771_pci_device;
extern const device_t s3_phoenix_vision968_pci_device;
-extern const device_t s3_phoenix_vision968_vlb_device;
extern const device_t s3_spea_mercury_p64v_pci_device;
extern const device_t s3_elsa_winner2000_pro_x_964_pci_device;
extern const device_t s3_elsa_winner2000_pro_x_pci_device;
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index 8fa86dfe00..e74ff8c06f 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -75,6 +75,7 @@
#define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN"
#define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN"
#define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN"
+#define ROM_DIAMOND_STEALTH64_968 "roms/video/s3/vv_303.rom"
enum {
S3_NUMBER9_9FX,
@@ -115,7 +116,8 @@ enum {
S3_NUMBER9_9FX_531,
S3_NUMBER9_9FX_771,
S3_SPEA_MERCURY_LITE_PCI,
- S3_86C805_ONBOARD
+ S3_86C805_ONBOARD,
+ S3_DIAMOND_STEALTH64_968
};
enum {
@@ -2770,13 +2772,15 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
case 0x3C7:
case 0x3C8:
case 0x3C9:
+ case 0x3CA: /*0x3c6 alias*/
+ case 0x3CB: /*0x3c7 alias*/
rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2);
if (s3->chip >= S3_TRIO32)
svga_out(addr, val, svga);
else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) {
rs3 = !!(svga->crtc[0x55] & 0x02);
bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga);
- } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771)))
+ } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771)))
ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga);
else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) {
rs3 = !!(svga->crtc[0x55] & 0x02);
@@ -2957,10 +2961,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
case 0x58:
case 0x59:
case 0x5a:
+ s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]);
s3_updatemapping(s3);
break;
case 0x55:
+ s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]);
if (s3->chip == S3_86C928) {
if (val & 0x28) {
svga->hwcursor_draw = NULL;
@@ -3093,6 +3099,8 @@ s3_in(uint16_t addr, void *priv)
case 0x3c7:
case 0x3c8:
case 0x3c9:
+ case 0x3ca: /*0x3c6 alias*/
+ case 0x3cb: /*0x3c7 alias*/
rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2);
if (s3->chip >= S3_TRIO32)
return svga_in(addr, svga);
@@ -3103,7 +3111,7 @@ s3_in(uint16_t addr, void *priv)
rs3 = !!(svga->crtc[0x55] & 0x02);
temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga);
return temp;
- } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771)))
+ } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771)))
return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga);
else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) {
rs3 = !!(svga->crtc[0x55] & 0x02);
@@ -3138,6 +3146,7 @@ s3_in(uint16_t addr, void *priv)
}
break;
case 0x30:
+ s3_log("[%04X:%08X]: Read CRTC30=%02x.\n", CS, cpu_state.pc, s3->id);
return s3->id; /*Chip ID*/
case 0x31:
return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4);
@@ -3168,6 +3177,7 @@ s3_in(uint16_t addr, void *priv)
/* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C
to be mirrors of 59 and 5A. */
case 0x6b:
+ s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe);
@@ -3178,6 +3188,7 @@ s3_in(uint16_t addr, void *priv)
return svga->crtc[0x6b];
break;
case 0x6c:
+ s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
return 0x00;
@@ -3190,6 +3201,7 @@ s3_in(uint16_t addr, void *priv)
default:
break;
}
+ s3_log("[%04X:%08X]: Read CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]);
return svga->crtc[svga->crtcreg];
default:
@@ -3458,6 +3470,7 @@ s3_recalctimings(svga_t *svga)
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
case S3_SPEA_MERCURY_P64V:
@@ -3640,6 +3653,7 @@ s3_recalctimings(svga_t *svga)
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
case S3_SPEA_MERCURY_P64V:
@@ -3827,6 +3841,7 @@ s3_recalctimings(svga_t *svga)
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
case S3_SPEA_MERCURY_P64V:
@@ -4039,6 +4054,7 @@ s3_recalctimings(svga_t *svga)
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_NUMBER9_9FX_771:
case S3_PHOENIX_VISION968:
case S3_SPEA_MERCURY_P64V:
@@ -4369,6 +4385,7 @@ s3_updatemapping(s3_t *s3)
s3->linear_base &= 0x00ffffff;
}
+ s3_log("LinearBase=%x, crtc58bits=%x.\n", s3->linear_base, svga->crtc[0x58] & 0x13);
if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) {
/*Linear framebuffer*/
mem_mapping_disable(&svga->mapping);
@@ -4414,7 +4431,11 @@ s3_updatemapping(s3_t *s3)
else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868))
s3->linear_base &= 0xfe000000;
- mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size);
+ s3_log("LinearBase update=%x, size=%x.\n", s3->linear_base, s3->linear_size);
+ if (s3->linear_base)
+ mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size);
+ else
+ mem_mapping_disable(&s3->linear_mapping);
}
svga->fb_only = 1;
} else {
@@ -4437,8 +4458,12 @@ s3_updatemapping(s3_t *s3)
}
/* New MMIO. */
- if (svga->crtc[0x53] & 0x08)
- mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000);
+ if (svga->crtc[0x53] & 0x08) {
+ if (s3->linear_base)
+ mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000);
+ else
+ mem_mapping_disable(&s3->new_mmio_mapping);
+ }
else
mem_mapping_disable(&s3->new_mmio_mapping);
}
@@ -9178,11 +9203,13 @@ s3_pci_read(UNUSED(int func), int addr, void *priv)
return 0x00; /*Supports VGA interface*/
else
return 0x01;
+ break;
case 0x0b:
if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868)
return 0x03;
else
return 0x00;
+ break;
case 0x0d:
return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00;
@@ -9461,6 +9488,7 @@ s3_reset(void *priv)
svga->crtc[0x5a] = 0x0a;
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_ELSAWIN2KPROX:
case S3_SPEA_MERCURY_P64V:
case S3_MIROVIDEO40SV_ERGO_968:
@@ -9639,10 +9667,7 @@ s3_init(const device_t *info)
case S3_PHOENIX_VISION868:
bios_fn = ROM_PHOENIX_VISION868;
chip = S3_VISION868;
- if (info->flags & DEVICE_PCI)
- video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci);
- else
- video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_vlb);
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci);
break;
case S3_DIAMOND_STEALTH64_964:
bios_fn = ROM_DIAMOND_STEALTH64_964;
@@ -9662,6 +9687,14 @@ s3_init(const device_t *info)
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb);
}
break;
+ case S3_DIAMOND_STEALTH64_968:
+ bios_fn = ROM_DIAMOND_STEALTH64_968;
+ chip = S3_VISION968;
+ if (info->flags & DEVICE_PCI)
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci);
+ else
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb);
+ break;
case S3_MIROVIDEO40SV_ERGO_968:
bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI;
chip = S3_VISION968;
@@ -9675,10 +9708,7 @@ s3_init(const device_t *info)
case S3_PHOENIX_VISION968:
bios_fn = ROM_PHOENIX_VISION968;
chip = S3_VISION968;
- if (info->flags & DEVICE_PCI)
- video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci);
- else
- video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb);
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci);
break;
case S3_ELSAWIN2KPROX_964:
bios_fn = ROM_ELSAWIN2KPROX_964;
@@ -9843,7 +9873,7 @@ s3_init(const device_t *info)
mem_mapping_disable(&s3->mmio_mapping);
mem_mapping_disable(&s3->new_mmio_mapping);
- if (chip == S3_VISION964 || chip == S3_VISION968)
+ if ((chip == S3_VISION964) || (chip == S3_VISION968))
svga_init(info, &s3->svga, s3, vram_size,
s3_recalctimings,
s3_in, s3_out,
@@ -9881,16 +9911,14 @@ s3_init(const device_t *info)
case S3_VISION968:
switch (info->local) {
+ case S3_DIAMOND_STEALTH64_968:
case S3_ELSAWIN2KPROX:
case S3_PHOENIX_VISION968:
case S3_NUMBER9_9FX_771:
svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw;
break;
- case S3_SPEA_MERCURY_P64V:
- case S3_MIROVIDEO40SV_ERGO_968:
- svga->dac_hwcursor_draw = tvp3026_hwcursor_draw;
- break;
default:
+ svga->dac_hwcursor_draw = tvp3026_hwcursor_draw;
break;
}
break;
@@ -10125,6 +10153,7 @@ s3_init(const device_t *info)
}
break;
+ case S3_DIAMOND_STEALTH64_968:
case S3_ELSAWIN2KPROX:
case S3_SPEA_MERCURY_P64V:
case S3_MIROVIDEO40SV_ERGO_968:
@@ -10132,8 +10161,9 @@ s3_init(const device_t *info)
case S3_PHOENIX_VISION968:
svga->decode_mask = (8 << 20) - 1;
s3->id = 0xe1; /*Vision968*/
- s3->id_ext = s3->id_ext_pci = 0xf0;
- s3->packed_mmio = 1;
+ s3->id_ext = 0xf0;
+ s3->id_ext_pci = s3->id_ext;
+ s3->packed_mmio = 1;
if (s3->pci) {
svga->crtc[0x53] = 0x18;
svga->crtc[0x58] = 0x10;
@@ -10147,6 +10177,7 @@ s3_init(const device_t *info)
}
switch (info->local) {
+ case S3_DIAMOND_STEALTH64_968:
case S3_ELSAWIN2KPROX:
case S3_PHOENIX_VISION968:
case S3_NUMBER9_9FX_771:
@@ -10376,6 +10407,12 @@ s3_diamond_stealth64_964_available(void)
return rom_present(ROM_DIAMOND_STEALTH64_964);
}
+static int
+s3_diamond_stealth64_968_available(void)
+{
+ return rom_present(ROM_DIAMOND_STEALTH64_968);
+}
+
static int
s3_mirovideo_40sv_ergo_968_pci_available(void)
{
@@ -10593,6 +10630,20 @@ static const device_config_t s3_968_config[] = {
{ .type = CONFIG_END }
};
+static const device_config_t s3_standard_config2[] = {
+ { .name = "memory",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .default_int = 4,
+ .selection = {
+ { .description = "2 MB",
+ .value = 2 },
+ { .description = "4 MB",
+ .value = 4 },
+ { .description = "" } } },
+ { .type = CONFIG_END }
+};
+
const device_t s3_orchid_86c911_isa_device = {
.name = "S3 86c911 ISA (Orchid Fahrenheit 1280)",
.internal_name = "orchid_s3_911",
@@ -10873,6 +10924,34 @@ const device_t s3_diamond_stealth64_964_pci_device = {
.config = s3_standard_config
};
+const device_t s3_diamond_stealth64_968_vlb_device = {
+ .name = "S3 Vision968 VLB (Diamond Stealth64 Video VRAM)",
+ .internal_name = "stealth64vv_vlb",
+ .flags = DEVICE_VLB,
+ .local = S3_DIAMOND_STEALTH64_968,
+ .init = s3_init,
+ .close = s3_close,
+ .reset = s3_reset,
+ { .available = s3_diamond_stealth64_968_available },
+ .speed_changed = s3_speed_changed,
+ .force_redraw = s3_force_redraw,
+ .config = s3_standard_config2
+};
+
+const device_t s3_diamond_stealth64_968_pci_device = {
+ .name = "S3 Vision968 PCI (Diamond Stealth64 Video VRAM)",
+ .internal_name = "stealth64vv_pci",
+ .flags = DEVICE_PCI,
+ .local = S3_DIAMOND_STEALTH64_968,
+ .init = s3_init,
+ .close = s3_close,
+ .reset = s3_reset,
+ { .available = s3_diamond_stealth64_968_available },
+ .speed_changed = s3_speed_changed,
+ .force_redraw = s3_force_redraw,
+ .config = s3_standard_config2
+};
+
const device_t s3_9fx_771_pci_device = {
.name = "S3 Vision968 PCI (Number 9 9FX 771)",
.internal_name = "n9_9fx_771_pci",
@@ -10901,20 +10980,6 @@ const device_t s3_phoenix_vision968_pci_device = {
.config = s3_standard_config
};
-const device_t s3_phoenix_vision968_vlb_device = {
- .name = "S3 Vision968 VLB (Phoenix)",
- .internal_name = "px_vision968_vlb",
- .flags = DEVICE_VLB,
- .local = S3_PHOENIX_VISION968,
- .init = s3_init,
- .close = s3_close,
- .reset = s3_reset,
- { .available = s3_phoenix_vision968_available },
- .speed_changed = s3_speed_changed,
- .force_redraw = s3_force_redraw,
- .config = s3_standard_config
-};
-
const device_t s3_mirovideo_40sv_ergo_968_pci_device = {
.name = "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)",
.internal_name = "mirovideo40sv_pci",
@@ -11195,20 +11260,6 @@ const device_t s3_9fx_531_pci_device = {
.config = s3_9fx_config
};
-const device_t s3_phoenix_vision868_vlb_device = {
- .name = "S3 Vision868 VLB (Phoenix)",
- .internal_name = "px_vision868_vlb",
- .flags = DEVICE_VLB,
- .local = S3_PHOENIX_VISION868,
- .init = s3_init,
- .close = s3_close,
- .reset = s3_reset,
- { .available = s3_phoenix_vision868_available },
- .speed_changed = s3_speed_changed,
- .force_redraw = s3_force_redraw,
- .config = s3_standard_config
-};
-
const device_t s3_phoenix_vision868_pci_device = {
.name = "S3 Vision868 PCI (Phoenix)",
.internal_name = "px_vision868_pci",
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index b2686b2f31..c99a41544d 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -188,6 +188,7 @@ video_cards[] = {
{ &s3_diamond_stealth64_pci_device },
{ &s3_9fx_pci_device },
{ &s3_phoenix_trio64_pci_device },
+ { &s3_diamond_stealth64_968_pci_device },
{ &s3_elsa_winner2000_pro_x_pci_device },
{ &s3_mirovideo_40sv_ergo_968_pci_device },
{ &s3_9fx_771_pci_device },
@@ -252,8 +253,7 @@ video_cards[] = {
{ &s3_9fx_vlb_device },
{ &s3_phoenix_trio64_vlb_device },
{ &s3_spea_mirage_p64_vlb_device },
- { &s3_phoenix_vision968_vlb_device },
- { &s3_phoenix_vision868_vlb_device },
+ { &s3_diamond_stealth64_968_vlb_device },
{ &s3_stb_powergraph_64_video_vlb_device },
{ &ht216_32_standalone_device },
{ &tgui9400cxi_device },
From e9f19ec32b11a8d36ecb37af9b1b67200889dd98 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Wed, 29 May 2024 23:54:39 +0200
Subject: [PATCH 009/567] Fix compile warning.
See above.
---
src/video/vid_s3.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index e74ff8c06f..8ecd3711e4 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -145,7 +145,6 @@ static video_timings_t timing_s3_stealth64_vlb = { .type = VIDEO_BUS, .write_b =
static video_timings_t timing_s3_stealth64_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 };
static video_timings_t timing_s3_vision864_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 };
static video_timings_t timing_s3_vision864_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 };
-static video_timings_t timing_s3_vision868_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 };
static video_timings_t timing_s3_vision868_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 };
static video_timings_t timing_s3_vision964_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 };
static video_timings_t timing_s3_vision964_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 };
From 11d7afd5780a5a7eb3fee560decc14934354bf63 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Thu, 30 May 2024 00:13:29 +0200
Subject: [PATCH 010/567] Video changes part 3 (minor though)
1. Added an on-board S3 ViRGE DX (375) video card to the Intel AP440FX socket 8-based machine alongside its on-board CS4236B audio.
2. Sanity check for on-board S3 ViRGE devices.
---
src/include/86box/video.h | 1 +
src/machine/m_at_socket8.c | 7 +++++
src/machine/machine_table.c | 14 +++++-----
src/video/vid_s3_virge.c | 51 +++++++++++++++++++++++++++----------
4 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index e1a1a75025..83930122ba 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -528,6 +528,7 @@ extern const device_t s3_diamond_stealth_2000_pci_device;
extern const device_t s3_diamond_stealth_3000_pci_device;
extern const device_t s3_stb_velocity_3d_pci_device;
extern const device_t s3_virge_375_pci_device;
+extern const device_t s3_virge_375_onboard_pci_device;
extern const device_t s3_diamond_stealth_2000pro_pci_device;
extern const device_t s3_virge_385_pci_device;
extern const device_t s3_virge_357_pci_device;
diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c
index e8262a6f4c..8c2688c1a3 100644
--- a/src/machine/m_at_socket8.c
+++ b/src/machine/m_at_socket8.c
@@ -33,6 +33,7 @@
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/sio.h>
+#include <86box/sound.h>
#include <86box/hwm.h>
#include <86box/spd.h>
#include <86box/video.h>
@@ -322,6 +323,12 @@ machine_at_ap440fx_init(const machine_t *model)
device_add(&pc87307_device);
device_add(&intel_flash_bxt_ami_device);
+ if (sound_card_current[0] == SOUND_INTERNAL)
+ device_add(&cs4236b_device);
+
+ if (gfxcard[0] == VID_INTERNAL)
+ device_add(&s3_virge_375_onboard_pci_device);
+
return ret;
}
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 4b91f1668e..9d38686bda 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -5182,7 +5182,7 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
- /* The board has a "ASII KB-100" which I was not able to find any information about,
+ /* The board has a "ASII KB-100" which I was not able to find any information about,
but the BIOS sends commands C9 without a parameter and D5, both of which are
Phoenix MultiKey commands. */
{
@@ -10606,7 +10606,7 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
- /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO.
+ /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO.
A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */
{
.name = "[i430HX] Supermicro P55T2S",
@@ -12658,7 +12658,7 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
-
+
/* ALi ALADDiN IV+ */
/* Has the ALi M1543 southbridge with on-chip KBC. */
{
@@ -13051,7 +13051,7 @@ const machine_t machines[] = {
.max_multi = 5.5
},
.bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB,
- .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB,
+ .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB,
.ram = {
.min = 8192,
.max = 786432,
@@ -13462,7 +13462,7 @@ const machine_t machines[] = {
.max_multi = 3.5
},
.bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB,
- .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */
+ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_VIDEO | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */
.ram = {
.min = 8192,
.max = 131072,
@@ -13476,8 +13476,8 @@ const machine_t machines[] = {
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
- .vid_device = NULL,
- .snd_device = NULL,
+ .vid_device = &s3_virge_375_onboard_pci_device,
+ .snd_device = &cs4236b_device,
.net_device = NULL
},
/* According to tests from real hardware: This has AMI MegaKey KBC firmware on the
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 4d64dffbd4..26560c4984 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -295,6 +295,8 @@ typedef struct virge_t {
void *i2c, *ddc;
int waiting;
+
+ int has_bios;
} virge_t;
static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 };
@@ -1070,14 +1072,13 @@ s3_virge_updatemapping(virge_t *virge)
virge->linear_base &= ~(virge->linear_size - 1);
s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7);
if (virge->linear_base == 0xa0000) {
- mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
+ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0);
mem_mapping_disable(&virge->linear_mapping);
} else {
- if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) {
+ if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X)
virge->linear_base &= 0xfe000000;
- } else {
+ else
virge->linear_base &= 0xfc000000;
- }
mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size);
}
@@ -4069,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv)
break;
case 0x30:
- ret = virge->pci_regs[0x30] & 0x01;
+ ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00;
break; /*BIOS ROM address*/
case 0x31:
ret = 0x00;
break;
case 0x32:
- ret = virge->pci_regs[0x32];
+ ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00;
break;
case 0x33:
- ret = virge->pci_regs[0x33];
+ ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00;
break;
case 0x34:
@@ -4202,6 +4203,8 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
case 0x30:
case 0x32:
case 0x33:
+ if (!virge->has_bios)
+ return;
virge->pci_regs[addr] = val;
if (virge->pci_regs[0x30] & 0x01) {
uint32_t biosaddr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24);
@@ -4337,7 +4340,8 @@ s3_virge_reset(void *priv)
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
- mem_mapping_disable(&virge->bios_rom.mapping);
+ if (virge->has_bios)
+ mem_mapping_disable(&virge->bios_rom.mapping);
s3_virge_updatemapping(virge);
@@ -4360,6 +4364,8 @@ s3_virge_init(const device_t *info)
else
virge->memory_size = device_get_config_int("memory");
+ virge->has_bios = !!(info->local & 0x100);
+
switch (info->local) {
case S3_VIRGE_325:
bios_fn = ROM_VIRGE_325;
@@ -4374,7 +4380,7 @@ s3_virge_init(const device_t *info)
bios_fn = ROM_STB_VELOCITY_3D;
break;
case S3_VIRGE_DX:
- bios_fn = ROM_VIRGE_DX;
+ bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL;
break;
case S3_DIAMOND_STEALTH3D_2000PRO:
bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO;
@@ -4408,11 +4414,12 @@ s3_virge_init(const device_t *info)
rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else
rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
- }
- mem_mapping_disable(&virge->bios_rom.mapping);
+ mem_mapping_disable(&virge->bios_rom.mapping);
+ }
- mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear,
+ mem_mapping_add(&virge->linear_mapping, 0, 0,
+ svga_read_linear,
svga_readw_linear,
svga_readl_linear,
svga_write_linear,
@@ -4421,7 +4428,8 @@ s3_virge_init(const device_t *info)
NULL,
MEM_MAPPING_EXTERNAL,
&virge->svga);
- mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read,
+ mem_mapping_add(&virge->mmio_mapping, 0, 0,
+ s3_virge_mmio_read,
s3_virge_mmio_read_w,
s3_virge_mmio_read_l,
s3_virge_mmio_write,
@@ -4430,7 +4438,8 @@ s3_virge_init(const device_t *info)
NULL,
MEM_MAPPING_EXTERNAL,
virge);
- mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read,
+ mem_mapping_add(&virge->new_mmio_mapping, 0, 0,
+ s3_virge_mmio_read,
s3_virge_mmio_read_w,
s3_virge_mmio_read_l,
s3_virge_mmio_write,
@@ -4896,6 +4905,20 @@ const device_t s3_virge_375_pci_device = {
.config = s3_virge_config
};
+const device_t s3_virge_375_onboard_pci_device = {
+ .name = "S3 ViRGE/DX (375) On-Board PCI",
+ .internal_name = "virge375_onboard_pci",
+ .flags = DEVICE_PCI,
+ .local = S3_VIRGE_DX | 0x100,
+ .init = s3_virge_init,
+ .close = s3_virge_close,
+ .reset = s3_virge_reset,
+ { .available = NULL },
+ .speed_changed = s3_virge_speed_changed,
+ .force_redraw = s3_virge_force_redraw,
+ .config = s3_virge_config
+};
+
const device_t s3_diamond_stealth_2000pro_pci_device = {
.name = "S3 ViRGE/DX (Diamond Stealth 3D 2000 Pro) PCI",
.internal_name = "stealth3d_2000pro_pci",
From 3d74f43b9557e13c1d7c18cb4d4a744417315b78 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Thu, 30 May 2024 00:25:29 +0200
Subject: [PATCH 011/567] NCR 53c400 timing fixes.
See above (CD-ROM speeds too for said SCSI chips).
---
src/scsi/scsi_ncr53c400.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c
index ca4d28ffb9..0e772c16c0 100644
--- a/src/scsi/scsi_ncr53c400.c
+++ b/src/scsi/scsi_ncr53c400.c
@@ -146,8 +146,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv)
if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) {
ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY;
ncr400->busy = 1;
- if (!(ncr->mode & MODE_MONITOR_BUSY))
- timer_on_auto(&ncr400->timer, ncr->period / 280.0);
+ if (!(ncr->mode & MODE_MONITOR_BUSY) && ((scsi_device_get_callback(dev) > 0.0)))
+ timer_on_auto(&ncr400->timer, ncr->period / 250.0);
}
}
break;
@@ -182,9 +182,12 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv)
memset(ncr400->buffer, 0, MIN(128, dev->buffer_length));
if (ncr->mode & MODE_MONITOR_BUSY)
timer_on_auto(&ncr400->timer, ncr->period);
- else
+ else if (scsi_device_get_callback(dev) > 0.0)
timer_on_auto(&ncr400->timer, 40.0);
- ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer));
+ else
+ timer_on_auto(&ncr400->timer, ncr->period);
+
+ ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer));
}
break;
@@ -239,8 +242,8 @@ ncr53c400_read(uint32_t addr, void *priv)
if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) {
ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY;
ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl);
- if (!(ncr->mode & MODE_MONITOR_BUSY))
- timer_on_auto(&ncr400->timer, ncr->period / 280.0);
+ if (!(ncr->mode & MODE_MONITOR_BUSY) && (scsi_device_get_callback(dev) > 0.0))
+ timer_on_auto(&ncr400->timer, ncr->period / 250.0);
}
}
break;
From 0897eea7df06d51b7343e053e4e6060909c604f2 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Thu, 30 May 2024 00:43:00 +0200
Subject: [PATCH 012/567] Plus a compile fix.
---
src/video/vid_s3_virge.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 26560c4984..352fe2bd82 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -1072,7 +1072,7 @@ s3_virge_updatemapping(virge_t *virge)
virge->linear_base &= ~(virge->linear_size - 1);
s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7);
if (virge->linear_base == 0xa0000) {
- mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0);
+ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
mem_mapping_disable(&virge->linear_mapping);
} else {
if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X)
From eff32906c5797a9a4a2ede39053ad94e20716e2e Mon Sep 17 00:00:00 2001
From: TC1995
Date: Thu, 30 May 2024 16:35:32 +0200
Subject: [PATCH 013/567] Fix onboard flag for actual onboard ViRGE BIOSes.
So that ViRGE cards can work again without black screening.
---
src/video/vid_s3_virge.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 352fe2bd82..7982f816e5 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -296,7 +296,7 @@ typedef struct virge_t {
int waiting;
- int has_bios;
+ int onboard;
} virge_t;
static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 };
@@ -4070,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv)
break;
case 0x30:
- ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00;
+ ret = (!virge->onboard) ? (virge->pci_regs[0x30] & 0x01) : 0x00;
break; /*BIOS ROM address*/
case 0x31:
ret = 0x00;
break;
case 0x32:
- ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00;
+ ret = (!virge->onboard) ? virge->pci_regs[0x32] : 0x00;
break;
case 0x33:
- ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00;
+ ret = (!virge->onboard) ? virge->pci_regs[0x33] : 0x00;
break;
case 0x34:
@@ -4203,7 +4203,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
case 0x30:
case 0x32:
case 0x33:
- if (!virge->has_bios)
+ if (virge->onboard)
return;
virge->pci_regs[addr] = val;
if (virge->pci_regs[0x30] & 0x01) {
@@ -4340,7 +4340,7 @@ s3_virge_reset(void *priv)
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
- if (virge->has_bios)
+ if (!virge->onboard)
mem_mapping_disable(&virge->bios_rom.mapping);
s3_virge_updatemapping(virge);
@@ -4364,7 +4364,7 @@ s3_virge_init(const device_t *info)
else
virge->memory_size = device_get_config_int("memory");
- virge->has_bios = !!(info->local & 0x100);
+ virge->onboard = !!(info->local & 0x100);
switch (info->local) {
case S3_VIRGE_325:
@@ -4380,7 +4380,7 @@ s3_virge_init(const device_t *info)
bios_fn = ROM_STB_VELOCITY_3D;
break;
case S3_VIRGE_DX:
- bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL;
+ bios_fn = virge->onboard ? NULL : ROM_VIRGE_DX;
break;
case S3_DIAMOND_STEALTH3D_2000PRO:
bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO;
From c68a4445ae9dd8bcbe95c0338875c3df9adf9ccf Mon Sep 17 00:00:00 2001
From: Shelby Jueden
Date: Thu, 30 May 2024 08:13:04 -0700
Subject: [PATCH 014/567] Add years to the Machine Type names
---
src/machine/machine_table.c | 44 ++++++++++++++++++-------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 9d38686bda..69a87e3253 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -58,28 +58,28 @@ extern const device_t ps1_2011_device;
const machine_filter_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE },
- { "8088", MACHINE_TYPE_8088 },
- { "8086", MACHINE_TYPE_8086 },
- { "80286", MACHINE_TYPE_286 },
- { "i386SX", MACHINE_TYPE_386SX },
- { "486SLC", MACHINE_TYPE_486SLC },
- { "i386DX", MACHINE_TYPE_386DX },
- { "i386DX/i486", MACHINE_TYPE_386DX_486 },
- { "i486 (Socket 168 and 1)", MACHINE_TYPE_486 },
- { "i486 (Socket 2)", MACHINE_TYPE_486_S2 },
- { "i486 (Socket 3)", MACHINE_TYPE_486_S3 },
- { "i486 (Miscellaneous)", MACHINE_TYPE_486_MISC },
- { "Socket 4", MACHINE_TYPE_SOCKET4 },
- { "Socket 5", MACHINE_TYPE_SOCKET5 },
- { "Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V },
- { "Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 },
- { "Super Socket 7", MACHINE_TYPE_SOCKETS7 },
- { "Socket 8", MACHINE_TYPE_SOCKET8 },
- { "Slot 1", MACHINE_TYPE_SLOT1 },
- { "Slot 1/2", MACHINE_TYPE_SLOT1_2 },
- { "Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 },
- { "Slot 2", MACHINE_TYPE_SLOT2 },
- { "Socket 370", MACHINE_TYPE_SOCKET370 },
+ { "[1979] 8088", MACHINE_TYPE_8088 },
+ { "[1978] 8086", MACHINE_TYPE_8086 },
+ { "[1982] 80286", MACHINE_TYPE_286 },
+ { "[1988] i386SX", MACHINE_TYPE_386SX },
+ { "[1992] 486SLC", MACHINE_TYPE_486SLC },
+ { "[1985] i386DX", MACHINE_TYPE_386DX },
+ { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 },
+ { "[1992] i486 (Socket 168 and 1)", MACHINE_TYPE_486 },
+ { "[1992] i486 (Socket 2)", MACHINE_TYPE_486_S2 },
+ { "[1994] i486 (Socket 3)", MACHINE_TYPE_486_S3 },
+ { "[1992] i486 (Miscellaneous)", MACHINE_TYPE_486_MISC },
+ { "[1993] Socket 4", MACHINE_TYPE_SOCKET4 },
+ { "[1994] Socket 5", MACHINE_TYPE_SOCKET5 },
+ { "[1995] Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V },
+ { "[1995] Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 },
+ { "[1998] Super Socket 7", MACHINE_TYPE_SOCKETS7 },
+ { "[1995] Socket 8", MACHINE_TYPE_SOCKET8 },
+ { "[1996] Slot 1", MACHINE_TYPE_SLOT1 },
+ { "[1998] Slot 1/2", MACHINE_TYPE_SLOT1_2 },
+ { "[1998] Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 },
+ { "[1998] Slot 2", MACHINE_TYPE_SLOT2 },
+ { "[1998] Socket 370", MACHINE_TYPE_SOCKET370 },
{ "Miscellaneous", MACHINE_TYPE_MISC }
};
From 3f0e5ccf27c21c6d4ddfdf4ab3c9a5989321ca7e Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 00:38:07 -0400
Subject: [PATCH 015/567] Add the lo-tech EMS Board
---
src/device/isamem.c | 149 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 146 insertions(+), 3 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 70f51ce8d4..9ff61bc452 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -33,8 +33,10 @@
*
*
* Authors: Fred N. van Kempen,
+ * Jasmine Iwanek
*
- * Copyright 2018 Fred N. van Kempen.
+ * Copyright 2018 Fred N. van Kempen.
+ * Copyright 2022-2024 Jasmine Iwanek.
*
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
@@ -98,6 +100,7 @@
#define ISAMEM_ABOVEBOARD_CARD 12
#define ISAMEM_BRAT_CARD 13
#define ISAMEM_EV165A_CARD 14
+#define ISAMEM_LOTECH_CARD 15
#define ISAMEM_DEBUG 0
@@ -318,6 +321,26 @@ ems_read(uint16_t port, void *priv)
return ret;
}
+/* Handle a READ operation from one of our registers. */
+static uint8_t
+consecutive_ems_read(uint16_t port, void *priv)
+{
+ const memdev_t *dev = (memdev_t *) priv;
+ uint8_t ret = 0xff;
+ int vpage;
+
+ /* Get the viewport page number. */
+ vpage = (port - dev->base_addr);
+
+ isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage);
+
+ ret = dev->ems[vpage].page;
+ if (dev->ems[vpage].enabled)
+ ret |= 0x80;
+
+ return ret;
+}
+
/* Handle a WRITE operation to one of our registers. */
static void
ems_write(uint16_t port, uint8_t val, void *priv)
@@ -393,6 +416,47 @@ ems_write(uint16_t port, uint8_t val, void *priv)
}
}
+/* Handle a WRITE operation to one of our registers. */
+static void
+consecutive_ems_write(uint16_t port, uint8_t val, void *priv)
+{
+ memdev_t *dev = (memdev_t *) priv;
+ int vpage;
+
+ /* Get the viewport page number. */
+ vpage = (port - dev->base_addr);
+
+ isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage);
+
+ isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val);
+ /* Set the page number. */
+ dev->ems[vpage].enabled = (val & 0xff);
+ dev->ems[vpage].page = (val & 0xff);
+
+ /* Make sure we can do that.. */
+ if (dev->flags & FLAG_CONFIG) {
+ if (dev->ems[vpage].page < dev->ems_pages) {
+ /* Pre-calculate the page address in EMS RAM. */
+ dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0xff) * EMS_PGSIZE);
+ } else {
+ /* That page does not exist. */
+ dev->ems[vpage].enabled = 0;
+ }
+
+ if (dev->ems[vpage].enabled) {
+ /* Update the EMS RAM address for this page. */
+ mem_mapping_set_exec(&dev->ems[vpage].mapping,
+ dev->ems[vpage].addr);
+
+ /* Enable this page. */
+ mem_mapping_enable(&dev->ems[vpage].mapping);
+ } else {
+ /* Disable this page. */
+ mem_mapping_disable(&dev->ems[vpage].mapping);
+ }
+ }
+}
+
/* Initialize the device for use. */
static void *
isamem_init(const device_t *info)
@@ -476,6 +540,13 @@ isamem_init(const device_t *info)
dev->flags |= FLAG_FAST;
break;
+ case ISAMEM_LOTECH_CARD:
+ dev->base_addr = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = 0;
+ dev->frame_addr = device_get_config_hex20("frame");
+ dev->flags |= (FLAG_EMS | FLAG_CONFIG);
+
default:
break;
}
@@ -663,9 +734,14 @@ isamem_init(const device_t *info)
mem_mapping_disable(&dev->ems[i].mapping);
/* Set up an I/O port handler. */
- io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2,
- ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
+ if (dev->board != ISAMEM_LOTECH_CARD)
+ io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2,
+ ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
}
+
+ if (dev->board == ISAMEM_LOTECH_CARD)
+ io_sethandler(dev->base_addr, 4,
+ consecutive_ems_read, NULL, NULL, consecutive_ems_write, NULL, NULL, dev);
}
/* Let them know our device instance. */
@@ -1439,6 +1515,72 @@ static const device_t brat_device = {
};
#endif
+static const device_config_t lotech_config[] = {
+// clang-format off
+ {
+ .name = "base",
+ .description = "Address",
+ .type = CONFIG_HEX16,
+ .default_string = "",
+ .default_int = 0x0260,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ { .description = "260H", .value = 0x0260 },
+ { .description = "264H", .value = 0x0264 },
+ { .description = "268H", .value = 0x0268 },
+ { .description = "26CH", .value = 0x026C },
+ { .description = "" }
+ },
+ },
+ {
+ .name = "frame",
+ .description = "Frame Address",
+ .type = CONFIG_HEX20,
+ .default_string = "",
+ .default_int = 0xe0000,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ { .description = "Disabled", .value = 0x00000 },
+ { .description = "C000H", .value = 0xC0000 },
+ { .description = "D000H", .value = 0xD0000 },
+ { .description = "E000H", .value = 0xE0000 },
+ { .description = "" }
+ },
+ },
+ {
+ .name = "size",
+ .description = "Memory Size",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 2048,
+ .file_filter = "",
+ .spinner = {
+ .min = 512,
+ .max = 4096,
+ .step = 512
+ },
+ .selection = { { 0 } }
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+// clang-format on
+};
+
+static const device_t lotech_device = {
+ .name = "Lo-tech EMS Board",
+ .internal_name = "lotechems",
+ .flags = DEVICE_ISA,
+ .local = ISAMEM_LOTECH_CARD,
+ .init = isamem_init,
+ .close = isamem_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = lotech_config
+};
+
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE)
static const device_config_t rampage_config[] = {
// clang-format off
@@ -1676,6 +1818,7 @@ static const struct {
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB)
{ &iab_device },
#endif
+ { &lotech_device },
{ NULL }
// clang-format on
};
From 028142136a4a031c0ead105b27b9cd0431ed8069 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 00:44:04 -0400
Subject: [PATCH 016/567] Fix Max EMS per board
---
src/device/isamem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 9ff61bc452..fea9c0d880 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -108,7 +108,7 @@
#define RAM_UMAMEM (384 << 10) /* upper memory block */
#define RAM_EXTMEM (1024 << 10) /* start of high memory */
-#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */
+#define EMS_MAXSIZE (4096 << 10) /* max EMS memory size */
#define EMS_PGSIZE (16 << 10) /* one page is this big */
#define EMS_MAXPAGE 4 /* number of viewport pages */
@@ -696,7 +696,7 @@ isamem_init(const device_t *info)
/* If EMS is enabled, use the remainder for EMS. */
if (dev->flags & FLAG_EMS) {
- /* EMS 3.2 cannot have more than 2048KB per board. */
+ /* EMS 3.2 cannot have more than 4096KB per board. */
t = k;
if (t > EMS_MAXSIZE)
t = EMS_MAXSIZE;
From bd28ad2fe44f70d75b00db38049e1db55acab032 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 00:45:33 -0400
Subject: [PATCH 017/567] Fix trivial bug in EMS5150
---
src/device/isamem.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index fea9c0d880..09374f30dc 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -499,6 +499,7 @@ isamem_init(const device_t *info)
case ISAMEM_EMS5150_CARD: /* Micro Mainframe EMS-5150(T) */
dev->base_addr = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
+ dev->start_addr = 0;
dev->frame_addr = 0xD0000;
dev->flags |= (FLAG_EMS | FLAG_CONFIG);
break;
From ab137e999e9339f660219c3df4186a99b7278f04 Mon Sep 17 00:00:00 2001
From: OBattler
Date: Sat, 1 Jun 2024 02:00:22 +0200
Subject: [PATCH 018/567] VIA Apollo VPX: Fix SMRAM handling.
---
src/chipset/via_apollo.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c
index 7c1203c3ab..20e2c7f74f 100644
--- a/src/chipset/via_apollo.c
+++ b/src/chipset/via_apollo.c
@@ -444,7 +444,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
break;
}
- else
+ else if (dev->id == VIA_595)
switch (val & 0x03) {
case 0x00:
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0);
@@ -468,6 +468,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
default:
break;
}
+ else {
+ smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000,
+ (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01),
+ dev->pci_conf[0x63] & 0x01);
+ flushmmucache();
+ }
break;
case 0x65:
if (dev->id == VIA_585)
@@ -532,6 +538,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[0x6d] = (dev->pci_conf[0x6d] & ~0x7f) | (val & 0x7f);
else
dev->pci_conf[0x6d] = val;
+ if (dev->id == VIA_585) {
+ smram_disable_all();
+ smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000,
+ (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01),
+ dev->pci_conf[0x63] & 0x01);
+ flushmmucache();
+ }
break;
case 0x6e:
if ((dev->id == VIA_595) || (dev->id == VIA_694))
From b7994ab917a9657290279438550208deca8358fa Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 22:40:52 -0400
Subject: [PATCH 019/567] A few formatting cleanups in fdd.c
---
src/floppy/fdd.c | 83 +++++++++++++++++++-----------------------------
1 file changed, 33 insertions(+), 50 deletions(-)
diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c
index 72d6ac6485..32cc2a570b 100644
--- a/src/floppy/fdd.c
+++ b/src/floppy/fdd.c
@@ -104,7 +104,7 @@ static const struct
void (*close)(int drive);
int size;
} loaders[] = {
- {"001", img_load, img_close, -1},
+ { "001", img_load, img_close, -1},
{ "002", img_load, img_close, -1},
{ "003", img_load, img_close, -1},
{ "004", img_load, img_close, -1},
@@ -139,59 +139,42 @@ static const struct
{ 0, 0, 0, 0 }
};
-static const struct
-{
+static const struct {
int max_track;
int flags;
const char *name;
const char *internal_name;
-} drive_types[] =
-{
- { /*None*/
- 0, 0, "None", "none"
- },
- { /*5.25" 1DD*/
- 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd"
- },
- { /*5.25" DD*/
- 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd"
- },
- { /*5.25" QD*/
- 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd"
- },
- { /*5.25" HD PS/2*/
- 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2"
- },
- { /*5.25" HD*/
- 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd"
- },
- { /*5.25" HD Dual RPM*/
- 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm"
- },
- { /*3.5" 1DD*/
- 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd"
- },
- { /*3.5" DD*/
- 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd"
- },
- { /*3.5" HD PS/2*/
- 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2"
- },
- { /*3.5" HD*/
- 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd"
- },
- { /*3.5" HD PC-98*/
- 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec"
- },
- { /*3.5" HD 3-Mode*/
- 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode"
- },
- { /*3.5" ED*/
- 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed"
- },
- { /*End of list*/
- -1, -1, "", ""
- }
+} drive_types[] = {
+ /* None */
+ { 0, 0, "None", "none" },
+ /* 5.25" 1DD */
+ { 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd" },
+ /* 5.25" DD */
+ { 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" },
+ /* 5.25" QD */
+ { 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" },
+ /* 5.25" HD PS/2 */
+ { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" },
+ /* 5.25" HD */
+ { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" },
+ /* 5.25" HD Dual RPM */
+ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" },
+ /* 3.5" 1DD */
+ { 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" },
+ /* 3.5" DD */
+ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" },
+ /* 3.5" HD PS/2 */
+ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" },
+ /* 3.5" HD */
+ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" },
+ /* 3.5" HD PC-98 */
+ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" },
+ /* 3.5" HD 3-Mode */
+ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" },
+ /* 3.5" ED */
+ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" },
+ /* End of list */
+ { -1, -1, "", "" }
};
#ifdef ENABLE_FDD_LOG
From 33eb7993fb35076cf521c3c2769f0ff0f1a2485f Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 23:42:07 -0400
Subject: [PATCH 020/567] Add some notes on drive equivalents
---
src/floppy/fdd.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c
index 32cc2a570b..351742b44c 100644
--- a/src/floppy/fdd.c
+++ b/src/floppy/fdd.c
@@ -161,17 +161,17 @@ static const struct {
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" },
/* 3.5" 1DD */
{ 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" },
- /* 3.5" DD */
+ /* 3.5" DD, Equivalent to TEAC FD-235F */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" },
/* 3.5" HD PS/2 */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" },
- /* 3.5" HD */
+ /* 3.5" HD, Equivalent to TEAC FD-235HF */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" },
/* 3.5" HD PC-98 */
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" },
- /* 3.5" HD 3-Mode */
+ /* 3.5" HD 3-Mode, Equivalent to TEAC FD-235HG */
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" },
- /* 3.5" ED */
+ /* 3.5" ED, Equivalent to TEAC FD-235J */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" },
/* End of list */
{ -1, -1, "", "" }
From 77d1da5e8ff582adcb2af4162a31e3b3da0191aa Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 23:50:48 -0400
Subject: [PATCH 021/567] Add ED dual RPM drive
---
src/floppy/fdd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c
index 351742b44c..8d3d40ecce 100644
--- a/src/floppy/fdd.c
+++ b/src/floppy/fdd.c
@@ -173,6 +173,8 @@ static const struct {
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" },
/* 3.5" ED, Equivalent to TEAC FD-235J */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" },
+ /* 3.5" ED Dual RPM, Equivalent to TEAC FD-335J */
+ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M 300/360 RPM", "35_2ed_dualrpm" },
/* End of list */
{ -1, -1, "", "" }
};
From 8e556ada7ec6fc9ec48078b50d66c24cc3dc02a1 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 23:51:55 -0400
Subject: [PATCH 022/567] Add (commented out) eqiv of the TEAC FD-235GF
Commented out because it could actually be our existing 35_2hd_nec, we need to check whether this needs the INVERT_DENSEL flag or not
---
src/floppy/fdd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c
index 8d3d40ecce..81edcc8b81 100644
--- a/src/floppy/fdd.c
+++ b/src/floppy/fdd.c
@@ -167,6 +167,8 @@ static const struct {
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" },
/* 3.5" HD, Equivalent to TEAC FD-235HF */
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" },
+ /* TODO: 3.5" DD, Equivalent to TEAC FD-235GF */
+// { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.25M", "35_2hd_2mode" },
/* 3.5" HD PC-98 */
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" },
/* 3.5" HD 3-Mode, Equivalent to TEAC FD-235HG */
From af03a0147e3b6c74b65911c7348cd9656300c1a9 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 31 May 2024 02:06:05 -0400
Subject: [PATCH 023/567] Two fixes to lo-tech EMS board
---
src/device/isamem.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 09374f30dc..df5161bb61 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -430,14 +430,14 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv)
isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val);
/* Set the page number. */
- dev->ems[vpage].enabled = (val & 0xff);
- dev->ems[vpage].page = (val & 0xff);
+ dev->ems[vpage].enabled = 1;
+ dev->ems[vpage].page = val;
/* Make sure we can do that.. */
if (dev->flags & FLAG_CONFIG) {
if (dev->ems[vpage].page < dev->ems_pages) {
/* Pre-calculate the page address in EMS RAM. */
- dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0xff) * EMS_PGSIZE);
+ dev->ems[vpage].addr = dev->ram + dev->ems_start + (val * EMS_PGSIZE);
} else {
/* That page does not exist. */
dev->ems[vpage].enabled = 0;
@@ -1543,7 +1543,6 @@ static const device_config_t lotech_config[] = {
.file_filter = "",
.spinner = { 0 },
.selection = {
- { .description = "Disabled", .value = 0x00000 },
{ .description = "C000H", .value = 0xC0000 },
{ .description = "D000H", .value = 0xD0000 },
{ .description = "E000H", .value = 0xE0000 },
From 066f153dee624310f29f5df67f2b99ac72e1a07f Mon Sep 17 00:00:00 2001
From: Jose Phillips
Date: Sat, 1 Jun 2024 18:39:40 -0500
Subject: [PATCH 024/567] Added Machine Motherboard Acer100T
---
src/chipset/CMakeLists.txt | 2 +-
src/chipset/ali1409.c | 199 +++++++++++++++++++++++++++++++++++
src/include/86box/chipset.h | 1 +
src/include/86box/machine.h | 1 +
src/include/86box/video.h | 1 +
src/machine/m_at_286_386sx.c | 25 +++++
src/machine/machine_table.c | 40 +++++++
src/video/vid_oak_oti.c | 80 ++++++++++++--
8 files changed, 341 insertions(+), 8 deletions(-)
create mode 100644 src/chipset/ali1409.c
diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt
index 0406ea0b89..4daccd2d8e 100644
--- a/src/chipset/CMakeLists.txt
+++ b/src/chipset/CMakeLists.txt
@@ -14,7 +14,7 @@
#
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
+ ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c ali1409.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
opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
diff --git a/src/chipset/ali1409.c b/src/chipset/ali1409.c
new file mode 100644
index 0000000000..3e4286f808
--- /dev/null
+++ b/src/chipset/ali1409.c
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ *
+ * Implementation of the ALi M1409 chipset.
+ *
+ * Note: This chipset has no datasheet, everything were done via
+ * reverse engineering.
+ *
+ *
+ *
+ * Authors: Jose Phillips,
+ * Sarah Walker,
+ *
+ * Copyright 2024 Jose Phillips.
+ * Copyright 2008-2018 Sarah Walker.
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#define HAVE_STDARG_H
+#include <86box/86box.h>
+#include "cpu.h"
+#include <86box/timer.h>
+#include <86box/io.h>
+#include <86box/device.h>
+
+#include <86box/apm.h>
+#include <86box/mem.h>
+#include <86box/fdd.h>
+#include <86box/fdc.h>
+#include <86box/smram.h>
+#include <86box/chipset.h>
+
+
+
+#ifdef ENABLE_ALI1409_LOG
+int ali1409_do_log = ENABLE_ALI1409_LOG;
+
+static void
+ali1409_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (ali1409_do_log) {
+ va_start(ap, fmt);
+ pclog_ex(fmt, ap);
+ va_end(ap);
+ }
+}
+#else
+# define ali1409_log(fmt, ...)
+#endif
+
+typedef struct ali_1409_t {
+ uint8_t is_g;
+ uint8_t index;
+ uint8_t cfg_locked;
+ uint8_t reg_57h;
+ uint8_t regs[256];
+ uint8_t last_reg;
+} ali1409_t;
+
+
+static void
+ali1409_write(uint16_t addr, uint8_t val, void *priv)
+{
+ ali1409_t *dev = (ali1409_t *) priv;
+ ali1409_log ("INPUT:addr %02x ,Value %02x \n" , addr , val);
+
+ if (addr & 1) {
+ if (dev->cfg_locked) {
+ if (dev->last_reg == 0x14 && val == 0x09)
+ dev->cfg_locked = 0;
+
+ dev->last_reg = val;
+ return;
+ }
+
+ if (dev->index == 0xff && val == 0xff)
+ dev->cfg_locked = 1;
+ else {
+ ali1409_log("Write reg %02x %02x %08x\n", dev->index, val, cs);
+ dev->regs[dev->index] = val;
+
+ switch (dev->index) {
+ case 0xa:
+ switch ((val >> 4) & 3) {
+ case 0:
+ mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ break;
+ case 1:
+ mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
+ break;
+ case 2:
+ mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
+ break;
+ case 3:
+ mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ break;
+ }
+ break;
+ case 0xb:
+ switch ((val >> 4) & 3) {
+ case 0:
+ mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ break;
+ case 1:
+ mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
+ break;
+ case 2:
+ mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY| MEM_WRITE_INTERNAL);
+ break;
+ case 3:
+ mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ break;
+ }
+ break;
+ }
+ }
+ } else
+ dev->index = val;
+}
+
+
+static uint8_t
+ali1409_read(uint16_t addr, void *priv)
+{
+ ali1409_log ("reading at %02X\n",addr);
+ const ali1409_t *dev = (ali1409_t *) priv;
+ uint8_t ret = 0xff;
+
+ if (dev->cfg_locked)
+ ret = 0xff;
+ if (addr & 1) {
+ if ((dev->index >= 0xc0 || dev->index == 0x20) && cpu_iscyrix)
+ ret = 0xff;
+ ret = dev->regs[dev->index];
+ } else
+ ret = dev->index;
+ return ret;
+}
+
+
+
+static void
+ali1409_close(void *priv)
+{
+ ali1409_t *dev = (ali1409_t *) priv;
+
+ free(dev);
+}
+
+static void *
+ali1409_init(const device_t *info)
+{
+ ali1409_t *dev = (ali1409_t *) malloc(sizeof(ali1409_t));
+ memset(dev, 0, sizeof(ali1409_t));
+
+ dev->cfg_locked = 1;
+
+ /* M1409 Ports:
+ 22h Index Port
+ 23h Data Port
+ */
+
+ ali1409_log ("Bus speed: %i",cpu_busspeed);
+
+
+ io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
+ io_sethandler(0x037f, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
+ io_sethandler(0x03f3, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
+
+ return dev;
+}
+
+const device_t ali1409_device = {
+ .name = "ALi M1409",
+ .internal_name = "ali1409",
+ .flags = 0,
+ .local = 0,
+ .init = ali1409_init,
+ .close = ali1409_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h
index d5a96baf94..4be7c2ae27 100644
--- a/src/include/86box/chipset.h
+++ b/src/include/86box/chipset.h
@@ -24,6 +24,7 @@ extern const device_t acc2168_device;
extern const device_t ali1217_device;
extern const device_t ali1429_device;
extern const device_t ali1429g_device;
+extern const device_t ali1409_device;
extern const device_t ali1435_device;
extern const device_t ali1489_device;
extern const device_t ali1531_device;
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index a5b9223583..7ff00ed525 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -481,6 +481,7 @@ extern int machine_at_325ax_init(const machine_t *);
extern int machine_at_mr1217_init(const machine_t *);
extern int machine_at_pja511m_init(const machine_t *);
extern int machine_at_prox1332_init(const machine_t *);
+extern int machine_at_acer100t_init(const machine_t *);
extern int machine_at_awardsx_init(const machine_t *);
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index 83930122ba..ed7064f9ce 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -453,6 +453,7 @@ extern const device_t oti037c_device;
extern const device_t oti067_device;
extern const device_t oti067_acer386_device;
extern const device_t oti067_ama932j_device;
+extern const device_t oti077_acer100t_device;
extern const device_t oti077_device;
/* Paradise/WD (S)VGA */
diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c
index b2470bae24..a1c3d77724 100644
--- a/src/machine/m_at_286_386sx.c
+++ b/src/machine/m_at_286_386sx.c
@@ -705,6 +705,31 @@ machine_at_awardsx_init(const machine_t *model)
return ret;
}
+int
+machine_at_acer100t_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_linear("roms/machines/acer100t/acer386.bin",
+ 0x000f0000, 65536, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_at_ps2_ide_init(model);
+
+ if (fdc_type == FDC_INTERNAL)
+ device_add(&fdc_at_device);
+
+ device_add(&ali1409_device);
+ if (gfxcard[0] == VID_INTERNAL)
+ device_add(&oti077_acer100t_device);
+
+
+ return ret;
+}
+
+
int
machine_at_arb1374_init(const machine_t *model)
{
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 69a87e3253..f97fab9010 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -4168,6 +4168,46 @@ const machine_t machines[] = {
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
+ },
+ {
+ .name = "[ALI M1409] Acer 100T",
+ .internal_name = "acer100t",
+ .type = MACHINE_TYPE_386SX,
+ .chipset = MACHINE_CHIPSET_ALI_M1409,
+ .init = machine_at_acer100t_init,
+ .p1_handler = NULL,
+ .gpio_handler = NULL,
+ .available_flag = MACHINE_AVAILABLE,
+ .gpio_acpi_handler = NULL,
+ .cpu = {
+ .package = CPU_PKG_386SX,
+ .block = CPU_BLOCK_NONE,
+ .min_bus = 16000000,
+ .max_bus = 25000000, /* Limited to 25 due a inaccurate cpu speed */
+ .min_voltage = 0,
+ .max_voltage = 0,
+ .min_multi = 0,
+ .max_multi = 0,
+
+ },
+ .bus_flags = MACHINE_PS2_PCI,
+ .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/
+ .ram = {
+ .min = 2048,
+ .max = 16256,
+ .step = 128
+ },
+ .nvrmask = 127,
+ .kbc_device = NULL,
+ .kbc_p1 = 0xff,
+ .gpio = 0xffffffff,
+ .gpio_acpi = 0xffffffff,
+ .device = NULL,
+ .fdc_device = NULL,
+ .sio_device = NULL,
+ .vid_device = &oti077_acer100t_device,
+ .snd_device = NULL,
+ .net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c
index f5bc449e69..f21e9d66c0 100644
--- a/src/video/vid_oak_oti.c
+++ b/src/video/vid_oak_oti.c
@@ -36,13 +36,16 @@
#define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM"
#define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM"
#define BIOS_077_PATH "roms/video/oti/oti077.vbi"
+#define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN"
+
enum {
OTI_037C = 0,
OTI_067 = 2,
OTI_067_AMA932J = 3,
OTI_067_M300 = 4,
- OTI_077 = 5
+ OTI_077 = 5,
+ OTI_077_ACER100T = 6
};
typedef struct {
@@ -92,7 +95,7 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
case 0x3c7:
case 0x3c8:
case 0x3c9:
- if (oti->chip_id == OTI_077)
+ if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T)
sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga);
else
svga_out(addr, val, svga);
@@ -153,7 +156,7 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
mem_mapping_disable(&svga->mapping);
else
mem_mapping_enable(&svga->mapping);
- } else if (oti->chip_id == OTI_077) {
+ } else if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) {
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
switch ((val & 0xc0) >> 6) {
@@ -238,7 +241,7 @@ oti_in(uint16_t addr, void *priv)
case 0x3c7:
case 0x3c8:
case 0x3c9:
- if (oti->chip_id == OTI_077)
+ if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T)
return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga);
return svga_in(addr, svga);
@@ -464,6 +467,12 @@ oti_init(const device_t *info)
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
+ case OTI_077_ACER100T:
+ romfn = BIOS_077_ACER100T_PATH;
+ oti->vram_size = device_get_config_int("memory");
+ oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
+ io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
+ break;
default:
break;
@@ -476,12 +485,19 @@ oti_init(const device_t *info)
oti->vram_mask = (oti->vram_size << 10) - 1;
- video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti);
+ if (oti->chip_id == OTI_077_ACER100T){
+ /* josephillips: Required to show all BIOS
+ information on Acer 100T only
+ */
+ video_inform(0x1,&timing_oti);
+ }else{
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti);
+ }
svga_init(info, &oti->svga, oti, oti->vram_size << 10,
oti_recalctimings, oti_in, oti_out, NULL, NULL);
- if (oti->chip_id == OTI_077)
+ if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T)
oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/
io_sethandler(0x03c0, 32,
@@ -489,7 +505,7 @@ oti_init(const device_t *info)
oti->svga.miscout = 1;
oti->svga.packed_chain4 = 1;
-
+
return oti;
}
@@ -531,6 +547,12 @@ oti067_ama932j_available(void)
return (rom_present(BIOS_067_AMA932J_PATH));
}
+static int
+oti077_acer100t_available(void)
+{
+ return (rom_present(BIOS_077_ACER100T_PATH));
+}
+
static int
oti067_077_available(void)
{
@@ -597,6 +619,35 @@ static const device_config_t oti067_ama932j_config[] = {
}
};
+static const device_config_t oti077_acer100t_config[] = {
+ {
+ .name = "memory",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .default_int = 512,
+ .selection = {
+ {
+ .description = "256 kB",
+ .value = 256
+ },
+ {
+ .description = "512 kB",
+ .value = 512
+ },
+ {
+ .description = "1 MB",
+ .value = 1024
+ },
+ {
+ .description = ""
+ }
+ }
+ },
+ {
+ .type = CONFIG_END
+ }
+};
+
static const device_config_t oti077_config[] = {
{
.name = "memory",
@@ -683,6 +734,21 @@ const device_t oti067_ama932j_device = {
.config = oti067_ama932j_config
};
+const device_t oti077_acer100t_device = {
+ .name = "Oak OTI-077 (Acer 100T)",
+ .internal_name = "oti077_acer100t",
+ .flags = DEVICE_ISA,
+ .local = 6,
+ .init = oti_init,
+ .close = oti_close,
+ .reset = NULL,
+ { .available = oti077_acer100t_available },
+ .speed_changed = oti_speed_changed,
+ .force_redraw = oti_force_redraw,
+ .config = oti077_acer100t_config
+};
+
+
const device_t oti077_device = {
.name = "Oak OTI-077",
.internal_name = "oti077",
From ca74d3a5bdf46d4cbb4a50998498dc41f66e0673 Mon Sep 17 00:00:00 2001
From: Jose Phillips
Date: Sat, 1 Jun 2024 21:24:02 -0500
Subject: [PATCH 025/567] Fixing bus type
---
src/machine/machine_table.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index f97fab9010..9723d53cd5 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -4190,7 +4190,7 @@ const machine_t machines[] = {
.max_multi = 0,
},
- .bus_flags = MACHINE_PS2_PCI,
+ .bus_flags = MACHINE_PS2,
.flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/
.ram = {
.min = 2048,
From b5312b949944b5842640cf0191c6254aa6f98749 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Sat, 1 Jun 2024 04:20:07 -0400
Subject: [PATCH 026/567] Add BocaRAM/XT
---
src/device/isamem.c | 76 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 72 insertions(+), 4 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index df5161bb61..571e5bc8df 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -98,9 +98,10 @@
#define ISAMEM_EV159_CARD 10
#define ISAMEM_RAMPAGEXT_CARD 11
#define ISAMEM_ABOVEBOARD_CARD 12
-#define ISAMEM_BRAT_CARD 13
-#define ISAMEM_EV165A_CARD 14
-#define ISAMEM_LOTECH_CARD 15
+#define ISAMEM_BRXT_CARD 13
+#define ISAMEM_BRAT_CARD 14
+#define ISAMEM_EV165A_CARD 15
+#define ISAMEM_LOTECH_CARD 16
#define ISAMEM_DEBUG 0
@@ -533,7 +534,8 @@ isamem_init(const device_t *info)
case ISAMEM_BRAT_CARD: /* BocaRAM/AT */
dev->base_addr = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
- dev->start_addr = device_get_config_int("start");
+ if (!!device_get_config_int("start"))
+ dev->start_addr = device_get_config_int("start");
dev->frame_addr = device_get_config_hex20("frame");
if (!!device_get_config_int("width"))
dev->flags |= FLAG_WIDE;
@@ -541,6 +543,7 @@ isamem_init(const device_t *info)
dev->flags |= FLAG_FAST;
break;
+ case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
case ISAMEM_LOTECH_CARD:
dev->base_addr = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
@@ -1421,6 +1424,70 @@ static const device_t ev165a_device = {
.config = ev165a_config
};
+static const device_config_t brxt_config[] = {
+ // clang-format off
+ {
+ .name = "base",
+ .description = "Address",
+ .type = CONFIG_HEX16,
+ .default_string = "",
+ .default_int = 0x0268,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ { .description = "208H", .value = 0x0208 },
+ { .description = "218H", .value = 0x0218 },
+ { .description = "258H", .value = 0x0258 },
+ { .description = "268H", .value = 0x0268 },
+ { .description = "" }
+ },
+ },
+ {
+ .name = "frame",
+ .description = "Frame Address",
+ .type = CONFIG_HEX20,
+ .default_string = "",
+ .default_int = 0xD0000,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ { .description = "D000H", .value = 0xD0000 },
+ { .description = "E000H", .value = 0xE0000 },
+ { .description = "" }
+ },
+ },
+ {
+ .name = "size",
+ .description = "Memory Size",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 512,
+ .file_filter = "",
+ .spinner = {
+ .min = 0,
+ .max = 2048,
+ .step = 512
+ },
+ .selection = { { 0 } }
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+ // clang-format on
+};
+
+static const device_t brxt_device = {
+ .name = "BocaRAM/XT",
+ .internal_name = "brxt",
+ .flags = DEVICE_ISA,
+ .local = ISAMEM_BRXT_CARD,
+ .init = isamem_init,
+ .close = isamem_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = brxt_config
+};
+
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
static const device_config_t brat_config[] = {
// clang-format off
@@ -1809,6 +1876,7 @@ static const struct {
{ &ems5150_device },
{ &ev159_device },
{ &ev165a_device },
+ { &brxt_device },
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
{ &brat_device },
#endif
From c39abcc09cd1fd840c1a23280f826015488aae5a Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Sat, 1 Jun 2024 14:17:55 -0400
Subject: [PATCH 027/567] A few fixes to to the BocaRAM/AT
---
src/device/isamem.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 571e5bc8df..a825d6a2ad 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -411,7 +411,7 @@ ems_write(uint16_t port, uint8_t val, void *priv)
if (val)
dev->flags |= FLAG_CONFIG;
break;
-
+
default:
break;
}
@@ -537,6 +537,7 @@ isamem_init(const device_t *info)
if (!!device_get_config_int("start"))
dev->start_addr = device_get_config_int("start");
dev->frame_addr = device_get_config_hex20("frame");
+ dev->flags |= (FLAG_EMS);
if (!!device_get_config_int("width"))
dev->flags |= FLAG_WIDE;
if (!!device_get_config_int("speed"))
@@ -1496,7 +1497,7 @@ static const device_config_t brat_config[] = {
.description = "Address",
.type = CONFIG_HEX16,
.default_string = "",
- .default_int = 0x0258,
+ .default_int = 0x0268,
.file_filter = "",
.spinner = { 0 },
.selection = {
@@ -1512,11 +1513,10 @@ static const device_config_t brat_config[] = {
.description = "Frame Address",
.type = CONFIG_HEX20,
.default_string = "",
- .default_int = 0,
+ .default_int = 0xD0000,
.file_filter = "",
.spinner = { 0 },
.selection = {
- { .description = "Disabled", .value = 0x00000 },
{ .description = "D000H", .value = 0xD0000 },
{ .description = "E000H", .value = 0xE0000 },
{ .description = "" }
@@ -1555,15 +1555,28 @@ static const device_config_t brat_config[] = {
.description = "Memory Size",
.type = CONFIG_SPINNER,
.default_string = "",
- .default_int = 128,
+ .default_int = 512,
.file_filter = "",
.spinner = {
.min = 0,
- .max = 8192,
+ .max = 4096,
.step = 512
},
.selection = { { 0 } }
},
+ {
+ .name = "start",
+ .description = "Start Address",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 0,
+ .file_filter = "",
+ .spinner = {
+ .min = 0,
+ .max = 14336,
+ .step = 512
+ },
+ },
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
From d0e01cfa5e4aee22b2f054df2bf07d506e736324 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Sat, 1 Jun 2024 23:57:22 -0400
Subject: [PATCH 028/567] Corrections to AST Rampage
---
src/device/isamem.c | 38 ++++++--------------------------------
1 file changed, 6 insertions(+), 32 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index a825d6a2ad..55caf23ce5 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -1662,6 +1662,8 @@ static const device_t lotech_device = {
};
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE)
+// TODO: Dual Paging support
+// TODO: Conventional memory suppport
static const device_config_t rampage_config[] = {
// clang-format off
{
@@ -1699,45 +1701,17 @@ static const device_config_t rampage_config[] = {
{ .description = "" }
},
},
- {
- .name = "width",
- .description = "I/O Width",
- .type = CONFIG_SELECTION,
- .default_string = "",
- .default_int = 8,
- .file_filter = "",
- .spinner = { 0 },
- .selection = {
- { .description = "8-bit", .value = 8 },
- { .description = "16-bit", .value = 16 },
- { .description = "" }
- },
- },
- {
- .name = "speed",
- .description = "Transfer Speed",
- .type = CONFIG_SELECTION,
- .default_string = "",
- .default_int = 0,
- .file_filter = "",
- .spinner = { 0 },
- .selection = {
- { .description = "Standard", .value = 0 },
- { .description = "High-Speed", .value = 1 },
- { .description = "" }
- }
- },
{
.name = "size",
.description = "Memory Size",
.type = CONFIG_SPINNER,
.default_string = "",
- .default_int = 128,
+ .default_int = 256, /* Technically 128k, but banks 2-7 must be 256, headaches elsewise */
.file_filter = "",
.spinner = {
- .min = 0,
- .max = 8192,
- .step = 128
+ .min = 256,
+ .max = 2048,
+ .step = 256
},
.selection = { { 0 } }
},
From d6baa289922b09fcfd72df409edb5bdcbef81c0c Mon Sep 17 00:00:00 2001
From: OBattler
Date: Mon, 3 Jun 2024 03:37:47 +0200
Subject: [PATCH 029/567] ISA memory cards: Implement EMS frame address
recalculation.
---
src/device/isamem.c | 48 +++++++++++++++++++++++----------------------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 55caf23ce5..0eac6d0971 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -363,27 +363,24 @@ ems_write(uint16_t port, uint8_t val, void *priv)
dev->ems[vpage].enabled = (val & 0x80);
dev->ems[vpage].page = (val & 0x7f);
- /* Make sure we can do that.. */
- if (dev->flags & FLAG_CONFIG) {
- if (dev->ems[vpage].page < dev->ems_pages) {
- /* Pre-calculate the page address in EMS RAM. */
- dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE);
- } else {
- /* That page does not exist. */
- dev->ems[vpage].enabled = 0;
- }
-
- if (dev->ems[vpage].enabled) {
- /* Update the EMS RAM address for this page. */
- mem_mapping_set_exec(&dev->ems[vpage].mapping,
- dev->ems[vpage].addr);
-
- /* Enable this page. */
- mem_mapping_enable(&dev->ems[vpage].mapping);
- } else {
- /* Disable this page. */
- mem_mapping_disable(&dev->ems[vpage].mapping);
- }
+ if (dev->ems[vpage].page < dev->ems_pages) {
+ /* Pre-calculate the page address in EMS RAM. */
+ dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE);
+ } else {
+ /* That page does not exist. */
+ dev->ems[vpage].enabled = 0;
+ }
+
+ if (dev->ems[vpage].enabled) {
+ /* Update the EMS RAM address for this page. */
+ mem_mapping_set_exec(&dev->ems[vpage].mapping,
+ dev->ems[vpage].addr);
+
+ /* Enable this page. */
+ mem_mapping_enable(&dev->ems[vpage].mapping);
+ } else {
+ /* Disable this page. */
+ mem_mapping_disable(&dev->ems[vpage].mapping);
}
break;
@@ -408,8 +405,13 @@ ems_write(uint16_t port, uint8_t val, void *priv)
*/
isamem_log("EMS: write(%02x) to register 1 !\n");
dev->ems[vpage].frame = val;
- if (val)
- dev->flags |= FLAG_CONFIG;
+ dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) ||
+ ((dev->ems[1].frame & 0x80) >> 6) ||
+ ((dev->ems[0].frame & 0x80) >> 7)) << 14);
+ mem_mapping_disable(&dev->ems[0].mapping);
+ mem_mapping_disable(&dev->ems[1].mapping);
+ mem_mapping_disable(&dev->ems[2].mapping);
+ mem_mapping_disable(&dev->ems[3].mapping);
break;
default:
From 27248397d25dae91d37dc9b9773ac7839fb72b91 Mon Sep 17 00:00:00 2001
From: OBattler
Date: Mon, 3 Jun 2024 04:01:00 +0200
Subject: [PATCH 030/567] ATi Mach 8: Fix a warning.
---
src/video/vid_ati_mach8.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c
index 83edb4355b..6abdc213ac 100644
--- a/src/video/vid_ati_mach8.c
+++ b/src/video/vid_ati_mach8.c
@@ -3451,8 +3451,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
static void
mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev)
{
- uint8_t old = 0;
-
if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9)
mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val);
From 9d7cffb7a84a3bb847aa6b2fa696e60acd8fb7fe Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Mon, 3 Jun 2024 00:07:32 -0400
Subject: [PATCH 031/567] Improve EMS logging
---
src/device/isamem.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 0eac6d0971..2c76939e2b 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -315,9 +315,7 @@ ems_read(uint16_t port, void *priv)
break;
}
-#if ISAMEM_DEBUG
- isamem_log("ISAMEM: read(%04x) = %02x)\n", port, ret);
-#endif
+ isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage);
return ret;
}
@@ -333,12 +331,13 @@ consecutive_ems_read(uint16_t port, void *priv)
/* Get the viewport page number. */
vpage = (port - dev->base_addr);
- isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage);
-
+
ret = dev->ems[vpage].page;
if (dev->ems[vpage].enabled)
ret |= 0x80;
+ isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage);
+
return ret;
}
@@ -353,12 +352,10 @@ ems_write(uint16_t port, uint8_t val, void *priv)
vpage = (port / EMS_PGSIZE);
port &= (EMS_PGSIZE - 1);
-#if ISAMEM_DEBUG
- isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage);
-#endif
-
switch (port - dev->base_addr) {
case 0x0000: /* page mapping registers */
+ isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! page=%d\n", port, val, vpage);
+
/* Set the page number. */
dev->ems[vpage].enabled = (val & 0x80);
dev->ems[vpage].page = (val & 0x7f);
@@ -385,6 +382,8 @@ ems_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x0001: /* page frame registers */
+ isamem_log("ISAMEM: write(%04x, %02x) to page frame registers! page=%d\n", port, val, vpage);
+
/*
* The EV-159 EMM driver configures the frame address
* by setting bits in these registers. The information
@@ -403,7 +402,6 @@ ems_write(uint16_t port, uint8_t val, void *priv)
* 80 c0 e0 DC000
* 80 c0 e0 E0000
*/
- isamem_log("EMS: write(%02x) to register 1 !\n");
dev->ems[vpage].frame = val;
dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) ||
((dev->ems[1].frame & 0x80) >> 6) ||
@@ -429,9 +427,8 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv)
/* Get the viewport page number. */
vpage = (port - dev->base_addr);
- isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage);
+ isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! (page=%d)\n", port, val, vpage);
- isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val);
/* Set the page number. */
dev->ems[vpage].enabled = 1;
dev->ems[vpage].page = val;
From 99957425f022ddbdbf1ba7d26ff2a9cb32d3061d Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Mon, 3 Jun 2024 00:39:05 -0400
Subject: [PATCH 032/567] Yet more improvements to Rampage/XT
---
src/device/isamem.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 2c76939e2b..ba60ddd2aa 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -529,6 +529,14 @@ isamem_init(const device_t *info)
break;
case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */
+ dev->base_addr = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = device_get_config_int("start");
+ tot = dev->total_size;
+ dev->flags |= FLAG_EMS;
+ dev->frame_addr = 0xE0000;
+ break;
+
case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */
case ISAMEM_BRAT_CARD: /* BocaRAM/AT */
dev->base_addr = device_get_config_hex16("base");
@@ -1670,7 +1678,7 @@ static const device_config_t rampage_config[] = {
.description = "Address",
.type = CONFIG_HEX16,
.default_string = "",
- .default_int = 0x0258,
+ .default_int = 0x0218,
.file_filter = "",
.spinner = { 0 },
.selection = {
@@ -1684,22 +1692,6 @@ static const device_config_t rampage_config[] = {
{ .description = "" }
},
},
- {
- .name = "frame",
- .description = "Frame Address",
- .type = CONFIG_HEX20,
- .default_string = "",
- .default_int = 0,
- .file_filter = "",
- .spinner = { 0 },
- .selection = {
- { .description = "Disabled", .value = 0x00000 },
- { .description = "C000H", .value = 0xC0000 },
- { .description = "D000H", .value = 0xD0000 },
- { .description = "E000H", .value = 0xE0000 },
- { .description = "" }
- },
- },
{
.name = "size",
.description = "Memory Size",
@@ -1714,6 +1706,19 @@ static const device_config_t rampage_config[] = {
},
.selection = { { 0 } }
},
+ {
+ .name = "start",
+ .description = "Start Address",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 640,
+ .file_filter = "",
+ .spinner = {
+ .min = 0,
+ .max = 640,
+ .step = 64
+ },
+ },
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
From a529359993e6fee41c4099817ca991a340911795 Mon Sep 17 00:00:00 2001
From: richardg867
Date: Mon, 3 Jun 2024 22:40:46 -0300
Subject: [PATCH 033/567] config: Fix incorrect saving of
cpu_override_interpreter
---
src/config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/config.c b/src/config.c
index 77ec89125d..ab23ddb4fe 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1927,7 +1927,7 @@ save_machine(void)
else
ini_section_delete_var(cat, "cpu_override");
if (cpu_override_interpreter)
- ini_section_set_int(cat, "cpu_override_interpreter", cpu_override);
+ ini_section_set_int(cat, "cpu_override_interpreter", cpu_override_interpreter);
else
ini_section_delete_var(cat, "cpu_override_interpreter");
From 0c6f54ac0e8656c9087fe3dd136984be9d0fc169 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Wed, 5 Jun 2024 22:10:26 +0200
Subject: [PATCH 034/567] Ported the "latest" YMFM changes.
To 86box.
---
src/sound/ymfm/ymfm.h | 3 +++
src/sound/ymfm/ymfm_fm.ipp | 2 +-
src/sound/ymfm/ymfm_ssg.h | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h
index 4f8ba1243c..c5986d66b7 100644
--- a/src/sound/ymfm/ymfm.h
+++ b/src/sound/ymfm/ymfm.h
@@ -485,6 +485,8 @@ class ymfm_saved_state
class ymfm_engine_callbacks
{
public:
+ virtual ~ymfm_engine_callbacks() = default;
+
// timer callback; called by the interface when a timer fires
virtual void engine_timer_expired(uint32_t tnum) = 0;
@@ -506,6 +508,7 @@ class ymfm_interface
template friend class fm_engine_base;
public:
+ virtual ~ymfm_interface() = default;
// the following functions must be implemented by any derived classes; the
// default implementations are sufficient for some minimal operation, but will
// likely need to be overridden to integrate with the outside world; they are
diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp
index 55cdd643dc..a3ee8d3332 100644
--- a/src/sound/ymfm/ymfm_fm.ipp
+++ b/src/sound/ymfm/ymfm_fm.ipp
@@ -1518,7 +1518,7 @@ void fm_engine_base::engine_timer_expired(uint32_t tnum)
for (uint32_t chnum = 0; chnum < CHANNELS; chnum++)
if (bitfield(RegisterType::CSM_TRIGGER_MASK, chnum))
{
- m_channel[chnum]->keyonoff(1, KEYON_CSM, chnum);
+ m_channel[chnum]->keyonoff(0xf, KEYON_CSM, chnum);
m_modified_channels |= 1 << chnum;
}
diff --git a/src/sound/ymfm/ymfm_ssg.h b/src/sound/ymfm/ymfm_ssg.h
index 749ad146fe..cb7ec9e7c4 100644
--- a/src/sound/ymfm/ymfm_ssg.h
+++ b/src/sound/ymfm/ymfm_ssg.h
@@ -49,6 +49,8 @@ namespace ymfm
class ssg_override
{
public:
+ virtual ~ssg_override() = default;
+
// reset our status
virtual void ssg_reset() = 0;
From fc6d93598f028eb549e064976fef47646c15de7e Mon Sep 17 00:00:00 2001
From: OBattler
Date: Thu, 6 Jun 2024 02:37:22 +0200
Subject: [PATCH 035/567] Tyan Trinity: Move the Winbond Super I/O chip onto
ports 3F0h/3F1h where it's supposed to be, fixes internal device mess in
Windows ME.
---
src/machine/m_at_socket370.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c
index 9e686ae8bc..010aee3da7 100644
--- a/src/machine/m_at_socket370.c
+++ b/src/machine/m_at_socket370.c
@@ -100,7 +100,7 @@ machine_at_s1857_init(const machine_t *model)
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_ami_pci_device);
- device_add(&w83977ef_370_device);
+ device_add(&w83977ef_device);
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
From b3e72559a78999eb07a3573a104360e507b8406b Mon Sep 17 00:00:00 2001
From: OBattler
Date: Fri, 7 Jun 2024 06:25:49 +0200
Subject: [PATCH 036/567] ISA Memory cards: Partial rewrite of EMS to support
up to two ranges on each EV-159, and make the page frame address changing
actually work.
---
src/device/isamem.c | 347 +++++++++++++++++++++++++++-----------------
1 file changed, 211 insertions(+), 136 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index ba60ddd2aa..63f8955f14 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -124,6 +124,11 @@ typedef struct emsreg_t {
char pad;
uint8_t *addr; /* start addr in EMS RAM */
mem_mapping_t mapping; /* mapping entry for page */
+ uint8_t *ram;
+ uint8_t *frame_val;
+ uint16_t *ems_size;
+ uint16_t *ems_pages;
+ uint32_t *frame_addr;
} emsreg_t;
typedef struct ext_ram_t {
@@ -136,20 +141,23 @@ typedef struct memdev_t {
uint8_t board : 6; /* board type */
uint8_t reserved : 2;
- uint8_t flags;
+ uint8_t flags;
#define FLAG_CONFIG 0x01 /* card is configured */
#define FLAG_WIDE 0x10 /* card uses 16b mode */
#define FLAG_FAST 0x20 /* fast (<= 120ns) chips */
#define FLAG_EMS 0x40 /* card has EMS mode enabled */
- uint16_t total_size; /* configured size in KB */
- uint32_t base_addr; /* configured I/O address */
- uint32_t start_addr; /* configured memory start */
- uint32_t frame_addr; /* configured frame address */
+ uint8_t frame_val[2];
- uint16_t ems_size; /* EMS size in KB */
- uint16_t ems_pages; /* EMS size in pages */
- uint32_t ems_start; /* start of EMS in RAM */
+ uint16_t total_size; /* configured size in KB */
+ uint16_t base_addr[2]; /* configured I/O address */
+
+ uint32_t start_addr; /* configured memory start */
+ uint32_t frame_addr[2]; /* configured frame address */
+
+ uint16_t ems_size[2]; /* EMS size in KB */
+ uint16_t ems_pages[2]; /* EMS size in pages */
+ uint32_t ems_start[2]; /* start of EMS in RAM */
uint8_t *ram; /* allocated RAM buffer */
@@ -158,7 +166,7 @@ typedef struct memdev_t {
mem_mapping_t low_mapping; /* mapping for low mem */
mem_mapping_t high_mapping; /* mapping for high mem */
- emsreg_t ems[EMS_MAXPAGE]; /* EMS controller registers */
+ emsreg_t ems[EMS_MAXPAGE * 2]; /* EMS controller registers */
} memdev_t;
#ifdef ENABLE_ISAMEM_LOG
@@ -231,14 +239,14 @@ ram_writew(uint32_t addr, uint16_t val, void *priv)
static uint8_t
ems_readb(uint32_t addr, void *priv)
{
- memdev_t *dev = (memdev_t *) priv;
+ emsreg_t *dev = (emsreg_t *) priv;
uint8_t ret = 0xff;
/* Grab the data. */
- ret = *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
+ ret = *(uint8_t *) (dev->addr + (addr & 0x3fff));
#if ISAMEM_DEBUG
if ((addr % 4096) == 0)
- isamem_log("EMS readb(%06x) = %02x\n", addr - dev & 0x3fff, ret);
+ isamem_log("EMS readb(%06x) = %02x\n", addr & 0x3fff, ret);
#endif
return ret;
@@ -248,14 +256,14 @@ ems_readb(uint32_t addr, void *priv)
static uint16_t
ems_readw(uint32_t addr, void *priv)
{
- memdev_t *dev = (memdev_t *) priv;
+ emsreg_t *dev = (emsreg_t *) priv;
uint16_t ret = 0xffff;
/* Grab the data. */
- ret = *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
+ ret = *(uint16_t *) (dev->addr + (addr & 0x3fff));
#if ISAMEM_DEBUG
if ((addr % 4096) == 0)
- isamem_log("EMS readw(%06x) = %04x\n", addr - dev & 0x3fff, ret);
+ isamem_log("EMS readw(%06x) = %04x\n", addr & 0x3fff, ret);
#endif
return ret;
@@ -265,46 +273,50 @@ ems_readw(uint32_t addr, void *priv)
static void
ems_writeb(uint32_t addr, uint8_t val, void *priv)
{
- memdev_t *dev = (memdev_t *) priv;
+ emsreg_t *dev = (emsreg_t *) priv;
/* Write the data. */
#if ISAMEM_DEBUG
if ((addr % 4096) == 0)
- isamem_log("EMS writeb(%06x, %02x)\n", addr - dev & 0x3fff, val);
+ isamem_log("EMS writeb(%06x, %02x)\n", addr & 0x3fff, val);
#endif
- *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
+ *(uint8_t *) (dev->addr + (addr & 0x3fff)) = val;
}
/* Write one word to onboard paged RAM. */
static void
ems_writew(uint32_t addr, uint16_t val, void *priv)
{
- memdev_t *dev = (memdev_t *) priv;
+ emsreg_t *dev = (emsreg_t *) priv;
/* Write the data. */
#if ISAMEM_DEBUG
if ((addr % 4096) == 0)
isamem_log("EMS writew(%06x, %04x)\n", addr & 0x3fff, val);
#endif
- *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
+ *(uint16_t *) (dev->addr + (addr & 0x3fff)) = val;
}
/* Handle a READ operation from one of our registers. */
static uint8_t
-ems_read(uint16_t port, void *priv)
+ems_in(uint16_t port, void *priv)
{
- const memdev_t *dev = (memdev_t *) priv;
- uint8_t ret = 0xff;
+ const emsreg_t *dev = (emsreg_t *) priv;
+ uint8_t ret = 0xff;
+#ifdef ENABLE_ISAMEM_LOG
int vpage;
+#endif
/* Get the viewport page number. */
+#ifdef ENABLE_ISAMEM_LOG
vpage = (port / EMS_PGSIZE);
+#endif
port &= (EMS_PGSIZE - 1);
- switch (port - dev->base_addr) {
+ switch (port & 0x0001) {
case 0x0000: /* page number register */
- ret = dev->ems[vpage].page;
- if (dev->ems[vpage].enabled)
+ ret = dev->page;
+ if (dev->enabled)
ret |= 0x80;
break;
@@ -322,15 +334,14 @@ ems_read(uint16_t port, void *priv)
/* Handle a READ operation from one of our registers. */
static uint8_t
-consecutive_ems_read(uint16_t port, void *priv)
+consecutive_ems_in(uint16_t port, void *priv)
{
const memdev_t *dev = (memdev_t *) priv;
uint8_t ret = 0xff;
int vpage;
/* Get the viewport page number. */
- vpage = (port - dev->base_addr);
-
+ vpage = (port - dev->base_addr[0]);
ret = dev->ems[vpage].page;
if (dev->ems[vpage].enabled)
@@ -343,73 +354,71 @@ consecutive_ems_read(uint16_t port, void *priv)
/* Handle a WRITE operation to one of our registers. */
static void
-ems_write(uint16_t port, uint8_t val, void *priv)
+ems_out(uint16_t port, uint8_t val, void *priv)
{
- memdev_t *dev = (memdev_t *) priv;
+ emsreg_t *dev = (emsreg_t *) priv;
int vpage;
/* Get the viewport page number. */
vpage = (port / EMS_PGSIZE);
port &= (EMS_PGSIZE - 1);
- switch (port - dev->base_addr) {
+ switch (port & 0x0001) {
case 0x0000: /* page mapping registers */
- isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! page=%d\n", port, val, vpage);
-
/* Set the page number. */
- dev->ems[vpage].enabled = (val & 0x80);
- dev->ems[vpage].page = (val & 0x7f);
+ dev->enabled = (val & 0x80);
+ dev->page = (val & 0x7f);
- if (dev->ems[vpage].page < dev->ems_pages) {
+ if (dev->enabled && (dev->page < *dev->ems_pages)) {
/* Pre-calculate the page address in EMS RAM. */
- dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE);
- } else {
- /* That page does not exist. */
- dev->ems[vpage].enabled = 0;
- }
+ dev->addr = dev->ram + ((val & 0x7f) * EMS_PGSIZE);
+
+ isamem_log("ISAMEM: map port %04X, page %i, starting at %08X: %08X -> %08X\n", port,
+ vpage, *dev->frame_addr,
+ *dev->frame_addr + (EMS_PGSIZE * (vpage & 3)), dev->addr - dev->ram);
+ mem_mapping_set_addr(&dev->mapping, *dev->frame_addr + (EMS_PGSIZE * vpage), EMS_PGSIZE);
- if (dev->ems[vpage].enabled) {
/* Update the EMS RAM address for this page. */
- mem_mapping_set_exec(&dev->ems[vpage].mapping,
- dev->ems[vpage].addr);
+ mem_mapping_set_exec(&dev->mapping, dev->addr);
/* Enable this page. */
- mem_mapping_enable(&dev->ems[vpage].mapping);
+ mem_mapping_enable(&dev->mapping);
} else {
+ isamem_log("ISAMEM: map port %04X, page %i, starting at %08X: %08X -> N/A\n",
+ port, vpage, *dev->frame_addr, *dev->frame_addr + (EMS_PGSIZE * vpage));
+
/* Disable this page. */
- mem_mapping_disable(&dev->ems[vpage].mapping);
+ mem_mapping_disable(&dev->mapping);
}
break;
case 0x0001: /* page frame registers */
- isamem_log("ISAMEM: write(%04x, %02x) to page frame registers! page=%d\n", port, val, vpage);
-
- /*
- * The EV-159 EMM driver configures the frame address
- * by setting bits in these registers. The information
- * in their manual is unclear, but here is what was
- * found out by repeatedly changing EMM's config:
- *
- * 00 04 08 Address
- * -----------------
- * 80 c0 e0 C0000
- * 80 c0 e0 C4000
- * 80 c0 e0 C8000
- * 80 c0 e0 CC000
- * 80 c0 e0 D0000
- * 80 c0 e0 D4000
- * 80 c0 e0 D8000
- * 80 c0 e0 DC000
- * 80 c0 e0 E0000
- */
- dev->ems[vpage].frame = val;
- dev->frame_addr = 0x000c4000 + ((((dev->ems[2].frame & 0x80) >> 5) ||
- ((dev->ems[1].frame & 0x80) >> 6) ||
- ((dev->ems[0].frame & 0x80) >> 7)) << 14);
- mem_mapping_disable(&dev->ems[0].mapping);
- mem_mapping_disable(&dev->ems[1].mapping);
- mem_mapping_disable(&dev->ems[2].mapping);
- mem_mapping_disable(&dev->ems[3].mapping);
+ /*
+ * The EV-159 EMM driver configures the frame address
+ * by setting bits in these registers. The information
+ * in their manual is unclear, but here is what was
+ * found out by repeatedly changing EMM's config:
+ *
+ * 08 04 00 Address
+ * -----------------
+ * 00 00 00 C4000
+ * 00 00 80 C8000
+ * 00 80 00 CC000
+ * 00 80 80 D0000
+ * 80 00 00 D4000
+ * 80 00 80 D8000
+ * 80 80 00 DC000
+ * 80 80 80 E0000
+ */
+ dev->frame = val;
+ *dev->frame_val = (*dev->frame_val & ~(1 << vpage)) | ((val >> 7) << vpage);
+ *dev->frame_addr = 0x000c4000 + (*dev->frame_val << 14);
+ isamem_log("ISAMEM: map port %04X page %i: frame_addr = %08X\n", port, vpage, *dev->frame_addr);
+ /* Destroy the page registers. */
+ for (uint8_t i = 0; i < 4; i ++) {
+ isamem_log(" ");
+ outb((port & 0x3ffe) + (i << 14), 0x00);
+ }
break;
default:
@@ -419,13 +428,13 @@ ems_write(uint16_t port, uint8_t val, void *priv)
/* Handle a WRITE operation to one of our registers. */
static void
-consecutive_ems_write(uint16_t port, uint8_t val, void *priv)
+consecutive_ems_out(uint16_t port, uint8_t val, void *priv)
{
memdev_t *dev = (memdev_t *) priv;
int vpage;
/* Get the viewport page number. */
- vpage = (port - dev->base_addr);
+ vpage = (port - dev->base_addr[0]);
isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! (page=%d)\n", port, val, vpage);
@@ -435,9 +444,9 @@ consecutive_ems_write(uint16_t port, uint8_t val, void *priv)
/* Make sure we can do that.. */
if (dev->flags & FLAG_CONFIG) {
- if (dev->ems[vpage].page < dev->ems_pages) {
+ if (dev->ems[vpage].page < dev->ems_pages[0]) {
/* Pre-calculate the page address in EMS RAM. */
- dev->ems[vpage].addr = dev->ram + dev->ems_start + (val * EMS_PGSIZE);
+ dev->ems[vpage].addr = dev->ram + dev->ems_start[0] + (val * EMS_PGSIZE);
} else {
/* That page does not exist. */
dev->ems[vpage].enabled = 0;
@@ -474,6 +483,9 @@ isamem_init(const device_t *info)
dev->name = info->name;
dev->board = info->local;
+ dev->base_addr[1] = 0x0000;
+ dev->frame_addr[1] = 0x00000000;
+
/* Do per-board initialization. */
tot = 0;
switch (dev->board) {
@@ -497,67 +509,69 @@ isamem_init(const device_t *info)
break;
case ISAMEM_EMS5150_CARD: /* Micro Mainframe EMS-5150(T) */
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
- dev->start_addr = 0;
- dev->frame_addr = 0xD0000;
- dev->flags |= (FLAG_EMS | FLAG_CONFIG);
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = 0;
+ dev->frame_addr[0] = 0xd0000;
+ dev->flags |= (FLAG_EMS | FLAG_CONFIG);
break;
case ISAMEM_EV159_CARD: /* Everex EV-159 RAM 3000 */
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
- dev->start_addr = device_get_config_int("start");
- tot = device_get_config_int("length");
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->base_addr[1] = device_get_config_hex16("base2");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = device_get_config_int("start");
+ tot = device_get_config_int("length");
if (!!device_get_config_int("width"))
- dev->flags |= FLAG_WIDE;
+ dev->flags |= FLAG_WIDE;
if (!!device_get_config_int("speed"))
- dev->flags |= FLAG_FAST;
+ dev->flags |= FLAG_FAST;
if (!!device_get_config_int("ems"))
- dev->flags |= FLAG_EMS;
- dev->frame_addr = 0xE0000;
+ dev->flags |= FLAG_EMS;
+ dev->frame_addr[0] = 0xd0000;
+ dev->frame_addr[1] = 0xe0000;
break;
case ISAMEM_EV165A_CARD: /* Everex Maxi Magic EV-165A */
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
- dev->start_addr = device_get_config_int("start");
- tot = device_get_config_int("length");
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = device_get_config_int("start");
+ tot = device_get_config_int("length");
if (!!device_get_config_int("ems"))
- dev->flags |= FLAG_EMS;
- dev->frame_addr = 0xE0000;
+ dev->flags |= FLAG_EMS;
+ dev->frame_addr[0] = 0xe0000;
break;
case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
- dev->start_addr = device_get_config_int("start");
- tot = dev->total_size;
- dev->flags |= FLAG_EMS;
- dev->frame_addr = 0xE0000;
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = device_get_config_int("start");
+ tot = dev->total_size;
+ dev->flags |= FLAG_EMS;
+ dev->frame_addr[0] = 0xe0000;
break;
case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */
case ISAMEM_BRAT_CARD: /* BocaRAM/AT */
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
if (!!device_get_config_int("start"))
dev->start_addr = device_get_config_int("start");
- dev->frame_addr = device_get_config_hex20("frame");
- dev->flags |= (FLAG_EMS);
+ dev->frame_addr[0] = device_get_config_hex20("frame");
+ dev->flags |= (FLAG_EMS);
if (!!device_get_config_int("width"))
- dev->flags |= FLAG_WIDE;
+ dev->flags |= FLAG_WIDE;
if (!!device_get_config_int("speed"))
- dev->flags |= FLAG_FAST;
+ dev->flags |= FLAG_FAST;
break;
case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
case ISAMEM_LOTECH_CARD:
- dev->base_addr = device_get_config_hex16("base");
- dev->total_size = device_get_config_int("size");
- dev->start_addr = 0;
- dev->frame_addr = device_get_config_hex20("frame");
- dev->flags |= (FLAG_EMS | FLAG_CONFIG);
+ dev->base_addr[0] = device_get_config_hex16("base");
+ dev->total_size = device_get_config_int("size");
+ dev->start_addr = 0;
+ dev->frame_addr[0] = device_get_config_hex20("frame");
+ dev->flags |= (FLAG_EMS | FLAG_CONFIG);
default:
break;
@@ -714,25 +728,48 @@ isamem_init(const device_t *info)
t = EMS_MAXSIZE;
/* Set up where EMS begins in local RAM, and how much we have. */
- dev->ems_start = ptr - dev->ram;
- dev->ems_size = t >> 10;
- dev->ems_pages = t / EMS_PGSIZE;
- isamem_log("ISAMEM: EMS enabled, I/O=%04XH, %iKB (%i pages)",
- dev->base_addr, dev->ems_size, dev->ems_pages);
- if (dev->frame_addr > 0)
- isamem_log(", Frame=%05XH", dev->frame_addr);
+ dev->ems_start[0] = ptr - dev->ram;
+ if ((dev->board == ISAMEM_EV159_CARD) && (t > 2048)) {
+ dev->ems_size[0] = 2 << 10;
+ dev->ems_pages[0] = (2 << 20) / EMS_PGSIZE;
+ } else {
+ dev->ems_size[0] = t >> 10;
+ dev->ems_pages[0] = t / EMS_PGSIZE;
+ }
+ isamem_log("ISAMEM: EMS #1 enabled, I/O=%04XH, %iKB (%i pages)",
+ dev->base_addr[0], dev->ems_size[0], dev->ems_pages[0]);
+ if (dev->frame_addr[0] > 0)
+ isamem_log(", Frame[0]=%05XH", dev->frame_addr[0]);
isamem_log("\n");
+ if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) {
+ dev->ems_start[1] = dev->ems_start[0] + (2 << 20);
+ dev->ems_size[1] = (t - (2 << 20)) >> 10;
+ dev->ems_pages[1] = (t - (2 << 20)) / EMS_PGSIZE;
+ isamem_log("ISAMEM: EMS #2 enabled, I/O=%04XH, %iKB (%i pages)",
+ dev->base_addr[1], dev->ems_size[1], dev->ems_pages[1]);
+ if (dev->frame_addr[1] > 0)
+ isamem_log(", Frame[1]=%05XH", dev->frame_addr[1]);
+
+ isamem_log("\n");
+ }
+
/*
* For each supported page (we can have a maximum of 4),
* create, initialize and disable the mappings, and set
* up the I/O control handler.
*/
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
+ dev->ems[i].ram = dev->ram + dev->ems_start[0];
+ dev->ems[i].frame_val = &dev->frame_val[0];
+ dev->ems[i].ems_size = &dev->ems_size[0];
+ dev->ems[i].ems_pages = &dev->ems_pages[0];
+ dev->ems[i].frame_addr = &dev->frame_addr[0];
+
/* Create and initialize a page mapping. */
mem_mapping_add(&dev->ems[i].mapping,
- dev->frame_addr + (EMS_PGSIZE * i), EMS_PGSIZE,
+ dev->frame_addr[0] + (EMS_PGSIZE * i), EMS_PGSIZE,
ems_readb,
(dev->flags & FLAG_WIDE) ? ems_readw : NULL,
NULL,
@@ -740,20 +777,46 @@ isamem_init(const device_t *info)
(dev->flags & FLAG_WIDE) ? ems_writew : NULL,
NULL,
ptr, MEM_MAPPING_EXTERNAL,
- dev);
+ &(dev->ems[i]));
/* For now, disable it. */
mem_mapping_disable(&dev->ems[i].mapping);
/* Set up an I/O port handler. */
- if (dev->board != ISAMEM_LOTECH_CARD)
- io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2,
- ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
+ if (dev->board != ISAMEM_LOTECH_CARD)
+ io_sethandler(dev->base_addr[0] + (EMS_PGSIZE * i), 2,
+ ems_in, NULL, NULL, ems_out, NULL, NULL, &(dev->ems[i]));
+
+ if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) {
+ dev->ems[i | 4].ram = dev->ram + dev->ems_start[1];
+ dev->ems[i | 4].frame_val = &dev->frame_val[1];
+ dev->ems[i | 4].ems_size = &dev->ems_size[1];
+ dev->ems[i | 4].ems_pages = &dev->ems_pages[1];
+ dev->ems[i | 4].frame_addr = &dev->frame_addr[1];
+
+ /* Create and initialize a page mapping. */
+ mem_mapping_add(&dev->ems[i | 4].mapping,
+ dev->frame_addr[1] + (EMS_PGSIZE * i), EMS_PGSIZE,
+ ems_readb,
+ (dev->flags & FLAG_WIDE) ? ems_readw : NULL,
+ NULL,
+ ems_writeb,
+ (dev->flags & FLAG_WIDE) ? ems_writew : NULL,
+ NULL,
+ ptr + (2 << 20), MEM_MAPPING_EXTERNAL,
+ &(dev->ems[i | 4]));
+
+ /* For now, disable it. */
+ mem_mapping_disable(&dev->ems[i | 4].mapping);
+
+ io_sethandler(dev->base_addr[1] + (EMS_PGSIZE * i), 2,
+ ems_in, NULL, NULL, ems_out, NULL, NULL, &(dev->ems[i | 4]));
+ }
}
if (dev->board == ISAMEM_LOTECH_CARD)
- io_sethandler(dev->base_addr, 4,
- consecutive_ems_read, NULL, NULL, consecutive_ems_write, NULL, NULL, dev);
+ io_sethandler(dev->base_addr[0], 4,
+ consecutive_ems_in, NULL, NULL, consecutive_ems_out, NULL, NULL, dev);
}
/* Let them know our device instance. */
@@ -766,13 +829,6 @@ isamem_close(void *priv)
{
memdev_t *dev = (memdev_t *) priv;
- if (dev->flags & FLAG_EMS) {
- for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
- io_removehandler(dev->base_addr + (EMS_PGSIZE * i), 2,
- ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
- }
- }
-
if (dev->ram != NULL)
free(dev->ram);
@@ -1319,6 +1375,25 @@ static const device_config_t ev159_config[] = {
{ .description = "" }
},
},
+ {
+ .name = "base2",
+ .description = "Address for > 2 MB",
+ .type = CONFIG_HEX16,
+ .default_string = "",
+ .default_int = 0x0268,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ { .description = "208H", .value = 0x0208 },
+ { .description = "218H", .value = 0x0218 },
+ { .description = "258H", .value = 0x0258 },
+ { .description = "268H", .value = 0x0268 },
+ { .description = "2A8H", .value = 0x02A8 },
+ { .description = "2B8H", .value = 0x02B8 },
+ { .description = "2E8H", .value = 0x02E8 },
+ { .description = "" }
+ },
+ },
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
From 3258ed67f94985096d0301b542c546e16255b8ad Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 01:37:51 -0400
Subject: [PATCH 037/567] Improve lotech EMS
---
src/device/isamem.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 63f8955f14..99e6e51b67 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -109,7 +109,8 @@
#define RAM_UMAMEM (384 << 10) /* upper memory block */
#define RAM_EXTMEM (1024 << 10) /* start of high memory */
-#define EMS_MAXSIZE (4096 << 10) /* max EMS memory size */
+#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */
+#define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */
#define EMS_PGSIZE (16 << 10) /* one page is this big */
#define EMS_MAXPAGE 4 /* number of viewport pages */
@@ -143,6 +144,7 @@ typedef struct memdev_t {
uint8_t flags;
#define FLAG_CONFIG 0x01 /* card is configured */
+#define FLAG_LOTECH 0x02 /* Lotech EMS supports upto 4MB with a hack */
#define FLAG_WIDE 0x10 /* card uses 16b mode */
#define FLAG_FAST 0x20 /* fast (<= 120ns) chips */
#define FLAG_EMS 0x40 /* card has EMS mode enabled */
@@ -565,8 +567,9 @@ isamem_init(const device_t *info)
dev->flags |= FLAG_FAST;
break;
- case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
- case ISAMEM_LOTECH_CARD:
+ case ISAMEM_LOTECH_CARD: /* Lotech EMS */
+ dev->flags |= FLAG_LOTECH;
+ case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
dev->base_addr[0] = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
dev->start_addr = 0;
@@ -724,7 +727,10 @@ isamem_init(const device_t *info)
if (dev->flags & FLAG_EMS) {
/* EMS 3.2 cannot have more than 4096KB per board. */
t = k;
- if (t > EMS_MAXSIZE)
+ if ((dev->flags & FLAG_LOTECH) && (t > EMS_LOTECH_MAXSIZE))
+ /* Lotech EMS cannot have more than 4096KB per board. */
+ t = EMS_LOTECH_MAXSIZE;
+ else if (t > EMS_MAXSIZE)
t = EMS_MAXSIZE;
/* Set up where EMS begins in local RAM, and how much we have. */
From e290347433fb2dc0963f4f081f191e98e12b1996 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 01:38:32 -0400
Subject: [PATCH 038/567] Remove needless parens
---
src/device/isamem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 99e6e51b67..1f071388cc 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -560,7 +560,7 @@ isamem_init(const device_t *info)
if (!!device_get_config_int("start"))
dev->start_addr = device_get_config_int("start");
dev->frame_addr[0] = device_get_config_hex20("frame");
- dev->flags |= (FLAG_EMS);
+ dev->flags |= FLAG_EMS;
if (!!device_get_config_int("width"))
dev->flags |= FLAG_WIDE;
if (!!device_get_config_int("speed"))
From 0f5fd9fbd0f8b20310b25c96070cde40cccfae5d Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 02:08:28 -0400
Subject: [PATCH 039/567] Fixed EV159's max ram and remove flag kludge
---
src/device/isamem.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 1f071388cc..7f01f2c4d4 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -110,6 +110,7 @@
#define RAM_EXTMEM (1024 << 10) /* start of high memory */
#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */
+#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for lotech cards */
#define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */
#define EMS_PGSIZE (16 << 10) /* one page is this big */
#define EMS_MAXPAGE 4 /* number of viewport pages */
@@ -144,7 +145,6 @@ typedef struct memdev_t {
uint8_t flags;
#define FLAG_CONFIG 0x01 /* card is configured */
-#define FLAG_LOTECH 0x02 /* Lotech EMS supports upto 4MB with a hack */
#define FLAG_WIDE 0x10 /* card uses 16b mode */
#define FLAG_FAST 0x20 /* fast (<= 120ns) chips */
#define FLAG_EMS 0x40 /* card has EMS mode enabled */
@@ -567,9 +567,8 @@ isamem_init(const device_t *info)
dev->flags |= FLAG_FAST;
break;
- case ISAMEM_LOTECH_CARD: /* Lotech EMS */
- dev->flags |= FLAG_LOTECH;
case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
+ case ISAMEM_LOTECH_CARD: /* Lotech EMS */
dev->base_addr[0] = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
dev->start_addr = 0;
@@ -725,12 +724,14 @@ isamem_init(const device_t *info)
/* If EMS is enabled, use the remainder for EMS. */
if (dev->flags & FLAG_EMS) {
- /* EMS 3.2 cannot have more than 4096KB per board. */
t = k;
- if ((dev->flags & FLAG_LOTECH) && (t > EMS_LOTECH_MAXSIZE))
+ if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE))
/* Lotech EMS cannot have more than 4096KB per board. */
t = EMS_LOTECH_MAXSIZE;
+ else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE))
+ t = EMS_EV159_MAXSIZE;
else if (t > EMS_MAXSIZE)
+ /* EMS 3.2 cannot have more than 4096KB per board. */
t = EMS_MAXSIZE;
/* Set up where EMS begins in local RAM, and how much we have. */
From 603fdb0331252213c2f1ed2e71967fa077c1fb11 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 02:33:21 -0400
Subject: [PATCH 040/567] Fix various comments in isamem.c
---
src/device/isamem.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 7f01f2c4d4..e4a37b8a30 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -110,7 +110,7 @@
#define RAM_EXTMEM (1024 << 10) /* start of high memory */
#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */
-#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for lotech cards */
+#define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for EV-159 cards */
#define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */
#define EMS_PGSIZE (16 << 10) /* one page is this big */
#define EMS_MAXPAGE 4 /* number of viewport pages */
@@ -726,12 +726,13 @@ isamem_init(const device_t *info)
if (dev->flags & FLAG_EMS) {
t = k;
if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE))
- /* Lotech EMS cannot have more than 4096KB per board. */
+ /* The Lotech EMS cannot have more than 4096KB per board. */
t = EMS_LOTECH_MAXSIZE;
else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE))
+ /* The EV-159 cannot have more than 3072KB per board. */
t = EMS_EV159_MAXSIZE;
else if (t > EMS_MAXSIZE)
- /* EMS 3.2 cannot have more than 4096KB per board. */
+ /* EMS 3.2 cannot have more than 2048KB per board. */
t = EMS_MAXSIZE;
/* Set up where EMS begins in local RAM, and how much we have. */
From ddc36d66df12cb980917c7be4fd02c8d7f91c646 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Thu, 6 Jun 2024 23:41:56 -0400
Subject: [PATCH 041/567] Add IBM PC/AT 128KB Memory Expansion Option
---
src/device/isamem.c | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index e4a37b8a30..d611cfaf2b 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -90,11 +90,12 @@
#define ISAMEM_GENXT_CARD 1
#define ISAMEM_RAMCARD_CARD 2
#define ISAMEM_SYSTEMCARD_CARD 3
-#define ISAMEM_IBMAT_CARD 4
-#define ISAMEM_GENAT_CARD 5
-#define ISAMEM_P5PAK_CARD 6
-#define ISAMEM_A6PAK_CARD 7
-#define ISAMEM_EMS5150_CARD 8
+#define ISAMEM_IBMAT_128K_CARD 4
+#define ISAMEM_IBMAT_CARD 5
+#define ISAMEM_GENAT_CARD 6
+#define ISAMEM_P5PAK_CARD 7
+#define ISAMEM_A6PAK_CARD 8
+#define ISAMEM_EMS5150_CARD 9
#define ISAMEM_EV159_CARD 10
#define ISAMEM_RAMPAGEXT_CARD 11
#define ISAMEM_ABOVEBOARD_CARD 12
@@ -502,6 +503,13 @@ isamem_init(const device_t *info)
tot = dev->total_size;
break;
+ case ISAMEM_IBMAT_128K_CARD: /* IBM PC/AT 128K Memory Expansion Option */
+ dev->total_size = 128;
+ dev->start_addr = 512;
+ tot = dev->total_size;
+ dev->flags |= FLAG_WIDE;
+ break;
+
case ISAMEM_IBMAT_CARD: /* IBM PC/AT Memory Expansion Card */
case ISAMEM_GENAT_CARD: /* Generic PC/AT Memory Expansion Card */
dev->total_size = device_get_config_int("size");
@@ -1035,6 +1043,20 @@ static const device_t mssystemcard_device = {
.config = mssystemcard_config
};
+static const device_t ibmat_128k_device = {
+ .name = "IBM PC/AT 128KB Memory Expansion Option",
+ .internal_name = "ibmat_128k",
+ .flags = DEVICE_ISA,
+ .local = ISAMEM_IBMAT_128K_CARD,
+ .init = isamem_init,
+ .close = isamem_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
static const device_config_t ibmat_config[] = {
// clang-format off
{
@@ -1939,12 +1961,16 @@ static const struct {
} boards[] = {
// clang-format off
{ &isa_none_device },
+ // XT Ram Expansion Cards
{ &ibmxt_device },
{ &genericxt_device },
{ &msramcard_device },
{ &mssystemcard_device },
+ // AT RAM Expansion Cards
+ { &ibmat_128k_device },
{ &ibmat_device },
{ &genericat_device },
+ // EMS Cards
{ &p5pak_device },
{ &a6pak_device },
{ &ems5150_device },
From 0e386ffad733adec6b502008640be9692b905ff0 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Thu, 6 Jun 2024 23:47:04 -0400
Subject: [PATCH 042/567] Add IBM PC/XT 32K Memory Expansion Option
---
src/device/isamem.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index d611cfaf2b..74f9844164 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -851,6 +851,54 @@ isamem_close(void *priv)
free(dev);
}
+static const device_config_t ibmxt_32k_config[] = {
+ // clang-format off
+ {
+ .name = "size",
+ .description = "Memory Size",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 32,
+ .file_filter = "",
+ .spinner = {
+ .min = 32,
+ .max = 576,
+ .step = 32
+ },
+ .selection = { { 0 } }
+ },
+ {
+ .name = "start",
+ .description = "Start Address",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 64,
+ .file_filter = "",
+ .spinner = {
+ .min = 0,
+ .max = 608,
+ .step = 32
+ },
+ .selection = { { 0 } }
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+ // clang-format on
+};
+
+static const device_t ibmxt_32k_device = {
+ .name = "IBM PC/XT 32K Memory Expansion Option",
+ .internal_name = "ibmxt_32k",
+ .flags = DEVICE_ISA,
+ .local = ISAMEM_IBMXT_CARD,
+ .init = isamem_init,
+ .close = isamem_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = ibmxt_32k_config
+};
+
static const device_config_t ibmxt_config[] = {
// clang-format off
{
@@ -1962,6 +2010,7 @@ static const struct {
// clang-format off
{ &isa_none_device },
// XT Ram Expansion Cards
+ { &ibmxt_32k_device },
{ &ibmxt_device },
{ &genericxt_device },
{ &msramcard_device },
From a206a2ee544e5aaaa290d65c0305a05ba75e01e3 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Thu, 6 Jun 2024 23:52:21 -0400
Subject: [PATCH 043/567] Add IBM PC/XT 64K Memory Expansion Option
---
src/device/isamem.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 74f9844164..04f04eef7a 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -899,6 +899,54 @@ static const device_t ibmxt_32k_device = {
.config = ibmxt_32k_config
};
+static const device_config_t ibmxt_64k_config[] = {
+ // clang-format off
+ {
+ .name = "size",
+ .description = "Memory Size",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 64,
+ .file_filter = "",
+ .spinner = {
+ .min = 64,
+ .max = 576,
+ .step = 64
+ },
+ .selection = { { 0 } }
+ },
+ {
+ .name = "start",
+ .description = "Start Address",
+ .type = CONFIG_SPINNER,
+ .default_string = "",
+ .default_int = 64,
+ .file_filter = "",
+ .spinner = {
+ .min = 0,
+ .max = 576,
+ .step = 64
+ },
+ .selection = { { 0 } }
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+ // clang-format on
+};
+
+static const device_t ibmxt_64k_device = {
+ .name = "IBM PC/XT 64K Memory Expansion Option",
+ .internal_name = "ibmxt_64k",
+ .flags = DEVICE_ISA,
+ .local = ISAMEM_IBMXT_CARD,
+ .init = isamem_init,
+ .close = isamem_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = ibmxt_64k_config
+};
+
static const device_config_t ibmxt_config[] = {
// clang-format off
{
@@ -2011,6 +2059,7 @@ static const struct {
{ &isa_none_device },
// XT Ram Expansion Cards
{ &ibmxt_32k_device },
+ { &ibmxt_64k_device },
{ &ibmxt_device },
{ &genericxt_device },
{ &msramcard_device },
From 006207151f6cf4df9e1095982a5910c07cfe8024 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Thu, 6 Jun 2024 23:59:28 -0400
Subject: [PATCH 044/567] 64/256KB Memory Expansion Option
---
src/device/isamem.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index 04f04eef7a..dbbd779a48 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -957,9 +957,9 @@ static const device_config_t ibmxt_config[] = {
.default_int = 128,
.file_filter = "",
.spinner = {
- .min = 0,
- .max = 512,
- .step = 16
+ .min = 64,
+ .max = 576,
+ .step = 64
},
.selection = { { 0 } }
},
@@ -982,7 +982,7 @@ static const device_config_t ibmxt_config[] = {
};
static const device_t ibmxt_device = {
- .name = "IBM PC/XT Memory Expansion",
+ .name = "IBM PC/XT 64/256K Memory Expansion Option",
.internal_name = "ibmxt",
.flags = DEVICE_ISA,
.local = ISAMEM_IBMXT_CARD,
From 1ea76d2e378bcd3c03a869a27a26805907d5ad86 Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 02:39:45 -0400
Subject: [PATCH 045/567] Correct onboard memory on the 5170
---
src/machine/machine_table.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 9723d53cd5..e841a85385 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -2545,8 +2545,8 @@ const machine_t machines[] = {
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 256,
- .max = 15872,
- .step = 128
+ .max = 512,
+ .step = 256
},
.nvrmask = 63,
.kbc_device = NULL,
From 86de260b245de535fe839182a2e4d23d75da265e Mon Sep 17 00:00:00 2001
From: OBattler
Date: Fri, 7 Jun 2024 14:19:10 +0200
Subject: [PATCH 046/567] mem.c: Double the pages array size for 386SX, fixes
the segmentation fault when trying to use the Amstrad MegaPC with more than
16 MB and the 486+ interpreter.
---
src/mem/mem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mem/mem.c b/src/mem/mem.c
index be097b5f3d..5fe7f3c29b 100644
--- a/src/mem/mem.c
+++ b/src/mem/mem.c
@@ -2833,8 +2833,8 @@ mem_reset(void)
*/
if (is286) {
if (cpu_16bitbus) {
- /* 80286/386SX; maximum address space is 16MB. */
- m = 4096;
+ /* 80286/386SX; maximum address space is 16MB + 16 MB for EMS. */
+ m = 8192;
/* ALi M6117; maximum address space is 64MB. */
if (is6117)
m <<= 2;
From dc7b93dc04669d984be2f7ea51e78fa021fbc494 Mon Sep 17 00:00:00 2001
From: OBattler
Date: Fri, 7 Jun 2024 18:21:55 +0200
Subject: [PATCH 047/567] device/isamem.c: Fix the two bugs reported by
lemondrops.
---
src/device/isamem.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index dbbd779a48..cd59aa02d1 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -478,6 +478,8 @@ isamem_init(const device_t *info)
uint32_t t;
uint32_t addr;
uint32_t tot;
+ /* EMS 3.2 cannot have more than 2048KB per board. */
+ uint32_t ems_max = EMS_MAXSIZE;
uint8_t *ptr;
/* Find our device and create an instance. */
@@ -527,6 +529,8 @@ isamem_init(const device_t *info)
break;
case ISAMEM_EV159_CARD: /* Everex EV-159 RAM 3000 */
+ /* The EV-159 cannot have more than 3072KB per board. */
+ ems_max = EMS_EV159_MAXSIZE;
dev->base_addr[0] = device_get_config_hex16("base");
dev->base_addr[1] = device_get_config_hex16("base2");
dev->total_size = device_get_config_int("size");
@@ -575,13 +579,16 @@ isamem_init(const device_t *info)
dev->flags |= FLAG_FAST;
break;
- case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
case ISAMEM_LOTECH_CARD: /* Lotech EMS */
+ /* The Lotech EMS cannot have more than 4096KB per board. */
+ ems_max = EMS_LOTECH_MAXSIZE;
+ case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
dev->base_addr[0] = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
dev->start_addr = 0;
dev->frame_addr[0] = device_get_config_hex20("frame");
dev->flags |= (FLAG_EMS | FLAG_CONFIG);
+ break;
default:
break;
@@ -733,19 +740,13 @@ isamem_init(const device_t *info)
/* If EMS is enabled, use the remainder for EMS. */
if (dev->flags & FLAG_EMS) {
t = k;
- if ((dev->board == ISAMEM_LOTECH_CARD) && (t > EMS_LOTECH_MAXSIZE))
- /* The Lotech EMS cannot have more than 4096KB per board. */
- t = EMS_LOTECH_MAXSIZE;
- else if ((dev->board == ISAMEM_EV159_CARD) && (t > EMS_EV159_MAXSIZE))
- /* The EV-159 cannot have more than 3072KB per board. */
- t = EMS_EV159_MAXSIZE;
- else if (t > EMS_MAXSIZE)
- /* EMS 3.2 cannot have more than 2048KB per board. */
- t = EMS_MAXSIZE;
+
+ if (t > ems_max)
+ t = ems_max;
/* Set up where EMS begins in local RAM, and how much we have. */
dev->ems_start[0] = ptr - dev->ram;
- if ((dev->board == ISAMEM_EV159_CARD) && (t > 2048)) {
+ if ((dev->board == ISAMEM_EV159_CARD) && (t > (2 << 20))) {
dev->ems_size[0] = 2 << 10;
dev->ems_pages[0] = (2 << 20) / EMS_PGSIZE;
} else {
From ec0287cd2f3739fd3d6d947f95e93c47d2bdcb99 Mon Sep 17 00:00:00 2001
From: OBattler
Date: Fri, 7 Jun 2024 18:23:16 +0200
Subject: [PATCH 048/567] Added the missing fallthrough marker.
---
src/device/isamem.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index cd59aa02d1..a53f5e66cc 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -582,6 +582,7 @@ isamem_init(const device_t *info)
case ISAMEM_LOTECH_CARD: /* Lotech EMS */
/* The Lotech EMS cannot have more than 4096KB per board. */
ems_max = EMS_LOTECH_MAXSIZE;
+ fallthrough;
case ISAMEM_BRXT_CARD: /* BocaRAM/XT */
dev->base_addr[0] = device_get_config_hex16("base");
dev->total_size = device_get_config_int("size");
From f95b1d984d72e056b3076f5aac8f0588f77de6dc Mon Sep 17 00:00:00 2001
From: OBattler
Date: Sat, 8 Jun 2024 04:35:29 +0200
Subject: [PATCH 049/567] ISA memory and RTC cards: Only enable the configure
button if the device actually has a configuration structure present.
---
src/device/isamem.c | 9 +++++++++
src/device/isartc.c | 9 +++++++++
src/include/86box/isamem.h | 1 +
src/include/86box/isartc.h | 1 +
src/qt/qt_settingsotherperipherals.cpp | 13 +++++++------
5 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/src/device/isamem.c b/src/device/isamem.c
index a53f5e66cc..fcbbbfb15e 100644
--- a/src/device/isamem.c
+++ b/src/device/isamem.c
@@ -2145,3 +2145,12 @@ isamem_get_device(int board)
/* Add the instance to the system. */
return boards[board].dev;
}
+
+int
+isamem_has_config(int board)
+{
+ if (boards[board].dev == NULL)
+ return 0;
+
+ return (boards[board].dev->config ? 1 : 0);
+}
diff --git a/src/device/isartc.c b/src/device/isartc.c
index 46f31c1373..fea108426d 100644
--- a/src/device/isartc.c
+++ b/src/device/isartc.c
@@ -815,3 +815,12 @@ isartc_get_device(int board)
{
return (boards[board].dev);
}
+
+int
+isartc_has_config(int board)
+{
+ if (boards[board].dev == NULL)
+ return 0;
+
+ return (boards[board].dev->config ? 1 : 0);
+}
diff --git a/src/include/86box/isamem.h b/src/include/86box/isamem.h
index 9a1841c53c..51fe50e330 100644
--- a/src/include/86box/isamem.h
+++ b/src/include/86box/isamem.h
@@ -64,6 +64,7 @@ extern const char *isamem_get_name(int t);
extern const char *isamem_get_internal_name(int t);
extern int isamem_get_from_internal_name(const char *s);
extern const device_t *isamem_get_device(int t);
+extern int isamem_has_config(int board);
#ifdef __cplusplus
}
diff --git a/src/include/86box/isartc.h b/src/include/86box/isartc.h
index 92c58e3506..0224180b36 100644
--- a/src/include/86box/isartc.h
+++ b/src/include/86box/isartc.h
@@ -58,6 +58,7 @@ extern void isartc_reset(void);
extern const char *isartc_get_internal_name(int t);
extern int isartc_get_from_internal_name(char *s);
extern const device_t *isartc_get_device(int t);
+extern int isartc_has_config(int board);
#ifdef __cplusplus
}
diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp
index 3904b653ab..a7db551ad8 100644
--- a/src/qt/qt_settingsotherperipherals.cpp
+++ b/src/qt/qt_settingsotherperipherals.cpp
@@ -81,6 +81,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId)
++d;
}
ui->comboBoxRTC->setCurrentIndex(selectedRow);
+ ui->pushButtonConfigureRTC->setEnabled((isartc_type != 0) && isartc_has_config(isartc_type) && machineHasIsa);
for (int c = 0; c < ISAMEM_MAX; c++) {
auto *cbox = findChild(QString("comboBoxCard%1").arg(c + 1));
@@ -106,7 +107,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId)
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
cbox->setEnabled(machineHasIsa);
- findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machineHasIsa);
+ findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled((isamem_type[c] != 0) && isamem_has_config(isamem_type[c]) && machineHasIsa);
}
}
@@ -138,7 +139,7 @@ SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index)
if (index < 0) {
return;
}
- ui->pushButtonConfigureRTC->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA));
+ ui->pushButtonConfigureRTC->setEnabled((index != 0) && isartc_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
@@ -153,7 +154,7 @@ SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index)
if (index < 0) {
return;
}
- ui->pushButtonConfigureCard1->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA));
+ ui->pushButtonConfigureCard1->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
@@ -168,7 +169,7 @@ SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index)
if (index < 0) {
return;
}
- ui->pushButtonConfigureCard2->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA));
+ ui->pushButtonConfigureCard2->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
@@ -183,7 +184,7 @@ SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index)
if (index < 0) {
return;
}
- ui->pushButtonConfigureCard3->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA));
+ ui->pushButtonConfigureCard3->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
@@ -198,7 +199,7 @@ SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index)
if (index < 0) {
return;
}
- ui->pushButtonConfigureCard4->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA));
+ ui->pushButtonConfigureCard4->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA));
}
void
From 1d325d411de7977ff419cb243174aaeea07934bd Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 22:34:22 -0400
Subject: [PATCH 050/567] Fix underlying segfaults too
---
src/qt/qt_deviceconfig.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp
index b031e65445..d24db2ed47 100644
--- a/src/qt/qt_deviceconfig.cpp
+++ b/src/qt/qt_deviceconfig.cpp
@@ -120,6 +120,9 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep)
int p;
int q;
+ if (config == NULL)
+ return;
+
while (config->type != -1) {
const int config_type = config->type & CONFIG_TYPE_MASK;
@@ -363,7 +366,11 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
dc.ProcessConfig(&device_context, config, false);
dc.setFixedSize(dc.minimumSizeHint());
+
if (dc.exec() == QDialog::Accepted) {
+ if (config == NULL)
+ return;
+
config = device->config;
while (config->type != -1) {
switch (config->type) {
From 152c0cbf1d6f85fdd0b69798de6b324d8cf5e70b Mon Sep 17 00:00:00 2001
From: OBattler
Date: Sat, 8 Jun 2024 05:02:58 +0200
Subject: [PATCH 051/567] Settings: Changed the List View to a Table View - now
the pages rows are no longer as small as they used to be.
---
src/qt/qt_settings.cpp | 4 ++--
src/qt/qt_settings.ui | 21 ++++++++++++++++++---
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp
index e9767083ad..caabdbfca6 100644
--- a/src/qt/qt_settings.cpp
+++ b/src/qt/qt_settings.cpp
@@ -182,8 +182,8 @@ Settings::Settings(QWidget *parent)
[this](const QModelIndex ¤t, const QModelIndex &previous) {
ui->stackedWidget->setCurrentIndex(current.row()); });
- ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) +
- qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent));
+ ui->listView->resizeColumnsToContents();
+ ui->listView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->listView->setCurrentIndex(model->index(0, 0));
diff --git a/src/qt/qt_settings.ui b/src/qt/qt_settings.ui
index 7b4d28bec9..fd92f7f580 100644
--- a/src/qt/qt_settings.ui
+++ b/src/qt/qt_settings.ui
@@ -36,10 +36,25 @@
0
-
-
-
- QListView::ListMode
+
+
+ QAbstractItemView::NoEditTriggers
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
+ false
+
-
From 4c74fdd4cc8968a00f6650f14cdf97fa9f9bdada Mon Sep 17 00:00:00 2001
From: Jasmine Iwanek
Date: Fri, 7 Jun 2024 23:56:37 -0400
Subject: [PATCH 052/567] Correct max mem on IBM 286 clones and the XT/286
---
src/machine/machine_table.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index e841a85385..da3df57b65 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -2665,7 +2665,7 @@ const machine_t machines[] = {
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 256,
- .max = 15872,
+ .max = 640,
.step = 128
},
.nvrmask = 127,
@@ -2705,8 +2705,8 @@ const machine_t machines[] = {
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 256,
- .max = 15872,
- .step = 128
+ .max = 512,
+ .step = 256
},
.nvrmask = 63,
.kbc_device = NULL,
@@ -3030,8 +3030,8 @@ const machine_t machines[] = {
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 256,
- .max = 15872,
- .step = 128
+ .max = 512,
+ .step = 256
},
.nvrmask = 63,
.kbc_device = NULL,
@@ -3070,8 +3070,8 @@ const machine_t machines[] = {
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 256,
- .max = 15872,
- .step = 128
+ .max = 512,
+ .step = 256
},
.nvrmask = 63,
.kbc_device = NULL,
From 4b77ef6823cc6840150e0ee2bf11e40cd7d8caa6 Mon Sep 17 00:00:00 2001
From: OBattler
Date: Sun, 9 Jun 2024 19:58:16 +0200
Subject: [PATCH 053/567] 286: Make LOCK legal with all instructions, per the
Programmers' Reference Manual.
---
src/cpu/386_common.c | 46 +++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c
index f3926f1701..801b543c39 100644
--- a/src/cpu/386_common.c
+++ b/src/cpu/386_common.c
@@ -426,42 +426,44 @@ x386_common_log(const char *fmt, ...)
int
is_lock_legal(uint32_t fetchdat)
{
- int legal;
- fetch_dat_t fetch_dat;
+ int legal = 1;
- fetch_dat.fd = fetchdat;
+ if (is386) {
+ fetch_dat_t fetch_dat;
+ fetch_dat.fd = fetchdat;
- legal = lock_legal[fetch_dat.b[0]];
- if (legal == 1)
- legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
- else if (legal == 2) {
- legal = lock_legal_0f[fetch_dat.b[1]];
+ legal = lock_legal[fetch_dat.b[0]];
if (legal == 1)
- legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */
- else if (legal == 3) {
- legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07];
+ legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
+ else if (legal == 2) {
+ legal = lock_legal_0f[fetch_dat.b[1]];
if (legal == 1)
- legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */
- }
- } else if (legal == 3) switch(fetch_dat.b[0]) {
- case 0x80 ... 0x83:
- legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07];
+ legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */
+ else if (legal == 3) {
+ legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07];
+ if (legal == 1)
+ legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */
+ }
+ } else if (legal == 3) switch(fetch_dat.b[0]) {
+ case 0x80 ... 0x83:
+ legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07];
if (legal == 1)
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
break;
- case 0xf6 ... 0xf7:
- legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07];
+ case 0xf6 ... 0xf7:
+ legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07];
if (legal == 1)
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
break;
- case 0xfe ... 0xff:
- legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07];
+ case 0xfe ... 0xff:
+ legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07];
if (legal == 1)
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
break;
- default:
- legal = 0;
+ default:
+ legal = 0;
break;
+ }
}
return legal;
From 0f29bcddf196763c4742a75dcdaaed7045372340 Mon Sep 17 00:00:00 2001
From: TC1995
Date: Sun, 9 Jun 2024 23:08:46 +0200
Subject: [PATCH 054/567] Upgrade to softfloat3e.
This should solve licensing problems as well.
---
src/codegen/codegen_ops_x86-64.h | 8 +-
src/codegen/codegen_ops_x86.h | 40 +-
src/codegen_new/codegen_backend_arm64_uops.c | 12 +-
src/codegen_new/codegen_backend_arm_uops.c | 12 +-
src/codegen_new/codegen_backend_x86-64_uops.c | 4 +-
src/codegen_new/codegen_backend_x86_uops.c | 4 +-
src/codegen_new/codegen_ops_fpu_arith.c | 22 +-
src/cpu/CMakeLists.txt | 4 +-
src/cpu/cpu.h | 4 +-
src/cpu/softfloat/CMakeLists.txt | 17 -
src/cpu/softfloat/config.h | 51 -
src/cpu/softfloat/softfloat-compare.h | 496 --
src/cpu/softfloat/softfloat-macros.h | 686 ---
src/cpu/softfloat/softfloat-muladd.cc | 558 ---
src/cpu/softfloat/softfloat-round-pack.cc | 896 ----
src/cpu/softfloat/softfloat-round-pack.h | 309 --
src/cpu/softfloat/softfloat-specialize.cc | 187 -
src/cpu/softfloat/softfloat-specialize.h | 789 ----
src/cpu/softfloat/softfloat.cc | 4012 -----------------
src/cpu/softfloat/softfloat.h | 488 --
src/cpu/softfloat/softfloat16.cc | 129 -
src/cpu/softfloat/softfloatx80.cc | 384 --
src/cpu/softfloat/softfloatx80.h | 121 -
src/cpu/softfloat3e/CMakeLists.txt | 56 +
src/cpu/softfloat3e/COPYING.txt | 37 +
src/cpu/softfloat3e/README.html | 49 +
src/cpu/softfloat3e/README.txt | 21 +
src/cpu/softfloat3e/config.h | 14 +
src/cpu/softfloat3e/consts.cc | 51 +
.../softfloat3e/doc/SoftFloat-history.html | 258 ++
src/cpu/softfloat3e/doc/SoftFloat-source.html | 686 +++
src/cpu/softfloat3e/doc/SoftFloat.html | 1527 +++++++
src/cpu/softfloat3e/extF80_addsub.cc | 106 +
src/cpu/softfloat3e/extF80_class.cc | 71 +
src/cpu/softfloat3e/extF80_compare.cc | 147 +
src/cpu/softfloat3e/extF80_div.cc | 188 +
src/cpu/softfloat3e/extF80_extract.cc | 97 +
src/cpu/softfloat3e/extF80_mul.cc | 153 +
src/cpu/softfloat3e/extF80_rem.cc | 199 +
src/cpu/softfloat3e/extF80_roundToInt.cc | 123 +
src/cpu/softfloat3e/extF80_scale.cc | 136 +
src/cpu/softfloat3e/extF80_sqrt.cc | 159 +
src/cpu/softfloat3e/extF80_to_f128.cc | 75 +
src/cpu/softfloat3e/extF80_to_f16.cc | 89 +
src/cpu/softfloat3e/extF80_to_f32.cc | 89 +
src/cpu/softfloat3e/extF80_to_f64.cc | 89 +
src/cpu/softfloat3e/extF80_to_i32.cc | 82 +
src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc | 93 +
src/cpu/softfloat3e/extF80_to_i64.cc | 88 +
src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc | 90 +
src/cpu/softfloat3e/extF80_to_ui32.cc | 83 +
.../softfloat3e/extF80_to_ui32_r_minMag.cc | 87 +
src/cpu/softfloat3e/extF80_to_ui64.cc | 83 +
.../softfloat3e/extF80_to_ui64_r_minMag.cc | 87 +
src/cpu/softfloat3e/f128_addsub.cc | 88 +
src/cpu/softfloat3e/f128_div.cc | 187 +
src/cpu/softfloat3e/f128_mul.cc | 148 +
src/cpu/softfloat3e/f128_mulAdd.cc | 332 ++
src/cpu/softfloat3e/f128_roundToInt.cc | 142 +
src/cpu/softfloat3e/f128_to_extF80.cc | 94 +
src/cpu/softfloat3e/f128_to_f32.cc | 83 +
src/cpu/softfloat3e/f128_to_f64.cc | 87 +
src/cpu/softfloat3e/f128_to_i32.cc | 80 +
src/cpu/softfloat3e/f128_to_i32_r_minMag.cc | 89 +
src/cpu/softfloat3e/f128_to_i64.cc | 90 +
src/cpu/softfloat3e/f128_to_i64_r_minMag.cc | 104 +
src/cpu/softfloat3e/f128_to_ui32.cc | 81 +
src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc | 83 +
src/cpu/softfloat3e/f128_to_ui64.cc | 90 +
src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc | 99 +
src/cpu/softfloat3e/f16_addsub.c | 60 +
src/cpu/softfloat3e/f16_class.c | 64 +
src/cpu/softfloat3e/f16_compare.c | 92 +
src/cpu/softfloat3e/f16_div.c | 149 +
src/cpu/softfloat3e/f16_getExp.c | 73 +
src/cpu/softfloat3e/f16_getMant.c | 108 +
src/cpu/softfloat3e/f16_minmax.c | 69 +
src/cpu/softfloat3e/f16_mul.c | 139 +
src/cpu/softfloat3e/f16_mulAdd.c | 232 +
src/cpu/softfloat3e/f16_range.c | 135 +
src/cpu/softfloat3e/f16_roundToInt.c | 112 +
src/cpu/softfloat3e/f16_sqrt.c | 130 +
src/cpu/softfloat3e/f16_to_extF80.cc | 88 +
src/cpu/softfloat3e/f16_to_f32.c | 81 +
src/cpu/softfloat3e/f16_to_f64.c | 81 +
src/cpu/softfloat3e/f16_to_i32.c | 81 +
src/cpu/softfloat3e/f16_to_i32_r_minMag.c | 82 +
src/cpu/softfloat3e/f16_to_i64.c | 80 +
src/cpu/softfloat3e/f16_to_i64_r_minMag.c | 82 +
src/cpu/softfloat3e/f16_to_ui32.c | 79 +
src/cpu/softfloat3e/f16_to_ui32_r_minMag.c | 81 +
src/cpu/softfloat3e/f16_to_ui64.c | 79 +
src/cpu/softfloat3e/f16_to_ui64_r_minMag.c | 81 +
src/cpu/{softfloat => softfloat3e}/f2xm1.cc | 69 +-
src/cpu/softfloat3e/f32_addsub.c | 60 +
src/cpu/softfloat3e/f32_class.c | 64 +
src/cpu/softfloat3e/f32_compare.c | 92 +
src/cpu/softfloat3e/f32_div.c | 146 +
src/cpu/softfloat3e/f32_frc.c | 101 +
src/cpu/softfloat3e/f32_getExp.c | 73 +
src/cpu/softfloat3e/f32_getMant.c | 108 +
src/cpu/softfloat3e/f32_minmax.c | 69 +
src/cpu/softfloat3e/f32_mul.c | 137 +
src/cpu/softfloat3e/f32_mulAdd.c | 233 +
src/cpu/softfloat3e/f32_range.c | 134 +
src/cpu/softfloat3e/f32_roundToInt.c | 112 +
src/cpu/softfloat3e/f32_scalef.c | 155 +
src/cpu/softfloat3e/f32_sqrt.c | 117 +
src/cpu/softfloat3e/f32_to_extF80.cc | 88 +
src/cpu/softfloat3e/f32_to_f128.cc | 86 +
src/cpu/softfloat3e/f32_to_f16.c | 82 +
src/cpu/softfloat3e/f32_to_f64.c | 81 +
src/cpu/softfloat3e/f32_to_i32.c | 78 +
src/cpu/softfloat3e/f32_to_i32_r_minMag.c | 83 +
src/cpu/softfloat3e/f32_to_i64.c | 79 +
src/cpu/softfloat3e/f32_to_i64_r_minMag.c | 88 +
src/cpu/softfloat3e/f32_to_ui32.c | 80 +
src/cpu/softfloat3e/f32_to_ui32_r_minMag.c | 83 +
src/cpu/softfloat3e/f32_to_ui64.c | 79 +
src/cpu/softfloat3e/f32_to_ui64_r_minMag.c | 84 +
src/cpu/softfloat3e/f64_addsub.c | 70 +
src/cpu/softfloat3e/f64_class.c | 64 +
src/cpu/softfloat3e/f64_compare.c | 92 +
src/cpu/softfloat3e/f64_div.c | 165 +
src/cpu/softfloat3e/f64_frc.c | 101 +
src/cpu/softfloat3e/f64_getExp.c | 73 +
src/cpu/softfloat3e/f64_getMant.c | 108 +
src/cpu/softfloat3e/f64_minmax.c | 69 +
src/cpu/softfloat3e/f64_mul.c | 139 +
src/cpu/softfloat3e/f64_mulAdd.c | 243 +
src/cpu/softfloat3e/f64_range.c | 135 +
src/cpu/softfloat3e/f64_roundToInt.c | 112 +
src/cpu/softfloat3e/f64_scalef.c | 156 +
src/cpu/softfloat3e/f64_sqrt.c | 130 +
src/cpu/softfloat3e/f64_to_extF80.cc | 88 +
src/cpu/softfloat3e/f64_to_f128.cc | 89 +
src/cpu/softfloat3e/f64_to_f16.c | 83 +
src/cpu/softfloat3e/f64_to_f32.c | 83 +
src/cpu/softfloat3e/f64_to_i32.c | 77 +
src/cpu/softfloat3e/f64_to_i32_r_minMag.c | 89 +
src/cpu/softfloat3e/f64_to_i64.c | 78 +
src/cpu/softfloat3e/f64_to_i64_r_minMag.c | 95 +
src/cpu/softfloat3e/f64_to_ui32.c | 77 +
src/cpu/softfloat3e/f64_to_ui32_r_minMag.c | 83 +
src/cpu/softfloat3e/f64_to_ui64.c | 76 +
src/cpu/softfloat3e/f64_to_ui64_r_minMag.c | 87 +
src/cpu/{softfloat => softfloat3e}/fpatan.cc | 171 +-
src/cpu/{softfloat => softfloat3e}/fprem.cc | 148 +-
.../{softfloat => softfloat3e}/fpu_constant.h | 2 +-
src/cpu/softfloat3e/fpu_trans.h | 117 +
src/cpu/{softfloat => softfloat3e}/fsincos.cc | 176 +-
src/cpu/{softfloat => softfloat3e}/fyl2x.cc | 223 +-
src/cpu/softfloat3e/i32_to_extF80.cc | 62 +
src/cpu/softfloat3e/i32_to_f128.cc | 59 +
src/cpu/softfloat3e/i32_to_f16.c | 61 +
src/cpu/softfloat3e/i32_to_f32.c | 52 +
src/cpu/softfloat3e/i32_to_f64.c | 56 +
src/cpu/softfloat3e/i64_to_extF80.cc | 62 +
src/cpu/softfloat3e/i64_to_f128.cc | 69 +
src/cpu/softfloat3e/i64_to_f16.c | 61 +
src/cpu/softfloat3e/i64_to_f32.c | 61 +
src/cpu/softfloat3e/i64_to_f64.c | 53 +
src/cpu/softfloat3e/internals.h | 150 +
src/cpu/softfloat3e/isNaN.cc | 63 +
src/cpu/softfloat3e/isSignalingNaN.cc | 63 +
src/cpu/softfloat3e/opts-GCC.h | 110 +
.../softfloat_poly.cc => softfloat3e/poly.cc} | 22 +-
src/cpu/softfloat3e/poly.h | 43 +
src/cpu/softfloat3e/primitiveTypes.h | 54 +
src/cpu/softfloat3e/primitives.h | 535 +++
src/cpu/softfloat3e/s_add128.cc | 51 +
src/cpu/softfloat3e/s_add256M.c | 60 +
src/cpu/softfloat3e/s_addMagsExtF80.cc | 146 +
src/cpu/softfloat3e/s_addMagsF128.cc | 138 +
src/cpu/softfloat3e/s_addMagsF16.c | 192 +
src/cpu/softfloat3e/s_addMagsF32.c | 147 +
src/cpu/softfloat3e/s_addMagsF64.c | 149 +
src/cpu/softfloat3e/s_approxRecipSqrt32_1.c | 63 +
src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c | 46 +
src/cpu/softfloat3e/s_approxRecip_1Ks.c | 46 +
src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc | 69 +
src/cpu/softfloat3e/s_commonNaNToF128UI.cc | 72 +
src/cpu/softfloat3e/s_commonNaNToF16UI.c | 62 +
src/cpu/softfloat3e/s_commonNaNToF32UI.c | 62 +
src/cpu/softfloat3e/s_commonNaNToF64UI.c | 62 +
src/cpu/softfloat3e/s_countLeadingZeros16.c | 56 +
src/cpu/softfloat3e/s_countLeadingZeros32.c | 61 +
src/cpu/softfloat3e/s_countLeadingZeros64.c | 70 +
src/cpu/softfloat3e/s_countLeadingZeros8.c | 57 +
src/cpu/softfloat3e/s_eq128.c | 46 +
src/cpu/softfloat3e/s_le128.c | 46 +
src/cpu/softfloat3e/s_lt128.c | 46 +
src/cpu/softfloat3e/s_mul128By32.cc | 54 +
src/cpu/softfloat3e/s_mul128To256M.cc | 62 +
.../softfloat3e/s_mul64ByShifted32To128.cc | 52 +
src/cpu/softfloat3e/s_mul64To128.cc | 63 +
.../softfloat3e/s_normRoundPackToExtF80.cc | 62 +
src/cpu/softfloat3e/s_normRoundPackToF128.cc | 75 +
src/cpu/softfloat3e/s_normRoundPackToF16.c | 49 +
src/cpu/softfloat3e/s_normRoundPackToF32.c | 49 +
src/cpu/softfloat3e/s_normRoundPackToF64.c | 49 +
.../softfloat3e/s_normSubnormalExtF80Sig.cc | 50 +
src/cpu/softfloat3e/s_normSubnormalF128Sig.cc | 61 +
src/cpu/softfloat3e/s_normSubnormalF16Sig.c | 50 +
src/cpu/softfloat3e/s_normSubnormalF32Sig.c | 51 +
src/cpu/softfloat3e/s_normSubnormalF64Sig.c | 49 +
src/cpu/softfloat3e/s_packToExtF80.cc | 54 +
src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc | 96 +
src/cpu/softfloat3e/s_propagateNaNF128UI.cc | 78 +
src/cpu/softfloat3e/s_propagateNaNF16UI.c | 57 +
src/cpu/softfloat3e/s_propagateNaNF32UI.c | 57 +
src/cpu/softfloat3e/s_propagateNaNF64UI.c | 57 +
src/cpu/softfloat3e/s_roundPackToExtF80.cc | 224 +
src/cpu/softfloat3e/s_roundPackToF128.cc | 102 +
src/cpu/softfloat3e/s_roundPackToF16.c | 104 +
src/cpu/softfloat3e/s_roundPackToF32.c | 108 +
src/cpu/softfloat3e/s_roundPackToF64.c | 108 +
src/cpu/softfloat3e/s_roundToI32.c | 79 +
src/cpu/softfloat3e/s_roundToI64.c | 77 +
src/cpu/softfloat3e/s_roundToUI32.c | 79 +
src/cpu/softfloat3e/s_roundToUI64.c | 76 +
src/cpu/softfloat3e/s_shiftRightJam128.cc | 65 +
.../softfloat3e/s_shiftRightJam128Extra.cc | 73 +
src/cpu/softfloat3e/s_shiftRightJam256M.c | 113 +
src/cpu/softfloat3e/s_shiftRightJam32.c | 45 +
src/cpu/softfloat3e/s_shiftRightJam64.c | 46 +
src/cpu/softfloat3e/s_shiftRightJam64Extra.c | 57 +
src/cpu/softfloat3e/s_shortShiftLeft128.cc | 51 +
src/cpu/softfloat3e/s_shortShiftRight128.cc | 51 +
src/cpu/softfloat3e/s_shortShiftRightJam64.c | 46 +
.../softfloat3e/s_shortShiftRightJam64Extra.c | 51 +
src/cpu/softfloat3e/s_sub128.cc | 50 +
src/cpu/softfloat3e/s_sub256M.c | 59 +
src/cpu/softfloat3e/s_subMagsExtF80.cc | 154 +
src/cpu/softfloat3e/s_subMagsF128.cc | 131 +
src/cpu/softfloat3e/s_subMagsF16.c | 190 +
src/cpu/softfloat3e/s_subMagsF32.c | 151 +
src/cpu/softfloat3e/s_subMagsF64.c | 150 +
src/cpu/softfloat3e/softfloat-compare.h | 725 +++
src/cpu/softfloat3e/softfloat-extra.h | 141 +
src/cpu/softfloat3e/softfloat-helpers.h | 158 +
src/cpu/softfloat3e/softfloat-specialize.h | 224 +
src/cpu/softfloat3e/softfloat.h | 702 +++
src/cpu/softfloat3e/softfloat_types.h | 87 +
src/cpu/softfloat3e/specialize.h | 280 ++
src/cpu/softfloat3e/ui32_to_extF80.cc | 56 +
src/cpu/softfloat3e/ui32_to_f128.cc | 55 +
src/cpu/softfloat3e/ui32_to_f16.c | 57 +
src/cpu/softfloat3e/ui32_to_f32.c | 50 +
src/cpu/softfloat3e/ui32_to_f64.c | 49 +
src/cpu/softfloat3e/ui64_to_extF80.cc | 56 +
src/cpu/softfloat3e/ui64_to_f128.cc | 65 +
src/cpu/softfloat3e/ui64_to_f16.c | 55 +
src/cpu/softfloat3e/ui64_to_f32.c | 55 +
src/cpu/softfloat3e/ui64_to_f64.c | 51 +
src/cpu/x86_ops.h | 8 +-
src/cpu/x86_ops_fpu.h | 8 +
src/cpu/x86_ops_i686.h | 8 +-
src/cpu/x86_ops_mmx.c | 6 +-
src/cpu/x87.c | 168 +-
src/cpu/x87.h | 132 +-
src/cpu/x87_ops.h | 399 +-
src/cpu/x87_ops_arith.h | 36 +-
src/cpu/x87_ops_misc.h | 42 +-
src/cpu/x87_ops_sf.h | 24 +-
src/cpu/x87_ops_sf_arith.h | 205 +-
src/cpu/x87_ops_sf_compare.h | 263 +-
src/cpu/x87_ops_sf_const.h | 15 +-
src/cpu/x87_ops_sf_load_store.h | 394 +-
src/cpu/x87_ops_sf_misc.h | 1 +
src/cpu/x87_ops_sf_trans.h | 153 +-
271 files changed, 25904 insertions(+), 10463 deletions(-)
delete mode 100644 src/cpu/softfloat/CMakeLists.txt
delete mode 100644 src/cpu/softfloat/config.h
delete mode 100644 src/cpu/softfloat/softfloat-compare.h
delete mode 100644 src/cpu/softfloat/softfloat-macros.h
delete mode 100644 src/cpu/softfloat/softfloat-muladd.cc
delete mode 100644 src/cpu/softfloat/softfloat-round-pack.cc
delete mode 100644 src/cpu/softfloat/softfloat-round-pack.h
delete mode 100644 src/cpu/softfloat/softfloat-specialize.cc
delete mode 100644 src/cpu/softfloat/softfloat-specialize.h
delete mode 100644 src/cpu/softfloat/softfloat.cc
delete mode 100644 src/cpu/softfloat/softfloat.h
delete mode 100644 src/cpu/softfloat/softfloat16.cc
delete mode 100644 src/cpu/softfloat/softfloatx80.cc
delete mode 100644 src/cpu/softfloat/softfloatx80.h
create mode 100644 src/cpu/softfloat3e/CMakeLists.txt
create mode 100644 src/cpu/softfloat3e/COPYING.txt
create mode 100644 src/cpu/softfloat3e/README.html
create mode 100644 src/cpu/softfloat3e/README.txt
create mode 100644 src/cpu/softfloat3e/config.h
create mode 100644 src/cpu/softfloat3e/consts.cc
create mode 100644 src/cpu/softfloat3e/doc/SoftFloat-history.html
create mode 100644 src/cpu/softfloat3e/doc/SoftFloat-source.html
create mode 100644 src/cpu/softfloat3e/doc/SoftFloat.html
create mode 100644 src/cpu/softfloat3e/extF80_addsub.cc
create mode 100644 src/cpu/softfloat3e/extF80_class.cc
create mode 100644 src/cpu/softfloat3e/extF80_compare.cc
create mode 100644 src/cpu/softfloat3e/extF80_div.cc
create mode 100644 src/cpu/softfloat3e/extF80_extract.cc
create mode 100644 src/cpu/softfloat3e/extF80_mul.cc
create mode 100644 src/cpu/softfloat3e/extF80_rem.cc
create mode 100644 src/cpu/softfloat3e/extF80_roundToInt.cc
create mode 100644 src/cpu/softfloat3e/extF80_scale.cc
create mode 100644 src/cpu/softfloat3e/extF80_sqrt.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_f128.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_f16.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_f32.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_f64.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_i32.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_i64.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_ui32.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_ui64.cc
create mode 100644 src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/f128_addsub.cc
create mode 100644 src/cpu/softfloat3e/f128_div.cc
create mode 100644 src/cpu/softfloat3e/f128_mul.cc
create mode 100644 src/cpu/softfloat3e/f128_mulAdd.cc
create mode 100644 src/cpu/softfloat3e/f128_roundToInt.cc
create mode 100644 src/cpu/softfloat3e/f128_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/f128_to_f32.cc
create mode 100644 src/cpu/softfloat3e/f128_to_f64.cc
create mode 100644 src/cpu/softfloat3e/f128_to_i32.cc
create mode 100644 src/cpu/softfloat3e/f128_to_i32_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/f128_to_i64.cc
create mode 100644 src/cpu/softfloat3e/f128_to_i64_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/f128_to_ui32.cc
create mode 100644 src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/f128_to_ui64.cc
create mode 100644 src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc
create mode 100644 src/cpu/softfloat3e/f16_addsub.c
create mode 100644 src/cpu/softfloat3e/f16_class.c
create mode 100644 src/cpu/softfloat3e/f16_compare.c
create mode 100644 src/cpu/softfloat3e/f16_div.c
create mode 100644 src/cpu/softfloat3e/f16_getExp.c
create mode 100644 src/cpu/softfloat3e/f16_getMant.c
create mode 100644 src/cpu/softfloat3e/f16_minmax.c
create mode 100644 src/cpu/softfloat3e/f16_mul.c
create mode 100644 src/cpu/softfloat3e/f16_mulAdd.c
create mode 100644 src/cpu/softfloat3e/f16_range.c
create mode 100644 src/cpu/softfloat3e/f16_roundToInt.c
create mode 100644 src/cpu/softfloat3e/f16_sqrt.c
create mode 100644 src/cpu/softfloat3e/f16_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/f16_to_f32.c
create mode 100644 src/cpu/softfloat3e/f16_to_f64.c
create mode 100644 src/cpu/softfloat3e/f16_to_i32.c
create mode 100644 src/cpu/softfloat3e/f16_to_i32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f16_to_i64.c
create mode 100644 src/cpu/softfloat3e/f16_to_i64_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f16_to_ui32.c
create mode 100644 src/cpu/softfloat3e/f16_to_ui32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f16_to_ui64.c
create mode 100644 src/cpu/softfloat3e/f16_to_ui64_r_minMag.c
rename src/cpu/{softfloat => softfloat3e}/f2xm1.cc (77%)
create mode 100644 src/cpu/softfloat3e/f32_addsub.c
create mode 100644 src/cpu/softfloat3e/f32_class.c
create mode 100644 src/cpu/softfloat3e/f32_compare.c
create mode 100644 src/cpu/softfloat3e/f32_div.c
create mode 100644 src/cpu/softfloat3e/f32_frc.c
create mode 100644 src/cpu/softfloat3e/f32_getExp.c
create mode 100644 src/cpu/softfloat3e/f32_getMant.c
create mode 100644 src/cpu/softfloat3e/f32_minmax.c
create mode 100644 src/cpu/softfloat3e/f32_mul.c
create mode 100644 src/cpu/softfloat3e/f32_mulAdd.c
create mode 100644 src/cpu/softfloat3e/f32_range.c
create mode 100644 src/cpu/softfloat3e/f32_roundToInt.c
create mode 100644 src/cpu/softfloat3e/f32_scalef.c
create mode 100644 src/cpu/softfloat3e/f32_sqrt.c
create mode 100644 src/cpu/softfloat3e/f32_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/f32_to_f128.cc
create mode 100644 src/cpu/softfloat3e/f32_to_f16.c
create mode 100644 src/cpu/softfloat3e/f32_to_f64.c
create mode 100644 src/cpu/softfloat3e/f32_to_i32.c
create mode 100644 src/cpu/softfloat3e/f32_to_i32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f32_to_i64.c
create mode 100644 src/cpu/softfloat3e/f32_to_i64_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f32_to_ui32.c
create mode 100644 src/cpu/softfloat3e/f32_to_ui32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f32_to_ui64.c
create mode 100644 src/cpu/softfloat3e/f32_to_ui64_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f64_addsub.c
create mode 100644 src/cpu/softfloat3e/f64_class.c
create mode 100644 src/cpu/softfloat3e/f64_compare.c
create mode 100644 src/cpu/softfloat3e/f64_div.c
create mode 100644 src/cpu/softfloat3e/f64_frc.c
create mode 100644 src/cpu/softfloat3e/f64_getExp.c
create mode 100644 src/cpu/softfloat3e/f64_getMant.c
create mode 100644 src/cpu/softfloat3e/f64_minmax.c
create mode 100644 src/cpu/softfloat3e/f64_mul.c
create mode 100644 src/cpu/softfloat3e/f64_mulAdd.c
create mode 100644 src/cpu/softfloat3e/f64_range.c
create mode 100644 src/cpu/softfloat3e/f64_roundToInt.c
create mode 100644 src/cpu/softfloat3e/f64_scalef.c
create mode 100644 src/cpu/softfloat3e/f64_sqrt.c
create mode 100644 src/cpu/softfloat3e/f64_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/f64_to_f128.cc
create mode 100644 src/cpu/softfloat3e/f64_to_f16.c
create mode 100644 src/cpu/softfloat3e/f64_to_f32.c
create mode 100644 src/cpu/softfloat3e/f64_to_i32.c
create mode 100644 src/cpu/softfloat3e/f64_to_i32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f64_to_i64.c
create mode 100644 src/cpu/softfloat3e/f64_to_i64_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f64_to_ui32.c
create mode 100644 src/cpu/softfloat3e/f64_to_ui32_r_minMag.c
create mode 100644 src/cpu/softfloat3e/f64_to_ui64.c
create mode 100644 src/cpu/softfloat3e/f64_to_ui64_r_minMag.c
rename src/cpu/{softfloat => softfloat3e}/fpatan.cc (59%)
rename src/cpu/{softfloat => softfloat3e}/fprem.cc (53%)
rename src/cpu/{softfloat => softfloat3e}/fpu_constant.h (98%)
create mode 100644 src/cpu/softfloat3e/fpu_trans.h
rename src/cpu/{softfloat => softfloat3e}/fsincos.cc (68%)
rename src/cpu/{softfloat => softfloat3e}/fyl2x.cc (61%)
create mode 100644 src/cpu/softfloat3e/i32_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/i32_to_f128.cc
create mode 100644 src/cpu/softfloat3e/i32_to_f16.c
create mode 100644 src/cpu/softfloat3e/i32_to_f32.c
create mode 100644 src/cpu/softfloat3e/i32_to_f64.c
create mode 100644 src/cpu/softfloat3e/i64_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/i64_to_f128.cc
create mode 100644 src/cpu/softfloat3e/i64_to_f16.c
create mode 100644 src/cpu/softfloat3e/i64_to_f32.c
create mode 100644 src/cpu/softfloat3e/i64_to_f64.c
create mode 100644 src/cpu/softfloat3e/internals.h
create mode 100644 src/cpu/softfloat3e/isNaN.cc
create mode 100644 src/cpu/softfloat3e/isSignalingNaN.cc
create mode 100644 src/cpu/softfloat3e/opts-GCC.h
rename src/cpu/{softfloat/softfloat_poly.cc => softfloat3e/poly.cc} (84%)
create mode 100644 src/cpu/softfloat3e/poly.h
create mode 100644 src/cpu/softfloat3e/primitiveTypes.h
create mode 100644 src/cpu/softfloat3e/primitives.h
create mode 100644 src/cpu/softfloat3e/s_add128.cc
create mode 100644 src/cpu/softfloat3e/s_add256M.c
create mode 100644 src/cpu/softfloat3e/s_addMagsExtF80.cc
create mode 100644 src/cpu/softfloat3e/s_addMagsF128.cc
create mode 100644 src/cpu/softfloat3e/s_addMagsF16.c
create mode 100644 src/cpu/softfloat3e/s_addMagsF32.c
create mode 100644 src/cpu/softfloat3e/s_addMagsF64.c
create mode 100644 src/cpu/softfloat3e/s_approxRecipSqrt32_1.c
create mode 100644 src/cpu/softfloat3e/s_approxRecipSqrt_1Ks.c
create mode 100644 src/cpu/softfloat3e/s_approxRecip_1Ks.c
create mode 100644 src/cpu/softfloat3e/s_commonNaNToExtF80UI.cc
create mode 100644 src/cpu/softfloat3e/s_commonNaNToF128UI.cc
create mode 100644 src/cpu/softfloat3e/s_commonNaNToF16UI.c
create mode 100644 src/cpu/softfloat3e/s_commonNaNToF32UI.c
create mode 100644 src/cpu/softfloat3e/s_commonNaNToF64UI.c
create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros16.c
create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros32.c
create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros64.c
create mode 100644 src/cpu/softfloat3e/s_countLeadingZeros8.c
create mode 100644 src/cpu/softfloat3e/s_eq128.c
create mode 100644 src/cpu/softfloat3e/s_le128.c
create mode 100644 src/cpu/softfloat3e/s_lt128.c
create mode 100644 src/cpu/softfloat3e/s_mul128By32.cc
create mode 100644 src/cpu/softfloat3e/s_mul128To256M.cc
create mode 100644 src/cpu/softfloat3e/s_mul64ByShifted32To128.cc
create mode 100644 src/cpu/softfloat3e/s_mul64To128.cc
create mode 100644 src/cpu/softfloat3e/s_normRoundPackToExtF80.cc
create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF128.cc
create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF16.c
create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF32.c
create mode 100644 src/cpu/softfloat3e/s_normRoundPackToF64.c
create mode 100644 src/cpu/softfloat3e/s_normSubnormalExtF80Sig.cc
create mode 100644 src/cpu/softfloat3e/s_normSubnormalF128Sig.cc
create mode 100644 src/cpu/softfloat3e/s_normSubnormalF16Sig.c
create mode 100644 src/cpu/softfloat3e/s_normSubnormalF32Sig.c
create mode 100644 src/cpu/softfloat3e/s_normSubnormalF64Sig.c
create mode 100644 src/cpu/softfloat3e/s_packToExtF80.cc
create mode 100644 src/cpu/softfloat3e/s_propagateNaNExtF80UI.cc
create mode 100644 src/cpu/softfloat3e/s_propagateNaNF128UI.cc
create mode 100644 src/cpu/softfloat3e/s_propagateNaNF16UI.c
create mode 100644 src/cpu/softfloat3e/s_propagateNaNF32UI.c
create mode 100644 src/cpu/softfloat3e/s_propagateNaNF64UI.c
create mode 100644 src/cpu/softfloat3e/s_roundPackToExtF80.cc
create mode 100644 src/cpu/softfloat3e/s_roundPackToF128.cc
create mode 100644 src/cpu/softfloat3e/s_roundPackToF16.c
create mode 100644 src/cpu/softfloat3e/s_roundPackToF32.c
create mode 100644 src/cpu/softfloat3e/s_roundPackToF64.c
create mode 100644 src/cpu/softfloat3e/s_roundToI32.c
create mode 100644 src/cpu/softfloat3e/s_roundToI64.c
create mode 100644 src/cpu/softfloat3e/s_roundToUI32.c
create mode 100644 src/cpu/softfloat3e/s_roundToUI64.c
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam128.cc
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam128Extra.cc
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam256M.c
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam32.c
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam64.c
create mode 100644 src/cpu/softfloat3e/s_shiftRightJam64Extra.c
create mode 100644 src/cpu/softfloat3e/s_shortShiftLeft128.cc
create mode 100644 src/cpu/softfloat3e/s_shortShiftRight128.cc
create mode 100644 src/cpu/softfloat3e/s_shortShiftRightJam64.c
create mode 100644 src/cpu/softfloat3e/s_shortShiftRightJam64Extra.c
create mode 100644 src/cpu/softfloat3e/s_sub128.cc
create mode 100644 src/cpu/softfloat3e/s_sub256M.c
create mode 100644 src/cpu/softfloat3e/s_subMagsExtF80.cc
create mode 100644 src/cpu/softfloat3e/s_subMagsF128.cc
create mode 100644 src/cpu/softfloat3e/s_subMagsF16.c
create mode 100644 src/cpu/softfloat3e/s_subMagsF32.c
create mode 100644 src/cpu/softfloat3e/s_subMagsF64.c
create mode 100644 src/cpu/softfloat3e/softfloat-compare.h
create mode 100644 src/cpu/softfloat3e/softfloat-extra.h
create mode 100644 src/cpu/softfloat3e/softfloat-helpers.h
create mode 100644 src/cpu/softfloat3e/softfloat-specialize.h
create mode 100644 src/cpu/softfloat3e/softfloat.h
create mode 100644 src/cpu/softfloat3e/softfloat_types.h
create mode 100644 src/cpu/softfloat3e/specialize.h
create mode 100644 src/cpu/softfloat3e/ui32_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/ui32_to_f128.cc
create mode 100644 src/cpu/softfloat3e/ui32_to_f16.c
create mode 100644 src/cpu/softfloat3e/ui32_to_f32.c
create mode 100644 src/cpu/softfloat3e/ui32_to_f64.c
create mode 100644 src/cpu/softfloat3e/ui64_to_extF80.cc
create mode 100644 src/cpu/softfloat3e/ui64_to_f128.cc
create mode 100644 src/cpu/softfloat3e/ui64_to_f16.c
create mode 100644 src/cpu/softfloat3e/ui64_to_f32.c
create mode 100644 src/cpu/softfloat3e/ui64_to_f64.c
diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h
index bc6293c0bf..08b9ee5f24 100644
--- a/src/codegen/codegen_ops_x86-64.h
+++ b/src/codegen/codegen_ops_x86-64.h
@@ -4434,7 +4434,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte((uint8_t) cpu_state_offset(npxs) + 1);
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
if (src) {
addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/
@@ -4467,7 +4467,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0x9f); /*LAHF*/
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
@@ -4493,7 +4493,7 @@ FP_COMPARE_MEM(void)
addbyte((uint8_t) cpu_state_offset(ST));
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0x66); /*COMISD XMM0, XMM1*/
addbyte(0x0f);
addbyte(0x2f);
@@ -4501,7 +4501,7 @@ FP_COMPARE_MEM(void)
addbyte(0x9f); /*LAHF*/
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h
index 410ce8e17a..c48324c2a9 100644
--- a/src/codegen/codegen_ops_x86.h
+++ b/src/codegen/codegen_ops_x86.h
@@ -2911,7 +2911,7 @@ FP_COMPARE_S(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xd8); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2919,7 +2919,7 @@ FP_COMPARE_S(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -2943,7 +2943,7 @@ FP_COMPARE_S(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xd8); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2951,7 +2951,7 @@ FP_COMPARE_S(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -2980,7 +2980,7 @@ FP_COMPARE_D(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2988,7 +2988,7 @@ FP_COMPARE_D(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3016,7 +3016,7 @@ FP_COMPARE_D(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3024,7 +3024,7 @@ FP_COMPARE_D(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3050,7 +3050,7 @@ FP_COMPARE_IW(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xde); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3058,7 +3058,7 @@ FP_COMPARE_IW(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3082,7 +3082,7 @@ FP_COMPARE_IW(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xde); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3090,7 +3090,7 @@ FP_COMPARE_IW(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3115,7 +3115,7 @@ FP_COMPARE_IL(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xda); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3123,7 +3123,7 @@ FP_COMPARE_IL(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3147,7 +3147,7 @@ FP_COMPARE_IL(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xda); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3155,7 +3155,7 @@ FP_COMPARE_IL(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3250,7 +3250,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7]));
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP ST[src][EBP]*/
addbyte(0x5d);
addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7]));
@@ -3258,7 +3258,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
@@ -3286,7 +3286,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe2);
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
if (src) {
addbyte(0xdd); /*FLD ST[EBX*8]*/
@@ -3312,7 +3312,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c
index 7514e1f0c3..421292c7ea 100644
--- a/src/codegen_new/codegen_backend_arm64_uops.c
+++ b/src/codegen_new/codegen_backend_arm64_uops.c
@@ -648,10 +648,10 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP);
host_arm64_MOVZ_IMM(block, dest_reg, 0);
host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3);
- host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3);
+ host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0);
host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg);
host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg);
} else
@@ -690,10 +690,10 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) {
host_arm64_MOVZ_IMM(block, dest_reg, 0);
host_arm64_FCMP_D(block, src_reg_a, src_reg_b);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3);
- host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3);
+ host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0);
host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg);
host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg);
} else
diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c
index 338d3dd546..04b61255b5 100644
--- a/src/codegen_new/codegen_backend_arm_uops.c
+++ b/src/codegen_new/codegen_backend_arm_uops.c
@@ -718,9 +718,9 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP);
host_arm_MOV_IMM(block, dest_reg, 0);
host_arm_VMRS_APSR(block);
- host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3);
- host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0);
- host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3);
+ host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3);
+ host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0);
+ host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
} else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
@@ -758,9 +758,9 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_arm_VCMP_D(block, src_reg_a, src_reg_b);
host_arm_MOV_IMM(block, dest_reg, 0);
host_arm_VMRS_APSR(block);
- host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3);
- host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0);
- host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3);
+ host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3);
+ host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0);
+ host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
} else
fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c
index fcab0f3ce8..1b82f9fcaf 100644
--- a/src/codegen_new/codegen_backend_x86-64_uops.c
+++ b/src/codegen_new/codegen_backend_x86-64_uops.c
@@ -672,7 +672,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
@@ -720,7 +720,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c
index 5ef2d97b8a..91f2c7ec37 100644
--- a/src/codegen_new/codegen_backend_x86_uops.c
+++ b/src/codegen_new/codegen_backend_x86_uops.c
@@ -677,7 +677,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
@@ -725,7 +725,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c
index 3ab7be8ac9..15a6399e6a 100644
--- a/src/codegen_new/codegen_ops_fpu_arith.c
+++ b/src/codegen_new/codegen_ops_fpu_arith.c
@@ -59,7 +59,7 @@ ropFCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
@@ -71,7 +71,7 @@ ropFCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP(block, ir);
@@ -82,7 +82,7 @@ ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe
{
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP2(block, ir);
@@ -269,7 +269,7 @@ ropFUCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
@@ -281,7 +281,7 @@ ropFUCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP(block, ir);
@@ -292,7 +292,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
{
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP2(block, ir);
@@ -328,7 +328,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
codegen_check_seg_read(block, ir, target_seg); \
load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
\
return op_pc + 1; \
@@ -344,7 +344,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
codegen_check_seg_read(block, ir, target_seg); \
load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
fpu_POP(block, ir); \
\
@@ -460,7 +460,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE)
uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
\
return op_pc + 1; \
@@ -477,7 +477,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE)
uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
fpu_POP(block, ir); \
\
@@ -600,7 +600,7 @@ ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3
{
uop_FP_ENTER(ir);
uop_FTST(ir, IREG_temp0_W, IREG_ST(0));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt
index bd03a5558f..fc5ba975fb 100644
--- a/src/cpu/CMakeLists.txt
+++ b/src/cpu/CMakeLists.txt
@@ -34,5 +34,5 @@ if(DYNAREC)
codegen_timing_winchip.c codegen_timing_winchip2.c)
endif()
-add_subdirectory(softfloat)
-target_link_libraries(86Box softfloat)
+add_subdirectory(softfloat3e)
+target_link_libraries(86Box softfloat3e)
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 900d3d7e1b..ae5b4692a5 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -21,7 +21,7 @@
#ifndef EMU_CPU_H
#define EMU_CPU_H
-#include "softfloat/softfloat.h"
+#include "softfloat3e/softfloat.h"
enum {
FPU_NONE,
@@ -592,8 +592,6 @@ extern uint32_t eip_msr;
extern uint64_t amd_efer;
extern uint64_t star;
-#define FPU_CW_Reserved_Bits (0xe0c0)
-
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2;
diff --git a/src/cpu/softfloat/CMakeLists.txt b/src/cpu/softfloat/CMakeLists.txt
deleted file mode 100644
index 9361571855..0000000000
--- a/src/cpu/softfloat/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# 86Box A hypervisor and IBM PC system emulator that specializes in
-# running old operating systems and software designed for IBM
-# PC systems and compatibles from 1981 through fairly recent
-# system designs based on the PCI bus.
-#
-# This file is part of the 86Box distribution.
-#
-# CMake build script.
-#
-# Authors: David Hrdlička,
-#
-# Copyright 2020-2021 David Hrdlička.
-#
-
-add_library(softfloat OBJECT f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc softfloat_poly.cc softfloat.cc softfloat16.cc
- softfloat-muladd.cc softfloat-round-pack.cc softfloat-specialize.cc softfloatx80.cc)
diff --git a/src/cpu/softfloat/config.h b/src/cpu/softfloat/config.h
deleted file mode 100644
index 9e39c2d29c..0000000000
--- a/src/cpu/softfloat/config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef EMU_SF_CONFIG_H
-#define EMU_SF_CONFIG_H
-
-#include
-
-typedef int8_t flag;
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint64_t uint64;
-typedef int64_t int64;
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines a type that holds integers
-| of _exactly_ the number of bits specified. For instance, for most
-| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
-| `unsigned short int' and `signed short int' (or `short int'), respectively.
-*----------------------------------------------------------------------------*/
-typedef uint8_t bits8;
-typedef int8_t sbits8;
-typedef uint16_t bits16;
-typedef int16_t sbits16;
-typedef uint32_t bits32;
-typedef int32_t sbits32;
-typedef uint64_t bits64;
-typedef int64_t sbits64;
-
-typedef uint8_t Bit8u;
-typedef int8_t Bit8s;
-typedef uint16_t Bit16u;
-typedef int16_t Bit16s;
-typedef uint32_t Bit32u;
-typedef int32_t Bit32s;
-typedef uint64_t Bit64u;
-typedef int64_t Bit64s;
-
-/*----------------------------------------------------------------------------
-| The `LIT64' macro takes as its argument a textual integer literal and
-| if necessary ``marks'' the literal as having a 64-bit integer type.
-| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
-| appended with the letters `LL' standing for `long long', which is `gcc's
-| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
-| defined as the identity macro: `#define LIT64( a ) a'.
-*----------------------------------------------------------------------------*/
-#define BX_CONST64(a) a##LL
-#define BX_CPP_INLINE static __inline
-
-#endif /*EMU_SF_CONFIG_H*/
diff --git a/src/cpu/softfloat/softfloat-compare.h b/src/cpu/softfloat/softfloat-compare.h
deleted file mode 100644
index 8b9821460b..0000000000
--- a/src/cpu/softfloat/softfloat-compare.h
+++ /dev/null
@@ -1,496 +0,0 @@
-/*============================================================================
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_COMPARE_H_
-#define _SOFTFLOAT_COMPARE_H_
-
-#include "softfloat.h"
-
-// ======= float32 ======= //
-
-typedef int (*float32_compare_method)(float32, float32, struct float_status_t *status);
-
-// 0x00
-BX_CPP_INLINE int float32_eq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x01
-BX_CPP_INLINE int float32_lt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x02
-BX_CPP_INLINE int float32_le_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x03
-BX_CPP_INLINE int float32_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x04
-BX_CPP_INLINE int float32_neq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x05
-BX_CPP_INLINE int float32_nlt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x06
-BX_CPP_INLINE int float32_nle_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x07
-BX_CPP_INLINE int float32_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x08
-BX_CPP_INLINE int float32_eq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x09
-BX_CPP_INLINE int float32_nge_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x0a
-BX_CPP_INLINE int float32_ngt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x0b
-BX_CPP_INLINE int float32_false_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_quiet(a, b, status);
- return 0;
-}
-
-// 0x0c
-BX_CPP_INLINE int float32_neq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x0d
-BX_CPP_INLINE int float32_ge_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x0e
-BX_CPP_INLINE int float32_gt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x0f
-BX_CPP_INLINE int float32_true_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_quiet(a, b, status);
- return 1;
-}
-
-// 0x10
-BX_CPP_INLINE int float32_eq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x11
-BX_CPP_INLINE int float32_lt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x12
-BX_CPP_INLINE int float32_le_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x13
-BX_CPP_INLINE int float32_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x14
-BX_CPP_INLINE int float32_neq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x15
-BX_CPP_INLINE int float32_nlt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x16
-BX_CPP_INLINE int float32_nle_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x17
-BX_CPP_INLINE int float32_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x18
-BX_CPP_INLINE int float32_eq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x19
-BX_CPP_INLINE int float32_nge_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x1a
-BX_CPP_INLINE int float32_ngt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x1b
-BX_CPP_INLINE int float32_false_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_two(a, b, status);
- return 0;
-}
-
-// 0x1c
-BX_CPP_INLINE int float32_neq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x1d
-BX_CPP_INLINE int float32_ge_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x1e
-BX_CPP_INLINE int float32_gt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x1f
-BX_CPP_INLINE int float32_true_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_two(a, b, status);
- return 1;
-}
-
-// ======= float64 ======= //
-
-typedef int (*float64_compare_method)(float64, float64, struct float_status_t *status);
-
-// 0x00
-BX_CPP_INLINE int float64_eq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x01
-BX_CPP_INLINE int float64_lt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x02
-BX_CPP_INLINE int float64_le_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x03
-BX_CPP_INLINE int float64_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x04
-BX_CPP_INLINE int float64_neq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x05
-BX_CPP_INLINE int float64_nlt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x06
-BX_CPP_INLINE int float64_nle_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x07
-BX_CPP_INLINE int float64_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x08
-BX_CPP_INLINE int float64_eq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x09
-BX_CPP_INLINE int float64_nge_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x0a
-BX_CPP_INLINE int float64_ngt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x0b
-BX_CPP_INLINE int float64_false_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_quiet(a, b, status);
- return 0;
-}
-
-// 0x0c
-BX_CPP_INLINE int float64_neq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x0d
-BX_CPP_INLINE int float64_ge_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x0e
-BX_CPP_INLINE int float64_gt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x0f
-BX_CPP_INLINE int float64_true_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_quiet(a, b, status);
- return 1;
-}
-
-// 0x10
-BX_CPP_INLINE int float64_eq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x11
-BX_CPP_INLINE int float64_lt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x12
-BX_CPP_INLINE int float64_le_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x13
-BX_CPP_INLINE int float64_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x14
-BX_CPP_INLINE int float64_neq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x15
-BX_CPP_INLINE int float64_nlt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x16
-BX_CPP_INLINE int float64_nle_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x17
-BX_CPP_INLINE int float64_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x18
-BX_CPP_INLINE int float64_eq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x19
-BX_CPP_INLINE int float64_nge_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x1a
-BX_CPP_INLINE int float64_ngt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x1b
-BX_CPP_INLINE int float64_false_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_two(a, b, status);
- return 0;
-}
-
-// 0x1c
-BX_CPP_INLINE int float64_neq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x1d
-BX_CPP_INLINE int float64_ge_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x1e
-BX_CPP_INLINE int float64_gt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x1f
-BX_CPP_INLINE int float64_true_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_two(a, b, status);
- return 1;
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-macros.h b/src/cpu/softfloat/softfloat-macros.h
deleted file mode 100644
index cb867bf5d1..0000000000
--- a/src/cpu/softfloat/softfloat-macros.h
+++ /dev/null
@@ -1,686 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_MACROS_H_
-#define _SOFTFLOAT_MACROS_H_
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 16, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16u shift16RightJamming(Bit16u a, int count)
-{
- Bit16u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 16) {
- z = (a>>count) | ((a<<((-count) & 15)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 32, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32u shift32RightJamming(Bit32u a, int count)
-{
- Bit32u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 32) {
- z = (a>>count) | ((a<<((-count) & 31)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 64, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u shift64RightJamming(Bit64u a, int count)
-{
- Bit64u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 64) {
- z = (a>>count) | ((a << ((-count) & 63)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
-| _plus_ the number of bits given in `count'. The shifted result is at most
-| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
-| bits shifted off form a second 64-bit result as follows: The _last_ bit
-| shifted off is the most-significant bit of the extra result, and the other
-| 63 bits of the extra result are all zero if and only if _all_but_the_last_
-| bits shifted off were all zero. This extra result is stored in the location
-| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0' and `a1' are considered to form
-| a fixed-point value with binary point between `a0' and `a1'. This fixed-
-| point value is shifted right by the number of bits given in `count', and
-| the integer part of the result is returned at the location pointed to by
-| `z0Ptr'. The fractional part of the result may be slightly corrupted as
-| described above, and is returned at the location pointed to by `z1Ptr'.)
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift64ExtraRightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count;
- }
- else {
- if (count == 64) {
- z1 = a0 | (a1 != 0);
- }
- else {
- z1 = ((a0 | a1) != 0);
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
-| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
-| any carry out is lost. The result is broken into two 64-bit pieces which
-| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void add128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z1 = a1 + b1;
- *z1Ptr = z1;
- *z0Ptr = a0 + b0 + (z1 < a1);
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
-| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
-| 2^128, so any borrow out (carry out) is lost. The result is broken into two
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
-| `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void
- sub128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- *z1Ptr = a1 - b1;
- *z0Ptr = a0 - b0 - (a1 < b1);
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
-| into two 64-bit pieces which are stored at the locations pointed to by
-| `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul64To128(Bit64u a, Bit64u b, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit32u aHigh, aLow, bHigh, bLow;
- Bit64u z0, zMiddleA, zMiddleB, z1;
-
- aLow = (Bit32u) a;
- aHigh = (Bit32u)(a>>32);
- bLow = (Bit32u) b;
- bHigh = (Bit32u)(b>>32);
- z1 = ((Bit64u) aLow) * bLow;
- zMiddleA = ((Bit64u) aLow) * bHigh;
- zMiddleB = ((Bit64u) aHigh) * bLow;
- z0 = ((Bit64u) aHigh) * bHigh;
- zMiddleA += zMiddleB;
- z0 += (((Bit64u) (zMiddleA < zMiddleB))<<32) + (zMiddleA>>32);
- zMiddleA <<= 32;
- z1 += zMiddleA;
- z0 += (z1 < zMiddleA);
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the 64-bit integer quotient obtained by dividing
-| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
-| divisor `b' must be at least 2^63. If q is the exact quotient truncated
-| toward zero, the approximation returned lies between q and q + 2 inclusive.
-| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
-| unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-#ifdef USE_estimateDiv128To64
-static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b)
-{
- Bit64u b0, b1;
- Bit64u rem0, rem1, term0, term1;
- Bit64u z;
-
- if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF);
- b0 = b>>32;
- z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32;
- mul64To128(b, z, &term0, &term1);
- sub128(a0, a1, term0, term1, &rem0, &rem1);
- while (((Bit64s) rem0) < 0) {
- z -= BX_CONST64(0x100000000);
- b1 = b<<32;
- add128(rem0, rem1, b0, b1, &rem0, &rem1);
- }
- rem0 = (rem0<<32) | (rem1>>32);
- z |= (b0<<32 <= rem0) ? 0xFFFFFFFF : rem0 / b0;
- return z;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the square root of the 32-bit significand given
-| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
-| `aExp' (the least significant bit) is 1, the integer returned approximates
-| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
-| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
-| case, the approximation returned lies strictly within +/-2 of the exact
-| value.
-*----------------------------------------------------------------------------*/
-
-#ifdef USE_estimateSqrt32
-static Bit32u estimateSqrt32(Bit16s aExp, Bit32u a)
-{
- static const Bit16u sqrtOddAdjustments[] = {
- 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
- 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
- };
- static const Bit16u sqrtEvenAdjustments[] = {
- 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
- 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
- };
- Bit32u z;
-
- int index = (a>>27) & 15;
- if (aExp & 1) {
- z = 0x4000 + (a>>17) - sqrtOddAdjustments[index];
- z = ((a / z)<<14) + (z<<15);
- a >>= 1;
- }
- else {
- z = 0x8000 + (a>>17) - sqrtEvenAdjustments[index];
- z = a / z + z;
- z = (0x20000 <= z) ? 0xFFFF8000 : (z<<15);
- if (z <= a) return (Bit32u) (((Bit32s) a)>>1);
- }
- return ((Bit32u) ((((Bit64u) a)<<31) / z)) + (z>>1);
-}
-#endif
-
-static const int countLeadingZeros8[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 16 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros16(Bit16u a)
-{
- int shiftCount = 0;
- if (a < 0x100) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZeros8[a>>8];
- return shiftCount;
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 32 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros32(Bit32u a)
-{
- int shiftCount = 0;
- if (a < 0x10000) {
- shiftCount += 16;
- a <<= 16;
- }
- if (a < 0x1000000) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZeros8[a>>24];
- return shiftCount;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 64 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros64(Bit64u a)
-{
- int shiftCount = 0;
- if (a < BX_CONST64(0x100000000)) {
- shiftCount += 32;
- }
- else {
- a >>= 32;
- }
- shiftCount += countLeadingZeros32((Bit32u)(a));
- return shiftCount;
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' can be arbitrarily large; in particular, if `count' is greater
-| than 128, the result will be 0. The result is broken into two 64-bit pieces
-| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128Right(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count);
- z0 = a0>>count;
- }
- else {
- z1 = (count < 128) ? (a0>>(count & 63)) : 0;
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. If any nonzero bits are shifted off, they
-| are ``jammed'' into the least significant bit of the result by setting the
-| least significant bit to 1. The value of `count' can be arbitrarily large;
-| in particular, if `count' is greater than 128, the result will be either
-| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
-| nonzero. The result is broken into two 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128RightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count) | ((a1<>count;
- }
- else {
- if (count == 64) {
- z1 = a0 | (a1 != 0);
- }
- else if (count < 128) {
- z1 = (a0>>(count & 63)) | (((a0<>((-count) & 63));
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
-| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
-| modulo 2^192, so any carry out is lost. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void add192(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- Bit64u b0,
- Bit64u b1,
- Bit64u b2,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- unsigned carry0, carry1;
-
- z2 = a2 + b2;
- carry1 = (z2 < a2);
- z1 = a1 + b1;
- carry0 = (z1 < a1);
- z0 = a0 + b0;
- z1 += carry1;
- z0 += (z1 < carry1);
- z0 += carry0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
-| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
-| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
-| result is broken into three 64-bit pieces which are stored at the locations
-| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void sub192(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- Bit64u b0,
- Bit64u b1,
- Bit64u b2,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- unsigned borrow0, borrow1;
-
- z2 = a2 - b2;
- borrow1 = (a2 < b2);
- z1 = a1 - b1;
- borrow0 = (a1 < b1);
- z0 = a0 - b0;
- z0 -= (z1 < borrow1);
- z1 -= borrow1;
- z0 -= borrow0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
-| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int eq128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 == b0) && (a1 == b1);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int le128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 < b0) || ((a0 == b0) && (a1 <= b1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
-| returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int lt128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 < b0) || ((a0 == b0) && (a1 < b1));
-}
-
-#endif /* FLOATX80 */
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
-| `b' to obtain a 192-bit product. The product is broken into three 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
-| `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul128By64To192(
- Bit64u a0,
- Bit64u a1,
- Bit64u b,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2, more1;
-
- mul64To128(a1, b, &z1, &z2);
- mul64To128(a0, b, &z0, &more1);
- add128(z0, more1, 0, z1, &z0, &z1);
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
-| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
-| product. The product is broken into four 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul128To256(
- Bit64u a0,
- Bit64u a1,
- Bit64u b0,
- Bit64u b1,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr,
- Bit64u *z3Ptr
-)
-{
- Bit64u z0, z1, z2, z3;
- Bit64u more1, more2;
-
- mul64To128(a1, b1, &z2, &z3);
- mul64To128(a1, b0, &z1, &more2);
- add128(z1, more2, 0, z2, &z1, &z2);
- mul64To128(a0, b0, &z0, &more1);
- add128(z0, more1, 0, z1, &z0, &z1);
- mul64To128(a0, b1, &more1, &more2);
- add128(more1, more2, 0, z2, &more1, &z2);
- add128(z0, z1, 0, more1, &z0, &z1);
- *z3Ptr = z3;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
-| by 64 _plus_ the number of bits given in `count'. The shifted result is
-| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
-| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
-| off form a third 64-bit result as follows: The _last_ bit shifted off is
-| the most-significant bit of the extra result, and the other 63 bits of the
-| extra result are all zero if and only if _all_but_the_last_ bits shifted off
-| were all zero. This extra result is stored in the location pointed to by
-| `z2Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0', `a1', and `a2' are considered
-| to form a fixed-point value with binary point between `a1' and `a2'. This
-| fixed-point value is shifted right by the number of bits given in `count',
-| and the integer part of the result is returned at the locations pointed to
-| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
-| corrupted as described above, and is returned at the location pointed to by
-| `z2Ptr'.)
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128ExtraRightJamming(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- int count,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z2 = a2;
- z1 = a1;
- z0 = a0;
- }
- else {
- if (count < 64) {
- z2 = a1<>count);
- z0 = a0>>count;
- }
- else {
- if (count == 64) {
- z2 = a1;
- z1 = a0;
- }
- else {
- a2 |= a1;
- if (count < 128) {
- z2 = a0<>(count & 63);
- }
- else {
- z2 = (count == 128) ? a0 : (a0 != 0);
- z1 = 0;
- }
- }
- z0 = 0;
- }
- z2 |= (a2 != 0);
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-muladd.cc b/src/cpu/softfloat/softfloat-muladd.cc
deleted file mode 100644
index 7c9fec70ed..0000000000
--- a/src/cpu/softfloat/softfloat-muladd.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * This code is based on QEMU patch by Peter Maydell
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes three single-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result. If any of `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-*----------------------------------------------------------------------------*/
-
-static float32 propagateFloat32MulAddNaN(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- int aIsNaN = float32_is_nan(a);
- int bIsNaN = float32_is_nan(b);
-
- int aIsSignalingNaN = float32_is_signaling_nan(a);
- int bIsSignalingNaN = float32_is_signaling_nan(b);
- int cIsSignalingNaN = float32_is_signaling_nan(c);
-
- a |= 0x00400000;
- b |= 0x00400000;
- c |= 0x00400000;
-
- if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN)
- float_raise(status, float_flag_invalid);
-
- // operate according to float_first_operand_nan mode
- if (aIsSignalingNaN | aIsNaN) {
- return a;
- }
- else {
- return (bIsSignalingNaN | bIsNaN) ? b : c;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes three double-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result. If any of `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-*----------------------------------------------------------------------------*/
-
-static float64 propagateFloat64MulAddNaN(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- int aIsNaN = float64_is_nan(a);
- int bIsNaN = float64_is_nan(b);
-
- int aIsSignalingNaN = float64_is_signaling_nan(a);
- int bIsSignalingNaN = float64_is_signaling_nan(b);
- int cIsSignalingNaN = float64_is_signaling_nan(c);
-
- a |= BX_CONST64(0x0008000000000000);
- b |= BX_CONST64(0x0008000000000000);
- c |= BX_CONST64(0x0008000000000000);
-
- if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN)
- float_raise(status, float_flag_invalid);
-
- // operate according to float_first_operand_nan mode
- if (aIsSignalingNaN | aIsNaN) {
- return a;
- }
- else {
- return (bIsSignalingNaN | bIsNaN) ? b : c;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b' then adding 'c', with no intermediate rounding step after the
-| multiplication. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic 754-2008.
-| The flags argument allows the caller to select negation of the
-| addend, the intermediate product, or the final result. (The difference
-| between this and having the caller do a separate negation is that negating
-| externally will flip the sign bit on NaNs.)
-*----------------------------------------------------------------------------*/
-
-float32 float32_muladd(float32 a, float32 b, float32 c, int flags, struct float_status_t *status)
-{
- int aSign, bSign, cSign, zSign;
- Bit16s aExp, bExp, cExp, pExp, zExp;
- Bit32u aSig, bSig, cSig;
- int pInf, pZero, pSign;
- Bit64u pSig64, cSig64, zSig64;
- Bit32u pSig;
- int shiftcount;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- cSig = extractFloat32Frac(c);
- cExp = extractFloat32Exp(c);
- cSign = extractFloat32Sign(c);
-
- /* It is implementation-defined whether the cases of (0,inf,qnan)
- * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
- * they return if they do), so we have to hand this information
- * off to the target-specific pick-a-NaN routine.
- */
- if (((aExp == 0xff) && aSig) ||
- ((bExp == 0xff) && bSig) ||
- ((cExp == 0xff) && cSig)) {
- return propagateFloat32MulAddNaN(a, b, c, status);
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- if (cExp == 0) cSig = 0;
- }
-
- int infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) ||
- (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0));
-
- if (infzero) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (flags & float_muladd_negate_c) {
- cSign ^= 1;
- }
-
- /* Work out the sign and type of the product */
- pSign = aSign ^ bSign;
- if (flags & float_muladd_negate_product) {
- pSign ^= 1;
- }
- pInf = (aExp == 0xff) || (bExp == 0xff);
- pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
-
- if (cExp == 0xff) {
- if (pInf && (pSign ^ cSign)) {
- /* addition of opposite-signed infinities => InvalidOperation */
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- /* Otherwise generate an infinity of the same sign */
- if ((aSig && aExp == 0) || (bSig && bExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat32(cSign, 0xff, 0);
- }
-
- if (pInf) {
- if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat32(pSign, 0xff, 0);
- }
-
- if (pZero) {
- if (cExp == 0) {
- if (cSig == 0) {
- /* Adding two exact zeroes */
- if (pSign == cSign) {
- zSign = pSign;
- } else if (get_float_rounding_mode(status) == float_round_down) {
- zSign = 1;
- } else {
- zSign = 0;
- }
- return packFloat32(zSign, 0, 0);
- }
- /* Exact zero plus a denormal */
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(cSign, 0, 0);
- }
- }
- /* Zero plus something non-zero */
- return packFloat32(cSign, cExp, cSig);
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
-
- /* Calculate the actual result a * b + c */
-
- /* Multiply first; this is easy. */
- /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f
- * because we want the true exponent, not the "one-less-than"
- * flavour that roundAndPackFloat32() takes.
- */
- pExp = aExp + bExp - 0x7e;
- aSig = (aSig | 0x00800000) << 7;
- bSig = (bSig | 0x00800000) << 8;
- pSig64 = (Bit64u)aSig * bSig;
- if ((Bit64s)(pSig64 << 1) >= 0) {
- pSig64 <<= 1;
- pExp--;
- }
-
- zSign = pSign;
-
- /* Now pSig64 is the significand of the multiply, with the explicit bit in
- * position 62.
- */
- if (cExp == 0) {
- if (!cSig) {
- /* Throw out the special case of c being an exact zero now */
- pSig = (Bit32u) shift64RightJamming(pSig64, 32);
- return roundAndPackFloat32(zSign, pExp - 1, pSig, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(cSig, &cExp, &cSig);
- }
-
- cSig64 = (Bit64u)cSig << 39;
- cSig64 |= BX_CONST64(0x4000000000000000);
- int expDiff = pExp - cExp;
-
- if (pSign == cSign) {
- /* Addition */
- if (expDiff > 0) {
- /* scale c to match p */
- cSig64 = shift64RightJamming(cSig64, expDiff);
- zExp = pExp;
- } else if (expDiff < 0) {
- /* scale p to match c */
- pSig64 = shift64RightJamming(pSig64, -expDiff);
- zExp = cExp;
- } else {
- /* no scaling needed */
- zExp = cExp;
- }
- /* Add significands and make sure explicit bit ends up in posn 62 */
- zSig64 = pSig64 + cSig64;
- if ((Bit64s)zSig64 < 0) {
- zSig64 = shift64RightJamming(zSig64, 1);
- } else {
- zExp--;
- }
- zSig64 = shift64RightJamming(zSig64, 32);
- return roundAndPackFloat32(zSign, zExp, zSig64, status);
- } else {
- /* Subtraction */
- if (expDiff > 0) {
- cSig64 = shift64RightJamming(cSig64, expDiff);
- zSig64 = pSig64 - cSig64;
- zExp = pExp;
- } else if (expDiff < 0) {
- pSig64 = shift64RightJamming(pSig64, -expDiff);
- zSig64 = cSig64 - pSig64;
- zExp = cExp;
- zSign ^= 1;
- } else {
- zExp = pExp;
- if (cSig64 < pSig64) {
- zSig64 = pSig64 - cSig64;
- } else if (pSig64 < cSig64) {
- zSig64 = cSig64 - pSig64;
- zSign ^= 1;
- } else {
- /* Exact zero */
- return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- }
- --zExp;
- /* Do the equivalent of normalizeRoundAndPackFloat32() but
- * starting with the significand in a Bit64u.
- */
- shiftcount = countLeadingZeros64(zSig64) - 1;
- zSig64 <<= shiftcount;
- zExp -= shiftcount;
- zSig64 = shift64RightJamming(zSig64, 32);
- return roundAndPackFloat32(zSign, zExp, zSig64, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b' then adding 'c', with no intermediate rounding step after the
-| multiplication. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic 754-2008.
-| The flags argument allows the caller to select negation of the
-| addend, the intermediate product, or the final result. (The difference
-| between this and having the caller do a separate negation is that negating
-| externally will flip the sign bit on NaNs.)
-*----------------------------------------------------------------------------*/
-
-float64 float64_muladd(float64 a, float64 b, float64 c, int flags, struct float_status_t *status)
-{
- int aSign, bSign, cSign, zSign;
- Bit16s aExp, bExp, cExp, pExp, zExp;
- Bit64u aSig, bSig, cSig;
- int pInf, pZero, pSign;
- Bit64u pSig0, pSig1, cSig0, cSig1, zSig0, zSig1;
- int shiftcount;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- cSig = extractFloat64Frac(c);
- cExp = extractFloat64Exp(c);
- cSign = extractFloat64Sign(c);
-
- /* It is implementation-defined whether the cases of (0,inf,qnan)
- * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
- * they return if they do), so we have to hand this information
- * off to the target-specific pick-a-NaN routine.
- */
- if (((aExp == 0x7ff) && aSig) ||
- ((bExp == 0x7ff) && bSig) ||
- ((cExp == 0x7ff) && cSig)) {
- return propagateFloat64MulAddNaN(a, b, c, status);
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- if (cExp == 0) cSig = 0;
- }
-
- int infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) ||
- (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0));
-
- if (infzero) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (flags & float_muladd_negate_c) {
- cSign ^= 1;
- }
-
- /* Work out the sign and type of the product */
- pSign = aSign ^ bSign;
- if (flags & float_muladd_negate_product) {
- pSign ^= 1;
- }
- pInf = (aExp == 0x7ff) || (bExp == 0x7ff);
- pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
-
- if (cExp == 0x7ff) {
- if (pInf && (pSign ^ cSign)) {
- /* addition of opposite-signed infinities => InvalidOperation */
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- /* Otherwise generate an infinity of the same sign */
- if ((aSig && aExp == 0) || (bSig && bExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat64(cSign, 0x7ff, 0);
- }
-
- if (pInf) {
- if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat64(pSign, 0x7ff, 0);
- }
-
- if (pZero) {
- if (cExp == 0) {
- if (cSig == 0) {
- /* Adding two exact zeroes */
- if (pSign == cSign) {
- zSign = pSign;
- } else if (get_float_rounding_mode(status) == float_round_down) {
- zSign = 1;
- } else {
- zSign = 0;
- }
- return packFloat64(zSign, 0, 0);
- }
- /* Exact zero plus a denormal */
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(cSign, 0, 0);
- }
- }
- /* Zero plus something non-zero */
- return packFloat64(cSign, cExp, cSig);
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
-
- /* Calculate the actual result a * b + c */
-
- /* Multiply first; this is easy. */
- /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff
- * because we want the true exponent, not the "one-less-than"
- * flavour that roundAndPackFloat64() takes.
- */
- pExp = aExp + bExp - 0x3fe;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- mul64To128(aSig, bSig, &pSig0, &pSig1);
- if ((Bit64s)(pSig0 << 1) >= 0) {
- shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1);
- pExp--;
- }
-
- zSign = pSign;
-
- /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit
- * bit in position 126.
- */
- if (cExp == 0) {
- if (!cSig) {
- /* Throw out the special case of c being an exact zero now */
- shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
- return roundAndPackFloat64(zSign, pExp - 1, pSig1, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(cSig, &cExp, &cSig);
- }
-
- cSig0 = cSig << 10;
- cSig1 = 0;
- cSig0 |= BX_CONST64(0x4000000000000000);
- int expDiff = pExp - cExp;
-
- if (pSign == cSign) {
- /* Addition */
- if (expDiff > 0) {
- /* scale c to match p */
- shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
- zExp = pExp;
- } else if (expDiff < 0) {
- /* scale p to match c */
- shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
- zExp = cExp;
- } else {
- /* no scaling needed */
- zExp = cExp;
- }
- /* Add significands and make sure explicit bit ends up in posn 126 */
- add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- if ((Bit64s)zSig0 < 0) {
- shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
- } else {
- zExp--;
- }
- shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
- return roundAndPackFloat64(zSign, zExp, zSig1, status);
- } else {
- /* Subtraction */
- if (expDiff > 0) {
- shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
- sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- zExp = pExp;
- } else if (expDiff < 0) {
- shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
- sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
- zExp = cExp;
- zSign ^= 1;
- } else {
- zExp = pExp;
- if (lt128(cSig0, cSig1, pSig0, pSig1)) {
- sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- } else if (lt128(pSig0, pSig1, cSig0, cSig1)) {
- sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
- zSign ^= 1;
- } else {
- /* Exact zero */
- return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- }
- --zExp;
- /* Do the equivalent of normalizeRoundAndPackFloat64() but
- * starting with the significand in a pair of Bit64u.
- */
- if (zSig0) {
- shiftcount = countLeadingZeros64(zSig0) - 1;
- shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1);
- if (zSig1) {
- zSig0 |= 1;
- }
- zExp -= shiftcount;
- } else {
- shiftcount = countLeadingZeros64(zSig1) - 1;
- zSig0 = zSig1 << shiftcount;
- zExp -= (shiftcount + 64);
- }
- return roundAndPackFloat64(zSign, zExp, zSig0, status);
- }
-}
diff --git a/src/cpu/softfloat/softfloat-round-pack.cc b/src/cpu/softfloat/softfloat-round-pack.cc
deleted file mode 100644
index 2b3965840c..0000000000
--- a/src/cpu/softfloat/softfloat-round-pack.cc
+++ /dev/null
@@ -1,896 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s roundAndPackInt32(int zSign, Bit64u exactAbsZ, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int roundIncrement = 0x40;
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) roundIncrement = 0;
- else {
- roundIncrement = 0x7F;
- if (zSign) {
- if (roundingMode == float_round_up) roundIncrement = 0;
- }
- else {
- if (roundingMode == float_round_down) roundIncrement = 0;
- }
- }
- }
- int roundBits = (int)(exactAbsZ & 0x7F);
- Bit64u absZ = (exactAbsZ + roundIncrement)>>7;
- absZ &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
- Bit32s z = (Bit32s) absZ;
- if (zSign) z = -z;
- if ((absZ>>32) || (z && ((z < 0) ^ zSign))) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((absZ << 7) > exactAbsZ)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status)
-{
- Bit64s z;
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int increment = ((Bit64s) absZ1 < 0);
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) increment = 0;
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && absZ1;
- }
- else {
- increment = (roundingMode == float_round_up) && absZ1;
- }
- }
- }
- Bit64u exactAbsZ0 = absZ0;
- if (increment) {
- ++absZ0;
- if (absZ0 == 0) goto overflow;
- absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
- }
- z = absZ0;
- if (zSign) z = -z;
- if (z && ((z < 0) ^ zSign)) {
- overflow:
- float_raise(status, float_flag_invalid);
- return (Bit64s)(int64_indefinite);
- }
- if (absZ1) {
- float_raise(status, float_flag_inexact);
- if (absZ0 > exactAbsZ0)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit unsigned integer corresponding to the
-| input. Ordinarily, the fixed-point input is simply rounded to an integer,
-| with the inexact exception raised if the input cannot be represented exactly
-| as an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int increment = ((Bit64s) absZ1 < 0);
- if (!roundNearestEven) {
- if (roundingMode == float_round_to_zero) {
- increment = 0;
- } else if (absZ1) {
- if (zSign) {
- increment = (roundingMode == float_round_down) && absZ1;
- } else {
- increment = (roundingMode == float_round_up) && absZ1;
- }
- }
- }
- if (increment) {
- ++absZ0;
- if (absZ0 == 0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
- absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
- }
-
- if (zSign && absZ0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (absZ1) {
- float_raise(status, float_flag_inexact);
- }
- return absZ0;
-}
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal half-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr)
-{
- int shiftCount = countLeadingZeros16(aSig) - 5;
- *zSigPtr = aSig<> 4;
- zSigRound &= ~(((roundBits ^ 0x10) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- return packFloat16(zSign, zExp, zSigRound);
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr)
-{
- int shiftCount = countLeadingZeros32(aSig) - 8;
- *zSigPtr = aSig<> 7;
- zSigRound &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((zSigRound << 7) > zSig) set_float_rounding_up(status);
- }
- return packFloat32(zSign, zExp, zSigRound);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status)
-{
- int shiftCount = countLeadingZeros32(zSig) - 1;
- return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<>10;
- zSigRound &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((zSigRound << 10) > zSig) set_float_rounding_up(status);
- }
- return packFloat64(zSign, zExp, zSigRound);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status)
-{
- int shiftCount = countLeadingZeros64(zSig) - 1;
- return roundAndPackFloat64(zSign, zExp - shiftCount, zSig< zSigExact) set_float_rounding_up(status);
- }
- return packFloatx80(zSign, zExp, zSig0);
- }
- }
- if (roundBits) float_raise(status, float_flag_inexact);
- zSigExact = zSig0;
- zSig0 += roundIncrement;
- if (zSig0 < roundIncrement) {
- // Basically scale by shifting right and keep overflow
- ++zExp;
- zSig0 = BX_CONST64(0x8000000000000000);
- zSigExact >>= 1; // must scale also, or else later tests will fail
- }
- roundIncrement = roundMask + 1;
- if (roundNearestEven && (roundBits<<1 == roundIncrement))
- roundMask |= roundIncrement;
- zSig0 &= ~roundMask;
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- if (zSig0 == 0) zExp = 0;
- return packFloatx80(zSign, zExp, zSig0);
- precision80:
- increment = ((Bit64s) zSig1 < 0);
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) increment = 0;
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && zSig1;
- }
- else {
- increment = (roundingMode == float_round_up) && zSig1;
- }
- }
- }
- if (0x7FFD <= (Bit32u) (zExp - 1)) {
- if ((0x7FFE < zExp)
- || ((zExp == 0x7FFE)
- && (zSig0 == BX_CONST64(0xFFFFFFFFFFFFFFFF))
- && increment))
- {
- roundMask = 0;
- overflow:
- float_raise(status, float_flag_overflow | float_flag_inexact);
- if ((roundingMode == float_round_to_zero)
- || (zSign && (roundingMode == float_round_up))
- || (! zSign && (roundingMode == float_round_down)))
- {
- return packFloatx80(zSign, 0x7FFE, ~roundMask);
- }
- set_float_rounding_up(status);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (zExp <= 0) {
- int isTiny = (zExp < 0) || (! increment)
- || (zSig0 < BX_CONST64(0xFFFFFFFFFFFFFFFF));
- shift64ExtraRightJamming(zSig0, zSig1, 1 - zExp, &zSig0, &zSig1);
- zExp = 0;
- if (isTiny) {
- if (zSig1 || (zSig0 && !float_exception_masked(status, float_flag_underflow)))
- float_raise(status, float_flag_underflow);
- }
- if (zSig1) float_raise(status, float_flag_inexact);
- if (roundNearestEven) increment = ((Bit64s) zSig1 < 0);
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && zSig1;
- } else {
- increment = (roundingMode == float_round_up) && zSig1;
- }
- }
- if (increment) {
- zSigExact = zSig0++;
- zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven);
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- if ((Bit64s) zSig0 < 0) zExp = 1;
- }
- return packFloatx80(zSign, zExp, zSig0);
- }
- }
- if (zSig1) float_raise(status, float_flag_inexact);
- if (increment) {
- zSigExact = zSig0++;
- if (zSig0 == 0) {
- zExp++;
- zSig0 = BX_CONST64(0x8000000000000000);
- zSigExact >>= 1; // must scale also, or else later tests will fail
- }
- else {
- zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven);
- }
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- }
- else {
- if (zSig0 == 0) zExp = 0;
- }
- return packFloatx80(zSign, zExp, zSig0);
-}
-
-floatx80 roundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- struct float_status_t *round_status = status;
- floatx80 result = SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status);
-
- // bias unmasked undeflow
- if (status->float_exception_flags & ~status->float_exception_masks & float_flag_underflow) {
- float_raise(round_status, float_flag_underflow);
- return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp + 0x6000, zSig0, zSig1, status = round_status);
- }
-
- // bias unmasked overflow
- if (status->float_exception_flags & ~status->float_exception_masks & float_flag_overflow) {
- float_raise(round_status, float_flag_overflow);
- return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp - 0x6000, zSig0, zSig1, status = round_status);
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- if (zSig0 == 0) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- int shiftCount = countLeadingZeros64(zSig0);
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- zExp -= shiftCount;
- return
- roundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status);
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat128Subnormal(
- Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr)
-{
- int shiftCount;
-
- if (aSig0 == 0) {
- shiftCount = countLeadingZeros64(aSig1) - 15;
- if (shiftCount < 0) {
- *zSig0Ptr = aSig1 >>(-shiftCount);
- *zSig1Ptr = aSig1 << (shiftCount & 63);
- }
- else {
- *zSig0Ptr = aSig1 << shiftCount;
- *zSig1Ptr = 0;
- }
- *zExpPtr = - shiftCount - 63;
- }
- else {
- shiftCount = countLeadingZeros64(aSig0) - 15;
- shortShift128Left(aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr);
- *zExpPtr = 1 - shiftCount;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 roundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status)
-{
- int increment = ((Bit64s) zSig2 < 0);
- if (0x7FFD <= (Bit32u) zExp) {
- if ((0x7FFD < zExp)
- || ((zExp == 0x7FFD)
- && eq128(BX_CONST64(0x0001FFFFFFFFFFFF),
- BX_CONST64(0xFFFFFFFFFFFFFFFF), zSig0, zSig1)
- && increment))
- {
- float_raise(status, float_flag_overflow | float_flag_inexact);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (zExp < 0) {
- int isTiny = (zExp < -1)
- || ! increment
- || lt128(zSig0, zSig1,
- BX_CONST64(0x0001FFFFFFFFFFFF),
- BX_CONST64(0xFFFFFFFFFFFFFFFF));
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, -zExp, &zSig0, &zSig1, &zSig2);
- zExp = 0;
- if (isTiny && zSig2) float_raise(status, float_flag_underflow);
- increment = ((Bit64s) zSig2 < 0);
- }
- }
- if (zSig2) float_raise(status, float_flag_inexact);
- if (increment) {
- add128(zSig0, zSig1, 0, 1, &zSig0, &zSig1);
- zSig1 &= ~((zSig2 + zSig2 == 0) & 1);
- }
- else {
- if ((zSig0 | zSig1) == 0) zExp = 0;
- }
- return packFloat128Four(zSign, zExp, zSig0, zSig1);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-float128 normalizeRoundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- Bit64u zSig2;
-
- if (zSig0 == 0) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- int shiftCount = countLeadingZeros64(zSig0) - 15;
- if (0 <= shiftCount) {
- zSig2 = 0;
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- }
- else {
- shift128ExtraRightJamming(
- zSig0, zSig1, 0, -shiftCount, &zSig0, &zSig1, &zSig2);
- }
- zExp -= shiftCount;
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-round-pack.h b/src/cpu/softfloat/softfloat-round-pack.h
deleted file mode 100644
index 1422aaea60..0000000000
--- a/src/cpu/softfloat/softfloat-round-pack.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_ROUND_PACK_H_
-#define _SOFTFLOAT_ROUND_PACK_H_
-
-#include "softfloat.h"
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s roundAndPackInt32(int zSign, Bit64u absZ, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit unsigned integer corresponding to the
-| input. Ordinarily, the fixed-point input is simply rounded to an integer,
-| with the inexact exception raised if the input cannot be represented exactly
-| as an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status);
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal half-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper half-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the half-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 14
-| and 13, which is 4 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float16 roundAndPackFloat16(int zSign, Bit16s zExp, Bit16u zSig, struct float_status_t *status);
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the single-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 30
-| and 29, which is 7 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 roundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal double-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat64Subnormal(Bit64u aSig, Bit16s *zExpPtr, Bit64u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the double-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded
-| to a subnormal number, and the underflow and inexact exceptions are raised
-| if the abstract input cannot be represented exactly as a subnormal double-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 62
-| and 61, which is 10 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 roundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status);
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal extended double-precision floating-point value
-| represented by the denormalized significand `aSig'. The normalized exponent
-| and significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloatx80Subnormal(Bit64u aSig, Bit32s *zExpPtr, Bit64u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| rounded and packed into the extended double-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal extended
-| double-precision floating-point number.
-| If `roundingPrecision' is 32 or 64, the result is rounded to the same
-| number of bits as single or double precision, respectively. Otherwise, the
-| result is rounded to the full precision of the extended double-precision
-| format.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. The
-| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 roundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-#endif // FLOATX80
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat128Subnormal(
- Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 roundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-float128 normalizeRoundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-#endif // FLOAT128
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-specialize.cc b/src/cpu/softfloat/softfloat-specialize.cc
deleted file mode 100644
index bf0d111446..0000000000
--- a/src/cpu/softfloat/softfloat-specialize.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status)
-{
- int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float32_is_nan(a);
- aIsSignalingNaN = float32_is_signaling_nan(a);
- bIsNaN = float32_is_nan(b);
- bIsSignalingNaN = float32_is_signaling_nan(b);
- a |= 0x00400000;
- b |= 0x00400000;
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (get_float_nan_handling_mode(status) == float_larger_significand_nan) {
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) return a;
- returnLargerSignificand:
- if ((Bit32u) (a<<1) < (Bit32u) (b<<1)) return b;
- if ((Bit32u) (b<<1) < (Bit32u) (a<<1)) return a;
- return (a < b) ? a : b;
- }
- else {
- return b;
- }
- } else {
- return (aIsSignalingNaN | aIsNaN) ? a : b;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status)
-{
- int aIsNaN = float64_is_nan(a);
- int aIsSignalingNaN = float64_is_signaling_nan(a);
- int bIsNaN = float64_is_nan(b);
- int bIsSignalingNaN = float64_is_signaling_nan(b);
- a |= BX_CONST64(0x0008000000000000);
- b |= BX_CONST64(0x0008000000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (get_float_nan_handling_mode(status) == float_larger_significand_nan) {
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) return a;
- returnLargerSignificand:
- if ((Bit64u) (a<<1) < (Bit64u) (b<<1)) return b;
- if ((Bit64u) (b<<1) < (Bit64u) (a<<1)) return a;
- return (a < b) ? a : b;
- }
- else {
- return b;
- }
- } else {
- return (aIsSignalingNaN | aIsNaN) ? a : b;
- }
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aIsNaN = floatx80_is_nan(a);
- int aIsSignalingNaN = floatx80_is_signaling_nan(a);
- int bIsNaN = floatx80_is_nan(b);
- int bIsSignalingNaN = floatx80_is_signaling_nan(b);
- a.fraction |= BX_CONST64(0xC000000000000000);
- b.fraction |= BX_CONST64(0xC000000000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) 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 {
- return b;
- }
-}
-
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status)
-{
- int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
- aIsNaN = float128_is_nan(a);
- aIsSignalingNaN = float128_is_signaling_nan(a);
- bIsNaN = float128_is_nan(b);
- bIsSignalingNaN = float128_is_signaling_nan(b);
- a.hi |= BX_CONST64(0x0000800000000000);
- b.hi |= BX_CONST64(0x0000800000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | !bIsNaN) return a;
- returnLargerSignificand:
- if (lt128(a.hi<<1, a.lo, b.hi<<1, b.lo)) return b;
- if (lt128(b.hi<<1, b.lo, a.hi<<1, a.lo)) return a;
- return (a.hi < b.hi) ? a : b;
- }
- else {
- return b;
- }
-}
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
-*----------------------------------------------------------------------------*/
-const float128 float128_default_nan =
- packFloat128(float128_default_nan_hi, float128_default_nan_lo);
-
-#endif /* FLOAT128 */
diff --git a/src/cpu/softfloat/softfloat-specialize.h b/src/cpu/softfloat/softfloat-specialize.h
deleted file mode 100644
index 302ce53e43..0000000000
--- a/src/cpu/softfloat/softfloat-specialize.h
+++ /dev/null
@@ -1,789 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#ifndef _SOFTFLOAT_SPECIALIZE_H_
-#define _SOFTFLOAT_SPECIALIZE_H_
-
-#include "softfloat.h"
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#define int16_indefinite ((Bit16s)0x8000)
-#define int32_indefinite ((Bit32s)0x80000000)
-#define int64_indefinite BX_CONST64(0x8000000000000000)
-
-#define uint16_indefinite (0xffff)
-#define uint32_indefinite (0xffffffff)
-#define uint64_indefinite BX_CONST64(0xffffffffffffffff)
-
-/*----------------------------------------------------------------------------
-| Internal canonical NaN format.
-*----------------------------------------------------------------------------*/
-
-typedef struct {
- int sign;
- Bit64u hi, lo;
-} commonNaNT;
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated half-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float16 float16_default_nan;
-
-#define float16_fraction extractFloat16Frac
-#define float16_exp extractFloat16Exp
-#define float16_sign extractFloat16Sign
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16u extractFloat16Frac(float16 a)
-{
- return a & 0x3FF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat16Exp(float16 a)
-{
- return (a>>10) & 0x1F;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat16Sign(float16 a)
-{
- return a>>15;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 packFloat16(int zSign, int zExp, Bit16u zSig)
-{
- return (((Bit16u) zSign)<<15) + (((Bit16u) zExp)<<10) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_nan(float16 a)
-{
- return (0xF800 < (Bit16u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_signaling_nan(float16 a)
-{
- return (((a>>9) & 0x3F) == 0x3E) && (a & 0x1FF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_denormal(float16 a)
-{
- return (extractFloat16Exp(a) == 0) && (extractFloat16Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float16 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 float16_denormal_to_zero(float16 a)
-{
- if (float16_is_denormal(a)) a &= 0x8000;
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the half-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float16ToCommonNaN(float16 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float16_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a>>15;
- z.lo = 0;
- z.hi = ((Bit64u) a)<<54;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the half-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 commonNaNToFloat16(commonNaNT a)
-{
- return (((Bit16u) a.sign)<<15) | 0x7E00 | (Bit16u)(a.hi>>54);
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-extern const float32 float32_negative_inf;
-extern const float32 float32_positive_inf;
-extern const float32 float32_negative_zero;
-extern const float32 float32_positive_zero;
-extern const float32 float32_negative_one;
-extern const float32 float32_positive_one;
-extern const float32 float32_max_float;
-extern const float32 float32_min_float;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float32 float32_default_nan;
-
-#define float32_fraction extractFloat32Frac
-#define float32_exp extractFloat32Exp
-#define float32_sign extractFloat32Sign
-
-#define FLOAT32_EXP_BIAS 0x7F
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32u extractFloat32Frac(float32 a)
-{
- return a & 0x007FFFFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat32Exp(float32 a)
-{
- return (a>>23) & 0xFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat32Sign(float32 a)
-{
- return a>>31;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 packFloat32(int zSign, Bit16s zExp, Bit32u zSig)
-{
- return (((Bit32u) zSign)<<31) + (((Bit32u) zExp)<<23) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_nan(float32 a)
-{
- return (0xFF000000 < (Bit32u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_signaling_nan(float32 a)
-{
- return (((a>>22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_denormal(float32 a)
-{
- return (extractFloat32Exp(a) == 0) && (extractFloat32Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float32 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 float32_denormal_to_zero(float32 a)
-{
- if (float32_is_denormal(a)) a &= 0x80000000;
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float32ToCommonNaN(float32 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float32_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a>>31;
- z.lo = 0;
- z.hi = ((Bit64u) a)<<41;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the single-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 commonNaNToFloat32(commonNaNT a)
-{
- return (((Bit32u) a.sign)<<31) | 0x7FC00000 | (Bit32u)(a.hi>>41);
-}
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes single-precision floating-point NaN `a' and returns the appropriate
-| NaN result. If `a' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 propagateFloat32NaNOne(float32 a, struct float_status_t *status)
-{
- if (float32_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- return a | 0x00400000;
-}
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-extern const float64 float64_negative_inf;
-extern const float64 float64_positive_inf;
-extern const float64 float64_negative_zero;
-extern const float64 float64_positive_zero;
-extern const float64 float64_negative_one;
-extern const float64 float64_positive_one;
-extern const float64 float64_max_float;
-extern const float64 float64_min_float;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float64 float64_default_nan;
-
-#define float64_fraction extractFloat64Frac
-#define float64_exp extractFloat64Exp
-#define float64_sign extractFloat64Sign
-
-#define FLOAT64_EXP_BIAS 0x3FF
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat64Frac(float64 a)
-{
- return a & BX_CONST64(0x000FFFFFFFFFFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat64Exp(float64 a)
-{
- return (Bit16s)(a>>52) & 0x7FF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat64Sign(float64 a)
-{
- return (int)(a>>63);
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| double-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 packFloat64(int zSign, Bit16s zExp, Bit64u zSig)
-{
- return (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<52) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_nan(float64 a)
-{
- return (BX_CONST64(0xFFE0000000000000) < (Bit64u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_signaling_nan(float64 a)
-{
- return (((a>>51) & 0xFFF) == 0xFFE) && (a & BX_CONST64(0x0007FFFFFFFFFFFF));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_denormal(float64 a)
-{
- return (extractFloat64Exp(a) == 0) && (extractFloat64Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float64 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 float64_denormal_to_zero(float64 a)
-{
- if (float64_is_denormal(a)) a &= ((Bit64u)(1) << 63);
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float64ToCommonNaN(float64 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float64_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = (int)(a>>63);
- z.lo = 0;
- z.hi = a<<12;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the double-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 commonNaNToFloat64(commonNaNT a)
-{
- return (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FF8000000000000) | (a.hi>>12);
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes double-precision floating-point NaN `a' and returns the appropriate
-| NaN result. If `a' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 propagateFloat64NaNOne(float64 a, struct float_status_t *status)
-{
- if (float64_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- return a | BX_CONST64(0x0008000000000000);
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN. The
-| `high' and `low' values hold the most- and least-significant bits,
-| respectively.
-*----------------------------------------------------------------------------*/
-#define floatx80_default_nan_exp 0xFFFF
-#define floatx80_default_nan_fraction BX_CONST64(0xC000000000000000)
-
-#define floatx80_fraction extractFloatx80Frac
-#define floatx80_exp extractFloatx80Exp
-#define floatx80_sign extractFloatx80Sign
-
-#define FLOATX80_EXP_BIAS 0x3FFF
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloatx80Frac(floatx80 a)
-{
- return a.fraction;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32s extractFloatx80Exp(floatx80 a)
-{
- return a.exp & 0x7FFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloatx80Sign(floatx80 a)
-{
- return a.exp>>15;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
-| extended double-precision floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 packFloatx80(int zSign, Bit32s zExp, Bit64u zSig)
-{
- floatx80 z;
- z.fraction = zSig;
- z.exp = (zSign << 15) + zExp;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_nan(floatx80 a)
-{
- // return ((a.exp & 0x7FFF) == 0x7FFF) && (Bit64s) (a.fraction<<1);
- return ((a.exp & 0x7FFF) == 0x7FFF) && (((Bit64s) (a.fraction<<1)) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_signaling_nan(floatx80 a)
-{
- Bit64u aLow = a.fraction & ~BX_CONST64(0x4000000000000000);
- return ((a.exp & 0x7FFF) == 0x7FFF) &&
- ((Bit64u) (aLow<<1)) && (a.fraction == aLow);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is an
-| unsupported; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_unsupported(floatx80 a)
-{
- return ((a.exp & 0x7FFF) && !(a.fraction & BX_CONST64(0x8000000000000000)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
-| invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT floatx80ToCommonNaN(floatx80 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (floatx80_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a.exp >> 15;
- z.lo = 0;
- z.hi = a.fraction << 1;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the extended
-| double-precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 commonNaNToFloatx80(commonNaNT a)
-{
- floatx80 z;
- z.fraction = BX_CONST64(0xC000000000000000) | (a.hi>>1);
- z.exp = (((Bit16u) a.sign)<<15) | 0x7FFF;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes extended double-precision floating-point NaN `a' and returns the
-| appropriate NaN result. If `a' is a signaling NaN, the invalid exception
-| is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 propagateFloatx80NaNOne(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- a.fraction |= BX_CONST64(0xC000000000000000);
-
- return a;
-}
-
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN. The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
-*----------------------------------------------------------------------------*/
-#define float128_default_nan_hi BX_CONST64(0xFFFF800000000000)
-#define float128_default_nan_lo BX_CONST64(0x0000000000000000)
-
-#define float128_exp extractFloat128Exp
-
-/*----------------------------------------------------------------------------
-| Returns the least-significant 64 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat128Frac1(float128 a)
-{
- return a.lo;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the most-significant 48 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat128Frac0(float128 a)
-{
- return a.hi & BX_CONST64(0x0000FFFFFFFFFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the quadruple-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32s extractFloat128Exp(float128 a)
-{
- return ((Bit32s)(a.hi>>48)) & 0x7FFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the quadruple-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat128Sign(float128 a)
-{
- return (int)(a.hi >> 63);
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', the exponent `zExp', and the significand formed
-| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
-| floating-point value, returning the result. After being shifted into the
-| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
-| added together to form the most significant 32 bits of the result. This
-| means that any integer portion of `zSig0' will be added into the exponent.
-| Since a properly normalized significand will have an integer portion equal
-| to 1, the `zExp' input should be 1 less than the desired result exponent
-| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 packFloat128Four(int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1)
-{
- float128 z;
- z.lo = zSig1;
- z.hi = (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<48) + zSig0;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Packs two 64-bit precision integers into into the quadruple-precision
-| floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 packFloat128(Bit64u zHi, Bit64u zLo)
-{
- float128 z;
- z.lo = zLo;
- z.hi = zHi;
- return z;
-}
-
-#ifdef _MSC_VER
-#define PACK_FLOAT_128(hi,lo) { lo, hi }
-#else
-#define PACK_FLOAT_128(hi,lo) packFloat128(BX_CONST64(hi),BX_CONST64(lo))
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float128_is_nan(float128 a)
-{
- return (BX_CONST64(0xFFFE000000000000) <= (Bit64u) (a.hi<<1))
- && (a.lo || (a.hi & BX_CONST64(0x0000FFFFFFFFFFFF)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float128_is_signaling_nan(float128 a)
-{
- return (((a.hi>>47) & 0xFFFF) == 0xFFFE)
- && (a.lo || (a.hi & BX_CONST64(0x00007FFFFFFFFFFF)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float128ToCommonNaN(float128 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float128_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = (int)(a.hi>>63);
- shortShift128Left(a.hi, a.lo, 16, &z.hi, &z.lo);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the quadruple-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 commonNaNToFloat128(commonNaNT a)
-{
- float128 z;
- shift128Right(a.hi, a.lo, 16, &z.hi, &z.lo);
- z.hi |= (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FFF800000000000);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float128 float128_default_nan;
-
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat.cc b/src/cpu/softfloat/softfloat.cc
deleted file mode 100644
index 0802089b90..0000000000
--- a/src/cpu/softfloat/softfloat.cc
+++ /dev/null
@@ -1,4012 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#define USE_estimateDiv128To64
-#define USE_estimateSqrt32
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-const unsigned float_all_exceptions_mask = 0x3f;
-
-float32 int32_to_float32(Bit32s a, struct float_status_t *status)
-{
- if (a == 0) return 0;
- if (a == (Bit32s) 0x80000000) return packFloat32(1, 0x9E, 0);
- int zSign = (a < 0);
- return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int32_to_float64(Bit32s a)
-{
- if (a == 0) return 0;
- int zSign = (a < 0);
- Bit32u absA = zSign ? -a : a;
- int shiftCount = countLeadingZeros32(absA) + 21;
- Bit64u zSig = absA;
- return packFloat64(zSign, 0x432 - shiftCount, zSig<> 1, status);
- return normalizeRoundAndPackFloat32(0, 0x9C, a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit unsigned integer `a' to the
-| double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 uint32_to_float64(Bit32u a)
-{
- if (a == 0) return 0;
- int shiftCount = countLeadingZeros32(a) + 21;
- Bit64u zSig = a;
- return packFloat64(0, 0x432 - shiftCount, zSig<> 1, status);
- return normalizeRoundAndPackFloat64(0, 0x43C, a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float32_to_int32(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
- if ((aExp == 0xFF) && aSig) aSign = 0;
- if (aExp) aSig |= 0x00800000;
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- int shiftCount = 0xAF - aExp;
- Bit64u aSig64 = Bit64u(aSig) << 32;
- if (0 < shiftCount) aSig64 = shift64RightJamming(aSig64, shiftCount);
- return roundAndPackInt32(aSign, aSig64, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float32_to_int32_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit32s z;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0x9E;
- if (0 <= shiftCount) {
- if (a != 0xCF000000) {
- float_raise(status, float_flag_invalid);
- }
- return (Bit32s)(int32_indefinite);
- }
- else if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig = (aSig | 0x800000)<<8;
- z = aSig>>(-shiftCount);
- if ((Bit32u) (aSig<<(shiftCount & 31))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or conversion overflows, the largest positive integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float32_to_uint32_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0x9E;
-
- if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- else if (0 < shiftCount || aSign) {
- float_raise(status, float_flag_invalid);
- return uint32_indefinite;
- }
-
- aSig = (aSig | 0x800000)<<8;
- Bit32u z = aSig >> (-shiftCount);
- if (aSig << (shiftCount & 31)) {
- float_raise(status, float_flag_inexact);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s float32_to_int64(float32 a, struct float_status_t *status)
-{
- Bit64u aSig64, aSigExtra;
-
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- int shiftCount = 0xBE - aExp;
- if (shiftCount < 0) {
- float_raise(status, float_flag_invalid);
- return (Bit64s)(int64_indefinite);
- }
- if (aExp) aSig |= 0x00800000;
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
- return roundAndPackInt64(aSign, aSig64, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s float32_to_int64_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit64u aSig64;
- Bit64s z;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0xBE;
- if (0 <= shiftCount) {
- if (a != 0xDF000000) {
- float_raise(status, float_flag_invalid);
- }
- return (Bit64s)(int64_indefinite);
- }
- else if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- z = aSig64>>(-shiftCount);
- if ((Bit64u) (aSig64<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or the conversion overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float32_to_uint64_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit64u aSig64;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0xBE;
-
- if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- else if (0 < shiftCount || aSign) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- Bit64u z = aSig64>>(-shiftCount);
- if ((Bit64u) (aSig64<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float32_to_uint64(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, shiftCount;
- Bit32u aSig;
- Bit64u aSig64, aSigExtra;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if ((aSign) && (aExp > 0x7E)) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- shiftCount = 0xBE - aExp;
- if (aExp) aSig |= 0x00800000;
-
- if (shiftCount < 0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
- return roundAndPackUint64(aSign, aSig64, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float32_to_uint32(float32 a, struct float_status_t *status)
-{
- Bit64u val_64 = float32_to_uint64(a, status);
-
- if (val_64 > 0xffffffff) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return uint32_indefinite;
- }
-
- return (Bit32u) val_64;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float32_to_float64(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return commonNaNToFloat64(float32ToCommonNaN(a, status));
- return packFloat64(aSign, 0x7FF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat64(aSign, 0, 0);
-
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- --aExp;
- }
- return packFloat64(aSign, aExp + 0x380, ((Bit64u) aSig)<<29);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the single-precision floating-point value `a' to an integer, and
-| returns the result as a single-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_round_to_int(float32 a, Bit8u scale, struct float_status_t *status)
-{
- Bit32u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- Bit16s aExp = extractFloat32Exp(a);
- scale &= 0xf;
-
- if ((aExp == 0xFF) && extractFloat32Frac(a)) {
- return propagateFloat32NaNOne(a, status);
- }
-
- aExp += scale; // scale the exponent
-
- if (0x96 <= aExp) {
- return a;
- }
-
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- }
-
- if (aExp <= 0x7E) {
- if ((Bit32u) (a<<1) == 0) return a;
- float_raise(status, float_flag_inexact);
- int aSign = extractFloat32Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x7E) && extractFloat32Frac(a)) {
- return packFloat32(aSign, 0x7F - scale, 0);
- }
- break;
- case float_round_down:
- return aSign ? packFloat32(1, 0x7F - scale, 0) : float32_positive_zero;
- case float_round_up:
- return aSign ? float32_negative_zero : packFloat32(0, 0x7F - scale, 0);
- }
- return packFloat32(aSign, 0, 0);
- }
-
- lastBitMask = 1;
- lastBitMask <<= 0x96 - aExp;
- roundBitsMask = lastBitMask - 1;
- float32 z = a;
- if (roundingMode == float_round_nearest_even) {
- z += lastBitMask>>1;
- if ((z & roundBitsMask) == 0) z &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloat32Sign(z) ^ (roundingMode == float_round_up)) {
- z += roundBitsMask;
- }
- }
- z &= ~roundBitsMask;
- if (z != a) float_raise(status, float_flag_inexact);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the fractional portion of single-precision floating-point value `a',
-| and returns the result as a single-precision floating-point value. The
-| fractional results are precise. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_frc(float32 a, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
-
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (aExp >= 0x96) {
- return packFloat32(roundingMode == float_round_down, 0, 0);
- }
-
- if (aExp < 0x7F) {
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat32(roundingMode == float_round_down, 0, 0);
-
- float_raise(status, float_flag_denormal);
- if (! float_exception_masked(status, float_flag_underflow))
- float_raise(status, float_flag_underflow);
-
- if(get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(aSign, 0, 0);
- }
- }
- return a;
- }
-
- Bit32u lastBitMask = 1 << (0x96 - aExp);
- Bit32u roundBitsMask = lastBitMask - 1;
-
- aSig &= roundBitsMask;
- aSig <<= 7;
- aExp--;
-
- if (aSig == 0)
- return packFloat32(roundingMode == float_round_down, 0, 0);
-
- return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the exponent portion of single-precision floating-point value 'a',
-| and returns the result as a single-precision floating-point value
-| representing unbiased integer exponent. The operation is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_getexp(float32 a, struct float_status_t *status)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- return float32_positive_inf;
- }
-
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return float32_negative_inf;
-
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
-
- return int32_to_float32(aExp - 0x7F, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the mantissa of single-precision floating-point value 'a' and
-| returns the result as a single-precision floating-point after applying
-| the mantissa interval normalization and sign control. The operation is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- }
- return packFloat32(~sign_ctrl & aSign, 0x7F, 0);
- }
-
- if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) {
- return packFloat32(~sign_ctrl & aSign, 0x7F, 0);
- }
-
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
-// aExp += 0x7E;
- aSig &= 0x7FFFFF;
- }
-
- switch(interv) {
- case 0x0: // interval [1,2)
- aExp = 0x7F;
- break;
- case 0x1: // interval [1/2,2)
- aExp -= 0x7F;
- aExp = 0x7F - (aExp & 0x1);
- break;
- case 0x2: // interval [1/2,1)
- aExp = 0x7E;
- break;
- case 0x3: // interval [3/4,3/2)
- aExp = 0x7F - ((aSig >> 22) & 0x1);
- break;
- }
-
- return packFloat32(~sign_ctrl & aSign, aExp, aSig);
-}
-
-/*----------------------------------------------------------------------------
-| Return the result of a floating point scale of the single-precision floating
-| point value `a' by multiplying it by 2 power of the single-precision
-| floating point value 'b' converted to integral value. If the result cannot
-| be represented in single precision, then the proper overflow response (for
-| positive scaling operand), or the proper underflow response (for negative
-| scaling operand) is issued. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_scalef(float32 a, float32 b, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
- Bit32u bSig = extractFloat32Frac(b);
- Bit16s bExp = extractFloat32Exp(b);
- int bSign = extractFloat32Sign(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- }
-
- if (aExp == 0xFF) {
- if (aSig) {
- int aIsSignalingNaN = (aSig & 0x00400000) == 0;
- if (aIsSignalingNaN || bExp != 0xFF || bSig)
- return propagateFloat32NaN(a, b, status);
-
- return bSign ? 0 : float32_positive_inf;
- }
-
- if (bExp == 0xFF && bSign) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- return a;
- }
-
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0xFF && ! bSign) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- return a;
- }
- float_raise(status, float_flag_denormal);
- }
-
- if ((bExp | bSig) == 0) return a;
-
- if (bExp == 0xFF) {
- if (bSign) return packFloat32(aSign, 0, 0);
- return packFloat32(aSign, 0xFF, 0);
- }
-
- if (bExp >= 0x8E) {
- // handle obvious overflow/underflow result
- return roundAndPackFloat32(aSign, bSign ? -0x7F : 0xFF, aSig, status);
- }
-
- int scale = 0;
-
- if (bExp <= 0x7E) {
- if (bExp == 0)
- float_raise(status, float_flag_denormal);
- scale = -bSign;
- }
- else {
- int shiftCount = bExp - 0x9E;
- bSig = (bSig | 0x800000)<<8;
- scale = bSig>>(-shiftCount);
-
- if (bSign) {
- if ((Bit32u) (bSig<<(shiftCount & 31))) scale++;
- scale = -scale;
- }
-
- if (scale > 0x200) scale = 0x200;
- if (scale < -0x200) scale = -0x200;
- }
-
- if (aExp != 0) {
- aSig |= 0x00800000;
- } else {
- aExp++;
- }
-
- aExp += scale - 1;
- aSig <<= 7;
- return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the single-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 addFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 6;
- bSig <<= 6;
-
- if (0 < expDiff) {
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= 0x20000000;
-
- bSig = shift32RightJamming(bSig, expDiff);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= 0x20000000;
-
- aSig = shift32RightJamming(aSig, -expDiff);
- zExp = bExp;
- }
- else {
- if (aExp == 0xFF) {
- if (aSig | bSig) return propagateFloat32NaN(a, b, status);
- return a;
- }
- if (aExp == 0) {
- zSig = (aSig + bSig) >> 6;
- if (aSig | bSig) {
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status) && (extractFloat32Frac(zSig) == zSig)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(zSign, 0, 0);
- }
- if (! float_exception_masked(status, float_flag_underflow)) {
- if (extractFloat32Frac(zSig) == zSig)
- float_raise(status, float_flag_underflow);
- }
- }
- return packFloat32(zSign, 0, zSig);
- }
- zSig = 0x40000000 + aSig + bSig;
- return roundAndPackFloat32(zSign, aExp, zSig, status);
- }
- aSig |= 0x20000000;
- zSig = (aSig + bSig)<<1;
- --zExp;
- if ((Bit32s) zSig < 0) {
- zSig = aSig + bSig;
- ++zExp;
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the single-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 subFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 7;
- bSig <<= 7;
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0xFF) {
- if (aSig | bSig) return propagateFloat32NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aExp == 0) {
- if (aSig | bSig) float_raise(status, float_flag_denormal);
- aExp = 1;
- bExp = 1;
- }
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bExpBigger:
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign ^ 1, 0xFF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= 0x40000000;
-
- aSig = shift32RightJamming(aSig, -expDiff);
- bSig |= 0x40000000;
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= 0x40000000;
-
- bSig = shift32RightJamming(bSig, expDiff);
- aSig |= 0x40000000;
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the single-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_add(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
-
- if (aSign == bSign) {
- return addFloat32Sigs(a, b, aSign, status);
- }
- else {
- return subFloat32Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sub(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
-
- if (aSign == bSign) {
- return subFloat32Sigs(a, b, aSign, status);
- }
- else {
- return addFloat32Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_mul(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig;
- Bit64u zSig64;
- Bit32u zSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0xFF) {
- if (aSig || ((bExp == 0xFF) && bSig))
- return propagateFloat32NaN(a, b, status);
-
- if ((bExp | bSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloat32(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x7F;
- aSig = (aSig | 0x00800000)<<7;
- bSig = (bSig | 0x00800000)<<8;
- zSig64 = shift64RightJamming(((Bit64u) aSig) * bSig, 32);
- zSig = (Bit32u) zSig64;
- if (0 <= (Bit32s) (zSig<<1)) {
- zSig <<= 1;
- --zExp;
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the single-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_div(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat32(zSign, 0xFF, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloat32(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x7D;
- aSig = (aSig | 0x00800000)<<7;
- bSig = (bSig | 0x00800000)<<8;
- if (bSig <= (aSig + aSig)) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = (((Bit64u) aSig)<<32) / bSig;
- if ((zSig & 0x3F) == 0) {
- zSig |= ((Bit64u) bSig * zSig != ((Bit64u) aSig)<<32);
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the single-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sqrt(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, zExp;
- Bit32u aSig, zSig;
- Bit64u rem, term;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign) {
- if ((aExp | aSig) == 0) return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aExp == 0) {
- if (aSig == 0) return 0;
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- zExp = ((aExp - 0x7F)>>1) + 0x7E;
- aSig = (aSig | 0x00800000)<<8;
- zSig = estimateSqrt32(aExp, aSig) + 2;
- if ((zSig & 0x7F) <= 5) {
- if (zSig < 2) {
- zSig = 0x7FFFFFFF;
- goto roundAndPack;
- }
- aSig >>= aExp & 1;
- term = ((Bit64u) zSig) * zSig;
- rem = (((Bit64u) aSig)<<32) - term;
- while ((Bit64s) rem < 0) {
- --zSig;
- rem += (((Bit64u) zSig)<<1) | 1;
- }
- zSig |= (rem != 0);
- }
- zSig = shift32RightJamming(zSig, 1);
- roundAndPack:
- return roundAndPackFloat32(0, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine single-precision floating-point number class.
-*----------------------------------------------------------------------------*/
-
-float_class_t float32_class(float32 a)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if(aExp == 0xFF) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & 0x00400000) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0) return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int float32_compare(float32 a, float32 b, int quiet, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- float_class_t aClass = float32_class(a);
- float_class_t bClass = float32_class(b);
-
- if (aClass == float_SNaN || bClass == float_SNaN) {
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
-
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
- if (aSign != bSign)
- return (aSign) ? float_relation_less : float_relation_greater;
-
- if (aSign ^ (a < b)) return float_relation_less;
- return float_relation_greater;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| smaller of them.
-*----------------------------------------------------------------------------*/
-
-float32 float32_min(float32 a, float32 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- return (float32_compare_two(a, b, status) == float_relation_less) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| larger of them.
-*----------------------------------------------------------------------------*/
-
-float32 float32_max(float32 a, float32 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- return (float32_compare_two(a, b, status) == float_relation_greater) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| smaller/larger of them. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- if (float32_is_nan(a) || float32_is_nan(b)) {
- if (float32_is_signaling_nan(a)) {
- return propagateFloat32NaNOne(a, status);
- }
- if (float32_is_signaling_nan(b) ) {
- return propagateFloat32NaNOne(b, status);
- }
- if (! float32_is_nan(b)) {
- if (float32_is_denormal(b))
- float_raise(status, float_flag_denormal);
- return b;
- }
- if (! float32_is_nan(a)) {
- if (float32_is_denormal(a))
- float_raise(status, float_flag_denormal);
- return a;
- }
- return propagateFloat32NaN(a, b, status);
- }
-
- float32 tmp_a = a, tmp_b = b;
- if (is_abs) {
- tmp_a &= ~0x80000000; // clear the sign bit
- tmp_b &= ~0x80000000;
- }
-
- int aSign = extractFloat32Sign(tmp_a);
- int bSign = extractFloat32Sign(tmp_b);
-
- if (float32_is_denormal(a) || float32_is_denormal(b))
- float_raise(status, float_flag_denormal);
-
- if (aSign != bSign) {
- if (! is_max) {
- return aSign ? a : b;
- } else {
- return aSign ? b : a;
- }
- } else {
- if (! is_max) {
- return (aSign ^ (tmp_a < tmp_b)) ? a : b;
- } else {
- return (aSign ^ (tmp_a < tmp_b)) ? b : a;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float64_to_int32(float64 a, struct float_status_t *status)
-{
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
- if ((aExp == 0x7FF) && aSig) aSign = 0;
- if (aExp) aSig |= BX_CONST64(0x0010000000000000);
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- int shiftCount = 0x42C - aExp;
- if (0 < shiftCount) aSig = shift64RightJamming(aSig, shiftCount);
- return roundAndPackInt32(aSign, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float64_to_int32_round_to_zero(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig, savedASig;
- Bit32s z;
- int shiftCount;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- if (0x41E < aExp) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- else if (aExp < 0x3FF) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp || aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig |= BX_CONST64(0x0010000000000000);
- shiftCount = 0x433 - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = (Bit32s) aSig;
- if (aSign) z = -z;
- if ((z < 0) ^ aSign) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if ((aSig<>= shiftCount;
- if ((aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or the conversion overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float64_to_uint64_round_to_zero(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig, z;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (aExp < 0x3FE) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
-
- if (0x43E <= aExp || aSign) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (aExp) aSig |= BX_CONST64(0x0010000000000000);
- int shiftCount = aExp - 0x433;
-
- if (0 <= shiftCount) {
- z = aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float64_to_uint32(float64 a, struct float_status_t *status)
-{
- Bit64u val_64 = float64_to_uint64(a, status);
-
- if (val_64 > 0xffffffff) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return uint32_indefinite;
- }
-
- return (Bit32u) val_64;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float64_to_uint64(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, shiftCount;
- Bit64u aSig, aSigExtra;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign && (aExp > 0x3FE)) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (aExp) {
- aSig |= BX_CONST64(0x0010000000000000);
- }
- shiftCount = 0x433 - aExp;
- if (shiftCount <= 0) {
- if (0x43E < aExp) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
- aSigExtra = 0;
- aSig <<= -shiftCount;
- } else {
- shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
- }
-
- return roundAndPackUint64(aSign, aSig, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float64_to_float32(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig;
- Bit32u zSig;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- if (aExp == 0x7FF) {
- if (aSig) return commonNaNToFloat32(float64ToCommonNaN(a, status));
- return packFloat32(aSign, 0xFF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- }
- aSig = shift64RightJamming(aSig, 22);
- zSig = (Bit32u) aSig;
- if (aExp || zSig) {
- zSig |= 0x40000000;
- aExp -= 0x381;
- }
- return roundAndPackFloat32(aSign, aExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the double-precision floating-point value `a' to an integer, and
-| returns the result as a double-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_round_to_int(float64 a, Bit8u scale, struct float_status_t *status)
-{
- Bit64u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- Bit16s aExp = extractFloat64Exp(a);
- scale &= 0xf;
-
- if ((aExp == 0x7FF) && extractFloat64Frac(a)) {
- return propagateFloat64NaNOne(a, status);
- }
-
- aExp += scale; // scale the exponent
-
- if (0x433 <= aExp) {
- return a;
- }
-
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- }
-
- if (aExp < 0x3FF) {
- if ((Bit64u) (a<<1) == 0) return a;
- float_raise(status, float_flag_inexact);
- int aSign = extractFloat64Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x3FE) && extractFloat64Frac(a)) {
- return packFloat64(aSign, 0x3FF - scale, 0);
- }
- break;
- case float_round_down:
- return aSign ? packFloat64(1, 0x3FF - scale, 0) : float64_positive_zero;
- case float_round_up:
- return aSign ? float64_negative_zero : packFloat64(0, 0x3FF - scale, 0);
- }
- return packFloat64(aSign, 0, 0);
- }
-
- lastBitMask = 1;
- lastBitMask <<= 0x433 - aExp;
- roundBitsMask = lastBitMask - 1;
- float64 z = a;
- if (roundingMode == float_round_nearest_even) {
- z += lastBitMask>>1;
- if ((z & roundBitsMask) == 0) z &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloat64Sign(z) ^ (roundingMode == float_round_up)) {
- z += roundBitsMask;
- }
- }
- z &= ~roundBitsMask;
- if (z != a) float_raise(status, float_flag_inexact);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the fractional portion of double-precision floating-point value `a',
-| and returns the result as a double-precision floating-point value. The
-| fractional results are precise. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_frc(float64 a, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
-
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (aExp >= 0x433) {
- return packFloat64(roundingMode == float_round_down, 0, 0);
- }
-
- if (aExp < 0x3FF) {
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat64(roundingMode == float_round_down, 0, 0);
-
- float_raise(status, float_flag_denormal);
- if (! float_exception_masked(status, float_flag_underflow))
- float_raise(status, float_flag_underflow);
-
- if(get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(aSign, 0, 0);
- }
- }
- return a;
- }
-
- Bit64u lastBitMask = BX_CONST64(1) << (0x433 - aExp);
- Bit64u roundBitsMask = lastBitMask - 1;
-
- aSig &= roundBitsMask;
- aSig <<= 10;
- aExp--;
-
- if (aSig == 0)
- return packFloat64(roundingMode == float_round_down, 0, 0);
-
- return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the exponent portion of double-precision floating-point value 'a',
-| and returns the result as a double-precision floating-point value
-| representing unbiased integer exponent. The operation is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_getexp(float64 a, struct float_status_t *status)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- return float64_positive_inf;
- }
-
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return float64_negative_inf;
-
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
-
- return int32_to_float64(aExp - 0x3FF);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the mantissa of double-precision floating-point value 'a' and
-| returns the result as a double-precision floating-point after applying
-| the mantissa interval normalization and sign control. The operation is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
- int aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- }
- return packFloat64(~sign_ctrl & aSign, 0x3FF, 0);
- }
-
- if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) {
- return packFloat64(~sign_ctrl & aSign, 0x3FF, 0);
- }
-
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
-// aExp += 0x3FE;
- aSig &= BX_CONST64(0xFFFFFFFFFFFFFFFF);
- }
-
- switch(interv) {
- case 0x0: // interval [1,2)
- aExp = 0x3FF;
- break;
- case 0x1: // interval [1/2,2)
- aExp -= 0x3FF;
- aExp = 0x3FF - (aExp & 0x1);
- break;
- case 0x2: // interval [1/2,1)
- aExp = 0x3FE;
- break;
- case 0x3: // interval [3/4,3/2)
- aExp = 0x3FF - ((aSig >> 51) & 0x1);
- break;
- }
-
- return packFloat64(~sign_ctrl & aSign, aExp, aSig);
-}
-
-/*----------------------------------------------------------------------------
-| Return the result of a floating point scale of the double-precision floating
-| point value `a' by multiplying it by 2 power of the double-precision
-| floating point value 'b' converted to integral value. If the result cannot
-| be represented in double precision, then the proper overflow response (for
-| positive scaling operand), or the proper underflow response (for negative
-| scaling operand) is issued. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_scalef(float64 a, float64 b, struct float_status_t *status)
-{
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
- Bit64u bSig = extractFloat64Frac(b);
- Bit16s bExp = extractFloat64Exp(b);
- int bSign = extractFloat64Sign(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- }
-
- if (aExp == 0x7FF) {
- if (aSig) {
- int aIsSignalingNaN = (aSig & BX_CONST64(0x0008000000000000)) == 0;
- if (aIsSignalingNaN || bExp != 0x7FF || bSig)
- return propagateFloat64NaN(a, b, status);
-
- return bSign ? 0 : float64_positive_inf;
- }
-
- if (bExp == 0x7FF && bSign) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- return a;
- }
-
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0x7FF && ! bSign) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- return a;
- }
- float_raise(status, float_flag_denormal);
- }
-
- if ((bExp | bSig) == 0) return a;
-
- if (bExp == 0x7FF) {
- if (bSign) return packFloat64(aSign, 0, 0);
- return packFloat64(aSign, 0x7FF, 0);
- }
-
- if (0x40F <= bExp) {
- // handle obvious overflow/underflow result
- return roundAndPackFloat64(aSign, bSign ? -0x3FF : 0x7FF, aSig, status);
- }
-
- int scale = 0;
-
- if (bExp < 0x3FF) {
- if (bExp == 0)
- float_raise(status, float_flag_denormal);
- scale = -bSign;
- }
- else {
- bSig |= BX_CONST64(0x0010000000000000);
- int shiftCount = 0x433 - bExp;
- Bit64u savedBSig = bSig;
- bSig >>= shiftCount;
- scale = (Bit32s) bSig;
- if (bSign) {
- if ((bSig< 0x1000) scale = 0x1000;
- if (scale < -0x1000) scale = -0x1000;
- }
-
- if (aExp != 0) {
- aSig |= BX_CONST64(0x0010000000000000);
- } else {
- aExp++;
- }
-
- aExp += scale - 1;
- aSig <<= 10;
- return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the double-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 addFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 9;
- bSig <<= 9;
- if (0 < expDiff) {
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= BX_CONST64(0x2000000000000000);
-
- bSig = shift64RightJamming(bSig, expDiff);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= BX_CONST64(0x2000000000000000);
-
- aSig = shift64RightJamming(aSig, -expDiff);
- zExp = bExp;
- }
- else {
- if (aExp == 0x7FF) {
- if (aSig | bSig) return propagateFloat64NaN(a, b, status);
- return a;
- }
- if (aExp == 0) {
- zSig = (aSig + bSig) >> 9;
- if (aSig | bSig) {
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status) && (extractFloat64Frac(zSig) == zSig)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(zSign, 0, 0);
- }
- if (! float_exception_masked(status, float_flag_underflow)) {
- if (extractFloat64Frac(zSig) == zSig)
- float_raise(status, float_flag_underflow);
- }
- }
- return packFloat64(zSign, 0, zSig);
- }
- zSig = BX_CONST64(0x4000000000000000) + aSig + bSig;
- return roundAndPackFloat64(zSign, aExp, zSig, status);
- }
- aSig |= BX_CONST64(0x2000000000000000);
- zSig = (aSig + bSig)<<1;
- --zExp;
- if ((Bit64s) zSig < 0) {
- zSig = aSig + bSig;
- ++zExp;
- }
- return roundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 subFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 10;
- bSig <<= 10;
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0x7FF) {
- if (aSig | bSig) return propagateFloat64NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aExp == 0) {
- if (aSig | bSig) float_raise(status, float_flag_denormal);
- aExp = 1;
- bExp = 1;
- }
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bExpBigger:
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign ^ 1, 0x7FF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= BX_CONST64(0x4000000000000000);
-
- aSig = shift64RightJamming(aSig, -expDiff);
- bSig |= BX_CONST64(0x4000000000000000);
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= BX_CONST64(0x4000000000000000);
-
- bSig = shift64RightJamming(bSig, expDiff);
- aSig |= BX_CONST64(0x4000000000000000);
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the double-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_add(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
-
- if (aSign == bSign) {
- return addFloat64Sigs(a, b, aSign, status);
- }
- else {
- return subFloat64Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sub(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
-
- if (aSign == bSign) {
- return subFloat64Sigs(a, b, aSign, status);
- }
- else {
- return addFloat64Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_mul(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0x7FF) {
- if (aSig || ((bExp == 0x7FF) && bSig)) {
- return propagateFloat64NaN(a, b, status);
- }
- if ((bExp | bSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloat64(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x3FF;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- mul64To128(aSig, bSig, &zSig0, &zSig1);
- zSig0 |= (zSig1 != 0);
- if (0 <= (Bit64s) (zSig0<<1)) {
- zSig0 <<= 1;
- --zExp;
- }
- return roundAndPackFloat64(zSign, zExp, zSig0, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the double-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_div(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit64u rem0, rem1;
- Bit64u term0, term1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat64(zSign, 0x7FF, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloat64(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x3FD;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- if (bSig <= (aSig + aSig)) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = estimateDiv128To64(aSig, 0, bSig);
- if ((zSig & 0x1FF) <= 2) {
- mul64To128(bSig, zSig, &term0, &term1);
- sub128(aSig, 0, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig;
- add128(rem0, rem1, 0, bSig, &rem0, &rem1);
- }
- zSig |= (rem1 != 0);
- }
- return roundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the double-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sqrt(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, zExp;
- Bit64u aSig, zSig, doubleZSig;
- Bit64u rem0, rem1, term0, term1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign) {
- if ((aExp | aSig) == 0) return packFloat64(aSign, 0, 0);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aExp == 0) {
- if (aSig == 0) return 0;
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- zExp = ((aExp - 0x3FF)>>1) + 0x3FE;
- aSig |= BX_CONST64(0x0010000000000000);
- zSig = estimateSqrt32(aExp, (Bit32u)(aSig>>21));
- aSig <<= 9 - (aExp & 1);
- zSig = estimateDiv128To64(aSig, 0, zSig<<32) + (zSig<<30);
- if ((zSig & 0x1FF) <= 5) {
- doubleZSig = zSig<<1;
- mul64To128(zSig, zSig, &term0, &term1);
- sub128(aSig, 0, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig;
- doubleZSig -= 2;
- add128(rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1);
- }
- zSig |= ((rem0 | rem1) != 0);
- }
- return roundAndPackFloat64(0, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine double-precision floating-point number class
-*----------------------------------------------------------------------------*/
-
-float_class_t float64_class(float64 a)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
- int aSign = extractFloat64Sign(a);
-
- if(aExp == 0x7FF) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & BX_CONST64(0x0008000000000000)) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0)
- return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int float64_compare(float64 a, float64 b, int quiet, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- float_class_t aClass = float64_class(a);
- float_class_t bClass = float64_class(b);
-
- if (aClass == float_SNaN || bClass == float_SNaN) {
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
-
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
- if (aSign != bSign)
- return (aSign) ? float_relation_less : float_relation_greater;
-
- if (aSign ^ (a < b)) return float_relation_less;
- return float_relation_greater;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| smaller of them.
-*----------------------------------------------------------------------------*/
-
-float64 float64_min(float64 a, float64 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- return (float64_compare_two(a, b, status) == float_relation_less) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| larger of them.
-*----------------------------------------------------------------------------*/
-
-float64 float64_max(float64 a, float64 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- return (float64_compare_two(a, b, status) == float_relation_greater) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| smaller/larger of them. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- if (float64_is_nan(a) || float64_is_nan(b)) {
- if (float64_is_signaling_nan(a)) {
- return propagateFloat64NaNOne(a, status);
- }
- if (float64_is_signaling_nan(b)) {
- return propagateFloat64NaNOne(b, status);
- }
- if (! float64_is_nan(b)) {
- if (float64_is_denormal(b))
- float_raise(status, float_flag_denormal);
- return b;
- }
- if (! float64_is_nan(a)) {
- if (float64_is_denormal(a))
- float_raise(status, float_flag_denormal);
- return a;
- }
- return propagateFloat64NaN(a, b, status);
- }
-
- float64 tmp_a = a, tmp_b = b;
- if (is_abs) {
- tmp_a &= ~BX_CONST64(0x8000000000000000); // clear the sign bit
- tmp_b &= ~BX_CONST64(0x8000000000000000);
- }
-
- int aSign = extractFloat64Sign(tmp_a);
- int bSign = extractFloat64Sign(tmp_b);
-
- if (float64_is_denormal(a) || float64_is_denormal(b))
- float_raise(status, float_flag_denormal);
-
- if (aSign != bSign) {
- if (! is_max) {
- return aSign ? a : b;
- } else {
- return aSign ? b : a;
- }
- } else {
- if (! is_max) {
- return (aSign ^ (tmp_a < tmp_b)) ? a : b;
- } else {
- return (aSign ^ (tmp_a < tmp_b)) ? b : a;
- }
- }
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int32_to_floatx80(Bit32s a)
-{
- if (a == 0) return packFloatx80(0, 0, 0);
- int zSign = (a < 0);
- Bit32u absA = zSign ? -a : a;
- int shiftCount = countLeadingZeros32(absA) + 32;
- Bit64u zSig = absA;
- return packFloatx80(zSign, 0x403E - shiftCount, zSig< 0x401E) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if (aExp < 0x3FFF) {
- if (aExp || aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- shiftCount = 0x403E - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = (Bit32s) aSig;
- if (aSign) z = -z;
- if ((z < 0) ^ aSign) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if ((aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the single-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 floatx80_to_float32(floatx80 a, struct float_status_t *status)
-{
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return commonNaNToFloat32(floatx80ToCommonNaN(a, status));
-
- return packFloat32(aSign, 0xFF, 0);
- }
- aSig = shift64RightJamming(aSig, 33);
- if (aExp || aSig) aExp -= 0x3F81;
- return roundAndPackFloat32(aSign, aExp, (Bit32u) aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 floatx80_to_float64(floatx80 a, struct float_status_t *status)
-{
- Bit32s aExp;
- Bit64u aSig, zSig;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) {
- return commonNaNToFloat64(floatx80ToCommonNaN(a, status));
- }
- return packFloat64(aSign, 0x7FF, 0);
- }
- zSig = shift64RightJamming(aSig, 1);
- if (aExp || aSig) aExp -= 0x3C01;
- return roundAndPackFloat64(aSign, aExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the extended double-precision floating-point value `a' to an integer,
-| and returns the result as an extended double-precision floating-point
-| value. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_round_to_int(floatx80 a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign;
- Bit64u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- floatx80 z;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u aSig = extractFloatx80Frac(a);
- if (0x403E <= aExp) {
- if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1)) {
- return propagateFloatx80NaNOne(a, status);
- }
- return a;
- }
- if (aExp < 0x3FFF) {
- if (aExp == 0) {
- if ((aSig<<1) == 0) return a;
- float_raise(status, float_flag_denormal);
- }
- float_raise(status, float_flag_inexact);
- aSign = extractFloatx80Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x3FFE) && (Bit64u) (aSig<<1)) {
- set_float_rounding_up(status);
- return packFloatx80(aSign, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- break;
- case float_round_down:
- if (aSign) {
- set_float_rounding_up(status);
- return packFloatx80(1, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- else {
- return packFloatx80(0, 0, 0);
- }
- case float_round_up:
- if (aSign) {
- return packFloatx80(1, 0, 0);
- }
- else {
- set_float_rounding_up(status);
- return packFloatx80(0, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- }
- return packFloatx80(aSign, 0, 0);
- }
- lastBitMask = 1;
- lastBitMask <<= 0x403E - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- if (roundingMode == float_round_nearest_even) {
- z.fraction += lastBitMask>>1;
- if ((z.fraction & roundBitsMask) == 0) z.fraction &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloatx80Sign(z) ^ (roundingMode == float_round_up))
- z.fraction += roundBitsMask;
- }
- z.fraction &= ~roundBitsMask;
- if (z.fraction == 0) {
- z.exp++;
- z.fraction = BX_CONST64(0x8000000000000000);
- }
- if (z.fraction != a.fraction) {
- float_raise(status, float_flag_inexact);
- if (z.fraction > a.fraction || z.exp > a.exp)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the extended double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
-| negated before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- return propagateFloatx80NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if ((bExp == 0) && bSig) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, bExp, bSig, 0, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0)
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, aExp, aSig, 0, status);
-
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- Bit32s expDiff = aExp - bExp;
- zExp = aExp;
- if (0 < expDiff) {
- shift64ExtraRightJamming(bSig, 0, expDiff, &bSig, &zSig1);
- }
- else if (expDiff < 0) {
- shift64ExtraRightJamming(aSig, 0, -expDiff, &aSig, &zSig1);
- zExp = bExp;
- }
- else {
- zSig0 = aSig + bSig;
- zSig1 = 0;
- goto shiftRight1;
- }
- zSig0 = aSig + bSig;
- if ((Bit64s) zSig0 < 0) goto roundAndPack;
- shiftRight1:
- shift64ExtraRightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
- zSig0 |= BX_CONST64(0x8000000000000000);
- zExp++;
- roundAndPack:
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the extended
-| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign ^ 1, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0) {
- if (bSig) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign ^ 1, bExp, bSig, 0, status);
- }
- return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign ^ 1, bExp, bSig, 0, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0)
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, aExp, aSig, 0, status);
-
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- Bit32s expDiff = aExp - bExp;
- if (0 < expDiff) {
- shift128RightJamming(bSig, 0, expDiff, &bSig, &zSig1);
- goto aBigger;
- }
- if (expDiff < 0) {
- shift128RightJamming(aSig, 0, -expDiff, &aSig, &zSig1);
- goto bBigger;
- }
- zSig1 = 0;
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bBigger:
- sub128(bSig, 0, aSig, zSig1, &zSig0, &zSig1);
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aBigger:
- sub128(aSig, 0, bSig, zSig1, &zSig0, &zSig1);
- zExp = aExp;
- normalizeRoundAndPack:
- return
- normalizeRoundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the extended double-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_add(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aSign == bSign)
- return addFloatx80Sigs(a, b, aSign, status);
- else
- return subFloatx80Sigs(a, b, aSign, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sub(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aSign == bSign)
- return subFloatx80Sigs(a, b, aSign, status);
- else
- return addFloatx80Sigs(a, b, aSign, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_mul(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- invalid:
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
- zSign = aSign ^ bSign;
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
- return propagateFloatx80NaN(a, b, status);
- }
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x3FFE;
- mul64To128(aSig, bSig, &zSig0, &zSig1);
- if (0 < (Bit64s) zSig0) {
- shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
- --zExp;
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the extended double-precision floating-point
-| value `a' by the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_div(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
- Bit64u rem0, rem1, rem2, term0, term1, term2;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x3FFE;
- rem1 = 0;
- if (bSig <= aSig) {
- shift128Right(aSig, 0, 1, &aSig, &rem1);
- ++zExp;
- }
- zSig0 = estimateDiv128To64(aSig, rem1, bSig);
- mul64To128(bSig, zSig0, &term0, &term1);
- sub128(aSig, rem1, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- add128(rem0, rem1, 0, bSig, &rem0, &rem1);
- }
- zSig1 = estimateDiv128To64(rem1, 0, bSig);
- if ((Bit64u) (zSig1<<1) <= 8) {
- mul64To128(bSig, zSig1, &term1, &term2);
- sub128(rem1, 0, term1, term2, &rem1, &rem2);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- add128(rem1, rem2, 0, bSig, &rem1, &rem2);
- }
- zSig1 |= ((rem1 | rem2) != 0);
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sqrt(floatx80 a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign;
- Bit32s aExp, zExp;
- Bit64u aSig0, aSig1, zSig0, zSig1, doubleZSig0;
- Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1)) return propagateFloatx80NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (aSign) {
- if ((aExp | aSig0) == 0) return a;
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (aExp == 0) {
- if (aSig0 == 0) return packFloatx80(0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
- }
- zExp = ((aExp - 0x3FFF)>>1) + 0x3FFF;
- zSig0 = estimateSqrt32(aExp, aSig0>>32);
- shift128Right(aSig0, 0, 2 + (aExp & 1), &aSig0, &aSig1);
- zSig0 = estimateDiv128To64(aSig0, aSig1, zSig0<<32) + (zSig0<<30);
- doubleZSig0 = zSig0<<1;
- mul64To128(zSig0, zSig0, &term0, &term1);
- sub128(aSig0, aSig1, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- doubleZSig0 -= 2;
- add128(rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1);
- }
- zSig1 = estimateDiv128To64(rem1, 0, doubleZSig0);
- if ((zSig1 & BX_CONST64(0x3FFFFFFFFFFFFFFF)) <= 5) {
- if (zSig1 == 0) zSig1 = 1;
- mul64To128(doubleZSig0, zSig1, &term1, &term2);
- sub128(rem1, 0, term1, term2, &rem1, &rem2);
- mul64To128(zSig1, zSig1, &term2, &term3);
- sub192(rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- shortShift128Left(0, zSig1, 1, &term2, &term3);
- term3 |= 1;
- term2 |= doubleZSig0;
- add192(rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3);
- }
- zSig1 |= ((rem1 | rem2 | rem3) != 0);
- }
- shortShift128Left(0, zSig1, 1, &zSig0, &zSig1);
- zSig0 |= doubleZSig0;
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- 0, zExp, zSig0, zSig1, status);
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the quadruple-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 floatx80_to_float128(floatx80 a, struct float_status_t *status)
-{
- Bit64u zSig0, zSig1;
-
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1))
- return commonNaNToFloat128(floatx80ToCommonNaN(a, status));
-
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- return packFloat128Four(aSign, aExp, zSig0, zSig1);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the extended double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float128_to_floatx80(float128 a, struct float_status_t *status)
-{
- Bit32s aExp;
- Bit64u aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- int aSign = extractFloat128Sign(a);
-
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1)
- return commonNaNToFloatx80(float128ToCommonNaN(a, status));
-
- return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
-
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloatx80(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- else aSig0 |= BX_CONST64(0x0001000000000000);
-
- shortShift128Left(aSig0, aSig1, 15, &aSig0, &aSig1);
- return roundAndPackFloatx80(80, aSign, aExp, aSig0, aSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point value `a' and quadruple-precision floating point value `b'. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig0, bSig1, zSig0, zSig1, zSig2;
- int aSign, bSign, zSign;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- invalid:
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig0 = extractFloat128Frac0(b);
- bSig1 = extractFloat128Frac1(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (bSig0 | bSig1)))
- {
- floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status));
- return propagateFloatx80NaN(a, r, status);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) {
- floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status));
- return propagateFloatx80NaN(a, r, status);
- }
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if ((bExp == 0) && (bSig0 | bSig1)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- else bSig0 |= BX_CONST64(0x0001000000000000);
-
- zExp = aExp + bExp - 0x3FFE;
- shortShift128Left(bSig0, bSig1, 15, &bSig0, &bSig1);
- mul128By64To192(bSig0, bSig1, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
- shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
- --zExp;
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the quadruple-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 addFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status)
-{
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- Bit32s expDiff;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- expDiff = aExp - bExp;
-
- if (0 < expDiff) {
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- return a;
- }
- if (bExp == 0) --expDiff;
- else bSig0 |= BX_CONST64(0x0001000000000000);
- shift128ExtraRightJamming(bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (aExp == 0) ++expDiff;
- else aSig0 |= BX_CONST64(0x0001000000000000);
- shift128ExtraRightJamming(aSig0, aSig1, 0, -expDiff, &aSig0, &aSig1, &zSig2);
- zExp = bExp;
- }
- else {
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1 | bSig0 | bSig1)
- return propagateFloat128NaN(a, b, status);
-
- return a;
- }
- add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- if (aExp == 0) return packFloat128Four(zSign, 0, zSig0, zSig1);
- zSig2 = 0;
- zSig0 |= BX_CONST64(0x0002000000000000);
- zExp = aExp;
- goto shiftRight1;
- }
- aSig0 |= BX_CONST64(0x0001000000000000);
- add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- --zExp;
- if (zSig0 < BX_CONST64(0x0002000000000000)) goto roundAndPack;
- ++zExp;
- shiftRight1:
- shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2);
- roundAndPack:
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the quadruple-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 subFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status)
-{
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
- Bit32s expDiff;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
-
- expDiff = aExp - bExp;
- shortShift128Left(aSig0, aSig1, 14, &aSig0, &aSig1);
- shortShift128Left(bSig0, bSig1, 14, &bSig0, &bSig1);
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1 | bSig0 | bSig1)
- return propagateFloat128NaN(a, b, status);
-
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- if (aExp == 0) {
- aExp = 1;
- bExp = 1;
- }
- if (bSig0 < aSig0) goto aBigger;
- if (aSig0 < bSig0) goto bBigger;
- if (bSig1 < aSig1) goto aBigger;
- if (aSig1 < bSig1) goto bBigger;
- return packFloat128(0, 0);
-
- bExpBigger:
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign ^ 1, 0x7FFF, 0, 0);
- }
- if (aExp == 0) ++expDiff;
- else {
- aSig0 |= BX_CONST64(0x4000000000000000);
- }
- shift128RightJamming(aSig0, aSig1, - expDiff, &aSig0, &aSig1);
- bSig0 |= BX_CONST64(0x4000000000000000);
- bBigger:
- sub128(bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1);
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- return a;
- }
- if (bExp == 0) --expDiff;
- else {
- bSig0 |= BX_CONST64(0x4000000000000000);
- }
- shift128RightJamming(bSig0, bSig1, expDiff, &bSig0, &bSig1);
- aSig0 |= BX_CONST64(0x4000000000000000);
- aBigger:
- sub128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat128(zSign, zExp - 14, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the quadruple-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_add(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign = extractFloat128Sign(a);
- int bSign = extractFloat128Sign(b);
-
- if (aSign == bSign) {
- return addFloat128Sigs(a, b, aSign, status);
- }
- else {
- return subFloat128Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sub(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign = extractFloat128Sign(a);
- int bSign = extractFloat128Sign(b);
-
- if (aSign == bSign) {
- return subFloat128Sigs(a, b, aSign, status);
- }
- else {
- return addFloat128Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_mul(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- aSign = extractFloat128Sign(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if ((aSig0 | aSig1) || ((bExp == 0x7FFF) && (bSig0 | bSig1))) {
- return propagateFloat128NaN(a, b, status);
- }
- if ((bExp | bSig0 | bSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- if ((aExp | aSig0 | aSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- zExp = aExp + bExp - 0x4000;
- aSig0 |= BX_CONST64(0x0001000000000000);
- shortShift128Left(bSig0, bSig1, 16, &bSig0, &bSig1);
- mul128To256(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3);
- add128(zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1);
- zSig2 |= (zSig3 != 0);
- if (BX_CONST64(0x0002000000000000) <= zSig0) {
- shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2);
- ++zExp;
- }
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the quadruple-precision floating-point value
-| `a' by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_div(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- aSign = extractFloat128Sign(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign, 0, 0, 0);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) {
- if ((aExp | aSig0 | aSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- zExp = aExp - bExp + 0x3FFD;
- shortShift128Left(
- aSig0 | BX_CONST64(0x0001000000000000), aSig1, 15, &aSig0, &aSig1);
- shortShift128Left(
- bSig0 | BX_CONST64(0x0001000000000000), bSig1, 15, &bSig0, &bSig1);
- if (le128(bSig0, bSig1, aSig0, aSig1)) {
- shift128Right(aSig0, aSig1, 1, &aSig0, &aSig1);
- ++zExp;
- }
- zSig0 = estimateDiv128To64(aSig0, aSig1, bSig0);
- mul128By64To192(bSig0, bSig1, zSig0, &term0, &term1, &term2);
- sub192(aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- add192(rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2);
- }
- zSig1 = estimateDiv128To64(rem1, rem2, bSig0);
- if ((zSig1 & 0x3FFF) <= 4) {
- mul128By64To192(bSig0, bSig1, zSig1, &term1, &term2, &term3);
- sub192(rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- add192(rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3);
- }
- zSig1 |= ((rem1 | rem2 | rem3) != 0);
- }
- shift128ExtraRightJamming(zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2);
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int64_to_float128(Bit64s a)
-{
- Bit64u zSig0, zSig1;
-
- if (a == 0) return packFloat128Four(0, 0, 0, 0);
- int zSign = (a < 0);
- Bit64u absA = zSign ? - a : a;
- Bit8u shiftCount = countLeadingZeros64(absA) + 49;
- Bit32s zExp = 0x406E - shiftCount;
- if (64 <= shiftCount) {
- zSig1 = 0;
- zSig0 = absA;
- shiftCount -= 64;
- }
- else {
- zSig1 = absA;
- zSig0 = 0;
- }
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- return packFloat128Four(zSign, zExp, zSig0, zSig1);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat.h b/src/cpu/softfloat/softfloat.h
deleted file mode 100644
index 1d1b0f08f9..0000000000
--- a/src/cpu/softfloat/softfloat.h
+++ /dev/null
@@ -1,488 +0,0 @@
-/*============================================================================
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "config.h" /* generated by configure script from config.h.in */
-
-#ifndef _SOFTFLOAT_H_
-#define _SOFTFLOAT_H_
-
-#define FLOAT16
-#define FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-#ifdef FLOAT16
-typedef Bit16u float16;
-#endif
-typedef Bit32u float32;
-typedef Bit64u float64;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point class.
-*----------------------------------------------------------------------------*/
-typedef enum {
- float_zero,
- float_SNaN,
- float_QNaN,
- float_negative_inf,
- float_positive_inf,
- float_denormal,
- float_normalized
-} float_class_t;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point NaN operands handling mode.
-*----------------------------------------------------------------------------*/
-enum float_nan_handling_mode_t {
- float_larger_significand_nan = 0, // this mode used by x87 FPU
- float_first_operand_nan = 1 // this mode used by SSE
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-enum float_round_t {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-enum float_exception_flag_t {
- float_flag_invalid = 0x01,
- float_flag_denormal = 0x02,
- float_flag_divbyzero = 0x04,
- float_flag_overflow = 0x08,
- float_flag_underflow = 0x10,
- float_flag_inexact = 0x20
-};
-
-extern const unsigned float_all_exceptions_mask;
-
-#ifdef FLOATX80
-#define RAISE_SW_C1 0x0200
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point ordering relations
-*----------------------------------------------------------------------------*/
-enum {
- float_relation_less = -1,
- float_relation_equal = 0,
- float_relation_greater = 1,
- float_relation_unordered = 2
-};
-
-/*----------------------------------------------------------------------------
-| Options to indicate which negations to perform in float*_muladd()
-| Using these differs from negating an input or output before calling
-| the muladd function in that this means that a NaN doesn't have its
-| sign bit inverted before it is propagated.
-*----------------------------------------------------------------------------*/
-enum {
- float_muladd_negate_c = 1,
- float_muladd_negate_product = 2,
- float_muladd_negate_result = float_muladd_negate_c | float_muladd_negate_product
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point status structure.
-*----------------------------------------------------------------------------*/
-struct float_status_t
-{
-#ifdef FLOATX80
- int float_rounding_precision; /* floatx80 only */
-#endif
- int float_rounding_mode;
- int float_exception_flags;
- int float_exception_masks;
- int float_suppress_exception;
- int float_nan_handling_mode; /* flag register */
- int flush_underflow_to_zero; /* flag register */
- int denormals_are_zeros; /* flag register */
-};
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void float_raise(struct float_status_t *status, int flags)
-{
- status->float_exception_flags |= flags;
-}
-
-/*----------------------------------------------------------------------------
-| Returns raised IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_exception_flags(const struct float_status_t *status)
-{
- return status->float_exception_flags & ~status->float_suppress_exception;
-}
-
-/*----------------------------------------------------------------------------
-| Routine to check if any or all of the software IEC/IEEE floating-point
-| exceptions are masked.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float_exception_masked(const struct float_status_t *status, int flag)
-{
- return status->float_exception_masks & flag;
-}
-
-/*----------------------------------------------------------------------------
-| Returns current floating point rounding mode specified by status word.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_float_rounding_mode(const struct float_status_t *status)
-{
- return status->float_rounding_mode;
-}
-
-/*----------------------------------------------------------------------------
-| Returns current floating point precision (floatx80 only).
-*----------------------------------------------------------------------------*/
-
-#ifdef FLOATX80
-BX_CPP_INLINE int get_float_rounding_precision(const struct float_status_t *status)
-{
- return status->float_rounding_precision;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns current floating point NaN operands handling mode specified
-| by status word.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_float_nan_handling_mode(const struct float_status_t *status)
-{
- return status->float_nan_handling_mode;
-}
-
-/*----------------------------------------------------------------------------
-| Raise floating point precision lost up flag (floatx80 only).
-*----------------------------------------------------------------------------*/
-
-#ifdef FLOATX80
-BX_CPP_INLINE void set_float_rounding_up(struct float_status_t *status)
-{
- status->float_exception_flags |= RAISE_SW_C1;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the feature is supported;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_denormals_are_zeros(const struct float_status_t *status)
-{
- return status->denormals_are_zeros;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the feature is supported;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_flush_underflow_to_zero(const struct float_status_t *status)
-{
- return status->flush_underflow_to_zero;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32(Bit32s, struct float_status_t *status);
-float64 int32_to_float64(Bit32s);
-float32 int64_to_float32(Bit64s, struct float_status_t *status);
-float64 int64_to_float64(Bit64s, struct float_status_t *status);
-
-float32 uint32_to_float32(Bit32u, struct float_status_t *status);
-float64 uint32_to_float64(Bit32u);
-float32 uint64_to_float32(Bit64u, struct float_status_t *status);
-float64 uint64_to_float64(Bit64u, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-Bit32s float32_to_int32(float32, struct float_status_t *status);
-Bit32s float32_to_int32_round_to_zero(float32, struct float_status_t *status);
-Bit64s float32_to_int64(float32, struct float_status_t *status);
-Bit64s float32_to_int64_round_to_zero(float32, struct float_status_t *status);
-Bit32u float32_to_uint32(float32, struct float_status_t *status);
-Bit32u float32_to_uint32_round_to_zero(float32, struct float_status_t *status);
-Bit64u float32_to_uint64(float32, struct float_status_t *status);
-Bit64u float32_to_uint64_round_to_zero(float32, struct float_status_t *status);
-float64 float32_to_float64(float32, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int(float32, Bit8u scale, struct float_status_t *status);
-float32 float32_add(float32, float32, struct float_status_t *status);
-float32 float32_sub(float32, float32, struct float_status_t *status);
-float32 float32_mul(float32, float32, struct float_status_t *status);
-float32 float32_div(float32, float32, struct float_status_t *status);
-float32 float32_sqrt(float32, struct float_status_t *status);
-float32 float32_frc(float32, struct float_status_t *status);
-float32 float32_muladd(float32, float32, float32, int flags, struct float_status_t *status);
-float32 float32_scalef(float32, float32, struct float_status_t *status);
-int float32_compare(float32, float32, int quiet, struct float_status_t *status);
-
-BX_CPP_INLINE float32 float32_round_to_int_one(float32 a, struct float_status_t *status)
-{
- return float32_round_to_int(a, 0, status);
-}
-
-BX_CPP_INLINE float32 float32_fmadd(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, 0, status);
-}
-
-BX_CPP_INLINE float32 float32_fmsub(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_c, status);
-}
-
-BX_CPP_INLINE float32 float32_fnmadd(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_product, status);
-}
-
-BX_CPP_INLINE float32 float32_fnmsub(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_result, status);
-}
-
-BX_CPP_INLINE int float32_compare_two(float32 a, float32 b, struct float_status_t *status)
-{
- return float32_compare(a, b, 0, status);
-}
-
-BX_CPP_INLINE int float32_compare_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- return float32_compare(a, b, 1, status);
-}
-
-float_class_t float32_class(float32);
-
-float32 float32_min(float32 a, float32 b, struct float_status_t *status);
-float32 float32_max(float32 a, float32 b, struct float_status_t *status);
-
-float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status);
-float32 float32_getexp(float32 a, struct float_status_t *status);
-float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-Bit32s float64_to_int32(float64, struct float_status_t *status);
-Bit32s float64_to_int32_round_to_zero(float64, struct float_status_t *status);
-Bit64s float64_to_int64(float64, struct float_status_t *status);
-Bit64s float64_to_int64_round_to_zero(float64, struct float_status_t *status);
-Bit32u float64_to_uint32(float64, struct float_status_t *status);
-Bit32u float64_to_uint32_round_to_zero(float64, struct float_status_t *status);
-Bit64u float64_to_uint64(float64, struct float_status_t *status);
-Bit64u float64_to_uint64_round_to_zero(float64, struct float_status_t *status);
-float32 float64_to_float32(float64, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int(float64, Bit8u scale, struct float_status_t *status);
-float64 float64_add(float64, float64, struct float_status_t *status);
-float64 float64_sub(float64, float64, struct float_status_t *status);
-float64 float64_mul(float64, float64, struct float_status_t *status);
-float64 float64_div(float64, float64, struct float_status_t *status);
-float64 float64_sqrt(float64, struct float_status_t *status);
-float64 float64_frc(float64, struct float_status_t *status);
-float64 float64_muladd(float64, float64, float64, int flags, struct float_status_t *status);
-float64 float64_scalef(float64, float64, struct float_status_t *status);
-int float64_compare(float64, float64, int quiet, struct float_status_t *status);
-
-BX_CPP_INLINE float64 float64_round_to_int_one(float64 a, struct float_status_t *status)
-{
- return float64_round_to_int(a, 0, status);
-}
-
-BX_CPP_INLINE float64 float64_fmadd(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, 0, status);
-}
-
-BX_CPP_INLINE float64 float64_fmsub(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_c, status);
-}
-
-BX_CPP_INLINE float64 float64_fnmadd(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_product, status);
-}
-
-BX_CPP_INLINE float64 float64_fnmsub(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_result, status);
-}
-
-BX_CPP_INLINE int float64_compare_two(float64 a, float64 b, struct float_status_t *status)
-{
- return float64_compare(a, b, 0, status);
-}
-
-BX_CPP_INLINE int float64_compare_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- return float64_compare(a, b, 1, status);
-}
-
-float_class_t float64_class(float64);
-
-float64 float64_min(float64 a, float64 b, struct float_status_t *status);
-float64 float64_max(float64 a, float64 b, struct float_status_t *status);
-
-float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status);
-float64 float64_getexp(float64 a, struct float_status_t *status);
-float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv);
-
-#ifdef FLOAT16
-float32 float16_to_float32(float16, struct float_status_t *status);
-float16 float32_to_float16(float32, struct float_status_t *status);
-
-float_class_t float16_class(float16);
-#endif
-
-#ifdef FLOATX80
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-
-#ifdef BX_BIG_ENDIAN
-typedef struct floatx80 { // leave alignment to compiler
- Bit16u exp;
- Bit64u fraction;
-}; floatx80
-#else
-typedef struct floatx80 {
- Bit64u fraction;
- Bit16u exp;
-} floatx80;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-floatx80 int32_to_floatx80(Bit32s);
-floatx80 int64_to_floatx80(Bit64s);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-floatx80 float32_to_floatx80(float32, struct float_status_t *status);
-floatx80 float64_to_floatx80(float64, struct float_status_t *status);
-
-Bit32s floatx80_to_int32(floatx80, struct float_status_t *status);
-Bit32s floatx80_to_int32_round_to_zero(floatx80, struct float_status_t *status);
-Bit64s floatx80_to_int64(floatx80, struct float_status_t *status);
-Bit64s floatx80_to_int64_round_to_zero(floatx80, struct float_status_t *status);
-
-float32 floatx80_to_float32(floatx80, struct float_status_t *status);
-float64 floatx80_to_float64(floatx80, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int(floatx80, struct float_status_t *status);
-floatx80 floatx80_add(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_sub(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_mul(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_div(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_sqrt(floatx80, struct float_status_t *status);
-
-float_class_t floatx80_class(floatx80);
-#ifdef __cplusplus
-}
-#endif
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-#ifdef BX_BIG_ENDIAN
-typedef struct float128 {
- Bit64u hi, lo;
-} float128;
-#else
-typedef struct float128 {
- Bit64u lo, hi;
-} float128;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-float128 floatx80_to_float128(floatx80 a, struct float_status_t *status);
-floatx80 float128_to_floatx80(float128 a, struct float_status_t *status);
-
-float128 int64_to_float128(Bit64s a);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_add(float128 a, float128 b, struct float_status_t *status);
-float128 float128_sub(float128 a, float128 b, struct float_status_t *status);
-float128 float128_mul(float128 a, float128 b, struct float_status_t *status);
-float128 float128_div(float128 a, float128 b, struct float_status_t *status);
-#ifdef __cplusplus
-}
-#endif
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat16.cc b/src/cpu/softfloat/softfloat16.cc
deleted file mode 100644
index 8c17d3a86e..0000000000
--- a/src/cpu/softfloat/softfloat16.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-
-#ifdef FLOAT16
-
-#include "softfloat-round-pack.h"
-#include "softfloat-specialize.h"
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Determine half-precision floating-point number class
-*----------------------------------------------------------------------------*/
-
-float_class_t float16_class(float16 a)
-{
- Bit16s aExp = extractFloat16Exp(a);
- Bit16u aSig = extractFloat16Frac(a);
- int aSign = extractFloat16Sign(a);
-
- if(aExp == 0x1F) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & 0x200) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0) return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the half-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float16_to_float32(float16 a, struct float_status_t *status)
-{
- Bit16u aSig = extractFloat16Frac(a);
- Bit16s aExp = extractFloat16Exp(a);
- int aSign = extractFloat16Sign(a);
-
- if (aExp == 0x1F) {
- if (aSig) return commonNaNToFloat32(float16ToCommonNaN(a, status));
- return packFloat32(aSign, 0xFF, 0);
- }
- if (aExp == 0) {
- // ignore denormals_are_zeros flag
- if (aSig == 0) return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat16Subnormal(aSig, &aExp, &aSig);
- --aExp;
- }
-
- return packFloat32(aSign, aExp + 0x70, ((Bit32u) aSig)<<13);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the half-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float16 float32_to_float16(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return commonNaNToFloat16(float32ToCommonNaN(a, status));
- return packFloat16(aSign, 0x1F, 0);
- }
- if (aExp == 0) {
- if (get_denormals_are_zeros(status)) aSig = 0;
- if (aSig == 0) return packFloat16(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- }
-
- aSig = shift32RightJamming(aSig, 9);
- Bit16u zSig = (Bit16u) aSig;
- if (aExp || zSig) {
- zSig |= 0x4000;
- aExp -= 0x71;
- }
-
- return roundAndPackFloat16(aSign, aExp, zSig, status);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc
deleted file mode 100644
index fc24096011..0000000000
--- a/src/cpu/softfloat/softfloatx80.cc
+++ /dev/null
@@ -1,384 +0,0 @@
-/*============================================================================
-This source file is an extension to the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
-floating point emulation.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Written for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include
-#include
-#include <86box/86box.h>
-#include "../cpu.h"
-
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
-#include "softfloat-macros.h"
-
-const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-const floatx80 Const_Z = packFloatx80(0, 0x0000, 0);
-const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
-const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe));
-const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc));
-const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
-const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799));
-const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac));
-const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000));
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-const float32 float32_negative_inf = 0xff800000;
-const float32 float32_positive_inf = 0x7f800000;
-const float32 float32_negative_zero = 0x80000000;
-const float32 float32_positive_zero = 0x00000000;
-const float32 float32_negative_one = 0xbf800000;
-const float32 float32_positive_one = 0x3f800000;
-const float32 float32_max_float = 0x7f7fffff;
-const float32 float32_min_float = 0xff7fffff;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-const float32 float32_default_nan = 0xffc00000;
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000);
-const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000);
-const float64 float64_negative_zero = BX_CONST64(0x8000000000000000);
-const float64 float64_positive_zero = BX_CONST64(0x0000000000000000);
-const float64 float64_negative_one = BX_CONST64(0xbff0000000000000);
-const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000);
-const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff);
-const float64 float64_min_float = BX_CONST64(0xffefffffffffffff);
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000);
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 16-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic - which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit16s floatx80_to_int16(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_unsupported(a)) {
- float_raise(status, float_flag_invalid);
- return int16_indefinite;
- }
-
- Bit32s v32 = floatx80_to_int32(a, status);
-
- if ((v32 > 32767) || (v32 < -32768)) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return int16_indefinite;
- }
-
- return (Bit16s) v32;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 16-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN or the conversion overflows, the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit16s floatx80_to_int16_round_to_zero(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_unsupported(a)) {
- float_raise(status, float_flag_invalid);
- return int16_indefinite;
- }
-
- Bit32s v32 = floatx80_to_int32_round_to_zero(a, status);
-
- if ((v32 > 32767) || (v32 < -32768)) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return int16_indefinite;
- }
-
- return (Bit16s) v32;
-}
-
-/*----------------------------------------------------------------------------
-| Separate the source extended double-precision floating point value `a'
-| into its exponent and significand, store the significant back to the
-| 'a' and return the exponent. The operation performed is a superset of
-| the IEC/IEEE recommended logb(x) function.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit64u aSig = extractFloatx80Frac(*a);
- Bit32s aExp = extractFloatx80Exp(*a);
- int aSign = extractFloatx80Sign(*a);
-
- if (floatx80_is_unsupported(*a))
- {
- float_raise(status, float_flag_invalid);
- *a = floatx80_default_nan;
- return *a;
- }
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- {
- *a = propagateFloatx80NaNOne(*a, status);
- return *a;
- }
- return packFloatx80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0)
- {
- if (aSig == 0) {
- float_raise(status, float_flag_divbyzero);
- *a = packFloatx80(aSign, 0, 0);
- return packFloatx80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
-
- a->exp = (aSign << 15) + 0x3FFF;
- a->fraction = aSig;
- return int32_to_floatx80(aExp - 0x3FFF);
-}
-
-/*----------------------------------------------------------------------------
-| Scales extended double-precision floating-point value in operand `a' by
-| value `b'. The function truncates the value in the second operand 'b' to
-| an integral value and adds that value to the exponent of the operand 'a'.
-| The operation performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp;
- Bit64u aSig, bSig;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
- }
- if ((bExp == 0x7FFF) && bSign) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- if (! bSign) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- return a;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- if (bSign) return packFloatx80(aSign, 0, 0);
- return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- if (aSig == 0) return a;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- if (bExp < 0x3FFF)
- return normalizeRoundAndPackFloatx80(80, aSign, aExp, aSig, 0, status);
- }
- if (bExp == 0) {
- if (bSig == 0) return a;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
-
- if (bExp > 0x400E) {
- /* generate appropriate overflow/underflow */
- return roundAndPackFloatx80(80, aSign,
- bSign ? -0x3FFF : 0x7FFF, aSig, 0, status);
- }
-
- if (bExp < 0x3FFF) return a;
-
- int shiftCount = 0x403E - bExp;
- bSig >>= shiftCount;
- Bit32s scale = (Bit32s) bSig;
- if (bSign) scale = -scale; /* -32768..32767 */
- return
- roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine extended-precision floating-point number class.
-*----------------------------------------------------------------------------*/
-
-float_class_t floatx80_class(floatx80 a)
-{
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u aSig = extractFloatx80Frac(a);
-
- if(aExp == 0) {
- if (aSig == 0)
- return float_zero;
-
- /* denormal or pseudo-denormal */
- return float_denormal;
- }
-
- /* valid numbers have the MS bit set */
- if (!(aSig & BX_CONST64(0x8000000000000000)))
- return float_SNaN; /* report unsupported as SNaNs */
-
- if(aExp == 0x7fff) {
- int aSign = extractFloatx80Sign(a);
-
- if (((Bit64u) (aSig<< 1)) == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & BX_CONST64(0x4000000000000000)) ? float_QNaN : float_SNaN;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two extended precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *status)
-{
- float_class_t aClass = floatx80_class(a);
- float_class_t bClass = floatx80_class(b);
-
- if (fpu_type < FPU_287XL) {
- if ((aClass == float_positive_inf) && (bClass == float_negative_inf))
- {
- return float_relation_equal;
- }
-
- if ((aClass == float_negative_inf) && (bClass == float_positive_inf))
- {
- return float_relation_equal;
- }
- }
-
- if (aClass == float_SNaN || bClass == float_SNaN)
- {
- /* unsupported reported as SNaN */
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aClass == float_zero) {
- if (bClass == float_zero) return float_relation_equal;
- return bSign ? float_relation_greater : float_relation_less;
- }
-
- if (bClass == float_zero || aSign != bSign) {
- return aSign ? float_relation_less : float_relation_greater;
- }
-
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
-
- if (aClass == float_denormal)
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
-
- if (bClass == float_denormal)
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
-
- if (aExp == bExp && aSig == bSig)
- return float_relation_equal;
-
- int less_than =
- aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
- : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));
-
- if (less_than) return float_relation_less;
- return float_relation_greater;
-}
-
-
-int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- return floatx80_compare(a, b, 0, status);
-}
-
-int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- return floatx80_compare(a, b, 1, status);
-}
diff --git a/src/cpu/softfloat/softfloatx80.h b/src/cpu/softfloat/softfloatx80.h
deleted file mode 100644
index 1f96141b4c..0000000000
--- a/src/cpu/softfloat/softfloatx80.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*============================================================================
-This source file is an extension to the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
-floating point emulation.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Written for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOATX80_EXTENSIONS_H_
-#define _SOFTFLOATX80_EXTENSIONS_H_
-
-#include "softfloat.h"
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-Bit16s floatx80_to_int16(floatx80, struct float_status_t *status);
-Bit16s floatx80_to_int16_round_to_zero(floatx80, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status);
-floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status);
-int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status);
-int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status);
-floatx80 f2xm1(floatx80 a, struct float_status_t *status);
-floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status);
-floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status);
-floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision trigonometric functions.
-*----------------------------------------------------------------------------*/
-
-int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status);
-int fsin(floatx80 *a, struct float_status_t *status);
-int fcos(floatx80 *a, struct float_status_t *status);
-int ftan(floatx80 *a, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision compare.
-*----------------------------------------------------------------------------*/
-
-int floatx80_compare(floatx80, floatx80, int quiet, struct float_status_t *status);
-int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status);
-int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*-----------------------------------------------------------------------------
-| Calculates the absolute value of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-BX_CPP_INLINE floatx80& floatx80_abs(floatx80 ®)
-#else
-BX_CPP_INLINE floatx80 floatx80_abs(floatx80 reg)
-#endif
-{
- reg.exp &= 0x7FFF;
- return reg;
-}
-
-/*-----------------------------------------------------------------------------
-| Changes the sign of the extended double-precision floating-point value 'a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-BX_CPP_INLINE floatx80& floatx80_chs(floatx80 ®)
-#else
-BX_CPP_INLINE floatx80 floatx80_chs(floatx80 reg)
-#endif
-{
- reg.exp ^= 0x8000;
- return reg;
-}
-
-/*-----------------------------------------------------------------------------
-| Commonly used extended double-precision floating-point constants.
-*----------------------------------------------------------------------------*/
-
-extern const floatx80 Const_Z;
-extern const floatx80 Const_1;
-extern const floatx80 Const_L2T;
-extern const floatx80 Const_L2E;
-extern const floatx80 Const_PI;
-extern const floatx80 Const_LG2;
-extern const floatx80 Const_LN2;
-extern const floatx80 Const_INF;
-#endif
diff --git a/src/cpu/softfloat3e/CMakeLists.txt b/src/cpu/softfloat3e/CMakeLists.txt
new file mode 100644
index 0000000000..5565460c84
--- /dev/null
+++ b/src/cpu/softfloat3e/CMakeLists.txt
@@ -0,0 +1,56 @@
+#
+# 86Box A hypervisor and IBM PC system emulator that specializes in
+# running old operating systems and software designed for IBM
+# PC systems and compatibles from 1981 through fairly recent
+# system designs based on the PCI bus.
+#
+# This file is part of the 86Box distribution.
+#
+# CMake build script.
+#
+# Authors: David Hrdlička,
+#
+# Copyright 2020-2021 David Hrdlička.
+#
+
+add_library(softfloat3e OBJECT extF80_addsub.cc extF80_class.cc extF80_compare.cc
+ extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc
+ extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc
+ extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc
+ extF80_to_i64_r_minMag.cc extF80_to_ui32.cc extF80_to_ui32_r_minMag.cc extF80_to_ui64.cc
+ extF80_to_ui64_r_minMag.cc f16_addsub.c f16_class.c f16_compare.c f16_div.c f16_getExp.c
+ f16_getMant.c f16_minmax.c f16_mul.c f16_mulAdd.c f16_range.c f16_roundToInt.c
+ f16_sqrt.c f16_to_extF80.cc f16_to_f32.c f16_to_f64.c f16_to_i32.c f16_to_i32_r_minMag.c
+ f16_to_i64.c f16_to_i64_r_minMag.c f16_to_ui32.c f16_to_ui32_r_minMag.c f16_to_ui64.c
+ f16_to_ui64_r_minMag.c f32_addsub.c f32_class.c f32_compare.c f32_div.c f32_frc.c
+ f32_getExp.c f32_getMant.c f32_minmax.c f32_mul.c f32_mulAdd.c f32_range.c
+ f32_roundToInt.c f32_scalef.c f32_sqrt.c f32_to_extF80.cc f32_to_f16.c f32_to_f64.c
+ f32_to_f128.cc f32_to_i32.c f32_to_i32_r_minMag.c f32_to_i64.c f32_to_i64_r_minMag.c
+ f32_to_ui32.c f32_to_ui32_r_minMag.c f32_to_ui64.c f32_to_ui64_r_minMag.c f64_addsub.c
+ f64_class.c f64_compare.c f64_div.c f64_frc.c f64_getExp.c f64_getMant.c f64_minmax.c
+ f64_mul.c f64_mulAdd.c f64_range.c f64_roundToInt.c f64_scalef.c f64_sqrt.c f64_to_extF80.cc
+ f64_to_f16.c f64_to_f32.c f64_to_f128.cc f64_to_i32.c f64_to_i32_r_minMag.c f64_to_i64.c
+ f64_to_i64_r_minMag.c f64_to_ui32.c f64_to_ui32_r_minMag.c f64_to_ui64.c f64_to_ui64_r_minMag.c
+ f128_addsub.cc f128_div.cc f128_mul.cc f128_mulAdd.cc f128_roundToInt.cc f128_to_extF80.cc
+ f128_to_f32.cc f128_to_f64.cc f128_to_i32.cc f128_to_i32_r_minMag.cc f128_to_i64.cc
+ f128_to_i64_r_minMag.cc f128_to_ui32.cc f128_to_ui32_r_minMag.cc f128_to_ui64.cc
+ f128_to_ui64_r_minMag.cc i32_to_extF80.cc i32_to_f16.c i32_to_f32.c i32_to_f64.c
+ i32_to_f128.cc i64_to_extF80.cc i64_to_f16.c i64_to_f32.c i64_to_f64.c i64_to_f128.cc
+ isNaN.cc isSignalingNaN.cc s_add128.cc s_add256M.c s_addMagsExtF80.cc s_addMagsF16.c
+ s_addMagsF32.c s_addMagsF64.c s_addMagsF128.cc s_approxRecip_1Ks.c s_approxRecipSqrt_1Ks.c
+ s_approxRecipSqrt32_1.c s_commonNaNToExtF80UI.cc s_commonNaNToF16UI.c s_commonNaNToF32UI.c
+ s_commonNaNToF64UI.c s_commonNaNToF128UI.cc s_countLeadingZeros8.c s_countLeadingZeros16.c
+ s_countLeadingZeros32.c s_countLeadingZeros64.c s_eq128.c s_le128.c s_lt128.c
+ s_mul64ByShifted32To128.cc s_mul64To128.cc s_mul128By32.cc s_mul128To256M.cc
+ s_normRoundPackToExtF80.cc s_normRoundPackToF16.c s_normRoundPackToF32.c s_normRoundPackToF64.c
+ s_normRoundPackToF128.cc s_normSubnormalExtF80Sig.cc s_normSubnormalF16Sig.c
+ s_normSubnormalF32Sig.c s_normSubnormalF64Sig.c s_normSubnormalF128Sig.cc s_packToExtF80.cc
+ s_propagateNaNExtF80UI.cc s_propagateNaNF16UI.c s_propagateNaNF32UI.c s_propagateNaNF64UI.c
+ s_propagateNaNF128UI.cc s_roundPackToExtF80.cc s_roundPackToF16.c s_roundPackToF32.c
+ s_roundPackToF64.c s_roundPackToF128.cc s_roundToI32.c s_roundToI64.c s_roundToUI32.c
+ s_roundToUI64.c s_shiftRightJam32.c s_shiftRightJam64.c s_shiftRightJam64Extra.c
+ s_shiftRightJam256M.c s_shortShiftLeft128.cc s_shortShiftRight128.cc s_shortShiftRightJam64.c
+ s_shortShiftRightJam64Extra.c s_sub128.cc s_sub256M.c s_subMagsExtF80.cc s_subMagsF16.c
+ s_subMagsF32.c s_subMagsF64.c s_subMagsF128.cc ui32_to_extF80.cc ui32_to_f16.c ui32_to_f32.c
+ ui32_to_f64.c ui32_to_f128.cc ui64_to_extF80.cc ui64_to_f16.c ui64_to_f32.c ui64_to_f64.c
+ ui64_to_f128.cc f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc poly.cc consts.cc)
\ No newline at end of file
diff --git a/src/cpu/softfloat3e/COPYING.txt b/src/cpu/softfloat3e/COPYING.txt
new file mode 100644
index 0000000000..b5690face0
--- /dev/null
+++ b/src/cpu/softfloat3e/COPYING.txt
@@ -0,0 +1,37 @@
+
+License for Berkeley SoftFloat Release 3e
+
+John R. Hauser
+2018 January 20
+
+The following applies to the whole of SoftFloat Release 3e as well as to
+each source file individually.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/cpu/softfloat3e/README.html b/src/cpu/softfloat3e/README.html
new file mode 100644
index 0000000000..e695c2bd82
--- /dev/null
+++ b/src/cpu/softfloat3e/README.html
@@ -0,0 +1,49 @@
+
+
+
+
+Berkeley SoftFloat Package Overview
+
+
+
+
+
Package Overview for Berkeley SoftFloat Release 3e
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Berkeley SoftFloat is a software implementation of binary floating-point that
+conforms to the IEEE Standard for Floating-Point Arithmetic.
+SoftFloat is distributed in the form of C source code.
+Building the SoftFloat sources generates a library file (typically
+softfloat.a
or libsoftfloat.a
) containing the
+floating-point subroutines.
+
+
+
+The SoftFloat package is documented in the following files in the
+doc
subdirectory:
+
+
+
+Other files in the package comprise the source code for SoftFloat.
+
+
+
+
diff --git a/src/cpu/softfloat3e/README.txt b/src/cpu/softfloat3e/README.txt
new file mode 100644
index 0000000000..1613c76718
--- /dev/null
+++ b/src/cpu/softfloat3e/README.txt
@@ -0,0 +1,21 @@
+
+Package Overview for Berkeley SoftFloat Release 3e
+
+John R. Hauser
+2018 January 20
+
+Berkeley SoftFloat is a software implementation of binary floating-point
+that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat
+is distributed in the form of C source code. Building the SoftFloat sources
+generates a library file (typically "softfloat.a" or "libsoftfloat.a")
+containing the floating-point subroutines.
+
+The SoftFloat package is documented in the following files in the "doc"
+subdirectory:
+
+ SoftFloat.html Documentation for using the SoftFloat functions.
+ SoftFloat-source.html Documentation for building SoftFloat.
+ SoftFloat-history.html History of the major changes to SoftFloat.
+
+Other files in the package comprise the source code for SoftFloat.
+
diff --git a/src/cpu/softfloat3e/config.h b/src/cpu/softfloat3e/config.h
new file mode 100644
index 0000000000..9febce2424
--- /dev/null
+++ b/src/cpu/softfloat3e/config.h
@@ -0,0 +1,14 @@
+#ifndef EMU_SF_CONFIG_H
+#define EMU_SF_CONFIG_H
+
+/*----------------------------------------------------------------------------
+| The `LIT64' macro takes as its argument a textual integer literal and
+| if necessary ``marks'' the literal as having a 64-bit integer type.
+| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+| appended with the letters `LL' standing for `long long', which is `gcc's
+| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
+| defined as the identity macro: `#define LIT64( a ) a'.
+*----------------------------------------------------------------------------*/
+#define BX_CONST64(a) a##LL
+
+#endif /*EMU_SF_CONFIG_H*/
diff --git a/src/cpu/softfloat3e/consts.cc b/src/cpu/softfloat3e/consts.cc
new file mode 100644
index 0000000000..235a039965
--- /dev/null
+++ b/src/cpu/softfloat3e/consts.cc
@@ -0,0 +1,51 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include <86box/86box.h>
+#include "../cpu.h"
+
+#include "softfloat-specialize.h"
+
+const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+const floatx80 Const_Z = packFloatx80(0, 0x0000, 0);
+const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
+const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe));
+const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc));
+const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
+const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799));
+const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac));
+const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000));
diff --git a/src/cpu/softfloat3e/doc/SoftFloat-history.html b/src/cpu/softfloat3e/doc/SoftFloat-history.html
new file mode 100644
index 0000000000..d81c6bc5a2
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat-history.html
@@ -0,0 +1,258 @@
+
+
+
+
+Berkeley SoftFloat History
+
+
+
+
+History of Berkeley SoftFloat, to Release 3e
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Release 3e (2018 January)
+
+
+
+-
+Changed the default numeric code for optional rounding mode
odd
+(round to odd, also known as jamming) from 5 to 6.
+
+ -
+Modified the behavior of rounding mode
odd
when rounding to an
+integer value (either conversion to an integer format or a
+‘roundToInt
’ function).
+Previously, for those cases only, rounding mode odd
acted the same
+as rounding to minimum magnitude.
+Now all operations are rounded consistently.
+
+ -
+Fixed some errors in the specialization code modeling Intel x86 floating-point,
+specifically the integers returned on invalid operations and the propagation of
+NaN payloads in a few rare cases.
+
+
-
+Added specialization code modeling ARM floating-point, conforming to VFPv2 or
+later.
+
+
-
+Added an example target for ARM processors.
+
+
-
+Fixed a minor bug whereby function
f16_to_ui64
might return a
+different integer than expected in the case that the floating-point operand is
+negative.
+
+ -
+Added example target-specific optimization for GCC, employing GCC instrinsics
+and support for 128-bit integer arithmetic.
+
+
-
+Made other minor improvements.
+
+
+
+
+Release 3d (2017 August)
+
+
+
+-
+Fixed bugs in the square root functions for 64-bit
+double-precision, 80-bit double-extended-precision, and
+128-bit quadruple-precision.
+For 64-bit double-precision (
f64_sqrt
), the result
+could sometimes be off by 1 unit in the last place
+(1 ulp) from what it should be.
+For the larger formats, the square root could be wrong in a large portion of
+the less-significant bits.
+(A bug in f128_sqrt
was first reported by Alexei Sibidanov.)
+
+
+
+
+Release 3c (2017 February)
+
+
+
+-
+Added optional rounding mode
odd
(round to odd, also known as
+jamming).
+
+ -
+Corrected the documentation concerning non-canonical representations in
+80-bit double-extended-precision.
+
+
+
+
+Release 3b (2016 July)
+
+
+
+-
+Implemented the common 16-bit “half-precision”
+floating-point format (
float16_t
).
+
+ -
+Made the integer values returned on invalid conversions to integer formats
+be determined by the port-specific specialization instead of being the same for
+all ports.
+
+
-
+Added preprocessor macro
THREAD_LOCAL
to allow the floating-point
+state (modes and exception flags) to be made per-thread.
+
+ -
+Modified the provided Makefiles to allow some options to be overridden from the
+
make
command.
+
+ -
+Made other minor improvements.
+
+
+
+
+Release 3a (2015 October)
+
+
+
+-
+Replaced the license text supplied by the University of California, Berkeley.
+
+
+
+
+Release 3 (2015 February)
+
+
+
+-
+Complete rewrite, funded by the University of California, Berkeley, and
+consequently having a different use license than earlier releases.
+Major changes included renaming most types and functions, upgrading some
+algorithms, restructuring the source files, and making SoftFloat into a true
+library.
+
+
-
+Added functions to convert between floating-point and unsigned integers, both
+32-bit and 64-bit (
uint32_t
and
+uint64_t
).
+
+ -
+Added functions for fused multiply-add, for all supported floating-point
+formats except 80-bit double-extended-precision.
+
+
-
+Added support for a fifth rounding mode,
near_maxMag
(round to
+nearest, with ties to maximum magnitude, away from zero).
+
+ -
+Dropped the
timesoftfloat
program (now part of the Berkeley
+TestFloat package).
+
+
+
+
+Release 2c (2015 January)
+
+
+
+-
+Fixed mistakes affecting some 64-bit processors.
+
+
-
+Further improved the documentation and the wording for the legal restrictions
+on using SoftFloat releases through 2c (not applicable to
+Release 3 or later).
+
+
+
+
+Release 2b (2002 May)
+
+
+
+-
+Made minor updates to the documentation, including improved wording for the
+legal restrictions on using SoftFloat.
+
+
+
+
+Release 2a (1998 December)
+
+
+
+-
+Added functions to convert between 64-bit integers
+(
int64
) and all supported floating-point formats.
+
+ -
+Fixed a bug in all 64-bit-version square root functions except
+
float32_sqrt
that caused the result sometimes to be off by
+1 unit in the last place (1 ulp) from what it should
+be.
+(Bug discovered by Paul Donahue.)
+
+ -
+Improved the Makefiles.
+
+
+
+Release 2 (1997 June)
+
+
+
+-
+Created the 64-bit (
bits64
) version, adding the
+floatx80
and float128
formats.
+
+ -
+Changed the source directory structure, splitting the sources into a
+
bits32
and a bits64
version.
+Renamed environment.h
to milieu.h
to avoid confusion
+with environment variables.
+
+ -
+Fixed a small error that caused
float64_round_to_int
often to
+round the wrong way in nearest/even mode when the operand was between
+220 and 221 and halfway between two integers.
+
+
+
+
+Release 1a (1996 July)
+
+
+
+-
+Corrected a mistake that caused borderline underflow cases not to raise the
+underflow flag when they should have.
+(Problem reported by Doug Priest.)
+
+
-
+Added the
float_detect_tininess
variable to control whether
+tininess is detected before or after rounding.
+
+
+
+
+Release 1 (1996 July)
+
+
+
+-
+Original release, based on work done for the International Computer Science
+Institute (ICSI) in Berkeley, California.
+
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/doc/SoftFloat-source.html b/src/cpu/softfloat3e/doc/SoftFloat-source.html
new file mode 100644
index 0000000000..4ff9d4c45a
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat-source.html
@@ -0,0 +1,686 @@
+
+
+
+
+Berkeley SoftFloat Source Documentation
+
+
+
+
+Berkeley SoftFloat Release 3e: Source Documentation
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Contents
+
+
+
+
+
+1. Introduction |
+2. Limitations |
+3. Acknowledgments and License |
+4. SoftFloat Package Directory Structure |
+5. Issues for Porting SoftFloat to a New Target |
+
+ |
+ 5.1. Standard Headers <stdbool.h> and
+ <stdint.h> |
+
+ | 5.2. Specializing Floating-Point Behavior |
+ | 5.3. Macros for Build Options |
+ | 5.4. Adapting a Template Target Directory |
+
+ | 5.5. Target-Specific Optimization of Primitive Functions |
+
+6. Testing SoftFloat |
+
+ 7. Providing SoftFloat as a Common Library for Applications |
+
+8. Contact Information |
+
+
+
+
+1. Introduction
+
+
+This document gives information needed for compiling and/or porting Berkeley
+SoftFloat, a library of C functions implementing binary floating-point
+conforming to the IEEE Standard for Floating-Point Arithmetic.
+For basic documentation about SoftFloat refer to
+SoftFloat.html
.
+
+
+
+The source code for SoftFloat is intended to be relatively machine-independent
+and should be compilable with any ISO-Standard C compiler that also supports
+64-bit integers.
+SoftFloat has been successfully compiled with the GNU C Compiler
+(gcc
) for several platforms.
+
+
+
+Release 3 of SoftFloat was a complete rewrite relative to
+Release 2 or earlier.
+Changes to the interface of SoftFloat functions are documented in
+SoftFloat.html
.
+The current version of SoftFloat is Release 3e.
+
+
+
+2. Limitations
+
+
+SoftFloat assumes the computer has an addressable byte size of either 8 or
+16 bits.
+(Nearly all computers in use today have 8-bit bytes.)
+
+
+
+SoftFloat is written in C and is designed to work with other C code.
+The C compiler used must conform at a minimum to the 1989 ANSI standard for the
+C language (same as the 1990 ISO standard) and must in addition support basic
+arithmetic on 64-bit integers.
+Earlier releases of SoftFloat included implementations of 32-bit
+single-precision and 64-bit double-precision floating-point that
+did not require 64-bit integers, but this option is not supported
+starting with Release 3.
+Since 1999, ISO standards for C have mandated compiler support for
+64-bit integers.
+A compiler conforming to the 1999 C Standard or later is recommended but not
+strictly required.
+
+
+
+C Standard header files <stdbool.h>
and
+<stdint.h>
are required for defining standard Boolean and
+integer types.
+If these headers are not supplied with the C compiler, minimal substitutes must
+be provided.
+SoftFloat’s dependence on these headers is detailed later in
+section 5.1, Standard Headers <stdbool.h>
+and <stdint.h>
.
+
+
+
+3. Acknowledgments and License
+
+
+The SoftFloat package was written by me, John R. Hauser.
+Release 3 of SoftFloat was a completely new implementation
+supplanting earlier releases.
+The project to create Release 3 (now through 3e) was
+done in the employ of the University of California, Berkeley, within the
+Department of Electrical Engineering and Computer Sciences, first for the
+Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab.
+The work was officially overseen by Prof. Krste Asanovic, with funding provided
+by these sources:
+
+
+
+
+
+
+Par Lab: |
+ |
+
+Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery
+(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia,
+NVIDIA, Oracle, and Samsung.
+ |
+
+
+ASPIRE Lab: |
+ |
+
+DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from
+ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA,
+Oracle, and Samsung.
+ |
+
+
+
+
+
+
+The following applies to the whole of SoftFloat Release 3e as well
+as to each source file individually.
+
+
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California.
+All rights reserved.
+
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+
+-
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions, and the following disclaimer.
+
+
+ -
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions, and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+
+ -
+
+Neither the name of the University nor the names of its contributors may be
+used to endorse or promote products derived from this software without specific
+prior written permission.
+
+
+
+
+
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”,
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+4. SoftFloat Package Directory Structure
+
+
+Because SoftFloat is targeted to multiple platforms, its source code is
+slightly scattered between target-specific and target-independent directories
+and files.
+The supplied directory structure is as follows:
+
+
+doc
+source
+ include
+ 8086
+ 8086-SSE
+ ARM-VFPv2
+ ARM-VFPv2-defaultNaN
+build
+ template-FAST_INT64
+ template-not-FAST_INT64
+ Linux-386-GCC
+ Linux-386-SSE2-GCC
+ Linux-x86_64-GCC
+ Linux-ARM-VFPv2-GCC
+ Win32-MinGW
+ Win32-SSE2-MinGW
+ Win64-MinGW-w64
+
+
+The majority of the SoftFloat sources are provided in the source
+directory.
+The include
subdirectory contains several header files
+(unsurprisingly), while the other subdirectories of source
contain
+source files that specialize the floating-point behavior to match particular
+processor families:
+
+
+8086
+-
+Intel’s older, 8087-derived floating-point, extended to all supported
+floating-point types
+
+8086-SSE
+-
+Intel’s x86 processors with Streaming SIMD Extensions (SSE) and later
+compatible extensions, having 8087 behavior for 80-bit
+double-extended-precision (
extFloat80_t
) and SSE behavior for
+other floating-point types
+
+ARM-VFPv2
+-
+ARM’s VFPv2 or later floating-point, with NaN payload propagation
+
+ARM-VFPv2-defaultNaN
+-
+ARM’s VFPv2 or later floating-point, with the “default NaN”
+option
+
+
+
+If other specializations are attempted, these would be expected to be other
+subdirectories of source
alongside the ones listed above.
+Specialization is covered later, in section 5.2, Specializing
+Floating-Point Behavior.
+
+
+
+The build
directory is intended to contain a subdirectory for each
+target platform for which a build of the SoftFloat library may be created.
+For each build target, the target’s subdirectory is where all derived
+object files and the completed SoftFloat library (typically
+softfloat.a
or libsoftfloat.a
) are created.
+The two template
subdirectories are not actual build targets but
+contain sample files for creating new target directories.
+(The meaning of FAST_INT64
will be explained later.)
+
+
+
+Ignoring the template
directories, the supplied target directories
+are intended to follow a naming system of
+<execution-environment>-<compiler>
.
+For the example targets,
+<execution-environment>
is
+Linux-386
, Linux-386-SSE2
,
+Linux-x86_64
,
+Linux-ARM-VFPv2
, Win32
,
+Win32-SSE2
, or Win64
, and
+<compiler>
is GCC
,
+MinGW
, or MinGW-w64
.
+
+
+
+All of the supplied target directories are merely examples that may or may not
+be correct for compiling on any particular system.
+Despite requests, there are currently no plans to include and maintain in the
+SoftFloat package the build files needed for a great many users’
+compilation environments, which can span a huge range of operating systems,
+compilers, and other tools.
+
+
+
+As supplied, each target directory contains two files:
+
+
+Makefile
+platform.h
+
+
+The provided Makefile
is written for GNU make
.
+A build of SoftFloat for the specific target is begun by executing the
+make
command with the target directory as the current directory.
+A completely different build tool can be used if an appropriate
+Makefile
equivalent is created.
+
+
+
+The platform.h
header file exists to provide a location for
+additional C declarations specific to the build target.
+Every C source file of SoftFloat contains a #include
for
+platform.h
.
+In many cases, the contents of platform.h
can be as simple as one
+or two lines of code.
+At the other extreme, to get maximal performance from SoftFloat, it may be
+desirable to include in header platform.h
(directly or via
+#include
) declarations for numerous target-specific optimizations.
+Such possibilities are discussed in the next section, Issues for Porting
+SoftFloat to a New Target.
+If the target’s compiler or library has bugs or other shortcomings,
+workarounds for these issues may also be possible with target-specific
+declarations in platform.h
, avoiding the need to modify the main
+SoftFloat sources.
+
+
+
+5. Issues for Porting SoftFloat to a New Target
+
+5.1. Standard Headers <stdbool.h>
and <stdint.h>
+
+
+The SoftFloat sources make use of standard headers
+<stdbool.h>
and <stdint.h>
, which have
+been part of the ISO C Standard Library since 1999.
+With any recent compiler, these standard headers are likely to be supported,
+even if the compiler does not claim complete conformance to the latest ISO C
+Standard.
+For older or nonstandard compilers, substitutes for
+<stdbool.h>
and <stdint.h>
may need to be
+created.
+SoftFloat depends on these names from <stdbool.h>
:
+
+
+bool
+true
+false
+
+
+and on these names from <stdint.h>
:
+
+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+UINT64_C
+INT64_C
+uint_least8_t
+uint_fast8_t
+uint_fast16_t
+uint_fast32_t
+uint_fast64_t
+int_fast8_t
+int_fast16_t
+int_fast32_t
+int_fast64_t
+
+
+
+
+
+5.2. Specializing Floating-Point Behavior
+
+
+The IEEE Floating-Point Standard allows for some flexibility in a conforming
+implementation, particularly concerning NaNs.
+The SoftFloat source
directory is supplied with some
+specialization subdirectories containing possible definitions for this
+implementation-specific behavior.
+For example, the 8086
and 8086-SSE
+subdirectories have source files that specialize SoftFloat’s behavior to
+match that of Intel’s x86 line of processors.
+The files in a specialization subdirectory must determine:
+
+-
+whether tininess for underflow is detected before or after rounding by default;
+
-
+how signaling NaNs are distinguished from quiet NaNs;
+
-
+what (if anything) special happens when exceptions are raised;
+
-
+the default generated quiet NaNs;
+
-
+how NaNs are propagated from function inputs to output; and
+
-
+the integer results returned when conversions to integer type raise the
+invalid exception.
+
+
+
+
+As provided, the build process for a target expects to involve exactly
+one specialization directory that defines all of these
+implementation-specific details for the target.
+A specialization directory such as 8086
is expected to contain a
+header file called specialize.h
, together with whatever other
+source files are needed to complete the specialization.
+
+
+
+A new build target may use an existing specialization, such as the ones
+provided by the 8086
and 8086-SSE
+subdirectories.
+If a build target needs a new specialization, different from any existing ones,
+it is recommended that a new specialization directory be created for this
+purpose.
+The specialize.h
header file from any of the provided
+specialization subdirectories can be used as a model for what definitions are
+needed.
+
+
+
+5.3. Macros for Build Options
+
+
+The SoftFloat source files adapt the floating-point implementation according to
+several C preprocessor macros:
+
+
+LITTLEENDIAN
+-
+Must be defined for little-endian machines; must not be defined for big-endian
+machines.
+
INLINE
+-
+Specifies the sequence of tokens used to indicate that a C function should be
+inlined.
+If macro
INLINE_LEVEL
is defined with a value of 1 or higher, this
+macro must be defined; otherwise, this macro is ignored and need not be
+defined.
+For compilers that conform to the C Standard’s rules for inline
+functions, this macro can be defined as the single keyword inline
.
+For other compilers that follow a convention pre-dating the standardization of
+inline
, this macro may need to be defined to extern
+inline
.
+ THREAD_LOCAL
+-
+Can be defined to a sequence of tokens that, when appearing at the start of a
+variable declaration, indicates to the C compiler that the variable is
+per-thread, meaning that each execution thread gets its own separate
+instance of the variable.
+This macro is used in header
softfloat.h
in the declarations of
+variables softfloat_roundingMode
,
+softfloat_detectTininess
, extF80_roundingPrecision
,
+and softfloat_exceptionFlags
.
+If macro THREAD_LOCAL
is left undefined, these variables will
+default to being ordinary global variables.
+Depending on the compiler, possible valid definitions of this macro include
+_Thread_local
and __thread
.
+
+
+SOFTFLOAT_ROUND_ODD
+-
+Can be defined to enable support for optional rounding mode
+
softfloat_round_odd
.
+
+
+INLINE_LEVEL
+-
+Can be defined to an integer to determine the degree of inlining requested of
+the compiler.
+Larger numbers request that more inlining be done.
+If this macro is not defined or is defined to a value less than 1
+(zero or negative), no inlining is requested.
+The maximum effective value is no higher than 5.
+Defining this macro to a value greater than 5 is the same as defining it
+to 5.
+
SOFTFLOAT_FAST_INT64
+-
+Can be defined to indicate that the build target’s implementation of
+64-bit arithmetic is efficient.
+For newer 64-bit processors, this macro should usually be defined.
+For very small microprocessors whose buses and registers are 8-bit
+or 16-bit in size, this macro should usually not be defined.
+Whether this macro should be defined for a 32-bit processor may
+depend on the target machine and the applications that will use SoftFloat.
+
SOFTFLOAT_FAST_DIV32TO16
+-
+Can be defined to indicate that the target’s division operator
+in C (written as
/
) is reasonably efficient for
+dividing a 32-bit unsigned integer by a 16-bit
+unsigned integer.
+Setting this macro may affect the performance of function f16_div
.
+ SOFTFLOAT_FAST_DIV64TO32
+-
+Can be defined to indicate that the target’s division operator
+in C (written as
/
) is reasonably efficient for
+dividing a 64-bit unsigned integer by a 32-bit
+unsigned integer.
+Setting this macro may affect the performance of division, remainder, and
+square root operations other than f16_div
.
+
+
+
+
+
+Following the usual custom for C, for most of these macros (all
+except INLINE
, THREAD_LOCAL
, and
+INLINE_LEVEL
), the content of any definition is irrelevant;
+what matters is a macro’s effect on #ifdef
directives.
+
+
+
+It is recommended that any definitions of macros LITTLEENDIAN
,
+INLINE
, and THREAD_LOCAL
be made in a build
+target’s platform.h
header file, because these macros are
+expected to be determined inflexibly by the target machine and compiler.
+The other five macros select options and control optimization, and thus might
+be better located in the target’s Makefile (or its equivalent).
+
+
+
+5.4. Adapting a Template Target Directory
+
+
+In the build
directory, two template
subdirectories
+provide models for new target directories.
+Two different templates exist because different functions are needed in the
+SoftFloat library depending on whether macro SOFTFLOAT_FAST_INT64
+is defined.
+If macro SOFTFLOAT_FAST_INT64
will be defined,
+template-FAST_INT64
is the template to use;
+otherwise, template-not-FAST_INT64
is the appropriate
+template.
+A new target directory can be created by copying the correct template directory
+and editing the files inside.
+To avoid confusion, it would be wise to refrain from editing the files within a
+template directory directly.
+
+
+
+5.5. Target-Specific Optimization of Primitive Functions
+
+
+Header file primitives.h
(in directory
+source/include
) declares macros and functions for numerous
+underlying arithmetic operations upon which many of SoftFloat’s
+floating-point functions are ultimately built.
+The SoftFloat sources include implementations of all of these functions/macros,
+written as standard C code, so a complete and correct SoftFloat library can be
+created using only the supplied code for all functions.
+However, for many targets, SoftFloat’s performance can be improved by
+substituting target-specific implementations of some of the functions/macros
+declared in primitives.h
.
+
+
+
+For example, primitives.h
declares a function called
+softfloat_countLeadingZeros32
that takes an unsigned
+32-bit integer as an argument and returns the number of the
+integer’s most-significant bits that are zeros.
+While the SoftFloat sources include an implementation of this function written
+in standard C, many processors can perform this same function
+directly in only one or two machine instructions.
+An alternative, target-specific implementation that maps to those instructions
+is likely to be more efficient than the generic C code from the SoftFloat
+package.
+
+
+
+A build target can replace the supplied version of any function or macro of
+primitives.h
by defining a macro with the same name in the
+target’s platform.h
header file.
+For this purpose, it may be helpful for platform.h
to
+#include
header file primitiveTypes.h
, which defines
+types used for arguments and results of functions declared in
+primitives.h
.
+When a desired replacement implementation is a function, not a macro, it is
+sufficient for platform.h
to include the line
+
+
+#define <function-name> <function-name>
+
+
+where <function-name>
is the name of the
+function.
+This technically defines <function-name>
+as a macro, but one that resolves to the same name, which may then be a
+function.
+(A preprocessor that conforms to the C Standard is required to limit recursive
+macro expansion from being applied more than once.)
+
+
+
+The supplied header file opts-GCC.h
(in directory
+source/include
) provides an example of target-specific
+optimization for the GCC compiler.
+Each GCC target example in the build
directory has
+
+#include "opts-GCC.h"
+
+in its platform.h
header file.
+Before opts-GCC.h
is included, the following macros must be
+defined (or not) to control which features are invoked:
+
+
+SOFTFLOAT_BUILTIN_CLZ
+-
+If defined, SoftFloat’s internal
+‘
countLeadingZeros
’ functions use intrinsics
+__builtin_clz
and __builtin_clzll
.
+
+SOFTFLOAT_INTRINSIC_INT128
+-
+If defined, SoftFloat makes use of GCC’s nonstandard 128-bit
+integer type
__int128
.
+
+
+
+On some machines, these improvements are observed to increase the speeds of
+f64_mul
and f128_mul
by around 20 to 25%, although
+other functions receive less dramatic boosts, or none at all.
+Results can vary greatly across different platforms.
+
+
+
+6. Testing SoftFloat
+
+
+SoftFloat can be tested using the testsoftfloat
program by the
+same author.
+This program is part of the Berkeley TestFloat package available at the Web
+page
+http://www.jhauser.us/arithmetic/TestFloat.html
.
+The TestFloat package also has a program called timesoftfloat
that
+measures the speed of SoftFloat’s floating-point functions.
+
+
+
+7. Providing SoftFloat as a Common Library for Applications
+
+
+Header file softfloat.h
defines the SoftFloat interface as seen by
+clients.
+If the SoftFloat library will be made a common library for programs on a
+system, the supplied softfloat.h
has a couple of deficiencies for
+this purpose:
+
+-
+As supplied,
softfloat.h
depends on another header,
+softfloat_types.h
, that is not intended for public use but which
+must also be visible to the programmer’s compiler.
+ -
+More troubling, at the time
softfloat.h
is included in a C source
+file, macros SOFTFLOAT_FAST_INT64
and THREAD_LOCAL
+must be defined, or not defined, consistent with how these macro were defined
+when the SoftFloat library was built.
+
+In the situation that new programs may regularly #include
header
+file softfloat.h
, it is recommended that a custom, self-contained
+version of this header file be created that eliminates these issues.
+
+
+
+8. Contact Information
+
+
+At the time of this writing, the most up-to-date information about SoftFloat
+and the latest release can be found at the Web page
+http://www.jhauser.us/arithmetic/SoftFloat.html
.
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/doc/SoftFloat.html b/src/cpu/softfloat3e/doc/SoftFloat.html
new file mode 100644
index 0000000000..b72b407f4f
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat.html
@@ -0,0 +1,1527 @@
+
+
+
+
+Berkeley SoftFloat Library Interface
+
+
+
+
+Berkeley SoftFloat Release 3e: Library Interface
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Contents
+
+
+
+
+
+1. Introduction |
+2. Limitations |
+3. Acknowledgments and License |
+4. Types and Functions |
+ | 4.1. Boolean and Integer Types |
+ | 4.2. Floating-Point Types |
+ | 4.3. Supported Floating-Point Functions |
+
+ |
+ 4.4. Non-canonical Representations in extFloat80_t |
+
+ | 4.5. Conventions for Passing Arguments and Results |
+5. Reserved Names |
+6. Mode Variables |
+ | 6.1. Rounding Mode |
+ | 6.2. Underflow Detection |
+
+ |
+ 6.3. Rounding Precision for the 80-Bit Extended Format |
+
+7. Exceptions and Exception Flags |
+8. Function Details |
+ | 8.1. Conversions from Integer to Floating-Point |
+ | 8.2. Conversions from Floating-Point to Integer |
+ | 8.3. Conversions Among Floating-Point Types |
+ | 8.4. Basic Arithmetic Functions |
+ | 8.5. Fused Multiply-Add Functions |
+ | 8.6. Remainder Functions |
+ | 8.7. Round-to-Integer Functions |
+ | 8.8. Comparison Functions |
+ | 8.9. Signaling NaN Test Functions |
+ | 8.10. Raise-Exception Function |
+9. Changes from SoftFloat Release 2 |
+ | 9.1. Name Changes |
+ | 9.2. Changes to Function Arguments |
+ | 9.3. Added Capabilities |
+ | 9.4. Better Compatibility with the C Language |
+ | 9.5. New Organization as a Library |
+ | 9.6. Optimization Gains (and Losses) |
+10. Future Directions |
+11. Contact Information |
+
+
+
+
+1. Introduction
+
+
+Berkeley SoftFloat is a software implementation of binary floating-point that
+conforms to the IEEE Standard for Floating-Point Arithmetic.
+The current release supports five binary formats: 16-bit
+half-precision, 32-bit single-precision, 64-bit
+double-precision, 80-bit double-extended-precision, and
+128-bit quadruple-precision.
+The following functions are supported for each format:
+
+-
+addition, subtraction, multiplication, division, and square root;
+
-
+fused multiply-add as defined by the IEEE Standard, except for
+80-bit double-extended-precision;
+
-
+remainder as defined by the IEEE Standard;
+
-
+round to integral value;
+
-
+comparisons;
+
-
+conversions to/from other supported formats; and
+
-
+conversions to/from 32-bit and 64-bit integers,
+signed and unsigned.
+
+All operations required by the original 1985 version of the IEEE Floating-Point
+Standard are implemented, except for conversions to and from decimal.
+
+
+
+This document gives information about the types defined and the routines
+implemented by SoftFloat.
+It does not attempt to define or explain the IEEE Floating-Point Standard.
+Information about the standard is available elsewhere.
+
+
+
+The current version of SoftFloat is Release 3e.
+This release modifies the behavior of the rarely used odd rounding mode
+(round to odd, also known as jamming), and also adds some new
+specialization and optimization examples for those compiling SoftFloat.
+
+
+
+The previous Release 3d fixed bugs that were found in the square
+root functions for the 64-bit, 80-bit, and
+128-bit floating-point formats.
+(Thanks to Alexei Sibidanov at the University of Victoria for reporting an
+incorrect result.)
+The bugs affected all prior Release-3 versions of SoftFloat
+through 3c.
+The flaw in the 64-bit floating-point square root function was of
+very minor impact, causing a 1-ulp error (1 unit in
+the last place) a few times out of a billion.
+The bugs in the 80-bit and 128-bit square root
+functions were more serious.
+Although incorrect results again occurred only a few times out of a billion,
+when they did occur a large portion of the less-significant bits could be
+wrong.
+
+
+
+Among earlier releases, 3b was notable for adding support for the
+16-bit half-precision format.
+For more about the evolution of SoftFloat releases, see
+SoftFloat-history.html
.
+
+
+
+The functional interface of SoftFloat Release 3 and later differs
+in many details from the releases that came before.
+For specifics of these differences, see section 9 below,
+Changes from SoftFloat Release 2.
+
+
+
+2. Limitations
+
+
+SoftFloat assumes the computer has an addressable byte size of 8 or
+16 bits.
+(Nearly all computers in use today have 8-bit bytes.)
+
+
+
+SoftFloat is written in C and is designed to work with other C code.
+The C compiler used must conform at a minimum to the 1989 ANSI standard for the
+C language (same as the 1990 ISO standard) and must in addition support basic
+arithmetic on 64-bit integers.
+Earlier releases of SoftFloat included implementations of 32-bit
+single-precision and 64-bit double-precision floating-point that
+did not require 64-bit integers, but this option is not supported
+starting with Release 3.
+Since 1999, ISO standards for C have mandated compiler support for
+64-bit integers.
+A compiler conforming to the 1999 C Standard or later is recommended but not
+strictly required.
+
+
+
+Most operations not required by the original 1985 version of the IEEE
+Floating-Point Standard but added in the 2008 version are not yet supported in
+SoftFloat Release 3e.
+
+
+
+3. Acknowledgments and License
+
+
+The SoftFloat package was written by me, John R. Hauser.
+Release 3 of SoftFloat was a completely new implementation
+supplanting earlier releases.
+The project to create Release 3 (now through 3e) was
+done in the employ of the University of California, Berkeley, within the
+Department of Electrical Engineering and Computer Sciences, first for the
+Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab.
+The work was officially overseen by Prof. Krste Asanovic, with funding provided
+by these sources:
+
+
+
+
+
+
+Par Lab: |
+ |
+
+Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery
+(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia,
+NVIDIA, Oracle, and Samsung.
+ |
+
+
+ASPIRE Lab: |
+ |
+
+DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from
+ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA,
+Oracle, and Samsung.
+ |
+
+
+
+
+
+
+The following applies to the whole of SoftFloat Release 3e as well
+as to each source file individually.
+
+
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California.
+All rights reserved.
+
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+
+-
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions, and the following disclaimer.
+
+
+ -
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions, and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+
+ -
+
+Neither the name of the University nor the names of its contributors may be
+used to endorse or promote products derived from this software without specific
+prior written permission.
+
+
+
+
+
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”,
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+4. Types and Functions
+
+
+The types and functions of SoftFloat are declared in header file
+softfloat.h
.
+
+
+4.1. Boolean and Integer Types
+
+
+Header file softfloat.h
depends on standard headers
+<stdbool.h>
and <stdint.h>
to define type
+bool
and several integer types.
+These standard headers have been part of the ISO C Standard Library since 1999.
+With any recent compiler, they are likely to be supported, even if the compiler
+does not claim complete conformance to the latest ISO C Standard.
+For older or nonstandard compilers, a port of SoftFloat may have substitutes
+for these headers.
+Header softfloat.h
depends only on the name bool
from
+<stdbool.h>
and on these type names from
+<stdint.h>
:
+
+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+uint_fast8_t
+uint_fast32_t
+uint_fast64_t
+int_fast32_t
+int_fast64_t
+
+
+
+
+
+4.2. Floating-Point Types
+
+
+The softfloat.h
header defines five floating-point types:
+
+
+
+float16_t |
+16-bit half-precision binary format |
+
+
+float32_t |
+32-bit single-precision binary format |
+
+
+float64_t |
+64-bit double-precision binary format |
+
+
+extFloat80_t |
+80-bit double-extended-precision binary format (old Intel or
+Motorola format) |
+
+
+float128_t |
+128-bit quadruple-precision binary format |
+
+
+
+The non-extended types are each exactly the size specified:
+16 bits for float16_t
, 32 bits for
+float32_t
, 64 bits for float64_t
, and
+128 bits for float128_t
.
+Aside from these size requirements, the definitions of all these types may
+differ for different ports of SoftFloat to specific systems.
+A given port of SoftFloat may or may not define some of the floating-point
+types as aliases for the C standard types float
,
+double
, and long
double
.
+
+
+
+Header file softfloat.h
also defines a structure,
+struct
extFloat80M
, for the representation of
+80-bit double-extended-precision floating-point values in memory.
+This structure is the same size as type extFloat80_t
and contains
+at least these two fields (not necessarily in this order):
+
+
+uint16_t signExp;
+uint64_t signif;
+
+
+Field signExp
contains the sign and exponent of the floating-point
+value, with the sign in the most significant bit (bit 15) and the
+encoded exponent in the other 15 bits.
+Field signif
is the complete 64-bit significand of
+the floating-point value.
+(In the usual encoding for 80-bit extended floating-point, the
+leading 1 bit of normalized numbers is not implicit but is stored
+in the most significant bit of the significand.)
+
+
+4.3. Supported Floating-Point Functions
+
+
+SoftFloat implements these arithmetic operations for its floating-point types:
+
+-
+conversions between any two floating-point formats;
+
-
+for each floating-point format, conversions to and from signed and unsigned
+32-bit and 64-bit integers;
+
-
+for each format, the usual addition, subtraction, multiplication, division, and
+square root operations;
+
-
+for each format except
extFloat80_t
, the fused multiply-add
+operation defined by the IEEE Standard;
+ -
+for each format, the floating-point remainder operation defined by the IEEE
+Standard;
+
-
+for each format, a “round to integer” operation that rounds to the
+nearest integer value in the same format; and
+
-
+comparisons between two values in the same floating-point format.
+
+
+
+
+The following operations required by the 2008 IEEE Floating-Point Standard are
+not supported in SoftFloat Release 3e:
+
+-
+nextUp, nextDown, minNum, maxNum, minNumMag,
+maxNumMag, scaleB, and logB;
+
-
+conversions between floating-point formats and decimal or hexadecimal character
+sequences;
+
-
+all “quiet-computation” operations (copy, negate,
+abs, and copySign, which all involve only simple copying and/or
+manipulation of the floating-point sign bit); and
+
-
+all “non-computational” operations other than isSignaling
+(which is supported).
+
+
+
+4.4. Non-canonical Representations in extFloat80_t
+
+
+Because the 80-bit double-extended-precision format,
+extFloat80_t
, stores an explicit leading significand bit, many
+finite floating-point numbers are encodable in this type in multiple equivalent
+forms.
+Of these multiple encodings, there is always a unique one with the least
+encoded exponent value, and this encoding is considered the canonical
+representation of the floating-point number.
+Any other equivalent representations (having a higher encoded exponent value)
+are non-canonical.
+For a value in the subnormal range (including zero), the canonical
+representation always has an encoded exponent of zero and a leading significand
+bit of 0.
+For finite values outside the subnormal range, the canonical representation
+always has an encoded exponent that is nonzero and a leading significand bit
+of 1.
+
+
+
+For an infinity or NaN, the leading significand bit is similarly expected to
+be 1.
+An infinity or NaN with a leading significand bit of 0 is again
+considered non-canonical.
+Hence, altogether, to be canonical, a value of type extFloat80_t
+must have a leading significand bit of 1, unless the value is
+subnormal or zero, in which case the leading significand bit and the encoded
+exponent must both be zero.
+
+
+
+SoftFloat’s functions are not guaranteed to operate as expected when
+inputs of type extFloat80_t
are non-canonical.
+Assuming all of a function’s extFloat80_t
inputs (if any)
+are canonical, function outputs of type extFloat80_t
will always
+be canonical.
+
+
+4.5. Conventions for Passing Arguments and Results
+
+
+Values that are at most 64 bits in size (i.e., not the
+80-bit or 128-bit floating-point formats) are in all
+cases passed as function arguments by value.
+Likewise, when an output of a function is no more than 64 bits, it
+is always returned directly as the function result.
+Thus, for example, the SoftFloat function for adding two 64-bit
+floating-point values has this simple signature:
+
+float64_t f64_add( float64_t, float64_t );
+
+
+
+
+The story is more complex when function inputs and outputs are
+80-bit and 128-bit floating-point.
+For these types, SoftFloat always provides a function that passes these larger
+values into or out of the function indirectly, via pointers.
+For example, for adding two 128-bit floating-point values,
+SoftFloat supplies this function:
+
+void f128M_add( const float128_t *, const float128_t *, float128_t * );
+
+The first two arguments point to the values to be added, and the last argument
+points to the location where the sum will be stored.
+The M
in the name f128M_add
is mnemonic for the fact
+that the 128-bit inputs and outputs are “in memory”,
+pointed to by pointer arguments.
+
+
+
+All ports of SoftFloat implement these pass-by-pointer functions for
+types extFloat80_t
and float128_t
.
+At the same time, SoftFloat ports may also implement alternate versions of
+these same functions that pass extFloat80_t
and
+float128_t
by value, like the smaller formats.
+Thus, besides the function with name f128M_add
shown above, a
+SoftFloat port may also supply an equivalent function with this signature:
+
+float128_t f128_add( float128_t, float128_t );
+
+
+
+
+As a general rule, on computers where the machine word size is
+32 bits or smaller, only the pass-by-pointer versions of functions
+(e.g., f128M_add
) are provided for types extFloat80_t
+and float128_t
, because passing such large types directly can have
+significant extra cost.
+On computers where the word size is 64 bits or larger, both
+function versions (f128M_add
and f128_add
) are
+provided, because the cost of passing by value is then more reasonable.
+Applications that must be portable accross both classes of computers must use
+the pointer-based functions, as these are always implemented.
+However, if it is known that SoftFloat includes the by-value functions for all
+platforms of interest, programmers can use whichever version they prefer.
+
+
+
+5. Reserved Names
+
+
+In addition to the variables and functions documented here, SoftFloat defines
+some symbol names for its own private use.
+These private names always begin with the prefix
+‘softfloat_
’.
+When a program includes header softfloat.h
or links with the
+SoftFloat library, all names with prefix ‘softfloat_
’
+are reserved for possible use by SoftFloat.
+Applications that use SoftFloat should not define their own names with this
+prefix, and should reference only such names as are documented.
+
+
+
+6. Mode Variables
+
+
+The following global variables control rounding mode, underflow detection, and
+the 80-bit extended format’s rounding precision:
+
+softfloat_roundingMode
+softfloat_detectTininess
+extF80_roundingPrecision
+
+These mode variables are covered in the next several subsections.
+For some SoftFloat ports, these variables may be per-thread (declared
+thread_local
), meaning that different execution threads have their
+own separate copies of the variables.
+
+
+6.1. Rounding Mode
+
+
+All five rounding modes defined by the 2008 IEEE Floating-Point Standard are
+implemented for all operations that require rounding.
+Some ports of SoftFloat may also implement the round-to-odd mode.
+
+
+
+The rounding mode is selected by the global variable
+
+uint_fast8_t softfloat_roundingMode;
+
+This variable may be set to one of the values
+
+
+
+softfloat_round_near_even |
+round to nearest, with ties to even |
+
+
+softfloat_round_near_maxMag |
+round to nearest, with ties to maximum magnitude (away from zero) |
+
+
+softfloat_round_minMag |
+round to minimum magnitude (toward zero) |
+
+
+softfloat_round_min |
+round to minimum (down) |
+
+
+softfloat_round_max |
+round to maximum (up) |
+
+
+softfloat_round_odd |
+round to odd (jamming), if supported by the SoftFloat port |
+
+
+
+Variable softfloat_roundingMode
is initialized to
+softfloat_round_near_even
.
+
+
+
+When softfloat_round_odd
is the rounding mode for a function that
+rounds to an integer value (either conversion to an integer format or a
+‘roundToInt
’ function), if the input is not already an
+integer, the rounded result is the closest odd integer.
+For other operations, this rounding mode acts as though the floating-point
+result is first rounded to minimum magnitude, the same as
+softfloat_round_minMag
, and then, if the result is inexact, the
+least-significant bit of the result is set to 1.
+Rounding to odd is also known as jamming.
+
+
+6.2. Underflow Detection
+
+
+In the terminology of the IEEE Standard, SoftFloat can detect tininess for
+underflow either before or after rounding.
+The choice is made by the global variable
+
+uint_fast8_t softfloat_detectTininess;
+
+which can be set to either
+
+softfloat_tininess_beforeRounding
+softfloat_tininess_afterRounding
+
+Detecting tininess after rounding is usually better because it results in fewer
+spurious underflow signals.
+The other option is provided for compatibility with some systems.
+Like most systems (and as required by the newer 2008 IEEE Standard), SoftFloat
+always detects loss of accuracy for underflow as an inexact result.
+
+
+6.3. Rounding Precision for the 80-Bit Extended Format
+
+
+For extFloat80_t
only, the rounding precision of the basic
+arithmetic operations is controlled by the global variable
+
+uint_fast8_t extF80_roundingPrecision;
+
+The operations affected are:
+
+extF80_add
+extF80_sub
+extF80_mul
+extF80_div
+extF80_sqrt
+
+When extF80_roundingPrecision
is set to its default value of 80,
+these operations are rounded to the full precision of the 80-bit
+double-extended-precision format, like occurs for other formats.
+Setting extF80_roundingPrecision
to 32 or to 64 causes the
+operations listed to be rounded to 32-bit precision (equivalent to
+float32_t
) or to 64-bit precision (equivalent to
+float64_t
), respectively.
+When rounding to reduced precision, additional bits in the result significand
+beyond the rounding point are set to zero.
+The consequences of setting extF80_roundingPrecision
to a value
+other than 32, 64, or 80 is not specified.
+Operations other than the ones listed above are not affected by
+extF80_roundingPrecision
.
+
+
+
+7. Exceptions and Exception Flags
+
+
+All five exception flags required by the IEEE Floating-Point Standard are
+implemented.
+Each flag is stored as a separate bit in the global variable
+
+uint_fast8_t softfloat_exceptionFlags;
+
+The positions of the exception flag bits within this variable are determined by
+the bit masks
+
+softfloat_flag_inexact
+softfloat_flag_underflow
+softfloat_flag_overflow
+softfloat_flag_infinite
+softfloat_flag_invalid
+
+Variable softfloat_exceptionFlags
is initialized to all zeros,
+meaning no exceptions.
+
+
+
+For some SoftFloat ports, softfloat_exceptionFlags
may be
+per-thread (declared thread_local
), meaning that different
+execution threads have their own separate instances of it.
+
+
+
+An individual exception flag can be cleared with the statement
+
+softfloat_exceptionFlags &= ~softfloat_flag_<exception>;
+
+where <exception>
is the appropriate name.
+To raise a floating-point exception, function softfloat_raiseFlags
+should normally be used.
+
+
+
+When SoftFloat detects an exception other than inexact, it calls
+softfloat_raiseFlags
.
+The default version of this function simply raises the corresponding exception
+flags.
+Particular ports of SoftFloat may support alternate behavior, such as exception
+traps, by modifying the default softfloat_raiseFlags
.
+A program may also supply its own softfloat_raiseFlags
function to
+override the one from the SoftFloat library.
+
+
+
+Because inexact results occur frequently under most circumstances (and thus are
+hardly exceptional), SoftFloat does not ordinarily call
+softfloat_raiseFlags
for inexact exceptions.
+It does always raise the inexact exception flag as required.
+
+
+
+8. Function Details
+
+
+In this section, <float>
appears in function names as
+a substitute for one of these abbreviations:
+
+
+
+f16 |
+indicates float16_t , passed by value |
+
+
+f32 |
+indicates float32_t , passed by value |
+
+
+f64 |
+indicates float64_t , passed by value |
+
+
+extF80M |
+indicates extFloat80_t , passed indirectly via pointers |
+
+
+extF80 |
+indicates extFloat80_t , passed by value |
+
+
+f128M |
+indicates float128_t , passed indirectly via pointers |
+
+
+f128 |
+indicates float128_t , passed by value |
+
+
+
+The circumstances under which values of floating-point types
+extFloat80_t
and float128_t
may be passed either by
+value or indirectly via pointers was discussed earlier in
+section 4.5, Conventions for Passing Arguments and Results.
+
+
+8.1. Conversions from Integer to Floating-Point
+
+
+All conversions from a 32-bit or 64-bit integer,
+signed or unsigned, to a floating-point format are supported.
+Functions performing these conversions have these names:
+
+ui32_to_<float>
+ui64_to_<float>
+i32_to_<float>
+i64_to_<float>
+
+Conversions from 32-bit integers to 64-bit
+double-precision and larger formats are always exact, and likewise conversions
+from 64-bit integers to 80-bit
+double-extended-precision and 128-bit quadruple-precision are also
+always exact.
+
+
+
+Each conversion function takes one input of the appropriate type and generates
+one output.
+The following illustrates the signatures of these functions in cases when the
+floating-point result is passed either by value or via pointers:
+
+
+float64_t i32_to_f64( int32_t a );
+
+
+void i32_to_f128M( int32_t a, float128_t *destPtr );
+
+
+
+
+8.2. Conversions from Floating-Point to Integer
+
+
+Conversions from a floating-point format to a 32-bit or
+64-bit integer, signed or unsigned, are supported with these
+functions:
+
+<float>_to_ui32
+<float>_to_ui64
+<float>_to_i32
+<float>_to_i64
+
+The functions have signatures as follows, depending on whether the
+floating-point input is passed by value or via pointers:
+
+
+int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+int_fast32_t
+ f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact );
+
+
+
+
+
+The roundingMode
argument specifies the rounding mode for
+the conversion.
+The variable that usually indicates rounding mode,
+softfloat_roundingMode
, is ignored.
+Argument exact
determines whether the inexact
+exception flag is raised if the conversion is not exact.
+If exact
is true
, the inexact flag may
+be raised;
+otherwise, it will not be, even if the conversion is inexact.
+
+
+
+A conversion from floating-point to integer format raises the invalid
+exception if the source value cannot be rounded to a representable integer of
+the desired size (32 or 64 bits).
+In such circumstances, the integer result returned is determined by the
+particular port of SoftFloat, although typically this value will be either the
+maximum or minimum value of the integer format.
+The functions that convert to integer types never raise the floating-point
+overflow exception.
+
+
+
+Because languages such as C require that conversions to integers
+be rounded toward zero, the following functions are provided for improved speed
+and convenience:
+
+<float>_to_ui32_r_minMag
+<float>_to_ui64_r_minMag
+<float>_to_i32_r_minMag
+<float>_to_i64_r_minMag
+
+These functions round only toward zero (to minimum magnitude).
+The signatures for these functions are the same as above without the redundant
+roundingMode
argument:
+
+
+int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact );
+
+
+int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact );
+
+
+
+
+8.3. Conversions Among Floating-Point Types
+
+
+Conversions between floating-point formats are done by functions with these
+names:
+
+<float>_to_<float>
+
+All combinations of source and result type are supported where the source and
+result are different formats.
+There are four different styles of signature for these functions, depending on
+whether the input and the output floating-point values are passed by value or
+via pointers:
+
+
+float32_t f64_to_f32( float64_t a );
+
+
+float32_t f128M_to_f32( const float128_t *aPtr );
+
+
+void f32_to_f128M( float32_t a, float128_t *destPtr );
+
+
+void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *destPtr );
+
+
+
+
+
+Conversions from a smaller to a larger floating-point format are always exact
+and so require no rounding.
+
+
+8.4. Basic Arithmetic Functions
+
+
+The following basic arithmetic functions are provided:
+
+<float>_add
+<float>_sub
+<float>_mul
+<float>_div
+<float>_sqrt
+
+Each floating-point operation takes two operands, except for sqrt
+(square root) which takes only one.
+The operands and result are all of the same floating-point format.
+Signatures for these functions take the following forms:
+
+
+float64_t f64_add( float64_t a, float64_t b );
+
+
+void
+ f128M_add(
+ const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+float64_t f64_sqrt( float64_t a );
+
+
+void f128M_sqrt( const float128_t *aPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments
+aPtr
and bPtr
point to the input
+operands, and the last argument, destPtr
, points to the
+location where the result is stored.
+
+
+
+Rounding of the 80-bit double-extended-precision
+(extFloat80_t
) functions is affected by variable
+extF80_roundingPrecision
, as explained earlier in
+section 6.3,
+Rounding Precision for the 80-Bit Extended Format.
+
+
+8.5. Fused Multiply-Add Functions
+
+
+The 2008 version of the IEEE Floating-Point Standard defines a fused
+multiply-add operation that does a combined multiplication and addition
+with only a single rounding.
+SoftFloat implements fused multiply-add with functions
+
+<float>_mulAdd
+
+Unlike other operations, fused multiple-add is not supported for the
+80-bit double-extended-precision format,
+extFloat80_t
.
+
+
+
+Depending on whether floating-point values are passed by value or via pointers,
+the fused multiply-add functions have signatures of these forms:
+
+
+float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c );
+
+
+void
+ f128M_mulAdd(
+ const float128_t *aPtr,
+ const float128_t *bPtr,
+ const float128_t *cPtr,
+ float128_t *destPtr
+ );
+
+
+The functions compute
+(a
× b
)
+ + c
+with a single rounding.
+When floating-point values are passed indirectly through pointers, arguments
+aPtr
, bPtr
, and
+cPtr
point to operands a
,
+b
, and c
respectively, and
+destPtr
points to the location where the result is stored.
+
+
+
+If one of the multiplication operands a
and
+b
is infinite and the other is zero, these functions raise
+the invalid exception even if operand c
is a quiet NaN.
+
+
+8.6. Remainder Functions
+
+
+For each format, SoftFloat implements the remainder operation defined by the
+IEEE Floating-Point Standard.
+The remainder functions have names
+
+<float>_rem
+
+Each remainder operation takes two floating-point operands of the same format
+and returns a result in the same format.
+Depending on whether floating-point values are passed by value or via pointers,
+the remainder functions have signatures of these forms:
+
+
+float64_t f64_rem( float64_t a, float64_t b );
+
+
+void
+ f128M_rem(
+ const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments
+aPtr
and bPtr
point to operands
+a
and b
respectively, and
+destPtr
points to the location where the result is stored.
+
+
+
+The IEEE Standard remainder operation computes the value
+a
+ − n × b
,
+where n is the integer closest to
+a
÷ b
.
+If a
÷ b
is exactly
+halfway between two integers, n is the even integer closest to
+a
÷ b
.
+The IEEE Standard’s remainder operation is always exact and so requires
+no rounding.
+
+
+
+Depending on the relative magnitudes of the operands, the remainder
+functions can take considerably longer to execute than the other SoftFloat
+functions.
+This is an inherent characteristic of the remainder operation itself and is not
+a flaw in the SoftFloat implementation.
+
+
+8.7. Round-to-Integer Functions
+
+
+For each format, SoftFloat implements the round-to-integer operation specified
+by the IEEE Floating-Point Standard.
+These functions are named
+
+<float>_roundToInt
+
+Each round-to-integer operation takes a single floating-point operand.
+This operand is rounded to an integer according to a specified rounding mode,
+and the resulting integer value is returned in the same floating-point format.
+(Note that the result is not an integer type.)
+
+
+
+The signatures of the round-to-integer functions are similar to those for
+conversions to an integer type:
+
+
+float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+void
+ f128M_roundToInt(
+ const float128_t *aPtr,
+ uint_fast8_t roundingMode,
+ bool exact,
+ float128_t *destPtr
+ );
+
+
+When floating-point values are passed indirectly through pointers,
+aPtr
points to the input operand and
+destPtr
points to the location where the result is stored.
+
+
+
+The roundingMode
argument specifies the rounding mode to
+apply.
+The variable that usually indicates rounding mode,
+softfloat_roundingMode
, is ignored.
+Argument exact
determines whether the inexact
+exception flag is raised if the conversion is not exact.
+If exact
is true
, the inexact flag may
+be raised;
+otherwise, it will not be, even if the conversion is inexact.
+
+
+8.8. Comparison Functions
+
+
+For each format, the following floating-point comparison functions are
+provided:
+
+<float>_eq
+<float>_le
+<float>_lt
+
+Each comparison takes two operands of the same type and returns a Boolean.
+The abbreviation eq
stands for “equal” (=);
+le
stands for “less than or equal” (≤);
+and lt
stands for “less than” (<).
+Depending on whether the floating-point operands are passed by value or via
+pointers, the comparison functions have signatures of these forms:
+
+
+bool f64_eq( float64_t a, float64_t b );
+
+
+bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr );
+
+
+
+
+
+The usual greater-than (>), greater-than-or-equal (≥), and not-equal
+(≠) comparisons are easily obtained from the functions provided.
+The not-equal function is just the logical complement of the equal function.
+The greater-than-or-equal function is identical to the less-than-or-equal
+function with the arguments in reverse order, and likewise the greater-than
+function is identical to the less-than function with the arguments reversed.
+
+
+
+The IEEE Floating-Point Standard specifies that the less-than-or-equal and
+less-than comparisons by default raise the invalid exception if either
+operand is any kind of NaN.
+Equality comparisons, on the other hand, are defined by default to raise the
+invalid exception only for signaling NaNs, not quiet NaNs.
+For completeness, SoftFloat provides these complementary functions:
+
+<float>_eq_signaling
+<float>_le_quiet
+<float>_lt_quiet
+
+The signaling
equality comparisons are identical to the default
+equality comparisons except that the invalid exception is raised for any
+NaN input, not just for signaling NaNs.
+Similarly, the quiet
comparison functions are identical to their
+default counterparts except that the invalid exception is not raised for
+quiet NaNs.
+
+
+8.9. Signaling NaN Test Functions
+
+
+Functions for testing whether a floating-point value is a signaling NaN are
+provided with these names:
+
+<float>_isSignalingNaN
+
+The functions take one floating-point operand and return a Boolean indicating
+whether the operand is a signaling NaN.
+Accordingly, the functions have the forms
+
+
+bool f64_isSignalingNaN( float64_t a );
+
+
+bool f128M_isSignalingNaN( const float128_t *aPtr );
+
+
+
+
+8.10. Raise-Exception Function
+
+
+SoftFloat provides a single function for raising floating-point exceptions:
+
+
+void softfloat_raiseFlags( uint_fast8_t exceptions );
+
+
+The exceptions
argument is a mask indicating the set of
+exceptions to raise.
+(See earlier section 7, Exceptions and Exception Flags.)
+In addition to setting the specified exception flags in variable
+softfloat_exceptionFlags
, the softfloat_raiseFlags
+function may cause a trap or abort appropriate for the current system.
+
+
+
+9. Changes from SoftFloat Release 2
+
+
+Apart from a change in the legal use license, Release 3 of
+SoftFloat introduced numerous technical differences compared to earlier
+releases.
+
+
+9.1. Name Changes
+
+
+The most obvious and pervasive difference compared to Release 2
+is that the names of most functions and variables have changed, even when the
+behavior has not.
+First, the floating-point types, the mode variables, the exception flags
+variable, the function to raise exceptions, and various associated constants
+have been renamed as follows:
+
+
+
+old name, Release 2: |
+new name, Release 3: |
+
+
+float32 |
+float32_t |
+
+
+float64 |
+float64_t |
+
+
+floatx80 |
+extFloat80_t |
+
+
+float128 |
+float128_t |
+
+
+float_rounding_mode |
+softfloat_roundingMode |
+
+
+float_round_nearest_even |
+softfloat_round_near_even |
+
+
+float_round_to_zero |
+softfloat_round_minMag |
+
+
+float_round_down |
+softfloat_round_min |
+
+
+float_round_up |
+softfloat_round_max |
+
+
+float_detect_tininess |
+softfloat_detectTininess |
+
+
+float_tininess_before_rounding |
+softfloat_tininess_beforeRounding |
+
+
+float_tininess_after_rounding |
+softfloat_tininess_afterRounding |
+
+
+floatx80_rounding_precision |
+extF80_roundingPrecision |
+
+
+float_exception_flags |
+softfloat_exceptionFlags |
+
+
+float_flag_inexact |
+softfloat_flag_inexact |
+
+
+float_flag_underflow |
+softfloat_flag_underflow |
+
+
+float_flag_overflow |
+softfloat_flag_overflow |
+
+
+float_flag_divbyzero |
+softfloat_flag_infinite |
+
+
+float_flag_invalid |
+softfloat_flag_invalid |
+
+
+float_raise |
+softfloat_raiseFlags |
+
+
+
+
+
+
+Furthermore, Release 3 adopted the following new abbreviations for
+function names:
+
+
+
+used in names in Release 2: |
+used in names in Release 3: |
+
+ int32 | i32 |
+ int64 | i64 |
+ float32 | f32 |
+ float64 | f64 |
+ floatx80 | extF80 |
+ float128 | f128 |
+
+
+Thus, for example, the function to add two 32-bit floating-point
+numbers, previously called float32_add
in Release 2,
+is now f32_add
.
+Lastly, there have been a few other changes to function names:
+
+
+
+used in names in Release 2: |
+used in names in Release 3: |
+relevant functions: |
+
+
+_round_to_zero |
+_r_minMag |
+conversions from floating-point to integer (section 8.2) |
+
+
+round_to_int |
+roundToInt |
+round-to-integer functions (section 8.7) |
+
+
+is_signaling_nan |
+isSignalingNaN |
+signaling NaN test functions (section 8.9) |
+
+
+
+
+
+9.2. Changes to Function Arguments
+
+
+Besides simple name changes, some operations were given a different interface
+in Release 3 than they had in Release 2:
+
+
+-
+
+Since Release 3, integer arguments and results of functions have
+standard types from header <stdint.h>
, such as
+uint32_t
, whereas previously their types could be defined
+differently for each port of SoftFloat, usually using traditional C types such
+as unsigned
int
.
+Likewise, functions in Release 3 and later pass Booleans as
+standard type bool
from <stdbool.h>
, whereas
+previously these were again passed as a port-specific type (usually
+int
).
+
+
+ -
+
+As explained earlier in section 4.5, Conventions for Passing
+Arguments and Results, SoftFloat functions in Release 3 and
+later may pass 80-bit and 128-bit floating-point
+values through pointers, meaning that functions take pointer arguments and then
+read or write floating-point values at the locations indicated by the pointers.
+In Release 2, floating-point arguments and results were always
+passed by value, regardless of their size.
+
+
+ -
+
+Functions that round to an integer have additional
+roundingMode
and exact
arguments that
+they did not have in Release 2.
+Refer to sections 8.2 and 8.7 for descriptions of these functions
+since Release 3.
+For Release 2, the rounding mode, when needed, was taken from the
+same global variable that affects the basic arithmetic operations (now called
+softfloat_roundingMode
but previously known as
+float_rounding_mode
).
+Also, for Release 2, if the original floating-point input was not
+an exact integer value, and if the invalid exception was not raised by
+the function, the inexact exception was always raised.
+Release 2 had no option to suppress raising inexact in this
+case.
+Applications using SoftFloat Release 3 or later can get the same
+effect as Release 2 by passing variable
+softfloat_roundingMode
for argument
+roundingMode
and true
for argument
+exact
.
+
+
+
+
+
+9.3. Added Capabilities
+
+
+With Release 3, some new features have been added that were not
+present in Release 2:
+
+
+-
+
+A port of SoftFloat can now define any of the floating-point types
+float32_t
, float64_t
, extFloat80_t
, and
+float128_t
as aliases for C’s standard floating-point types
+float
, double
, and long
+double
, using either #define
or typedef
.
+This potential convenience was not supported under Release 2.
+
+
+
+(Note, however, that there may be a performance cost to defining
+SoftFloat’s floating-point types this way, depending on the platform and
+the applications using SoftFloat.
+Ports of SoftFloat may choose to forgo the convenience in favor of better
+speed.)
+
+
+
+
-
+As of Release 3b, 16-bit half-precision,
+
float16_t
, is supported.
+
+
+
+
-
+Functions have been added for converting between the floating-point types and
+unsigned integers.
+Release 2 supported only signed integers, not unsigned.
+
+
+
+
-
+Fused multiply-add functions have been added for all floating-point formats
+except 80-bit double-extended-precision,
+
extFloat80_t
.
+
+
+
+
-
+New rounding modes are supported:
+
softfloat_round_near_maxMag
(round to nearest, with ties to
+maximum magnitude, away from zero), and, as of Release 3c,
+optional softfloat_round_odd
(round to odd, also known as
+jamming).
+
+
+
+
+
+9.4. Better Compatibility with the C Language
+
+
+Release 3 of SoftFloat was written to conform better to the ISO C
+Standard’s rules for portability.
+For example, older releases of SoftFloat employed type conversions in ways
+that, while commonly practiced, are not fully defined by the C Standard.
+Such problematic type conversions have generally been replaced by the use of
+unions, the behavior around which is more strictly regulated these days.
+
+
+9.5. New Organization as a Library
+
+
+Starting with Release 3, SoftFloat now builds as a library.
+Previously, SoftFloat compiled into a single, monolithic object file containing
+all the SoftFloat functions, with the consequence that a program linking with
+SoftFloat would get every SoftFloat function in its binary file even if only a
+few functions were actually used.
+With SoftFloat in the form of a library, a program that is linked by a standard
+linker will include only those functions of SoftFloat that it needs and no
+others.
+
+
+9.6. Optimization Gains (and Losses)
+
+
+Individual SoftFloat functions have been variously improved in
+Release 3 compared to earlier releases.
+In particular, better, faster algorithms have been deployed for the operations
+of division, square root, and remainder.
+For functions operating on the larger 80-bit and
+128-bit formats, extFloat80_t
and
+float128_t
, code size has also generally been reduced.
+
+
+
+However, because Release 2 compiled all of SoftFloat together as a
+single object file, compilers could make optimizations across function calls
+when one SoftFloat function calls another.
+Now that the functions of SoftFloat are compiled separately and only afterward
+linked together into a program, there is not usually the same opportunity to
+optimize across function calls.
+Some loss of speed has been observed due to this change.
+
+
+
+10. Future Directions
+
+
+The following improvements are anticipated for future releases of SoftFloat:
+
+-
+more functions from the 2008 version of the IEEE Floating-Point Standard;
+
-
+consistent, defined behavior for non-canonical representations of extended
+format
extFloat80_t
(discussed in section 4.4,
+Non-canonical Representations in extFloat80_t
).
+
+
+
+
+
+11. Contact Information
+
+
+At the time of this writing, the most up-to-date information about SoftFloat
+and the latest release can be found at the Web page
+http://www.jhauser.us/arithmetic/SoftFloat.html
.
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/extF80_addsub.cc b/src/cpu/softfloat3e/extF80_addsub.cc
new file mode 100644
index 0000000000..a60d2c6be1
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_addsub.cc
@@ -0,0 +1,106 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extern extFloat80_t softfloat_addMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
+extern extFloat80_t softfloat_subMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
+
+extFloat80_t extF80_add(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ a.signExp = defaultNaNExtF80UI64;
+ a.signif = defaultNaNExtF80UI0;
+ return a;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
+
+extFloat80_t extF80_sub(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ a.signExp = defaultNaNExtF80UI64;
+ a.signif = defaultNaNExtF80UI0;
+ return a;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/extF80_class.cc b/src/cpu/softfloat3e/extF80_class.cc
new file mode 100644
index 0000000000..155dc51a2a
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_class.cc
@@ -0,0 +1,71 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t extF80_class(extFloat80_t a)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+
+ if (! expA) {
+ if (! sigA) return softfloat_zero;
+ return softfloat_denormal; /* denormal or pseudo-denormal */
+ }
+
+ /* valid numbers have the MS bit set */
+ if (!(sigA & UINT64_C(0x8000000000000000)))
+ return softfloat_SNaN; /* report unsupported as SNaNs */
+
+ if (expA == 0x7FFF) {
+ if ((sigA<<1) == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & UINT64_C(0x4000000000000000)) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/extF80_compare.cc b/src/cpu/softfloat3e/extF80_compare.cc
new file mode 100644
index 0000000000..f8a360a411
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_compare.cc
@@ -0,0 +1,147 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include <86box/86box.h>
+#include "../cpu.h"
+
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two extended precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int extF80_compare(extFloat80_t a, extFloat80_t b, int quiet, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+
+ struct exp32_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ softfloat_class_t aClass = extF80_class(a);
+ softfloat_class_t bClass = extF80_class(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (fpu_type < FPU_287XL) {
+ if ((aClass == softfloat_positive_inf) && (bClass == softfloat_negative_inf))
+ {
+ return softfloat_relation_equal;
+ }
+
+ if ((aClass == softfloat_negative_inf) && (bClass == softfloat_positive_inf))
+ {
+ return softfloat_relation_equal;
+ }
+ }
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN)
+ {
+ /* unsupported reported as SNaN */
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_denormal || bClass == softfloat_denormal) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_zero) {
+ if (bClass == softfloat_zero) return softfloat_relation_equal;
+ return signB ? softfloat_relation_greater : softfloat_relation_less;
+ }
+
+ if (bClass == softfloat_zero || signA != signB) {
+ return signA ? softfloat_relation_less : softfloat_relation_greater;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_denormal) {
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+ if (bClass == softfloat_denormal) {
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+
+ if (expA == expB && sigA == sigB)
+ return softfloat_relation_equal;
+
+ int less_than =
+ signA ? ((expB < expA) || ((expB == expA) && (sigB < sigA)))
+ : ((expA < expB) || ((expA == expB) && (sigA < sigB)));
+
+ if (less_than) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/extF80_div.cc b/src/cpu/softfloat3e/extF80_div.cc
new file mode 100644
index 0000000000..e4b1fbb24b
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_div.cc
@@ -0,0 +1,188 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ bool signZ;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint128 rem;
+ uint32_t recip32;
+ uint64_t sigZ;
+ int ix;
+ uint64_t q64;
+ uint32_t q;
+ struct uint128 term;
+ uint64_t sigZExtra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ goto invalid;
+ }
+ if (! expB && sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ if (! expA && sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) {
+ if (! sigA) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) return packToExtF80(signZ, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FFF;
+ if (sigA < sigB) {
+ --expZ;
+ rem = softfloat_shortShiftLeft128(0, sigA, 32);
+ } else {
+ rem = softfloat_shortShiftLeft128(0, sigA, 31);
+ }
+ recip32 = softfloat_approxRecip32_1(sigB>>32);
+ sigZ = 0;
+ ix = 2;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
+ q = (q64 + 0x80000000)>>32;
+ --ix;
+ if (ix < 0) break;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB>>32, sigB<<32);
+ }
+ sigZ = (sigZ<<29) + q;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (((q + 1) & 0x3FFFFF) < 2) {
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ term = softfloat_shortShiftLeft128(0, sigB, 32);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, term.v64, term.v0);
+ } else if (softfloat_le128(term.v64, term.v0, rem.v64, rem.v0)) {
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ }
+ if (rem.v64 | rem.v0) q |= 1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZ = (sigZ<<6) + (q>>23);
+ sigZExtra = (uint64_t) ((uint64_t) q<<41);
+ return
+ softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+}
diff --git a/src/cpu/softfloat3e/extF80_extract.cc b/src/cpu/softfloat3e/extF80_extract.cc
new file mode 100644
index 0000000000..692190a47b
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_extract.cc
@@ -0,0 +1,97 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Separate the source extended double-precision floating point value `a'
+| into its exponent and significand, store the significant back to the
+| 'a' and return the exponent. The operation performed is a superset of
+| the IEC/IEEE recommended logb(x) function.
+*----------------------------------------------------------------------------*/
+
+extFloat80_t extF80_extract(extFloat80_t *a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ struct exp32_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(*a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ *a = packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ return *a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a->signExp;
+ uiA0 = a->signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA<<1) {
+ *a = softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
+ return *a;
+ }
+ return packToExtF80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ softfloat_raiseFlags(status, softfloat_flag_divbyzero);
+ *a = packToExtF80(signA, 0, 0);
+ return packToExtF80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+
+ *a = packToExtF80(signA, 0x3FFF, sigA);
+ return i32_to_extF80(expA - 0x3FFF);
+}
diff --git a/src/cpu/softfloat3e/extF80_mul.cc b/src/cpu/softfloat3e/extF80_mul.cc
new file mode 100644
index 0000000000..d38e97f026
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_mul.cc
@@ -0,0 +1,153 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint128 sig128Z;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
+ goto propagateNaN;
+ }
+ magBits = expB | sigB;
+ goto infArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ magBits = expA | sigA;
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) {
+ if (! expB && sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) return packToExtF80(signZ, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FFE;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ if (sig128Z.v64 < UINT64_C(0x8000000000000000)) {
+ --expZ;
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0);
+ }
+ return
+ softfloat_roundPackToExtF80(signZ, expZ, sig128Z.v64, sig128Z.v0, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ64 = defaultNaNExtF80UI64;
+ uiZ0 = defaultNaNExtF80UI0;
+ } else {
+ if ((! expA && sigA) || (! expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ uiZ64 = packToExtF80UI64(signZ, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/extF80_rem.cc b/src/cpu/softfloat3e/extF80_rem.cc
new file mode 100644
index 0000000000..39d233a7e4
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_rem.cc
@@ -0,0 +1,199 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ int32_t expB;
+ uint64_t sigB;
+ struct exp32_sig64 normExpSig;
+ int32_t expDiff;
+ struct uint128 rem, shiftedSigB;
+ uint32_t q, recip32;
+ uint64_t q64;
+ struct uint128 term, altRem, meanRem;
+ bool signRem;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
+ goto propagateNaN;
+ }
+ goto invalid;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ /*--------------------------------------------------------------------
+ | Argument b is an infinity. Doubling `expB' is an easy way to ensure
+ | that `expDiff' later is less than -1, which will result in returning
+ | a canonicalized version of argument a.
+ *--------------------------------------------------------------------*/
+ expB += expB;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) goto invalid;
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) {
+ expA = 0;
+ goto copyA;
+ }
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (expDiff < -1) goto copyA;
+ rem = softfloat_shortShiftLeft128(0, sigA, 32);
+ shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 32);
+ if (expDiff < 1) {
+ if (expDiff) {
+ --expB;
+ shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 33);
+ q = 0;
+ } else {
+ q = (sigB <= sigA);
+ if (q) {
+ rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ }
+ }
+ } else {
+ recip32 = softfloat_approxRecip32_1(sigB>>32);
+ expDiff -= 30;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
+ if (expDiff < 0) break;
+ q = (q64 + 0x80000000)>>32;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ rem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ }
+ expDiff -= 29;
+ }
+ /*--------------------------------------------------------------------
+ | (`expDiff' cannot be less than -29 here.)
+ *--------------------------------------------------------------------*/
+ q = (uint32_t) (q64>>32)>>(~expDiff & 31);
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, expDiff + 30);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ altRem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ goto selectRem;
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ do {
+ altRem = rem;
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ } while (! (rem.v64 & UINT64_C(0x8000000000000000)));
+ selectRem:
+ meanRem = softfloat_add128(rem.v64, rem.v0, altRem.v64, altRem.v0);
+ if ((meanRem.v64 & UINT64_C(0x8000000000000000)) || (! (meanRem.v64 | meanRem.v0) && (q & 1))) {
+ rem = altRem;
+ }
+ signRem = signA;
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ signRem = ! signRem;
+ rem = softfloat_sub128(0, 0, rem.v64, rem.v0);
+ }
+ return softfloat_normRoundPackToExtF80(signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ copyA:
+ if (expA < 1) {
+ sigA >>= 1 - expA;
+ expA = 0;
+ }
+ return packToExtF80(signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/extF80_roundToInt.cc b/src/cpu/softfloat3e/extF80_roundToInt.cc
new file mode 100644
index 0000000000..f71cdfc50e
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_roundToInt.cc
@@ -0,0 +1,123 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t
+ extF80_roundToInt(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64, signUI64;
+ int32_t exp;
+ uint64_t sigA;
+ uint16_t uiZ64;
+ uint64_t sigZ;
+ uint64_t lastBitMask, roundBitsMask;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ signUI64 = uiA64 & packToExtF80UI64(1, 0);
+ exp = expExtF80UI64(uiA64);
+ sigA = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x403E <= exp) {
+ if ((exp == 0x7FFF) && (uint64_t) (sigA<<1)) {
+ return softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp <= 0x3FFE) {
+ if (! exp) {
+ if ((sigA<<1) == 0) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!(sigA & UINT64_C(0x7FFFFFFFFFFFFFFF))) break;
+ case softfloat_round_near_maxMag:
+ if (exp == 0x3FFE) goto mag1;
+ break;
+ case softfloat_round_min:
+ if (signUI64) goto mag1;
+ break;
+ case softfloat_round_max:
+ if (!signUI64) goto mag1;
+ break;
+ }
+ return packToExtF80(signUI64, 0, 0);
+ mag1:
+ softfloat_setRoundingUp(status);
+ return packToExtF80(signUI64, 0x3FFF, UINT64_C(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = signUI64 | exp;
+ lastBitMask = (uint64_t) 1<<(0x403E - exp);
+ roundBitsMask = lastBitMask - 1;
+ sigZ = sigA;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ sigZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ sigZ += lastBitMask>>1;
+ if (!(sigZ & roundBitsMask)) sigZ &= ~lastBitMask;
+ } else if (roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max)) {
+ sigZ += roundBitsMask;
+ }
+ sigZ &= ~roundBitsMask;
+ if (!sigZ) {
+ ++uiZ64;
+ sigZ = UINT64_C(0x8000000000000000);
+ softfloat_setRoundingUp(status);
+ }
+ if (sigZ != sigA) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ if (sigZ > sigA)
+ softfloat_setRoundingUp(status);
+ }
+ return packToExtF80_twoargs(uiZ64, sigZ);
+}
diff --git a/src/cpu/softfloat3e/extF80_scale.cc b/src/cpu/softfloat3e/extF80_scale.cc
new file mode 100644
index 0000000000..48bd53afd4
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_scale.cc
@@ -0,0 +1,136 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Scales extended double-precision floating-point value in operand `a' by
+| value `b'. The function truncates the value in the second operand 'b' to
+| an integral value and adds that value to the exponent of the operand 'a'.
+| The operation performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+extFloat80_t extF80_scale(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ struct exp32_sig64 normExpSig;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+
+ if (expA == 0x7FFF) {
+ if ((sigA<<1) || ((expB == 0x7FFF) && (sigB<<1))) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ }
+ if ((expB == 0x7FFF) && signB) goto invalid;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return a;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB<<1) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ }
+ if ((expA | sigA) == 0) {
+ if (! signB) goto invalid;
+ return a;
+ }
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (signB) return packToExtF80(signA, 0, 0);
+ return packToExtF80(signA, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ if (! expA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ if (expB < 0x3FFF)
+ return softfloat_normRoundPackToExtF80(signA, expA, sigA, 0, 80, status);
+ }
+ if (!expB) {
+ if (!sigB) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+
+ if (expB > 0x400E) {
+ /* generate appropriate overflow/underflow */
+ return softfloat_roundPackToExtF80(signA, signB ? -0x3FFF : 0x7FFF, sigA, 0, 80, status);
+ }
+
+ if (expB < 0x3FFF) return a;
+
+ int shiftCount = 0x403E - expB;
+ sigB >>= shiftCount;
+ int32_t scale = (int32_t) sigB;
+ if (signB) scale = -scale; /* -32768..32767 */
+
+ return softfloat_roundPackToExtF80(signA, expA + scale, sigA, 0, 80, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_sqrt.cc b/src/cpu/softfloat3e/extF80_sqrt.cc
new file mode 100644
index 0000000000..1a5d52e5dc
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_sqrt.cc
@@ -0,0 +1,159 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ uint32_t sig32A, recipSqrt32, sig32Z;
+ struct uint128 rem;
+ uint64_t q, x64, sigZ;
+ struct uint128 y, term;
+ uint64_t sigZExtra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if ((expA | sigA) == 0) return packToExtF80(signA, 0, 0);
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) return packToExtF80(signA, 0, 0);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ | (`sig32Z' is guaranteed to be a lower bound on the square root of
+ | `sig32A', which makes `sig32Z' also a lower bound on the square root of
+ | `sigA'.)
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x3FFF)>>1) + 0x3FFF;
+ expA &= 1;
+ sig32A = sigA>>32;
+ recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A);
+ sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
+ if (expA) {
+ sig32Z >>= 1;
+ rem = softfloat_shortShiftLeft128(0, sigA, 61);
+ } else {
+ rem = softfloat_shortShiftLeft128(0, sigA, 62);
+ }
+ rem.v64 -= (uint64_t) sig32Z * sig32Z;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ q = ((uint32_t) (rem.v64>>2) * (uint64_t) recipSqrt32)>>32;
+ x64 = (uint64_t) sig32Z<<32;
+ sigZ = x64 + (q<<3);
+ y = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ /*------------------------------------------------------------------------
+ | (Repeating this loop is a rare occurrence.)
+ *------------------------------------------------------------------------*/
+ for (;;) {
+ term = softfloat_mul64ByShifted32To128(x64 + sigZ, q);
+ rem = softfloat_sub128(y.v64, y.v0, term.v64, term.v0);
+ if (! (rem.v64 & UINT64_C(0x8000000000000000))) break;
+ --q;
+ sigZ -= 1<<3;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ q = (((rem.v64>>2) * recipSqrt32)>>32) + 2;
+ x64 = sigZ;
+ sigZ = (sigZ<<1) + (q>>25);
+ sigZExtra = (uint64_t) (q<<39);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((q & 0xFFFFFF) <= 2) {
+ q &= ~(uint64_t) 0xFFFF;
+ sigZExtra = (uint64_t) (q<<39);
+ term = softfloat_mul64ByShifted32To128(x64 + (q>>27), q);
+ x64 = (uint32_t) (q<<5) * (uint64_t) (uint32_t) q;
+ term = softfloat_add128(term.v64, term.v0, 0, x64);
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 28);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ if (! sigZExtra) --sigZ;
+ --sigZExtra;
+ } else {
+ if (rem.v64 | rem.v0) sigZExtra |= 1;
+ }
+ }
+ return
+ softfloat_roundPackToExtF80(0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f128.cc b/src/cpu/softfloat3e/extF80_to_f128.cc
new file mode 100644
index 0000000000..24e523cac8
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f128.cc
@@ -0,0 +1,75 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ uint16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ bool sign;
+ struct uint128 frac128;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ exp = expExtF80UI64(uiA64);
+ frac = uiA0 & UINT64_C(0x7FFFFFFFFFFFFFFF);
+ if ((exp == 0x7FFF) && frac) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ sign = signExtF80UI64(uiA64);
+ frac128 = softfloat_shortShiftLeft128(0, frac, 49);
+ uiZ.v64 = packToF128UI64(sign, exp, frac128.v64);
+ uiZ.v0 = frac128.v0;
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f16.cc b/src/cpu/softfloat3e/extF80_to_f16.cc
new file mode 100644
index 0000000000..5078e689cc
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f16.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 extF80_to_f16(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, sig16;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig16 = softfloat_shortShiftRightJam64(sig, 49);
+ if (! (exp | sig16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3FF1;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x40) exp = -0x40;
+ }
+ return softfloat_roundPackToF16(sign, exp, sig16, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f32.cc b/src/cpu/softfloat3e/extF80_to_f32.cc
new file mode 100644
index 0000000000..558df4c235
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f32.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 extF80_to_f32(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, sig32;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = softfloat_shortShiftRightJam64(sig, 33);
+ if (! (exp | sig32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3F81;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF32(sign, exp, sig32, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f64.cc b/src/cpu/softfloat3e/extF80_to_f64.cc
new file mode 100644
index 0000000000..4ba4174e3c
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f64.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 extF80_to_f64(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! (exp | sig)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = softfloat_shortShiftRightJam64(sig, 1);
+ exp -= 0x3C01;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF64(sign, exp, sig, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i32.cc b/src/cpu/softfloat3e/extF80_to_i32.cc
new file mode 100644
index 0000000000..ea6c94484c
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i32.cc
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t extF80_to_i32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x4032 - exp;
+ if (shiftDist <= 0) shiftDist = 1;
+ sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc
new file mode 100644
index 0000000000..42415c4599
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc
@@ -0,0 +1,93 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t extF80_to_i32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (shiftDist < 33) {
+ if ((uiA64 == packToExtF80UI64(1, 0x401E)) && (sig < UINT64_C(0x8000000100000000))) {
+ if (exact && (sig & UINT64_C(0x00000000FFFFFFFF))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ absZ = sig>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t extF80_to_i64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ uint64_t sigExtra;
+ struct uint64_extra sig64Extra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigExtra = 0;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ sig = sig64Extra.v;
+ sigExtra = sig64Extra.extra;
+ }
+ return softfloat_roundToI64(sign, sig, sigExtra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc
new file mode 100644
index 0000000000..3500b20d27
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc
@@ -0,0 +1,90 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t extF80_to_i64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ int64_t absZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (shiftDist <= 0) {
+ if ((uiA64 == packToExtF80UI64(1, 0x403E)) && (sig == UINT64_C(0x8000000000000000))) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ absZ = sig>>shiftDist;
+ if (exact && (uint64_t) (sig<<(-shiftDist & 63))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return sign ? -absZ : absZ;
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui32.cc b/src/cpu/softfloat3e/extF80_to_ui32.cc
new file mode 100644
index 0000000000..449cafa884
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui32.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t
+ extF80_to_ui32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x4032 - exp;
+ if (shiftDist <= 0) shiftDist = 1;
+ sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToUI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc
new file mode 100644
index 0000000000..7ef1001390
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t extF80_to_ui32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (sign || (shiftDist < 32)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ z = sig>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t extF80_to_ui64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ uint64_t sigExtra;
+ struct uint64_extra sig64Extra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigExtra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ sig = sig64Extra.v;
+ sigExtra = sig64Extra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig, sigExtra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc
new file mode 100644
index 0000000000..78b058754d
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t extF80_to_ui64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ uint64_t z;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ z = sig>>shiftDist;
+ if (exact && (z<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float128_t
+ softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
+extern float128_t
+ softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
+
+float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
+
+float128_t f128_sub(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f128_div.cc b/src/cpu/softfloat3e/f128_div.cc
new file mode 100644
index 0000000000..837eb15aa0
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_div.cc
@@ -0,0 +1,187 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signZ;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ struct uint128 rem;
+ uint32_t recip32;
+ int ix;
+ uint64_t q64;
+ uint32_t q;
+ struct uint128 term;
+ uint32_t qs[3];
+ uint64_t sigZExtra;
+ struct uint128 sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0) goto propagateNaN;
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ goto invalid;
+ }
+ goto infinity;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) {
+ if (! (expA | sigA.v64 | sigA.v0)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FFE;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ rem = sigA;
+ if (softfloat_lt128(sigA.v64, sigA.v0, sigB.v64, sigB.v0)) {
+ --expZ;
+ rem = softfloat_add128(sigA.v64, sigA.v0, sigA.v64, sigA.v0);
+ }
+ recip32 = softfloat_approxRecip32_1(sigB.v64>>17);
+ ix = 3;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>19) * recip32;
+ q = (q64 + 0x80000000)>>32;
+ --ix;
+ if (ix < 0) break;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ }
+ qs[ix] = q;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (((q + 1) & 7) < 2) {
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ } else if (softfloat_le128(sigB.v64, sigB.v0, rem.v64, rem.v0)) {
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ }
+ if (rem.v64 | rem.v0) q |= 1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZExtra = (uint64_t) ((uint64_t) q<<60);
+ term = softfloat_shortShiftLeft128(0, qs[1], 54);
+ sigZ = softfloat_add128((uint64_t) qs[2]<<19, ((uint64_t) qs[0]<<25) + (q>>4), term.v64, term.v0);
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ uiZ.v64 = packToF128UI64(signZ, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_mul.cc b/src/cpu/softfloat3e/f128_mul.cc
new file mode 100644
index 0000000000..fd63a4590a
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_mul.cc
@@ -0,0 +1,148 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "primitiveTypes.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ uint64_t sig256Z[4];
+ uint64_t sigZExtra;
+ struct uint128 sigZ;
+ struct uint128_extra sig128Extra;
+ struct uint128 uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
+ goto propagateNaN;
+ }
+ magBits = expB | sigB.v64 | sigB.v0;
+ goto infArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ magBits = expA | sigA.v64 | sigA.v0;
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x4000;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 16);
+ softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
+ sigZExtra = sig256Z[indexWord(4, 1)] | (sig256Z[indexWord(4, 0)] != 0);
+ sigZ = softfloat_add128(sig256Z[indexWord(4, 3)], sig256Z[indexWord(4, 2)], sigA.v64, sigA.v0);
+ if (UINT64_C(0x0002000000000000) <= sigZ.v64) {
+ ++expZ;
+ sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1);
+ sigZ = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ }
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ }
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ uiZ.v64 = packToF128UI64(signZ, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_mulAdd.cc b/src/cpu/softfloat3e/f128_mulAdd.cc
new file mode 100644
index 0000000000..749342f5f1
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_mulAdd.cc
@@ -0,0 +1,332 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "primitiveTypes.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float128_t f128_mulAdd(float128_t a, float128_t b, float128_t c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signC;
+ int32_t expC;
+ struct uint128 sigC;
+ bool signZ;
+ uint64_t magBits;
+ struct uint128 uiZ;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ uint64_t sig256Z[4];
+ struct uint128 sigZ;
+ int32_t shiftDist, expDiff;
+ struct uint128 x128;
+ uint64_t sig256C[4];
+ static uint64_t zero256[4] = INIT_UINTM4(0, 0, 0, 0);
+ uint64_t sigZExtra, sig256Z0;
+ uint64_t uiA64, uiA0;
+ uint64_t uiB64, uiB0;
+ uint64_t uiC64, uiC0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ uiC64 = c.v64;
+ uiC0 = c.v0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signC = signF128UI64(uiC64) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF128UI64(uiC64);
+ sigC.v64 = fracF128UI64(uiC64);
+ sigC.v0 = uiC0;
+ signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
+ goto propagateNaN_ABC;
+ }
+ magBits = expB | sigB.v64 | sigB.v0;
+ goto infProdArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN_ABC;
+ magBits = expA | sigA.v64 | sigA.v0;
+ goto infProdArg;
+ }
+ if (expC == 0x7FFF) {
+ if (sigC.v64 | sigC.v0) {
+ uiZ.v64 = 0;
+ uiZ.v0 = 0;
+ goto propagateNaN_ZC;
+ }
+ uiZ.v64 = uiC64;
+ uiZ.v0 = uiC0;
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FFE;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ sigA = softfloat_shortShiftLeft128(sigA.v64, sigA.v0, 8);
+ sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 15);
+ softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ shiftDist = 0;
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = -1;
+ }
+ if (! expC) {
+ if (! (sigC.v64 | sigC.v0)) {
+ shiftDist += 8;
+ goto sigZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigC.v64, sigC.v0);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC.v64 |= UINT64_C(0x0001000000000000);
+ sigC = softfloat_shortShiftLeft128(sigC.v64, sigC.v0, 8);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expZ - expC;
+ if (expDiff < 0) {
+ expZ = expC;
+ if ((signZ == signC) || (expDiff < -1)) {
+ shiftDist -= expDiff;
+ if (shiftDist) {
+ sigZ = softfloat_shiftRightJam128(sigZ.v64, sigZ.v0, shiftDist);
+ }
+ } else {
+ if (! shiftDist) {
+ x128 = softfloat_shortShiftRight128(sig256Z[indexWord(4, 1)], sig256Z[indexWord(4, 0)], 1);
+ sig256Z[indexWord(4, 1)] = (sigZ.v0<<63) | x128.v64;
+ sig256Z[indexWord(4, 0)] = x128.v0;
+ sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, 1);
+ sig256Z[indexWord(4, 3)] = sigZ.v64;
+ sig256Z[indexWord(4, 2)] = sigZ.v0;
+ }
+ }
+ } else {
+ if (shiftDist) softfloat_add256M(sig256Z, sig256Z, sig256Z);
+ if (! expDiff) {
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ } else {
+ sig256C[indexWord(4, 3)] = sigC.v64;
+ sig256C[indexWord(4, 2)] = sigC.v0;
+ sig256C[indexWord(4, 1)] = 0;
+ sig256C[indexWord(4, 0)] = 0;
+ softfloat_shiftRightJam256M(sig256C, expDiff, sig256C);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 8;
+ if (signZ == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ sigZ = softfloat_add128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
+ } else {
+ softfloat_add256M(sig256Z, sig256C, sig256Z);
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ }
+ if (sigZ.v64 & UINT64_C(0x0200000000000000)) {
+ ++expZ;
+ shiftDist = 9;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ signZ = signC;
+ if (expDiff < -1) {
+ sigZ = softfloat_sub128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
+ sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
+ if (sigZExtra) {
+ sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, 0, 1);
+ }
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = 7;
+ }
+ goto shiftRightRoundPack;
+ } else {
+ sig256C[indexWord(4, 3)] = sigC.v64;
+ sig256C[indexWord(4, 2)] = sigC.v0;
+ sig256C[indexWord(4, 1)] = 0;
+ sig256C[indexWord(4, 0)] = 0;
+ softfloat_sub256M(sig256C, sig256Z, sig256Z);
+ }
+ } else if (! expDiff) {
+ sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, sigC.v64, sigC.v0);
+ if (! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord(4, 1)] && ! sig256Z[indexWord(4, 0)]) {
+ goto completeCancellation;
+ }
+ sig256Z[indexWord(4, 3)] = sigZ.v64;
+ sig256Z[indexWord(4, 2)] = sigZ.v0;
+ if (sigZ.v64 & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ softfloat_sub256M(zero256, sig256Z, sig256Z);
+ }
+ } else {
+ softfloat_sub256M(sig256Z, sig256C, sig256Z);
+ if (1 < expDiff) {
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = 7;
+ }
+ goto sigZ;
+ }
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ sigZExtra = sig256Z[indexWord(4, 1)];
+ sig256Z0 = sig256Z[indexWord(4, 0)];
+ if (sigZ.v64) {
+ if (sig256Z0) sigZExtra |= 1;
+ } else {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = sigZExtra;
+ sigZExtra = sig256Z0;
+ if (! sigZ.v64) {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = sigZExtra;
+ sigZExtra = 0;
+ if (! sigZ.v64) {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = 0;
+ }
+ }
+ }
+ shiftDist = softfloat_countLeadingZeros64(sigZ.v64);
+ expZ += 7 - shiftDist;
+ shiftDist = 15 - shiftDist;
+ if (0 < shiftDist) goto shiftRightRoundPack;
+ if (shiftDist) {
+ shiftDist = -shiftDist;
+ sigZ = softfloat_shortShiftLeft128(sigZ.v64, sigZ.v0, shiftDist);
+ x128 = softfloat_shortShiftLeft128(0, sigZExtra, shiftDist);
+ sigZ.v0 |= x128.v64;
+ sigZExtra = x128.v0;
+ }
+ goto roundPack;
+ }
+ sigZ:
+ sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
+ shiftRightRoundPack:
+ sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0);
+ sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, shiftDist);
+ roundPack:
+ return softfloat_roundPackToF128(signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN_ABC:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ goto propagateNaN_ZC;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infProdArg:
+ if ((sigC.v64 | sigC.v0) && expC == 0x7FFF) goto propagateNaN_ZC;
+ if (magBits) {
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ if (expC != 0x7FFF) return uiZ;
+ if (signZ == signC) return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ propagateNaN_ZC:
+ uiZ = softfloat_propagateNaNF128UI(uiZ.v64, uiZ.v0, uiC64, uiC0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zeroProd:
+ uiZ.v64 = uiC64;
+ uiZ.v0 = uiC0;
+ if (! (expC | sigC.v64 | sigC.v0) && (signZ != signC)) {
+ completeCancellation:
+ uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_roundToInt.cc b/src/cpu/softfloat3e/f128_roundToInt.cc
new file mode 100644
index 0000000000..c3b7287040
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_roundToInt.cc
@@ -0,0 +1,142 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t
+ f128_roundToInt(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ struct uint128 uiZ;
+ uint64_t lastBitMask0, roundBitsMask;
+ bool roundNearEven;
+ uint64_t lastBitMask64;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x402F <= exp) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (0x406F <= exp) {
+ if ((exp == 0x7FFF) && (fracF128UI64(uiA64) | uiA0)) {
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status);
+ return uiZ;
+ }
+ return a;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ lastBitMask0 = (uint64_t) 2<<(0x406E - exp);
+ roundBitsMask = lastBitMask0 - 1;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ roundNearEven = (roundingMode == softfloat_round_near_even);
+ if (roundNearEven || (roundingMode == softfloat_round_near_maxMag)) {
+ if (exp == 0x402F) {
+ if (UINT64_C(0x8000000000000000) <= uiZ.v0) {
+ ++uiZ.v64;
+ if (roundNearEven && (uiZ.v0 == UINT64_C(0x8000000000000000))) {
+ uiZ.v64 &= ~1;
+ }
+ }
+ } else {
+ uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, lastBitMask0>>1);
+ if (roundNearEven && !(uiZ.v0 & roundBitsMask)) {
+ uiZ.v0 &= ~lastBitMask0;
+ }
+ }
+ } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, roundBitsMask);
+ }
+ uiZ.v0 &= ~roundBitsMask;
+ lastBitMask64 = !lastBitMask0;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp < 0x3FFF) {
+ if (!((uiA64 & UINT64_C(0x7FFFFFFFFFFFFFFF)) | uiA0)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ.v64 = uiA64 & packToF128UI64(1, 0, 0);
+ uiZ.v0 = 0;
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!(fracF128UI64(uiA64) | uiA0)) break;
+ case softfloat_round_near_maxMag:
+ if (exp == 0x3FFE) uiZ.v64 |= packToF128UI64(0, 0x3FFF, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ.v64) uiZ.v64 = packToF128UI64(1, 0x3FFF, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ.v64) uiZ.v64 = packToF128UI64(0, 0x3FFF, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ uiZ.v64 = uiA64;
+ uiZ.v0 = 0;
+ lastBitMask64 = (uint64_t) 1<<(0x402F - exp);
+ roundBitsMask = lastBitMask64 - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ.v64 += lastBitMask64>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ.v64 += lastBitMask64>>1;
+ if (!((uiZ.v64 & roundBitsMask) | uiA0)) {
+ uiZ.v64 &= ~lastBitMask64;
+ }
+ } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;
+ }
+ uiZ.v64 &= ~roundBitsMask;
+ lastBitMask0 = 0;
+ }
+ if ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_to_extF80.cc b/src/cpu/softfloat3e/f128_to_extF80.cc
new file mode 100644
index 0000000000..916820bc9d
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_extF80.cc
@@ -0,0 +1,94 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64, frac0;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp32_sig128 normExpSig;
+ struct uint128 sig128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64);
+ frac0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64 | frac0) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! (frac64 | frac0)) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(frac64, frac0);
+ exp = normExpSig.exp;
+ frac64 = normExpSig.sig.v64;
+ frac0 = normExpSig.sig.v0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig128 = softfloat_shortShiftLeft128(frac64 | UINT64_C(0x0001000000000000), frac0, 15);
+ return softfloat_roundPackToExtF80(sign, exp, sig128.v64, sig128.v0, 80, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_f32.cc b/src/cpu/softfloat3e/f128_to_f32.cc
new file mode 100644
index 0000000000..485d68a0ce
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_f32.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f128_to_f32(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, frac32;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac32 = softfloat_shortShiftRightJam64(frac64, 18);
+ if (! (exp | frac32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3F81;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF32(sign, exp, frac32 | 0x40000000, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_f64.cc b/src/cpu/softfloat3e/f128_to_f64.cc
new file mode 100644
index 0000000000..0809c7102c
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_f64.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f128_to_f64(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64, frac0;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct uint128 frac128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64);
+ frac0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64 | frac0) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac128 = softfloat_shortShiftLeft128(frac64, frac0, 14);
+ frac64 = frac128.v64 | (frac128.v0 != 0);
+ if (! (exp | frac64)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3C01;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return
+ softfloat_roundPackToF64(sign, exp, frac64 | UINT64_C(0x4000000000000000), status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i32.cc b/src/cpu/softfloat3e/f128_to_i32.cc
new file mode 100644
index 0000000000..68cf2b3a70
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i32.cc
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig64 | sig0)) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sig64 |= (sig0 != 0);
+ shiftDist = 0x4023 - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc
new file mode 100644
index 0000000000..a62233d4df
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (49 <= shiftDist) {
+ if (exact && (exp | sig64)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF128UI64(uiA64);
+ if (shiftDist < 18) {
+ if (sign && (shiftDist == 17) && (sig64 < UINT64_C(0x0000000000020000))) {
+ if (exact && sig64) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && sig64 ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ absZ = sig64>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ struct uint128 sig128;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -15) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ if (shiftDist) {
+ sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
+ sig64 = sig128.v64;
+ sig0 = sig128.v0;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
+ sig64 = sigExtra.v;
+ sig0 = sigExtra.extra;
+ }
+ return softfloat_roundToI64(sign, sig64, sig0, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc
new file mode 100644
index 0000000000..edeccf1828
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc
@@ -0,0 +1,104 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ int8_t negShiftDist;
+ uint64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist < 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -14) {
+ if ((uiA64 == UINT64_C(0xC03E000000000000)) && (sig0 < UINT64_C(0x0002000000000000))) {
+ if (exact && sig0) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FFF) && (sig64 | sig0)
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ negShiftDist = -shiftDist;
+ absZ = sig64<>(shiftDist & 63);
+ if (exact && (uint64_t) (sig0<>shiftDist;
+ if (exact && (sig0 || (absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FFF) && sig64) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ shiftDist = 0x4023 - exp;
+ if (0 < shiftDist) {
+ sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ }
+ return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc
new file mode 100644
index 0000000000..96007f6a1d
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (49 <= shiftDist) {
+ if (exact && (exp | sig64)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF128UI64(uiA64);
+ if (sign || (shiftDist < 17)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && sig64 ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ z = sig64>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ struct uint128 sig128;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -15) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ if (shiftDist) {
+ sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
+ sig64 = sig128.v64;
+ sig0 = sig128.v0;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
+ sig64 = sigExtra.v;
+ sig0 = sigExtra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig64, sig0, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc
new file mode 100644
index 0000000000..8d30420b02
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc
@@ -0,0 +1,99 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ int8_t negShiftDist;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist < 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (sign || (shiftDist < -15)) goto invalid;
+ sig64 |= UINT64_C(0x0001000000000000);
+ negShiftDist = -shiftDist;
+ z = sig64<>(shiftDist & 63);
+ if (exact && (uint64_t) (sig0<>shiftDist;
+ if (exact && (sig0 || (z<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float16 softfloat_addMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
+extern float16 softfloat_subMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
+
+float16 f16_add(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
+ return softfloat_subMagsF16(a, b, status);
+ } else {
+ return softfloat_addMagsF16(a, b, status);
+ }
+}
+
+float16 f16_sub(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
+ return softfloat_addMagsF16(a, b, status);
+ } else {
+ return softfloat_subMagsF16(a, b, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f16_class.c b/src/cpu/softfloat3e/f16_class.c
new file mode 100644
index 0000000000..b375c1544e
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f16_class(float16 a)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & 0x200) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f16_compare.c b/src/cpu/softfloat3e/f16_compare.c
new file mode 100644
index 0000000000..1cfd56bec9
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f16_compare(float16 a, float16 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f16_class(a);
+ bClass = f16_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & 0x8000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & 0x8000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint16_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF16UI(a);
+ signB = signF16UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f16_div.c b/src/cpu/softfloat3e/f16_div.c
new file mode 100644
index 0000000000..c91760b03b
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_div.c
@@ -0,0 +1,149 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+#define SOFTFLOAT_FAST_DIV32TO16 1
+
+extern const uint16_t softfloat_approxRecip_1k0s[];
+extern const uint16_t softfloat_approxRecip_1k1s[];
+
+float16 f16_div(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signZ;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+#ifdef SOFTFLOAT_FAST_DIV32TO16
+ uint32_t sig32A;
+ uint16_t sigZ;
+#endif
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0xE;
+ sigA |= 0x0400;
+ sigB |= 0x0400;
+#ifdef SOFTFLOAT_FAST_DIV32TO16
+ if (sigA < sigB) {
+ --expZ;
+ sig32A = (uint32_t) sigA<<15;
+ } else {
+ sig32A = (uint32_t) sigA<<14;
+ }
+ sigZ = sig32A / sigB;
+ if (! (sigZ & 7)) sigZ |= ((uint32_t) sigB * sigZ != sig32A);
+#endif
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF16UI(signZ, 0x1F, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF16UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f16_getExp.c b/src/cpu/softfloat3e/f16_getExp.c
new file mode 100644
index 0000000000..dfade995f7
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of half-precision floating-point value 'a',
+| and returns the result as a half-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float16 f16_getExp(float16 a, struct softfloat_status_t *status)
+{
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
+ return (float16)packToF32UI(0, 0x1F, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return (float16)packToF32UI(1, 0x1F, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f16((int32_t)(expA) - 0xF, status);
+}
diff --git a/src/cpu/softfloat3e/f16_getMant.c b/src/cpu/softfloat3e/f16_getMant.c
new file mode 100644
index 0000000000..f0d8d54821
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of half-precision floating-point value 'a' and
+| returns the result as a half-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float16 f16_getMant(float16 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+ }
+ return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+ }
+
+ if (expA == 0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= 0x3ff;
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0xF;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0xF;
+ expA = 0xF - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0xE;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0xF - ((sigA >> 9) & 0x1);
+ break;
+ }
+
+ return packToF16UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f16_minmax.c b/src/cpu/softfloat3e/f16_minmax.c
new file mode 100644
index 0000000000..11922a1ba2
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float16 f16_min(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f16_denormal_to_zero(a);
+ b = f16_denormal_to_zero(b);
+ }
+
+ return (f16_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float16 f16_max(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f16_denormal_to_zero(a);
+ b = f16_denormal_to_zero(b);
+ }
+
+ return (f16_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f16_mul.c b/src/cpu/softfloat3e/f16_mul.c
new file mode 100644
index 0000000000..2e7e74826a
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_mul.c
@@ -0,0 +1,139 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_mul(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signZ;
+ uint16_t magBits;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+ uint32_t sig32Z;
+ uint16_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA || ((expB == 0x1F) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0xF;
+ sigA = (sigA | 0x0400)<<4;
+ sigB = (sigB | 0x0400)<<5;
+ sig32Z = (uint32_t) sigA * sigB;
+ sigZ = sig32Z>>16;
+ if (sig32Z & 0xFFFF) sigZ |= 1;
+ if (sigZ < 0x4000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF16UI;
+ } else {
+ uiZ = packToF16UI(signZ, 0x1F, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF16UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f16_mulAdd.c b/src/cpu/softfloat3e/f16_mulAdd.c
new file mode 100644
index 0000000000..0e630a9b7c
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_mulAdd.c
@@ -0,0 +1,232 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float16 f16_mulAdd(float16 a, float16 b, float16 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signC;
+ int8_t expC;
+ uint16_t sigC;
+ bool signProd;
+ uint16_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp8_sig16 normExpSig;
+ int8_t expProd;
+ uint32_t sigProd;
+ bool signZ;
+ int8_t expZ;
+ uint16_t sigZ;
+ int8_t expDiff;
+ uint32_t sig32Z, sig32C;
+ int8_t shiftDist;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(uiA);
+ expA = expF16UI(uiA);
+ sigA = fracF16UI(uiA);
+ signB = signF16UI(uiB);
+ expB = expF16UI(uiB);
+ sigB = fracF16UI(uiB);
+ signC = signF16UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF16UI(uiC);
+ sigC = fracF16UI(uiC);
+ signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0x1F) && sigA;
+ bool bisNaN = (expB == 0x1F) && sigB;
+ bool cisNaN = (expC == 0x1F) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF16UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF16UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0x1F) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0x1F) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF16UI(signC, 0x1F, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expProd = expA + expB - 0xE;
+ sigA = (sigA | 0x0400)<<4;
+ sigB = (sigB | 0x0400)<<4;
+ sigProd = (uint32_t) sigA * sigB;
+ if (sigProd < 0x20000000) {
+ --expProd;
+ sigProd <<= 1;
+ }
+ signZ = signProd;
+ if (! expC) {
+ if (! sigC) {
+ expZ = expProd - 1;
+ sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | 0x0400)<<3;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expProd - expC;
+ if (signProd == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ expZ = expC;
+ sigZ = sigC + softfloat_shiftRightJam32(sigProd, 16 - expDiff);
+ } else {
+ expZ = expProd;
+ sig32Z = sigProd + softfloat_shiftRightJam32((uint32_t) sigC<<16, expDiff);
+ sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0);
+ }
+ if (sigZ < 0x4000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig32C = (uint32_t) sigC<<16;
+ if (expDiff < 0) {
+ signZ = signC;
+ expZ = expC;
+ sig32Z = sig32C - softfloat_shiftRightJam32(sigProd, -expDiff);
+ } else if (! expDiff) {
+ expZ = expProd;
+ sig32Z = sigProd - sig32C;
+ if (! sig32Z) goto completeCancellation;
+ if (sig32Z & 0x80000000) {
+ signZ = ! signZ;
+ sig32Z = -sig32Z;
+ }
+ } else {
+ expZ = expProd;
+ sig32Z = sigProd - softfloat_shiftRightJam32(sig32C, expDiff);
+ }
+ shiftDist = softfloat_countLeadingZeros32(sig32Z) - 1;
+ expZ -= shiftDist;
+ shiftDist -= 16;
+ if (shiftDist < 0) {
+ sigZ = sig32Z>>(-shiftDist) | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
+ } else {
+ sigZ = (uint16_t) sig32Z<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_range(float16 a, float16 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint16_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF16UI(a)) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF16UI(b)) {
+ return softfloat_propagateNaNF16UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF16UI(a);
+ bIsNaN = isNaNF16UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF16UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF16UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float16 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~0x8000; // clear the sign bit
+ tmp_b = tmp_b & ~0x8000;
+ signA = 0;
+ }
+
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~0x8000) | (a & 0x8000); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~0x8000; // zero out the sign bit
+ break;
+ case 3:
+ z = z | 0x8000; // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f16_roundToInt.c b/src/cpu/softfloat3e/f16_roundToInt.c
new file mode 100644
index 0000000000..ee9be0c0b3
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_roundToInt(float16 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ bool sign;
+ uint16_t uiZ, lastBitMask, roundBitsMask;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ sign = signF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x19 <= (exp + scale)) {
+ if ((exp == 0x1F) && frac) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF16UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0xE) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF16UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0xE) uiZ |= packToF16UI(0, 0xF - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF16UI(1, 0xF - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF16UI(0, 0xF - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint16_t) 1<<(0x19 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f16_sqrt.c b/src/cpu/softfloat3e/f16_sqrt.c
new file mode 100644
index 0000000000..f0f8afef19
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_sqrt.c
@@ -0,0 +1,130 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extern const uint16_t softfloat_approxRecipSqrt_1k0s[];
+extern const uint16_t softfloat_approxRecipSqrt_1k1s[];
+
+float16 f16_sqrt(float16 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+ int index;
+ uint16_t r0;
+ uint32_t ESqrR0;
+ uint16_t sigma0;
+ uint16_t recipSqrt16, sigZ, shiftedSigZ;
+ uint16_t negRem;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF16UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0xF)>>1) + 0xE;
+ expA &= 1;
+ sigA |= 0x0400;
+ index = (sigA>>6 & 0xE) + expA;
+ r0 = softfloat_approxRecipSqrt_1k0s[index]
+ - (((uint32_t) softfloat_approxRecipSqrt_1k1s[index] * (sigA & 0x7F)) >>11);
+ ESqrR0 = ((uint32_t) r0 * r0)>>1;
+ if (expA) ESqrR0 >>= 1;
+ sigma0 = ~(uint16_t) ((ESqrR0 * sigA)>>16);
+ recipSqrt16 = r0 + (((uint32_t) r0 * sigma0)>>25);
+ if (! (recipSqrt16 & 0x8000)) recipSqrt16 = 0x8000;
+ sigZ = ((uint32_t) (sigA<<5) * recipSqrt16)>>16;
+ if (expA) sigZ >>= 1;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ ++sigZ;
+ if (! (sigZ & 7)) {
+ shiftedSigZ = sigZ>>1;
+ negRem = shiftedSigZ * shiftedSigZ;
+ sigZ &= ~1;
+ if (negRem & 0x8000) {
+ sigZ |= 1;
+ } else {
+ if (negRem) --sigZ;
+ }
+ }
+ return softfloat_roundPackToF16(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+}
diff --git a/src/cpu/softfloat3e/f16_to_extF80.cc b/src/cpu/softfloat3e/f16_to_extF80.cc
new file mode 100644
index 0000000000..418be8083d
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f16_to_extF80(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3FF0);
+ uiZ0 = (uint64_t) (frac | 0x0400)<<53;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f16_to_f32.c b/src/cpu/softfloat3e/f16_to_f32.c
new file mode 100644
index 0000000000..4d862161d8
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_f32.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f16_to_f32(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ uint32_t uiZ;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF32UI(sign, exp + 0x70, (uint32_t) frac<<13);
+}
diff --git a/src/cpu/softfloat3e/f16_to_f64.c b/src/cpu/softfloat3e/f16_to_f64.c
new file mode 100644
index 0000000000..7d61b63577
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_f64.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f16_to_f64(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF64UI(sign, exp + 0x3F0, (uint64_t) frac<<42);
+}
diff --git a/src/cpu/softfloat3e/f16_to_i32.c b/src/cpu/softfloat3e/f16_to_i32.c
new file mode 100644
index 0000000000..d00cfe2360
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i32.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f16_to_i32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ int32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if (0 <= shiftDist) {
+ sig32 <<= shiftDist;
+ return sign ? -sig32 : sig32;
+ }
+ shiftDist = exp - 0x0D;
+ if (0 < shiftDist) sig32 <<= shiftDist;
+ }
+ else {
+ if (softfloat_denormalsAreZeros(status)) sig32 = 0;
+ }
+ return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f16_to_i32_r_minMag.c b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c
new file mode 100644
index 0000000000..9a6bbdf83b
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f16_to_i32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ int32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (int32_t) (frac | 0x0400)<>= 10;
+ return sign ? -alignedSig : alignedSig;
+}
diff --git a/src/cpu/softfloat3e/f16_to_i64.c b/src/cpu/softfloat3e/f16_to_i64.c
new file mode 100644
index 0000000000..7dcbeaad80
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i64.c
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f16_to_i64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ int32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if (0 <= shiftDist) {
+ sig32 <<= shiftDist;
+ return sign ? -sig32 : sig32;
+ }
+ shiftDist = exp - 0x0D;
+ if (0 < shiftDist) sig32 <<= shiftDist;
+ }
+ else {
+ if (softfloat_denormalsAreZeros(status)) sig32 = 0;
+ }
+ return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f16_to_i64_r_minMag.c b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c
new file mode 100644
index 0000000000..4289c53525
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f16_to_i64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ int32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (int32_t) (frac | 0x0400)<>= 10;
+ return sign ? -alignedSig : alignedSig;
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui32.c b/src/cpu/softfloat3e/f16_to_ui32.c
new file mode 100644
index 0000000000..d217b2627f
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui32.c
@@ -0,0 +1,79 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f16_to_ui32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ uint32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if ((0 <= shiftDist) && ! sign) {
+ return sig32<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f16_to_ui32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ uint32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (sign || (exp == 0x1F)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (uint32_t) (frac | 0x0400)<>10;
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui64.c b/src/cpu/softfloat3e/f16_to_ui64.c
new file mode 100644
index 0000000000..351edb32ce
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui64.c
@@ -0,0 +1,79 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f16_to_ui64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ uint32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if ((0 <= shiftDist) && ! sign) {
+ return sig32<>12, (uint64_t) sig32<<52, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c
new file mode 100644
index 0000000000..d80d6e8f5d
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f16_to_ui64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ uint32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (sign || (exp == 0x1F)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (uint32_t) (frac | 0x0400)<>10;
+}
diff --git a/src/cpu/softfloat/f2xm1.cc b/src/cpu/softfloat3e/f2xm1.cc
similarity index 77%
rename from src/cpu/softfloat/f2xm1.cc
rename to src/cpu/softfloat3e/f2xm1.cc
index ed4af1d125..16daec1d36 100644
--- a/src/cpu/softfloat/f2xm1.cc
+++ b/src/cpu/softfloat3e/f2xm1.cc
@@ -25,12 +25,15 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
+#include "softfloat-helpers.h"
static const floatx80 floatx80_negone = packFloatx80(1, 0x3fff, BX_CONST64(0x8000000000000000));
static const floatx80 floatx80_neghalf = packFloatx80(1, 0x3ffe, BX_CONST64(0x8000000000000000));
-static const float128 float128_ln2 =
+static const float128_t float128_ln2 =
packFloat128(BX_CONST64(0x3ffe62e42fefa39e), BX_CONST64(0xf35793c7673007e6));
#ifdef BETTER_THAN_PENTIUM
@@ -47,7 +50,7 @@ static const float128 float128_ln2 =
#define EXP_ARR_SIZE 15
-static float128 exp_arr[EXP_ARR_SIZE] =
+static float128_t exp_arr[EXP_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
@@ -66,10 +69,10 @@ static float128 exp_arr[EXP_ARR_SIZE] =
PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
};
-extern float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
+extern float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status);
/* required -1 < x < 1 */
-static float128 poly_exp(float128 x, struct float_status_t *status)
+static float128_t poly_exp(float128_t x, struct softfloat_status_t *status)
{
/*
// 2 3 4 5 6 7 8 9
@@ -92,8 +95,8 @@ static float128 poly_exp(float128 x, struct float_status_t *status)
// e - 1 ~ x * [ p(x) + x * q(x) ]
//
*/
- float128 t = EvalPoly(x, exp_arr, EXP_ARR_SIZE, status);
- return float128_mul(t, x, status);
+ float128_t t = EvalPoly(x, (const float128_t*) exp_arr, EXP_ARR_SIZE, status);
+ return f128_mul(t, x, status);
}
// =================================================
@@ -114,49 +117,51 @@ static float128 poly_exp(float128 x, struct float_status_t *status)
// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
// 1! 2! 3! 4! 5! n!
//
-
-floatx80 f2xm1(floatx80 a, struct float_status_t *status)
+floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u zSig0, zSig1, zSig2;
+ static const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+
+ uint64_t zSig0, zSig1, zSig2;
+ struct exp32_sig64 normExpSig;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaNOne(a, status);
+ if (aSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, 0, 0, status);
return (aSign) ? floatx80_negone : a;
}
- if (aExp == 0) {
- if (aSig == 0) return a;
- float_raise(status, float_flag_denormal | float_flag_inexact);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ if (! aExp) {
+ if (! aSig) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal | softfloat_flag_inexact);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
tiny_argument:
mul128By64To192(LN2_SIG_HI, LN2_SIG_LO, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--aExp;
}
- return
- roundAndPackFloatx80(80, aSign, aExp, zSig0, zSig1, status);
+ return softfloat_roundPackToExtF80(aSign, aExp, zSig0, zSig1, 80, status);
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
if (aExp < 0x3FFF)
{
@@ -167,14 +172,14 @@ floatx80 f2xm1(floatx80 a, struct float_status_t *status)
/* using float128 for approximation */
/* ******************************** */
- float128 x = floatx80_to_float128(a, status);
- x = float128_mul(x, float128_ln2, status);
+ float128_t x = extF80_to_f128(a, status);
+ x = f128_mul(x, float128_ln2, status);
x = poly_exp(x, status);
- return float128_to_floatx80(x, status);
+ return f128_to_extF80(x, status);
}
else
{
- if (a.exp == 0xBFFF && ! (aSig<<1))
+ if (a.signExp == 0xBFFF && ! (aSig<<1))
return floatx80_neghalf;
return a;
diff --git a/src/cpu/softfloat3e/f32_addsub.c b/src/cpu/softfloat3e/f32_addsub.c
new file mode 100644
index 0000000000..0b12d0e76a
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_addsub.c
@@ -0,0 +1,60 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float32 softfloat_addMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
+extern float32 softfloat_subMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
+
+float32 f32_add(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
+ return softfloat_subMagsF32(a, b, status);
+ } else {
+ return softfloat_addMagsF32(a, b, status);
+ }
+}
+
+float32 f32_sub(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
+ return softfloat_addMagsF32(a, b, status);
+ } else {
+ return softfloat_subMagsF32(a, b, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f32_class.c b/src/cpu/softfloat3e/f32_class.c
new file mode 100644
index 0000000000..84c337d0e8
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f32_class(float32 a)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & 0x00400000) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f32_compare.c b/src/cpu/softfloat3e/f32_compare.c
new file mode 100644
index 0000000000..6c8ecfaaec
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f32_compare(float32 a, float32 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f32_class(a);
+ bClass = f32_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & 0x80000000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & 0x80000000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint32_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF32UI(a);
+ signB = signF32UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f32_div.c b/src/cpu/softfloat3e/f32_div.c
new file mode 100644
index 0000000000..a9ccfcfd4a
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_div.c
@@ -0,0 +1,146 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+#define SOFTFLOAT_FAST_DIV64TO32
+
+float32 f32_div(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signZ;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+ uint64_t sig64A;
+ uint32_t sigZ;
+#endif
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x7E;
+ sigA |= 0x00800000;
+ sigB |= 0x00800000;
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+ if (sigA < sigB) {
+ --expZ;
+ sig64A = (uint64_t) sigA<<31;
+ } else {
+ sig64A = (uint64_t) sigA<<30;
+ }
+ sigZ = sig64A / sigB;
+ if (! (sigZ & 0x3F)) sigZ |= ((uint64_t) sigB * sigZ != sig64A);
+#endif
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF32UI(signZ, 0xFF, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF32UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f32_frc.c b/src/cpu/softfloat3e/f32_frc.c
new file mode 100644
index 0000000000..fc1b024603
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_frc.c
@@ -0,0 +1,101 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the fractional portion of single-precision floating-point value `a',
+| and returns the result as a single-precision floating-point value. The
+| fractional results are precise. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_frc(float32 a, struct softfloat_status_t *status)
+{
+ int roundingMode = softfloat_getRoundingMode(status);
+
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ uint32_t lastBitMask;
+ uint32_t roundBitsMask;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ if (expA >= 0x96) {
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+ }
+
+ if (expA < 0x7F) {
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow))
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF32UI(signA, 0, 0);
+ }
+ }
+ return a;
+ }
+
+ lastBitMask = 1 << (0x96 - expA);
+ roundBitsMask = lastBitMask - 1;
+
+ sigA &= roundBitsMask;
+ sigA <<= 7;
+ expA--;
+
+ if (! sigA)
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+
+ return softfloat_normRoundPackToF32(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f32_getExp.c b/src/cpu/softfloat3e/f32_getExp.c
new file mode 100644
index 0000000000..66b00ac7c5
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of single-precision floating-point value 'a',
+| and returns the result as a single-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_getExp(float32 a, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ return packToF32UI(0, 0xFF, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF32UI(1, 0xFF, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f32((int32_t)(expA) - 0x7F, status);
+}
diff --git a/src/cpu/softfloat3e/f32_getMant.c b/src/cpu/softfloat3e/f32_getMant.c
new file mode 100644
index 0000000000..9dfa58a632
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of single-precision floating-point value 'a' and
+| returns the result as a single-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_getMant(float32 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ }
+ return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ }
+
+ if (! expA) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= 0x7FFFFF;
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0x7F;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0x7F;
+ expA = 0x7F - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0x7E;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0x7F - ((sigA >> 22) & 0x1);
+ break;
+ }
+
+ return packToF32UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f32_minmax.c b/src/cpu/softfloat3e/f32_minmax.c
new file mode 100644
index 0000000000..e36c297ae7
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float32 f32_min(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f32_denormal_to_zero(a);
+ b = f32_denormal_to_zero(b);
+ }
+
+ return (f32_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float32 f32_max(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f32_denormal_to_zero(a);
+ b = f32_denormal_to_zero(b);
+ }
+
+ return (f32_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f32_mul.c b/src/cpu/softfloat3e/f32_mul.c
new file mode 100644
index 0000000000..db96e0db7a
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_mul.c
@@ -0,0 +1,137 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_mul(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signZ;
+ uint32_t magBits;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+ uint32_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA || ((expB == 0xFF) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x7F;
+ sigA = (sigA | 0x00800000)<<7;
+ sigB = (sigB | 0x00800000)<<8;
+ sigZ = softfloat_shortShiftRightJam64((uint64_t) sigA * sigB, 32);
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF32UI;
+ } else {
+ uiZ = packToF32UI(signZ, 0xFF, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF32UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f32_mulAdd.c b/src/cpu/softfloat3e/f32_mulAdd.c
new file mode 100644
index 0000000000..101b20f18b
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_mulAdd.c
@@ -0,0 +1,233 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float32 f32_mulAdd(float32 a, float32 b, float32 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signC;
+ int16_t expC;
+ uint32_t sigC;
+ bool signProd;
+ uint32_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp16_sig32 normExpSig;
+ int16_t expProd;
+ uint64_t sigProd;
+ bool signZ;
+ int16_t expZ;
+ uint32_t sigZ;
+ int16_t expDiff;
+ uint64_t sig64Z, sig64C;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(uiA);
+ expA = expF32UI(uiA);
+ sigA = fracF32UI(uiA);
+ signB = signF32UI(uiB);
+ expB = expF32UI(uiB);
+ sigB = fracF32UI(uiB);
+ signC = signF32UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF32UI(uiC);
+ sigC = fracF32UI(uiC);
+ signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0xFF) && sigA;
+ bool bisNaN = (expB == 0xFF) && sigB;
+ bool cisNaN = (expC == 0xFF) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF32UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF32UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0xFF) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0xFF) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF32UI(signC, 0xFF, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expProd = expA + expB - 0x7E;
+ sigA = (sigA | 0x00800000)<<7;
+ sigB = (sigB | 0x00800000)<<7;
+ sigProd = (uint64_t) sigA * sigB;
+ if (sigProd < UINT64_C(0x2000000000000000)) {
+ --expProd;
+ sigProd <<= 1;
+ }
+ signZ = signProd;
+ if (! expC) {
+ if (! sigC) {
+ expZ = expProd - 1;
+ sigZ = softfloat_shortShiftRightJam64(sigProd, 31);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | 0x00800000)<<6;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expProd - expC;
+ if (signProd == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ expZ = expC;
+ sigZ = sigC + softfloat_shiftRightJam64(sigProd, 32 - expDiff);
+ } else {
+ expZ = expProd;
+ sig64Z = sigProd + softfloat_shiftRightJam64((uint64_t) sigC<<32, expDiff);
+ sigZ = softfloat_shortShiftRightJam64(sig64Z, 32);
+ }
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64C = (uint64_t) sigC<<32;
+ if (expDiff < 0) {
+ signZ = signC;
+ expZ = expC;
+ sig64Z = sig64C - softfloat_shiftRightJam64(sigProd, -expDiff);
+ } else if (! expDiff) {
+ expZ = expProd;
+ sig64Z = sigProd - sig64C;
+ if (! sig64Z) goto completeCancellation;
+ if (sig64Z & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ sig64Z = -sig64Z;
+ }
+ } else {
+ expZ = expProd;
+ sig64Z = sigProd - softfloat_shiftRightJam64(sig64C, expDiff);
+ }
+ shiftDist = softfloat_countLeadingZeros64(sig64Z) - 1;
+ expZ -= shiftDist;
+ shiftDist -= 32;
+ if (shiftDist < 0) {
+ sigZ = softfloat_shortShiftRightJam64(sig64Z, -shiftDist);
+ } else {
+ sigZ = (uint32_t) sig64Z<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_range(float32 a, float32 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF32UI(a)) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF32UI(b)) {
+ return softfloat_propagateNaNF32UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF32UI(a);
+ bIsNaN = isNaNF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF32UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF32UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float32 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~0x80000000; // clear the sign bit
+ tmp_b = tmp_b & ~0x80000000;
+ signA = 0;
+ }
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~0x80000000) | (a & 0x80000000); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~0x80000000; // zero out the sign bit
+ break;
+ case 3:
+ z = z | 0x80000000; // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f32_roundToInt.c b/src/cpu/softfloat3e/f32_roundToInt.c
new file mode 100644
index 0000000000..7791fbbf41
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_roundToInt(float32 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ int32_t frac;
+ uint32_t uiZ, lastBitMask, roundBitsMask;
+ bool sign;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ sign = signF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x96 <= (exp + scale)) {
+ if ((exp == 0xFF) && frac) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF32UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0x7E) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF32UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0x7E) uiZ |= packToF32UI(0, 0x7F - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF32UI(1, 0x7F - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF32UI(0, 0x7F - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint32_t) 1<<(0x96 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF32UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f32_scalef.c b/src/cpu/softfloat3e/f32_scalef.c
new file mode 100644
index 0000000000..320baff30a
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_scalef.c
@@ -0,0 +1,155 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Return the result of a floating point scale of the single-precision floating
+| point value `a' by multiplying it by 2 power of the single-precision
+| floating point value 'b' converted to integral value. If the result cannot
+| be represented in single precision, then the proper overflow response (for
+| positive scaling operand), or the proper underflow response (for negative
+| scaling operand) is issued. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_scalef(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ int shiftCount;
+ int scale = 0;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0xFF) {
+ if (sigB) return softfloat_propagateNaNF32UI(a, b, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) {
+ int aIsSignalingNaN = (sigA & 0x00400000) == 0;
+ if (aIsSignalingNaN || expB != 0xFF || sigB)
+ return softfloat_propagateNaNF32UI(a, b, status);
+
+ return signB ? 0 : packToF32UI(0, 0xFF, 0);
+ }
+
+ if (expB == 0xFF && signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (expB == 0xFF && ! signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ return packToF32UI(signA, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((expB | sigB) == 0) return a;
+
+ if (expB == 0xFF) {
+ if (signB) return packToF32UI(signA, 0, 0);
+ return packToF32UI(signA, 0xFF, 0);
+ }
+
+ if (expB >= 0x8E) {
+ // handle obvious overflow/underflow result
+ return softfloat_roundPackToF32(signA, signB ? -0x7F : 0xFF, sigA, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB <= 0x7E) {
+ if (! expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ scale = -signB;
+ }
+ else {
+ shiftCount = expB - 0x9E;
+ sigB = (sigB | 0x800000)<<8;
+ scale = sigB>>(-shiftCount);
+
+ if (signB) {
+ if ((uint32_t) (sigB<<(shiftCount & 31))) scale++;
+ scale = -scale;
+ }
+
+ if (scale > 0x200) scale = 0x200;
+ if (scale < -0x200) scale = -0x200;
+ }
+
+ if (expA != 0) {
+ sigA |= 0x00800000;
+ } else {
+ expA++;
+ }
+
+ expA += scale - 1;
+ sigA <<= 7;
+ return softfloat_normRoundPackToF32(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f32_sqrt.c b/src/cpu/softfloat3e/f32_sqrt.c
new file mode 100644
index 0000000000..fc2ef8f761
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_sqrt.c
@@ -0,0 +1,117 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_sqrt(float32 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+ uint32_t sigZ, shiftedSigZ;
+ uint32_t negRem;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF32UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x7F)>>1) + 0x7E;
+ expA &= 1;
+ sigA = (sigA | 0x00800000)<<8;
+ sigZ =
+ ((uint64_t) sigA * softfloat_approxRecipSqrt32_1(expA, sigA))>>32;
+ if (expA) sigZ >>= 1;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZ += 2;
+ if ((sigZ & 0x3F) < 2) {
+ shiftedSigZ = sigZ>>2;
+ negRem = shiftedSigZ * shiftedSigZ;
+ sigZ &= ~3;
+ if (negRem & 0x80000000) {
+ sigZ |= 1;
+ } else {
+ if (negRem) --sigZ;
+ }
+ }
+ return softfloat_roundPackToF32(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+}
diff --git a/src/cpu/softfloat3e/f32_to_extF80.cc b/src/cpu/softfloat3e/f32_to_extF80.cc
new file mode 100644
index 0000000000..73b8bedfdd
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f32_to_extF80(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3F80);
+ uiZ0 = (uint64_t) (frac | 0x00800000)<<40;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f32_to_f128.cc b/src/cpu/softfloat3e/f32_to_f128.cc
new file mode 100644
index 0000000000..6d3fafec29
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f128.cc
@@ -0,0 +1,86 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f32_to_f128(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ uiZ.v64 = packToF128UI64(sign, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ.v64 = packToF128UI64(sign, exp + 0x3F80, (uint64_t) frac<<25);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f32_to_f16.c b/src/cpu/softfloat3e/f32_to_f16.c
new file mode 100644
index 0000000000..9253a958a5
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f16.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f32_to_f16(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, frac16;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF16UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac16 = frac>>9 | ((frac & 0x1FF) != 0);
+ if (! (exp | frac16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF16(sign, exp - 0x71, frac16 | 0x4000, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_f64.c b/src/cpu/softfloat3e/f32_to_f64.c
new file mode 100644
index 0000000000..28ebb61b6c
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f64.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f32_to_f64(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF64UI(sign, exp + 0x380, (uint64_t) frac<<29);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i32.c b/src/cpu/softfloat3e/f32_to_i32.c
new file mode 100644
index 0000000000..2b3df52a3c
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i32.c
@@ -0,0 +1,78 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f32_to_i32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ uint64_t sig64;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0xFF) && sig) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<32;
+ shiftDist = 0xAA - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i32_r_minMag.c b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c
new file mode 100644
index 0000000000..abe782d3b0
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f32_to_i32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x9E - exp;
+ if (32 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (shiftDist <= 0) {
+ if (a == packToF32UI(1, 0x9E, 0)) return -0x7FFFFFFF - 1;
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = (sig | 0x00800000)<<8;
+ absZ = sig>>shiftDist;
+ if (exact && ((uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f32_to_i64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ uint64_t sig64, extra;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ extra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
+ sig64 = sig64Extra.v;
+ extra = sig64Extra.extra;
+ }
+ return softfloat_roundToI64(sign, sig64, extra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i64_r_minMag.c b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c
new file mode 100644
index 0000000000..2ccabd09de
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f32_to_i64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t sig64;
+ int64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (shiftDist <= 0) {
+ if (a == packToF32UI(1, 0xBE, 0)) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ absZ = sig64>>shiftDist;
+ shiftDist = 40 - shiftDist;
+ if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return sign ? -absZ : absZ;
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui32.c b/src/cpu/softfloat3e/f32_to_ui32.c
new file mode 100644
index 0000000000..5a8d574142
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui32.c
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f32_to_ui32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ uint64_t sig64;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0xFF) && sig) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<32;
+ shiftDist = 0xAA - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c
new file mode 100644
index 0000000000..4b37708b04
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c
@@ -0,0 +1,83 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f32_to_ui32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x9E - exp;
+ if (32 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = (sig | 0x00800000)<<8;
+ z = sig>>shiftDist;
+ if (exact && (z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f32_to_ui64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ uint64_t sig64, extra;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<40;
+ extra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
+ sig64 = sig64Extra.v;
+ extra = sig64Extra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig64, extra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c
new file mode 100644
index 0000000000..111c50e7f2
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c
@@ -0,0 +1,84 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f32_to_ui64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t sig64, z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ z = sig64>>shiftDist;
+ shiftDist = 40 - shiftDist;
+ if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f64_addsub.c b/src/cpu/softfloat3e/f64_addsub.c
new file mode 100644
index 0000000000..6c5acb4f77
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_addsub.c
@@ -0,0 +1,70 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float64 softfloat_addMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
+extern float64 softfloat_subMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
+
+float64 f64_add(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ bool signB;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA == signB) {
+ return softfloat_addMagsF64(a, b, signA, status);
+ } else {
+ return softfloat_subMagsF64(a, b, signA, status);
+ }
+}
+
+float64 f64_sub(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ bool signB;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA == signB) {
+ return softfloat_subMagsF64(a, b, signA, status);
+ } else {
+ return softfloat_addMagsF64(a, b, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f64_class.c b/src/cpu/softfloat3e/f64_class.c
new file mode 100644
index 0000000000..1d44a63518
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f64_class(float64 a)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & UINT64_C(0x0008000000000000)) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f64_compare.c b/src/cpu/softfloat3e/f64_compare.c
new file mode 100644
index 0000000000..aed2507682
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f64_compare(float64 a, float64 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f64_class(a);
+ bClass = f64_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & UINT64_C(0x8000000000000000);
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & UINT64_C(0x8000000000000000);
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint64_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f64_div.c b/src/cpu/softfloat3e/f64_div.c
new file mode 100644
index 0000000000..89f74f1b10
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_div.c
@@ -0,0 +1,165 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_div(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signZ;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ uint32_t recip32, sig32Z, doubleTerm;
+ uint64_t rem;
+ uint32_t q;
+ uint64_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FE;
+ sigA |= UINT64_C(0x0010000000000000);
+ sigB |= UINT64_C(0x0010000000000000);
+ if (sigA < sigB) {
+ --expZ;
+ sigA <<= 11;
+ } else {
+ sigA <<= 10;
+ }
+ sigB <<= 11;
+ recip32 = softfloat_approxRecip32_1(sigB>>32) - 2;
+ sig32Z = ((uint32_t) (sigA>>32) * (uint64_t) recip32)>>32;
+ doubleTerm = sig32Z<<1;
+ rem =
+ ((sigA - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
+ - (uint64_t) doubleTerm * ((uint32_t) sigB>>4);
+ q = (((uint32_t) (rem>>32) * (uint64_t) recip32)>>32) + 4;
+ sigZ = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<4);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((sigZ & 0x1FF) < 4<<4) {
+ q &= ~7;
+ sigZ &= ~(uint64_t) 0x7F;
+ doubleTerm = q<<1;
+ rem =
+ ((rem - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
+ - (uint64_t) doubleTerm * ((uint32_t) sigB>>4);
+ if (rem & UINT64_C(0x8000000000000000)) {
+ sigZ -= 1<<7;
+ } else {
+ if (rem) sigZ |= 1;
+ }
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF64UI(signZ, 0x7FF, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF64UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f64_frc.c b/src/cpu/softfloat3e/f64_frc.c
new file mode 100644
index 0000000000..46c21ac4f8
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_frc.c
@@ -0,0 +1,101 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the fractional portion of double-precision floating-point value `a',
+| and returns the result as a double-precision floating-point value. The
+| fractional results are precise. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_frc(float64 a, struct softfloat_status_t *status)
+{
+ int roundingMode = softfloat_getRoundingMode(status);
+
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ uint64_t lastBitMask;
+ uint64_t roundBitsMask;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ if (expA >= 0x433) {
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+ }
+
+ if (expA < 0x3FF) {
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow))
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signA, 0, 0);
+ }
+ }
+ return a;
+ }
+
+ lastBitMask = UINT64_C(1) << (0x433 - expA);
+ roundBitsMask = lastBitMask - 1;
+
+ sigA &= roundBitsMask;
+ sigA <<= 10;
+ expA--;
+
+ if (! sigA)
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+
+ return softfloat_normRoundPackToF64(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f64_getExp.c b/src/cpu/softfloat3e/f64_getExp.c
new file mode 100644
index 0000000000..b76cc996d5
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of double-precision floating-point value 'a',
+| and returns the result as a double-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_getExp(float64 a, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ return packToF64UI(0, 0x7FF, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF64UI(1, 0x7FF, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f64((int32_t)(expA) - 0x3FF);
+}
diff --git a/src/cpu/softfloat3e/f64_getMant.c b/src/cpu/softfloat3e/f64_getMant.c
new file mode 100644
index 0000000000..84077e3148
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of double-precision floating-point value 'a' and
+| returns the result as a double-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_getMant(float64 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ }
+ return packToF64UI(~sign_ctrl & signA, 0x3FF, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF64UI(~sign_ctrl & signA, 0x3FF, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ }
+
+ if (expA == 0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= UINT64_C(0xFFFFFFFFFFFFF);
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0x3FF;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0x3FF;
+ expA = 0x3FF - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0x3FE;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0x3FF - ((sigA >> 51) & 0x1);
+ break;
+ }
+
+ return packToF64UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f64_minmax.c b/src/cpu/softfloat3e/f64_minmax.c
new file mode 100644
index 0000000000..3c927410ab
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float64 f64_min(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f64_denormal_to_zero(a);
+ b = f64_denormal_to_zero(b);
+ }
+
+ return (f64_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float64 f64_max(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f64_denormal_to_zero(a);
+ b = f64_denormal_to_zero(b);
+ }
+
+ return (f64_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f64_mul.c b/src/cpu/softfloat3e/f64_mul.c
new file mode 100644
index 0000000000..c1e98f2b6d
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_mul.c
@@ -0,0 +1,139 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_mul(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ struct uint128 sig128Z;
+ uint64_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA || ((expB == 0x7FF) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FF;
+ sigA = (sigA | UINT64_C(0x0010000000000000))<<10;
+ sigB = (sigB | UINT64_C(0x0010000000000000))<<11;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ sigZ = sig128Z.v64 | (sig128Z.v0 != 0);
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF64UI;
+ } else {
+ uiZ = packToF64UI(signZ, 0x7FF, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF64UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f64_mulAdd.c b/src/cpu/softfloat3e/f64_mulAdd.c
new file mode 100644
index 0000000000..9623b49800
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_mulAdd.c
@@ -0,0 +1,243 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float64 f64_mulAdd(float64 a, float64 b, float64 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signC;
+ int16_t expC;
+ uint64_t sigC;
+ bool signZ;
+ uint64_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ struct uint128 sig128Z;
+ uint64_t sigZ;
+ int16_t expDiff;
+ struct uint128 sig128C;
+ int8_t shiftDist;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(uiA);
+ expA = expF64UI(uiA);
+ sigA = fracF64UI(uiA);
+ signB = signF64UI(uiB);
+ expB = expF64UI(uiB);
+ sigB = fracF64UI(uiB);
+ signC = signF64UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF64UI(uiC);
+ sigC = fracF64UI(uiC);
+ signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0x7FF) && sigA;
+ bool bisNaN = (expB == 0x7FF) && sigB;
+ bool cisNaN = (expC == 0x7FF) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF64UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF64UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0x7FF) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0x7FF) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF64UI(signC, 0x7FF, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FE;
+ sigA = (sigA | UINT64_C(0x0010000000000000))<<10;
+ sigB = (sigB | UINT64_C(0x0010000000000000))<<10;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ if (sig128Z.v64 < UINT64_C(0x2000000000000000)) {
+ --expZ;
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0);
+ }
+ if (! expC) {
+ if (! sigC) {
+ --expZ;
+ sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | UINT64_C(0x0010000000000000))<<9;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expZ - expC;
+ if (expDiff < 0) {
+ expZ = expC;
+ if ((signZ == signC) || (expDiff < -1)) {
+ sig128Z.v64 = softfloat_shiftRightJam64(sig128Z.v64, -expDiff);
+ } else {
+ sig128Z = softfloat_shortShiftRightJam128(sig128Z.v64, sig128Z.v0, 1);
+ }
+ } else if (expDiff) {
+ sig128C = softfloat_shiftRightJam128(sigC, 0, expDiff);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signZ == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0);
+ } else {
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0);
+ sigZ = sig128Z.v64 | (sig128Z.v0 != 0);
+ }
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ signZ = signC;
+ sig128Z = softfloat_sub128(sigC, 0, sig128Z.v64, sig128Z.v0);
+ } else if (! expDiff) {
+ sig128Z.v64 = sig128Z.v64 - sigC;
+ if (! (sig128Z.v64 | sig128Z.v0)) goto completeCancellation;
+ if (sig128Z.v64 & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ sig128Z = softfloat_sub128(0, 0, sig128Z.v64, sig128Z.v0);
+ }
+ } else {
+ sig128Z = softfloat_sub128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0);
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! sig128Z.v64) {
+ expZ -= 64;
+ sig128Z.v64 = sig128Z.v0;
+ sig128Z.v0 = 0;
+ }
+ shiftDist = softfloat_countLeadingZeros64(sig128Z.v64) - 1;
+ expZ -= shiftDist;
+ if (shiftDist < 0) {
+ sigZ = softfloat_shortShiftRightJam64(sig128Z.v64, -shiftDist);
+ } else {
+ sig128Z = softfloat_shortShiftLeft128(sig128Z.v64, sig128Z.v0, shiftDist);
+ sigZ = sig128Z.v64;
+ }
+ sigZ |= (sig128Z.v0 != 0);
+ }
+ roundPack:
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infProdArg:
+ if (magBits) {
+ uiZ = packToF64UI(signZ, 0x7FF, 0);
+ if (signZ == signC || expC != 0x7FF) {
+ if ((sigA && !expA) || (sigB && !expB) || (sigC && !expC))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiZ;
+ }
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF64UI;
+ return softfloat_propagateNaNF64UI(uiZ, uiC, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zeroProd:
+ uiZ = packToF64UI(signC, expC, sigC);
+ if (!expC && sigC) {
+ /* Exact zero plus a denormal */
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signC, 0, 0);
+ }
+ }
+ if (! (expC | sigC) && (signZ != signC)) {
+ completeCancellation:
+ uiZ = packToF64UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_range.c b/src/cpu/softfloat3e/f64_range.c
new file mode 100644
index 0000000000..6f01c84cce
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_range.c
@@ -0,0 +1,135 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_range(float64 a, float64 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF64UI(a)) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF64UI(b)) {
+ return softfloat_propagateNaNF64UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF64UI(a);
+ bIsNaN = isNaNF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF64UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF64UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float64 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~UINT64_C(0x8000000000000000); // clear the sign bit
+ tmp_b = tmp_b & ~UINT64_C(0x8000000000000000);
+ signA = 0;
+ }
+
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~UINT64_C(0x8000000000000000)) | (a & UINT64_C(0x8000000000000000)); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~UINT64_C(0x8000000000000000); // zero out the sign bit
+ break;
+ case 3:
+ z = z | UINT64_C(0x8000000000000000); // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f64_roundToInt.c b/src/cpu/softfloat3e/f64_roundToInt.c
new file mode 100644
index 0000000000..3c5f7fb8c2
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_roundToInt(float64 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ int64_t frac;
+ bool sign;
+ uint64_t uiZ, lastBitMask, roundBitsMask;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ sign = signF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x433 <= (exp + scale)) {
+ if ((exp == 0x7FF) && frac) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF64UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0x3FE) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF64UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0x3FE) uiZ |= packToF64UI(0, 0x3FF - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF64UI(1, 0x3FF - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF64UI(0, 0x3FF - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint64_t) 1<<(0x433 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF64UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_scalef.c b/src/cpu/softfloat3e/f64_scalef.c
new file mode 100644
index 0000000000..7a552ccc3b
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_scalef.c
@@ -0,0 +1,156 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Return the result of a floating point scale of the double-precision floating
+| point value `a' by multiplying it by 2 power of the double-precision
+| floating point value 'b' converted to integral value. If the result cannot
+| be represented in double precision, then the proper overflow response (for
+| positive scaling operand), or the proper underflow response (for negative
+| scaling operand) is issued. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_scalef(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ int shiftCount;
+ int scale = 0;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0x7FF) {
+ if (sigB) return softfloat_propagateNaNF64UI(a, b, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) {
+ int aIsSignalingNaN = (sigA & UINT64_C(0x0008000000000000)) == 0;
+ if (aIsSignalingNaN || expB != 0x7FF || sigB)
+ return softfloat_propagateNaNF64UI(a, b, status);
+
+ return signB ? 0 : packToF64UI(0, 0x7FF, 0);
+ }
+
+ if (expB == 0x7FF && signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (expB == 0x7FF && ! signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ return packToF64UI(signA, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((expB | sigB) == 0) return a;
+
+ if (expB == 0x7FF) {
+ if (signB) return packToF64UI(signA, 0, 0);
+ return packToF64UI(signA, 0x7FF, 0);
+ }
+
+ if (0x40F <= expB) {
+ // handle obvious overflow/underflow result
+ return softfloat_roundPackToF64(signA, signB ? -0x3FF : 0x7FF, sigA, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB < 0x3FF) {
+ if (expB == 0)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ scale = -signB;
+ }
+ else {
+ sigB |= UINT64_C(0x0010000000000000);
+ shiftCount = 0x433 - expB;
+ uint64_t prev_sigB = sigB;
+ sigB >>= shiftCount;
+ scale = (int32_t) sigB;
+ if (signB) {
+ if ((sigB< 0x1000) scale = 0x1000;
+ if (scale < -0x1000) scale = -0x1000;
+ }
+
+ if (expA != 0) {
+ sigA |= UINT64_C(0x0010000000000000);
+ } else {
+ expA++;
+ }
+
+ expA += scale - 1;
+ sigA <<= 10;
+ return softfloat_normRoundPackToF64(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f64_sqrt.c b/src/cpu/softfloat3e/f64_sqrt.c
new file mode 100644
index 0000000000..d3ea81af86
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_sqrt.c
@@ -0,0 +1,130 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_sqrt(float64 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ uint32_t sig32A, recipSqrt32, sig32Z;
+ uint64_t rem;
+ uint32_t q;
+ uint64_t sigZ, shiftedSigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF64UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ | (`sig32Z' is guaranteed to be a lower bound on the square root of
+ | `sig32A', which makes `sig32Z' also a lower bound on the square root of
+ | `sigA'.)
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x3FF)>>1) + 0x3FE;
+ expA &= 1;
+ sigA |= UINT64_C(0x0010000000000000);
+ sig32A = sigA>>21;
+ recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A);
+ sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
+ if (expA) {
+ sigA <<= 8;
+ sig32Z >>= 1;
+ } else {
+ sigA <<= 9;
+ }
+ rem = sigA - (uint64_t) sig32Z * sig32Z;
+ q = ((uint32_t) (rem>>2) * (uint64_t) recipSqrt32)>>32;
+ sigZ = ((uint64_t) sig32Z<<32 | 1<<5) + ((uint64_t) q<<3);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((sigZ & 0x1FF) < 0x22) {
+ sigZ &= ~(uint64_t) 0x3F;
+ shiftedSigZ = sigZ>>6;
+ rem = (sigA<<52) - shiftedSigZ * shiftedSigZ;
+ if (rem & UINT64_C(0x8000000000000000)) {
+ --sigZ;
+ } else {
+ if (rem) sigZ |= 1;
+ }
+ }
+ return softfloat_roundPackToF64(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+}
diff --git a/src/cpu/softfloat3e/f64_to_extF80.cc b/src/cpu/softfloat3e/f64_to_extF80.cc
new file mode 100644
index 0000000000..88b27f9d3c
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f64_to_extF80(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp16_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3C00);
+ uiZ0 = (frac | UINT64_C(0x0010000000000000))<<11;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f64_to_f128.cc b/src/cpu/softfloat3e/f64_to_f128.cc
new file mode 100644
index 0000000000..cfae728249
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f128.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f64_to_f128(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ struct exp16_sig64 normExpSig;
+ struct uint128 frac128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ uiZ.v64 = packToF128UI64(sign, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac128 = softfloat_shortShiftLeft128(0, frac, 60);
+ uiZ.v64 = packToF128UI64(sign, exp + 0x3C00, frac128.v64);
+ uiZ.v0 = frac128.v0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_to_f16.c b/src/cpu/softfloat3e/f64_to_f16.c
new file mode 100644
index 0000000000..fe8dea057a
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f16.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f64_to_f16(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, frac16;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF16UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac16 = softfloat_shortShiftRightJam64(frac, 38);
+ if (! (exp | frac16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF16(sign, exp - 0x3F1, frac16 | 0x4000, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_f32.c b/src/cpu/softfloat3e/f64_to_f32.c
new file mode 100644
index 0000000000..7ebbf428f3
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f32.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f64_to_f32(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, frac32;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF32UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac32 = softfloat_shortShiftRightJam64(frac, 22);
+ if (! (exp | frac32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF32(sign, exp - 0x381, frac32 | 0x40000000, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_i32.c b/src/cpu/softfloat3e/f64_to_i32.c
new file mode 100644
index 0000000000..c296e0bd5e
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i32.c
@@ -0,0 +1,77 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f64_to_i32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FF) && sig) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x427 - exp;
+ if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToI32(sign, sig, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f64_to_i32_r_minMag.c b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c
new file mode 100644
index 0000000000..80e2d6bc3e
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f64_to_i32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (shiftDist < 22) {
+ if (sign && (exp == 0x41E) && (sig < UINT64_C(0x0000000000200000))) {
+ if (exact && sig) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f64_to_i64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ sigExtra.v = sig<<-shiftDist;
+ sigExtra.extra = 0;
+ } else {
+ sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ }
+ return softfloat_roundToI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && fracF64UI(a)
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+}
+
diff --git a/src/cpu/softfloat3e/f64_to_i64_r_minMag.c b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c
new file mode 100644
index 0000000000..eb633eb227
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c
@@ -0,0 +1,95 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f64_to_i64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ uint64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -10) {
+ if (a == packToF64UI(1, 0x43E, 0)) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig<<-shiftDist;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig>>shiftDist;
+ if (exact && (absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f64_to_ui32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FF) && sig) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x427 - exp;
+ if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToUI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c
new file mode 100644
index 0000000000..7610d7c371
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c
@@ -0,0 +1,83 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f64_to_ui32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (sign || (shiftDist < 21)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ z = sig>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f64_to_ui64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ sigExtra.v = sig<<-shiftDist;
+ sigExtra.extra = 0;
+ } else {
+ sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ }
+ return softfloat_roundToUI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && fracF64UI(a)
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+}
diff --git a/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c
new file mode 100644
index 0000000000..e7bda4c67e
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f64_to_ui64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (sign) goto invalid;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ z = (sig | UINT64_C(0x0010000000000000))<<-shiftDist;
+ } else {
+ sig |= UINT64_C(0x0010000000000000);
+ z = sig>>shiftDist;
+ if (exact && (uint64_t) (sig<<(-shiftDist & 63))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ }
+ return z;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FF) && sig ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+}
diff --git a/src/cpu/softfloat/fpatan.cc b/src/cpu/softfloat3e/fpatan.cc
similarity index 59%
rename from src/cpu/softfloat/fpatan.cc
rename to src/cpu/softfloat3e/fpatan.cc
index f33a3ff667..207dc320a7 100644
--- a/src/cpu/softfloat/fpatan.cc
+++ b/src/cpu/softfloat3e/fpatan.cc
@@ -25,27 +25,31 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
#include "fpu_constant.h"
+#include "poly.h"
#define FPATAN_ARR_SIZE 11
-static const float128 float128_one =
+static const float128_t float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_sqrt3 =
+static const float128_t float128_sqrt3 =
packFloat128(BX_CONST64(0x3fffbb67ae8584ca), BX_CONST64(0xa73b25742d7078b8));
static const floatx80 floatx80_pi =
packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
-static const float128 float128_pi2 =
+static const float128_t float128_pi2 =
packFloat128(BX_CONST64(0x3fff921fb54442d1), BX_CONST64(0x8469898CC5170416));
-static const float128 float128_pi4 =
+static const float128_t float128_pi4 =
packFloat128(BX_CONST64(0x3ffe921fb54442d1), BX_CONST64(0x8469898CC5170416));
-static const float128 float128_pi6 =
+static const float128_t float128_pi6 =
packFloat128(BX_CONST64(0x3ffe0c152382d736), BX_CONST64(0x58465BB32E0F580F));
-static float128 atan_arr[FPATAN_ARR_SIZE] =
+static float128_t atan_arr[FPATAN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */
@@ -60,10 +64,10 @@ static float128 atan_arr[FPATAN_ARR_SIZE] =
PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */
};
-extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
+extern float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
/* |x| < 1/4 */
-static float128 poly_atan(float128 x1, struct float_status_t *status)
+static float128_t poly_atan(float128_t x1, softfloat_status_t &status)
{
/*
// 3 5 7 9 11 13 15 17
@@ -86,12 +90,11 @@ static float128 poly_atan(float128 x1, struct float_status_t *status)
// atan(x) ~ x * [ p(x) + x * q(x) ]
//
*/
- return OddPoly(x1, atan_arr, FPATAN_ARR_SIZE, status);
+ return OddPoly(x1, (const float128_t*) atan_arr, FPATAN_ARR_SIZE, status);
}
// =================================================
-// FPATAN Compute y * log (x)
-// 2
+// FPATAN Compute arctan(y/x)
// =================================================
//
@@ -134,125 +137,129 @@ static float128 poly_atan(float128 x1, struct float_status_t *status)
// 3 5 7 9 2n+1
//
-floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
+ uint64_t bSig = extF80_fraction(b);
+ int32_t bExp = extF80_exp(b);
+ int bSign = extF80_sign(b);
int zSign = aSign ^ bSign;
if (bExp == 0x7FFF)
{
- if ((Bit64u) (bSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (bSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaN(a, b, status);
-
- if (aSign) { /* return 3PI/4 */
- return roundAndPackFloatx80(80, bSign,
- FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status);
- }
- else { /* return PI/4 */
- return roundAndPackFloatx80(80, bSign,
- FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
- }
+ if (aSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
+
+ if (aSign) /* return 3PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status);
+ else /* return PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
}
- if (aSig && (aExp == 0))
- float_raise(status, float_flag_denormal);
+ if (aSig && ! aExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* return PI/2 */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
}
if (aExp == 0x7FFF)
{
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (aSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
- if (bSig && (bExp == 0))
- float_raise(status, float_flag_denormal);
+ if (bSig && ! bExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
return_PI_or_ZERO:
- if (aSign) { /* return PI */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
- } else { /* return 0 */
- return packFloatx80(bSign, 0, 0);
- }
+ if (aSign) /* return PI */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
+ else /* return 0 */
+ return packToExtF80(bSign, 0, 0);
}
- if (bExp == 0)
+ if (! bExp)
{
- if (bSig == 0) {
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
+ if (! bSig) {
+ if (aSig && ! aExp) softfloat_raiseFlags(&status, softfloat_flag_denormal);
goto return_PI_or_ZERO;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0)
+ if (! aExp)
{
- if (aSig == 0) /* return PI/2 */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ if (! aSig) /* return PI/2 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
/* |a| = |b| ==> return PI/4 */
- if (aSig == bSig && aExp == bExp)
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ if (aSig == bSig && aExp == bExp) {
+ if (aSign)
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status);
+ else
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
+ }
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
- float128 a128 = normalizeRoundAndPackFloat128(0, aExp-0x10, aSig, 0, status);
- float128 b128 = normalizeRoundAndPackFloat128(0, bExp-0x10, bSig, 0, status);
- float128 x;
+ float128_t a128 = softfloat_normRoundPackToF128(0, aExp-0x10, aSig, 0, &status);
+ float128_t b128 = softfloat_normRoundPackToF128(0, bExp-0x10, bSig, 0, &status);
+ float128_t x;
int swap = 0, add_pi6 = 0, add_pi4 = 0;
if (aExp > bExp || (aExp == bExp && aSig > bSig))
{
- x = float128_div(b128, a128, status);
+ x = f128_div(b128, a128, &status);
}
else {
- x = float128_div(a128, b128, status);
+ x = f128_div(a128, b128, &status);
swap = 1;
}
- Bit32s xExp = extractFloat128Exp(x);
+ int32_t xExp = expF128UI64(x.v64);
if (xExp <= FLOATX80_EXP_BIAS-40)
goto approximation_completed;
- if (x.hi >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1
+ if (x.v64 >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1
{
/*
arctan(x) = arctan((x-1)/(x+1)) + pi/4
*/
- float128 t1 = float128_sub(x, float128_one, status);
- float128 t2 = float128_add(x, float128_one, status);
- x = float128_div(t1, t2, status);
+ float128_t t1 = f128_sub(x, float128_one, &status);
+ float128_t t2 = f128_add(x, float128_one, &status);
+ x = f128_div(t1, t2, &status);
add_pi4 = 1;
}
else
@@ -263,26 +270,26 @@ floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status)
/*
arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6
*/
- float128 t1 = float128_mul(x, float128_sqrt3, status);
- float128 t2 = float128_add(x, float128_sqrt3, status);
- x = float128_sub(t1, float128_one, status);
- x = float128_div(x, t2, status);
+ float128_t t1 = f128_mul(x, float128_sqrt3, &status);
+ float128_t t2 = f128_add(x, float128_sqrt3, &status);
+ x = f128_sub(t1, float128_one, &status);
+ x = f128_div(x, t2, &status);
add_pi6 = 1;
}
}
x = poly_atan(x, status);
- if (add_pi6) x = float128_add(x, float128_pi6, status);
- if (add_pi4) x = float128_add(x, float128_pi4, status);
+ if (add_pi6) x = f128_add(x, float128_pi6, &status);
+ if (add_pi4) x = f128_add(x, float128_pi4, &status);
approximation_completed:
- if (swap) x = float128_sub(float128_pi2, x, status);
- floatx80 result = float128_to_floatx80(x, status);
+ if (swap) x = f128_sub(float128_pi2, x, &status);
+ floatx80 result = f128_to_extF80(x, &status);
if (zSign) floatx80_chs(result);
- int rSign = extractFloatx80Sign(result);
+ int rSign = extF80_sign(result);
if (!bSign && rSign)
- return floatx80_add(result, floatx80_pi, status);
+ return extF80_add(result, floatx80_pi, &status);
if (bSign && !rSign)
- return floatx80_sub(result, floatx80_pi, status);
+ return extF80_sub(result, floatx80_pi, &status);
return result;
}
diff --git a/src/cpu/softfloat/fprem.cc b/src/cpu/softfloat3e/fprem.cc
similarity index 53%
rename from src/cpu/softfloat/fprem.cc
rename to src/cpu/softfloat3e/fprem.cc
index 26637c5c57..2252f12307 100644
--- a/src/cpu/softfloat/fprem.cc
+++ b/src/cpu/softfloat3e/fprem.cc
@@ -23,100 +23,109 @@ these four paragraphs for those parts of this code that are retained.
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "fpu_trans.h"
#define USE_estimateDiv128To64
-#include "softfloat-macros.h"
+#include "softfloat-helpers.h"
+
+#include "specialize.h" // for softfloat_propagateNaNExtF80UI
/* executes single exponent reduction cycle */
-static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1)
+static uint64_t remainder_kernel(uint64_t aSig0, uint64_t bSig, int expDiff, uint64_t *zSig0, uint64_t *zSig1)
{
- Bit64u term0, term1;
- Bit64u aSig1 = 0;
-
+ uint128 term, z;
+ uint64_t aSig1 = 0;
shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
- Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig);
- mul64To128(bSig, q, &term0, &term1);
- sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
- while ((Bit64s)(*zSig1) < 0) {
+ uint64_t q = estimateDiv128To64(aSig1, aSig0, bSig);
+ term = softfloat_mul64To128(bSig, q);
+ z = softfloat_sub128(aSig1, aSig0, term.v64, term.v0);
+ while ((int64_t) z.v64 < 0) {
--q;
- add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0);
+ z = softfloat_add128(z.v64, z.v0, 0, bSig);
}
+ *zSig0 = z.v0;
+ *zSig1 = z.v64;
return q;
}
-static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding_mode, struct float_status_t *status)
+static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, int rounding_mode, struct softfloat_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ static const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit32s aExp, bExp, zExp, expDiff;
- Bit64u aSig0, aSig1, bSig;
+ int32_t aExp, bExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0, bSig;
int aSign;
+ struct exp32_sig64 normExpSig;
+ uint128 term;
+
*q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+ bSig = extF80_fraction(b);
+ bExp = extF80_exp(b);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
- *r = propagateFloatx80NaN(a, b, status);
+ if ((aSig0<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status);
return -1;
}
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) {
- *r = propagateFloatx80NaN(a, b, status);
+ if (bSig << 1) {
+ *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status);
return -1;
}
- if (aExp == 0 && aSig0) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
- *r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
- packFloatx80(aSign, aExp, aSig0) : a;
+ if (! aExp && aSig0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
return 0;
}
*r = a;
return 0;
}
- if (bExp == 0) {
- if (bSig == 0) {
- float_raise(status, float_flag_invalid);
+ if (! bExp) {
+ if (! bSig) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0) {
- if (aSig0 == 0) {
+ if (! aExp) {
+ if (! aSig0) {
*r = a;
return 0;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
- expDiff = aExp - bExp;
- aSig1 = 0;
- Bit32u overflow = 0;
+ expDiff = aExp - bExp;
+ int overflow = 0;
if (expDiff >= 64) {
int n = (expDiff & 0x1f) | 0x20;
@@ -129,11 +138,10 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
if (expDiff < 0) {
if (expDiff < -1) {
- *r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
- packFloatx80(aSign, aExp, aSig0) : a;
+ *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
return 0;
}
- shift128Right(aSig0, 0, 1, &aSig0, &aSig1);
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
expDiff = 0;
}
@@ -147,26 +155,28 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
}
}
- if (rounding_mode == float_round_nearest_even)
- {
- Bit64u term0, term1;
- shift128Right(bSig, 0, 1, &term0, &term1);
-
- if (! lt128(aSig0, aSig1, term0, term1))
- {
- int lt = lt128(term0, term1, aSig0, aSig1);
- int eq = eq128(aSig0, aSig1, term0, term1);
-
- if ((eq && ((*q) & 1)) || lt) {
- aSign = !aSign;
- ++(*q);
- }
- if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1);
+ if (rounding_mode == softfloat_round_near_even) {
+ uint64_t term0, term1;
+ shortShift128Right(bSig, 0, 1, &term0, &term1);
+
+ if (! softfloat_lt128(aSig0, aSig1, term0, term1)) {
+ int lt = softfloat_lt128(term0, term1, aSig0, aSig1);
+ int eq = softfloat_eq128(aSig0, aSig1, term0, term1);
+
+ if ((eq && ((*q) & 1)) || lt) {
+ aSign = !aSign;
+ ++(*q);
+ }
+ if (lt) {
+ term = softfloat_sub128(bSig, 0, aSig0, aSig1);
+ aSig0 = term.v64;
+ aSig1 = term.v0;
+ }
}
}
}
- *r = normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1, status);
+ *r = softfloat_normRoundPackToExtF80(aSign, zExp, aSig0, aSig1, 80, status);
return overflow;
}
@@ -176,9 +186,9 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
-int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
+int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status)
{
- return do_fprem(a, b, r, q, float_round_nearest_even, status);
+ return do_fprem(a, b, r, q, softfloat_round_near_even, status);
}
/*----------------------------------------------------------------------------
@@ -190,7 +200,7 @@ int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, s
| quotient of 'a' divided by 'b' to an integer.
*----------------------------------------------------------------------------*/
-int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
+int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status)
{
- return do_fprem(a, b, r, q, float_round_to_zero, status);
+ return do_fprem(a, b, r, q, softfloat_round_to_zero, status);
}
diff --git a/src/cpu/softfloat/fpu_constant.h b/src/cpu/softfloat3e/fpu_constant.h
similarity index 98%
rename from src/cpu/softfloat/fpu_constant.h
rename to src/cpu/softfloat3e/fpu_constant.h
index 7a7fc6f1aa..d7d44ee3c1 100644
--- a/src/cpu/softfloat/fpu_constant.h
+++ b/src/cpu/softfloat3e/fpu_constant.h
@@ -24,7 +24,7 @@ these four paragraphs for those parts of this code that are retained.
#include "config.h"
// Pentium CPU uses only 68-bit precision M_PI approximation
-//#define BETTER_THAN_PENTIUM
+// #define BETTER_THAN_PENTIUM
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
diff --git a/src/cpu/softfloat3e/fpu_trans.h b/src/cpu/softfloat3e/fpu_trans.h
new file mode 100644
index 0000000000..bd3d3cecba
--- /dev/null
+++ b/src/cpu/softfloat3e/fpu_trans.h
@@ -0,0 +1,117 @@
+/////////////////////////////////////////////////////////////////////////
+// $Id$
+/////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2003-2018 Stanislav Shwartsman
+// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _FPU_TRANS_H_
+#define _FPU_TRANS_H_
+
+#include "softfloat.h"
+#include "softfloat-specialize.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision operations.
+*----------------------------------------------------------------------------*/
+
+int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status);
+int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status);
+
+floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status);
+#ifdef __cplusplus
+floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status);
+floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status);
+floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status);
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision trigonometric functions.
+*----------------------------------------------------------------------------*/
+
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status);
+int fsin(floatx80 &a, softfloat_status_t &status);
+int fcos(floatx80 &a, softfloat_status_t &status);
+int ftan(floatx80 &a, softfloat_status_t &status);
+#else
+floatx80 fyl2x(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+floatx80 fyl2xp1(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+floatx80 fpatan(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision trigonometric functions.
+*----------------------------------------------------------------------------*/
+
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct softfloat_status_t *status);
+int fsin(floatx80 *a, struct softfloat_status_t *status);
+int fcos(floatx80 *a, struct softfloat_status_t *status);
+int ftan(floatx80 *a, struct softfloat_status_t *status);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*-----------------------------------------------------------------------------
+| Calculates the absolute value of the extended double-precision floating-point
+| value `a'. The operation is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+static __inline floatx80 &floatx80_abs(floatx80 ®)
+#else
+static __inline floatx80 floatx80_abs(floatx80 reg)
+#endif
+{
+ reg.signExp &= 0x7FFF;
+ return reg;
+}
+
+/*-----------------------------------------------------------------------------
+| Changes the sign of the extended double-precision floating-point value 'a'.
+| The operation is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+static __inline floatx80 &floatx80_chs(floatx80 ®)
+#else
+static __inline floatx80 floatx80_chs(floatx80 reg)
+#endif
+{
+ reg.signExp ^= 0x8000;
+ return reg;
+}
+
+#ifdef __cplusplus
+static __inline floatx80 FPU_round_const(const floatx80 &a, int adj)
+#else
+static __inline floatx80 FPU_round_const(const floatx80 a, int adj)
+#endif
+{
+ floatx80 result = a;
+ result.signif += adj;
+ return result;
+}
+
+#endif
diff --git a/src/cpu/softfloat/fsincos.cc b/src/cpu/softfloat3e/fsincos.cc
similarity index 68%
rename from src/cpu/softfloat/fsincos.cc
rename to src/cpu/softfloat3e/fsincos.cc
index f5b33a8230..1a2a018de8 100644
--- a/src/cpu/softfloat/fsincos.cc
+++ b/src/cpu/softfloat3e/fsincos.cc
@@ -26,24 +26,29 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
#define USE_estimateDiv128To64
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
+#include "softfloat-helpers.h"
#include "fpu_constant.h"
+#include "poly.h"
+
static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
/* reduce trigonometric function argument using 128-bit precision
M_PI approximation */
-static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1)
+static uint64_t argument_reduction_kernel(uint64_t aSig0, int Exp, uint64_t *zSig0, uint64_t *zSig1)
{
- Bit64u term0, term1, term2;
- Bit64u aSig1 = 0;
+ uint64_t term0, term1, term2;
+ uint64_t aSig1 = 0;
shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
- Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
+ uint64_t q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
- while ((Bit64s)(*zSig1) < 0) {
+ while ((int64_t)(*zSig1) < 0) {
--q;
add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
}
@@ -51,35 +56,35 @@ static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bi
return q;
}
-static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1)
+static int reduce_trig_arg(int expDiff, int &zSign, uint64_t &aSig0, uint64_t &aSig1)
{
- Bit64u term0, term1, q = 0;
+ uint64_t term0, term1, q = 0;
if (expDiff < 0) {
- shift128Right(*aSig0, 0, 1, aSig0, aSig1);
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
expDiff = 0;
}
if (expDiff > 0) {
- q = argument_reduction_kernel(*aSig0, expDiff, aSig0, aSig1);
+ q = argument_reduction_kernel(aSig0, expDiff, &aSig0, &aSig1);
}
else {
- if (FLOAT_PI_HI <= *aSig0) {
- *aSig0 -= FLOAT_PI_HI;
+ if (FLOAT_PI_HI <= aSig0) {
+ aSig0 -= FLOAT_PI_HI;
q = 1;
}
}
- shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
- if (! lt128(*aSig0, *aSig1, term0, term1))
+ shortShift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
+ if (! softfloat_lt128(aSig0, aSig1, term0, term1))
{
- int lt = lt128(term0, term1, *aSig0, *aSig1);
- int eq = eq128(*aSig0, *aSig1, term0, term1);
+ int lt = softfloat_lt128(term0, term1, aSig0, aSig1);
+ int eq = softfloat_eq128(aSig0, aSig1, term0, term1);
if ((eq && (q & 1)) || lt) {
- *zSign = !(*zSign);
+ zSign = !zSign;
++q;
}
- if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, *aSig0, *aSig1, aSig0, aSig1);
+ if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, aSig0, aSig1, &aSig0, &aSig1);
}
return (int)(q & 3);
@@ -88,7 +93,7 @@ static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1
#define SIN_ARR_SIZE 11
#define COS_ARR_SIZE 11
-static float128 sin_arr[SIN_ARR_SIZE] =
+static float128_t sin_arr[SIN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */
@@ -103,7 +108,7 @@ static float128 sin_arr[SIN_ARR_SIZE] =
PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */
};
-static float128 cos_arr[COS_ARR_SIZE] =
+static float128_t cos_arr[COS_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */
PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */
@@ -118,10 +123,8 @@ static float128 cos_arr[COS_ARR_SIZE] =
PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */
};
-extern float128 OddPoly (float128 x, float128 *arr, int n, struct float_status_t *status);
-
/* 0 <= x <= pi/4 */
-BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status)
+static __inline float128_t poly_sin(float128_t x, softfloat_status_t &status)
{
// 3 5 7 9 11 13 15
// x x x x x x x
@@ -143,13 +146,11 @@ BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status)
// sin(x) ~ x * [ p(x) + x * q(x) ]
//
- return OddPoly(x, sin_arr, SIN_ARR_SIZE, status);
+ return OddPoly(x, (const float128_t*) sin_arr, SIN_ARR_SIZE, status);
}
-extern float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
-
/* 0 <= x <= pi/4 */
-BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status)
+static __inline float128_t poly_cos(float128_t x, softfloat_status_t &status)
{
// 2 4 6 8 10 12 14
// x x x x x x x
@@ -166,22 +167,22 @@ BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status)
// cos(x) ~ [ p(x) + x * q(x) ]
//
- return EvenPoly(x, cos_arr, COS_ARR_SIZE, status);
+ return EvenPoly(x, (const float128_t*) cos_arr, COS_ARR_SIZE, status);
}
-BX_CPP_INLINE void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+static __inline void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = a;
}
-BX_CPP_INLINE void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+static __inline void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = floatx80_one;
}
-static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struct float_status_t *status)
+static floatx80 sincos_approximation(int neg, float128_t r, uint64_t quotient, softfloat_status_t &status)
{
if (quotient & 0x1) {
r = poly_cos(r, status);
@@ -190,7 +191,7 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc
r = poly_sin(r, status);
}
- floatx80 result = float128_to_floatx80(r, status);
+ floatx80 result = f128_to_extF80(r, &status);
if (quotient & 0x2)
neg = ! neg;
@@ -220,59 +221,62 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc
// sin(x+2pi) = sin(x)
//
-int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status)
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u aSig0, aSig1 = 0;
- Bit32s aExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a)) {
+ if (extF80_isUnsupported(a)) {
goto invalid;
}
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
/* invalid argument */
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1)) {
- sincos_invalid(sin_a, cos_a, propagateFloatx80NaNOne(a, status));
+ if (aSig0 << 1) {
+ sincos_invalid(sin_a, cos_a, softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status));
return 0;
}
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
sincos_invalid(sin_a, cos_a, floatx80_default_nan);
return 0;
}
- if (aExp == 0) {
- if (aSig0 == 0) {
+ if (! aExp) {
+ if (! aSig0) {
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
- float_raise(status, float_flag_denormal);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (sin_a)
- float_raise(status, float_flag_underflow);
+ softfloat_raiseFlags(&status, softfloat_flag_underflow);
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
zSign = aSign;
@@ -283,7 +287,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
if (expDiff >= 63)
return -1;
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
@@ -294,7 +298,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
zExp = aExp;
}
else {
- q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
}
/* **************************** */
@@ -302,7 +306,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
/* **************************** */
/* using float128 for approximation */
- float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status);
if (aSign) q = -q;
if (sin_a) *sin_a = sincos_approximation(zSign, r, q, status);
@@ -311,14 +315,14 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
return 0;
}
-int fsin(floatx80 *a, struct float_status_t *status)
+int fsin(floatx80 &a, softfloat_status_t &status)
{
- return fsincos(*a, a, 0, status);
+ return fsincos(a, &a, 0, status);
}
-int fcos(floatx80 *a, struct float_status_t *status)
+int fcos(floatx80 &a, softfloat_status_t &status)
{
- return fsincos(*a, 0, a, status);
+ return fsincos(a, 0, &a, status);
}
// =================================================
@@ -348,51 +352,55 @@ int fcos(floatx80 *a, struct float_status_t *status)
// cos(x)
//
-int ftan(floatx80 *a, struct float_status_t *status)
+int ftan(floatx80 &a, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u aSig0, aSig1 = 0;
- Bit32s aExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(*a)) {
+ if (extF80_isUnsupported(a)) {
goto invalid;
}
- aSig0 = extractFloatx80Frac(*a);
- aExp = extractFloatx80Exp(*a);
- aSign = extractFloatx80Sign(*a);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
/* invalid argument */
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1))
+ if (aSig0 << 1)
{
- *a = propagateFloatx80NaNOne(*a, status);
+ a = softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status);
return 0;
}
invalid:
- float_raise(status, float_flag_invalid);
- *a = floatx80_default_nan;
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
+ a = floatx80_default_nan;
return 0;
}
- if (aExp == 0) {
- if (aSig0 == 0) return 0;
- float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig0) return 0;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
- float_raise(status, float_flag_inexact | float_flag_underflow);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact | softfloat_flag_underflow);
return 0;
}
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
zSign = aSign;
@@ -403,17 +411,17 @@ int ftan(floatx80 *a, struct float_status_t *status)
if (expDiff >= 63)
return -1;
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
- *a = packFloatx80(aSign, aExp, aSig0);
+ a = packFloatx80(aSign, aExp, aSig0);
return 0;
}
zExp = aExp;
}
else {
- q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
}
/* **************************** */
@@ -421,21 +429,21 @@ int ftan(floatx80 *a, struct float_status_t *status)
/* **************************** */
/* using float128 for approximation */
- float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status);
- float128 sin_r = poly_sin(r, status);
- float128 cos_r = poly_cos(r, status);
+ float128_t sin_r = poly_sin(r, status);
+ float128_t cos_r = poly_cos(r, status);
if (q & 0x1) {
- r = float128_div(cos_r, sin_r, status);
+ r = f128_div(cos_r, sin_r, &status);
zSign = ! zSign;
} else {
- r = float128_div(sin_r, cos_r, status);
+ r = f128_div(sin_r, cos_r, &status);
}
- *a = float128_to_floatx80(r, status);
+ a = f128_to_extF80(r, &status);
if (zSign)
- floatx80_chs(*a);
+ floatx80_chs(a);
return 0;
}
diff --git a/src/cpu/softfloat/fyl2x.cc b/src/cpu/softfloat3e/fyl2x.cc
similarity index 61%
rename from src/cpu/softfloat/fyl2x.cc
rename to src/cpu/softfloat3e/fyl2x.cc
index 875f866a91..7c90e6207f 100644
--- a/src/cpu/softfloat/fyl2x.cc
+++ b/src/cpu/softfloat3e/fyl2x.cc
@@ -24,29 +24,28 @@ these four paragraphs for those parts of this code that are retained.
* ==========================================================================*/
#define FLOAT128
-
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "fpu_trans.h"
+#include "specialize.h"
+#include "softfloat-helpers.h"
#include "fpu_constant.h"
+#include "poly.h"
-static const floatx80 floatx80_one =
- packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
+static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
-static const float128 float128_one =
+static const float128_t float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_two =
+static const float128_t float128_two =
packFloat128(BX_CONST64(0x4000000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_ln2inv2 =
+static const float128_t float128_ln2inv2 =
packFloat128(BX_CONST64(0x400071547652b82f), BX_CONST64(0xe1777d0ffda0d23a));
#define SQRT2_HALF_SIG BX_CONST64(0xb504f333f9de6484)
-extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
-
#define L2_ARR_SIZE 9
-static float128 ln_arr[L2_ARR_SIZE] =
+static float128_t ln_arr[L2_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */
@@ -59,7 +58,7 @@ static float128 ln_arr[L2_ARR_SIZE] =
PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */
};
-static float128 poly_ln(float128 x1, struct float_status_t *status)
+static float128_t poly_ln(float128_t x1, softfloat_status_t &status)
{
/*
//
@@ -84,28 +83,28 @@ static float128 poly_ln(float128 x1, struct float_status_t *status)
// 1-u
//
*/
- return OddPoly(x1, ln_arr, L2_ARR_SIZE, status);
+ return OddPoly(x1, (const float128_t*) ln_arr, L2_ARR_SIZE, status);
}
/* required sqrt(2)/2 < x < sqrt(2) */
-static float128 poly_l2(float128 x, struct float_status_t *status)
+static float128_t poly_l2(float128_t x, softfloat_status_t &status)
{
/* using float128 for approximation */
- float128 x_p1 = float128_add(x, float128_one, status);
- float128 x_m1 = float128_sub(x, float128_one, status);
- x = float128_div(x_m1, x_p1, status);
+ float128_t x_p1 = f128_add(x, float128_one, &status);
+ float128_t x_m1 = f128_sub(x, float128_one, &status);
+ x = f128_div(x_m1, x_p1, &status);
x = poly_ln(x, status);
- x = float128_mul(x, float128_ln2inv2, status);
+ x = f128_mul(x, float128_ln2inv2, &status);
return x;
}
-static float128 poly_l2p1(float128 x, struct float_status_t *status)
+static float128_t poly_l2p1(float128_t x, softfloat_status_t &status)
{
/* using float128 for approximation */
- float128 x_p2 = float128_add(x, float128_two, status);
- x = float128_div(x, x_p2, status);
+ float128_t x_plus2 = f128_add(x, float128_two, &status);
+ x = f128_div(x, x_plus2, &status);
x = poly_ln(x, status);
- x = float128_mul(x, float128_ln2inv2, status);
+ x = f128_mul(x, float128_ln2inv2, &status);
return x;
}
@@ -134,7 +133,7 @@ static float128 poly_l2p1(float128 x, struct float_status_t *status)
// 1-u 3 5 7 2n+1
//
-floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
@@ -142,71 +141,73 @@ floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
+ uint64_t bSig = extF80_fraction(b);
+ int32_t bExp = extF80_exp(b);
+ int bSign = extF80_sign(b);
int zSign = bSign ^ 1;
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
+ if ((aSig<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
}
if (aSign) goto invalid;
else {
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
- if (bExp == 0x7FFF)
- {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSign && (Bit64u)(aExp | aSig)) goto invalid;
- if (aSig && (aExp == 0))
- float_raise(status, float_flag_denormal);
+ if (bExp == 0x7FFF) {
+ if (bSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
+ if (aSign && (uint64_t)(aExp | aSig)) goto invalid;
+ if (aSig && ! aExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
if (aExp < 0x3FFF) {
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid;
+ if (aExp == 0x3FFF && ! (aSig<<1)) goto invalid;
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0) {
- if (aSig == 0) {
+ if (! aExp) {
+ if (! aSig) {
if ((bExp | bSig) == 0) goto invalid;
- float_raise(status, float_flag_divbyzero);
+ softfloat_raiseFlags(&status, softfloat_flag_divbyzero);
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aSign) goto invalid;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
if (aSign) goto invalid;
- if (bExp == 0) {
- if (bSig == 0) {
+ if (! bExp) {
+ if (! bSig) {
if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0);
return packFloatx80(bSign, 0, 0);
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0))
+ if (aExp == 0x3FFF && ! (aSig<<1))
return packFloatx80(bSign, 0, 0);
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
int ExpDiff = aExp - 0x3FFF;
aExp = 0;
@@ -219,12 +220,15 @@ floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
/* using float128 for approximation */
/* ******************************** */
- Bit64u zSig0, zSig1;
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- float128 x = packFloat128Four(0, aExp+0x3FFF, zSig0, zSig1);
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status);
+
+ uint64_t zSig0, zSig1;
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1);
x = poly_l2(x, status);
- x = float128_add(x, int64_to_float128((Bit64s) ExpDiff), status);
- return floatx80_128_mul(b, x, status);
+ x = f128_add(x, i32_to_f128(ExpDiff), &status);
+ x = f128_mul(x, b128, &status);
+ return f128_to_extF80(x, &status);
}
// =================================================
@@ -252,112 +256,117 @@ floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
// 1-u 3 5 7 2n+1
//
-floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status)
{
+ int32_t aExp, bExp;
+ uint64_t aSig, bSig, zSig0, zSig1, zSig2;
+ int aSign, bSign;
+
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit32s aExp, bExp;
- Bit64u aSig, bSig, zSig0, zSig1, zSig2;
- int aSign, bSign;
-
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
+
+ aSig = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+ bSig = extF80_fraction(b);
+ bExp = extF80_exp(b);
+ bSign = extF80_sign(b);
int zSign = aSign ^ bSign;
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
+ if ((aSig<<1) != 0 || ((bExp == 0x7FFF) && (bSig<<1) != 0)) {
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
}
if (aSign) goto invalid;
else {
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
if (bExp == 0x7FFF)
{
- if ((Bit64u) (bSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (bSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig) {
+ if (bSig && ! bExp) softfloat_raiseFlags(&status, softfloat_flag_denormal);
return packFloatx80(zSign, 0, 0);
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
- if (bExp == 0) {
- if (bSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ if (! bExp) {
+ if (! bSig) return packFloatx80(zSign, 0, 0);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (aSign && aExp >= 0x3FFF)
return a;
if (aExp >= 0x3FFC) // big argument
{
- return fyl2x(floatx80_add(a, floatx80_one, status), b, status);
+ return fyl2x(extF80_add(a, floatx80_one, &status), b, status);
}
// handle tiny argument
if (aExp < FLOATX80_EXP_BIAS-70)
{
// first order approximation, return (a*b)/ln(2)
- Bit32s zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
+ int32_t zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
- mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
zExp = zExp + bExp - 0x3FFE;
- mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
- return
- roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1, status);
+ return softfloat_roundPackToExtF80(aSign ^ bSign, zExp, zSig0, zSig1, 80, &status);
}
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- float128 x = packFloat128Four(aSign, aExp, zSig0, zSig1);
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status);
+
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(aSign, aExp, zSig0, zSig1);
x = poly_l2p1(x, status);
- return floatx80_128_mul(b, x, status);
+ x = f128_mul(x, b128, &status);
+ return f128_to_extF80(x, &status);
}
diff --git a/src/cpu/softfloat3e/i32_to_extF80.cc b/src/cpu/softfloat3e/i32_to_extF80.cc
new file mode 100644
index 0000000000..edd92ced0e
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_extF80.cc
@@ -0,0 +1,62 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+extFloat80_t i32_to_extF80(int32_t a)
+{
+ uint16_t uiZ64;
+ uint32_t absA;
+ bool sign;
+ int8_t shiftDist;
+ extFloat80_t z;
+
+ uiZ64 = 0;
+ absA = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA);
+ uiZ64 = packToExtF80UI64(sign, 0x401E - shiftDist);
+ absA <<= shiftDist;
+ }
+ z.signExp = uiZ64;
+ z.signif = (uint64_t) absA<<32;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i32_to_f128.cc b/src/cpu/softfloat3e/i32_to_f128.cc
new file mode 100644
index 0000000000..1ae64e46b7
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_f128.cc
@@ -0,0 +1,59 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float128_t i32_to_f128(int32_t a)
+{
+ uint64_t uiZ64;
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+ float128_t z;
+
+ uiZ64 = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) + 17;
+ uiZ64 = packToF128UI64(sign, 0x402E - shiftDist, (uint64_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float16 i32_to_f16(int32_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+ uint16_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) - 21;
+ if (0 <= shiftDist) {
+ return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA<>(-shiftDist) | ((uint32_t) (absA<<(shiftDist & 31)) != 0)
+ : (uint16_t) absA<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+float32 i32_to_f32(int32_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint32_t absA;
+
+ sign = (a < 0);
+ if (! (a & 0x7FFFFFFF)) {
+ return sign ? packToF32UI(1, 0x9E, 0) : 0;
+ }
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ return softfloat_normRoundPackToF32(sign, 0x9C, absA, status);
+}
diff --git a/src/cpu/softfloat3e/i32_to_f64.c b/src/cpu/softfloat3e/i32_to_f64.c
new file mode 100644
index 0000000000..7aaa4e1c28
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_f64.c
@@ -0,0 +1,56 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float64 i32_to_f64(int32_t a)
+{
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+
+ if (! a) {
+ return 0;
+ } else {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) + 21;
+ return packToF64UI(sign, 0x432 - shiftDist, (uint64_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+extFloat80_t i64_to_extF80(int64_t a)
+{
+ uint16_t uiZ64;
+ uint64_t absA;
+ bool sign;
+ int8_t shiftDist;
+ extFloat80_t z;
+
+ uiZ64 = 0;
+ absA = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA);
+ uiZ64 = packToExtF80UI64(sign, 0x403E - shiftDist);
+ absA <<= shiftDist;
+ }
+ z.signExp = uiZ64;
+ z.signif = absA;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i64_to_f128.cc b/src/cpu/softfloat3e/i64_to_f128.cc
new file mode 100644
index 0000000000..4d80a9e7ab
--- /dev/null
+++ b/src/cpu/softfloat3e/i64_to_f128.cc
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float128_t i64_to_f128(int64_t a)
+{
+ uint64_t uiZ64, uiZ0;
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ struct uint128 zSig;
+ float128_t z;
+
+ if (! a) {
+ uiZ64 = 0;
+ uiZ0 = 0;
+ } else {
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) + 49;
+ if (64 <= shiftDist) {
+ zSig.v64 = absA<<(shiftDist - 64);
+ zSig.v0 = 0;
+ } else {
+ zSig = softfloat_shortShiftLeft128(0, absA, shiftDist);
+ }
+ uiZ64 = packToF128UI64(sign, 0x406E - shiftDist, zSig.v64);
+ uiZ0 = zSig.v0;
+ }
+ z.v64 = uiZ64;
+ z.v0 = uiZ0;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i64_to_f16.c b/src/cpu/softfloat3e/i64_to_f16.c
new file mode 100644
index 0000000000..43873610a4
--- /dev/null
+++ b/src/cpu/softfloat3e/i64_to_f16.c
@@ -0,0 +1,61 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float16 i64_to_f16(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ uint16_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) - 53;
+ if (0 <= shiftDist) {
+ return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float32 i64_to_f32(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ uint32_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) - 40;
+ if (0 <= shiftDist) {
+ return a ? packToF32UI(sign, 0x95 - shiftDist, (uint32_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float64 i64_to_f64(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+
+ sign = (a < 0);
+ if (! (a & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+ return sign ? packToF64UI(1, 0x43E, 0) : 0;
+ }
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ return softfloat_normRoundPackToF64(sign, 0x43C, absA, status);
+}
diff --git a/src/cpu/softfloat3e/internals.h b/src/cpu/softfloat3e/internals.h
new file mode 100644
index 0000000000..3b5d7aa4d5
--- /dev/null
+++ b/src/cpu/softfloat3e/internals.h
@@ -0,0 +1,150 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#ifndef _INTERNALS_H_
+#define _INTERNALS_H_
+
+#include
+#include
+//#include "primitives.h"
+#include "softfloat_types.h"
+
+struct softfloat_status_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+uint32_t softfloat_roundToUI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+uint64_t softfloat_roundToUI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+
+int32_t softfloat_roundToI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+int64_t softfloat_roundToI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+
+#define signF16UI(a) ((bool) ((uint16_t) (a)>>15))
+#define expF16UI(a) ((int8_t) ((a)>>10) & 0x1F)
+#define fracF16UI(a) ((a) & 0x03FF)
+#define packToF16UI(sign, exp, sig) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig))
+
+#define isNaNF16UI(a) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF))
+
+struct exp8_sig16 { int8_t exp; uint16_t sig; };
+struct exp8_sig16 softfloat_normSubnormalF16Sig(uint16_t);
+
+float16 softfloat_roundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *);
+float16 softfloat_normRoundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF32UI(a) ((bool) ((uint32_t) (a)>>31))
+#define expF32UI(a) ((int16_t) ((a)>>23) & 0xFF)
+#define fracF32UI(a) ((a) & 0x007FFFFF)
+#define packToF32UI(sign, exp, sig) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))
+
+#define isNaNF32UI(a) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF))
+
+struct exp16_sig32 { int16_t exp; uint32_t sig; };
+struct exp16_sig32 softfloat_normSubnormalF32Sig(uint32_t);
+
+float32 softfloat_roundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *);
+float32 softfloat_normRoundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF64UI(a) ((bool) ((uint64_t) (a)>>63))
+#define expF64UI(a) ((int16_t) ((a)>>52) & 0x7FF)
+#define fracF64UI(a) ((a) & UINT64_C(0x000FFFFFFFFFFFFF))
+#define packToF64UI(sign, exp, sig) ((uint64_t) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<52) + (sig)))
+
+#define isNaNF64UI(a) (((~(a) & UINT64_C(0x7FF0000000000000)) == 0) && ((a) & UINT64_C(0x000FFFFFFFFFFFFF)))
+
+struct exp16_sig64 { int16_t exp; uint64_t sig; };
+struct exp16_sig64 softfloat_normSubnormalF64Sig(uint64_t);
+
+float64 softfloat_roundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *);
+float64 softfloat_normRoundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status);
+extFloat80_t softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status);
+
+#define signExtF80UI64(a64) ((bool) ((uint16_t) (a64)>>15))
+#define expExtF80UI64(a64) ((a64) & 0x7FFF)
+#define packToExtF80UI64(sign, exp) ((uint16_t) (sign)<<15 | (exp))
+
+#define isNaNExtF80UI(a64, a0) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C(0x7FFFFFFFFFFFFFFF)))
+
+extFloat80_t packToExtF80(bool, uint16_t, uint64_t);
+extFloat80_t packToExtF80_twoargs(uint16_t, uint64_t);
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+struct exp32_sig64 { int32_t exp; uint64_t sig; };
+struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint64_t);
+
+extFloat80_t
+ softfloat_roundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *);
+extFloat80_t
+ softfloat_normRoundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF128UI64(a64) ((bool) ((uint64_t) (a64)>>63))
+#define expF128UI64(a64) ((int32_t) ((a64)>>48) & 0x7FFF)
+#define fracF128UI64(a64) ((a64) & UINT64_C(0x0000FFFFFFFFFFFF))
+#define packToF128UI64(sign, exp, sig64) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<48) + (sig64))
+
+#define isNaNF128UI(a64, a0) (((~(a64) & UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64) & UINT64_C(0x0000FFFFFFFFFFFF))))
+
+struct exp32_sig128 { int32_t exp; struct uint128 sig; };
+struct exp32_sig128 softfloat_normSubnormalF128Sig(uint64_t, uint64_t);
+
+float128_t
+ softfloat_roundPackToF128(bool, int32_t, uint64_t, uint64_t, uint64_t, struct softfloat_status_t *);
+float128_t
+ softfloat_normRoundPackToF128(bool, int32_t, uint64_t, uint64_t, struct softfloat_status_t *);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/cpu/softfloat3e/isNaN.cc b/src/cpu/softfloat3e/isNaN.cc
new file mode 100644
index 0000000000..8c0bd19122
--- /dev/null
+++ b/src/cpu/softfloat3e/isNaN.cc
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+bool f16_isNaN(float16 a)
+{
+ return isNaNF16UI(a);
+}
+
+bool f32_isNaN(float32 a)
+{
+ return isNaNF32UI(a);
+}
+
+bool f64_isNaN(float64 a)
+{
+ return isNaNF64UI(a);
+}
+
+bool extF80_isNaN(extFloat80_t a)
+{
+ return isNaNExtF80UI(a.signExp, a.signif);
+}
+
+bool f128_isNaN(float128_t a)
+{
+ return isNaNF128UI(a.v64, a.v0);
+}
diff --git a/src/cpu/softfloat3e/isSignalingNaN.cc b/src/cpu/softfloat3e/isSignalingNaN.cc
new file mode 100644
index 0000000000..994ac37841
--- /dev/null
+++ b/src/cpu/softfloat3e/isSignalingNaN.cc
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+bool f16_isSignalingNaN(float16 a)
+{
+ return softfloat_isSigNaNF16UI(a);
+}
+
+bool f32_isSignalingNaN(float32 a)
+{
+ return softfloat_isSigNaNF32UI(a);
+}
+
+bool f64_isSignalingNaN(float64 a)
+{
+ return softfloat_isSigNaNF64UI(a);
+}
+
+bool extF80_isSignalingNaN(extFloat80_t a)
+{
+ return softfloat_isSigNaNExtF80UI(a.signExp, a.signif);
+}
+
+bool f128_isSignalingNaN(float128_t a)
+{
+ return softfloat_isSigNaNF128UI(a.v64, a.v0);
+}
diff --git a/src/cpu/softfloat3e/opts-GCC.h b/src/cpu/softfloat3e/opts-GCC.h
new file mode 100644
index 0000000000..dd6c0ab640
--- /dev/null
+++ b/src/cpu/softfloat3e/opts-GCC.h
@@ -0,0 +1,110 @@
+
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2017 The Regents of the University of California. All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#ifndef _OPTS_GCC_H_
+#define _OPTS_GCC_H_
+
+#include
+#include "primitiveTypes.h"
+
+#ifdef SOFTFLOAT_BUILTIN_CLZ
+
+static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a)
+ { return a ? __builtin_clz(a) - 16 : 16; }
+#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16
+
+static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a)
+ { return a ? __builtin_clz(a) : 32; }
+#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
+
+static __inline uint8_t softfloat_countLeadingZeros64(uint64_t a)
+ { return a ? __builtin_clzll(a) : 64; }
+#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
+
+#endif
+
+#ifdef SOFTFLOAT_INTRINSIC_INT128
+
+static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = (unsigned __int128) a * ((uint64_t) b<<32);
+ return uZ.s;
+}
+#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128
+
+static __inline struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = (unsigned __int128) a * b;
+ return uZ.s;
+}
+#define softfloat_mul64To128 softfloat_mul64To128
+
+static __inline
+struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = ((unsigned __int128) a64<<64 | a0) * b;
+ return uZ.s;
+}
+#define softfloat_mul128By32 softfloat_mul128By32
+
+static __inline
+void
+ softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr)
+{
+ unsigned __int128 z0, mid1, mid, z128;
+ z0 = (unsigned __int128) a0 * b0;
+ mid1 = (unsigned __int128) a64 * b0;
+ mid = mid1 + (unsigned __int128) a0 * b64;
+ z128 = (unsigned __int128) a64 * b64;
+ z128 += (unsigned __int128) (mid < mid1)<<64 | mid>>64;
+ mid <<= 64;
+ z0 += mid;
+ z128 += (z0 < mid);
+ zPtr[indexWord(4, 0)] = z0;
+ zPtr[indexWord(4, 1)] = z0>>64;
+ zPtr[indexWord(4, 2)] = z128;
+ zPtr[indexWord(4, 3)] = z128>>64;
+}
+#define softfloat_mul128To256M softfloat_mul128To256M
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/cpu/softfloat/softfloat_poly.cc b/src/cpu/softfloat3e/poly.cc
similarity index 84%
rename from src/cpu/softfloat/softfloat_poly.cc
rename to src/cpu/softfloat3e/poly.cc
index 5c7079353e..a89d7f03f8 100644
--- a/src/cpu/softfloat/softfloat_poly.cc
+++ b/src/cpu/softfloat3e/poly.cc
@@ -23,10 +23,10 @@ these four paragraphs for those parts of this code that are retained.
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
-#define FLOAT128
-
#include
+
#include "softfloat.h"
+#include "poly.h"
// 2 3 4 n
// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
@@ -39,13 +39,15 @@ these four paragraphs for those parts of this code that are retained.
// f(x) ~ [ p(x) + x * q(x) ]
//
-float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status)
{
- float128 r = arr[--n];
+ float128_t r = arr[--n];
do {
- r = float128_mul(r, x, status);
- r = float128_add(r, arr[--n], status);
+ r = f128_mulAdd(r, x, arr[--n], 0, status);
+// r = f128_mul(r, x, &status);
+// r = f128_add(r, arr[--n], &status);
+
} while (n > 0);
return r;
@@ -63,9 +65,9 @@ float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *statu
// f(x) ~ [ p(x) + x * q(x) ]
//
-float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status)
{
- return EvalPoly(float128_mul(x, x, status), arr, n, status);
+ return EvalPoly(f128_mul(x, x, &status), arr, n, &status);
}
// 3 5 7 9 2n+1
@@ -83,7 +85,7 @@ float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *statu
// f(x) ~ x * [ p(x) + x * q(x) ]
//
-float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status)
{
- return float128_mul(x, EvenPoly(x, arr, n, status), status);
+ return f128_mul(x, EvenPoly(x, arr, n, status), &status);
}
diff --git a/src/cpu/softfloat3e/poly.h b/src/cpu/softfloat3e/poly.h
new file mode 100644
index 0000000000..1d6c3170c6
--- /dev/null
+++ b/src/cpu/softfloat3e/poly.h
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////
+// $Id$
+/////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2003-2018 Stanislav Shwartsman
+// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _POLY_H_
+#define _POLY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
+#else
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status);
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, struct float_status_t *status);
+#endif // __cplusplus
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _POLY_H_
diff --git a/src/cpu/softfloat3e/primitiveTypes.h b/src/cpu/softfloat3e/primitiveTypes.h
new file mode 100644
index 0000000000..67751372f0
--- /dev/null
+++ b/src/cpu/softfloat3e/primitiveTypes.h
@@ -0,0 +1,54 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#ifndef primitiveTypes_h
+#define primitiveTypes_h
+
+/*----------------------------------------------------------------------------
+| These macros are used to isolate the differences in word order between big-
+| endian and little-endian platforms.
+*----------------------------------------------------------------------------*/
+#define wordIncr 1
+#define indexWord(total, n) (n)
+#define indexWordHi(total) ((total) - 1)
+#define indexWordLo(total) 0
+#define indexMultiword(total, m, n) (n)
+#define indexMultiwordHi(total, n) ((total) - (n))
+#define indexMultiwordLo(total, n) 0
+#define indexMultiwordHiBut(total, n) (n)
+#define indexMultiwordLoBut(total, n) 0
+#define INIT_UINTM4(v3, v2, v1, v0) { v0, v1, v2, v3 }
+
+#endif
diff --git a/src/cpu/softfloat3e/primitives.h b/src/cpu/softfloat3e/primitives.h
new file mode 100644
index 0000000000..993067996e
--- /dev/null
+++ b/src/cpu/softfloat3e/primitives.h
@@ -0,0 +1,535 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#ifndef _PRIMITIVES_H_
+#define _PRIMITIVES_H_
+
+#include
+#include
+#include "softfloat_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOFTFLOAT_FAST_DIV64TO32
+
+#ifndef softfloat_shortShiftRightJam64
+/*----------------------------------------------------------------------------
+| Shifts 'a' right by the number of bits given in 'dist', which must be in
+| the range 1 to 63. If any nonzero bits are shifted off, they are "jammed"
+| into the least-significant bit of the shifted value by setting the least-
+| significant bit to 1. This shifted-and-jammed value is returned.
+*----------------------------------------------------------------------------*/
+static __inline
+uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint8_t dist)
+{
+ return a>>dist | ((a & (((uint64_t) 1<>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);
+}
+#endif
+
+#ifndef softfloat_shiftRightJam64
+/*----------------------------------------------------------------------------
+| Shifts 'a' right by the number of bits given in 'dist', which must not
+| be zero. If any nonzero bits are shifted off, they are "jammed" into the
+| least-significant bit of the shifted value by setting the least-significant
+| bit to 1. This shifted-and-jammed value is returned.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
+| greater than 64, the result will be either 0 or 1, depending on whether 'a'
+| is zero or nonzero.
+*----------------------------------------------------------------------------*/
+static __inline uint64_t softfloat_shiftRightJam64(uint64_t a, uint32_t dist)
+{
+ return (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| A constant table that translates an 8-bit unsigned integer (the array index)
+| into the number of leading 0 bits before the most-significant 1 of that
+| integer. For integer zero (index 0), the corresponding table element is 8.
+*----------------------------------------------------------------------------*/
+extern const uint_least8_t softfloat_countLeadingZeros8[256];
+
+#ifndef softfloat_countLeadingZeros16
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 16 is returned.
+*----------------------------------------------------------------------------*/
+static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a)
+{
+ uint8_t count = 8;
+ if (0x100 <= a) {
+ count = 0;
+ a >>= 8;
+ }
+ count += softfloat_countLeadingZeros8[a];
+ return count;
+}
+#endif
+
+#ifndef softfloat_countLeadingZeros32
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 32 is returned.
+*----------------------------------------------------------------------------*/
+static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a)
+{
+ uint8_t count = 0;
+ if (a < 0x10000) {
+ count = 16;
+ a <<= 16;
+ }
+ if (a < 0x1000000) {
+ count += 8;
+ a <<= 8;
+ }
+ count += softfloat_countLeadingZeros8[a>>24];
+ return count;
+}
+#endif
+
+#ifndef softfloat_countLeadingZeros64
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 64 is returned.
+*----------------------------------------------------------------------------*/
+uint8_t softfloat_countLeadingZeros64(uint64_t a);
+#endif
+
+extern const uint16_t softfloat_approxRecip_1k0s[16];
+extern const uint16_t softfloat_approxRecip_1k1s[16];
+
+#ifndef softfloat_approxRecip32_1
+/*----------------------------------------------------------------------------
+| Returns an approximation to the reciprocal of the number represented by 'a',
+| where 'a' is interpreted as an unsigned fixed-point number with one integer
+| bit and 31 fraction bits. The 'a' input must be "normalized", meaning that
+| its most-significant bit (bit 31) must be 1. Thus, if A is the value of
+| the fixed-point interpretation of 'a', then 1 <= A < 2. The returned value
+| is interpreted as a pure unsigned fraction, having no integer bits and 32
+| fraction bits. The approximation returned is never greater than the true
+| reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp
+| (units in the last place).
+*----------------------------------------------------------------------------*/
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+#define softfloat_approxRecip32_1(a) ((uint32_t) (UINT64_C(0x7FFFFFFFFFFFFFFF) / (uint32_t) (a)))
+#endif
+#endif
+
+extern const uint16_t softfloat_approxRecipSqrt_1k0s[16];
+extern const uint16_t softfloat_approxRecipSqrt_1k1s[16];
+
+/*----------------------------------------------------------------------------
+| Returns an approximation to the reciprocal of the square root of the number
+| represented by 'a', where 'a' is interpreted as an unsigned fixed-point
+| number either with one integer bit and 31 fraction bits or with two integer
+| bits and 30 fraction bits. The format of 'a' is determined by 'oddExpA',
+| which must be either 0 or 1. If 'oddExpA' is 1, 'a' is interpreted as
+| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having
+| two integer bits. The 'a' input must be "normalized", meaning that its
+| most-significant bit (bit 31) must be 1. Thus, if A is the value of the
+| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA'
+| is 1, and 2 <= A < 4 when 'oddExpA' is 0.
+| The returned value is interpreted as a pure unsigned fraction, having
+| no integer bits and 32 fraction bits. The approximation returned is never
+| greater than the true reciprocal 1/sqrt(A), and it differs from the true
+| reciprocal by at most 2.06 ulp (units in the last place). The approximation
+| returned is also always within the range 0.5 to 1; thus, the most-
+| significant bit of the result is always set.
+*----------------------------------------------------------------------------*/
+uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a);
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating
+| 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 == b64) && (a0 == b0);
+}
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is less than or equal to the 128-bit unsigned integer formed by
+| concatenating 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 < b64) || ((a64 == b64) && (a0 <= b0));
+}
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is less than the 128-bit unsigned integer formed by concatenating
+| 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 < b64) || ((a64 == b64) && (a0 < b0));
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the
+| number of bits given in 'dist', which must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint8_t dist)
+{
+ struct uint128 z;
+ z.v64 = a64<>(-dist & 63);
+ z.v0 = a0<>dist;
+ z.v0 = a64<<(-dist & 63) | a0>>dist;
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| This function is the same as 'softfloat_shiftRightJam64Extra' (below),
+| except that 'dist' must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint8_t dist)
+{
+ struct uint64_extra z;
+ z.v = a>>dist;
+ z.extra = a<<(-dist & 63) | (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the
+| number of bits given in 'dist', which must be in the range 1 to 63. If any
+| nonzero bits are shifted off, they are "jammed" into the least-significant
+| bit of the shifted value by setting the least-significant bit to 1. This
+| shifted-and-jammed value is returned.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint8_t dist)
+{
+ uint8_t negDist = -dist;
+ struct uint128 z;
+ z.v64 = a64>>dist;
+ z.v0 =
+ a64<<(negDist & 63) | a0>>dist
+ | ((uint64_t) (a0<<(negDist & 63)) != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| This function is the same as 'softfloat_shiftRightJam128Extra' (below),
+| except that 'dist' must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist)
+{
+ uint8_t negDist = -dist;
+ struct uint128_extra z;
+ z.v.v64 = a64>>dist;
+ z.v.v0 = a64<<(negDist & 63) | a0>>dist;
+ z.extra = a0<<(negDist & 63) | (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64
+| _plus_ the number of bits given in 'dist', which must not be zero. This
+| shifted value is at most 64 nonzero bits and is returned in the 'v' field
+| of the 'struct uint64_extra' result. The 64-bit 'extra' field of the result
+| contains a value formed as follows from the bits that were shifted off: The
+| _last_ bit shifted off is the most-significant bit of the 'extra' field, and
+| the other 63 bits of the 'extra' field are all zero if and only if _all_but_
+| _the_last_ bits shifted off were all zero.
+| (This function makes more sense if 'a' and 'extra' are considered to form
+| an unsigned fixed-point number with binary point between 'a' and 'extra'.
+| This fixed-point value is shifted right by the number of bits given in
+| 'dist', and the integer part of this shifted value is returned in the 'v'
+| field of the result. The fractional part of the shifted value is modified
+| as described above and returned in the 'extra' field of the result.)
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint64_extra
+ softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint32_t dist)
+{
+ struct uint64_extra z;
+ if (dist < 64) {
+ z.v = a>>dist;
+ z.extra = a<<(-dist & 63);
+ } else {
+ z.v = 0;
+ z.extra = (dist == 64) ? a : (a != 0);
+ }
+ z.extra |= (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the
+| number of bits given in 'dist', which must not be zero. If any nonzero bits
+| are shifted off, they are "jammed" into the least-significant bit of the
+| shifted value by setting the least-significant bit to 1. This shifted-and-
+| jammed value is returned.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
+| greater than 128, the result will be either 0 or 1, depending on whether the
+| original 128 bits are all zeros.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128
+ softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint32_t dist)
+{
+ uint8_t u8NegDist;
+ struct uint128 z;
+
+ if (dist < 64) {
+ u8NegDist = -dist;
+ z.v64 = a64>>dist;
+ z.v0 =
+ a64<<(u8NegDist & 63) | a0>>dist
+ | ((uint64_t) (a0<<(u8NegDist & 63)) != 0);
+ } else {
+ z.v64 = 0;
+ z.v0 =
+ (dist < 127)
+ ? a64>>(dist & 63)
+ | (((a64 & (((uint64_t) 1<<(dist & 63)) - 1)) | a0)
+ != 0)
+ : ((a64 | a0) != 0);
+ }
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right
+| by 64 _plus_ the number of bits given in 'dist', which must not be zero.
+| This shifted value is at most 128 nonzero bits and is returned in the 'v'
+| field of the 'struct uint128_extra' result. The 64-bit 'extra' field of the
+| result contains a value formed as follows from the bits that were shifted
+| off: The _last_ bit shifted off is the most-significant bit of the 'extra'
+| field, and the other 63 bits of the 'extra' field are all zero if and only
+| if _all_but_the_last_ bits shifted off were all zero.
+| (This function makes more sense if 'a64', 'a0', and 'extra' are considered
+| to form an unsigned fixed-point number with binary point between 'a0' and
+| 'extra'. This fixed-point value is shifted right by the number of bits
+| given in 'dist', and the integer part of this shifted value is returned
+| in the 'v' field of the result. The fractional part of the shifted value
+| is modified as described above and returned in the 'extra' field of the
+| result.)
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128_extra
+ softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint32_t dist)
+{
+ uint8_t u8NegDist;
+ struct uint128_extra z;
+
+ u8NegDist = -dist;
+ if (dist < 64) {
+ z.v.v64 = a64>>dist;
+ z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist;
+ z.extra = a0<<(u8NegDist & 63);
+ } else {
+ z.v.v64 = 0;
+ if (dist == 64) {
+ z.v.v0 = a64;
+ z.extra = a0;
+ } else {
+ extra |= a0;
+ if (dist < 128) {
+ z.v.v0 = a64>>(dist & 63);
+ z.extra = a64<<(u8NegDist & 63);
+ } else {
+ z.v.v0 = 0;
+ z.extra = (dist == 128) ? a64 : (a64 != 0);
+ }
+ }
+ }
+ z.extra |= (extra != 0);
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number
+| of bits given in 'dist', which must not be zero. If any nonzero bits are
+| shifted off, they are "jammed" into the least-significant bit of the shifted
+| value by setting the least-significant bit to 1. This shifted-and-jammed
+| value is stored at the location pointed to by 'zPtr'. Each of 'aPtr' and
+| 'zPtr' points to an array of four 64-bit elements that concatenate in the
+| platform's normal endian order to form a 256-bit integer.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist'
+| is greater than 256, the stored result will be either 0 or 1, depending on
+| whether the original 256 bits are all zeros.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *zPtr);
+
+#ifndef softfloat_add128
+/*----------------------------------------------------------------------------
+| Returns the sum of the 128-bit integer formed by concatenating 'a64' and
+| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. The
+| addition is modulo 2^128, so any carry out is lost.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+ z.v0 = a0 + b0;
+ z.v64 = a64 + b64 + (z.v0 < a0);
+ return z;
+}
+#endif
+
+#ifndef softfloat_add256M
+/*----------------------------------------------------------------------------
+| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'. The addition
+| is modulo 2^256, so any carry out is lost. The sum is stored at the
+| location pointed to by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to
+| an array of four 64-bit elements that concatenate in the platform's normal
+| endian order to form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr);
+#endif
+
+#ifndef softfloat_sub128
+/*----------------------------------------------------------------------------
+| Returns the difference of the 128-bit integer formed by concatenating 'a64'
+| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'.
+| The subtraction is modulo 2^128, so any borrow out (carry out) is lost.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+ z.v0 = a0 - b0;
+ z.v64 = a64 - b64;
+ z.v64 -= (a0 < b0);
+ return z;
+}
+#endif
+
+#ifndef softfloat_sub256M
+/*----------------------------------------------------------------------------
+| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer
+| pointed to by 'aPtr'. The addition is modulo 2^256, so any borrow out
+| (carry out) is lost. The difference is stored at the location pointed to
+| by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four
+| 64-bit elements that concatenate in the platform's normal endian order to
+| form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_sub256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr);
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns the 128-bit product of 'a', 'b', and 2^32.
+*----------------------------------------------------------------------------*/
+static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
+{
+ uint64_t mid;
+ struct uint128 z;
+ mid = (uint64_t) (uint32_t) a * b;
+ z.v0 = mid<<32;
+ z.v64 = (uint64_t) (uint32_t) (a>>32) * b + (mid>>32);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Returns the 128-bit product of 'a' and 'b'.
+*----------------------------------------------------------------------------*/
+struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b);
+
+/*----------------------------------------------------------------------------
+| Returns the product of the 128-bit integer formed by concatenating 'a64' and
+| 'a0', multiplied by 'b'. The multiplication is modulo 2^128; any overflow
+| bits are discarded.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
+{
+ struct uint128 z;
+ uint64_t mid;
+ uint32_t carry;
+ z.v0 = a0 * b;
+ mid = (uint64_t) (uint32_t) (a0>>32) * b;
+ carry = (uint32_t) ((uint32_t) (z.v0>>32) - (uint32_t) mid);
+ z.v64 = a64 * b + (uint32_t) ((mid + carry)>>32);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and
+| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and
+| 'b0'. The 256-bit product is stored at the location pointed to by 'zPtr'.
+| Argument 'zPtr' points to an array of four 64-bit elements that concatenate
+| in the platform's normal endian order to form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _PRIMITIVES_H_
diff --git a/src/cpu/softfloat3e/s_add128.cc b/src/cpu/softfloat3e/s_add128.cc
new file mode 100644
index 0000000000..8efabb8501
--- /dev/null
+++ b/src/cpu/softfloat3e/s_add128.cc
@@ -0,0 +1,51 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "softfloat_types.h"
+
+#ifndef softfloat_add128
+
+struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+
+ z.v0 = a0 + b0;
+ z.v64 = a64 + b64 + (z.v0 < a0);
+ return z;
+}
+
+#endif
+
diff --git a/src/cpu/softfloat3e/s_add256M.c b/src/cpu/softfloat3e/s_add256M.c
new file mode 100644
index 0000000000..32fdf122f5
--- /dev/null
+++ b/src/cpu/softfloat3e/s_add256M.c
@@ -0,0 +1,60 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "primitiveTypes.h"
+
+#ifndef softfloat_add256M
+
+void softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr)
+{
+ unsigned int index;
+ uint8_t carry;
+ uint64_t wordA, wordZ;
+
+ index = indexWordLo(4);
+ carry = 0;
+ for (;;) {
+ wordA = aPtr[index];
+ wordZ = wordA + bPtr[index] + carry;
+ zPtr[index] = wordZ;
+ if (index == indexWordHi(4)) break;
+ if (wordZ != wordA) carry = (wordZ < wordA);
+ index += wordIncr;
+ }
+}
+
+#endif
+
diff --git a/src/cpu/softfloat3e/s_addMagsExtF80.cc b/src/cpu/softfloat3e/s_addMagsExtF80.cc
new file mode 100644
index 0000000000..5cc969198b
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsExtF80.cc
@@ -0,0 +1,146 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status)
+{
+ int32_t expA;
+ uint64_t sigA;
+ int32_t expB;
+ uint64_t sigB;
+ int32_t expDiff;
+ uint64_t sigZ, sigZExtra;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA << 1) || ((expB == 0x7FFF) && (sigB << 1)))
+ goto propagateNaN;
+ if (sigB && ! expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80_twoargs(uiA64, uiA0);
+ }
+ if (expB == 0x7FFF) {
+ if (sigB << 1) goto propagateNaN;
+ if (sigA && ! expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (! expB && sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+ expZ = expB;
+ sigZ = sigB;
+ sigZExtra = 0;
+ goto roundAndPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0) {
+ if (sigB == 0) {
+ expZ = expA;
+ sigZ = sigA;
+ sigZExtra = 0;
+ goto roundAndPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ sigZ = sigA + sigB;
+ sigZExtra = 0;
+ expZ = expA;
+ goto shiftRight1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ expZ = expB;
+ sig64Extra = softfloat_shiftRightJam64Extra(sigA, 0, -expDiff);
+ sigA = sig64Extra.v;
+ sigZExtra = sig64Extra.extra;
+ } else {
+ expZ = expA;
+ sig64Extra = softfloat_shiftRightJam64Extra(sigB, 0, expDiff);
+ sigB = sig64Extra.v;
+ sigZExtra = sig64Extra.extra;
+ }
+ sigZ = sigA + sigB;
+ if (sigZ & UINT64_C(0x8000000000000000)) goto roundAndPack;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftRight1:
+ sig64Extra = softfloat_shortShiftRightJam64Extra(sigZ, sigZExtra, 1);
+ sigZ = sig64Extra.v | UINT64_C(0x8000000000000000);
+ sigZExtra = sig64Extra.extra;
+ ++expZ;
+ roundAndPack:
+ return softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF128.cc b/src/cpu/softfloat3e/s_addMagsF128.cc
new file mode 100644
index 0000000000..b831796cc4
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF128.cc
@@ -0,0 +1,138 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status)
+{
+ int32_t expA;
+ struct uint128 sigA;
+ int32_t expB;
+ struct uint128 sigB;
+ int32_t expDiff;
+ struct uint128 uiZ, sigZ;
+ int32_t expZ;
+ uint64_t sigZExtra;
+ struct uint128_extra sig128Extra;
+
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ expDiff = expA - expB;
+ if (! expDiff) {
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0) goto propagateNaN;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ return uiZ;
+ }
+ sigZ = softfloat_add128(sigA.v64, sigA.v0, sigB.v64, sigB.v0);
+ if (! expA) {
+ uiZ.v64 = packToF128UI64(signZ, 0, sigZ.v64);
+ uiZ.v0 = sigZ.v0;
+ return uiZ;
+ }
+ expZ = expA;
+ sigZ.v64 |= UINT64_C(0x0002000000000000);
+ sigZExtra = 0;
+ goto shiftRight1;
+ }
+ if (expDiff < 0) {
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ expZ = expB;
+ if (expA) {
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ } else {
+ ++expDiff;
+ sigZExtra = 0;
+ if (! expDiff) goto newlyAligned;
+ }
+ sig128Extra =
+ softfloat_shiftRightJam128Extra(sigA.v64, sigA.v0, 0, -expDiff);
+ sigA = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ } else {
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0) goto propagateNaN;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ return uiZ;
+ }
+ expZ = expA;
+ if (expB) {
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ } else {
+ --expDiff;
+ sigZExtra = 0;
+ if (! expDiff) goto newlyAligned;
+ }
+ sig128Extra = softfloat_shiftRightJam128Extra(sigB.v64, sigB.v0, 0, expDiff);
+ sigB = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ }
+ newlyAligned:
+ sigZ =
+ softfloat_add128(
+ sigA.v64 | UINT64_C(0x0001000000000000),
+ sigA.v0,
+ sigB.v64,
+ sigB.v0
+ );
+ --expZ;
+ if (sigZ.v64 < UINT64_C(0x0002000000000000)) goto roundAndPack;
+ ++expZ;
+ shiftRight1:
+ sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1);
+ sigZ = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ roundAndPack:
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF16.c b/src/cpu/softfloat3e/s_addMagsF16.c
new file mode 100644
index 0000000000..022f254a80
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF16.c
@@ -0,0 +1,192 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 softfloat_addMagsF16(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status)
+{
+ int8_t expA;
+ uint16_t sigA;
+ int8_t expB;
+ uint16_t sigB;
+ int8_t expDiff;
+ uint16_t uiZ;
+ bool signZ;
+ int8_t expZ;
+ uint16_t sigZ;
+ uint16_t sigX, sigY;
+ int8_t shiftDist;
+ uint32_t sig32Z;
+ int8_t roundingMode;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF16UI(uiA);
+ sigA = fracF16UI(uiA);
+ expB = expF16UI(uiB);
+ sigB = fracF16UI(uiB);
+ signZ = signF16UI(uiA);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF16UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF16UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF16UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0x1F) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = 0x0800 + sigA + sigB;
+ if (! (sigZ & 1) && (expZ < 0x1E)) {
+ sigZ >>= 1;
+ goto pack;
+ }
+ sigZ <<= 3;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ /*----------------------------------------------------------------
+ *----------------------------------------------------------------*/
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF16UI(signZ, 0x1F, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ if (expDiff <= -13) {
+ uiZ = packToF16UI(signZ, expB, sigB);
+ if (expA | sigA) goto addEpsilon;
+ return uiZ;
+ }
+ expZ = expB;
+ sigX = sigB | 0x0400;
+ sigY = sigA + (expA ? 0x0400 : sigA);
+ shiftDist = 19 + expDiff;
+ } else {
+ /*----------------------------------------------------------------
+ *----------------------------------------------------------------*/
+ uiZ = uiA;
+ if (expA == 0x1F) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiZ;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ if (13 <= expDiff) {
+ if (expB | sigB) goto addEpsilon;
+ return uiZ;
+ }
+ expZ = expA;
+ sigX = sigA | 0x0400;
+ sigY = sigB + (expB ? 0x0400 : sigB);
+ shiftDist = 19 - expDiff;
+ }
+ sig32Z = ((uint32_t) sigX<<19) + ((uint32_t) sigY<>16;
+ if (sig32Z & 0xFFFF) {
+ sigZ |= 1;
+ } else {
+ if (! (sigZ & 0xF) && (expZ < 0x1E)) {
+ sigZ >>= 4;
+ goto pack;
+ }
+ }
+ }
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(uiA, uiB, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ addEpsilon:
+ roundingMode = softfloat_getRoundingMode(status);
+ if (roundingMode != softfloat_round_near_even) {
+ if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ ++uiZ;
+ if ((uint16_t) (uiZ<<1) == 0xF800) {
+ softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact);
+ }
+ }
+ }
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ pack:
+ return packToF16UI(signZ, expZ, sigZ);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF32.c b/src/cpu/softfloat3e/s_addMagsF32.c
new file mode 100644
index 0000000000..df902348a4
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF32.c
@@ -0,0 +1,147 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float32 softfloat_addMagsF32(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint32_t sigA;
+ int16_t expB;
+ uint32_t sigB;
+ int16_t expDiff;
+ uint32_t uiZ;
+ bool signZ;
+ int16_t expZ;
+ uint32_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF32UI(uiA);
+ sigA = fracF32UI(uiA);
+ expB = expF32UI(uiB);
+ sigB = fracF32UI(uiB);
+ signZ = signF32UI(uiA);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF32UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF32UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF32UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0xFF) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = 0x01000000 + sigA + sigB;
+ if (! (sigZ & 1) && (expZ < 0xFE)) {
+ return packToF32UI(signZ, expZ, sigZ>>1);
+ }
+ sigZ <<= 6;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ signZ = signF32UI(uiA);
+ sigA <<= 6;
+ sigB <<= 6;
+ if (expDiff < 0) {
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF32UI(signZ, 0xFF, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expB;
+ sigA += expA ? 0x20000000 : sigA;
+ sigA = softfloat_shiftRightJam32(sigA, -expDiff);
+ } else {
+ if (expA == 0xFF) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiA;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expA;
+ sigB += expB ? 0x20000000 : sigB;
+ sigB = softfloat_shiftRightJam32(sigB, expDiff);
+ }
+ sigZ = 0x20000000 + sigA + sigB;
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ }
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(uiA, uiB, status);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF64.c b/src/cpu/softfloat3e/s_addMagsF64.c
new file mode 100644
index 0000000000..a315860f6c
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF64.c
@@ -0,0 +1,149 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float64 softfloat_addMagsF64(uint64_t uiA, uint64_t uiB, bool signZ, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint64_t sigA;
+ int16_t expB;
+ uint64_t sigB;
+ int16_t expDiff;
+ uint64_t uiZ;
+ int16_t expZ;
+ uint64_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF64UI(uiA);
+ sigA = fracF64UI(uiA);
+ expB = expF64UI(uiB);
+ sigB = fracF64UI(uiB);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF64UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF64UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0x7FF) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = UINT64_C(0x0020000000000000) + sigA + sigB;
+ sigZ <<= 9;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigA <<= 9;
+ sigB <<= 9;
+ if (expDiff < 0) {
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF64UI(signZ, 0x7FF, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expB;
+ if (expA) {
+ sigA += UINT64_C(0x2000000000000000);
+ } else {
+ sigA <<= 1;
+ }
+ sigA = softfloat_shiftRightJam64(sigA, -expDiff);
+ } else {
+ if (expA == 0x7FF) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiA;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expA;
+ if (expB) {
+ sigB += UINT64_C(0x2000000000000000);
+ } else {
+ sigB <<= 1;
+ }
+ sigB = softfloat_shiftRightJam64(sigB, expDiff);
+ }
+ sigZ = UINT64_C(0x2000000000000000) + sigA + sigB;
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(uiA, uiB, status);
+}
diff --git a/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c
new file mode 100644
index 0000000000..776c146ef3
--- /dev/null
+++ b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the University nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=============================================================================*/
+
+#include