diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml
index 22db9f1514..64f8f91ed7 100644
--- a/.ci/AppImageBuilder.yml
+++ b/.ci/AppImageBuilder.yml
@@ -59,6 +59,7 @@ AppDir:
- libqt5widgets5 # if QT:BOOL=ON
- libsixel1 # if CLI:BOOL=ON
- libslirp0
+ - libsndfile1
- libsndio7.0 # if OPENAL:BOOL=ON
- libvdeplug-dev # -dev also pulls in libvdeplug2. -dev is required to get the proper .so symlink to the library
- libx11-6 # if QT:BOOL=ON
diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile
index a57d3c715e..04b0bc3505 100644
--- a/.ci/Jenkinsfile
+++ b/.ci/Jenkinsfile
@@ -20,11 +20,12 @@ def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0]
def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null]
def branch = ['master', scm.branches[0].name]
def buildType = ['beta', 'alpha']
+def tarballFlags = ['', '-s']
def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0
def osArchs = [
- 'Windows': ['32', '64'],
- 'Linux': ['x86', 'x86_64', 'arm32', 'arm64'],
+ 'Windows': ['64'],
+ 'Linux': ['x86_64', 'arm64'],
'macOS': ['x86_64+x86_64h+arm64']
]
@@ -238,7 +239,7 @@ pipeline {
dir("${env.WORKSPACE_TMP}/output") {
/* Run source tarball creation process. */
def packageName = "${env.JOB_BASE_NAME}-Source$buildSuffix"
- if (runBuild("-s \"$packageName\"") == 0) {
+ if (runBuild("-s \"$packageName\" ${tarballFlags[buildBranch]}") == 0) {
/* Archive resulting artifacts. */
archiveArtifacts artifacts: "$packageName*"
} else {
diff --git a/.ci/build.sh b/.ci/build.sh
index 1b1e5825e6..c60016d51f 100755
--- a/.ci/build.sh
+++ b/.ci/build.sh
@@ -208,7 +208,7 @@ cmake_flags_extra=
if [ -z "$package_name" -a -z "$tarball_name" ] || [ -n "$package_name" -a -z "$arch" ]
then
echo '[!] Usage: build.sh -b {package_name} {architecture} [-t] [cmake_flags...]'
- echo ' build.sh -s {source_tarball_name}'
+ echo ' build.sh -s {source_tarball_name} [-t]'
echo 'Dep. tree: build.sh -p [archive_tmp/path/to/binary]'
exit 100
fi
@@ -228,7 +228,10 @@ then
[ ! -d "$cwd" ] && mkdir -p "$cwd"
# Save current HEAD commit to VERSION.
- git log --stat -1 > VERSION || rm -f VERSION
+ if [ $strip -eq 0 ]
+ then
+ git log --stat -1 > VERSION || rm -f VERSION
+ fi
# Archive source.
make_tar "$cwd/$tarball_name.tar"
@@ -535,6 +538,14 @@ then
sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile"
sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile"
fi
+
+ # Patch wget to remove libproxy support, as it depends on shared-mime-info which
+ # fails to build for a 10.13 target, which we have to do despite wget only being
+ # a host dependency. MacPorts issue 69406 strongly implies this will not be fixed.
+ wget_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/net/wget/Portfile"
+ sudo sed -i -e 's/--enable-libproxy/--disable-libproxy/g' "$wget_portfile"
+ sudo sed -i -e 's/port:libproxy//g' "$wget_portfile"
+
while :
do
# Attempt to install dependencies.
@@ -605,7 +616,7 @@ else
# ...and the ones we do want listed. Non-dev packages fill missing spots on the list.
libpkgs=""
longest_libpkg=0
- for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev
+ for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev
do
libpkgs="$libpkgs $pkg:$arch_deb"
length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c)
diff --git a/.ci/dependencies_macports.txt b/.ci/dependencies_macports.txt
index 5ec71d07cd..b23ac441d5 100644
--- a/.ci/dependencies_macports.txt
+++ b/.ci/dependencies_macports.txt
@@ -15,3 +15,4 @@ fluidsynth
ghostscript
libslirp
vde2
+libsndfile
diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt
index 694fe3e289..eacdb8b36f 100644
--- a/.ci/dependencies_msys.txt
+++ b/.ci/dependencies_msys.txt
@@ -13,3 +13,4 @@ fluidsynth
qt5-static
qt5-translations
vulkan-headers
+libsndfile
diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml
index 04238ece0d..ed0f055a2f 100644
--- a/.github/workflows/cmake_linux.yml
+++ b/.github/workflows/cmake_linux.yml
@@ -40,10 +40,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
- preset: debug
+ preset: dev_debug
slug: -Debug
- name: Dev
- preset: experimental
+ preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -88,7 +88,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
- uses: SonarSource/sonarcloud-github-c-cpp@v2
+ uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d
- name: Configure CMake
run: >-
diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml
index 5a9f31a01f..dc45312f50 100644
--- a/.github/workflows/cmake_macos.yml
+++ b/.github/workflows/cmake_macos.yml
@@ -40,10 +40,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
- preset: debug
+ preset: dev_debug
slug: -Debug
- name: Dev
- preset: experimental
+ preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -76,9 +76,7 @@ jobs:
run: >-
brew install
ninja
- freetype
sdl2
- libpng
rtmidi
openal-soft
fluidsynth
@@ -90,7 +88,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
- uses: SonarSource/sonarcloud-github-c-cpp@v2
+ uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d
- name: Configure CMake
run: >-
@@ -124,3 +122,102 @@ jobs:
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**
+
+ macos14-arm64:
+ name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, arm64"
+
+ runs-on: macos-14
+
+# env:
+# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+
+ strategy:
+ fail-fast: true
+ matrix:
+ build:
+# - name: Regular
+# preset: regular
+ - name: Debug
+ preset: dev_debug
+ slug: -Debug
+ - name: Dev
+ preset: development
+ slug: -Dev
+ dynarec:
+# - name: ODR
+# new: off
+# slug: -ODR
+ - name: NDR
+ new: on
+ slug: -NDR
+ ui:
+ - name: SDL GUI
+ qt: off
+ static: on
+ src-packages: >-
+ libsndfile
+ - name: Qt GUI
+ qt: on
+ slug: -Qt
+ packages: >-
+ qt@5
+ src-packages: >-
+ libsndfile
+
+ steps:
+ - name: Install source dependencies
+ run: >-
+ brew reinstall -s
+ ${{ matrix.ui.src-packages }}
+
+ - name: Install dependencies
+ run: >-
+ brew install
+ ninja
+ sdl2
+ rtmidi
+ openal-soft
+ fluidsynth
+ libslirp
+ ${{ matrix.ui.packages }}
+
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+
+# - name: Install sonar-scanner and build-wrapper
+# uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d
+
+ - name: Configure CMake
+ run: >-
+ cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
+ --toolchain ./cmake/llvm-macos-aarch64.cmake
+ -D NEW_DYNAREC=${{ matrix.dynarec.new }}
+ -D CMAKE_INSTALL_PREFIX=./build/artifacts
+ -D QT=${{ matrix.ui.qt }}
+ -D Qt5_ROOT=$(brew --prefix qt@5)
+ -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
+ -D OpenAL_ROOT=$(brew --prefix openal-soft)
+
+ - name: Build
+ run: |
+ cmake --build build
+
+# - name: Run sonar-scanner
+# if: 0
+# env:
+# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+# run: |
+# sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
+
+ - name: Generate package
+ run: |
+ cmake --install build
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-arm64-gha${{ github.run_number }}'
+ path: build/artifacts/**
diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml
index 36442684aa..91442eafd2 100644
--- a/.github/workflows/cmake_windows_msys2.yml
+++ b/.github/workflows/cmake_windows_msys2.yml
@@ -44,10 +44,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
- preset: debug
+ preset: dev_debug
slug: -Debug
- name: Dev
- preset: experimental
+ preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -111,7 +111,7 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
- uses: SonarSource/sonarcloud-github-c-cpp@v2
+ uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d
- name: Configure CMake
run: >-
diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml
index 73ccfb2146..fee26a0a66 100644
--- a/.github/workflows/codeql_linux.yml
+++ b/.github/workflows/codeql_linux.yml
@@ -47,7 +47,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
- preset: experimental
+ preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml
index 6d2c3861f3..266a1f051f 100644
--- a/.github/workflows/codeql_macos.yml
+++ b/.github/workflows/codeql_macos.yml
@@ -47,7 +47,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
- preset: experimental
+ preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
@@ -70,9 +70,7 @@ jobs:
run: >-
brew install
ninja
- freetype
sdl2
- libpng
rtmidi
openal-soft
fluidsynth
diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml
index 2b468f9960..652a1986aa 100644
--- a/.github/workflows/codeql_windows_msys2.yml
+++ b/.github/workflows/codeql_windows_msys2.yml
@@ -51,7 +51,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
- preset: experimental
+ preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa1d02a151..a70cbd61f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,16 +1,17 @@
#
-# 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.
+# 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.
+# This file is part of the 86Box distribution.
#
-# CMake build script.
+# CMake build script.
#
-# Authors: David Hrdlička,
+# Authors: David Hrdlička,
#
-# Copyright 2020-2021 David Hrdlička.
+# Copyright 2020-2021 David Hrdlička.
+# Copyright 2021-2024 Jasmine Iwanek.
#
cmake_minimum_required(VERSION 3.16)
@@ -35,7 +36,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
- VERSION 4.2
+ VERSION 4.2.2
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
@@ -122,46 +123,55 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Optional features
#
-# Option Description Def.
-# ------ ----------- ----
-option(RELEASE "Release build" OFF)
-option(DYNAREC "Dynamic recompiler" ON)
-option(OPENAL "OpenAL" ON)
-option(RTMIDI "RtMidi" ON)
-option(FLUIDSYNTH "FluidSynth" ON)
-option(MUNT "MUNT" ON)
-option(VNC "VNC renderer" OFF)
-option(CPPTHREADS "C++11 threads" ON)
-option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
-option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
-option(GDBSTUB "Enable GDB stub server for debugging" OFF)
-option(DEV_BRANCH "Development branch" OFF)
-option(DISCORD "Discord Rich Presence support" ON)
-option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
+# Option Description Def.
+# ------ ----------- ----
+option(RELEASE "Release build" OFF)
+option(DYNAREC "Dynamic recompiler" ON)
+option(OPENAL "OpenAL" ON)
+option(RTMIDI "RtMidi" ON)
+option(FLUIDSYNTH "FluidSynth" ON)
+option(MUNT "MUNT" ON)
+option(VNC "VNC renderer" OFF)
+option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
+option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
+option(GDBSTUB "Enable GDB stub server for debugging" OFF)
+option(DEV_BRANCH "Development branch" OFF)
+option(DISCORD "Discord Rich Presence support" ON)
+option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
if(WIN32)
set(QT ON)
+ option(CPPTHREADS "C++11 threads" OFF)
else()
option(QT "Qt GUI" ON)
+ option(CPPTHREADS "C++11 threads" ON)
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,wxneeded")
endif()
# Development branch features
#
-# Option Description Def. Condition Otherwise
-# ------ ----------- ---- --------- ---------
-cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
-cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
+# Option Description Def. Condition Otherwise
+# ------ ----------- ---- ------------ ---------
+cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF)
+cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
# Ditto but for Qt
if(QT)
diff --git a/CMakePresets.json b/CMakePresets.json
index 0dbaf19881..c19a7abc0d 100644
--- a/CMakePresets.json
+++ b/CMakePresets.json
@@ -43,17 +43,15 @@
"name": "development",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
- "DEV_BRANCH": "ON",
- "NEW_DYNAREC": "OFF"
+ "DEV_BRANCH": "ON"
},
"inherits": "base"
},
{
- "name": "experimental",
+ "name": "dev_debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
- "DEV_BRANCH": "ON",
- "NEW_DYNAREC": "ON"
+ "DEV_BRANCH": "ON"
},
"inherits": "base"
},
diff --git a/README.md b/README.md
index b4b4142be5..ce38632e6d 100644
--- a/README.md
+++ b/README.md
@@ -53,10 +53,14 @@ We operate an IRC channel and a Discord server for discussing 86Box, its develop
[](https://discord.gg/QXK9XTv)
Contributions
----------
+-------------
We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed.
+Building
+---------
+For instructions on how to build 86Box from source, see the [build guide](https://86box.readthedocs.io/en/latest/dev/buildguide.html).
+
Licensing
---------
diff --git a/debian/changelog b/debian/changelog
index fe8aa68213..ae80cfa9d4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,5 @@
-86box (4.2) UNRELEASED; urgency=medium
+86box (4.2.2) UNRELEASED; urgency=medium
* Bump release.
- -- Jasmine Iwanek Sat, 23 Mar 2024 17:19:08 +0100
+ -- Jasmine Iwanek Sat, 28 Sep 2024 18:31:57 +0200
diff --git a/debian/control b/debian/control
index d67f5965ba..a718aee337 100644
--- a/debian/control
+++ b/debian/control
@@ -13,6 +13,7 @@ Build-Depends: cmake (>= 3.21),
libsdl2-dev,
libslirp-dev,
libxkbcommon-x11-dev,
+ libsndfile-dev,
ninja-build,
qttools5-dev,
qtbase5-private-dev
@@ -31,4 +32,4 @@ Recommends: libpcap0.8-dev
Description: An emulator for classic IBM PC clones
86Box is a low level x86 emulator that runs older operating systems and software
designed for IBM PC systems and compatibles from 1981 through
- fairly recent system designs based on the PCI bus.
\ No newline at end of file
+ fairly recent system designs based on the PCI bus.
diff --git a/src/86box.c b/src/86box.c
index 61b81bbf3e..5e1f584133 100644
--- a/src/86box.c
+++ b/src/86box.c
@@ -171,15 +171,15 @@ int video_filter_method = 1; /* (C) video *
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
-bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of
- pass-through for serial ports */
+bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; /* (C) activation and kind of
+ pass-through for serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */
int postcard_enabled = 0; /* (C) enable POST card */
int unittester_enabled = 0; /* (C) enable unit tester device */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
-int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
+int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
@@ -354,12 +354,14 @@ fatal(const char *fmt, ...)
if ((sp = strchr(temp, '\n')) != NULL)
*sp = '\0';
+ do_pause(2);
+
+ ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
+
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
- ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
-
fflush(stdlog);
exit(-1);
@@ -396,12 +398,14 @@ fatal_ex(const char *fmt, va_list ap)
if ((sp = strchr(temp, '\n')) != NULL)
*sp = '\0';
+ do_pause(2);
+
+ ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
+
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
- ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
-
fflush(stdlog);
}
@@ -1000,12 +1004,15 @@ pc_init_modules(void)
}
}
- if (!video_card_available(gfxcard[1])) {
- char tempc[512] = { 0 };
- device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc);
- swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc);
- ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
- gfxcard[1] = 0;
+ // TODO
+ for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
+ if (!video_card_available(gfxcard[i])) {
+ char tempc[512] = { 0 };
+ device_get_name(video_card_getdevice(gfxcard[i]), 0, tempc);
+ swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc);
+ ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
+ gfxcard[i] = 0;
+ }
}
atfullspeed = 0;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c5ec2587c2..8f9fb39df2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,16 +12,45 @@
# dob205
#
# Copyright 2020-2022 David Hrdlička.
-# Copyright 2021 dob205.
+# Copyright 2021 dob205.
+# Copyright 2024 Jasmine Iwanek.
#
+
if(APPLE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
-add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
- dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
- mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
- machine_status.c ini.c cJSON.c)
+add_executable(86Box
+ 86box.c
+ config.c
+ log.c
+ random.c
+ timer.c
+ io.c
+ acpi.c
+ apm.c
+ dma.c
+ ddma.c
+ nmi.c
+ pic.c
+ pit.c
+ pit_fast.c
+ port_6x.c
+ port_92.c
+ ppi.c
+ pci.c
+ mca.c
+ usb.c
+ fifo.c
+ fifo8.c
+ device.c
+ nvr.c
+ nvr_at.c
+ nvr_ps2.c
+ machine_status.c
+ ini.c
+ cJSON.c
+)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
@@ -48,10 +77,6 @@ if(DYNAREC)
add_compile_definitions(USE_DYNAREC)
endif()
-if(DEV_BRANCH)
- add_compile_definitions(DEV_BRANCH)
-endif()
-
if(DISCORD)
add_compile_definitions(DISCORD)
target_sources(86Box PRIVATE discord.c)
@@ -65,8 +90,11 @@ if(VNC)
find_package(LibVNCServer)
if(LibVNCServer_FOUND)
add_compile_definitions(USE_VNC)
- add_library(vnc OBJECT vnc.c vnc_keymap.c)
- target_link_libraries(86Box vnc LibVNCServer::vncserver)
+ add_library(vnc OBJECT
+ vnc.c
+ vnc_keymap.c
+ )
+ target_link_libraries(86Box vnc LibVNCServer::vncserver)
if(WIN32)
target_link_libraries(86Box ws2_32)
endif()
@@ -143,8 +171,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories(include)
if(NEW_DYNAREC)
include_directories(cpu codegen_new)
-else()
+elseif(DYNAREC)
include_directories(cpu codegen)
+else()
+ include_directories(cpu)
endif()
add_subdirectory(cdrom)
@@ -154,7 +184,7 @@ add_subdirectory(usb)
add_subdirectory(cpu)
if(NEW_DYNAREC)
add_subdirectory(codegen_new)
-else()
+elseif(DYNAREC)
add_subdirectory(codegen)
endif()
diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt
index d3b38095e7..2f0f1cd23e 100644
--- a/src/cdrom/CMakeLists.txt
+++ b/src/cdrom/CMakeLists.txt
@@ -9,8 +9,31 @@
# CMake build script.
#
# Authors: David Hrdlička,
+# Jasmine Iwanek,
#
# Copyright 2020-2021 David Hrdlička.
+# Copyright 2024 Jasmine Iwanek.
#
-add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_ioctl.c cdrom_mitsumi.c)
+find_package(PkgConfig REQUIRED)
+
+pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile)
+
+add_library(cdrom OBJECT
+ cdrom.c
+ cdrom_image_backend.c
+ cdrom_image_viso.c
+ cdrom_image.c
+ cdrom_ioctl.c
+)
+target_link_libraries(86Box PkgConfig::SNDFILE)
+
+if(CDROM_MITSUMI)
+ target_compile_definitions(cdrom PRIVATE USE_CDROM_MITSUMI)
+ target_sources(cdrom PRIVATE cdrom_mitsumi.c)
+endif()
+
+if (WIN32)
+ # MSYS2
+ target_link_libraries(86Box -static ${SNDFILE_STATIC_LIBRARIES})
+endif()
diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c
index 88811c0168..41cc1db982 100644
--- a/src/cdrom/cdrom.c
+++ b/src/cdrom/cdrom.c
@@ -2016,6 +2016,25 @@ cdrom_insert(uint8_t id)
dev->insert(dev->priv);
}
+void
+cdrom_exit(uint8_t id)
+{
+ cdrom_t *dev = &cdrom[id];
+
+ strcpy(dev->prev_image_path, dev->image_path);
+
+ if (dev->ops) {
+ if (dev->ops->exit)
+ dev->ops->exit(dev);
+
+ dev->ops = NULL;
+ }
+
+ memset(dev->image_path, 0, sizeof(dev->image_path));
+
+ cdrom_insert(id);
+}
+
/* The mechanics of ejecting a CD-ROM from a drive. */
void
cdrom_eject(uint8_t id)
@@ -2028,13 +2047,7 @@ cdrom_eject(uint8_t id)
return;
}
- strcpy(dev->prev_image_path, dev->image_path);
-
- dev->ops->exit(dev);
- dev->ops = NULL;
- memset(dev->image_path, 0, sizeof(dev->image_path));
-
- cdrom_insert(id);
+ cdrom_exit(id);
plat_cdrom_ui_update(id, 0);
diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c
index 2203674cdb..113d426c6c 100644
--- a/src/cdrom/cdrom_image.c
+++ b/src/cdrom/cdrom_image.c
@@ -294,7 +294,6 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
dev->cd_status = CD_STATUS_DATA_ONLY;
else
dev->cd_status = CD_STATUS_STOPPED;
- dev->is_dir = (i == 3);
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = image_get_capacity(dev);
diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c
index 482769799d..7dcde1cdb6 100644
--- a/src/cdrom/cdrom_image_backend.c
+++ b/src/cdrom/cdrom_image_backend.c
@@ -14,10 +14,12 @@
* Authors: Miran Grca,
* Fred N. van Kempen,
* The DOSBox Team,
+ * Cacodemon345
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2002-2020 The DOSBox Team.
+ * Copyright 2024 Cacodemon345.
*/
#define __STDC_FORMAT_MACROS
#include
@@ -40,6 +42,8 @@
#include <86box/plat.h>
#include <86box/cdrom_image_backend.h>
+#include
+
#define CDROM_BCD(x) (((x) % 10) | (((x) / 10) << 4))
#define MAX_LINE_LENGTH 512
@@ -66,41 +70,142 @@ cdrom_image_backend_log(const char *fmt, ...)
# define cdrom_image_backend_log(fmt, ...)
#endif
+typedef struct audio_file_t {
+ SNDFILE *file;
+ SF_INFO info;
+} audio_file_t;
+
+/* Audio file functions */
+static int
+audio_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
+{
+ track_file_t *tf = (track_file_t *) priv;
+ audio_file_t *audio = (audio_file_t *) tf->priv;
+ uint64_t samples_seek = seek / 4;
+ uint64_t samples_count = count / 4;
+
+ if ((seek & 3) || (count & 3)) {
+ cdrom_image_backend_log("CD Audio file: Reading on non-4-aligned boundaries.\n");
+ }
+
+ sf_count_t res = sf_seek(audio->file, samples_seek, SEEK_SET);
+
+ if (res == -1)
+ return 0;
+
+ return !!sf_readf_short(audio->file, (short *) buffer, samples_count);
+}
+
+static uint64_t
+audio_get_length(void *priv)
+{
+ track_file_t *tf = (track_file_t *) priv;
+ audio_file_t *audio = (audio_file_t *) tf->priv;
+
+ /* Assume 16-bit audio, 2 channel. */
+ return audio->info.frames * 4ull;
+}
+
+static void
+audio_close(void *priv)
+{
+ track_file_t *tf = (track_file_t *) priv;
+ audio_file_t *audio = (audio_file_t *) tf->priv;
+
+ memset(tf->fn, 0x00, sizeof(tf->fn));
+ if (audio && audio->file)
+ sf_close(audio->file);
+ free(audio);
+ free(tf);
+}
+
+static track_file_t *
+audio_init(const char *filename, int *error)
+{
+ track_file_t *tf = (track_file_t *) calloc(sizeof(track_file_t), 1);
+ audio_file_t *audio = (audio_file_t *) calloc(sizeof(audio_file_t), 1);
+#ifdef _WIN32
+ wchar_t filename_w[4096];
+#endif
+
+ if (tf == NULL || audio == NULL) {
+ goto cleanup_error;
+ }
+
+ memset(tf->fn, 0x00, sizeof(tf->fn));
+ strncpy(tf->fn, filename, sizeof(tf->fn) - 1);
+#ifdef _WIN32
+ mbstowcs(filename_w, filename, 4096);
+ audio->file = sf_wchar_open(filename_w, SFM_READ, &audio->info);
+#else
+ audio->file = sf_open(filename, SFM_READ, &audio->info);
+#endif
+
+ if (!audio->file) {
+ cdrom_image_backend_log("Audio file open error!");
+ goto cleanup_error;
+ }
+
+ if (audio->info.channels != 2 || audio->info.samplerate != 44100 || !audio->info.seekable) {
+ cdrom_image_backend_log("Audio file not seekable or in non-CD format!");
+ sf_close(audio->file);
+ goto cleanup_error;
+ }
+
+ *error = 0;
+ tf->priv = audio;
+ tf->fp = NULL;
+ tf->close = audio_close;
+ tf->get_length = audio_get_length;
+ tf->read = audio_read;
+ return tf;
+cleanup_error:
+ free(tf);
+ free(audio);
+ *error = 1;
+ return NULL;
+}
+
/* Binary file functions. */
static int
bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
{
- track_file_t *tf;
-
- cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n",
- tf->fp, seek, count);
+ track_file_t *tf = NULL;
if ((tf = (track_file_t *) priv)->fp == NULL)
return 0;
+ cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu)\n",
+ tf->fp, seek, count);
+
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
-#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
-#endif
+
return 0;
}
if (fread(buffer, count, 1, tf->fp) != 1) {
-#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
-#endif
+
return 0;
}
+ if (UNLIKELY(tf->motorola)) {
+ for (uint64_t i = 0; i < count; i += 2) {
+ uint8_t buffer0 = buffer[i];
+ uint8_t buffer1 = buffer[i + 1];
+ buffer[i] = buffer1;
+ buffer[i + 1] = buffer0;
+ }
+ }
+
return 1;
}
static uint64_t
bin_get_length(void *priv)
{
- track_file_t *tf;
-
- cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp);
+ track_file_t *tf = NULL;
if ((tf = (track_file_t *) priv)->fp == NULL)
return 0;
@@ -133,7 +238,7 @@ bin_close(void *priv)
static track_file_t *
bin_init(const char *filename, int *error)
{
- track_file_t *tf = (track_file_t *) malloc(sizeof(track_file_t));
+ track_file_t *tf = (track_file_t *) calloc(1, sizeof(track_file_t));
struct stat stats;
if (tf == NULL) {
@@ -279,12 +384,11 @@ int
cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
{
const track_t *trk = &cdi->tracks[track - 1];
+ const int pos = trk->start + 150;
if ((track < 1) || (track > cdi->tracks_num))
return 0;
- const int pos = trk->start + 150;
-
FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr);
*track_num = trk->track_number;
@@ -360,20 +464,20 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
{
const int track = cdi_get_track(cdi, sector) - 1;
const uint64_t sect = (uint64_t) sector;
- int raw_size;
- int cooked_size;
- uint64_t offset;
- int m = 0;
- int s = 0;
- int f = 0;
+ int raw_size;
+ int cooked_size;
+ uint64_t offset;
+ int m = 0;
+ int s = 0;
+ int f = 0;
if (track < 0)
return 0;
- const track_t *trk = &cdi->tracks[track];
- const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
+ const track_t *trk = &cdi->tracks[track];
+ const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
- const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size);
+ const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size);
if (track_is_raw)
raw_size = trk->sector_size;
@@ -420,13 +524,13 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
int
cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num)
{
- int success = 1;
+ int success = 1;
/* TODO: This fails to account for Mode 2. Shouldn't we have a function
to get sector size? */
- const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
- const uint32_t buf_len = num * sector_size;
- uint8_t *buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t));
+ const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
+ const uint32_t buf_len = num * sector_size;
+ uint8_t *buf = (uint8_t *) calloc(1, buf_len * sizeof(uint8_t));
for (uint32_t i = 0; i < num; i++) {
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
@@ -434,9 +538,7 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
break;
/* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an
audio track. */
- if (raw && (sector < cdi->tracks[0].length) &&
- !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) &&
- *(uint64_t *) &(buf[(i * sector_size) + 2068]))
+ if (raw && (sector < cdi->tracks[0].length) && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[(i * sector_size) + 2068]))
return 0;
}
@@ -509,11 +611,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form)
uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */
if (sector_size == RAW_SECTOR_SIZE) {
- if (!mode2 || (form == 0))
- seek += 16;
- else
+ if (mode2 && (form > 0))
seek += 24;
- }
+ else
+ seek += 16;
+ } else if (form > 0)
+ seek += 8;
file->read(file, pvd, seek, COOKED_SECTOR_SIZE);
@@ -537,75 +640,93 @@ cdi_track_push_back(cd_img_t *cdi, track_t *trk)
}
int
-cdi_load_iso(cd_img_t *cdi, const char *filename)
+cdi_get_iso_track(cd_img_t *cdi, track_t *trk, const char *filename)
{
- int error;
- int ret = 2;
- track_t trk;
-
- cdi->tracks = NULL;
- cdi->tracks_num = 0;
-
- memset(&trk, 0, sizeof(track_t));
+ int error = 0;
+ int ret = 2;
+ memset(trk, 0, sizeof(track_t));
/* Data track (shouldn't there be a lead in track?). */
- trk.file = bin_init(filename, &error);
+ trk->file = bin_init(filename, &error);
if (error) {
- if ((trk.file != NULL) && (trk.file->close != NULL))
- trk.file->close(trk.file);
- ret = 3;
- trk.file = viso_init(filename, &error);
+ if ((trk->file != NULL) && (trk->file->close != NULL))
+ trk->file->close(trk->file);
+ ret = 3;
+ trk->file = viso_init(filename, &error);
if (error) {
- if ((trk.file != NULL) && (trk.file->close != NULL))
- trk.file->close(trk.file);
+ if ((trk->file != NULL) && (trk->file->close != NULL))
+ trk->file->close(trk->file);
return 0;
}
}
- trk.number = 1;
- trk.track_number = 1;
- trk.attr = DATA_TRACK;
+ trk->number = 1;
+ trk->track_number = 1;
+ trk->attr = DATA_TRACK;
/* Try to detect ISO type. */
- trk.form = 0;
- trk.mode2 = 0;
-
- if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0))
- trk.sector_size = RAW_SECTOR_SIZE;
- else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) {
- trk.sector_size = 2336;
- trk.mode2 = 1;
- } else if (cdi_can_read_pvd(trk.file, 2324, 1, 2)) {
- trk.sector_size = 2324;
- trk.mode2 = 1;
- trk.form = 2;
- } else if (cdi_can_read_pvd(trk.file, 2328, 1, 2)) {
- trk.sector_size = 2328;
- trk.mode2 = 1;
- trk.form = 2;
- } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) {
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.mode2 = 1;
- } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 1)) {
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.mode2 = 1;
- trk.form = 1;
+ trk->form = 0;
+ trk->mode2 = 0;
+
+ if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 0, 0))
+ trk->sector_size = RAW_SECTOR_SIZE;
+ else if (cdi_can_read_pvd(trk->file, 2336, 1, 0)) {
+ trk->sector_size = 2336;
+ trk->mode2 = 1;
+ } else if (cdi_can_read_pvd(trk->file, 2324, 1, 2)) {
+ trk->sector_size = 2324;
+ trk->mode2 = 1;
+ trk->form = 2;
+ trk->noskip = 1;
+ } else if (cdi_can_read_pvd(trk->file, 2328, 1, 2)) {
+ trk->sector_size = 2328;
+ trk->mode2 = 1;
+ trk->form = 2;
+ trk->noskip = 1;
+ } else if (cdi_can_read_pvd(trk->file, 2336, 1, 1)) {
+ trk->sector_size = 2336;
+ trk->mode2 = 1;
+ trk->form = 1;
+ trk->skip = 8;
+ } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 0)) {
+ trk->sector_size = RAW_SECTOR_SIZE;
+ trk->mode2 = 1;
+ } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 1)) {
+ trk->sector_size = RAW_SECTOR_SIZE;
+ trk->mode2 = 1;
+ trk->form = 1;
} else {
/* We use 2048 mode 1 as the default. */
- trk.sector_size = COOKED_SECTOR_SIZE;
+ trk->sector_size = COOKED_SECTOR_SIZE;
}
- trk.length = trk.file->get_length(trk.file) / trk.sector_size;
- cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk.length, trk.sector_size);
- cdi_track_push_back(cdi, &trk);
+ trk->length = trk->file->get_length(trk->file) / trk->sector_size;
+ cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk->length, trk->sector_size);
+ return ret;
+}
- /* Lead out track. */
- trk.number = 2;
- trk.track_number = 0xAA;
- trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */
- trk.start = trk.length;
- trk.length = 0;
- trk.file = NULL;
- cdi_track_push_back(cdi, &trk);
+int
+cdi_load_iso(cd_img_t *cdi, const char *filename)
+{
+ int ret = 2;
+ track_t trk = { 0 };
+
+ cdi->tracks = NULL;
+ cdi->tracks_num = 0;
+
+ ret = cdi_get_iso_track(cdi, &trk, filename);
+
+ if (ret >= 1) {
+ cdi_track_push_back(cdi, &trk);
+
+ /* Lead out track. */
+ trk.number = 2;
+ trk.track_number = 0xAA;
+ trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */
+ trk.start = trk.length;
+ trk.length = 0;
+ trk.file = NULL;
+ cdi_track_push_back(cdi, &trk);
+ }
return ret;
}
@@ -696,9 +817,9 @@ static int
cdi_cue_get_frame(uint64_t *frames, char **line)
{
char temp[128];
- int min;
- int sec;
- int fr;
+ int min = 0;
+ int sec = 0;
+ int fr = 0;
int success;
success = cdi_cue_get_buffer(temp, line, 0);
@@ -759,6 +880,8 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
if (cur->number != 1)
return 0;
cur->skip = skip * cur->sector_size;
+ if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip)
+ cur->skip += 8;
cur->start += cur_pregap;
*total_pregap = cur_pregap;
cdi_track_push_back(cdi, cur);
@@ -774,13 +897,15 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
cur->start += *total_pregap;
} else {
const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip);
- prev->length = temp / ((uint64_t) prev->sector_size);
+ prev->length = temp / ((uint64_t) prev->sector_size);
if ((temp % prev->sector_size) != 0)
prev->length++;
/* Padding. */
cur->start += prev->start + prev->length + cur_pregap;
cur->skip = skip * cur->sector_size;
+ if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip)
+ cur->skip += 8;
*shift += prev->start + prev->length;
*total_pregap = cur_pregap;
}
@@ -803,12 +928,13 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
{
track_t trk;
char pathname[MAX_FILENAME_LENGTH];
- uint64_t shift = 0ULL;
- uint64_t prestart = 0ULL;
- uint64_t cur_pregap = 0ULL;
+ uint64_t shift = 0ULL;
+ uint64_t prestart = 0ULL;
+ uint64_t cur_pregap = 0ULL;
uint64_t total_pregap = 0ULL;
- uint64_t frame = 0ULL;
+ uint64_t frame = 0ULL;
uint64_t index;
+ int iso_file_used = 0;
int success;
int error;
int can_add_track = 0;
@@ -864,81 +990,97 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
if (!success)
break;
- trk.start = 0;
- trk.skip = 0;
- cur_pregap = 0;
- prestart = 0;
-
- trk.number = cdi_cue_get_number(&line);
- trk.track_number = trk.number;
- success = cdi_cue_get_keyword(&type, &line);
- if (!success)
- break;
+ if (iso_file_used) {
+ /* We don't alter anything of the detected track type with the one specified in the CUE file, except its numbers. */
+ cur_pregap = 0;
+ prestart = 0;
- trk.form = 0;
- trk.mode2 = 0;
-
- trk.pre = 0;
-
- if (!strcmp(type, "AUDIO")) {
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.attr = AUDIO_TRACK;
- } else if (!strcmp(type, "MODE1/2048")) {
- trk.sector_size = COOKED_SECTOR_SIZE;
- trk.attr = DATA_TRACK;
- } else if (!strcmp(type, "MODE1/2352")) {
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.attr = DATA_TRACK;
- } else if (!strcmp(type, "MODE1/2448")) {
- trk.sector_size = 2448;
- trk.attr = DATA_TRACK;
- } else if (!strcmp(type, "MODE2/2048")) {
- trk.form = 1;
- trk.sector_size = COOKED_SECTOR_SIZE;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "MODE2/2324")) {
- trk.form = 2;
- trk.sector_size = 2324;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "MODE2/2328")) {
- trk.form = 2;
- trk.sector_size = 2328;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "MODE2/2336")) {
- trk.sector_size = 2336;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "MODE2/2352")) {
- /* Assume this is XA Mode 2 Form 1. */
- trk.form = 1;
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "MODE2/2448")) {
- /* Assume this is XA Mode 2 Form 1. */
- trk.form = 1;
- trk.sector_size = 2448;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "CDG/2448")) {
- trk.sector_size = 2448;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "CDI/2336")) {
- trk.sector_size = 2336;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else if (!strcmp(type, "CDI/2352")) {
- trk.sector_size = RAW_SECTOR_SIZE;
- trk.attr = DATA_TRACK;
- trk.mode2 = 1;
- } else
- success = 0;
+ trk.number = cdi_cue_get_number(&line);
+ trk.track_number = trk.number;
+ success = cdi_cue_get_keyword(&type, &line);
+ if (!success)
+ break;
+ can_add_track = 1;
+
+ iso_file_used = 0;
+ } else {
+ trk.start = 0;
+ trk.skip = 0;
+ cur_pregap = 0;
+ prestart = 0;
+
+ trk.number = cdi_cue_get_number(&line);
+ trk.track_number = trk.number;
+ success = cdi_cue_get_keyword(&type, &line);
+ if (!success)
+ break;
- can_add_track = 1;
+ trk.form = 0;
+ trk.mode2 = 0;
+
+ trk.pre = 0;
+
+ if (!strcmp(type, "AUDIO")) {
+ trk.sector_size = RAW_SECTOR_SIZE;
+ trk.attr = AUDIO_TRACK;
+ } else if (!strcmp(type, "MODE1/2048")) {
+ trk.sector_size = COOKED_SECTOR_SIZE;
+ trk.attr = DATA_TRACK;
+ } else if (!strcmp(type, "MODE1/2352")) {
+ trk.sector_size = RAW_SECTOR_SIZE;
+ trk.attr = DATA_TRACK;
+ } else if (!strcmp(type, "MODE1/2448")) {
+ trk.sector_size = 2448;
+ trk.attr = DATA_TRACK;
+ } else if (!strcmp(type, "MODE2/2048")) {
+ trk.form = 1;
+ trk.sector_size = COOKED_SECTOR_SIZE;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "MODE2/2324")) {
+ trk.form = 2;
+ trk.sector_size = 2324;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "MODE2/2328")) {
+ trk.form = 2;
+ trk.sector_size = 2328;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "MODE2/2336")) {
+ trk.form = 1;
+ trk.sector_size = 2336;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "MODE2/2352")) {
+ /* Assume this is XA Mode 2 Form 1. */
+ trk.form = 1;
+ trk.sector_size = RAW_SECTOR_SIZE;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "MODE2/2448")) {
+ /* Assume this is XA Mode 2 Form 1. */
+ trk.form = 1;
+ trk.sector_size = 2448;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "CDG/2448")) {
+ trk.sector_size = 2448;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "CDI/2336")) {
+ trk.sector_size = 2336;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else if (!strcmp(type, "CDI/2352")) {
+ trk.sector_size = RAW_SECTOR_SIZE;
+ trk.attr = DATA_TRACK;
+ trk.mode2 = 1;
+ } else
+ success = 0;
+
+ can_add_track = 1;
+ }
} else if (!strcmp(command, "INDEX")) {
index = cdi_cue_get_number(&line);
success = cdi_cue_get_frame(&frame, &line);
@@ -957,8 +1099,8 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
break;
}
} else if (!strcmp(command, "FILE")) {
- char filename[MAX_FILENAME_LENGTH];
- char ansi[MAX_FILENAME_LENGTH];
+ char filename[MAX_FILENAME_LENGTH];
+ char ansi[MAX_FILENAME_LENGTH];
if (can_add_track)
success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap);
@@ -981,15 +1123,41 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
trk.file = NULL;
error = 1;
- if (!strcmp(type, "BINARY")) {
- path_append_filename(filename, pathname, ansi);
- trk.file = track_file_init(filename, &error);
+ if (!strcmp(type, "BINARY") || !strcmp(type, "MOTOROLA")) {
+ int fn_len = 0;
+ if (!path_abs(ansi)) {
+ path_append_filename(filename, pathname, ansi);
+ } else {
+ strcpy(filename, ansi);
+ }
+ fn_len = strlen(filename);
+ if ((tolower((int) filename[fn_len - 1]) == 'o'
+ && tolower((int) filename[fn_len - 2]) == 's'
+ && tolower((int) filename[fn_len - 3]) == 'i'
+ && filename[fn_len - 4] == '.')
+ || plat_dir_check(filename)) {
+ error = !cdi_get_iso_track(cdi, &trk, filename);
+ if (!error) {
+ iso_file_used = 1;
+ }
+ } else
+ trk.file = track_file_init(filename, &error);
+
+ if (trk.file) {
+ trk.file->motorola = !strcmp(type, "MOTOROLA");
+ }
+ } else if (!strcmp(type, "WAVE") || !strcmp(type, "AIFF") || !strcmp(type, "MP3")) {
+ if (!path_abs(ansi)) {
+ path_append_filename(filename, pathname, ansi);
+ } else {
+ strcpy(filename, ansi);
+ }
+ trk.file = audio_init(filename, &error);
}
if (error) {
-#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
- cdrom_image_backend_log("CUE: cannot open fille '%s' in cue sheet!\n",
+ cdrom_image_backend_log("CUE: cannot open file '%s' in cue sheet!\n",
filename);
-#endif
+
if (trk.file != NULL) {
trk.file->close(trk.file);
trk.file = NULL;
@@ -1004,9 +1172,8 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
/* Ignored commands. */
success = 1;
} else {
-#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command);
-#endif
+
success = 0;
}
@@ -1056,7 +1223,7 @@ cdi_has_audio_track(cd_img_t *cdi)
if ((cdi == NULL) || (cdi->tracks == NULL))
return 0;
- /* Audio track has attribute 0x14. */
+ /* Audio track has attribute 0x10. */
for (int i = 0; i < cdi->tracks_num; i++) {
if (cdi->tracks[i].attr == AUDIO_TRACK)
return 1;
diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c
index 7ed68cd86c..90bd83cf78 100644
--- a/src/cdrom/cdrom_image_viso.c
+++ b/src/cdrom/cdrom_image_viso.c
@@ -46,28 +46,35 @@
# define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
#endif
-#define VISO_SKIP(p, n) \
- { \
- memset(p, 0x00, n); \
- p += n; \
+#ifdef _WIN32
+# define stat _stat64
+typedef struct __stat64 stat_t;
+#else
+typedef struct stat stat_t;
+#endif
+
+#define VISO_SKIP(p, n) \
+ { \
+ memset((p), 0x00, (n)); \
+ (p) += (n); \
}
#define VISO_TIME_VALID(t) ((t) > 0)
/* ISO 9660 defines "both endian" data formats, which
are stored as little endian followed by big endian. */
-#define VISO_LBE_16(p, x) \
- { \
- *((uint16_t *) p) = cpu_to_le16(x); \
- p += 2; \
- *((uint16_t *) p) = cpu_to_be16(x); \
- p += 2; \
+#define VISO_LBE_16(p, x) \
+ { \
+ *((uint16_t *) (p)) = cpu_to_le16((x)); \
+ (p) += 2; \
+ *((uint16_t *) (p)) = cpu_to_be16((x)); \
+ (p) += 2; \
}
-#define VISO_LBE_32(p, x) \
- { \
- *((uint32_t *) p) = cpu_to_le32(x); \
- p += 4; \
- *((uint32_t *) p) = cpu_to_be32(x); \
- p += 4; \
+#define VISO_LBE_32(p, x) \
+ { \
+ *((uint32_t *) (p)) = cpu_to_le32((x)); \
+ (p) += 4; \
+ *((uint32_t *) (p)) = cpu_to_be32((x)); \
+ (p) += 4; \
}
#define VISO_SECTOR_SIZE COOKED_SECTOR_SIZE
@@ -106,7 +113,7 @@ typedef struct _viso_entry_ {
};
uint16_t pt_idx;
- struct stat stats;
+ stat_t stats;
struct _viso_entry_ *parent, *next, *next_dir, *first_child;
@@ -496,10 +503,6 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type)
*p++ = 0; /* extended attribute length */
VISO_SKIP(p, 8); /* sector offset */
VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */
-#ifdef _WIN32
- if (entry->stats.st_mtime < 0)
- pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path);
-#endif
p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
@@ -671,9 +674,9 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
/* Handle reads in a sector by sector basis. */
while (count > 0) {
/* Determine the current sector, offset and remainder. */
- uint32_t sector = seek / viso->sector_size;
- uint32_t sector_offset = seek % viso->sector_size;
- uint32_t sector_remain = MIN(count, viso->sector_size - sector_offset);
+ size_t sector = seek / viso->sector_size;
+ size_t sector_offset = seek % viso->sector_size;
+ size_t sector_remain = MIN(count, viso->sector_size - sector_offset);
/* Handle sector. */
if (sector < viso->metadata_sectors) {
@@ -830,7 +833,7 @@ viso_init(const char *dirname, int *error)
strcpy(dir->path, dirname);
if (stat(dirname, &dir->stats) != 0) {
/* Use a blank structure if stat failed. */
- memset(&dir->stats, 0x00, sizeof(struct stat));
+ memset(&dir->stats, 0x00, sizeof(stat_t));
}
if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */
goto end;
@@ -879,7 +882,7 @@ viso_init(const char *dirname, int *error)
/* Stat the current directory or parent directory. */
if (stat(children_count ? dir->parent->path : dir->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
- memset(&entry->stats, 0x00, sizeof(struct stat));
+ memset(&entry->stats, 0x00, sizeof(stat_t));
}
/* Set basename. */
@@ -909,7 +912,7 @@ viso_init(const char *dirname, int *error)
/* Stat this child. */
if (stat(entry->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
- memset(&entry->stats, 0x00, sizeof(struct stat));
+ memset(&entry->stats, 0x00, sizeof(stat_t));
}
/* Handle file size and El Torito boot code. */
@@ -1432,7 +1435,7 @@ viso_init(const char *dirname, int *error)
/* Allocate entry map for sector->file lookups. */
size_t orig_sector_size = viso->sector_size;
while (1) {
- cdrom_image_viso_log("VISO: Allocating entry map for %d %d-byte sectors\n", viso->entry_map_size, viso->sector_size);
+ cdrom_image_viso_log("VISO: Allocating entry map for %zu %zu-byte sectors\n", viso->entry_map_size, viso->sector_size);
viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *));
if (viso->entry_map) {
/* Successfully allocated. */
@@ -1444,7 +1447,7 @@ viso_init(const char *dirname, int *error)
/* If we don't have enough memory, double the sector size. */
viso->sector_size *= 2;
- if (viso->sector_size == 0) /* give up if sectors become too large */
+ if ((viso->sector_size < VISO_SECTOR_SIZE) || (viso->sector_size > (1 << 30))) /* give up if sectors become too large */
goto end;
/* Go through files, recalculating the entry map size. */
@@ -1515,10 +1518,10 @@ viso_init(const char *dirname, int *error)
entry->data_offset = ((uint64_t) viso->all_sectors) * viso->sector_size;
/* Determine how many sectors this file will take. */
- uint32_t size = entry->stats.st_size / viso->sector_size;
+ size_t size = entry->stats.st_size / viso->sector_size;
if (entry->stats.st_size % viso->sector_size)
size++; /* round up to the next sector */
- cdrom_image_viso_log("[%08X] %s => %" PRIu32 " + %" PRIu32 " sectors\n", entry, entry->path, viso->all_sectors, size);
+ cdrom_image_viso_log("[%08X] %s => %zu + %zu sectors\n", entry, entry->path, viso->all_sectors, size);
/* Allocate sectors to this file. */
viso->all_sectors += size;
@@ -1537,13 +1540,13 @@ viso_init(const char *dirname, int *error)
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp);
/* Metadata processing is finished, read it back to memory. */
- cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
+ cdrom_image_viso_log("VISO: Reading back %zu %zu-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size);
if (!viso->metadata)
goto end;
fseeko64(viso->tf.fp, 0, SEEK_SET);
- uint64_t metadata_size = viso->metadata_sectors * viso->sector_size;
- uint64_t metadata_remain = metadata_size;
+ size_t metadata_size = viso->metadata_sectors * viso->sector_size;
+ size_t metadata_remain = metadata_size;
while (metadata_remain > 0)
metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.fp);
diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c
index a204fad0f4..13df2d965c 100644
--- a/src/cdrom/cdrom_ioctl.c
+++ b/src/cdrom/cdrom_ioctl.c
@@ -254,7 +254,6 @@ cdrom_ioctl_open(cdrom_t *dev, const char *drv)
/* All good, reset state. */
dev->cd_status = CD_STATUS_STOPPED;
- dev->is_dir = 0;
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = ioctl_get_capacity(dev);
diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt
index 0406ea0b89..6018dd0453 100644
--- a/src/chipset/CMakeLists.txt
+++ b/src/chipset/CMakeLists.txt
@@ -9,20 +9,80 @@
# CMake build script.
#
# Authors: David Hrdlička,
+# Jasmine Iwanek,
#
# Copyright 2020-2021 David Hrdlička.
+# Copyright 2024 Jasmine Iwanek.
#
-add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
- ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
- compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
- intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
- opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
- sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c
- sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c
- sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c
- via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c
- umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
+add_library(chipset OBJECT
+ 82c100.c
+ acc2168.c
+ cs8230.c
+ ali1429.c
+ ali1435.c
+ ali1489.c
+ ali1531.c
+ ali1541.c
+ ali1543.c
+ ali1621.c
+ ali6117.c
+ 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
+ opti499.c
+ opti602.c
+ opti822.c
+ opti895.c
+ opti5x7.c
+ scamp.c
+ scat.c
+ sis_85c310.c
+ sis_85c4xx.c
+ sis_85c496.c
+ sis_85c50x.c
+ sis_5511.c
+ sis_5571.c
+ sis_5581.c
+ sis_5591.c
+ sis_5600.c
+ sis_5511_h2p.c
+ sis_5571_h2p.c
+ sis_5581_h2p.c
+ sis_5591_h2p.c
+ sis_5600_h2p.c
+ sis_5513_p2i.c
+ sis_5513_ide.c
+ sis_5572_usb.c
+ sis_5595_pmu.c
+ sis_55xx.c
+ via_vt82c49x.c
+ via_vt82c505.c
+ gc100.c
+ stpc.c
+ umc_8886.c
+ umc_hb4.c
+ umc_8890.c
+ via_apollo.c
+ via_pipc.c
+ vl82c480.c
+ wd76c10.c
+)
if(OLIVETTI)
target_sources(chipset PRIVATE olivetti_eva.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/chipset/compaq_386.c b/src/chipset/compaq_386.c
index 7d55bc5a5d..8c241e0871 100644
--- a/src/chipset/compaq_386.c
+++ b/src/chipset/compaq_386.c
@@ -37,6 +37,7 @@
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
+#include <86box/chipset.h>
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
#define RAM_DIAG_L_BASE_MEM_INV 0x10
@@ -746,6 +747,23 @@ compaq_386_init(UNUSED(const device_t *info))
return dev;
}
+static void
+compaq_genoa_outw(uint16_t port, uint16_t val, void *priv)
+{
+ if (port == 0x0c02)
+ cpq_write_regs(0x80c00000, val, priv);
+}
+
+static void *
+compaq_genoa_init(UNUSED(const device_t *info))
+{
+ void *cpq = device_add(&compaq_386_device);
+
+ io_sethandler(0x0c02, 2, NULL, NULL, NULL, NULL, compaq_genoa_outw, NULL, cpq);
+
+ return ram;
+}
+
const device_t compaq_386_device = {
.name = "Compaq 386 Memory Control",
.internal_name = "compaq_386",
@@ -759,3 +777,17 @@ const device_t compaq_386_device = {
.force_redraw = NULL,
.config = NULL
};
+
+const device_t compaq_genoa_device = {
+ .name = "Compaq Genoa Memory Control",
+ .internal_name = "compaq_genoa",
+ .flags = 0,
+ .local = 0,
+ .init = compaq_genoa_init,
+ .close = NULL,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c
index 859cfc5b00..1f379176a3 100644
--- a/src/chipset/intel_piix.c
+++ b/src/chipset/intel_piix.c
@@ -599,9 +599,9 @@ piix_write(int func, int addr, uint8_t val, void *priv)
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
if (dev->type == 3) {
if (val & 0x20)
- sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
- else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
+ else
+ sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
}
piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled");
}
diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c
index 1fa59f2f05..63976985be 100644
--- a/src/chipset/opti283.c
+++ b/src/chipset/opti283.c
@@ -31,6 +31,7 @@
#include <86box/mem.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
+#include <86box/port_92.h>
#include <86box/chipset.h>
#ifdef ENABLE_OPTI283_LOG
@@ -215,16 +216,27 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
opti283_t *dev = (opti283_t *) priv;
switch (addr) {
+ default:
+ break;
+
case 0x22:
dev->index = val;
break;
+ case 0x23:
+ if (dev->index == 0x01)
+ dev->regs[dev->index] = val;
+ break;
+
case 0x24:
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
+ default:
+ break;
+
case 0x10:
- dev->regs[dev->index] = val;
+ dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f);
break;
case 0x14:
@@ -236,13 +248,9 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
opti283_shadow_recalc(dev);
break;
-
- default:
- break;
}
- break;
- default:
+ dev->index = 0xff;
break;
}
}
@@ -250,11 +258,17 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t
opti283_read(uint16_t addr, void *priv)
{
- const opti283_t *dev = (opti283_t *) priv;
- uint8_t ret = 0xff;
+ opti283_t *dev = (opti283_t *) priv;
+ uint8_t ret = 0xff;
- if (addr == 0x24)
+ if ((addr == 0x23) && (dev->index == 0x01))
ret = dev->regs[dev->index];
+ else if (addr == 0x24) {
+ if ((dev->index >= 0x10) && (dev->index <= 0x14))
+ ret = dev->regs[dev->index];
+
+ dev->index = 0xff;
+ }
return ret;
}
@@ -274,6 +288,7 @@ opti283_init(UNUSED(const device_t *info))
memset(dev, 0x00, sizeof(opti283_t));
io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
+ io_sethandler(0x0023, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
dev->regs[0x10] = 0x3f;
@@ -296,6 +311,8 @@ opti283_init(UNUSED(const device_t *info))
opti283_shadow_recalc(dev);
+ device_add(&port_92_device);
+
return dev;
}
diff --git a/src/chipset/opti391.c b/src/chipset/opti391.c
index 03cbb2ea7a..c22c2a04b8 100644
--- a/src/chipset/opti391.c
+++ b/src/chipset/opti391.c
@@ -54,10 +54,34 @@ typedef struct mem_remapping_t {
} mem_remapping_t;
typedef struct opti391_t {
+ uint8_t type;
+ uint8_t reg_base;
+ uint8_t min_reg;
+ uint8_t max_reg;
+
+ uint16_t shadowed;
+ uint16_t old_start;
+
uint8_t index;
uint8_t regs[256];
} opti391_t;
+static void
+opti391_recalcremap(opti391_t *dev)
+{
+ if (dev->type < 2) {
+ if ((mem_size > 8192) || (dev->shadowed & 0x0ff0) ||
+ !(dev->regs[0x01] & 0x0f) || !(dev->regs[0x01] & 0x10)) {
+ mem_remap_top_ex(0, dev->old_start);
+ dev->old_start = 1024;
+ } else {
+ mem_remap_top_ex(0, dev->old_start);
+ dev->old_start = (dev->regs[0x01] & 0x0f) * 1024;
+ mem_remap_top_ex(-256, dev->old_start);
+ }
+ }
+}
+
static void
opti391_shadow_recalc(opti391_t *dev)
{
@@ -70,24 +94,25 @@ opti391_shadow_recalc(opti391_t *dev)
shadowbios = shadowbios_write = 0;
/* F0000-FFFFF */
- sh_enable = !(dev->regs[0x22] & 0x80);
+ sh_enable = (dev->regs[0x02] & 0x80);
if (sh_enable)
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
+ dev->shadowed |= 0xf000;
- sh_write_internal = (dev->regs[0x26] & 0x40);
+ sh_write_internal = (dev->regs[0x06] & 0x40);
/* D0000-EFFFF */
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if (base >= 0xe0000) {
- sh_master = (dev->regs[0x22] & 0x40);
- sh_wp = (dev->regs[0x22] & 0x10);
+ sh_master = (dev->regs[0x02] & 0x20);
+ sh_wp = (dev->regs[0x02] & 0x08);
} else {
- sh_master = (dev->regs[0x22] & 0x20);
- sh_wp = (dev->regs[0x22] & 0x08);
+ sh_master = (dev->regs[0x02] & 0x40);
+ sh_wp = (dev->regs[0x02] & 0x10);
}
- sh_enable = dev->regs[0x23] & (1 << i);
+ sh_enable = dev->regs[0x03] & (1 << i);
if (sh_master) {
if (sh_enable) {
@@ -95,22 +120,29 @@ opti391_shadow_recalc(opti391_t *dev)
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- } else if (sh_write_internal)
+ dev->shadowed |= (1 << (i + 4));
+ } else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- else
+ dev->shadowed |= (1 << (i + 4));
+ } else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
- } else if (sh_write_internal)
+ dev->shadowed &= ~(1 << (i + 4));
+ }
+ } else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- else
+ dev->shadowed |= (1 << (i + 4));
+ } else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ dev->shadowed &= ~(1 << (i + 4));
+ }
}
/* C0000-CFFFF */
- sh_master = !(dev->regs[0x26] & 0x10);
- sh_wp = (dev->regs[0x26] & 0x20);
+ sh_master = (dev->regs[0x06] & 0x10); /* OPTi 391 datasheet erratum! */
+ sh_wp = (dev->regs[0x06] & 0x20);
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
- sh_enable = dev->regs[0x26] & (1 << i);
+ sh_enable = dev->regs[0x06] & (1 << i);
if (sh_master) {
if (sh_enable) {
@@ -118,15 +150,24 @@ opti391_shadow_recalc(opti391_t *dev)
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- } else if (sh_write_internal)
+ dev->shadowed |= (1 << i);
+ } else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- else
+ dev->shadowed |= (1 << i);
+ } else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
- } else if (sh_write_internal)
+ dev->shadowed &= ~(1 << i);
+ }
+ } else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- else
+ dev->shadowed |= (1 << i);
+ } else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ dev->shadowed &= ~(1 << i);
+ }
}
+
+ opti391_recalcremap(dev);
}
static void
@@ -134,7 +175,12 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
{
opti391_t *dev = (opti391_t *) priv;
+ opti391_log("[W] %04X = %02X\n", addr, val);
+
switch (addr) {
+ default:
+ break;
+
case 0x22:
dev->index = val;
break;
@@ -142,35 +188,92 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
case 0x24:
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
- switch (dev->index) {
- case 0x20:
- dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
+ if ((dev->index <= 0x01) && (dev->type < 2)) switch (dev->index) {
+ case 0x00:
+ if (!(dev->regs[0x10] & 0x20) && (val & 0x20)) {
+ softresetx86(); /* Pulse reset! */
+ cpu_set_edx();
+ flushmmucache();
+ }
+ dev->regs[dev->index + 0x10] = val;
break;
- case 0x21:
- case 0x24:
- case 0x25:
- case 0x27:
- case 0x28:
- case 0x29:
- case 0x2a:
- case 0x2b:
- dev->regs[dev->index] = val;
+ case 0x01:
+ dev->regs[dev->index + 0x10] = val;
+ reset_on_hlt = !!(val & 0x02);
+ break;
+ } else switch (dev->index - dev->reg_base) {
+ default:
break;
- case 0x22:
- case 0x23:
- case 0x26:
- dev->regs[dev->index] = val;
- opti391_shadow_recalc(dev);
+ case 0x00:
+ if (dev->type == 2) {
+ reset_on_hlt = !!(val & 0x02);
+ if (!(dev->regs[dev->index - dev->reg_base] & 0x01) && (val & 0x01)) {
+ softresetx86(); /* Pulse reset! */
+ cpu_set_edx();
+ flushmmucache();
+ }
+ dev->regs[dev->index - dev->reg_base] =
+ (dev->regs[dev->index - dev->reg_base] & 0xc0) | (val & 0x3f);
+ }
break;
- default:
+ case 0x01:
+ dev->regs[dev->index - dev->reg_base] = val;
+ if (dev->type == 2) {
+ cpu_cache_ext_enabled = !!(dev->regs[0x01] & 0x10);
+ cpu_update_waitstates();
+ } else
+ opti391_recalcremap(dev);
+ break;
+
+ case 0x05:
+ if (dev->type == 2)
+ dev->regs[dev->index - dev->reg_base] = val & 0xf8;
+ else
+ dev->regs[dev->index - dev->reg_base] = val;
+ break;
+
+ case 0x04:
+ case 0x09:
+ case 0x0a:
+ case 0x0b:
+ dev->regs[dev->index - dev->reg_base] = val;
+ break;
+
+ case 0x07:
+ dev->regs[dev->index - dev->reg_base] = val;
+ if (dev->type < 2) {
+ mem_a20_alt = val & 0x08;
+ mem_a20_recalc();
+ }
+ break;
+ case 0x08:
+ if (dev->type == 2)
+ dev->regs[dev->index - dev->reg_base] = val & 0xe3;
+ else {
+ dev->regs[dev->index - dev->reg_base] = val;
+ cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x40);
+ cpu_update_waitstates();
+ }
+ break;
+ case 0x0c:
+ case 0x0d:
+ if (dev->type < 2)
+ dev->regs[dev->index - dev->reg_base] = val;
+ break;
+
+ case 0x02:
+ case 0x03:
+ case 0x06:
+ opti391_log("Write %02X: %02X\n", dev->index - dev->reg_base, val);
+ dev->regs[dev->index - dev->reg_base] = val;
+ opti391_shadow_recalc(dev);
break;
}
- break;
- default:
+ dev->index = 0xff;
break;
}
}
@@ -178,11 +281,19 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t
opti391_read(uint16_t addr, void *priv)
{
- const opti391_t *dev = (opti391_t *) priv;
- uint8_t ret = 0xff;
+ opti391_t *dev = (opti391_t *) priv;
+ uint8_t ret = 0xff;
- if (addr == 0x24)
- ret = dev->regs[dev->index];
+ if (addr == 0x24) {
+ if ((dev->index <= 0x01) && (dev->type < 2))
+ ret = dev->regs[dev->index + 0x10];
+ else if ((dev->index >= dev->min_reg) && (dev->index <= dev->max_reg))
+ ret = dev->regs[dev->index - dev->reg_base];
+
+ dev->index = 0xff;
+ }
+
+ opti391_log("[R] %04X = %02X\n", addr, ret);
return ret;
}
@@ -196,34 +307,98 @@ opti391_close(void *priv)
}
static void *
-opti391_init(UNUSED(const device_t *info))
+opti391_init(const device_t *info)
{
- opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t));
- memset(dev, 0x00, sizeof(opti391_t));
+ opti391_t *dev = (opti391_t *) calloc(1, sizeof(opti391_t));
io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
- dev->regs[0x21] = 0x84;
- dev->regs[0x24] = 0x07;
- dev->regs[0x25] = 0xf0;
- dev->regs[0x26] = 0x30;
- dev->regs[0x27] = 0x91;
- dev->regs[0x28] = 0x80;
- dev->regs[0x29] = 0x10;
- dev->regs[0x2a] = 0x80;
- dev->regs[0x2b] = 0x10;
+ dev->type = info->local;
+
+ if (info->local == 2) {
+ dev->reg_base = 0x20;
+ dev->min_reg = 0x20;
+ dev->max_reg = 0x2b;
+
+ dev->regs[0x02] = 0x84;
+ dev->regs[0x04] = 0x07;
+ dev->regs[0x05] = 0xf0;
+ dev->regs[0x06] = 0x30;
+ dev->regs[0x07] = 0x91;
+ dev->regs[0x08] = 0x80;
+ dev->regs[0x09] = 0x10;
+ dev->regs[0x0a] = 0x80;
+ dev->regs[0x0b] = 0x10;
+ } else {
+ dev->reg_base = 0x0f;
+ dev->min_reg = 0x10;
+ dev->max_reg = 0x1c;
+
+ dev->regs[0x01] = 0x01;
+ dev->regs[0x02] = 0xe0;
+ if (info->local == 1)
+ /* Guess due to no OPTi 48x datasheet. */
+ dev->regs[0x04] = 0x07;
+ else
+ dev->regs[0x04] = 0x77;
+ dev->regs[0x05] = 0x60;
+ dev->regs[0x06] = 0x10;
+ dev->regs[0x07] = 0x50;
+ if (info->local == 1) {
+ /* Guess due to no OPTi 48x datasheet. */
+ dev->regs[0x09] = 0x80; /* Non-Cacheable Block 1 */
+ dev->regs[0x0b] = 0x80; /* Non-Cacheable Block 2 */
+ dev->regs[0x0d] = 0x91; /* Cacheable Area */
+ } else {
+ dev->regs[0x09] = 0xe0; /* Non-Cacheable Block 1 */
+ dev->regs[0x0b] = 0x10; /* Non-Cacheable Block 2 */
+ dev->regs[0x0d] = 0x80; /* Cacheable Area */
+ }
+ dev->regs[0x0a] = 0x10;
+ dev->regs[0x0c] = 0x10;
+ }
+
+ dev->old_start = 1024;
opti391_shadow_recalc(dev);
return dev;
}
+const device_t opti381_device = {
+ .name = "OPTi 82C381",
+ .internal_name = "opti381",
+ .flags = 0,
+ .local = 0,
+ .init = opti391_init,
+ .close = opti391_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
+const device_t opti481_device = {
+ .name = "OPTi 82C481",
+ .internal_name = "opti481",
+ .flags = 0,
+ .local = 1,
+ .init = opti391_init,
+ .close = opti391_close,
+ .reset = NULL,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
const device_t opti391_device = {
.name = "OPTi 82C391",
.internal_name = "opti391",
.flags = 0,
- .local = 0,
+ .local = 2,
.init = opti391_init,
.close = opti391_close,
.reset = NULL,
diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c
index 13bc2a1245..84ef6a2020 100644
--- a/src/chipset/opti495.c
+++ b/src/chipset/opti495.c
@@ -32,6 +32,8 @@
#include <86box/chipset.h>
typedef struct opti495_t {
+ uint8_t type;
+ uint8_t max;
uint8_t idx;
uint8_t regs[256];
uint8_t scratch[2];
@@ -55,6 +57,22 @@ opti495_log(const char *fmt, ...)
# define opti495_log(fmt, ...)
#endif
+enum {
+ OPTI493 = 0,
+ OPTI495,
+ OPTI495SLC,
+ OPTI495SX,
+ OPTI495XLC,
+ TMAX
+};
+
+/* OPTi 82C493: According to The Last Byte, bit 1 of register 22h, while unused, must still be writable. */
+static uint8_t masks[TMAX][0x1c] = { { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xfb, 0x7f, 0x9f, 0xe3, 0xff, 0xe3, 0xff },
+ { 0x3a, 0x7f, 0xff, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
+ { 0x3a, 0x7f, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
+ { 0x3a, 0xff, 0xfd, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
+ { 0x3a, 0xff, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 } };
+
static void
opti495_recalc(opti495_t *dev)
{
@@ -119,16 +137,25 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
opti495_t *dev = (opti495_t *) priv;
switch (addr) {
+ default:
+ break;
+
case 0x22:
opti495_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
dev->idx = val;
break;
case 0x24:
- if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
- dev->regs[dev->idx] = val;
+ if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
opti495_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
+ dev->regs[dev->idx] = val & masks[dev->type][dev->idx - 0x20];
+ if ((dev->type == OPTI493) && (dev->idx == 0x20))
+ val |= 0x40;
+
switch (dev->idx) {
+ default:
+ break;
+
case 0x21:
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
cpu_update_waitstates();
@@ -139,36 +166,36 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
case 0x26:
opti495_recalc(dev);
break;
- default:
- break;
}
}
+
+ dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
- default:
- break;
}
}
static uint8_t
opti495_read(uint16_t addr, void *priv)
{
- uint8_t ret = 0xff;
- const opti495_t *dev = (opti495_t *) priv;
+ uint8_t ret = 0xff;
+ opti495_t *dev = (opti495_t *) priv;
switch (addr) {
case 0x22:
opti495_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
break;
case 0x24:
- if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
+ if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
ret = dev->regs[dev->idx];
opti495_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
}
+
+ dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
@@ -202,8 +229,11 @@ opti495_init(const device_t *info)
dev->scratch[0] = dev->scratch[1] = 0xff;
- if (info->local == 1) {
+ dev->type = info->local;
+
+ if (info->local >= OPTI495) {
/* 85C495 */
+ dev->max = 0x29;
dev->regs[0x20] = 0x02;
dev->regs[0x21] = 0x20;
dev->regs[0x22] = 0xe4;
@@ -214,6 +244,7 @@ opti495_init(const device_t *info)
dev->regs[0x29] = 0x10;
} else {
/* 85C493 */
+ dev->max = 0x2b;
dev->regs[0x20] = 0x40;
dev->regs[0x22] = 0x84;
dev->regs[0x24] = 0x87;
@@ -236,7 +267,7 @@ const device_t opti493_device = {
.name = "OPTi 82C493",
.internal_name = "opti493",
.flags = 0,
- .local = 0,
+ .local = OPTI493,
.init = opti495_init,
.close = opti495_close,
.reset = NULL,
@@ -250,7 +281,7 @@ const device_t opti495_device = {
.name = "OPTi 82C495",
.internal_name = "opti495",
.flags = 0,
- .local = 1,
+ .local = OPTI495XLC,
.init = opti495_init,
.close = opti495_close,
.reset = NULL,
diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c
index f8b8785590..ecadd2224d 100644
--- a/src/chipset/opti499.c
+++ b/src/chipset/opti499.c
@@ -38,6 +38,9 @@ typedef struct opti499_t {
uint8_t scratch[2];
} opti499_t;
+/* According to The Last Byte, register 2Dh bit 7 must still be writable, even if it is unused. */
+static uint8_t masks[0x0e] = { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfb, 0xff, 0x00, 0xff };
+
#ifdef ENABLE_OPTI499_LOG
int opti499_do_log = ENABLE_OPTI499_LOG;
@@ -84,7 +87,7 @@ opti499_recalc(opti499_t *dev)
shflags = MEM_READ_INTERNAL;
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
- if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
+ if (dev->regs[0x2d] & (1 << ((i >> 1) + 2)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
@@ -101,13 +104,13 @@ opti499_recalc(opti499_t *dev)
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x26] & 0x40) {
- if (dev->regs[0x2d] && (1 << (i >> 1)))
+ if (dev->regs[0x2d] & (1 << (i >> 1)))
shflags = MEM_READ_EXTANY;
else
shflags = MEM_READ_EXTERNAL;
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
- if (dev->regs[0x2d] && (1 << (i >> 1)))
+ if (dev->regs[0x2d] & (1 << (i >> 1)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
@@ -126,19 +129,25 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
+ default:
+ break;
+
case 0x22:
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
dev->idx = val;
break;
case 0x24:
- if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
- if (dev->idx == 0x20)
- dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
- else
- dev->regs[dev->idx] = val;
+ if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
+ dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
+ if (dev->idx == 0x2a)
+ dev->regs[dev->idx] |= 0x04;
+
switch (dev->idx) {
+ default:
+ break;
+
case 0x20:
reset_on_hlt = !(val & 0x02);
break;
@@ -154,20 +163,16 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
case 0x2d:
opti499_recalc(dev);
break;
-
- default:
- break;
}
}
+
+ dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
-
- default:
- break;
}
}
@@ -178,25 +183,23 @@ opti499_read(uint16_t addr, void *priv)
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
+ default:
+ break;
+
case 0x22:
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
break;
case 0x24:
- if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
- if (dev->idx == 0x2d)
- ret = dev->regs[dev->idx] & 0xbf;
- else
- ret = dev->regs[dev->idx];
+ if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
+ ret = dev->regs[dev->idx];
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
}
+ dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
ret = dev->scratch[~addr & 0x01];
break;
-
- default:
- break;
}
return ret;
@@ -226,8 +229,6 @@ opti499_reset(void *priv)
cpu_update_waitstates();
opti499_recalc(dev);
-
- free(dev);
}
static void
diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c
index 64adacde46..494fdee649 100644
--- a/src/chipset/opti5x7.c
+++ b/src/chipset/opti5x7.c
@@ -35,7 +35,7 @@
typedef struct opti5x7_t {
uint8_t idx;
uint8_t is_pci;
- uint8_t regs[16];
+ uint8_t regs[18];
} opti5x7_t;
#ifdef ENABLE_OPTI5X7_LOG
@@ -158,7 +158,7 @@ opti5x7_read(uint16_t addr, void *priv)
{
const opti5x7_t *dev = (opti5x7_t *) priv;
- return (addr == 0x24) ? dev->regs[dev->idx] : 0xff;
+ return ((addr == 0x24) && (dev->idx < sizeof(dev->regs))) ? dev->regs[dev->idx] : 0xff;
}
static void
diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c
index 77297ae950..f1878a51bd 100644
--- a/src/chipset/opti895.c
+++ b/src/chipset/opti895.c
@@ -42,6 +42,9 @@ typedef struct opti895_t {
smram_t *smram;
} opti895_t;
+static uint8_t masks[0x10] = { 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+ 0xe3, 0xff, 0xe3, 0xff, 0x00, 0xff, 0xff, 0xff };
+
#ifdef ENABLE_OPTI895_LOG
int opti895_do_log = ENABLE_OPTI895_LOG;
@@ -153,8 +156,12 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0x24:
- if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
- dev->regs[dev->idx] = val;
+ if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
+ ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
+ if (dev->idx > 0x2f)
+ dev->regs[dev->idx] = val;
+ else
+ dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
@@ -217,7 +224,8 @@ opti895_read(uint16_t addr, void *priv)
break;
case 0x24:
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
- if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
+ if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
+ ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
ret = dev->regs[dev->idx];
if (dev->idx == 0xe0)
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c
index 137ddb5cf2..2286105ce9 100644
--- a/src/chipset/sis_85c50x.c
+++ b/src/chipset/sis_85c50x.c
@@ -107,8 +107,8 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
if (dev->states[8 + i] != state) {
mem_set_mem_state_both(base, 0x00004000, state);
sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff,
- (dev->pci_conf[0x543 & (0x80 >> i)) ?
- ((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E',
+ (dev->pci_conf[0x54] & (0x80 >> i)) ?
+ ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E',
(dev->pci_conf[0x54] & (0x80 >> i)) ?
((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E');
dev->states[8 + i] = state;
diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c
index 7a049b1cbe..4242062c6a 100644
--- a/src/chipset/umc_8886.c
+++ b/src/chipset/umc_8886.c
@@ -126,19 +126,70 @@ umc_8886_ide_handler(umc_8886_t *dev)
ide_sec_disable();
if (dev->pci_conf_sb[1][0x04] & 0x01) {
- if (dev->pci_conf_sb[1][0x40] & 0x80)
+ if (dev->pci_conf_sb[1][0x41] & 0x80)
ide_pri_enable();
- if (dev->pci_conf_sb[1][0x40] & 0x40)
+ if (dev->pci_conf_sb[1][0x41] & 0x40)
ide_sec_enable();
}
}
+static void
+umc_8886_bus_recalc(umc_8886_t *dev)
+{
+ switch (dev->pci_conf_sb[0x00][0xa4] & 0x03) {
+ case 0x00:
+ cpu_set_pci_speed(cpu_busspeed / 2);
+ break;
+ case 0x01:
+ cpu_set_pci_speed(cpu_busspeed);
+ break;
+ case 0x02:
+ cpu_set_pci_speed((cpu_busspeed * 2) / 3);
+ break;
+ }
+
+ switch (dev->pci_conf_sb[0x00][0x56] & 0x03) {
+ default:
+ break;
+ case 0x00:
+ cpu_set_isa_pci_div(3);
+ break;
+ case 0x01:
+ cpu_set_isa_pci_div(4);
+ break;
+ case 0x02:
+ cpu_set_isa_pci_div(2);
+ break;
+ }
+}
+
+static void
+umc_8886_irq_recalc(umc_8886_t *dev)
+{
+ int irq_routing;
+ uint8_t *conf = dev->pci_conf_sb[0];
+
+ irq_routing = (conf[0x46] & 0x01) ? (conf[0x43] >> 4) : PCI_IRQ_DISABLED;
+ pci_set_irq_routing(PCI_INTA, irq_routing);
+ irq_routing = (conf[0x46] & 0x02) ? (conf[0x43] & 0x0f) : PCI_IRQ_DISABLED;
+ pci_set_irq_routing(PCI_INTB, irq_routing);
+
+ irq_routing = (conf[0x46] & 0x04) ? (conf[0x44] >> 4) : PCI_IRQ_DISABLED;
+ pci_set_irq_routing(PCI_INTC, irq_routing);
+ irq_routing = (conf[0x46] & 0x08) ? (conf[0x44] & 0x0f) : PCI_IRQ_DISABLED;
+ pci_set_irq_routing(PCI_INTD, irq_routing);
+
+ pci_set_irq_level(PCI_INTA, (conf[0x47] & 0x01));
+ pci_set_irq_level(PCI_INTB, (conf[0x47] & 0x02));
+ pci_set_irq_level(PCI_INTC, (conf[0x47] & 0x04));
+ pci_set_irq_level(PCI_INTD, (conf[0x47] & 0x08));
+}
+
static void
umc_8886_write(int func, int addr, uint8_t val, void *priv)
{
umc_8886_t *dev = (umc_8886_t *) priv;
- int irq_routing;
if (func <= dev->max_func)
switch (func) {
@@ -153,7 +204,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0x50 ... 0x55:
case 0x57:
case 0x70 ... 0x76:
- case 0x80 ... 0x82:
+ case 0x80 ... 0x83:
case 0x90 ... 0x92:
case 0xa0 ... 0xa1:
case 0xa5 ... 0xa8:
@@ -165,46 +216,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x43:
- dev->pci_conf_sb[func][addr] = val;
- irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) :
- PCI_IRQ_DISABLED;
- pci_set_irq_routing(PCI_INTA, irq_routing);
- irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) :
- PCI_IRQ_DISABLED;
- pci_set_irq_routing(PCI_INTB, irq_routing);
- break;
case 0x44:
- dev->pci_conf_sb[func][addr] = val;
- irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) :
- PCI_IRQ_DISABLED;
- pci_set_irq_routing(PCI_INTC, irq_routing);
- irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) :
- PCI_IRQ_DISABLED;
- pci_set_irq_routing(PCI_INTD, irq_routing);
- break;
-
case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */
case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
dev->pci_conf_sb[func][addr] = val;
+ umc_8886_irq_recalc(dev);
break;
case 0x56:
dev->pci_conf_sb[func][addr] = val;
-
- switch (val & 3) {
- case 0:
- cpu_set_isa_pci_div(3);
- break;
- case 1:
- cpu_set_isa_pci_div(4);
- break;
- case 2:
- cpu_set_isa_pci_div(2);
- break;
- default:
- break;
- }
+ umc_8886_bus_recalc(dev);
break;
case 0xa2:
@@ -225,7 +247,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0xa4:
dev->pci_conf_sb[func][addr] = val;
- cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
+ umc_8886_bus_recalc(dev);
break;
default:
@@ -248,13 +270,13 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x3c:
- case 0x41 ... 0x4b:
- case 0x54 ... 0x59:
+ case 0x40:
+ case 0x42 ... 0x59:
if (dev->ide_id == 0x673a)
dev->pci_conf_sb[func][addr] = val;
break;
- case 0x40:
+ case 0x41:
if (dev->ide_id == 0x673a) {
dev->pci_conf_sb[func][addr] = val;
umc_8886_ide_handler(dev);
@@ -300,25 +322,17 @@ umc_8886_reset(void *priv)
dev->pci_conf_sb[0][0x09] = 0x00;
dev->pci_conf_sb[0][0x0a] = 0x01;
dev->pci_conf_sb[0][0x0b] = 0x06;
+
dev->pci_conf_sb[0][0x40] = 0x01;
- dev->pci_conf_sb[0][0x41] = 0x06;
+ dev->pci_conf_sb[0][0x41] = 0x04;
dev->pci_conf_sb[0][0x42] = 0x08;
- dev->pci_conf_sb[0][0x43] = 0x00;
- dev->pci_conf_sb[0][0x44] = 0x00;
- dev->pci_conf_sb[0][0x45] = 0x04;
- dev->pci_conf_sb[0][0x46] = 0x00;
- dev->pci_conf_sb[0][0x47] = 0x40;
- dev->pci_conf_sb[0][0x50] = 0x01;
- dev->pci_conf_sb[0][0x51] = 0x03;
- dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00;
- dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00;
- dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00;
- dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00;
- dev->pci_conf_sb[0][0x82] = 0x00;
- dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00;
- dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00;
- dev->pci_conf_sb[0][0xa4] = 0x00;
- dev->pci_conf_sb[0][0xa8] = 0x20;
+ dev->pci_conf_sb[0][0x43] = 0x9a;
+ dev->pci_conf_sb[0][0x44] = 0xbc;
+ dev->pci_conf_sb[0][0x45] = 0x00;
+ dev->pci_conf_sb[0][0x46] = 0x10;
+ dev->pci_conf_sb[0][0x47] = 0x30;
+
+ dev->pci_conf_sb[0][0x51] = 0x02;
if (dev->has_ide) {
dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */
@@ -341,13 +355,15 @@ umc_8886_reset(void *priv)
dev->pci_conf_sb[1][0x21] = 0x10;
if (dev->ide_id == 0x673a) {
- dev->pci_conf_sb[1][0x40] = 0xc0;
- dev->pci_conf_sb[1][0x41] = 0x00;
+ dev->pci_conf_sb[1][0x40] = 0x00;
+ dev->pci_conf_sb[1][0x41] = 0xc0;
dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00;
dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00;
dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00;
- dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00;
- dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00;
+ dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x55;
+ dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x55;
+ dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x88;
+ dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0xaa;
dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00;
dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00;
dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00;
@@ -362,8 +378,7 @@ umc_8886_reset(void *priv)
for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
- cpu_set_isa_pci_div(3);
- cpu_set_pci_speed(cpu_busspeed / 2);
+ umc_8886_bus_recalc(dev);
}
static void
diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c
index a7ed0b880e..c1f359f261 100644
--- a/src/chipset/umc_hb4.c
+++ b/src/chipset/umc_hb4.c
@@ -136,6 +136,9 @@ hb4_log(const char *fmt, ...)
#endif
typedef struct hb4_t {
+ uint8_t idx;
+ uint8_t access_data;
+
uint8_t pci_slot;
uint8_t pci_conf[256]; /* PCI Registers */
@@ -176,7 +179,9 @@ hb4_shadow_bios_low(hb4_t *dev)
int state;
/* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */
- state = shadow_bios[dev->pci_conf[0x55] >> 6];
+ state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[dev->pci_conf[0x54] & 0x01] :
+ MEM_READ_EXTANY;
+ state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[7]) {
mem_set_mem_state_both(0xe0000, 0x10000, state);
@@ -194,8 +199,9 @@ hb4_shadow_main(hb4_t *dev)
int n = 0;
for (uint8_t i = 0; i < 6; i++) {
- state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] |
- shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
+ state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] :
+ MEM_READ_EXTANY;
+ state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[i + 1]) {
n++;
@@ -212,8 +218,9 @@ hb4_shadow_video(hb4_t *dev)
{
int state;
- state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] |
- shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
+ state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] :
+ MEM_READ_EXTANY;
+ state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[0]) {
mem_set_mem_state_both(0xc0000, 0x8000, state);
@@ -302,7 +309,7 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
hb4_shadow(dev);
break;
- case 0x56 ... 0x5b:
+ case 0x56 ... 0x5a:
case 0x5e ... 0x5f:
dev->pci_conf[addr] = val;
break;
@@ -313,10 +320,14 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
hb4_smram(dev);
break;
- case 0x61 ... 0x62:
+ case 0x61:
dev->pci_conf[addr] = val;
break;
+ case 0x62:
+ dev->pci_conf[addr] = val & 0x03;
+ break;
+
default:
break;
}
@@ -354,14 +365,16 @@ hb4_reset(void *priv)
dev->pci_conf[0x52] = 0x01;
dev->pci_conf[0x53] = 0x00;
dev->pci_conf[0x54] = 0x00;
- dev->pci_conf[0x55] = 0x00;
- dev->pci_conf[0x56] = 0x00;
- dev->pci_conf[0x57] = 0x00;
- dev->pci_conf[0x58] = 0x00;
- dev->pci_conf[0x59] = 0x00;
- dev->pci_conf[0x5a] = 0x04;
+ dev->pci_conf[0x55] = 0x40;
+ dev->pci_conf[0x56] = 0xff;
+ dev->pci_conf[0x57] = 0x0f;
+ dev->pci_conf[0x58] = 0xff;
+ dev->pci_conf[0x59] = 0x0f;
+ dev->pci_conf[0x5a] = 0x00;
+ dev->pci_conf[0x5b] = 0x2c;
dev->pci_conf[0x5c] = 0x00;
- dev->pci_conf[0x5d] = 0x20;
+ dev->pci_conf[0x5d] = 0x0f;
+ dev->pci_conf[0x5e] = 0x00;
dev->pci_conf[0x5f] = 0xff;
dev->pci_conf[0x60] = 0x00;
dev->pci_conf[0x61] = 0x00;
@@ -385,6 +398,55 @@ hb4_close(void *priv)
free(dev);
}
+static void
+ims8848_write(uint16_t addr, uint8_t val, void *priv)
+{
+ hb4_t *dev = (hb4_t *) priv;
+
+ switch (addr) {
+ case 0x22:
+ dev->idx = val;
+ break;
+ case 0x23:
+ if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
+ dev->access_data = 1;
+ break;
+ case 0x24:
+ if (dev->access_data)
+ dev->access_data = 0;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static uint8_t
+ims8848_read(uint16_t addr, void *priv)
+{
+ uint8_t ret = 0xff;
+ hb4_t *dev = (hb4_t *) priv;
+
+ switch (addr) {
+ case 0x22:
+ ret = dev->idx;
+ break;
+ case 0x23:
+ ret = (dev->idx >> 4) | (dev->idx << 4);
+ break;
+ case 0x24:
+ if (dev->access_data) {
+ ret = dev->pci_conf[dev->idx];
+ dev->access_data = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static void *
hb4_init(UNUSED(const device_t *info))
{
@@ -402,6 +464,8 @@ hb4_init(UNUSED(const device_t *info))
dev->smram_base = 0x000a0000;
hb4_reset(dev);
+ io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
+
return dev;
}
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))
diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt
index 3cb9de6cab..3d000c98d6 100644
--- a/src/codegen/CMakeLists.txt
+++ b/src/codegen/CMakeLists.txt
@@ -9,19 +9,28 @@
# CMake build script.
#
# Authors: David Hrdlička,
+# Jasmine Iwanek,
#
# Copyright 2020-2021 David Hrdlička.
+# Copyright 2024 Jasmine Iwanek.
#
if(DYNAREC)
- add_library(dynarec OBJECT codegen.c codegen_ops.c)
+ add_library(dynarec OBJECT
+ codegen.c
+ codegen_ops.c
+ )
if(ARCH STREQUAL "i386")
- target_sources(dynarec PRIVATE codegen_x86.c
- codegen_accumulate_x86.c)
+ target_sources(dynarec PRIVATE
+ codegen_x86.c
+ codegen_accumulate_x86.c
+ )
elseif(ARCH STREQUAL "x86_64")
- target_sources(dynarec PRIVATE codegen_x86-64.c
- codegen_accumulate_x86-64.c)
+ target_sources(dynarec PRIVATE
+ codegen_x86-64.c
+ codegen_accumulate_x86-64.c
+ )
else()
message(SEND_ERROR
"Dynarec is incompatible with target platform ${ARCH}")
diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h
index 6d30211a69..d020fc57fd 100644
--- a/src/codegen/codegen.h
+++ b/src/codegen/codegen.h
@@ -311,6 +311,7 @@ extern codegen_timing_t codegen_timing_686;
extern codegen_timing_t codegen_timing_486;
extern codegen_timing_t codegen_timing_winchip;
extern codegen_timing_t codegen_timing_winchip2;
+extern codegen_timing_t codegen_timing_k5;
extern codegen_timing_t codegen_timing_k6;
extern codegen_timing_t codegen_timing_p6;
diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c
index a81eef67e1..c8e258e788 100644
--- a/src/codegen/codegen_ops.c
+++ b/src/codegen/codegen_ops.c
@@ -12,6 +12,7 @@
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
+#include "x87_sf.h"
#include "x87.h"
#include "386_common.h"
#include "cpu.h"
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/codegen_x86-64.c b/src/codegen/codegen_x86-64.c
index 421f200262..9588721623 100644
--- a/src/codegen/codegen_x86-64.c
+++ b/src/codegen/codegen_x86-64.c
@@ -13,6 +13,7 @@
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c
index 456f93ae9b..74c209001b 100644
--- a/src/codegen/codegen_x86.c
+++ b/src/codegen/codegen_x86.c
@@ -51,6 +51,7 @@
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
/*ex*/
# include <86box/nmi.h>
diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt
index 038f1edd16..cee7d5cb9c 100644
--- a/src/codegen_new/CMakeLists.txt
+++ b/src/codegen_new/CMakeLists.txt
@@ -9,39 +9,71 @@
# CMake build script.
#
# Authors: David Hrdlička,
+# Jasmine Iwanek,
#
# Copyright 2020-2021 David Hrdlička.
+# Copyright 2024 Jasmine Iwanek.
#
if(DYNAREC)
- add_library(dynarec OBJECT codegen.c codegen_accumulate.c
- codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c
- codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c
- codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c
- codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c
- codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c
- codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c
- codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c
- codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c
- codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c)
+ add_library(dynarec OBJECT
+ codegen.c
+ codegen_accumulate.c
+ codegen_allocator.c
+ codegen_block.c
+ codegen_ir.c
+ codegen_ops.c
+ codegen_ops_3dnow.c
+ codegen_ops_branch.c
+ codegen_ops_arith.c
+ codegen_ops_fpu_arith.c
+ codegen_ops_fpu_constant.c
+ codegen_ops_fpu_loadstore.c
+ codegen_ops_fpu_misc.c
+ codegen_ops_helpers.c
+ codegen_ops_jump.c
+ codegen_ops_logic.c
+ codegen_ops_misc.c
+ codegen_ops_mmx_arith.c
+ codegen_ops_mmx_cmp.c
+ codegen_ops_mmx_loadstore.c
+ codegen_ops_mmx_logic.c
+ codegen_ops_mmx_pack.c
+ codegen_ops_mmx_shift.c
+ codegen_ops_mov.c
+ codegen_ops_shift.c
+ codegen_ops_stack.c
+ codegen_reg.c
+ )
if(ARCH STREQUAL "i386")
- target_sources(dynarec PRIVATE codegen_backend_x86.c
- codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c
+ target_sources(dynarec PRIVATE
+ codegen_backend_x86.c
+ codegen_backend_x86_ops.c
+ codegen_backend_x86_ops_fpu.c
codegen_backend_x86_ops_sse.c
- codegen_backend_x86_uops.c)
+ codegen_backend_x86_uops.c
+ )
elseif(ARCH STREQUAL "x86_64")
- target_sources(dynarec PRIVATE codegen_backend_x86-64.c
+ target_sources(dynarec PRIVATE
+ codegen_backend_x86-64.c
codegen_backend_x86-64_ops.c
codegen_backend_x86-64_ops_sse.c
- codegen_backend_x86-64_uops.c)
+ codegen_backend_x86-64_uops.c
+ )
elseif(ARCH STREQUAL "arm64")
- target_sources(dynarec PRIVATE codegen_backend_arm64.c
- codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c
- codegen_backend_arm64_imm.c)
+ target_sources(dynarec PRIVATE
+ codegen_backend_arm64.c
+ codegen_backend_arm64_ops.c
+ codegen_backend_arm64_uops.c
+ codegen_backend_arm64_imm.c
+ )
elseif(ARCH STREQUAL "arm")
- target_sources(dynarec PRIVATE codegen_backend_arm.c
- codegen_backend_arm_ops.c codegen_backend_arm_uops.c)
+ target_sources(dynarec PRIVATE
+ codegen_backend_arm.c
+ codegen_backend_arm_ops.c
+ codegen_backend_arm_uops.c
+ )
else()
message(SEND_ERROR
"Dynarec is incompatible with target platform ${ARCH}")
diff --git a/src/codegen_new/codegen.h b/src/codegen_new/codegen.h
index deeeb899c8..eecfa249bf 100644
--- a/src/codegen_new/codegen.h
+++ b/src/codegen_new/codegen.h
@@ -341,6 +341,7 @@ extern codegen_timing_t codegen_timing_686;
extern codegen_timing_t codegen_timing_486;
extern codegen_timing_t codegen_timing_winchip;
extern codegen_timing_t codegen_timing_winchip2;
+extern codegen_timing_t codegen_timing_k5;
extern codegen_timing_t codegen_timing_k6;
extern codegen_timing_t codegen_timing_p6;
diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c
index b1e904096c..9c480dccf6 100644
--- a/src/codegen_new/codegen_backend_arm.c
+++ b/src/codegen_new/codegen_backend_arm.c
@@ -15,6 +15,7 @@
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)
diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c
index 1eb94a9090..5c2233b635 100644
--- a/src/codegen_new/codegen_backend_arm64.c
+++ b/src/codegen_new/codegen_backend_arm64.c
@@ -15,6 +15,7 @@
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)
diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c
index 7514e1f0c3..deaf53c200 100644
--- a/src/codegen_new/codegen_backend_arm64_uops.c
+++ b/src/codegen_new/codegen_backend_arm64_uops.c
@@ -9,6 +9,7 @@
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"
@@ -648,10 +649,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 +691,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..d8c2238845 100644
--- a/src/codegen_new/codegen_backend_arm_uops.c
+++ b/src/codegen_new/codegen_backend_arm_uops.c
@@ -10,6 +10,7 @@
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"
@@ -718,9 +719,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 +759,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..46af68e751 100644
--- a/src/codegen_new/codegen_backend_x86-64_uops.c
+++ b/src/codegen_new/codegen_backend_x86-64_uops.c
@@ -9,6 +9,7 @@
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"
@@ -672,7 +673,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 +721,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..cd79b9b47e 100644
--- a/src/codegen_new/codegen_backend_x86_uops.c
+++ b/src/codegen_new/codegen_backend_x86_uops.c
@@ -10,6 +10,7 @@
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
+# include "x87_sf.h"
# include "386_common.h"
# include "codegen.h"
# include "codegen_allocator.h"
@@ -677,7 +678,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 +726,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_block.c b/src/codegen_new/codegen_block.c
index ee0a030ba9..a8ea0e06e6 100644
--- a/src/codegen_new/codegen_block.c
+++ b/src/codegen_new/codegen_block.c
@@ -12,6 +12,7 @@
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
+#include "x87_sf.h"
#include "x87.h"
#include "386_common.h"
diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c
index 3ab7be8ac9..a7b5290f4e 100644
--- a/src/codegen_new/codegen_ops_fpu_arith.c
+++ b/src/codegen_new/codegen_ops_fpu_arith.c
@@ -9,6 +9,7 @@
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_accumulate.h"
@@ -59,7 +60,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 +72,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 +83,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 +270,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 +282,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 +293,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 +329,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 +345,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 +461,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 +478,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 +601,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/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c
index 8628458687..a91d675c5d 100644
--- a/src/codegen_new/codegen_ops_fpu_constant.c
+++ b/src/codegen_new/codegen_ops_fpu_constant.c
@@ -9,6 +9,7 @@
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_accumulate.h"
diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c
index 7635063e86..12babaf49d 100644
--- a/src/codegen_new/codegen_ops_fpu_loadstore.c
+++ b/src/codegen_new/codegen_ops_fpu_loadstore.c
@@ -9,6 +9,7 @@
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_accumulate.h"
diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c
index 7865e05730..31b668488e 100644
--- a/src/codegen_new/codegen_ops_fpu_misc.c
+++ b/src/codegen_new/codegen_ops_fpu_misc.c
@@ -9,6 +9,7 @@
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_accumulate.h"
diff --git a/src/config.c b/src/config.c
index 77ec89125d..0153e20e88 100644
--- a/src/config.c
+++ b/src/config.c
@@ -431,10 +431,17 @@ load_video(void)
strcpy(p, "none");
}
free_p = 1;
+ } else if (!strcmp(p, "c&t_69000")) {
+ p = (char *) malloc((strlen("chips_69000") + 1) * sizeof(char));
+ strcpy(p, "chips_69000");
+ free_p = 1;
}
gfxcard[0] = video_get_video_from_internal_name(p);
- if (free_p)
+ if (free_p) {
free(p);
+ p = NULL;
+ free_p = 0;
+ }
}
if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) ||
@@ -452,10 +459,13 @@ load_video(void)
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
- p = ini_section_get_string(cat, "gfxcard_2", NULL);
- if (!p)
- p = "none";
- gfxcard[1] = video_get_video_from_internal_name(p);
+ // TODO
+ for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
+ p = ini_section_get_string(cat, "gfxcard_2", NULL);
+ if (!p)
+ p = "none";
+ gfxcard[i] = video_get_video_from_internal_name(p);
+ }
}
/* Load "Input Devices" section. */
@@ -551,36 +561,24 @@ load_sound(void)
char *p;
p = ini_section_get_string(cat, "sndcard", NULL);
- /* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
- if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
- p = "es1371";
if (p != NULL)
sound_card_current[0] = sound_card_get_from_internal_name(p);
else
sound_card_current[0] = 0;
p = ini_section_get_string(cat, "sndcard2", NULL);
- /* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
- if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
- p = "es1371";
if (p != NULL)
sound_card_current[1] = sound_card_get_from_internal_name(p);
else
sound_card_current[1] = 0;
p = ini_section_get_string(cat, "sndcard3", NULL);
- /* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
- if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
- p = "es1371";
if (p != NULL)
sound_card_current[2] = sound_card_get_from_internal_name(p);
else
sound_card_current[2] = 0;
p = ini_section_get_string(cat, "sndcard4", NULL);
- /* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
- if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
- p = "es1371";
if (p != NULL)
sound_card_current[3] = sound_card_get_from_internal_name(p);
else
@@ -792,10 +790,31 @@ load_storage_controllers(void)
}
p = ini_section_get_string(cat, "fdc", NULL);
+#if 1
if (p != NULL)
- fdc_type = fdc_card_get_from_internal_name(p);
+ fdc_current[0] = fdc_card_get_from_internal_name(p);
else
- fdc_type = FDC_INTERNAL;
+ fdc_current[0] = FDC_INTERNAL;
+#else
+ if (p == NULL) {
+ if (machine_has_flags(machine, MACHINE_FDC)) {
+ p = (char *) malloc((strlen("internal") + 1) * sizeof(char));
+ strcpy(p, "internal");
+ } else {
+ p = (char *) malloc((strlen("none") + 1) * sizeof(char));
+ strcpy(p, "none");
+ }
+ free_p = 1;
+ }
+
+ fdc_current[0] = fdc_card_get_from_internal_name(p);
+
+ if (free_p) {
+ free(p);
+ p = NULL;
+ free_p = 0;
+ }
+#endif
p = ini_section_get_string(cat, "hdc", NULL);
if (p == NULL) {
@@ -810,15 +829,15 @@ load_storage_controllers(void)
}
/* Migrate renamed and merged cards. */
if (!strcmp(p, "xtide_plus")) {
- hdc_current = hdc_get_from_internal_name("xtide");
+ hdc_current[0] = hdc_get_from_internal_name("xtide");
migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE");
ini_section_set_string(migration_cat, "bios", "xt_plus");
} else if (!strcmp(p, "xtide_at_386")) {
- hdc_current = hdc_get_from_internal_name("xtide_at");
+ hdc_current[0] = hdc_get_from_internal_name("xtide_at");
migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE");
ini_section_set_string(migration_cat, "bios", "at_386");
} else
- hdc_current = hdc_get_from_internal_name(p);
+ hdc_current[0] = hdc_get_from_internal_name(p);
if (free_p) {
free(p);
@@ -832,6 +851,7 @@ load_storage_controllers(void)
if (free_p) {
free(p);
p = NULL;
+ free_p = 0;
}
ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0);
@@ -841,16 +861,46 @@ load_storage_controllers(void)
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
else
cassette_enable = 0;
+
p = ini_section_get_string(cat, "cassette_file", "");
- if (strlen(p) > 511)
- fatal("load_storage_controllers(): strlen(p) > 511\n");
- else
- strncpy(cassette_fname, p, 511);
+
+ if (!strcmp(p, usr_path))
+ p[0] = 0x00;
+
+ if (p[0] != 0x00) {
+ if (path_abs(p)) {
+ if (strlen(p) > 511)
+ fatal("load_storage_controllers(): strlen(p) > 511 (cassette_fname)\n");
+ else
+ strncpy(cassette_fname, p, 511);
+ } else
+ path_append_filename(cassette_fname, usr_path, p);
+ path_normalize(cassette_fname);
+ }
+
p = ini_section_get_string(cat, "cassette_mode", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_mode, p, 511);
+
+ for (int i = 0; i < MAX_PREV_IMAGES; i++) {
+ cassette_image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
+ sprintf(temp, "cassette_image_history_%02i", i + 1);
+ p = ini_section_get_string(cat, temp, NULL);
+ if (p) {
+ if (path_abs(p)) {
+ if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
+ fatal("load_storage_controllers(): strlen(p) > 2047 "
+ "(cassette_image_history[%i])\n", i);
+ else
+ snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
+ } else
+ snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
+ path_get_slash(usr_path), p);
+ path_normalize(cassette_image_history[i]);
+ }
+ }
cassette_pos = ini_section_get_int(cat, "cassette_position", 0);
cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100);
cassette_append = !!ini_section_get_int(cat, "cassette_append", 0);
@@ -874,6 +924,24 @@ load_storage_controllers(void)
path_append_filename(cart_fns[c], usr_path, p);
path_normalize(cart_fns[c]);
}
+
+ for (int i = 0; i < MAX_PREV_IMAGES; i++) {
+ cart_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
+ sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
+ p = ini_section_get_string(cat, temp, NULL);
+ if (p) {
+ if (path_abs(p)) {
+ if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
+ fatal("load_storage_controllers(): strlen(p) > 2047 "
+ "(cart_image_history[%i][%i])\n", c, i);
+ else
+ snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
+ } else
+ snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
+ path_get_slash(usr_path), p);
+ path_normalize(cart_image_history[c][i]);
+ }
+ }
}
lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0);
@@ -1611,7 +1679,7 @@ config_load(void)
video_fullscreen_first = 1;
video_fullscreen_scale = 1;
time_sync = TIME_SYNC_ENABLED;
- hdc_current = hdc_get_from_internal_name("none");
+ hdc_current[0] = hdc_get_from_internal_name("none");
com_ports[0].enabled = 1;
com_ports[1].enabled = 1;
@@ -1700,7 +1768,7 @@ save_general(void)
char temp[512];
char buffer[512] = { 0 };
- const char *va_name = NULL;
+ const char *va_name;
ini_section_set_int(cat, "vid_resize", vid_resize);
if (vid_resize == 0)
@@ -1927,7 +1995,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");
@@ -1993,10 +2061,13 @@ save_video(void)
else
ini_section_set_int(cat, "xga", xga_standalone_enabled);
- if (gfxcard[1] == 0)
- ini_section_delete_var(cat, "gfxcard_2");
- else
- ini_section_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard[1]));
+ // TODO
+ for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
+ if (gfxcard[i] == 0)
+ ini_section_delete_var(cat, "gfxcard_2");
+ else
+ ini_section_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard[i]));
+ }
if (show_second_monitors == 1)
ini_section_delete_var(cat, "show_second_monitors");
@@ -2273,14 +2344,14 @@ save_storage_controllers(void)
scsi_card_get_internal_name(scsi_card_current[c]));
}
- if (fdc_type == FDC_INTERNAL)
+ if (fdc_current[0] == FDC_INTERNAL)
ini_section_delete_var(cat, "fdc");
else
ini_section_set_string(cat, "fdc",
- fdc_card_get_internal_name(fdc_type));
+ fdc_card_get_internal_name(fdc_current[0]));
ini_section_set_string(cat, "hdc",
- hdc_get_internal_name(hdc_current));
+ hdc_get_internal_name(hdc_current[0]));
if (cdrom_interface_current == 0)
ini_section_delete_var(cat, "cdrom_interface");
@@ -2307,14 +2378,32 @@ save_storage_controllers(void)
if (strlen(cassette_fname) == 0)
ini_section_delete_var(cat, "cassette_file");
- else
- ini_section_set_string(cat, "cassette_file", cassette_fname);
+ else {
+ path_normalize(cassette_fname);
+ if (!strnicmp(cassette_fname, usr_path, strlen(usr_path)))
+ ini_section_set_string(cat, "cassette_file", &cassette_fname[strlen(usr_path)]);
+ else
+ ini_section_set_string(cat, "cassette_file", cassette_fname);
+ }
if (strlen(cassette_mode) == 0)
ini_section_delete_var(cat, "cassette_mode");
else
ini_section_set_string(cat, "cassette_mode", cassette_mode);
+ for (int i = 0; i < MAX_PREV_IMAGES; i++) {
+ sprintf(temp, "cassette_image_history_%02i", i + 1);
+ if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0)
+ ini_section_delete_var(cat, temp);
+ else {
+ path_normalize(cassette_image_history[i]);
+ if (!strnicmp(cassette_image_history[i], usr_path, strlen(usr_path)))
+ ini_section_set_string(cat, temp, &cassette_image_history[i][strlen(usr_path)]);
+ else
+ ini_section_set_string(cat, temp, cassette_image_history[i]);
+ }
+ }
+
if (cassette_pos == 0)
ini_section_delete_var(cat, "cassette_position");
else
@@ -2342,10 +2431,29 @@ save_storage_controllers(void)
for (c = 0; c < 2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
+
if (strlen(cart_fns[c]) == 0)
ini_section_delete_var(cat, temp);
- else
- ini_section_set_string(cat, temp, cart_fns[c]);
+ else {
+ path_normalize(cart_fns[c]);
+ if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path)))
+ ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]);
+ else
+ ini_section_set_string(cat, temp, cart_fns[c]);
+ }
+
+ for (int i = 0; i < MAX_PREV_IMAGES; i++) {
+ sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
+ if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0)
+ ini_section_delete_var(cat, temp);
+ else {
+ path_normalize(cart_image_history[c][i]);
+ if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path)))
+ ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]);
+ else
+ ini_section_set_string(cat, temp, cart_image_history[c][i]);
+ }
+ }
}
if (lba_enhancer_enabled == 0)
diff --git a/src/cpu/386.c b/src/cpu/386.c
index 5379dccf9b..8b612604df 100644
--- a/src/cpu/386.c
+++ b/src/cpu/386.c
@@ -15,6 +15,7 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include <86box/io.h>
#include <86box/nmi.h>
@@ -211,11 +212,11 @@ fetch_ea_16_long(uint32_t rmdat)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#define CHECK_READ_CS(size) \
- if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
- ((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
- x86gpf("Limit check (READ)", 0); \
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \
x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \
+ else if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
+ ((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
+ x86gpf("Limit check (READ CS)", 0);
#include "386_ops.h"
@@ -260,7 +261,13 @@ exec386_2386(int32_t cycs)
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
ol = opcode_length[fetchdat & 0xff];
- CHECK_READ_CS(MIN(ol, 4));
+ if ((ol == 3) && opcode_has_modrm[fetchdat & 0xff] && (((fetchdat >> 14) & 0x03) == 0x03))
+ ol = 2;
+ if (cpu_16bitbus) {
+ CHECK_READ_CS(MIN(ol, 2));
+ } else {
+ CHECK_READ_CS(MIN(ol, 4));
+ }
ins_fetch_fault = cpu_386_check_instruction_fault();
/* Breakpoint fault has priority over other faults. */
@@ -272,7 +279,7 @@ exec386_2386(int32_t cycs)
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG
if (in_smm)
- x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
+ x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
@@ -297,6 +304,13 @@ exec386_2386(int32_t cycs)
cpu_state.pc &= 0xffff;
#endif
+ if (cpu_flush_pending == 1)
+ cpu_flush_pending++;
+ else if (cpu_flush_pending == 2) {
+ cpu_flush_pending = 0;
+ flushmmucache_pc();
+ }
+
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;
diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c
index f3926f1701..dcbe3608c6 100644
--- a/src/cpu/386_common.c
+++ b/src/cpu/386_common.c
@@ -14,6 +14,7 @@
#include <86box/timer.h>
#include "x86.h"
#include "x86seg_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include <86box/nmi.h>
#include <86box/mem.h>
@@ -50,6 +51,8 @@ uint32_t dr[8];
uint32_t use32;
int stack32;
+int cpu_init = 0;
+
uint32_t *eal_r;
uint32_t *eal_w;
@@ -103,6 +106,28 @@ uint32_t backupregs[16];
x86seg _oldds;
+int opcode_has_modrm[256] = {
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
+ 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/
+
+ 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/
+ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/
+};
+
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
@@ -426,42 +451,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;
@@ -989,9 +1016,14 @@ smram_restore_state_p6(uint32_t *saved_state)
cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_gs);
- mem_a20_alt = 0x00;
- mem_a20_key = saved_state[SMRAM_FIELD_P6_A20M] ? 0x00 : 0x02;
- mem_a20_recalc();
+ rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
+ if (is6117)
+ rammask |= 0x3000000;
+
+ if (saved_state[SMRAM_FIELD_P6_A20M] & 0x01)
+ rammask &= 0xffefffff;
+
+ flushmmucache();
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET];
diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h
index 6ef65771d4..ec40612ee3 100644
--- a/src/cpu/386_common.h
+++ b/src/cpu/386_common.h
@@ -449,6 +449,7 @@ get_ram_ptr(uint32_t a)
}
}
+extern int opcode_has_modrm[256];
extern int opcode_length[256];
#ifdef OPS_286_386
@@ -457,6 +458,7 @@ fastreadw_fetch(uint32_t a)
{
uint16_t ret;
+ cpu_old_paging = (cpu_flush_pending == 2);
if ((a & 0xFFF) > 0xFFE) {
ret = fastreadb(a);
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
@@ -468,6 +470,7 @@ fastreadw_fetch(uint32_t a)
ret = readmemwl_2386(a);
read_type = 4;
}
+ cpu_old_paging = 0;
return ret;
}
@@ -485,7 +488,9 @@ fastreadl_fetch(uint32_t a)
ret = 0;
else {
read_type = 1;
+ cpu_old_paging = (cpu_flush_pending == 2);
ret = readmemll_2386(a);
+ cpu_old_paging = 0;
read_type = 4;
}
@@ -562,35 +567,52 @@ fastreadl_fetch(uint32_t a)
}
#endif
+#ifdef OPS_286_386
static __inline uint8_t
getbyte(void)
{
+ uint8_t ret;
cpu_state.pc++;
- return fastreadb(cs + (cpu_state.pc - 1));
+ cpu_old_paging = (cpu_flush_pending == 2);
+ ret = fastreadb(cs + (cpu_state.pc - 1));
+ cpu_old_paging = 0;
+ return ret;
+
}
static __inline uint16_t
getword(void)
{
+ uint16_t ret;
cpu_state.pc += 2;
- return fastreadw(cs + (cpu_state.pc - 2));
+ cpu_old_paging = (cpu_flush_pending == 2);
+ ret = fastreadw(cs + (cpu_state.pc - 2));
+ cpu_old_paging = 0;
+ return ret;
}
static __inline uint32_t
getlong(void)
{
+ uint32_t ret;
cpu_state.pc += 4;
- return fastreadl(cs + (cpu_state.pc - 4));
+ cpu_old_paging = (cpu_flush_pending == 2);
+ ret = fastreadl(cs + (cpu_state.pc - 4));
+ cpu_old_paging = 0;
+ return ret;
}
static __inline uint64_t
getquad(void)
{
+ uint64_t ret;
cpu_state.pc += 8;
- return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
+ cpu_old_paging = (cpu_flush_pending == 2);
+ ret = fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
+ cpu_old_paging = 0;
+ return ret;
}
-#ifdef OPS_286_386
static __inline uint8_t
geteab(void)
{
@@ -677,6 +699,34 @@ seteaq(uint64_t v)
# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v);
# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v);
#else
+static __inline uint8_t
+getbyte(void)
+{
+ cpu_state.pc++;
+ return fastreadb(cs + (cpu_state.pc - 1));
+}
+
+static __inline uint16_t
+getword(void)
+{
+ cpu_state.pc += 2;
+ return fastreadw(cs + (cpu_state.pc - 2));
+}
+
+static __inline uint32_t
+getlong(void)
+{
+ cpu_state.pc += 4;
+ return fastreadl(cs + (cpu_state.pc - 4));
+}
+
+static __inline uint64_t
+getquad(void)
+{
+ cpu_state.pc += 8;
+ return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
+}
+
static __inline uint8_t
geteab(void)
{
diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c
index 77914a2a53..590d6f5c70 100644
--- a/src/cpu/386_dynarec.c
+++ b/src/cpu/386_dynarec.c
@@ -19,6 +19,7 @@
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
+#include "x87_sf.h"
#include "x87.h"
#include <86box/io.h>
#include <86box/mem.h>
@@ -349,6 +350,9 @@ exec386_dynarec_int(void)
CPU_BLOCK_END();
}
+ if (cpu_init)
+ CPU_BLOCK_END();
+
if (cpu_state.abrt)
CPU_BLOCK_END();
if (smi_line)
@@ -413,7 +417,8 @@ exec386_dynarec_dyn(void)
int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f);
- if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
+ if ((page->code_present_mask & mask) ||
+ ((page->mem != page_ff) && (page->byte_code_present_mask[byte_offset] & byte_mask)))
# else
if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
# endif
@@ -590,6 +595,9 @@ exec386_dynarec_dyn(void)
# endif
CPU_BLOCK_END();
+ if (cpu_init)
+ CPU_BLOCK_END();
+
if ((cpu_state.flags & T_FLAG) || (trap == 2))
CPU_BLOCK_END();
if (smi_line)
@@ -687,6 +695,9 @@ exec386_dynarec_dyn(void)
# endif
CPU_BLOCK_END();
+ if (cpu_init)
+ CPU_BLOCK_END();
+
if (cpu_state.flags & T_FLAG)
CPU_BLOCK_END();
if (smi_line)
@@ -766,6 +777,11 @@ exec386_dynarec(int32_t cycs)
exec386_dynarec_dyn();
}
+ if (cpu_init) {
+ cpu_init = 0;
+ resetx86();
+ }
+
if (cpu_state.abrt) {
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
@@ -917,6 +933,13 @@ exec386(int32_t cycs)
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
#endif
+ if (cpu_flush_pending == 1)
+ cpu_flush_pending++;
+ else if (cpu_flush_pending == 2) {
+ cpu_flush_pending = 0;
+ flushmmucache_pc();
+ }
+
#ifndef USE_NEW_DYNAREC
if (!use32)
cpu_state.pc &= 0xffff;
diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c
index 066b00dd69..c31b725b23 100644
--- a/src/cpu/386_dynarec_ops.c
+++ b/src/cpu/386_dynarec_ops.c
@@ -15,6 +15,7 @@
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
+#include "x87_sf.h"
#include "x87.h"
#include "x86_flags.h"
#include <86box/io.h>
diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h
index 3e0d191f20..1301663443 100644
--- a/src/cpu/386_ops.h
+++ b/src/cpu/386_ops.h
@@ -1384,7 +1384,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = {
// clang-format on
};
-# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+# ifdef USE_CYRIX_6X86
const OpFn OP_TABLE(c6x86_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1476,7 +1476,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = {
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
// clang-format on
};
-# endif
+# endif /* USE_CYRIX_6X86 */
const OpFn OP_TABLE(pentiummmx_0f)[1024] = {
// clang-format off
@@ -1754,7 +1754,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = {
// clang-format on
};
-# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+# ifdef USE_CYRIX_6X86
const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1846,7 +1846,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
// clang-format on
};
-# endif
+# endif /* USE_CYRIX_6X86 */
const OpFn OP_TABLE(pentiumpro_0f)[1024] = {
// clang-format off
diff --git a/src/cpu/808x.c b/src/cpu/808x.c
index 5b411dd669..990f9ae87d 100644
--- a/src/cpu/808x.c
+++ b/src/cpu/808x.c
@@ -130,10 +130,10 @@ typedef int (*OpFn)(uint32_t fetchdat);
static int tempc_fpu = 0;
#ifdef ENABLE_808X_LOG
+#if 0
void dumpregs(int);
-
+#endif
int x808x_do_log = ENABLE_808X_LOG;
-int indump = 0;
static void
x808x_log(const char *fmt, ...)
@@ -785,6 +785,7 @@ seteaq(uint64_t val)
complicates compiling. */
#define FPU_8087
#define tempc tempc_fpu
+#include "x87_sf.h"
#include "x87.h"
#include "x87_ops.h"
#undef tempc
diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt
index bd03a5558f..890d02e3e7 100644
--- a/src/cpu/CMakeLists.txt
+++ b/src/cpu/CMakeLists.txt
@@ -9,30 +9,61 @@
# CMake build script.
#
# Authors: David Hrdlička,
+# Jasmine Iwanek,
#
# Copyright 2020-2021 David Hrdlička.
+# Copyright 2024 Jasmine Iwanek.
#
-add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
- 386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c
- x87_timings.c 8080.c)
+add_library(cpu OBJECT
+ cpu.c
+ cpu_table.c
+ fpu.c x86.c
+ 808x.c
+ 386.c
+ 386_common.c
+ 386_dynarec.c
+ x86_ops_mmx.c
+ x86seg_common.c
+ x86seg.c
+ x86seg_2386.c
+ x87.c
+ x87_timings.c
+ 8080.c
+)
if(AMD_K5)
target_compile_definitions(cpu PRIVATE USE_AMD_K5)
+
+if(DYNAREC)
+ add_library(ctk5 OBJECT codegen_timing_k5.c)
+ target_link_libraries(86Box ctk5)
+endif()
+
endif()
if(CYRIX_6X86)
target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86)
+
+if(DYNAREC)
+ add_library(ct686 OBJECT codegen_timing_686.c)
+ target_link_libraries(86Box ct686)
+endif()
endif()
if(DYNAREC)
target_sources(cpu PRIVATE 386_dynarec_ops.c)
- add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c
- codegen_timing_common.c codegen_timing_k6.c
- codegen_timing_pentium.c codegen_timing_p6.c
- codegen_timing_winchip.c codegen_timing_winchip2.c)
+ add_library(cgt OBJECT
+ codegen_timing_486.c
+ codegen_timing_common.c
+ codegen_timing_k6.c
+ codegen_timing_pentium.c
+ codegen_timing_p6.c
+ 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/codegen_timing_486.c b/src/cpu/codegen_timing_486.c
index e862b123e7..90d6822110 100644
--- a/src/cpu/codegen_timing_486.c
+++ b/src/cpu/codegen_timing_486.c
@@ -9,6 +9,7 @@
#include "x86.h"
#include "x86_ops.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_ops.h"
@@ -17,7 +18,7 @@
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
-static int *opcode_timings[256] = {
+static int *opcode_timings_486[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -41,7 +42,7 @@ static int *opcode_timings[256] = {
// clang-format on
};
-static int *opcode_timings_mod3[256] = {
+static int *opcode_timings_486_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -65,7 +66,7 @@ static int *opcode_timings_mod3[256] = {
// clang-format on
};
-static int *opcode_timings_0f[256] = {
+static int *opcode_timings_486_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -88,7 +89,7 @@ static int *opcode_timings_0f[256] = {
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
-static int *opcode_timings_0f_mod3[256] = {
+static int *opcode_timings_486_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -112,65 +113,65 @@ static int *opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static int *opcode_timings_shift[8] = {
+static int *opcode_timings_486_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
};
-static int *opcode_timings_shift_mod3[8] = {
+static int *opcode_timings_486_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
-static int *opcode_timings_f6[8] = {
+static int *opcode_timings_486_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static int *opcode_timings_f6_mod3[8] = {
+static int *opcode_timings_486_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static int *opcode_timings_f7[8] = {
+static int *opcode_timings_486_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
-static int *opcode_timings_f7_mod3[8] = {
+static int *opcode_timings_486_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
};
-static int *opcode_timings_ff[8] = {
+static int *opcode_timings_486_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
};
-static int *opcode_timings_ff_mod3[8] = {
+static int *opcode_timings_486_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
-static int *opcode_timings_d8[8] = {
+static int *opcode_timings_486_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_d8_mod3[8] = {
+static int *opcode_timings_486_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_d9[8] = {
+static int *opcode_timings_486_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
-static int *opcode_timings_d9_mod3[64] = {
+static int *opcode_timings_486_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
@@ -191,25 +192,25 @@ static int *opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static int *opcode_timings_da[8] = {
+static int *opcode_timings_486_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_da_mod3[8] = {
+static int *opcode_timings_486_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
-static int *opcode_timings_db[8] = {
+static int *opcode_timings_486_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6)
// clang-format on
};
-static int *opcode_timings_db_mod3[64] = {
+static int *opcode_timings_486_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -223,74 +224,74 @@ static int *opcode_timings_db_mod3[64] = {
// clang-format on
};
-static int *opcode_timings_dc[8] = {
+static int *opcode_timings_486_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_dc_mod3[8] = {
+static int *opcode_timings_486_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_dd[8] = {
+static int *opcode_timings_486_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3)
// clang-format on
};
-static int *opcode_timings_dd_mod3[8] = {
+static int *opcode_timings_486_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
-static int *opcode_timings_de[8] = {
+static int *opcode_timings_486_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_de_mod3[8] = {
+static int *opcode_timings_486_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
-static int *opcode_timings_df[8] = {
+static int *opcode_timings_486_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28)
// clang-format on
};
-static int *opcode_timings_df_mod3[8] = {
+static int *opcode_timings_486_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
-static int *opcode_timings_8x[8] = {
+static int *opcode_timings_486_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
-static int *opcode_timings_8x_mod3[8] = {
+static int *opcode_timings_486_8x_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
-static int *opcode_timings_81[8] = {
+static int *opcode_timings_486_81[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
-static int *opcode_timings_81_mod3[8] = {
+static int *opcode_timings_486_81_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
@@ -329,7 +330,7 @@ codegen_timing_486_start(void)
void
codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
{
- timing_count += COUNT(opcode_timings[prefix], 0);
+ timing_count += COUNT(opcode_timings_486[prefix], 0);
last_prefix = prefix;
}
@@ -343,47 +344,47 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
switch (last_prefix) {
case 0x0f:
- timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ timings = mod3 ? opcode_timings_486_0f_mod3 : opcode_timings_486_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ timings = mod3 ? opcode_timings_486_d8_mod3 : opcode_timings_486_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ timings = mod3 ? opcode_timings_486_d9_mod3 : opcode_timings_486_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ timings = mod3 ? opcode_timings_486_da_mod3 : opcode_timings_486_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ timings = mod3 ? opcode_timings_486_db_mod3 : opcode_timings_486_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ timings = mod3 ? opcode_timings_486_dc_mod3 : opcode_timings_486_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ timings = mod3 ? opcode_timings_486_dd_mod3 : opcode_timings_486_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ timings = mod3 ? opcode_timings_486_de_mod3 : opcode_timings_486_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ timings = mod3 ? opcode_timings_486_df_mod3 : opcode_timings_486_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -393,12 +394,12 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0x80:
case 0x82:
case 0x83:
- timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ timings = mod3 ? opcode_timings_486_8x_mod3 : opcode_timings_486_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
- timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
+ timings = mod3 ? opcode_timings_486_81_mod3 : opcode_timings_486_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -409,29 +410,29 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0xd1:
case 0xd2:
case 0xd3:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_486_shift_mod3 : opcode_timings_486_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ timings = mod3 ? opcode_timings_486_f6_mod3 : opcode_timings_486_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ timings = mod3 ? opcode_timings_486_f7_mod3 : opcode_timings_486_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ timings = mod3 ? opcode_timings_486_ff_mod3 : opcode_timings_486_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- timings = mod3 ? opcode_timings_mod3 : opcode_timings;
+ timings = mod3 ? opcode_timings_486_mod3 : opcode_timings_486;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c
index a6800c5b22..285881956f 100644
--- a/src/cpu/codegen_timing_686.c
+++ b/src/cpu/codegen_timing_686.c
@@ -19,6 +19,7 @@
#include "x86.h"
#include "x86_ops.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_timing_common.h"
@@ -64,7 +65,7 @@ static uint32_t prev_fetchdat;
static uint32_t last_regmask_modified;
static uint32_t regmask_modified;
-static uint32_t opcode_timings[256] = {
+static uint32_t opcode_timings_686[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
@@ -201,7 +202,7 @@ static uint32_t opcode_timings[256] = {
// clang-format on
};
-static uint32_t opcode_timings_mod3[256] = {
+static uint32_t opcode_timings_686_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
@@ -339,7 +340,7 @@ static uint32_t opcode_timings_mod3[256] = {
// clang-format on
};
-static uint32_t opcode_timings_0f[256] = {
+static uint32_t opcode_timings_686_0f[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -422,7 +423,7 @@ static uint32_t opcode_timings_0f[256] = {
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
// clang-format on
};
-static uint32_t opcode_timings_0f_mod3[256] = {
+static uint32_t opcode_timings_686_0f_mod3[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -505,44 +506,44 @@ static uint32_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static uint32_t opcode_timings_shift[8] = {
+static uint32_t opcode_timings_686_shift[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
-static uint32_t opcode_timings_shift_mod3[8] = {
+static uint32_t opcode_timings_686_shift_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
-static uint32_t opcode_timings_shift_imm[8] = {
+static uint32_t opcode_timings_686_shift_imm[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
-static uint32_t opcode_timings_shift_imm_mod3[8] = {
+static uint32_t opcode_timings_686_shift_imm_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
-static uint32_t opcode_timings_shift_cl[8] = {
+static uint32_t opcode_timings_686_shift_cl[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
-static uint32_t opcode_timings_shift_cl_mod3[8] = {
+static uint32_t opcode_timings_686_shift_cl_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
-static uint32_t opcode_timings_f6[8] = {
+static uint32_t opcode_timings_686_f6[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -550,7 +551,7 @@ static uint32_t opcode_timings_f6[8] = {
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
-static uint32_t opcode_timings_f6_mod3[8] = {
+static uint32_t opcode_timings_686_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -558,7 +559,7 @@ static uint32_t opcode_timings_f6_mod3[8] = {
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
-static uint32_t opcode_timings_f7[8] = {
+static uint32_t opcode_timings_686_f7[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -566,7 +567,7 @@ static uint32_t opcode_timings_f7[8] = {
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
-static uint32_t opcode_timings_f7_mod3[8] = {
+static uint32_t opcode_timings_686_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -574,7 +575,7 @@ static uint32_t opcode_timings_f7_mod3[8] = {
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
-static uint32_t opcode_timings_ff[8] = {
+static uint32_t opcode_timings_686_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5),
@@ -582,7 +583,7 @@ static uint32_t opcode_timings_ff[8] = {
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID
// clang-format on
};
-static uint32_t opcode_timings_ff_mod3[8] = {
+static uint32_t opcode_timings_686_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
@@ -591,7 +592,7 @@ static uint32_t opcode_timings_ff_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_d8[8] = {
+static uint32_t opcode_timings_686_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -599,7 +600,7 @@ static uint32_t opcode_timings_d8[8] = {
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
-static uint32_t opcode_timings_d8_mod3[8] = {
+static uint32_t opcode_timings_686_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -608,7 +609,7 @@ static uint32_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_d9[8] = {
+static uint32_t opcode_timings_686_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -616,7 +617,7 @@ static uint32_t opcode_timings_d9[8] = {
PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5)
// clang-format on
};
-static uint32_t opcode_timings_d9_mod3[64] = {
+static uint32_t opcode_timings_686_d9_mod3[64] = {
// clang-format off
/*FLD*/
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -649,7 +650,7 @@ static uint32_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static uint32_t opcode_timings_da[8] = {
+static uint32_t opcode_timings_686_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
@@ -657,14 +658,14 @@ static uint32_t opcode_timings_da[8] = {
PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48)
// clang-format on
};
-static uint32_t opcode_timings_da_mod3[8] = {
+static uint32_t opcode_timings_686_da_mod3[8] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
INVALID, PAIR_X | CYCLES(5), INVALID, INVALID
// clang-format on
};
-static uint32_t opcode_timings_db[8] = {
+static uint32_t opcode_timings_686_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -672,7 +673,7 @@ static uint32_t opcode_timings_db[8] = {
INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2)
// clang-format on
};
-static uint32_t opcode_timings_db_mod3[64] = {
+static uint32_t opcode_timings_686_db_mod3[64] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -702,7 +703,7 @@ static uint32_t opcode_timings_db_mod3[64] = {
// clang-format on
};
-static uint32_t opcode_timings_dc[8] = {
+static uint32_t opcode_timings_686_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7),
@@ -710,7 +711,7 @@ static uint32_t opcode_timings_dc[8] = {
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
-static uint32_t opcode_timings_dc_mod3[8] = {
+static uint32_t opcode_timings_686_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID,
@@ -719,7 +720,7 @@ static uint32_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_dd[8] = {
+static uint32_t opcode_timings_686_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -727,7 +728,7 @@ static uint32_t opcode_timings_dd[8] = {
PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2)
// clang-format on
};
-static uint32_t opcode_timings_dd_mod3[8] = {
+static uint32_t opcode_timings_686_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -736,14 +737,14 @@ static uint32_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_de[8] = {
+static uint32_t opcode_timings_686_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38)
};
-static uint32_t opcode_timings_de_mod3[8] = {
+static uint32_t opcode_timings_686_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7),
@@ -752,7 +753,7 @@ static uint32_t opcode_timings_de_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_df[8] = {
+static uint32_t opcode_timings_686_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13),
@@ -760,7 +761,7 @@ static uint32_t opcode_timings_df[8] = {
INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13)
// clang-format on
};
-static uint32_t opcode_timings_df_mod3[8] = {
+static uint32_t opcode_timings_686_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -768,25 +769,25 @@ static uint32_t opcode_timings_df_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_8x[8] = {
+static uint32_t opcode_timings_686_8x[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
-static uint32_t opcode_timings_8x_mod3[8] = {
+static uint32_t opcode_timings_686_8x_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
// clang-format on
};
-static uint32_t opcode_timings_81[8] = {
+static uint32_t opcode_timings_686_81[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
-static uint32_t opcode_timings_81_mod3[8] = {
+static uint32_t opcode_timings_686_81_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
@@ -873,47 +874,47 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
switch (last_prefix) {
case 0x0f:
- timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ timings = mod3 ? opcode_timings_686_0f_mod3 : opcode_timings_686_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ timings = mod3 ? opcode_timings_686_d8_mod3 : opcode_timings_686_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ timings = mod3 ? opcode_timings_686_d9_mod3 : opcode_timings_686_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ timings = mod3 ? opcode_timings_686_da_mod3 : opcode_timings_686_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ timings = mod3 ? opcode_timings_686_db_mod3 : opcode_timings_686_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ timings = mod3 ? opcode_timings_686_dc_mod3 : opcode_timings_686_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ timings = mod3 ? opcode_timings_686_dd_mod3 : opcode_timings_686_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ timings = mod3 ? opcode_timings_686_de_mod3 : opcode_timings_686_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ timings = mod3 ? opcode_timings_686_df_mod3 : opcode_timings_686_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -923,55 +924,55 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0x80:
case 0x82:
case 0x83:
- timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ timings = mod3 ? opcode_timings_686_8x_mod3 : opcode_timings_686_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
- timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
+ timings = mod3 ? opcode_timings_686_81_mod3 : opcode_timings_686_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
case 0xc0:
case 0xc1:
- timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
+ timings = mod3 ? opcode_timings_686_shift_imm_mod3 : opcode_timings_686_shift_imm;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd0:
case 0xd1:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_686_shift_mod3 : opcode_timings_686_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd2:
case 0xd3:
- timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
+ timings = mod3 ? opcode_timings_686_shift_cl_mod3 : opcode_timings_686_shift_cl;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ timings = mod3 ? opcode_timings_686_f6_mod3 : opcode_timings_686_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ timings = mod3 ? opcode_timings_686_f7_mod3 : opcode_timings_686_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ timings = mod3 ? opcode_timings_686_ff_mod3 : opcode_timings_686_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- timings = mod3 ? opcode_timings_mod3 : opcode_timings;
+ timings = mod3 ? opcode_timings_686_mod3 : opcode_timings_686;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/codegen_timing_k5.c b/src/cpu/codegen_timing_k5.c
new file mode 100644
index 0000000000..42b1129fe2
--- /dev/null
+++ b/src/cpu/codegen_timing_k5.c
@@ -0,0 +1,2232 @@
+/*Most of the vector instructions here are a total guess.
+ Some of the timings are based on https://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000502_k5_InstLatX86.txt*/
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include <86box/mem.h>
+#include "cpu.h"
+#include <86box/machine.h>
+
+#include "x86.h"
+#include "x86_ops.h"
+#include "x86seg_common.h"
+#include "x87_sf.h"
+#include "x87.h"
+#include "386_common.h"
+#include "codegen.h"
+#include "codegen_ops.h"
+#include "codegen_timing_common.h"
+
+typedef enum uop_type_t {
+ UOP_ALU = 0, /*Executes in Integer X or Y units*/
+ UOP_ALUX, /*Executes in Integer X unit*/
+ UOP_LOAD, /*Executes in Load unit*/
+ UOP_STORE, /*Executes in Store unit*/
+ UOP_FLOAD, /*Executes in Load unit*/
+ UOP_FSTORE, /*Executes in Store unit*/
+ UOP_MLOAD, /*Executes in Load unit*/
+ UOP_MSTORE, /*Executes in Store unit*/
+ UOP_FLOAT, /*Executes in Floating Point unit*/
+ UOP_MEU, /*Executes in Multimedia unit*/
+ UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/
+ UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/
+ UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/
+ UOP_BRANCH, /*Executes in Branch unit*/
+ UOP_LIMM /*Does not require an execution unit*/
+} uop_type_t;
+
+typedef enum decode_type_t {
+ DECODE_SHORT,
+ DECODE_LONG,
+ DECODE_VECTOR
+} decode_type_t;
+
+#define MAX_UOPS 10
+
+typedef struct risc86_uop_t {
+ uop_type_t type;
+ int throughput;
+ int latency;
+} risc86_uop_t;
+
+typedef struct risc86_instruction_t {
+ int nr_uops;
+ decode_type_t decode_type;
+ risc86_uop_t uop[MAX_UOPS];
+} risc86_instruction_t;
+
+static const risc86_instruction_t alu_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t alux_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t load_alu_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t load_alux_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t alu_store_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t alux_store_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t branch_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t limm_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t load_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}
+};
+
+static const risc86_instruction_t store_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t bswap_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t leave_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t lods_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t loop_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t mov_reg_seg_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+};
+static const risc86_instruction_t movs_op = {
+ .nr_uops = 4,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t pop_reg_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t pop_mem_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t push_imm_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2},
+};
+static const risc86_instruction_t push_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t push_seg_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t stos_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t test_reg_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t test_reg_b_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t test_mem_imm_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t test_mem_imm_b_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t xchg_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_LONG,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t m3dn_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t mmx_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t mmx_mul_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}
+};
+static const risc86_instruction_t mmx_shift_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t load_3dn_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_MEU_3DN, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t load_mmx_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_MEU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t load_mmx_mul_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2}
+};
+static const risc86_instruction_t load_mmx_shift_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t mload_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2}
+};
+
+static const risc86_instruction_t mstore_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t pmul_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}
+};
+static const risc86_instruction_t pmul_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2}
+};
+
+static const risc86_instruction_t float_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}
+};
+static const risc86_instruction_t load_float_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2}
+};
+static const risc86_instruction_t fstore_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t fdiv_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40}
+};
+static const risc86_instruction_t fdiv_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_FLOAT, .throughput = 40, .latency = 40}
+};
+static const risc86_instruction_t fsin_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62}
+};
+static const risc86_instruction_t fsqrt_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_SHORT,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41}
+};
+
+static const risc86_instruction_t vector_fldcw_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8}
+};
+static const risc86_instruction_t vector_float_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}
+};
+static const risc86_instruction_t vector_float_l_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50}
+};
+static const risc86_instruction_t vector_flde_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_FLOAD, .throughput = 1, .latency = 2},
+ .uop[2] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2}
+};
+static const risc86_instruction_t vector_fste_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2},
+ .uop[1] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1}
+};
+
+static const risc86_instruction_t vector_alu1_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alu2_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alu3_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alu6_op = {
+ .nr_uops = 6,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[4] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[5] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alux1_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alux3_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alux6_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[4] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[5] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alu_store_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_alux_store_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_arpl_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3},
+ .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3}
+};
+static const risc86_instruction_t vector_bound_op = {
+ .nr_uops = 4,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_bsx_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10}
+};
+static const risc86_instruction_t vector_call_far_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_cli_sti_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7}
+};
+static const risc86_instruction_t vector_cmps_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_cmpsb_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_cmpxchg_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+};
+static const risc86_instruction_t vector_cmpxchg_b_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+};
+static const risc86_instruction_t vector_cpuid_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22}
+};
+static const risc86_instruction_t vector_div16_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10}
+};
+static const risc86_instruction_t vector_div16_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_ALUX, .throughput = 10, .latency = 10}
+};
+static const risc86_instruction_t vector_div32_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18}
+};
+static const risc86_instruction_t vector_div32_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_ALUX, .throughput = 18, .latency = 18}
+};
+static const risc86_instruction_t vector_emms_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25}
+};
+static const risc86_instruction_t vector_enter_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_ALU, .throughput = 10, .latency = 10}
+};
+static const risc86_instruction_t vector_femms_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6}
+};
+static const risc86_instruction_t vector_in_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}
+};
+static const risc86_instruction_t vector_ins_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 },
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 }
+};
+static const risc86_instruction_t vector_int_op = {
+ .nr_uops = 5,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 },
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1 },
+ .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1 },
+ .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 }
+};
+static const risc86_instruction_t vector_iret_op = {
+ .nr_uops = 5,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[3] = { .type = UOP_ALU, .throughput = 20, .latency = 20},
+ .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 }
+};
+static const risc86_instruction_t vector_invd_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000}
+};
+static const risc86_instruction_t vector_jmp_far_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3},
+ .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_load_alu_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_load_alux_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_loop_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_lss_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[2] = { .type = UOP_ALU, .throughput = 3, .latency = 3}
+};
+static const risc86_instruction_t vector_mov_mem_seg_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_mov_seg_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3}
+};
+static const risc86_instruction_t vector_mov_seg_reg_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}
+};
+static const risc86_instruction_t vector_mul_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_mul_mem_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_mul64_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_mul64_mem_op = {
+ .nr_uops = 4,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_out_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10}
+};
+static const risc86_instruction_t vector_outs_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1 },
+ .uop[1] = { .type = UOP_STORE, .throughput = 10, .latency = 10},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 }
+};
+static const risc86_instruction_t vector_pusha_op = {
+ .nr_uops = 8,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[4] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[5] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[6] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[7] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_popa_op = {
+ .nr_uops = 8,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[3] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[4] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[5] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[6] = { .type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[7] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_popf_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 },
+ .uop[1] = { .type = UOP_ALUX, .throughput = 17, .latency = 17}
+};
+static const risc86_instruction_t vector_push_mem_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_pushf_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_ret_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_retf_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3},
+ .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_scas_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_scasb_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_setcc_mem_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_setcc_reg_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_test_mem_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_test_mem_b_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2},
+ .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_xchg_mem_op = {
+ .nr_uops = 3,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1},
+ .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}
+};
+static const risc86_instruction_t vector_xlat_op = {
+ .nr_uops = 2,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1},
+ .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}
+};
+static const risc86_instruction_t vector_wbinvd_op = {
+ .nr_uops = 1,
+ .decode_type = DECODE_VECTOR,
+ .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000}
+};
+
+#define INVALID NULL
+
+static const risc86_instruction_t *opcode_timings_k5[256] = {
+ // clang-format off
+/* ADD ADD ADD ADD*/
+/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
+/* ADD ADD PUSH ES POP ES*/
+ &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op,
+/* OR OR OR OR*/
+ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
+/* OR OR PUSH CS */
+ &alux_op, &alu_op, &push_seg_op, INVALID,
+
+/* ADC ADC ADC ADC*/
+/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op,
+/* ADC ADC PUSH SS POP SS*/
+ &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op,
+/* SBB SBB SBB SBB*/
+/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op,
+/* SBB SBB PUSH DS POP DS*/
+ &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op,
+
+/* AND AND AND AND*/
+/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
+/* AND AND DAA*/
+ &alux_op, &alu_op, INVALID, &vector_alux1_op,
+/* SUB SUB SUB SUB*/
+ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
+/* SUB SUB DAS*/
+ &alux_op, &alu_op, INVALID, &vector_alux1_op,
+
+/* XOR XOR XOR XOR*/
+/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
+/* XOR XOR AAA*/
+ &alux_op, &alu_op, INVALID, &vector_alux6_op,
+/* CMP CMP CMP CMP*/
+ &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op,
+/* CMP CMP AAS*/
+ &alux_op, &alu_op, INVALID, &vector_alux6_op,
+
+/* INC EAX INC ECX INC EDX INC EBX*/
+/*40*/ &alu_op, &alu_op, &alu_op, &alu_op,
+/* INC ESP INC EBP INC ESI INC EDI*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+/* DEC EAX DEC ECX DEC EDX DEC EBX*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+/* DEC ESP DEC EBP DEC ESI DEC EDI*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+
+/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
+/*50*/ &store_op, &store_op, &store_op, &store_op,
+/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
+ &store_op, &store_op, &store_op, &store_op,
+/* POP EAX POP ECX POP EDX POP EBX*/
+ &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op,
+/* POP ESP POP EBP POP ESI POP EDI*/
+ &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op,
+
+/* PUSHA POPA BOUND ARPL*/
+/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op,
+ INVALID, INVALID, INVALID, INVALID,
+/* PUSH imm IMUL PUSH imm IMUL*/
+ &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op,
+/* INSB INSW OUTSB OUTSW*/
+ &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op,
+
+/* Jxx*/
+/*70*/ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+
+/*80*/ INVALID, INVALID, INVALID, INVALID,
+/* TEST TEST XCHG XCHG*/
+ &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op,
+/* MOV MOV MOV MOV*/
+ &store_op, &store_op, &load_op, &load_op,
+/* MOV from seg LEA MOV to seg POP*/
+ &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op,
+
+/* NOP XCHG XCHG XCHG*/
+/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op,
+/* XCHG XCHG XCHG XCHG*/
+ &xchg_op, &xchg_op, &xchg_op, &xchg_op,
+/* CBW CWD CALL far WAIT*/
+ &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op,
+/* PUSHF POPF SAHF LAHF*/
+ &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op,
+
+/* MOV MOV MOV MOV*/
+/*a0*/ &load_op, &load_op, &store_op, &store_op,
+/* MOVSB MOVSW CMPSB CMPSW*/
+ &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op,
+/* TEST TEST STOSB STOSW*/
+ &test_reg_b_op, &test_reg_op, &stos_op, &stos_op,
+/* LODSB LODSW SCASB SCASW*/
+ &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op,
+
+/* MOV*/
+/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+
+/* RET imm RET*/
+/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op,
+/* LES LDS MOV MOV*/
+ &vector_lss_op, &vector_lss_op, &store_op, &store_op,
+/* ENTER LEAVE RETF RETF*/
+ &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op,
+/* INT3 INT INTO IRET*/
+ &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op,
+
+
+/*d0*/ INVALID, INVALID, INVALID, INVALID,
+/* AAM AAD SETALC XLAT*/
+ &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+/* LOOPNE LOOPE LOOP JCXZ*/
+/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op,
+/* IN AL IN AX OUT_AL OUT_AX*/
+ &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op,
+/* CALL JMP JMP JMP*/
+ &store_op, &branch_op, &vector_jmp_far_op, &branch_op,
+/* IN AL IN AX OUT_AL OUT_AX*/
+ &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op,
+
+/* REPNE REPE*/
+/*f0*/ INVALID, INVALID, INVALID, INVALID,
+/* HLT CMC*/
+ &vector_alux1_op, &vector_alu2_op, INVALID, INVALID,
+/* CLC STC CLI STI*/
+ &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op,
+/* CLD STD INCDEC*/
+ &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_mod3[256] = {
+ // clang-format off
+/* ADD ADD ADD ADD*/
+/*00*/ &alux_op, &alu_op, &alux_op, &alu_op,
+/* ADD ADD PUSH ES POP ES*/
+ &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op,
+/* OR OR OR OR*/
+ &alux_op, &alu_op, &alux_op, &alu_op,
+/* OR OR PUSH CS */
+ &alux_op, &alu_op, &push_seg_op, INVALID,
+
+/* ADC ADC ADC ADC*/
+/*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op,
+/* ADC ADC PUSH SS POP SS*/
+ &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op,
+/* SBB SBB SBB SBB*/
+ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op,
+/* SBB SBB PUSH DS POP DS*/
+ &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op,
+
+/* AND AND AND AND*/
+/*20*/ &alux_op, &alu_op, &alux_op, &alu_op,
+/* AND AND DAA*/
+ &alux_op, &alu_op, INVALID, &vector_alux1_op,
+/* SUB SUB SUB SUB*/
+ &alux_op, &alu_op, &alux_op, &alu_op,
+/* SUB SUB DAS*/
+ &alux_op, &alu_op, INVALID, &vector_alux1_op,
+
+/* XOR XOR XOR XOR*/
+/*30*/ &alux_op, &alu_op, &alux_op, &alu_op,
+/* XOR XOR AAA*/
+ &alux_op, &alu_op, INVALID, &vector_alux6_op,
+/* CMP CMP CMP CMP*/
+ &alux_op, &alu_op, &alux_op, &alu_op,
+/* CMP CMP AAS*/
+ &alux_op, &alu_op, INVALID, &vector_alux6_op,
+
+/* INC EAX INC ECX INC EDX INC EBX*/
+/*40*/ &alu_op, &alu_op, &alu_op, &alu_op,
+/* INC ESP INC EBP INC ESI INC EDI*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+/* DEC EAX DEC ECX DEC EDX DEC EBX*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+/* DEC ESP DEC EBP DEC ESI DEC EDI*/
+ &alu_op, &alu_op, &alu_op, &alu_op,
+
+/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
+/*50*/ &store_op, &store_op, &store_op, &store_op,
+/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
+ &store_op, &store_op, &store_op, &store_op,
+/* POP EAX POP ECX POP EDX POP EBX*/
+ &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op,
+/* POP ESP POP EBP POP ESI POP EDI*/
+ &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op,
+
+/* PUSHA POPA BOUND ARPL*/
+/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op,
+ INVALID, INVALID, INVALID, INVALID,
+/* PUSH imm IMUL PUSH imm IMUL*/
+ &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op,
+/* INSB INSW OUTSB OUTSW*/
+ &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op,
+
+/* Jxx*/
+/*70*/ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+
+/*80*/ INVALID, INVALID, INVALID, INVALID,
+/* TEST TEST XCHG XCHG*/
+ &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op,
+/* MOV MOV MOV MOV*/
+ &store_op, &store_op, &load_op, &load_op,
+/* MOV from seg LEA MOV to seg POP*/
+ &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op,
+
+/* NOP XCHG XCHG XCHG*/
+/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op,
+/* XCHG XCHG XCHG XCHG*/
+ &xchg_op, &xchg_op, &xchg_op, &xchg_op,
+/* CBW CWD CALL far WAIT*/
+ &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op,
+/* PUSHF POPF SAHF LAHF*/
+ &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op,
+
+/* MOV MOV MOV MOV*/
+/*a0*/ &load_op, &load_op, &store_op, &store_op,
+/* MOVSB MOVSW CMPSB CMPSW*/
+ &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op,
+/* TEST TEST STOSB STOSW*/
+ &test_reg_b_op, &test_reg_op, &stos_op, &stos_op,
+/* LODSB LODSW SCASB SCASW*/
+ &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op,
+
+/* MOV*/
+/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+ &limm_op, &limm_op, &limm_op, &limm_op,
+
+/* RET imm RET*/
+/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op,
+/* LES LDS MOV MOV*/
+ &vector_lss_op, &vector_lss_op, &store_op, &store_op,
+/* ENTER LEAVE RETF RETF*/
+ &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op,
+/* INT3 INT INTO IRET*/
+ &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op,
+
+
+/*d0*/ INVALID, INVALID, INVALID, INVALID,
+/* AAM AAD SETALC XLAT*/
+ &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+/* LOOPNE LOOPE LOOP JCXZ*/
+/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op,
+/* IN AL IN AX OUT_AL OUT_AX*/
+ &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op,
+/* CALL JMP JMP JMP*/
+ &store_op, &branch_op, &vector_jmp_far_op, &branch_op,
+/* IN AL IN AX OUT_AL OUT_AX*/
+ &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op,
+
+/* REPNE REPE*/
+/*f0*/ INVALID, INVALID, INVALID, INVALID,
+/* HLT CMC*/
+ &vector_alux1_op, &vector_alu2_op, INVALID, INVALID,
+/* CLC STC CLI STI*/
+ &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op,
+/* CLD STD INCDEC*/
+ &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_0f[256] = {
+ // clang-format off
+/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
+ INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
+ &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID,
+ INVALID, &load_op, &vector_femms_op, &load_3dn_op,
+
+/*10*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
+ &vector_alu6_op, &vector_alu6_op, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*40*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*50*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op,
+ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op,
+ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op,
+ INVALID, INVALID, &mload_op, &mload_op,
+
+/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op,
+ &load_mmx_op, &load_mmx_op, &load_mmx_op, &vector_emms_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, &mstore_op, &mstore_op,
+
+/*80*/ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+
+/*90*/ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op,
+ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op,
+ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op,
+ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op,
+
+/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_load_alu_op,
+ &vector_alu_store_op, &vector_alu_store_op, INVALID, INVALID,
+ &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_load_alu_op,
+ &vector_alu_store_op, &vector_alu_store_op, INVALID, &vector_mul_op,
+
+/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_load_alu_op,
+ &vector_lss_op, &vector_lss_op, &load_alux_op, &load_alu_op,
+ INVALID, INVALID, &vector_load_alu_op, &vector_load_alu_op,
+ &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op,
+
+/*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID,
+ INVALID, INVALID, INVALID, &vector_cmpxchg_op,
+ &bswap_op, &bswap_op, &bswap_op, &bswap_op,
+ &bswap_op, &bswap_op, &bswap_op, &bswap_op,
+
+/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op,
+ INVALID, &load_mmx_mul_op, INVALID, INVALID,
+ &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op,
+ &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op,
+
+/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID,
+ INVALID, &pmul_mem_op, INVALID, INVALID,
+ &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op,
+ &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op,
+
+/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op,
+ INVALID, &pmul_mem_op, INVALID, INVALID,
+ &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
+ &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_0f_mod3[256] = {
+ // clang-format off
+/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
+ INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
+ &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID,
+ INVALID, INVALID, &vector_femms_op, &m3dn_op,
+
+/*10*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
+ &vector_alu6_op, &vector_alu6_op, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*40*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*50*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op,
+ &mmx_op, &mmx_op, &mmx_op, &mmx_op,
+ &mmx_op, &mmx_op, &mmx_op, &mmx_op,
+ INVALID, INVALID, &mmx_op, &mmx_op,
+
+/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op,
+ &mmx_op, &mmx_op, &mmx_op, &vector_emms_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, &mmx_op, &mmx_op,
+
+/*80*/ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+ &branch_op, &branch_op, &branch_op, &branch_op,
+
+/*90*/ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op,
+ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op,
+ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op,
+ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op,
+
+/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_alu1_op,
+ &vector_alu1_op, &vector_alu1_op, INVALID, INVALID,
+ &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_alu1_op,
+ &vector_alu1_op, &vector_alu1_op, INVALID, &vector_mul_op,
+
+/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_alu1_op,
+ &vector_lss_op, &vector_lss_op, &alux_op, &alu_op,
+ INVALID, INVALID, &vector_alu1_op, &vector_alu1_op,
+ &vector_bsx_op, &vector_bsx_op, &alux_op, &alu_op,
+
+/*c0*/ &vector_alux1_op, &vector_alu1_op, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ &bswap_op, &bswap_op, &bswap_op, &bswap_op,
+ &bswap_op, &bswap_op, &bswap_op, &bswap_op,
+
+/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op,
+ INVALID, &mmx_mul_op, INVALID, INVALID,
+ &mmx_op, &mmx_op, INVALID, &mmx_op,
+ &mmx_op, &mmx_op, INVALID, &mmx_op,
+
+/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID,
+ INVALID, &pmul_op, INVALID, INVALID,
+ &mmx_op, &mmx_op, INVALID, &mmx_op,
+ &mmx_op, &mmx_op, INVALID, &mmx_op,
+
+/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op,
+ INVALID, &pmul_op, INVALID, INVALID,
+ &mmx_op, &mmx_op, &mmx_op, INVALID,
+ &mmx_op, &mmx_op, &mmx_op, INVALID,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_0f0f[256] = {
+ // clang-format off
+/*00*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, &load_3dn_op, INVALID, INVALID,
+
+/*10*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, &load_3dn_op, INVALID, INVALID,
+
+/*20*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*30*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*40*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*50*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*60*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*70*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*80*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*90*/ &load_3dn_op, INVALID, INVALID, INVALID,
+ &load_3dn_op, INVALID, &load_3dn_op, &load_3dn_op,
+ INVALID, INVALID, &load_3dn_op, INVALID,
+ INVALID, INVALID, &load_3dn_op, INVALID,
+
+/*a0*/ &load_3dn_op, INVALID, INVALID, INVALID,
+ &load_3dn_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
+ INVALID, INVALID, &load_3dn_op, INVALID,
+ INVALID, INVALID, &load_3dn_op, INVALID,
+
+/*b0*/ &load_3dn_op, INVALID, INVALID, INVALID,
+ &load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, &load_mmx_op,
+
+/*c0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*d0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*e0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*f0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_0f0f_mod3[256] = {
+ // clang-format off
+/*00*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, &m3dn_op, INVALID, INVALID,
+
+/*10*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, &m3dn_op, INVALID, INVALID,
+
+/*20*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*30*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*40*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*50*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*60*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*70*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*80*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*90*/ &m3dn_op, INVALID, INVALID, INVALID,
+ &m3dn_op, INVALID, &m3dn_op, &m3dn_op,
+ INVALID, INVALID, &m3dn_op, INVALID,
+ INVALID, INVALID, &m3dn_op, INVALID,
+
+/*a0*/ &m3dn_op, INVALID, INVALID, INVALID,
+ &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op,
+ INVALID, INVALID, &m3dn_op, INVALID,
+ INVALID, INVALID, &m3dn_op, INVALID,
+
+/*b0*/ &m3dn_op, INVALID, INVALID, INVALID,
+ &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, &mmx_op,
+
+/*c0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*d0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*e0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/*f0*/ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_shift[8] = {
+ // clang-format off
+ &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
+ &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_shift_b[8] = {
+ // clang-format off
+ &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
+ &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_shift_mod3[8] = {
+ // clang-format off
+ &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op,
+ &alu_op, &alu_op, &alu_op, &alu_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_shift_b_mod3[8] = {
+ // clang-format off
+ &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op,
+ &alux_op, &alux_op, &alux_op, &alux_op
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_80[8] = {
+ // clang-format off
+ &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
+ &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_80_mod3[8] = {
+ // clang-format off
+ &alux_op, &alux_op, &alux_store_op, &alux_store_op,
+ &alux_op, &alux_op, &alux_op, &alux_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_8x[8] = {
+ // clang-format off
+ &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
+ &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_8x_mod3[8] = {
+ // clang-format off
+ &alu_op, &alu_op, &alu_store_op, &alu_store_op,
+ &alu_op, &alu_op, &alu_op, &alu_op,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_f6[8] = {
+ // clang-format off
+/* TST NOT NEG*/
+ &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op,
+/* MUL IMUL DIV IDIV*/
+ &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_f6_mod3[8] = {
+ // clang-format off
+/* TST NOT NEG*/
+ &test_reg_b_op, INVALID, &alux_op, &alux_op,
+/* MUL IMUL DIV IDIV*/
+ &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_f7[8] = {
+ // clang-format off
+/* TST NOT NEG*/
+ &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op,
+/* MUL IMUL DIV IDIV*/
+ &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_f7_mod3[8] = {
+ // clang-format off
+/* TST NOT NEG*/
+ &test_reg_op, INVALID, &alu_op, &alu_op,
+/* MUL IMUL DIV IDIV*/
+ &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_ff[8] = {
+ // clang-format off
+/* INC DEC CALL CALL far*/
+ &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op,
+/* JMP JMP far PUSH*/
+ &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_ff_mod3[8] = {
+ // clang-format off
+/* INC DEC CALL CALL far*/
+ &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op,
+/* JMP JMP far PUSH*/
+ &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_d8[8] = {
+ // clang-format off
+/* FADDs FMULs FCOMs FCOMPs*/
+ &load_float_op, &load_float_op, &load_float_op, &load_float_op,
+/* FSUBs FSUBRs FDIVs FDIVRs*/
+ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_d8_mod3[8] = {
+ // clang-format off
+/* FADD FMUL FCOM FCOMP*/
+ &float_op, &float_op, &float_op, &float_op,
+/* FSUB FSUBR FDIV FDIVR*/
+ &float_op, &float_op, &fdiv_op, &fdiv_op,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_d9[8] = {
+ // clang-format off
+/* FLDs FSTs FSTPs*/
+ &load_float_op, INVALID, &fstore_op, &fstore_op,
+/* FLDENV FLDCW FSTENV FSTCW*/
+ &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_d9_mod3[64] = {
+ // clang-format off
+ /*FLD*/
+ &float_op, &float_op, &float_op, &float_op,
+ &float_op, &float_op, &float_op, &float_op,
+ /*FXCH*/
+ &float_op, &float_op, &float_op, &float_op,
+ &float_op, &float_op, &float_op, &float_op,
+ /*FNOP*/
+ &float_op, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ /*FSTP*/
+ &float_op, &float_op, &float_op, &float_op,
+ &float_op, &float_op, &float_op, &float_op,
+/* opFCHS opFABS*/
+ &float_op, &float_op, INVALID, INVALID,
+/* opFTST opFXAM*/
+ &float_op, &float_op, INVALID, INVALID,
+/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/
+ &float_op, &float_op, &float_op, &float_op,
+/* opFLDEG2 opFLDLN2 opFLDZ*/
+ &float_op, &float_op, &float_op, INVALID,
+/* opF2XM1 opFYL2X opFPTAN opFPATAN*/
+ &fsin_op, &fsin_op, &fsin_op, &fsin_op,
+/* opFDECSTP opFINCSTP,*/
+ INVALID, INVALID, &float_op, &float_op,
+/* opFPREM opFSQRT opFSINCOS*/
+ &fdiv_op, INVALID, &fsqrt_op, &fsin_op,
+/* opFRNDINT opFSCALE opFSIN opFCOS*/
+ &float_op, &fdiv_op, &fsin_op, &fsin_op
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_da[8] = {
+ // clang-format off
+/* FIADDl FIMULl FICOMl FICOMPl*/
+ &load_float_op, &load_float_op, &load_float_op, &load_float_op,
+/* FISUBl FISUBRl FIDIVl FIDIVRl*/
+ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_da_mod3[8] = {
+ // clang-format off
+ INVALID, INVALID, INVALID, INVALID,
+/* FCOMPP*/
+ INVALID, &float_op, INVALID, INVALID
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_db[8] = {
+ // clang-format off
+/* FLDil FSTil FSTPil*/
+ &load_float_op, INVALID, &fstore_op, &fstore_op,
+/* FLDe FSTPe*/
+ INVALID, &vector_flde_op, INVALID, &vector_fste_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_db_mod3[64] = {
+ // clang-format off
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+/* opFNOP opFCLEX opFINIT*/
+ INVALID, &float_op, &float_op, &float_op,
+/* opFNOP opFNOP*/
+ &float_op, &float_op, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+
+ INVALID, INVALID, INVALID, INVALID,
+ INVALID, INVALID, INVALID, INVALID,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_dc[8] = {
+ // clang-format off
+/* FADDd FMULd FCOMd FCOMPd*/
+ &load_float_op, &load_float_op, &load_float_op, &load_float_op,
+/* FSUBd FSUBRd FDIVd FDIVRd*/
+ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_dc_mod3[8] = {
+ // clang-format off
+/* opFADDr opFMULr*/
+ &float_op, &float_op, INVALID, INVALID,
+/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
+ &float_op, &float_op, &fdiv_op, &fdiv_op
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_dd[8] = {
+ // clang-format off
+/* FLDd FSTd FSTPd*/
+ &load_float_op, INVALID, &fstore_op, &fstore_op,
+/* FRSTOR FSAVE FSTSW*/
+ &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_dd_mod3[8] = {
+ // clang-format off
+/* FFFREE FST FSTP*/
+ &float_op, INVALID, &float_op, &float_op,
+/* FUCOM FUCOMP*/
+ &float_op, &float_op, INVALID, INVALID
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_de[8] = {
+ // clang-format off
+/* FIADDw FIMULw FICOMw FICOMPw*/
+ &load_float_op, &load_float_op, &load_float_op, &load_float_op,
+/* FISUBw FISUBRw FIDIVw FIDIVRw*/
+ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_de_mod3[8] = {
+ // clang-format off
+/* FADDP FMULP FCOMPP*/
+ &float_op, &float_op, INVALID, &float_op,
+/* FSUBP FSUBRP FDIVP FDIVRP*/
+ &float_op, &float_op, &fdiv_op, &fdiv_op,
+ // clang-format on
+};
+
+static const risc86_instruction_t *opcode_timings_k5_df[8] = {
+ // clang-format off
+/* FILDiw FISTiw FISTPiw*/
+ &load_float_op, INVALID, &fstore_op, &fstore_op,
+/* FILDiq FBSTP FISTPiq*/
+ INVALID, &load_float_op, &vector_float_l_op, &fstore_op,
+ // clang-format on
+};
+static const risc86_instruction_t *opcode_timings_k5_df_mod3[8] = {
+ // clang-format off
+ INVALID, INVALID, INVALID, INVALID,
+/* FSTSW AX*/
+ &float_op, INVALID, INVALID, INVALID
+ // clang-format on
+};
+
+static uint8_t last_prefix;
+static int prefixes;
+
+static int decode_timestamp;
+static int last_complete_timestamp;
+
+typedef struct k5_unit_t {
+ uint32_t uop_mask;
+ int first_available_cycle;
+} k5_unit_t;
+
+static int nr_units;
+static k5_unit_t *units;
+
+/*k5 has dedicated MMX unit*/
+static k5_unit_t k5_units[] = {
+ { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) }, /*Integer X*/
+ { .uop_mask = (1 << UOP_ALU) }, /*Integer Y*/
+ { .uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) }, /*Multimedia*/
+ { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/
+ { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/
+ { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/
+ { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/
+};
+#define NR_k5_UNITS (sizeof(k5_units) / sizeof(k5_unit_t))
+
+/*k5-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and
+ 3DNow ALU between two execution units*/
+static k5_unit_t k5_2_units[] = {
+ { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/
+ (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) },
+ { .uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/
+ (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) },
+ { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/
+ { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/
+ { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/
+ { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/
+};
+#define NR_k5_2_UNITS (sizeof(k5_2_units) / sizeof(k5_unit_t))
+
+/*First available cycles of shared execution units. Each of these can be submitted
+ to by ALU X and Y*/
+static int mul_first_available_cycle;
+static int shift_first_available_cycle;
+static int m3dnow_first_available_cycle;
+
+static int
+uop_run(const risc86_uop_t *uop, int decode_time)
+{
+ k5_unit_t *best_unit = NULL;
+ int best_start_cycle = 99999;
+
+ /*UOP_LIMM does not require execution*/
+ if (uop->type == UOP_LIMM)
+ return decode_time;
+
+ /*Handle shared units on k5-2 and later*/
+ if (units == k5_2_units) {
+ if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle)
+ decode_time = mul_first_available_cycle;
+ else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle)
+ decode_time = shift_first_available_cycle;
+ else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle)
+ decode_time = m3dnow_first_available_cycle;
+ }
+
+ /*Find execution unit for this uOP*/
+ for (int c = 0; c < nr_units; c++) {
+ if (units[c].uop_mask & (1 << uop->type)) {
+ if (units[c].first_available_cycle < best_start_cycle) {
+ best_unit = &units[c];
+ best_start_cycle = units[c].first_available_cycle;
+ }
+ }
+ }
+ if (!best_unit)
+ fatal("uop_run: can not find execution unit\n");
+
+ if (best_start_cycle < decode_time)
+ best_start_cycle = decode_time;
+ best_unit->first_available_cycle = best_start_cycle + uop->throughput;
+
+ if (units == k5_2_units) {
+ if (uop->type == UOP_MEU_MUL)
+ mul_first_available_cycle = best_start_cycle + uop->throughput;
+ else if (uop->type == UOP_MEU_SHIFT)
+ shift_first_available_cycle = best_start_cycle + uop->throughput;
+ else if (uop->type == UOP_MEU_3DN)
+ m3dnow_first_available_cycle = best_start_cycle + uop->throughput;
+ }
+
+ return best_start_cycle + uop->throughput;
+}
+
+/*The k5 decoder can decode, per clock :
+ - 1 or 2 'short' instructions, each up to 2 uOPs and 7 bytes long
+ - 1 'long' instruction, up to 4 uOPs
+ - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay)
+*/
+static struct {
+ int nr_uops;
+ const risc86_uop_t *uops[4];
+ /*Earliest time a uop can start. If the timestamp is -1, then the uop is
+ part of a dependency chain and the start time is the completion time of
+ the previous uop*/
+ int earliest_start[4];
+} decode_buffer;
+
+#define NR_OPQUADS 6
+/*Timestamps of when the last six opquads completed. The k5 scheduler retires
+ opquads in order, so this is needed to determine when the next can be scheduled*/
+static int opquad_completion_timestamp[NR_OPQUADS];
+static int next_opquad = 0;
+
+#define NR_REGS 8
+/*Timestamp of when last operation on an integer register completed*/
+static int reg_available_timestamp[NR_REGS];
+/*Timestamp of when last operation on an FPU register completed*/
+static int fpu_st_timestamp[8];
+/*Completion time of the last uop to be processed. Used to calculate timing of
+ dependent uop chains*/
+static int last_uop_timestamp = 0;
+
+void
+decode_flush_k5(void)
+{
+ int uop_timestamp = 0;
+
+ /*Decoded opquad can not be submitted if there are no free spaces in the
+ opquad buffer*/
+ if (decode_timestamp < opquad_completion_timestamp[next_opquad])
+ decode_timestamp = opquad_completion_timestamp[next_opquad];
+
+ /*Ensure that uops can not be submitted before they have been decoded*/
+ if (decode_timestamp > last_uop_timestamp)
+ last_uop_timestamp = decode_timestamp;
+
+ /*Submit uops to execution units, and determine the latest completion time*/
+ for (int c = 0; c < decode_buffer.nr_uops; c++) {
+ int start_timestamp;
+
+ if (decode_buffer.earliest_start[c] == -1)
+ start_timestamp = last_uop_timestamp;
+ else
+ start_timestamp = decode_buffer.earliest_start[c];
+
+ last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp);
+ if (last_uop_timestamp > uop_timestamp)
+ uop_timestamp = last_uop_timestamp;
+ }
+
+ /*Calculate opquad completion time. Since opquads complete in order, it
+ must be after the last completion.*/
+ if (uop_timestamp <= last_complete_timestamp)
+ last_complete_timestamp = last_complete_timestamp + 1;
+ else
+ last_complete_timestamp = uop_timestamp;
+
+ /*Advance to next opquad in buffer*/
+ opquad_completion_timestamp[next_opquad] = last_complete_timestamp;
+ next_opquad++;
+ if (next_opquad == NR_OPQUADS)
+ next_opquad = 0;
+
+ decode_timestamp++;
+ decode_buffer.nr_uops = 0;
+}
+
+/*The instruction is only of interest here if it's longer than 7 bytes, as that's the
+ limit on k5 short decoding*/
+static int
+codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32)
+{
+ int len = prefixes + 1; /*Opcode*/
+ if (deps & MODRM) {
+ len++; /*ModR/M*/
+ if (deps & HAS_IMM8)
+ len++;
+ if (deps & HAS_IMM1632)
+ len += (op_32 & 0x100) ? 4 : 2;
+
+ if (op_32 & 0x200) {
+ if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) {
+ /* Has SIB*/
+ len++;
+ if ((fetchdat & 0xc0) == 0x40)
+ len++;
+ else if ((fetchdat & 0xc0) == 0x80)
+ len += 4;
+ else if ((fetchdat & 0x700) == 0x500)
+ len += 4;
+ } else {
+ if ((fetchdat & 0xc0) == 0x40)
+ len++;
+ else if ((fetchdat & 0xc0) == 0x80)
+ len += 4;
+ else if ((fetchdat & 0xc7) == 0x05)
+ len += 4;
+ }
+ } else {
+ if ((fetchdat & 0xc0) == 0x40)
+ len++;
+ else if ((fetchdat & 0xc0) == 0x80)
+ len += 2;
+ else if ((fetchdat & 0xc7) == 0x06)
+ len += 2;
+ }
+ }
+
+ return len;
+}
+
+static void
+decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8)
+{
+ uint32_t regmask_required;
+ uint32_t regmask_modified;
+ int c;
+ int d;
+ int earliest_start = 0;
+ decode_type_t decode_type = ins->decode_type;
+ int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32);
+
+ /*Generate input register mask, and determine the earliest time this
+ instruction can start. This is not accurate, as this is calculated per
+ x86 instruction when it should be handled per uop*/
+ regmask_required = get_dstdep_mask(deps, fetchdat, bit8);
+ regmask_required |= get_addr_regmask(deps, fetchdat, op_32);
+ for (c = 0; c < 8; c++) {
+ if (regmask_required & (1 << c)) {
+ if (reg_available_timestamp[c] > decode_timestamp)
+ earliest_start = reg_available_timestamp[c];
+ }
+ }
+ if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp)
+ earliest_start = fpu_st_timestamp[0];
+ if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp)
+ earliest_start = fpu_st_timestamp[1];
+ if (deps & FPU_RW_STREG) {
+ int reg = fetchdat & 7;
+
+ if (fpu_st_timestamp[reg] > decode_timestamp)
+ earliest_start = fpu_st_timestamp[reg];
+ }
+
+ /*Short decoders are limited to 7 bytes*/
+ if (decode_type == DECODE_SHORT && instr_length > 7)
+ decode_type = DECODE_LONG;
+ /*Long decoder is limited to 11 bytes*/
+ else if (instr_length > 11)
+ decode_type = DECODE_VECTOR;
+
+ switch (decode_type) {
+ case DECODE_SHORT:
+ if (decode_buffer.nr_uops) {
+ decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0];
+ decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start;
+ if (ins->nr_uops > 1) {
+ decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1];
+ decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1;
+ }
+ decode_buffer.nr_uops += ins->nr_uops;
+
+ decode_flush_k5();
+ } else {
+ decode_buffer.nr_uops = ins->nr_uops;
+ decode_buffer.uops[0] = &ins->uop[0];
+ decode_buffer.earliest_start[0] = earliest_start;
+ if (ins->nr_uops > 1) {
+ decode_buffer.uops[1] = &ins->uop[1];
+ decode_buffer.earliest_start[1] = -1;
+ }
+ }
+ break;
+
+ case DECODE_LONG:
+ if (decode_buffer.nr_uops)
+ decode_flush_k5();
+
+ decode_buffer.nr_uops = ins->nr_uops;
+ for (c = 0; c < ins->nr_uops; c++) {
+ decode_buffer.uops[c] = &ins->uop[c];
+ if (c == 0)
+ decode_buffer.earliest_start[c] = earliest_start;
+ else
+ decode_buffer.earliest_start[c] = -1;
+ }
+ decode_flush_k5();
+ break;
+
+ case DECODE_VECTOR:
+ if (decode_buffer.nr_uops)
+ decode_flush_k5();
+
+ decode_timestamp++;
+ d = 0;
+
+ for (c = 0; c < ins->nr_uops; c++) {
+ decode_buffer.uops[d] = &ins->uop[c];
+ if (c == 0)
+ decode_buffer.earliest_start[d] = earliest_start;
+ else
+ decode_buffer.earliest_start[d] = -1;
+ d++;
+
+ if (d == 4) {
+ d = 0;
+ decode_buffer.nr_uops = 4;
+ decode_flush_k5();
+ }
+ }
+ if (d) {
+ decode_buffer.nr_uops = d;
+ decode_flush_k5();
+ }
+ break;
+ }
+
+ /*Update write timestamps for any output registers*/
+ regmask_modified = get_dstdep_mask(deps, fetchdat, bit8);
+ for (c = 0; c < 8; c++) {
+ if (regmask_modified & (1 << c))
+ reg_available_timestamp[c] = last_complete_timestamp;
+ }
+ if (deps & FPU_POP) {
+ for (c = 0; c < 7; c++)
+ fpu_st_timestamp[c] = fpu_st_timestamp[c + 1];
+ fpu_st_timestamp[7] = 0;
+ }
+ if (deps & FPU_POP2) {
+ for (c = 0; c < 6; c++)
+ fpu_st_timestamp[c] = fpu_st_timestamp[c + 2];
+ fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0;
+ }
+ if (deps & FPU_PUSH) {
+ for (c = 0; c < 7; c++)
+ fpu_st_timestamp[c + 1] = fpu_st_timestamp[c];
+ fpu_st_timestamp[0] = 0;
+ }
+ if (deps & FPU_WRITE_ST0)
+ fpu_st_timestamp[0] = last_complete_timestamp;
+ if (deps & FPU_WRITE_ST1)
+ fpu_st_timestamp[1] = last_complete_timestamp;
+ if (deps & FPU_WRITE_STREG) {
+ int reg = fetchdat & 7;
+ if (deps & FPU_POP)
+ reg--;
+ if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1)))
+ fpu_st_timestamp[reg] = last_complete_timestamp;
+ }
+}
+
+void
+codegen_timing_k5_block_start(void)
+{
+ int c;
+
+ for (c = 0; c < nr_units; c++)
+ units[c].first_available_cycle = 0;
+
+ mul_first_available_cycle = 0;
+ shift_first_available_cycle = 0;
+ m3dnow_first_available_cycle = 0;
+
+ decode_timestamp = 0;
+ last_complete_timestamp = 0;
+
+ for (c = 0; c < NR_OPQUADS; c++)
+ opquad_completion_timestamp[c] = 0;
+ next_opquad = 0;
+
+ for (c = 0; c < NR_REGS; c++)
+ reg_available_timestamp[c] = 0;
+ for (c = 0; c < 8; c++)
+ fpu_st_timestamp[c] = 0;
+}
+
+void
+codegen_timing_k5_start(void)
+{
+ if (cpu_s->cpu_type == CPU_K5) {
+ units = k5_units;
+ nr_units = NR_k5_UNITS;
+ } else {
+ units = k5_2_units;
+ nr_units = NR_k5_2_UNITS;
+ }
+ last_prefix = 0;
+ prefixes = 0;
+}
+
+void
+codegen_timing_k5_prefix(uint8_t prefix, uint32_t fetchdat)
+{
+ if (prefix != 0x0f)
+ decode_timestamp++;
+
+ last_prefix = prefix;
+ prefixes++;
+}
+
+void
+codegen_timing_k5_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
+{
+ const risc86_instruction_t **ins_table;
+ const uint64_t *deps;
+ int mod3 = ((fetchdat & 0xc0) == 0xc0);
+ int old_last_complete_timestamp = last_complete_timestamp;
+ int bit8 = !(opcode & 1);
+
+ switch (last_prefix) {
+ case 0x0f:
+ if (opcode == 0x0f) {
+ /*3DNow has the actual opcode after ModR/M, SIB and any offset*/
+ uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/
+ uint8_t modrm = fetchdat & 0xff;
+ uint8_t sib = (fetchdat >> 8) & 0xff;
+
+ if ((modrm & 0xc0) != 0xc0) {
+ if (op_32 & 0x200) {
+ if ((modrm & 7) == 4) {
+ /* Has SIB*/
+ opcode_pc++;
+ if ((modrm & 0xc0) == 0x40)
+ opcode_pc++;
+ else if ((modrm & 0xc0) == 0x80)
+ opcode_pc += 4;
+ else if ((sib & 0x07) == 0x05)
+ opcode_pc += 4;
+ } else {
+ if ((modrm & 0xc0) == 0x40)
+ opcode_pc++;
+ else if ((modrm & 0xc0) == 0x80)
+ opcode_pc += 4;
+ else if ((modrm & 0xc7) == 0x05)
+ opcode_pc += 4;
+ }
+ } else {
+ if ((modrm & 0xc0) == 0x40)
+ opcode_pc++;
+ else if ((modrm & 0xc0) == 0x80)
+ opcode_pc += 2;
+ else if ((modrm & 0xc7) == 0x06)
+ opcode_pc += 2;
+ }
+ }
+
+ opcode = fastreadb(cs + opcode_pc);
+
+ ins_table = mod3 ? opcode_timings_k5_0f0f_mod3 : opcode_timings_k5_0f0f;
+ deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f;
+ } else {
+ ins_table = mod3 ? opcode_timings_k5_0f_mod3 : opcode_timings_k5_0f;
+ deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
+ }
+ break;
+
+ case 0xd8:
+ ins_table = mod3 ? opcode_timings_k5_d8_mod3 : opcode_timings_k5_d8;
+ deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
+ opcode = (opcode >> 3) & 7;
+ break;
+ case 0xd9:
+ ins_table = mod3 ? opcode_timings_k5_d9_mod3 : opcode_timings_k5_d9;
+ deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
+ opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
+ break;
+ case 0xda:
+ ins_table = mod3 ? opcode_timings_k5_da_mod3 : opcode_timings_k5_da;
+ deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
+ opcode = (opcode >> 3) & 7;
+ break;
+ case 0xdb:
+ ins_table = mod3 ? opcode_timings_k5_db_mod3 : opcode_timings_k5_db;
+ deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
+ opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
+ break;
+ case 0xdc:
+ ins_table = mod3 ? opcode_timings_k5_dc_mod3 : opcode_timings_k5_dc;
+ deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
+ opcode = (opcode >> 3) & 7;
+ break;
+ case 0xdd:
+ ins_table = mod3 ? opcode_timings_k5_dd_mod3 : opcode_timings_k5_dd;
+ deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
+ opcode = (opcode >> 3) & 7;
+ break;
+ case 0xde:
+ ins_table = mod3 ? opcode_timings_k5_de_mod3 : opcode_timings_k5_de;
+ deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
+ opcode = (opcode >> 3) & 7;
+ break;
+ case 0xdf:
+ ins_table = mod3 ? opcode_timings_k5_df_mod3 : opcode_timings_k5_df;
+ deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
+ opcode = (opcode >> 3) & 7;
+ break;
+
+ default:
+ switch (opcode) {
+ case 0x80:
+ case 0x82:
+ ins_table = mod3 ? opcode_timings_k5_80_mod3 : opcode_timings_k5_80;
+ deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+ case 0x81:
+ case 0x83:
+ ins_table = mod3 ? opcode_timings_k5_8x_mod3 : opcode_timings_k5_8x;
+ deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+
+ case 0xc0:
+ case 0xd0:
+ case 0xd2:
+ ins_table = mod3 ? opcode_timings_k5_shift_b_mod3 : opcode_timings_k5_shift_b;
+ deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+
+ case 0xc1:
+ case 0xd1:
+ case 0xd3:
+ ins_table = mod3 ? opcode_timings_k5_shift_mod3 : opcode_timings_k5_shift;
+ deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+
+ case 0xf6:
+ ins_table = mod3 ? opcode_timings_k5_f6_mod3 : opcode_timings_k5_f6;
+ deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+ case 0xf7:
+ ins_table = mod3 ? opcode_timings_k5_f7_mod3 : opcode_timings_k5_f7;
+ deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+ case 0xff:
+ ins_table = mod3 ? opcode_timings_k5_ff_mod3 : opcode_timings_k5_ff;
+ deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
+ opcode = (fetchdat >> 3) & 7;
+ break;
+
+ default:
+ ins_table = mod3 ? opcode_timings_k5_mod3 : opcode_timings_k5;
+ deps = mod3 ? opcode_deps_mod3 : opcode_deps;
+ break;
+ }
+ }
+
+ if (ins_table[opcode])
+ decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8);
+ else
+ decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8);
+ codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp);
+}
+
+void
+codegen_timing_k5_block_end(void)
+{
+ if (decode_buffer.nr_uops) {
+ int old_last_complete_timestamp = last_complete_timestamp;
+ decode_flush_k5();
+ codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp);
+ }
+}
+
+int
+codegen_timing_k5_jump_cycles(void)
+{
+ if (decode_buffer.nr_uops)
+ return 1;
+ return 0;
+}
+
+codegen_timing_t codegen_timing_k5 = {
+ codegen_timing_k5_start,
+ codegen_timing_k5_prefix,
+ codegen_timing_k5_opcode,
+ codegen_timing_k5_block_start,
+ codegen_timing_k5_block_end,
+ codegen_timing_k5_jump_cycles
+};
diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c
index 4a9f23cd82..5566fbbcd8 100644
--- a/src/cpu/codegen_timing_k6.c
+++ b/src/cpu/codegen_timing_k6.c
@@ -1,5 +1,5 @@
/*Most of the vector instructions here are a total guess.
- Some of the timings are based on http://http://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/
+ Some of the timings are based on https://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/
#include
#include
#include
@@ -12,6 +12,7 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "386_common.h"
#include "codegen.h"
@@ -758,7 +759,7 @@ static const risc86_instruction_t vector_wbinvd_op = {
#define INVALID NULL
-static const risc86_instruction_t *opcode_timings[256] = {
+static const risc86_instruction_t *opcode_timings_k6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
@@ -895,7 +896,7 @@ static const risc86_instruction_t *opcode_timings[256] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_mod3[256] = {
+static const risc86_instruction_t *opcode_timings_k6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alux_op, &alu_op, &alux_op, &alu_op,
@@ -1032,7 +1033,7 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_0f[256] = {
+static const risc86_instruction_t *opcode_timings_k6_0f[256] = {
// clang-format off
/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
@@ -1115,7 +1116,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = {
&load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_0f_mod3[256] = {
+static const risc86_instruction_t *opcode_timings_k6_0f_mod3[256] = {
// clang-format off
/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
@@ -1199,7 +1200,7 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_0f0f[256] = {
+static const risc86_instruction_t *opcode_timings_k6_0f0f[256] = {
// clang-format off
/*00*/ INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1282,7 +1283,7 @@ static const risc86_instruction_t *opcode_timings_0f0f[256] = {
INVALID, INVALID, INVALID, INVALID,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = {
+static const risc86_instruction_t *opcode_timings_k6_0f0f_mod3[256] = {
// clang-format off
/*00*/ INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1366,57 +1367,57 @@ static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_shift[8] = {
+static const risc86_instruction_t *opcode_timings_k6_shift[8] = {
// clang-format off
&vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
&vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_shift_b[8] = {
+static const risc86_instruction_t *opcode_timings_k6_shift_b[8] = {
// clang-format off
&vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
&vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_shift_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_shift_mod3[8] = {
// clang-format off
&vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op,
&alu_op, &alu_op, &alu_op, &alu_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_shift_b_mod3[8] = {
// clang-format off
&vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op,
&alux_op, &alux_op, &alux_op, &alux_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_80[8] = {
+static const risc86_instruction_t *opcode_timings_k6_80[8] = {
// clang-format off
&alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
&alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_80_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_80_mod3[8] = {
// clang-format off
&alux_op, &alux_op, &alux_store_op, &alux_store_op,
&alux_op, &alux_op, &alux_op, &alux_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_8x[8] = {
+static const risc86_instruction_t *opcode_timings_k6_8x[8] = {
// clang-format off
&alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_8x_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_8x_mod3[8] = {
// clang-format off
&alu_op, &alu_op, &alu_store_op, &alu_store_op,
&alu_op, &alu_op, &alu_op, &alu_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_f6[8] = {
+static const risc86_instruction_t *opcode_timings_k6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op,
@@ -1424,7 +1425,7 @@ static const risc86_instruction_t *opcode_timings_f6[8] = {
&vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_f6_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_b_op, INVALID, &alux_op, &alux_op,
@@ -1432,7 +1433,7 @@ static const risc86_instruction_t *opcode_timings_f6_mod3[8] = {
&vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_f7[8] = {
+static const risc86_instruction_t *opcode_timings_k6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op,
@@ -1440,7 +1441,7 @@ static const risc86_instruction_t *opcode_timings_f7[8] = {
&vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_f7_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_op, INVALID, &alu_op, &alu_op,
@@ -1448,7 +1449,7 @@ static const risc86_instruction_t *opcode_timings_f7_mod3[8] = {
&vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_ff[8] = {
+static const risc86_instruction_t *opcode_timings_k6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&alu_store_op, &alu_store_op, &store_op, &vector_call_far_op,
@@ -1456,7 +1457,7 @@ static const risc86_instruction_t *opcode_timings_ff[8] = {
&branch_op, &vector_jmp_far_op, &push_mem_op, INVALID
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_ff_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op,
@@ -1465,7 +1466,7 @@ static const risc86_instruction_t *opcode_timings_ff_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_d8[8] = {
+static const risc86_instruction_t *opcode_timings_k6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1473,7 +1474,7 @@ static const risc86_instruction_t *opcode_timings_d8[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_d8_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
&float_op, &float_op, &float_op, &float_op,
@@ -1482,7 +1483,7 @@ static const risc86_instruction_t *opcode_timings_d8_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_d9[8] = {
+static const risc86_instruction_t *opcode_timings_k6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1490,7 +1491,7 @@ static const risc86_instruction_t *opcode_timings_d9[8] = {
&vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_d9_mod3[64] = {
+static const risc86_instruction_t *opcode_timings_k6_d9_mod3[64] = {
// clang-format off
/*FLD*/
&float_op, &float_op, &float_op, &float_op,
@@ -1523,7 +1524,7 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_da[8] = {
+static const risc86_instruction_t *opcode_timings_k6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1531,7 +1532,7 @@ static const risc86_instruction_t *opcode_timings_da[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_da_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -1539,7 +1540,7 @@ static const risc86_instruction_t *opcode_timings_da_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_db[8] = {
+static const risc86_instruction_t *opcode_timings_k6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1547,7 +1548,7 @@ static const risc86_instruction_t *opcode_timings_db[8] = {
INVALID, &vector_flde_op, INVALID, &vector_fste_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_db_mod3[64] = {
+static const risc86_instruction_t *opcode_timings_k6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1577,7 +1578,7 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_dc[8] = {
+static const risc86_instruction_t *opcode_timings_k6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1585,7 +1586,7 @@ static const risc86_instruction_t *opcode_timings_dc[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_dc_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
&float_op, &float_op, INVALID, INVALID,
@@ -1594,7 +1595,7 @@ static const risc86_instruction_t *opcode_timings_dc_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_dd[8] = {
+static const risc86_instruction_t *opcode_timings_k6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1602,7 +1603,7 @@ static const risc86_instruction_t *opcode_timings_dd[8] = {
&vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_dd_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
&float_op, INVALID, &float_op, &float_op,
@@ -1611,7 +1612,7 @@ static const risc86_instruction_t *opcode_timings_dd_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_de[8] = {
+static const risc86_instruction_t *opcode_timings_k6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1619,7 +1620,7 @@ static const risc86_instruction_t *opcode_timings_de[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_de_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
&float_op, &float_op, INVALID, &float_op,
@@ -1628,7 +1629,7 @@ static const risc86_instruction_t *opcode_timings_de_mod3[8] = {
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_df[8] = {
+static const risc86_instruction_t *opcode_timings_k6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1636,7 +1637,7 @@ static const risc86_instruction_t *opcode_timings_df[8] = {
INVALID, &load_float_op, &vector_float_l_op, &fstore_op,
// clang-format on
};
-static const risc86_instruction_t *opcode_timings_df_mod3[8] = {
+static const risc86_instruction_t *opcode_timings_k6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -1768,7 +1769,7 @@ static int fpu_st_timestamp[8];
static int last_uop_timestamp = 0;
void
-decode_flush(void)
+decode_flush_k6(void)
{
int uop_timestamp = 0;
@@ -1907,7 +1908,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
}
decode_buffer.nr_uops += ins->nr_uops;
- decode_flush();
+ decode_flush_k6();
} else {
decode_buffer.nr_uops = ins->nr_uops;
decode_buffer.uops[0] = &ins->uop[0];
@@ -1921,7 +1922,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
case DECODE_LONG:
if (decode_buffer.nr_uops)
- decode_flush();
+ decode_flush_k6();
decode_buffer.nr_uops = ins->nr_uops;
for (c = 0; c < ins->nr_uops; c++) {
@@ -1931,12 +1932,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
else
decode_buffer.earliest_start[c] = -1;
}
- decode_flush();
+ decode_flush_k6();
break;
case DECODE_VECTOR:
if (decode_buffer.nr_uops)
- decode_flush();
+ decode_flush_k6();
decode_timestamp++;
d = 0;
@@ -1952,12 +1953,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
if (d == 4) {
d = 0;
decode_buffer.nr_uops = 4;
- decode_flush();
+ decode_flush_k6();
}
}
if (d) {
decode_buffer.nr_uops = d;
- decode_flush();
+ decode_flush_k6();
}
break;
}
@@ -2093,51 +2094,51 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
opcode = fastreadb(cs + opcode_pc);
- ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f;
+ ins_table = mod3 ? opcode_timings_k6_0f0f_mod3 : opcode_timings_k6_0f0f;
deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f;
} else {
- ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ ins_table = mod3 ? opcode_timings_k6_0f_mod3 : opcode_timings_k6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
}
break;
case 0xd8:
- ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ ins_table = mod3 ? opcode_timings_k6_d8_mod3 : opcode_timings_k6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ ins_table = mod3 ? opcode_timings_k6_d9_mod3 : opcode_timings_k6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ ins_table = mod3 ? opcode_timings_k6_da_mod3 : opcode_timings_k6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ ins_table = mod3 ? opcode_timings_k6_db_mod3 : opcode_timings_k6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ ins_table = mod3 ? opcode_timings_k6_dc_mod3 : opcode_timings_k6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ ins_table = mod3 ? opcode_timings_k6_dd_mod3 : opcode_timings_k6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ ins_table = mod3 ? opcode_timings_k6_de_mod3 : opcode_timings_k6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ ins_table = mod3 ? opcode_timings_k6_df_mod3 : opcode_timings_k6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -2146,13 +2147,13 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
switch (opcode) {
case 0x80:
case 0x82:
- ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80;
+ ins_table = mod3 ? opcode_timings_k6_80_mod3 : opcode_timings_k6_80;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
case 0x83:
- ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ ins_table = mod3 ? opcode_timings_k6_8x_mod3 : opcode_timings_k6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
@@ -2160,7 +2161,7 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
case 0xc0:
case 0xd0:
case 0xd2:
- ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b;
+ ins_table = mod3 ? opcode_timings_k6_shift_b_mod3 : opcode_timings_k6_shift_b;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
@@ -2168,29 +2169,29 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
case 0xc1:
case 0xd1:
case 0xd3:
- ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ ins_table = mod3 ? opcode_timings_k6_shift_mod3 : opcode_timings_k6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ ins_table = mod3 ? opcode_timings_k6_f6_mod3 : opcode_timings_k6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ ins_table = mod3 ? opcode_timings_k6_f7_mod3 : opcode_timings_k6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ ins_table = mod3 ? opcode_timings_k6_ff_mod3 : opcode_timings_k6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- ins_table = mod3 ? opcode_timings_mod3 : opcode_timings;
+ ins_table = mod3 ? opcode_timings_k6_mod3 : opcode_timings_k6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
@@ -2208,7 +2209,7 @@ codegen_timing_k6_block_end(void)
{
if (decode_buffer.nr_uops) {
int old_last_complete_timestamp = last_complete_timestamp;
- decode_flush();
+ decode_flush_k6();
codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp);
}
}
diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c
index 2c087ae86c..a228130686 100644
--- a/src/cpu/codegen_timing_p6.c
+++ b/src/cpu/codegen_timing_p6.c
@@ -13,6 +13,7 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
+#include "x87_sf.h"
#include "x87.h"
#include "386_common.h"
#include "codegen.h"
@@ -786,7 +787,7 @@ static const macro_op_t wbinvd_op = {
};
#define INVALID NULL
-static const macro_op_t *opcode_timings[256] = {
+static const macro_op_t *opcode_timings_p6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op,
@@ -923,7 +924,7 @@ static const macro_op_t *opcode_timings[256] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_mod3[256] = {
+static const macro_op_t *opcode_timings_p6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op,
@@ -1061,7 +1062,7 @@ static const macro_op_t *opcode_timings_mod3[256] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_0f[256] = {
+static const macro_op_t *opcode_timings_p6_0f[256] = {
// clang-format off
/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op,
INVALID, &alu6_op, &alu6_op, INVALID,
@@ -1144,7 +1145,7 @@ static const macro_op_t *opcode_timings_0f[256] = {
&load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
// clang-format on
};
-static const macro_op_t *opcode_timings_0f_mod3[256] = {
+static const macro_op_t *opcode_timings_p6_0f_mod3[256] = {
// clang-format off
/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op,
INVALID, &alu6_op, &alu6_op, INVALID,
@@ -1227,58 +1228,58 @@ static const macro_op_t *opcode_timings_0f_mod3[256] = {
&mmx_op, &mmx_op, &mmx_op, INVALID,
};
-static const macro_op_t *opcode_timings_shift[8] =
+static const macro_op_t *opcode_timings_p6_shift[8] =
{
// clang-format off
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op
// clang-format on
};
-static const macro_op_t *opcode_timings_shift_b[8] = {
+static const macro_op_t *opcode_timings_p6_shift_b[8] = {
// clang-format off
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op
// clang-format on
};
-static const macro_op_t *opcode_timings_shift_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_shift_mod3[8] = {
// clang-format off
&complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op,
&alu_op, &alu_op, &alu_op, &alu_op
// clang-format on
};
-static const macro_op_t *opcode_timings_shift_b_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_shift_b_mod3[8] = {
// clang-format off
&complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op,
&alup0_op, &alup0_op, &alup0_op, &alup0_op
// clang-format on
};
-static const macro_op_t *opcode_timings_80[8] = {
+static const macro_op_t *opcode_timings_p6_80[8] = {
// clang-format off
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_80_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_80_mod3[8] = {
// clang-format off
&alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op,
&alup0_op, &alup0_op, &alup0_op, &alup0_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_8x[8] = {
+static const macro_op_t *opcode_timings_p6_8x[8] = {
// clang-format off
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_8x_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_8x_mod3[8] = {
// clang-format off
&alu_op, &alu_op, &alu_store_op, &alu_store_op,
&alu_op, &alu_op, &alu_op, &alu_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_f6[8] = {
+static const macro_op_t *opcode_timings_p6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op,
@@ -1286,7 +1287,7 @@ static const macro_op_t *opcode_timings_f6[8] = {
&mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_f6_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_b_op, INVALID, &alup0_op, &alup0_op,
@@ -1294,7 +1295,7 @@ static const macro_op_t *opcode_timings_f6_mod3[8] = {
&mul_op, &mul_op, &div16_op, &div16_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_f7[8] = {
+static const macro_op_t *opcode_timings_p6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op,
@@ -1302,7 +1303,7 @@ static const macro_op_t *opcode_timings_f7[8] = {
&mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_f7_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_op, INVALID, &alu_op, &alu_op,
@@ -1310,7 +1311,7 @@ static const macro_op_t *opcode_timings_f7_mod3[8] = {
&mul64_op, &mul64_op, &div32_op, &div32_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_ff[8] = {
+static const macro_op_t *opcode_timings_p6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&alu_store_op, &alu_store_op, &store_op, &call_far_op,
@@ -1318,7 +1319,7 @@ static const macro_op_t *opcode_timings_ff[8] = {
&branch_op, &jmp_far_op, &push_mem_op, INVALID
// clang-format on
};
-static const macro_op_t *opcode_timings_ff_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op,
@@ -1327,7 +1328,7 @@ static const macro_op_t *opcode_timings_ff_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_d8[8] = {
+static const macro_op_t *opcode_timings_p6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1335,7 +1336,7 @@ static const macro_op_t *opcode_timings_d8[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_d8_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
&fadd_op, &fmul_op, &float_op, &float_op,
@@ -1344,7 +1345,7 @@ static const macro_op_t *opcode_timings_d8_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_d9[8] = {
+static const macro_op_t *opcode_timings_p6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1352,7 +1353,7 @@ static const macro_op_t *opcode_timings_d9[8] = {
&complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op
// clang-format on
};
-static const macro_op_t *opcode_timings_d9_mod3[64] = {
+static const macro_op_t *opcode_timings_p6_d9_mod3[64] = {
// clang-format off
/*FLD*/
&float_op, &float_op, &float_op, &float_op,
@@ -1385,7 +1386,7 @@ static const macro_op_t *opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_da[8] = {
+static const macro_op_t *opcode_timings_p6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1393,7 +1394,7 @@ static const macro_op_t *opcode_timings_da[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_da_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -1401,7 +1402,7 @@ static const macro_op_t *opcode_timings_da_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_db[8] = {
+static const macro_op_t *opcode_timings_p6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1409,7 +1410,7 @@ static const macro_op_t *opcode_timings_db[8] = {
INVALID, &flde_op, INVALID, &fste_op
// clang-format on
};
-static const macro_op_t *opcode_timings_db_mod3[64] = {
+static const macro_op_t *opcode_timings_p6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1439,7 +1440,7 @@ static const macro_op_t *opcode_timings_db_mod3[64] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_dc[8] = {
+static const macro_op_t *opcode_timings_p6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1447,7 +1448,7 @@ static const macro_op_t *opcode_timings_dc[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_dc_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
&fadd_op, &fmul_op, INVALID, INVALID,
@@ -1456,7 +1457,7 @@ static const macro_op_t *opcode_timings_dc_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_dd[8] = {
+static const macro_op_t *opcode_timings_p6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1464,7 +1465,7 @@ static const macro_op_t *opcode_timings_dd[8] = {
&complex_float_l_op, INVALID, &complex_float_l_op, &complex_float_l_op
// clang-format on
};
-static const macro_op_t *opcode_timings_dd_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
&float_op, INVALID, &float_op, &float_op,
@@ -1473,7 +1474,7 @@ static const macro_op_t *opcode_timings_dd_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_de[8] = {
+static const macro_op_t *opcode_timings_p6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
&load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op,
@@ -1481,7 +1482,7 @@ static const macro_op_t *opcode_timings_de[8] = {
&load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_de_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
&fadd_op, &fmul_op, INVALID, &float_op,
@@ -1490,7 +1491,7 @@ static const macro_op_t *opcode_timings_de_mod3[8] = {
// clang-format on
};
-static const macro_op_t *opcode_timings_df[8] = {
+static const macro_op_t *opcode_timings_p6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1498,7 +1499,7 @@ static const macro_op_t *opcode_timings_df[8] = {
INVALID, &load_float_op, &complex_float_l_op, &fstore_op,
// clang-format on
};
-static const macro_op_t *opcode_timings_df_mod3[8] = {
+static const macro_op_t *opcode_timings_p6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -1864,47 +1865,47 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
switch (last_prefix) {
case 0x0f:
- ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ ins_table = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ ins_table = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ ins_table = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ ins_table = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ ins_table = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ ins_table = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ ins_table = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ ins_table = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ ins_table = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -1913,13 +1914,13 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
switch (opcode) {
case 0x80:
case 0x82:
- ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80;
+ ins_table = mod3 ? opcode_timings_p6_80_mod3 : opcode_timings_p6_80;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
case 0x83:
- ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ ins_table = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1927,7 +1928,7 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
case 0xc0:
case 0xd0:
case 0xd2:
- ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b;
+ ins_table = mod3 ? opcode_timings_p6_shift_b_mod3 : opcode_timings_p6_shift_b;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1935,29 +1936,29 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
case 0xc1:
case 0xd1:
case 0xd3:
- ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ ins_table = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ ins_table = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ ins_table = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ ins_table = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- ins_table = mod3 ? opcode_timings_mod3 : opcode_timings;
+ ins_table = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c
index 3951acc942..aa78ee1c96 100644
--- a/src/cpu/codegen_timing_pentium.c
+++ b/src/cpu/codegen_timing_pentium.c
@@ -21,6 +21,7 @@
#include "x86.h"
#include "x86_ops.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_ops.h"
@@ -109,7 +110,7 @@ static uint32_t addr_regmask;
static int fpu_latency;
static int fpu_st_latency[8];
-static uint64_t opcode_timings[256] = {
+static uint64_t opcode_timings_p6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM,
@@ -246,7 +247,7 @@ static uint64_t opcode_timings[256] = {
// clang-format on
};
-static uint64_t opcode_timings_mod3[256] = {
+static uint64_t opcode_timings_p6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
@@ -384,7 +385,7 @@ static uint64_t opcode_timings_mod3[256] = {
// clang-format on
};
-static uint64_t opcode_timings_0f[256] = {
+static uint64_t opcode_timings_p6_0f[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -467,7 +468,7 @@ static uint64_t opcode_timings_0f[256] = {
PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID,
// clang-format on
};
-static uint64_t opcode_timings_0f_mod3[256] = {
+static uint64_t opcode_timings_p6_0f_mod3[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -551,20 +552,20 @@ static uint64_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static uint64_t opcode_timings_shift[8] = {
+static uint64_t opcode_timings_p6_shift[8] = {
// clang-format off
PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW,
PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW,
// clang-format on
};
-static uint64_t opcode_timings_shift_mod3[8] = {
+static uint64_t opcode_timings_p6_shift_mod3[8] = {
// clang-format off
PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG,
PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG,
// clang-format on
};
-static uint64_t opcode_timings_f6[8] = {
+static uint64_t opcode_timings_p6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -572,7 +573,7 @@ static uint64_t opcode_timings_f6[8] = {
PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22)
// clang-format on
};
-static uint64_t opcode_timings_f6_mod3[8] = {
+static uint64_t opcode_timings_p6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -580,7 +581,7 @@ static uint64_t opcode_timings_f6_mod3[8] = {
PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22)
// clang-format on
};
-static uint64_t opcode_timings_f7[8] = {
+static uint64_t opcode_timings_p6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -588,7 +589,7 @@ static uint64_t opcode_timings_f7[8] = {
PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46)
// clang-format on
};
-static uint64_t opcode_timings_f7_mod3[8] = {
+static uint64_t opcode_timings_p6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -596,7 +597,7 @@ static uint64_t opcode_timings_f7_mod3[8] = {
PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46)
// clang-format on
};
-static uint64_t opcode_timings_ff[8] = {
+static uint64_t opcode_timings_p6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
@@ -604,7 +605,7 @@ static uint64_t opcode_timings_ff[8] = {
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID
// clang-format on
};
-static uint64_t opcode_timings_ff_mod3[8] = {
+static uint64_t opcode_timings_p6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
@@ -613,7 +614,7 @@ static uint64_t opcode_timings_ff_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_d8[8] = {
+static uint64_t opcode_timings_p6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -621,7 +622,7 @@ static uint64_t opcode_timings_d8[8] = {
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2)
// clang-format on
};
-static uint64_t opcode_timings_d8_mod3[8] = {
+static uint64_t opcode_timings_p6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -630,7 +631,7 @@ static uint64_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_d9[8] = {
+static uint64_t opcode_timings_p6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0),
@@ -638,7 +639,7 @@ static uint64_t opcode_timings_d9[8] = {
PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0)
// clang-format on
};
-static uint64_t opcode_timings_d9_mod3[64] = {
+static uint64_t opcode_timings_p6_d9_mod3[64] = {
// clang-format off
/*FLD*/
PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -671,7 +672,7 @@ static uint64_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static uint64_t opcode_timings_da[8] = {
+static uint64_t opcode_timings_p6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0),
@@ -679,7 +680,7 @@ static uint64_t opcode_timings_da[8] = {
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2)
// clang-format on
};
-static uint64_t opcode_timings_da_mod3[8] = {
+static uint64_t opcode_timings_p6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -687,7 +688,7 @@ static uint64_t opcode_timings_da_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_db[8] = {
+static uint64_t opcode_timings_p6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0),
@@ -695,7 +696,7 @@ static uint64_t opcode_timings_db[8] = {
INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0)
// clang-format on
};
-static uint64_t opcode_timings_db_mod3[64] = {
+static uint64_t opcode_timings_p6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -725,7 +726,7 @@ static uint64_t opcode_timings_db_mod3[64] = {
// clang-format on
};
-static uint64_t opcode_timings_dc[8] = {
+static uint64_t opcode_timings_p6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -733,7 +734,7 @@ static uint64_t opcode_timings_dc[8] = {
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2)
// clang-format on
};
-static uint64_t opcode_timings_dc_mod3[8] = {
+static uint64_t opcode_timings_p6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID,
@@ -742,7 +743,7 @@ static uint64_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_dd[8] = {
+static uint64_t opcode_timings_p6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0),
@@ -750,7 +751,7 @@ static uint64_t opcode_timings_dd[8] = {
PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0)
// clang-format on
};
-static uint64_t opcode_timings_dd_mod3[8] = {
+static uint64_t opcode_timings_p6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0),
@@ -759,7 +760,7 @@ static uint64_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_de[8] = {
+static uint64_t opcode_timings_p6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0),
@@ -767,7 +768,7 @@ static uint64_t opcode_timings_de[8] = {
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2)
// clang-format on
};
-static uint64_t opcode_timings_de_mod3[8] = {
+static uint64_t opcode_timings_p6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0),
@@ -776,7 +777,7 @@ static uint64_t opcode_timings_de_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_df[8] = {
+static uint64_t opcode_timings_p6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0),
@@ -784,7 +785,7 @@ static uint64_t opcode_timings_df[8] = {
INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0)
// clang-format on
};
-static uint64_t opcode_timings_df_mod3[8] = {
+static uint64_t opcode_timings_p6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -792,25 +793,25 @@ static uint64_t opcode_timings_df_mod3[8] = {
// clang-format on
};
-static uint64_t opcode_timings_81[8] = {
+static uint64_t opcode_timings_p6_81[8] = {
// clang-format off
PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632,
PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632
// clang-format on
};
-static uint64_t opcode_timings_81_mod3[8] = {
+static uint64_t opcode_timings_p6_81_mod3[8] = {
// clang-format off
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG
// clang-format on
};
-static uint64_t opcode_timings_8x[8] = {
+static uint64_t opcode_timings_p6_8x[8] = {
// clang-format off
PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8,
PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8
// clang-format on
};
-static uint64_t opcode_timings_8x_mod3[8] = {
+static uint64_t opcode_timings_p6_8x_mod3[8] = {
// clang-format off
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG
@@ -1096,47 +1097,47 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
switch (last_prefix) {
case 0x0f:
- timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ timings = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ timings = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ timings = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ timings = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ timings = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ timings = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ timings = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ timings = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ timings = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -1146,12 +1147,12 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0x80:
case 0x82:
case 0x83:
- timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ timings = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
- timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
+ timings = mod3 ? opcode_timings_p6_81_mod3 : opcode_timings_p6_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1160,36 +1161,36 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0xc1:
case 0xd0:
case 0xd1:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd2:
case 0xd3:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ timings = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ timings = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ timings = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- timings = mod3 ? opcode_timings_mod3 : opcode_timings;
+ timings = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c
index 11dd912b4f..3597517cef 100644
--- a/src/cpu/codegen_timing_winchip.c
+++ b/src/cpu/codegen_timing_winchip.c
@@ -9,6 +9,7 @@
#include "x86.h"
#include "x86_ops.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_ops.h"
@@ -17,7 +18,7 @@
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
-static int *opcode_timings[256] = {
+static int *opcode_timings_winchip[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -41,7 +42,7 @@ static int *opcode_timings[256] = {
// clang-format on
};
-static int *opcode_timings_mod3[256] = {
+static int *opcode_timings_winchip_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -65,7 +66,7 @@ static int *opcode_timings_mod3[256] = {
// clang-format on
};
-static int *opcode_timings_0f[256] = {
+static int *opcode_timings_winchip_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -88,7 +89,7 @@ static int *opcode_timings_0f[256] = {
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
-static int *opcode_timings_0f_mod3[256] = {
+static int *opcode_timings_winchip_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -112,68 +113,68 @@ static int *opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static int *opcode_timings_shift[8] = {
+static int *opcode_timings_winchip_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
// clang-format on
};
-static int *opcode_timings_shift_mod3[8] = {
+static int *opcode_timings_winchip_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
-static int *opcode_timings_f6[8] = {
+static int *opcode_timings_winchip_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static int *opcode_timings_f6_mod3[8] = {
+static int *opcode_timings_winchip_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static int *opcode_timings_f7[8] = {
+static int *opcode_timings_winchip_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
-static int *opcode_timings_f7_mod3[8] = {
+static int *opcode_timings_winchip_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
-static int *opcode_timings_ff[8] = {
+static int *opcode_timings_winchip_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
-static int *opcode_timings_ff_mod3[8] = {
+static int *opcode_timings_winchip_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
-static int *opcode_timings_d8[8] = {
+static int *opcode_timings_winchip_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
-static int *opcode_timings_d8_mod3[8] = {
+static int *opcode_timings_winchip_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
-static int *opcode_timings_d9[8] = {
+static int *opcode_timings_winchip_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
-static int *opcode_timings_d9_mod3[64] = {
+static int *opcode_timings_winchip_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
@@ -194,25 +195,25 @@ static int *opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static int *opcode_timings_da[8] = {
+static int *opcode_timings_winchip_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
-static int *opcode_timings_da_mod3[8] = {
+static int *opcode_timings_winchip_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
-static int *opcode_timings_db[8] = {
+static int *opcode_timings_winchip_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8)
// clang-format on
};
-static int *opcode_timings_db_mod3[64] = {
+static int *opcode_timings_winchip_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -226,71 +227,71 @@ static int *opcode_timings_db_mod3[64] = {
// clang-format on
};
-static int *opcode_timings_dc[8] = {
+static int *opcode_timings_winchip_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74)
// clang-format on
};
-static int *opcode_timings_dc_mod3[8] = {
+static int *opcode_timings_winchip_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
-static int *opcode_timings_dd[8] = {
+static int *opcode_timings_winchip_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5)
// clang-format on
};
-static int *opcode_timings_dd_mod3[8] = {
+static int *opcode_timings_winchip_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
-static int *opcode_timings_de[8] = {
+static int *opcode_timings_winchip_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
-static int *opcode_timings_de_mod3[8] = {
+static int *opcode_timings_winchip_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
-static int *opcode_timings_df[8] = {
+static int *opcode_timings_winchip_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8)
// clang-format on
};
-static int *opcode_timings_df_mod3[8] = {
+static int *opcode_timings_winchip_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
-static int *opcode_timings_8x[8] = {
+static int *opcode_timings_winchip_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
-static int *opcode_timings_8x_mod3[8] =
+static int *opcode_timings_winchip_8x_mod3[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
-static int *opcode_timings_81[8] =
+static int *opcode_timings_winchip_81[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
-static int *opcode_timings_81_mod3[8] =
+static int *opcode_timings_winchip_81_mod3[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
@@ -329,7 +330,7 @@ codegen_timing_winchip_start(void)
void
codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
{
- timing_count += COUNT(opcode_timings[prefix], 0);
+ timing_count += COUNT(opcode_timings_winchip[prefix], 0);
last_prefix = prefix;
}
@@ -343,47 +344,47 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
switch (last_prefix) {
case 0x0f:
- timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ timings = mod3 ? opcode_timings_winchip_0f_mod3 : opcode_timings_winchip_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ timings = mod3 ? opcode_timings_winchip_d8_mod3 : opcode_timings_winchip_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ timings = mod3 ? opcode_timings_winchip_d9_mod3 : opcode_timings_winchip_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ timings = mod3 ? opcode_timings_winchip_da_mod3 : opcode_timings_winchip_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ timings = mod3 ? opcode_timings_winchip_db_mod3 : opcode_timings_winchip_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ timings = mod3 ? opcode_timings_winchip_dc_mod3 : opcode_timings_winchip_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ timings = mod3 ? opcode_timings_winchip_dd_mod3 : opcode_timings_winchip_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ timings = mod3 ? opcode_timings_winchip_de_mod3 : opcode_timings_winchip_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ timings = mod3 ? opcode_timings_winchip_df_mod3 : opcode_timings_winchip_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -393,12 +394,12 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0x80:
case 0x82:
case 0x83:
- timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ timings = mod3 ? opcode_timings_winchip_8x_mod3 : opcode_timings_winchip_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
- timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
+ timings = mod3 ? opcode_timings_winchip_81_mod3 : opcode_timings_winchip_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -409,29 +410,29 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0xd1:
case 0xd2:
case 0xd3:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_winchip_shift_mod3 : opcode_timings_winchip_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ timings = mod3 ? opcode_timings_winchip_f6_mod3 : opcode_timings_winchip_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ timings = mod3 ? opcode_timings_winchip_f7_mod3 : opcode_timings_winchip_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ timings = mod3 ? opcode_timings_winchip_ff_mod3 : opcode_timings_winchip_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- timings = mod3 ? opcode_timings_mod3 : opcode_timings;
+ timings = mod3 ? opcode_timings_winchip_mod3 : opcode_timings_winchip;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c
index d4e32611e4..f37fe33660 100644
--- a/src/cpu/codegen_timing_winchip2.c
+++ b/src/cpu/codegen_timing_winchip2.c
@@ -18,6 +18,7 @@
#include "x86.h"
#include "x86_ops.h"
+#include "x87_sf.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_ops.h"
@@ -62,7 +63,7 @@
#define INVALID 0
-static uint32_t opcode_timings[256] = {
+static uint32_t opcode_timings_winchip2[256] = {
// clang-format off
/*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
/*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
@@ -86,7 +87,7 @@ static uint32_t opcode_timings[256] = {
// clang-format on
};
-static uint32_t opcode_timings_mod3[256] = {
+static uint32_t opcode_timings_winchip2_mod3[256] = {
// clang-format off
/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
@@ -110,7 +111,7 @@ static uint32_t opcode_timings_mod3[256] = {
// clang-format on
};
-static uint32_t opcode_timings_0f[256] = {
+static uint32_t opcode_timings_winchip2_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
@@ -133,7 +134,7 @@ static uint32_t opcode_timings_0f[256] = {
/*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID,
// clang-format on
};
-static uint32_t opcode_timings_0f_mod3[256] = {
+static uint32_t opcode_timings_winchip2_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
@@ -157,49 +158,49 @@ static uint32_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
-static uint32_t opcode_timings_shift[8] = {
+static uint32_t opcode_timings_winchip2_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
// clang-format on
};
-static uint32_t opcode_timings_shift_mod3[8] = {
+static uint32_t opcode_timings_winchip2_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
-static uint32_t opcode_timings_f6[8] = {
+static uint32_t opcode_timings_winchip2_f6[8] = {
// clang-format off
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static uint32_t opcode_timings_f6_mod3[8] = {
+static uint32_t opcode_timings_winchip2_f6_mod3[8] = {
// clang-format off
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
-static uint32_t opcode_timings_f7[8] = {
+static uint32_t opcode_timings_winchip2_f7[8] = {
// clang-format off
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
-static uint32_t opcode_timings_f7_mod3[8] = {
+static uint32_t opcode_timings_winchip2_f7_mod3[8] = {
// clang-format off
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
-static uint32_t opcode_timings_ff[8] = {
+static uint32_t opcode_timings_winchip2_ff[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
// clang-format on
};
-static uint32_t opcode_timings_ff_mod3[8] = {
+static uint32_t opcode_timings_winchip2_ff_mod3[8] = {
// clang-format off
CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
// clang-format on
};
-static uint32_t opcode_timings_d8[8] = {
+static uint32_t opcode_timings_winchip2_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -207,7 +208,7 @@ static uint32_t opcode_timings_d8[8] = {
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
// clang-format on
};
-static uint32_t opcode_timings_d8_mod3[8] = {
+static uint32_t opcode_timings_winchip2_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -216,7 +217,7 @@ static uint32_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_d9[8] = {
+static uint32_t opcode_timings_winchip2_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
@@ -224,7 +225,7 @@ static uint32_t opcode_timings_d9[8] = {
FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0)
// clang-format on
};
-static uint32_t opcode_timings_d9_mod3[64] = {
+static uint32_t opcode_timings_winchip2_d9_mod3[64] = {
// clang-format off
/*FLD*/
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -257,7 +258,7 @@ static uint32_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
-static uint32_t opcode_timings_da[8] = {
+static uint32_t opcode_timings_winchip2_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
@@ -265,7 +266,7 @@ static uint32_t opcode_timings_da[8] = {
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
// clang-format on
};
-static uint32_t opcode_timings_da_mod3[8] = {
+static uint32_t opcode_timings_winchip2_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -273,7 +274,7 @@ static uint32_t opcode_timings_da_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_db[8] = {
+static uint32_t opcode_timings_winchip2_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
@@ -281,7 +282,7 @@ static uint32_t opcode_timings_db[8] = {
INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0)
// clang-format on
};
-static uint32_t opcode_timings_db_mod3[64] = {
+static uint32_t opcode_timings_winchip2_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -311,7 +312,7 @@ static uint32_t opcode_timings_db_mod3[64] = {
// clang-format on
};
-static uint32_t opcode_timings_dc[8] = {
+static uint32_t opcode_timings_winchip2_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -319,7 +320,7 @@ static uint32_t opcode_timings_dc[8] = {
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
// clang-format on
};
-static uint32_t opcode_timings_dc_mod3[8] = {
+static uint32_t opcode_timings_winchip2_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID,
@@ -328,7 +329,7 @@ static uint32_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_dd[8] = {
+static uint32_t opcode_timings_winchip2_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
@@ -336,7 +337,7 @@ static uint32_t opcode_timings_dd[8] = {
FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0)
// clang-format on
};
-static uint32_t opcode_timings_dd_mod3[8] = {
+static uint32_t opcode_timings_winchip2_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -345,7 +346,7 @@ static uint32_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_de[8] = {
+static uint32_t opcode_timings_winchip2_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
@@ -353,7 +354,7 @@ static uint32_t opcode_timings_de[8] = {
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
// clang-format on
};
-static uint32_t opcode_timings_de_mod3[8] = {
+static uint32_t opcode_timings_winchip2_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0),
@@ -362,7 +363,7 @@ static uint32_t opcode_timings_de_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_df[8] = {
+static uint32_t opcode_timings_winchip2_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
@@ -370,7 +371,7 @@ static uint32_t opcode_timings_df[8] = {
INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0)
// clang-format on
};
-static uint32_t opcode_timings_df_mod3[8] = {
+static uint32_t opcode_timings_winchip2_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -378,22 +379,22 @@ static uint32_t opcode_timings_df_mod3[8] = {
// clang-format on
};
-static uint32_t opcode_timings_8x[8] = {
+static uint32_t opcode_timings_winchip2_8x[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
-static uint32_t opcode_timings_8x_mod3[8] = {
+static uint32_t opcode_timings_winchip2_8x_mod3[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
-static uint32_t opcode_timings_81[8] = {
+static uint32_t opcode_timings_winchip2_81[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
-static uint32_t opcode_timings_81_mod3[8] = {
+static uint32_t opcode_timings_winchip2_81_mod3[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
@@ -612,47 +613,47 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
switch (last_prefix) {
case 0x0f:
- timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
+ timings = mod3 ? opcode_timings_winchip2_0f_mod3 : opcode_timings_winchip2_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
- timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
+ timings = mod3 ? opcode_timings_winchip2_d8_mod3 : opcode_timings_winchip2_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
- timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
+ timings = mod3 ? opcode_timings_winchip2_d9_mod3 : opcode_timings_winchip2_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
- timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
+ timings = mod3 ? opcode_timings_winchip2_da_mod3 : opcode_timings_winchip2_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
- timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
+ timings = mod3 ? opcode_timings_winchip2_db_mod3 : opcode_timings_winchip2_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
- timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
+ timings = mod3 ? opcode_timings_winchip2_dc_mod3 : opcode_timings_winchip2_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
- timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
+ timings = mod3 ? opcode_timings_winchip2_dd_mod3 : opcode_timings_winchip2_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
- timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
+ timings = mod3 ? opcode_timings_winchip2_de_mod3 : opcode_timings_winchip2_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
- timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
+ timings = mod3 ? opcode_timings_winchip2_df_mod3 : opcode_timings_winchip2_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -662,12 +663,12 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
case 0x80:
case 0x82:
case 0x83:
- timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
+ timings = mod3 ? opcode_timings_winchip2_8x_mod3 : opcode_timings_winchip2_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
- timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
+ timings = mod3 ? opcode_timings_winchip2_81_mod3 : opcode_timings_winchip2_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -678,29 +679,29 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
case 0xd1:
case 0xd2:
case 0xd3:
- timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
+ timings = mod3 ? opcode_timings_winchip2_shift_mod3 : opcode_timings_winchip2_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
- timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
+ timings = mod3 ? opcode_timings_winchip2_f6_mod3 : opcode_timings_winchip2_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
- timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
+ timings = mod3 ? opcode_timings_winchip2_f7_mod3 : opcode_timings_winchip2_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
- timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
+ timings = mod3 ? opcode_timings_winchip2_ff_mod3 : opcode_timings_winchip2_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
- timings = mod3 ? opcode_timings_mod3 : opcode_timings;
+ timings = mod3 ? opcode_timings_winchip2_mod3 : opcode_timings_winchip2;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index b812a24f94..0c6d360976 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -29,6 +29,8 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
+#include "x86.h"
+#include "x87_sf.h"
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/io.h>
@@ -38,13 +40,14 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
+#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#ifdef USE_DYNAREC
# include "codegen.h"
-#endif
+#endif /* USE_DYNAREC */
#include "x87_timings.h"
#define CCR1_USE_SMI (1 << 1)
@@ -116,7 +119,7 @@ const OpFn *x86_dynarec_opcodes_df_a32;
const OpFn *x86_dynarec_opcodes_REPE;
const OpFn *x86_dynarec_opcodes_REPNE;
const OpFn *x86_dynarec_opcodes_3DNOW;
-#endif
+#endif /* USE_DYNAREC */
const OpFn *x86_opcodes;
const OpFn *x86_opcodes_0f;
@@ -179,6 +182,8 @@ int cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
+int cpu_flush_pending;
+int cpu_old_paging;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;
@@ -501,9 +506,10 @@ cpu_set(void)
#ifdef USE_ACYCS
acycs = 0;
-#endif
+#endif /* USE_ACYCS */
- soft_reset_pci = 0;
+ soft_reset_pci = 0;
+ cpu_init = 0;
cpu_alt_reset = 0;
unmask_a20_in_smm = 0;
@@ -572,7 +578,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
x86_setopcodes(ops_386, ops_386_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f);
x86_opcodes_REPE = ops_REPE;
x86_opcodes_REPNE = ops_REPNE;
@@ -583,7 +589,7 @@ cpu_set(void)
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW;
-#endif
+#endif /* USE_DYNAREC */
if (hasfpu) {
#ifdef USE_DYNAREC
@@ -622,7 +628,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
}
-#endif
+#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d8_a16 = ops_sf_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_sf_fpu_d8_a32;
@@ -710,7 +716,7 @@ cpu_set(void)
x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32;
-#endif
+#endif /* USE_DYNAREC */
x86_opcodes_d8_a16 = ops_nofpu_a16;
x86_opcodes_d8_a32 = ops_nofpu_a32;
x86_opcodes_d9_a16 = ops_nofpu_a16;
@@ -748,7 +754,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_486);
-#endif
+#endif /* USE_DYNAREC */
memset(&msr, 0, sizeof(msr));
@@ -770,7 +776,7 @@ cpu_set(void)
x86_setopcodes(ops_186, ops_186_0f, dynarec_ops_186, dynarec_ops_186_0f);
#else
x86_setopcodes(ops_186, ops_186_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f);
break;
@@ -779,7 +785,7 @@ cpu_set(void)
x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
#else
x86_setopcodes(ops_286, ops_286_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f);
if (fpu_type == FPU_287) {
@@ -815,7 +821,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
-#endif
+#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
@@ -917,7 +923,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f);
#else
x86_setopcodes(ops_386, ops_ibm486_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f);
cpu_features = CPU_FEATURE_MSR;
fallthrough;
@@ -957,7 +963,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
-#endif
+#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
@@ -1063,7 +1069,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1103,7 +1109,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1156,7 +1162,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
-#endif
+#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1205,7 +1211,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_stpc_0f);
else
x86_setopcodes(ops_386, ops_c486_0f);
-#endif
+#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 3; /* register dest - memory src */
@@ -1248,7 +1254,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f);
#else
x86_setopcodes(ops_386, ops_c486_0f);
-#endif
+#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 1; /* register dest - memory src */
@@ -1297,7 +1303,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_winchip2_0f);
else
x86_setopcodes(ops_386, ops_winchip_0f);
-#endif
+#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1346,7 +1352,7 @@ cpu_set(void)
codegen_timing_set(&codegen_timing_winchip2);
else
codegen_timing_set(&codegen_timing_winchip);
-#endif
+#endif /* USE_DYNAREC */
break;
case CPU_P24T:
@@ -1362,7 +1368,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentiummmx_0f);
else
x86_setopcodes(ops_386, ops_pentium_0f);
-#endif
+#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1405,10 +1411,10 @@ cpu_set(void)
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_pentium);
-#endif
+#endif /* USE_DYNAREC */
break;
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -1430,7 +1436,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
}
-# endif
+# endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
@@ -1468,7 +1474,7 @@ cpu_set(void)
# if 0
x86_setopcodes(ops_386, ops_c6x86_0f);
# endif
-# endif
+# endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 1; /* register dest - memory src */
@@ -1520,19 +1526,65 @@ cpu_set(void)
# ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
-# endif
+# endif /* USE_DYNAREC */
if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX))
ccr4 = 0x80;
else if (CPU_Cx6x86)
CPUID = 0; /* Disabled on powerup by default */
break;
-#endif
+#endif /* USE_CYRIX_6X86 */
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
+#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
-#endif
+#ifdef USE_DYNAREC
+ x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
+#else
+ x86_setopcodes(ops_386, ops_pentiummmx_0f);
+#endif /* USE_DYNAREC */
+
+ timing_rr = 1; /* register dest - register src */
+ timing_rm = 2; /* register dest - memory src */
+ timing_mr = 3; /* memory dest - register src */
+ timing_mm = 3;
+ timing_rml = 2; /* register dest - memory src long */
+ timing_mrl = 3; /* memory dest - register src long */
+ timing_mml = 3;
+ timing_bt = 0; /* branch taken */
+ timing_bnt = 1; /* branch not taken */
+
+ timing_int = 6;
+ timing_int_rm = 11;
+ timing_int_v86 = 54;
+ timing_int_pm = 25;
+ timing_int_pm_outer = 42;
+ timing_iret_rm = 7;
+ timing_iret_v86 = 27; /* unknown */
+ timing_iret_pm = 10;
+ timing_iret_pm_outer = 27;
+ timing_call_rm = 4;
+ timing_call_pm = 4;
+ timing_call_pm_gate = 22;
+ timing_call_pm_gate_inner = 44;
+ timing_retf_rm = 4;
+ timing_retf_pm = 4;
+ timing_retf_pm_outer = 23;
+ timing_jmp_rm = 3;
+ timing_jmp_pm = 3;
+ timing_jmp_pm_gate = 18;
+
+ timing_misaligned = 3;
+
+ cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
+ cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PGE;
+
+#ifdef USE_DYNAREC
+ codegen_timing_set(&codegen_timing_k5);
+#endif /* USE_DYNAREC */
+ break;
+
+#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -1542,34 +1594,20 @@ cpu_set(void)
#ifdef USE_DYNAREC
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f);
-# if defined(DEV_BRANCH) && defined(USE_AMD_K5)
- else if (cpu_s->cpu_type == CPU_K6)
- x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
- else
- x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
-# else
else
x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
-# endif
#else
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f);
-# if defined(DEV_BRANCH) && defined(USE_AMD_K5)
- else if (cpu_s->cpu_type == CPU_K6)
- x86_setopcodes(ops_386, ops_k6_0f);
- else
- x86_setopcodes(ops_386, ops_pentiummmx_0f);
-# else
else
x86_setopcodes(ops_386, ops_k6_0f);
-# endif
-#endif
+#endif /* USE_DYNAREC */
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) {
x86_opcodes_3DNOW = ops_3DNOWE;
#ifdef USE_DYNAREC
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE;
-#endif
+#endif /* USE_DYNAREC */
}
timing_rr = 1; /* register dest - register src */
@@ -1609,27 +1647,15 @@ cpu_set(void)
cpu_features |= CPU_FEATURE_3DNOW;
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P))
cpu_features |= CPU_FEATURE_3DNOWE;
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
- cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE;
- if (cpu_s->cpu_type >= CPU_K6) {
- cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE);
- if (cpu_s->cpu_type <= CPU_K6)
- cpu_CR4_mask |= CR4_PCE;
- else if (cpu_s->cpu_type >= CPU_K6_2C)
- cpu_CR4_mask |= CR4_PGE;
- } else
- cpu_CR4_mask |= CR4_PGE;
-#else
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE;
if (cpu_s->cpu_type == CPU_K6)
cpu_CR4_mask |= CR4_PCE;
else if (cpu_s->cpu_type >= CPU_K6_2C)
cpu_CR4_mask |= CR4_PGE;
-#endif
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_k6);
-#endif
+#endif /* USE_DYNAREC */
break;
case CPU_PENTIUMPRO:
@@ -1664,7 +1690,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentium2d_0f);
else
x86_setopcodes(ops_386, ops_pentium2_0f);
-#endif
+#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
@@ -1722,7 +1748,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
-#endif
+#endif /* USE_DYNAREC */
break;
case CPU_CYRIX3S:
@@ -1730,7 +1756,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f);
#else
x86_setopcodes(ops_386, ops_winchip2_0f);
-#endif
+#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
timing_mr = 2; /* memory dest - register src */
@@ -1770,7 +1796,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_winchip);
-#endif
+#endif /* USE_DYNAREC */
break;
default:
@@ -1808,7 +1834,7 @@ cpu_set(void)
cpu_exec = exec386_dynarec;
cpu_use_exec = 1;
} else
-#endif
+#endif /* defined(USE_DYNAREC) && !defined(USE_GDBSTUB) */
/* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */
if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) ||
cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC) || cpu_override_interpreter) {
@@ -2061,7 +2087,7 @@ cpu_CPUID(void)
EAX = EBX = ECX = EDX = 0;
break;
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
+#ifdef USE_AMD_K5
case CPU_K5:
if (!EAX) {
EAX = 0x00000001;
@@ -2119,7 +2145,7 @@ cpu_CPUID(void)
break;
}
break;
-#endif
+#endif /* USE_AMD_K5 */
case CPU_K6:
switch (EAX) {
@@ -2350,7 +2376,7 @@ cpu_CPUID(void)
EAX = EBX = ECX = EDX = 0;
break;
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
if (!EAX) {
EAX = 0x00000001;
@@ -2406,7 +2432,7 @@ cpu_CPUID(void)
} else
EAX = EBX = ECX = EDX = 0;
break;
-#endif
+#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
if (!EAX) {
@@ -2561,10 +2587,10 @@ cpu_ven_reset(void)
msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL;
fallthrough;
case CPU_K6_2:
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
+#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
-#endif
+#endif /* USE_AMD_K5 */
case CPU_K6:
msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL;
break;
@@ -2785,10 +2811,10 @@ cpu_RDMSR(void)
}
break;
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
+#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
-#endif
+#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -3071,7 +3097,7 @@ cpu_RDMSR(void)
cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -3111,7 +3137,7 @@ cpu_RDMSR(void)
}
cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
-#endif
+#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
@@ -3274,26 +3300,17 @@ cpu_RDMSR(void)
break;
/* SYSENTER_CS - SYSENTER target CS */
case 0x174:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_rdmsr;
-
EAX &= 0xffff0000;
EAX |= msr.sysenter_cs;
EDX = 0x00000000;
break;
/* SYSENTER_ESP - SYSENTER target ESP */
case 0x175:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_rdmsr;
-
EAX = msr.sysenter_esp;
EDX = 0x00000000;
break;
/* SYSENTER_EIP - SYSENTER target EIP */
case 0x176:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_rdmsr;
-
EAX = msr.sysenter_eip;
EDX = 0x00000000;
break;
@@ -3489,7 +3506,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3565,7 +3582,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */
case 0xc1:
@@ -3634,10 +3651,10 @@ cpu_WRMSR(void)
}
break;
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
+#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
-#endif
+#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -3661,7 +3678,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x00000010:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Array Access Register */
case 0x00000082:
@@ -3688,7 +3705,7 @@ cpu_WRMSR(void)
/* Extended Feature Enable Register */
case 0xc0000080:
temp = EAX | ((uint64_t) EDX << 32);
- if (temp & ~1ULL)
+ if (temp & ~0x1fULL)
x86gpf(NULL, 0);
else
msr.amd_efer = temp;
@@ -3831,7 +3848,7 @@ cpu_WRMSR(void)
/* Time Stamp Counter */
case 0x00000010:
case 0x80000010:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x00000011:
@@ -3898,7 +3915,7 @@ cpu_WRMSR(void)
}
break;
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -3916,7 +3933,7 @@ cpu_WRMSR(void)
msr.tr5 = EAX & 0x008f0f3b;
/* Time Stamp Counter */
case 0x10:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3932,7 +3949,7 @@ cpu_WRMSR(void)
break;
}
break;
-#endif
+#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
@@ -3949,7 +3966,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
- tsc = EAX | ((uint64_t) EDX << 32);
+ timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Unknown */
case 0x18:
@@ -4043,23 +4060,14 @@ cpu_WRMSR(void)
break;
/* SYSENTER_CS - SYSENTER target CS */
case 0x174:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_wrmsr;
-
msr.sysenter_cs = EAX & 0xFFFF;
break;
/* SYSENTER_ESP - SYSENTER target ESP */
case 0x175:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_wrmsr;
-
msr.sysenter_esp = EAX;
break;
/* SYSENTER_EIP - SYSENTER target EIP */
case 0x176:
- if (cpu_s->cpu_type == CPU_PENTIUMPRO)
- goto i686_invalid_wrmsr;
-
msr.sysenter_eip = EAX;
break;
/* MCG_CAP - Machine Check Global Capability */
@@ -4245,14 +4253,14 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
case 0xe8: /* CCR4 */
if ((ccr3 & 0xf0) == 0x10) {
ccr4 = val;
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
+#ifdef USE_CYRIX_6X86
if (cpu_s->cpu_type >= CPU_Cx6x86) {
if (val & 0x80)
CPUID = cpu_s->cpuid_model;
else
CPUID = 0;
}
-#endif
+#endif /* USE_CYRIX_6X86 */
}
break;
case 0xe9: /* CCR5 */
@@ -4326,7 +4334,7 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
-#endif
+#endif /* USE_DYNAREC */
void
x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f)
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 900d3d7e1b..d96d7951d6 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -21,8 +21,6 @@
#ifndef EMU_CPU_H
#define EMU_CPU_H
-#include "softfloat/softfloat.h"
-
enum {
FPU_NONE,
FPU_8087,
@@ -406,22 +404,6 @@ typedef struct {
uint32_t _smbase;
} cpu_state_t;
-typedef struct {
- uint16_t cwd;
- uint16_t swd;
- uint16_t tag;
- uint16_t foo;
- uint32_t fip;
- uint32_t fdp;
- uint16_t fcs;
- uint16_t fds;
- floatx80 st_space[8];
- unsigned char tos;
- unsigned char align1;
- unsigned char align2;
- unsigned char align3;
-} fpu_state_t;
-
#define in_smm cpu_state._in_smm
#define smi_line cpu_state._smi_line
@@ -502,7 +484,6 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128)
/* Global variables. */
extern cpu_state_t cpu_state;
-extern fpu_state_t fpu_state;
extern const cpu_family_t cpu_families[];
extern cpu_family_t *cpu_f;
@@ -592,8 +573,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;
@@ -637,6 +616,8 @@ extern int cpu_prefetch_width;
extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
+extern int cpu_flush_pending;
+extern int cpu_old_paging;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;
diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c
index 502b2c86e3..5326c9d14d 100644
--- a/src/cpu/cpu_table.c
+++ b/src/cpu/cpu_table.c
@@ -16,13 +16,15 @@
* Fred N. van Kempen,
* RichardG,
* dob205,
+ * Jasmine Iwanek,
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 leilei.
- * Copyright 2016-2019 Miran Grca.
+ * Copyright 2016-2024 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2020 RichardG.
* Copyright 2021 dob205.
+ * Copyright 2022-2024 Jasmine Iwanek.
*/
#include
#include
@@ -71,1912 +73,7927 @@ FPU fpus_internal[] = {
const cpu_family_t cpu_families[] = {
// clang-format off
{
- .package = CPU_PKG_8088,
- .manufacturer = "Intel",
- .name = "8088",
- .internal_name = "8088",
- .cpus = (const CPU[]) {
- {
- .name = "4.77",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 4772728,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "7.16",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
+ .package = CPU_PKG_8088,
+ .manufacturer = "Intel",
+ .name = "8088",
+ .internal_name = "8088",
+ .cpus = (const CPU[]) {
+ {
+ .name = "4.77",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 4772728,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "7.16",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
#if 0
- {
- .name = "9.54",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 9545456,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
+ {
+ .name = "9.54",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 9545456,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
#endif
- {
- .name = "10",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_8088_EUROPC,
- .manufacturer = "Intel",
- .name = "8088",
- .internal_name = "8088_europc",
- .cpus = (const CPU[]) {
- {
- .name = "4.77",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 4772728,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "7.16",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "9.54",
- .cpu_type = CPU_8088,
- .fpus = fpus_8088,
- .rspeed = 9545456,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_8086,
- .manufacturer = "Intel",
- .name = "8086",
- .internal_name = "8086",
- .cpus = (const CPU[]) {
- {
- .name = "7.16",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "9.54",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 9545456,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_8086,
- .fpus = fpus_8088,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 2
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_188,
- .manufacturer = "Intel",
- .name = "80188",
- .internal_name = "80188",
- .cpus = (const CPU[]) {
- {
- .name = "6",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 6000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "7.16",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "9.54",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 9545456,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 2
- },
- {
- .name = "20",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 20000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 3
- },
- {
- .name = "25",
- .cpu_type = CPU_188,
- .fpus = fpus_8088,
- .rspeed = 25000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 3
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_8088,
- .manufacturer = "NEC",
- .name = "V20",
- .internal_name = "necv20",
- .cpus = (const CPU[]) {
- {
- .name = "4.77",
- .cpu_type = CPU_V20,
- .fpus = fpus_8088,
- .rspeed = 4772728,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "7.16",
- .cpu_type = CPU_V20,
- .fpus = fpus_8088,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_V20,
- .fpus = fpus_8088,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_V20,
- .fpus = fpus_8088,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_V20,
- .fpus = fpus_8088,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 2
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_186,
- .manufacturer = "Intel",
- .name = "80186",
- .internal_name = "80186",
- .cpus = (const CPU[]) {
- {
- .name = "6",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 6000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "7.16",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 7159092,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "9.54",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 9545456,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = CPU_ALTERNATE_XTAL,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 2
- },
- {
- .name = "20",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 20000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 3
- },
- {
- .name = "25",
- .cpu_type = CPU_186,
- .fpus = fpus_80186,
- .rspeed = 25000000,
- .multi = 1,
- .voltage = 0,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 3
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_8086,
- .manufacturer = "NEC",
- .name = "V30",
- .internal_name = "necv30",
- .cpus = (const CPU[]) {
- {
- .name = "5",
- .cpu_type = CPU_V30,
- .fpus = fpus_80186,
- .rspeed = 5000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_V30,
- .fpus = fpus_80186,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_V30,
- .fpus = fpus_80186,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_V30,
- .fpus = fpus_80186,
- .rspeed = 12000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 1
- },
- {
- .name = "16",
- .cpu_type = CPU_V30,
- .fpus = fpus_80186,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 0,
- .mem_write_cycles = 0,
- .cache_read_cycles = 0,
- .cache_write_cycles = 0,
- .atclk_div = 2
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_286,
- .manufacturer = "Intel",
- .name = "80286",
- .internal_name = "286",
- .cpus = (const CPU[]) {
- {
- .name = "6",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 6000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 2,
- .mem_write_cycles = 2,
- .cache_read_cycles = 2,
- .cache_write_cycles = 2,
- .atclk_div = 1
- },
- {
- .name = "8",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 8000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 2,
- .mem_write_cycles = 2,
- .cache_read_cycles = 2,
- .cache_write_cycles = 2,
- .atclk_div = 1
- },
- {
- .name = "10",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 10000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 2,
- .mem_write_cycles = 2,
- .cache_read_cycles = 2,
- .cache_write_cycles = 2,
- .atclk_div = 1
- },
- {
- .name = "12",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 12500000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 3,
- .mem_write_cycles = 3,
- .cache_read_cycles = 3,
- .cache_write_cycles = 3,
- .atclk_div = 2
- },
- {
- .name = "16",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 16000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 3,
- .mem_write_cycles = 3,
- .cache_read_cycles = 3,
- .cache_write_cycles = 3,
- .atclk_div = 2
- },
- {
- .name = "20",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 20000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 4,
- .mem_write_cycles = 4,
- .cache_read_cycles = 4,
- .cache_write_cycles = 4,
- .atclk_div = 3
- },
- {
- .name = "25",
- .cpu_type = CPU_286,
- .fpus = fpus_80286,
- .rspeed = 25000000,
- .multi = 1,
- .voltage = 5000,
- .edx_reset = 0,
- .cpuid_model = 0,
- .cyrix_id = 0,
- .cpu_flags = 0,
- .mem_read_cycles = 4,
- .mem_write_cycles = 4,
- .cache_read_cycles = 4,
- .cache_write_cycles = 4,
- .atclk_div = 3
- },
- { .name = "", 0 }
- }
- }, {
- .package = CPU_PKG_386SX,
- .manufacturer = "Intel",
- .name = "i386SX",
- .internal_name = "i386sx",
- .cpus = (const CPU[]) {
- {"16", CPU_386SX, fpus_80386, 16000000, 1, 5000, 0x2308, 0, 0, 0, 3,3,3,3, 2},
- {"20", CPU_386SX, fpus_80386, 20000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"25", CPU_386SX, fpus_80386, 25000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"33", CPU_386SX, fpus_80386, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4},
- {"40", CPU_386SX, fpus_80386, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386SX,
- .manufacturer = "AMD",
- .name = "Am386SX",
- .internal_name = "am386sx",
- .cpus = (const CPU[]) {
- {"16", CPU_386SX, fpus_80386, 16000000, 1, 5000, 0x2308, 0, 0, 0, 3,3,3,3, 2},
- {"20", CPU_386SX, fpus_80386, 20000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"25", CPU_386SX, fpus_80386, 25000000, 1, 5000, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"33", CPU_386SX, fpus_80386, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4},
- {"40", CPU_386SX, fpus_80386, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX,
- .manufacturer = "Intel",
- .name = "i386DX",
- .internal_name = "i386dx",
- .cpus = (const CPU[]) {
- {"16", CPU_386DX, fpus_80386, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2},
- {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"33", CPU_386DX, fpus_80386, 33333333, 1, 5000, 0x0308, 0, 0, 0, 6,6,3,3, 4},
- {"40", CPU_386DX, fpus_80386, 40000000, 1, 5000, 0x0308, 0, 0, 0, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX_DESKPRO386,
- .manufacturer = "Intel",
- .name = "i386DX",
- .internal_name = "i386dx_deskpro386",
- .cpus = (const CPU[]) {
- {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2},
- {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX,
- .manufacturer = "Intel",
- .name = "RapidCAD",
- .internal_name = "rapidcad",
- .cpus = (const CPU[]) {
- {"25", CPU_RAPIDCAD, fpus_internal, 25000000, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
- {"33", CPU_RAPIDCAD, fpus_internal, 33333333, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
- {"40", CPU_RAPIDCAD, fpus_internal, 40000000, 1, 5000, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX,
- .manufacturer = "AMD",
- .name = "Am386DX",
- .internal_name = "am386dx",
- .cpus = (const CPU[]) {
- {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"33", CPU_386DX, fpus_80386, 33333333, 1, 5000, 0x0308, 0, 0, 0, 6,6,3,3, 4},
- {"40", CPU_386DX, fpus_80386, 40000000, 1, 5000, 0x0308, 0, 0, 0, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_M6117,
- .manufacturer = "ALi",
- .name = "M6117",
- .internal_name = "m6117",
- .cpus = (const CPU[]) { /* All timings and edx_reset values assumed. */
- {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2309, 0, 0, 0, 6,6,3,3, 4},
- {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2309, 0, 0, 0, 7,7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386SLC_IBM,
- .manufacturer = "IBM",
- .name = "386SLC",
- .internal_name = "ibm386slc",
- .cpus = (const CPU[]) {
- {"16", CPU_IBM386SLC, fpus_80386, 16000000, 1, 5000, 0xA301, 0, 0, 0, 3,3,3,3, 2},
- {"20", CPU_IBM386SLC, fpus_80386, 20000000, 1, 5000, 0xA301, 0, 0, 0, 4,4,3,3, 3},
- {"25", CPU_IBM386SLC, fpus_80386, 25000000, 1, 5000, 0xA301, 0, 0, 0, 4,4,3,3, 3},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386SX,
- .manufacturer = "Cyrix",
- .name = "Cx486SLC",
- .internal_name = "cx486slc",
- .cpus = (const CPU[]) {
- {"20", CPU_486SLC, fpus_80386, 20000000, 1, 5000, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
- {"25", CPU_486SLC, fpus_80386, 25000000, 1, 5000, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
- {"33", CPU_486SLC, fpus_80386, 33333333, 1, 5000, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386SX,
- .manufacturer = "Cyrix",
- .name = "Cx486SRx2",
- .internal_name = "cx486srx2",
- .cpus = (const CPU[]) {
- {"32", CPU_486SLC, fpus_80386, 32000000, 2, 5000, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
- {"40", CPU_486SLC, fpus_80386, 40000000, 2, 5000, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
- {"50", CPU_486SLC, fpus_80386, 50000000, 2, 5000, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_486SLC_IBM,
- .manufacturer = "IBM",
- .name = "486SLC",
- .internal_name = "ibm486slc",
- .cpus = (const CPU[]) {
- {"33", CPU_IBM486SLC, fpus_80386, 33333333, 1, 5000, 0xA401, 0, 0, 0, 6,6,3,3, 4},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_486SLC_IBM,
- .manufacturer = "IBM",
- .name = "486SLC2",
- .internal_name = "ibm486slc2",
- .cpus = (const CPU[]) {
- {"40", CPU_IBM486SLC, fpus_80386, 40000000, 2, 5000, 0xA421, 0, 0, 0, 7,7,6,6, 5},
- {"50", CPU_IBM486SLC, fpus_80386, 50000000, 2, 5000, 0xA421, 0, 0, 0, 8,8,6,6, 6},
- {"66", CPU_IBM486SLC, fpus_80386, 66666666, 2, 5000, 0xA421, 0, 0, 0, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_486SLC_IBM,
- .manufacturer = "IBM",
- .name = "486SLC3",
- .internal_name = "ibm486slc3",
- .cpus = (const CPU[]) {
- {"60", CPU_IBM486SLC, fpus_80386, 60000000, 3, 5000, 0xA439, 0, 0, 0, 12,12,9,9, 7},
- {"75", CPU_IBM486SLC, fpus_80386, 75000000, 3, 5000, 0xA439, 0, 0, 0, 12,12,9,9, 9},
- {"100", CPU_IBM486SLC, fpus_80386, 100000000, 3, 5000, 0xA439, 0, 0, 0, 18,18,9,9, 12},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_486BL,
- .manufacturer = "IBM",
- .name = "486BL2",
- .internal_name = "ibm486bl2",
- .cpus = (const CPU[]) {
- {"50", CPU_IBM486BL, fpus_80386, 50000000, 2, 5000, 0xA439, 0, 0, 0, 8,8,6,6, 6},
- {"66", CPU_IBM486BL, fpus_80386, 66666666, 2, 5000, 0xA439, 0, 0, 0, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_486BL,
- .manufacturer = "IBM",
- .name = "486BL3",
- .internal_name = "ibm486bl3",
- .cpus = (const CPU[]) {
- {"75", CPU_IBM486BL, fpus_80386, 75000000, 3, 5000, 0xA439, 0, 0, 0, 12,12,9,9, 9},
- {"100", CPU_IBM486BL, fpus_80386, 100000000, 3, 5000, 0xA439, 0, 0, 0, 18,18,9,9, 12},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX,
- .manufacturer = "Cyrix",
- .name = "Cx486DLC",
- .internal_name = "cx486dlc",
- .cpus = (const CPU[]) {
- {"25", CPU_486DLC, fpus_80386, 25000000, 1, 5000, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3},
- {"33", CPU_486DLC, fpus_80386, 33333333, 1, 5000, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4},
- {"40", CPU_486DLC, fpus_80386, 40000000, 1, 5000, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_386DX,
- .manufacturer = "Cyrix",
- .name = "Cx486DRx2",
- .internal_name = "cx486drx2",
- .cpus = (const CPU[]) {
- {"32", CPU_486DLC, fpus_80386, 32000000, 2, 5000, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4},
- {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
- {"50", CPU_486DLC, fpus_80386, 50000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
- {"66", CPU_486DLC, fpus_80386, 66666666, 2, 5000, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486SX",
- .internal_name = "i486sx",
- .cpus = (const CPU[]) {
- {"16", CPU_i486SX, fpus_486sx, 16000000, 1, 5000, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
- {"20", CPU_i486SX, fpus_486sx, 20000000, 1, 5000, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"25", CPU_i486SX, fpus_486sx, 25000000, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"33", CPU_i486SX, fpus_486sx, 33333333, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486SX-S",
- .internal_name = "i486sx_slenh",
- .cpus = (const CPU[]) {
- {"25", CPU_i486SX_SLENH, fpus_486sx, 25000000, 1, 5000, 0x423, 0x423, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"33", CPU_i486SX_SLENH, fpus_486sx, 33333333, 1, 5000, 0x42a, 0x42a, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486SX2",
- .internal_name = "i486sx2",
- .cpus = (const CPU[]) {
- {"50", CPU_i486SX_SLENH, fpus_486sx, 50000000, 2, 5000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"66 (Q0569)", CPU_i486SX_SLENH, fpus_486sx, 66666666, 2, 5000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486DX",
- .internal_name = "i486dx",
- .cpus = (const CPU[]) {
- {"25", CPU_i486DX, fpus_internal, 25000000, 1, 5000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"33", CPU_i486DX, fpus_internal, 33333333, 1, 5000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"50", CPU_i486DX, fpus_internal, 50000000, 1, 5000, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486DX-S",
- .internal_name = "i486dx_slenh",
- .cpus = (const CPU[]) {
- {"33", CPU_i486DX_SLENH, fpus_internal, 33333333, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"50", CPU_i486DX_SLENH, fpus_internal, 50000000, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486DX2",
- .internal_name = "i486dx2",
- .cpus = (const CPU[]) {
- {"40", CPU_i486DX, fpus_internal, 40000000, 2, 5000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
- {"50", CPU_i486DX, fpus_internal, 50000000, 2, 5000, 0x433, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"66", CPU_i486DX, fpus_internal, 66666666, 2, 5000, 0x433, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Intel",
- .name = "i486DX2-S",
- .internal_name = "i486dx2_slenh",
- .cpus = (const CPU[]) {
- {"40", CPU_i486DX_SLENH, fpus_internal, 40000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
- {"50", CPU_i486DX_SLENH, fpus_internal, 50000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"66", CPU_i486DX_SLENH, fpus_internal, 66666666, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330,
- .manufacturer = "Intel",
- .name = "i486DX2 WB",
- .internal_name = "i486dx2_pc330",
- .cpus = (const CPU[]) {
- {"50", CPU_i486DX_SLENH, fpus_internal, 50000000, 2, 5000, 0x436, 0x436, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"66", CPU_i486DX_SLENH, fpus_internal, 66666666, 2, 5000, 0x436, 0x436, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330, /*OEM versions are 3.3V, Retail versions are 3.3V with a 5V regulator for installation in older boards. They are functionally identical*/
- .manufacturer = "Intel",
- .name = "iDX4",
- .internal_name = "idx4",
- .cpus = (const CPU[]) {
- {"75", CPU_i486DX_SLENH, fpus_internal, 75000000, 3.0, 5000, 0x480, 0x480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"100", CPU_i486DX_SLENH, fpus_internal, 100000000, 3.0, 5000, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3 | CPU_PKG_SOCKET3_PC330,
- .manufacturer = "Intel",
- .name = "Pentium OverDrive",
- .internal_name = "pentium_p24t",
- .cpus = (const CPU[]) {
- {"63", CPU_P24T, fpus_internal, 62500000, 2.5, 5000, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
- {"83", CPU_P24T, fpus_internal, 83333333, 2.5, 5000, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486SX",
- .internal_name = "am486sx",
- .cpus = (const CPU[]) {
- {"33", CPU_Am486SX, fpus_486sx, 33333333, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"40", CPU_Am486SX, fpus_486sx, 40000000, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486SX2",
- .internal_name = "am486sx2",
- .cpus = (const CPU[]) {
- {"50", CPU_Am486SX, fpus_486sx, 50000000, 2, 5000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"66", CPU_Am486SX, fpus_486sx, 66666666, 2, 5000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486DX",
- .internal_name = "am486dx",
- .cpus = (const CPU[]) {
- {"33", CPU_Am486DX, fpus_internal, 33333333, 1, 5000, 0x412, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"40", CPU_Am486DX, fpus_internal, 40000000, 1, 5000, 0x412, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486DX2",
- .internal_name = "am486dx2",
- .cpus = (const CPU[]) {
- {"50", CPU_Am486DX, fpus_internal, 50000000, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"66", CPU_Am486DX, fpus_internal, 66666666, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"80", CPU_Am486DX, fpus_internal, 80000000, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486DXL",
- .internal_name = "am486dxl",
- .cpus = (const CPU[]) {
- {"33", CPU_Am486DXL, fpus_internal, 33333333, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"40", CPU_Am486DXL, fpus_internal, 40000000, 1, 5000, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "AMD",
- .name = "Am486DXL2",
- .internal_name = "am486dxl2",
- .cpus = (const CPU[]) {
- {"50", CPU_Am486DXL, fpus_internal, 50000000, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"66", CPU_Am486DXL, fpus_internal, 66666666, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"80", CPU_Am486DXL, fpus_internal, 80000000, 2, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "AMD",
- .name = "Am486DX4",
- .internal_name = "am486dx4",
- .cpus = (const CPU[]) {
- {"75", CPU_Am486DX, fpus_internal, 75000000, 3.0, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"90", CPU_Am486DX, fpus_internal, 90000000, 3.0, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"100", CPU_Am486DX, fpus_internal, 100000000, 3.0, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"120", CPU_Am486DX, fpus_internal, 120000000, 3.0, 5000, 0x432, 0, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "AMD",
- .name = "Am486DX2 (Enhanced)",
- .internal_name = "am486dx2_slenh",
- .cpus = (const CPU[]) {
- {"66", CPU_ENH_Am486DX, fpus_internal, 66666666, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"80", CPU_ENH_Am486DX, fpus_internal, 80000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "AMD",
- .name = "Am486DX4 (Enhanced)",
- .internal_name = "am486dx4_slenh",
- .cpus = (const CPU[]) {
- {"75", CPU_ENH_Am486DX, fpus_internal, 75000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"100", CPU_ENH_Am486DX, fpus_internal, 100000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"120", CPU_ENH_Am486DX, fpus_internal, 120000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "AMD",
- .name = "Am5x86",
- .internal_name = "am5x86",
- .cpus = (const CPU[]) {
- {"133 (P75)", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
- {"150 (P75+)", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/
- {"160 (P90)", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Cyrix",
- .name = "Cx486S",
- .internal_name = "cx486s",
- .cpus = (const CPU[]) {
- {"25", CPU_Cx486S, fpus_486sx, 25000000, 1.0, 5000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
- {"33", CPU_Cx486S, fpus_486sx, 33333333, 1.0, 5000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"40", CPU_Cx486S, fpus_486sx, 40000000, 1.0, 5000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Cyrix",
- .name = "Cx486DX",
- .internal_name = "cx486dx",
- .cpus = (const CPU[]) {
- {"33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 5000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 5000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET1,
- .manufacturer = "Cyrix",
- .name = "Cx486DX2",
- .internal_name = "cx486dx2",
- .cpus = (const CPU[]) {
- {"50", CPU_Cx486DX, fpus_internal, 50000000, 2.0, 5000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"66", CPU_Cx486DX, fpus_internal, 66666666, 2.0, 5000, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"80", CPU_Cx486DX, fpus_internal, 80000000, 2.0, 5000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "Cyrix",
- .name = "Cx486DX4",
- .internal_name = "cx486dx4",
- .cpus = (const CPU[]) {
- {"75", CPU_Cx486DX, fpus_internal, 75000000, 3.0, 5000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"100", CPU_Cx486DX, fpus_internal, 100000000, 3.0, 5000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET3,
- .manufacturer = "Cyrix",
- .name = "Cx5x86",
- .internal_name = "cx5x86",
- .cpus = (const CPU[]) {
- {"80", CPU_Cx5x86, fpus_internal, 80000000, 2.0, 5000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/
- {"100", CPU_Cx5x86, fpus_internal, 100000000, 3.0, 5000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"120", CPU_Cx5x86, fpus_internal, 120000000, 3.0, 5000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
- {"133", CPU_Cx5x86, fpus_internal, 133333333, 4.0, 5000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_STPC,
- .manufacturer = "ST",
- .name = "STPC-DX",
- .internal_name = "stpc_dx",
- .cpus = (const CPU[]) {
- {"66", CPU_STPC, fpus_internal, 66666666, 1.0, 3300, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"75", CPU_STPC, fpus_internal, 75000000, 1.0, 3300, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_STPC,
- .manufacturer = "ST",
- .name = "STPC-DX2",
- .internal_name = "stpc_dx2",
- .cpus = (const CPU[]) {
- {"133", CPU_STPC, fpus_internal, 133333333, 2.0, 3300, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET4,
- .manufacturer = "Intel",
- .name = "Pentium",
- .internal_name = "pentium_p5",
- .cpus = (const CPU[]) {
- {"50 (Q0399)", CPU_PENTIUM, fpus_internal, 50000000, 1, 5000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 4, 4,3,3, 6},
- {"60", CPU_PENTIUM, fpus_internal, 60000000, 1, 5000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6,3,3, 7},
- {"66", CPU_PENTIUM, fpus_internal, 66666666, 1, 5000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6,3,3, 8},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET4,
- .manufacturer = "Intel",
- .name = "Pentium OverDrive",
- .internal_name = "pentium_p54c_od5v",
- .cpus = (const CPU[]) {
- {"100", CPU_PENTIUM, fpus_internal, 100000000, 2, 5000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 8, 8,6,6, 12},
- {"120", CPU_PENTIUM, fpus_internal, 120000000, 2, 5000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12,6,6, 14},
- {"133", CPU_PENTIUM, fpus_internal, 133333333, 2, 5000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12,6,6, 16},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Intel",
- .name = "Pentium",
- .internal_name = "pentium_p54c",
- .cpus = (const CPU[]) {
- {"75", CPU_PENTIUM, fpus_internal, 75000000, 1.5, 3520, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"90", CPU_PENTIUM, fpus_internal, 90000000, 1.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
- {"100/50", CPU_PENTIUM, fpus_internal, 100000000, 2.0, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
- {"100/66", CPU_PENTIUM, fpus_internal, 100000000, 1.5, 3520, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
- {"120", CPU_PENTIUM, fpus_internal, 120000000, 2.0, 3520, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
- {"133", CPU_PENTIUM, fpus_internal, 133333333, 2.0, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
- {"150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"200", CPU_PENTIUM, fpus_internal, 200000000, 3.0, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Intel",
- .name = "Pentium MMX",
- .internal_name = "pentium_p55c",
- .cpus = (const CPU[]) {
- {"166", CPU_PENTIUMMMX, fpus_internal, 166666666, 2.5, 2800, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 2800, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"233", CPU_PENTIUMMMX, fpus_internal, 233333333, 3.5, 2800, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Intel",
- .name = "Mobile Pentium MMX",
- .internal_name = "pentium_tillamook",
- .cpus = (const CPU[]) {
- {"120", CPU_PENTIUMMMX, fpus_internal, 120000000, 2.0, 2800, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"133", CPU_PENTIUMMMX, fpus_internal, 133333333, 2.0, 2800, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"150", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 2800, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"166", CPU_PENTIUMMMX, fpus_internal, 166666666, 2.5, 2800, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 2800, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"233", CPU_PENTIUMMMX, fpus_internal, 233333333, 3.5, 2800, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"266", CPU_PENTIUMMMX, fpus_internal, 266666666, 4.0, 2800, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"300", CPU_PENTIUMMMX, fpus_internal, 300000000, 4.5, 2800, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Intel",
- .name = "Pentium OverDrive",
- .internal_name = "pentium_p54c_od3v",
- .cpus = (const CPU[]) {
- {"125", CPU_PENTIUM, fpus_internal, 125000000, 3.0, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12,7,7, 15},
- {"150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15,7,7, 35/2},
- {"166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 3520, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15,7,7, 20},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Intel",
- .name = "Pentium OverDrive MMX",
- .internal_name = "pentium_p55c_od",
- .cpus = (const CPU[]) {
- {"75", CPU_PENTIUMMMX, fpus_internal, 75000000, 1.5, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 7, 7,4,4, 9},
- {"125", CPU_PENTIUMMMX, fpus_internal, 125000000, 2.5, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12,7,7, 15},
- {"150/60", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15,7,7, 35/2},
- {"166", CPU_PENTIUMMMX, fpus_internal, 166000000, 2.5, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15,7,7, 20},
- {"180", CPU_PENTIUMMMX, fpus_internal, 180000000, 3.0, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 18,18,9,9, 21},
- {"200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 3520, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 18,18,9,9, 24},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "IDT",
- .name = "WinChip",
- .internal_name = "winchip",
- .cpus = (const CPU[]) {
- {"75", CPU_WINCHIP, fpus_internal, 75000000, 1.5, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
- {"90", CPU_WINCHIP, fpus_internal, 90000000, 1.5, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
- {"100", CPU_WINCHIP, fpus_internal, 100000000, 1.5, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
- {"120", CPU_WINCHIP, fpus_internal, 120000000, 2.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14},
- {"133", CPU_WINCHIP, fpus_internal, 133333333, 2.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16},
- {"150", CPU_WINCHIP, fpus_internal, 150000000, 2.5, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2},
- {"166", CPU_WINCHIP, fpus_internal, 166666666, 2.5, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40},
- {"180", CPU_WINCHIP, fpus_internal, 180000000, 3.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21},
- {"200", CPU_WINCHIP, fpus_internal, 200000000, 3.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
- {"225", CPU_WINCHIP, fpus_internal, 225000000, 3.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
- {"240", CPU_WINCHIP, fpus_internal, 240000000, 4.0, 3520, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "IDT",
- .name = "WinChip 2",
- .internal_name = "winchip2",
- .cpus = (const CPU[]) {
- {"200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 3520, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
- {"225", CPU_WINCHIP2, fpus_internal, 225000000, 3.0, 3520, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9},
- {"240", CPU_WINCHIP2, fpus_internal, 240000000, 4.0, 3520, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"250", CPU_WINCHIP2, fpus_internal, 250000000, 3.0, 3520, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "IDT",
- .name = "WinChip 2A",
- .internal_name = "winchip2a",
- .cpus = (const CPU[]) {
- {"200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 3520, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
- {"233", CPU_WINCHIP2, fpus_internal, 233333333, 3.5, 3520, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2},
- {"266", CPU_WINCHIP2, fpus_internal, 233333333, 7.0/3.0, 3520, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28},
- {"300", CPU_WINCHIP2, fpus_internal, 250000000, 2.5, 3520, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30},
- {"", 0}
- }
- },
-#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
- {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K5 (Model 0)",
- .internal_name = "k5_ssa5",
- .cpus = (const CPU[]) {
- {"75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
- {"100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K5 (Model 1/2/3)",
- .internal_name = "k5_5k86",
- .cpus = (const CPU[]) {
- {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
- {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
- {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
- {"116.7 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
- {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
- {"", 0}
- }
+ {
+ .name = "10",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ { .name = "", 0 }
+ }
},
-#endif
{
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6 (Model 6)",
- .internal_name = "k6_m6",
- .cpus = (const CPU[]) {
- {"66", CPU_K6, fpus_internal, 66666666, 1.0, 2900, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, /* out of spec */
- {"100", CPU_K6, fpus_internal, 100000000, 1.5, 2900, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_K6, fpus_internal, 133333333, 2.0, 2900, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6, fpus_internal, 166666666, 2.5, 2900, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"200", CPU_K6, fpus_internal, 200000000, 3.0, 2900, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"233", CPU_K6, fpus_internal, 233333333, 3.5, 3200, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6 (Model 7)",
- .internal_name = "k6_m7",
- .cpus = (const CPU[]) {
- {"100", CPU_K6, fpus_internal, 100000000, 1.5, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_K6, fpus_internal, 133333333, 2.0, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6, fpus_internal, 166666666, 2.5, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, /* out of spec */
- {"200", CPU_K6, fpus_internal, 200000000, 3.0, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"233", CPU_K6, fpus_internal, 233333333, 3.5, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"266", CPU_K6, fpus_internal, 266666666, 4.0, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"300", CPU_K6, fpus_internal, 300000000, 4.5, 2200, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6-2",
- .internal_name = "k6_2",
- .cpus = (const CPU[]) {
- {"100", CPU_K6_2, fpus_internal, 100000000, 1.5, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_K6_2, fpus_internal, 133333333, 2.0, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6_2, fpus_internal, 166666666, 2.5, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, /* out of spec */
- {"200", CPU_K6_2, fpus_internal, 200000000, 3.0, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, /* out of spec */
- {"233", CPU_K6_2, fpus_internal, 233333333, 3.5, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28},
- {"266", CPU_K6_2, fpus_internal, 266666666, 4.0, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32},
- {"300", CPU_K6_2, fpus_internal, 300000000, 3.0, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36},
- {"333", CPU_K6_2, fpus_internal, 332500000, 3.5, 2200, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40},
- {"350", CPU_K6_2C, fpus_internal, 350000000, 3.5, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42},
- {"366", CPU_K6_2C, fpus_internal, 366666666, 5.5, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44},
- {"380", CPU_K6_2C, fpus_internal, 380000000, 4.0, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46},
- {"400/66", CPU_K6_2C, fpus_internal, 400000000, 6.0, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"400/100", CPU_K6_2C, fpus_internal, 400000000, 4.0, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"450", CPU_K6_2C, fpus_internal, 450000000, 4.5, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"475", CPU_K6_2C, fpus_internal, 475000000, 5.0, 2400, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"500", CPU_K6_2C, fpus_internal, 500000000, 5.0, 2400, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"533", CPU_K6_2C, fpus_internal, 533333333, 5.5, 2200, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
- {"550", CPU_K6_2C, fpus_internal, 550000000, 5.5, 2300, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6-2+",
- .internal_name = "k6_2p",
- .cpus = (const CPU[]) {
- {"100", CPU_K6_2P, fpus_internal, 100000000, 1.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_K6_2P, fpus_internal, 133333333, 2.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6_2P, fpus_internal, 166666666, 2.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, /* out of spec */
- {"200", CPU_K6_2P, fpus_internal, 200000000, 3.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, /* out of spec */
- {"233", CPU_K6_2P, fpus_internal, 233333333, 3.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, /* out of spec */
- {"266", CPU_K6_2P, fpus_internal, 266666666, 4.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, /* out of spec */
- {"300", CPU_K6_2P, fpus_internal, 300000000, 3.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, /* out of spec */
- {"333", CPU_K6_2P, fpus_internal, 332500000, 3.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, /* out of spec */
- {"350", CPU_K6_2P, fpus_internal, 350000000, 3.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, /* out of spec */
- {"366", CPU_K6_2P, fpus_internal, 366666666, 5.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, /* out of spec */
- {"380", CPU_K6_2P, fpus_internal, 380000000, 4.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, /* out of spec */
- {"400/66", CPU_K6_2P, fpus_internal, 400000000, 6.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, /* out of spec */
- {"400/100", CPU_K6_2P, fpus_internal, 400000000, 4.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, /* out of spec */
- {"450", CPU_K6_2P, fpus_internal, 450000000, 4.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"475", CPU_K6_2P, fpus_internal, 475000000, 5.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"500", CPU_K6_2P, fpus_internal, 500000000, 5.0, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"533", CPU_K6_2P, fpus_internal, 533333333, 5.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
- {"550", CPU_K6_2P, fpus_internal, 550000000, 5.5, 2000, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6-III",
- .internal_name = "k6_3",
- .cpus = (const CPU[]) {
- {"100", CPU_K6_3, fpus_internal, 100000000, 1.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_K6_3, fpus_internal, 133333333, 2.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6_3, fpus_internal, 166666666, 2.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, /* out of spec */
- {"200", CPU_K6_3, fpus_internal, 200000000, 3.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, /* out of spec */
- {"233", CPU_K6_3, fpus_internal, 233333333, 3.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, /* out of spec */
- {"266", CPU_K6_3, fpus_internal, 266666666, 4.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, /* out of spec */
- {"300", CPU_K6_3, fpus_internal, 300000000, 3.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, /* out of spec */
- {"333", CPU_K6_3, fpus_internal, 332500000, 3.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, /* out of spec */
- {"350", CPU_K6_3, fpus_internal, 350000000, 3.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, /* out of spec */
- {"366", CPU_K6_3, fpus_internal, 366666666, 5.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, /* out of spec */
- {"380", CPU_K6_3, fpus_internal, 380000000, 4.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, /* out of spec */
- {"400", CPU_K6_3, fpus_internal, 400000000, 4.0, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"450", CPU_K6_3, fpus_internal, 450000000, 4.5, 2200, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "AMD",
- .name = "K6-III+",
- .internal_name = "k6_3p",
- .cpus = (const CPU[]) {
- {"100", CPU_K6_3P, fpus_internal, 100000000, 1.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, /* out of spec */
- {"133", CPU_K6_3P, fpus_internal, 133333333, 2.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 16}, /* out of spec */
- {"166", CPU_K6_3P, fpus_internal, 166666666, 2.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, /* out of spec */
- {"200", CPU_K6_3P, fpus_internal, 200000000, 3.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, /* out of spec */
- {"233", CPU_K6_3P, fpus_internal, 233333333, 3.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, /* out of spec */
- {"266", CPU_K6_3P, fpus_internal, 266666666, 4.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, /* out of spec */
- {"300", CPU_K6_3P, fpus_internal, 300000000, 3.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, /* out of spec */
- {"333", CPU_K6_3P, fpus_internal, 332500000, 3.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, /* out of spec */
- {"350", CPU_K6_3P, fpus_internal, 350000000, 3.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, /* out of spec */
- {"366", CPU_K6_3P, fpus_internal, 366666666, 5.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, /* out of spec */
- {"380", CPU_K6_3P, fpus_internal, 380000000, 4.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, /* out of spec */
- {"400", CPU_K6_3P, fpus_internal, 400000000, 4.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"450", CPU_K6_3P, fpus_internal, 450000000, 4.5, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"475", CPU_K6_3P, fpus_internal, 475000000, 5.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"500", CPU_K6_3P, fpus_internal, 500000000, 5.0, 2000, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"", 0}
- }
- },
-#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
- {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Cyrix",
- .name = "Cx6x86",
- .internal_name = "cx6x86",
- .cpus = (const CPU[]) {
- {"80 (PR90+)", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
- {"100 (PR120+)", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"110 (PR133+)", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"120 (PR150+)", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"133 (PR166+)", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"150 (PR200+)", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Cyrix",
- .name = "Cx6x86L",
- .internal_name = "cx6x86l",
- .cpus = (const CPU[]) {
- {"110 (PR133+)", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"120 (PR150+)", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"133 (PR166+)", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"150 (PR200+)", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Cyrix",
- .name = "Cx6x86MX",
- .internal_name = "cx6x86mx",
- .cpus = (const CPU[]) {
- {"133 (PR166)", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"166 (PR200)", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"187.5 (PR233)", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
- {"208.3 (PR266)", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET5_7,
- .manufacturer = "Cyrix",
- .name = "MII",
- .internal_name = "mii",
- .cpus = (const CPU[]) {
- {"233 (PR300)", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28},
- {"250/83 (PR333)", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30},
- {"250/100 (PR366)", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30},
- {"285 (PR400)", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34},
- {"300 (PR433)", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36},
- {"", 0}
- }
+ .package = CPU_PKG_8088_EUROPC,
+ .manufacturer = "Intel",
+ .name = "8088",
+ .internal_name = "8088_europc",
+ .cpus = (const CPU[]) {
+ {
+ .name = "4.77",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 4772728,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "7.16",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "9.54",
+ .cpu_type = CPU_8088,
+ .fpus = fpus_8088,
+ .rspeed = 9545456,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ { .name = "", 0 }
+ }
},
-#endif
{
- .package = CPU_PKG_SOCKET8,
- .manufacturer = "Intel",
- .name = "Pentium Pro",
- .internal_name = "pentiumpro",
- .cpus = (const CPU[]) {
- {"60", CPU_PENTIUMPRO, fpus_internal, 60000000, 1.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 1, 1, 7}, /* out of spec */
- {"66", CPU_PENTIUMPRO, fpus_internal, 66666666, 1.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 1, 1, 8}, /* out of spec */
- {"90", CPU_PENTIUMPRO, fpus_internal, 90000000, 1.5, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 11}, /* out of spec */
- {"100", CPU_PENTIUMPRO, fpus_internal, 100000000, 1.5, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 12}, /* out of spec */
- {"120", CPU_PENTIUMPRO, fpus_internal, 120000000, 2.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 5, 5, 14}, /* out of spec */
- {"133", CPU_PENTIUMPRO, fpus_internal, 133333333, 2.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 5, 5, 16}, /* out of spec */
- {"150", CPU_PENTIUMPRO, fpus_internal, 150000000, 2.5, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"166", CPU_PENTIUMPRO, fpus_internal, 166666666, 2.5, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"180", CPU_PENTIUMPRO, fpus_internal, 180000000, 3.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
- {"200", CPU_PENTIUMPRO, fpus_internal, 200000000, 3.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SOCKET8,
- .manufacturer = "Intel",
- .name = "Pentium II OverDrive",
- .internal_name = "pentium2_od",
- .cpus = (const CPU[]) {
- {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of spec */
- {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12, 6, 6, 16}, /* out of spec */
- {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15, 7, 7, 20}, /* out of spec */
- {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 18,18, 9, 9, 24}, /* out of spec */
- {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 21,21,10,10, 28}, /* out of spec */
- {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 24,24,12,12, 32}, /* out of spec */
- {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 5.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 36},
- {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 40},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SLOT1,
- .manufacturer = "Intel",
- .name = "Pentium II (Klamath)",
- .internal_name = "pentium2_klamath",
- .cpus = (const CPU[]) {
- {"66", CPU_PENTIUM2, fpus_internal, 66666666, 1.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, /* out of spec */
- {"100", CPU_PENTIUM2, fpus_internal, 100000000, 1.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */
- {"133", CPU_PENTIUM2, fpus_internal, 133333333, 2.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */
- {"166", CPU_PENTIUM2, fpus_internal, 166666666, 2.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, /* out of spec */
- {"200", CPU_PENTIUM2, fpus_internal, 200000000, 3.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, /* out of spec */
- {"233", CPU_PENTIUM2, fpus_internal, 233333333, 3.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"266", CPU_PENTIUM2, fpus_internal, 266666666, 4.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"300", CPU_PENTIUM2, fpus_internal, 300000000, 4.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
- {"", 0}
- }
- }, {
- .package = CPU_PKG_SLOT1,
- .manufacturer = "Intel",
- .name = "Pentium II (Deschutes)",
- .internal_name = "pentium2_deschutes",
- .cpus = (const CPU[]) {
- {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, /* out of spec */
- {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 5, 5, 12}, /* out of spec */
- {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */
- {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, /* out of spec */
- {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, /* out of spec */
- {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, /* out of spec */
- {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
- {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
- {"350", CPU_PENTIUM2D, fpus_internal, 350000000, 3.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42},
- {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48},
- {"450", CPU_PENTIUM2D, fpus_internal, 450000000, 4.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54},
- {"", 0}
- }
+ .package = CPU_PKG_8086,
+ .manufacturer = "Intel",
+ .name = "8086",
+ .internal_name = "8086",
+ .cpus = (const CPU[]) {
+ {
+ .name = "7.16",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "9.54",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 9545456,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_8086,
+ .fpus = fpus_8088,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 2
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_188,
+ .manufacturer = "Intel",
+ .name = "80188",
+ .internal_name = "80188",
+ .cpus = (const CPU[]) {
+ {
+ .name = "6",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 6000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "7.16",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "9.54",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 9545456,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_188,
+ .fpus = fpus_8088,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 3
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_8088,
+ .manufacturer = "NEC",
+ .name = "V20",
+ .internal_name = "necv20",
+ .cpus = (const CPU[]) {
+ {
+ .name = "4.77",
+ .cpu_type = CPU_V20,
+ .fpus = fpus_8088,
+ .rspeed = 4772728,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "7.16",
+ .cpu_type = CPU_V20,
+ .fpus = fpus_8088,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_V20,
+ .fpus = fpus_8088,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_V20,
+ .fpus = fpus_8088,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_V20,
+ .fpus = fpus_8088,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 2
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_186,
+ .manufacturer = "Intel",
+ .name = "80186",
+ .internal_name = "80186",
+ .cpus = (const CPU[]) {
+ {
+ .name = "6",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 6000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "7.16",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 7159092,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "9.54",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 9545456,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_ALTERNATE_XTAL,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_186,
+ .fpus = fpus_80186,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 0,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 3
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_8086,
+ .manufacturer = "NEC",
+ .name = "V30",
+ .internal_name = "necv30",
+ .cpus = (const CPU[]) {
+ {
+ .name = "5",
+ .cpu_type = CPU_V30,
+ .fpus = fpus_80186,
+ .rspeed = 5000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_V30,
+ .fpus = fpus_80186,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_V30,
+ .fpus = fpus_80186,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_V30,
+ .fpus = fpus_80186,
+ .rspeed = 12000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 1
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_V30,
+ .fpus = fpus_80186,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 0,
+ .mem_write_cycles = 0,
+ .cache_read_cycles = 0,
+ .cache_write_cycles = 0,
+ .atclk_div = 2
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_286,
+ .manufacturer = "Intel",
+ .name = "80286",
+ .internal_name = "286",
+ .cpus = (const CPU[]) {
+ {
+ .name = "6",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 6000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 2,
+ .mem_write_cycles = 2,
+ .cache_read_cycles = 2,
+ .cache_write_cycles = 2,
+ .atclk_div = 1
+ },
+ {
+ .name = "8",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 8000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 2,
+ .mem_write_cycles = 2,
+ .cache_read_cycles = 2,
+ .cache_write_cycles = 2,
+ .atclk_div = 1
+ },
+ {
+ .name = "10",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 10000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 2,
+ .mem_write_cycles = 2,
+ .cache_read_cycles = 2,
+ .cache_write_cycles = 2,
+ .atclk_div = 1
+ },
+ {
+ .name = "12",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 12500000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "16",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_286,
+ .fpus = fpus_80286,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 3
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386SX,
+ .manufacturer = "Intel",
+ .name = "i386SX",
+ .internal_name = "i386sx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386SX,
+ .manufacturer = "AMD",
+ .name = "Am386SX",
+ .internal_name = "am386sx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX,
+ .manufacturer = "Intel",
+ .name = "i386DX",
+ .internal_name = "i386dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX_DESKPRO386,
+ .manufacturer = "Intel",
+ .name = "i386DX",
+ .internal_name = "i386dx_deskpro386",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80286,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX,
+ .manufacturer = "Intel",
+ .name = "RapidCAD",
+ .internal_name = "rapidcad",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_RAPIDCAD,
+ .fpus = fpus_internal,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0340,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_RAPIDCAD,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0340,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_RAPIDCAD,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0340,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX,
+ .manufacturer = "AMD",
+ .name = "Am386DX",
+ .internal_name = "am386dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_386DX,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x0308,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_M6117,
+ .manufacturer = "ALi",
+ .name = "M6117",
+ .internal_name = "m6117",
+ .cpus = (const CPU[]) { /* All timings and edx_reset values assumed. */
+ {
+ .name = "33",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_none,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2309,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_386SX,
+ .fpus = fpus_none,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x2309,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386SLC_IBM,
+ .manufacturer = "IBM",
+ .name = "386SLC",
+ .internal_name = "ibm386slc",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_IBM386SLC,
+ .fpus = fpus_80386,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0xA301,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_IBM386SLC,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0xA301,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_IBM386SLC,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0xA301,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386SX,
+ .manufacturer = "Cyrix",
+ .name = "Cx486SLC",
+ .internal_name = "cx486slc",
+ .cpus = (const CPU[]) {
+ {
+ .name = "20",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x400,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0000,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x400,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0000,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x400,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0000,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386SX,
+ .manufacturer = "Cyrix",
+ .name = "Cx486SRx2",
+ .internal_name = "cx486srx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "32",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 32000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x406,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0006,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x406,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0006,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x406,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0006,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_486SLC_IBM,
+ .manufacturer = "IBM",
+ .name = "486SLC",
+ .internal_name = "ibm486slc",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0xA401,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_486SLC_IBM,
+ .manufacturer = "IBM",
+ .name = "486SLC2",
+ .internal_name = "ibm486slc2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "40",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0xA421,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 5
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0xA421,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0xA421,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_486SLC_IBM,
+ .manufacturer = "IBM",
+ .name = "486SLC3",
+ .internal_name = "ibm486slc3",
+ .cpus = (const CPU[]) {
+ {
+ .name = "60",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 60000000,
+ .multi = 3,
+ .voltage = 5000,
+ .edx_reset = 0xA439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 7
+ },
+ {
+ .name = "75",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 75000000,
+ .multi = 3,
+ .voltage = 5000,
+ .edx_reset = 0xA439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_IBM486SLC,
+ .fpus = fpus_80386,
+ .rspeed = 100000000,
+ .multi = 3,
+ .voltage = 5000,
+ .edx_reset = 0xA439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_486BL,
+ .manufacturer = "IBM",
+ .name = "486BL2",
+ .internal_name = "ibm486bl2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_IBM486BL,
+ .fpus = fpus_80386,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x8439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_IBM486BL,
+ .fpus = fpus_80386,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x8439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_486BL,
+ .manufacturer = "IBM",
+ .name = "486BL3",
+ .internal_name = "ibm486bl3",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_IBM486BL,
+ .fpus = fpus_80386,
+ .rspeed = 75000000,
+ .multi = 3,
+ .voltage = 5000,
+ .edx_reset = 0x8439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_IBM486BL,
+ .fpus = fpus_80386,
+ .rspeed = 100000000,
+ .multi = 3,
+ .voltage = 5000,
+ .edx_reset = 0x8439,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = 0,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX,
+ .manufacturer = "Cyrix",
+ .name = "Cx486DLC",
+ .internal_name = "cx486dlc",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x401,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0001,
+ .cpu_flags = 0,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x401,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0001,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x401,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0001,
+ .cpu_flags = 0,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_386DX,
+ .manufacturer = "Cyrix",
+ .name = "Cx486DRx2",
+ .internal_name = "cx486drx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "32",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 32000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x407,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0007,
+ .cpu_flags = 0,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 40000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x407,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0007,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x407,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0007,
+ .cpu_flags = 0,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_486DLC,
+ .fpus = fpus_80386,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x407,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0007,
+ .cpu_flags = 0,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486SX",
+ .internal_name = "i486sx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "16",
+ .cpu_type = CPU_i486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 16000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x420,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 3,
+ .mem_write_cycles = 3,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 2
+ },
+ {
+ .name = "20",
+ .cpu_type = CPU_i486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 20000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x420,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "25",
+ .cpu_type = CPU_i486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_i486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486SX-S",
+ .internal_name = "i486sx_slenh",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_i486SX_SLENH,
+ .fpus = fpus_486sx,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x423,
+ .cpuid_model = 0x423,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_i486SX_SLENH,
+ .fpus = fpus_486sx,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x42a,
+ .cpuid_model = 0x42a,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486SX2",
+ .internal_name = "i486sx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_i486SX_SLENH,
+ .fpus = fpus_486sx,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x45b,
+ .cpuid_model = 0x45b,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66 (Q0569)",
+ .cpu_type = CPU_i486SX_SLENH,
+ .fpus = fpus_486sx,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x45b,
+ .cpuid_model = 0x45b,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486DX",
+ .internal_name = "i486dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 25000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x404,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x404,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x411,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 6
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486DX-S",
+ .internal_name = "i486dx_slenh",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x414,
+ .cpuid_model = 0x414,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x414,
+ .cpuid_model = 0x414,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 6
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486DX2",
+ .internal_name = "i486dx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "40",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 5
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x433,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_i486DX,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x433,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Intel",
+ .name = "i486DX2-S",
+ .internal_name = "i486dx2_slenh",
+ .cpus = (const CPU[]) {
+ {
+ .name = "40",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x435,
+ .cpuid_model = 0x435,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 5
+ },
+ {
+ .name = "50",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x435,
+ .cpuid_model = 0x435,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x435,
+ .cpuid_model = 0x435,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330,
+ .manufacturer = "Intel",
+ .name = "i486DX2 WB",
+ .internal_name = "i486dx2_pc330",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x436,
+ .cpuid_model = 0x436,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x436,
+ .cpuid_model = 0x436,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ { /*OEM versions are 3.3V, Retail versions are 3.3V with a 5V regulator for installation in older boards. They are functionally identical*/
+ .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330,
+ .manufacturer = "Intel",
+ .name = "iDX4",
+ .internal_name = "idx4",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0x480,
+ .cyrix_id = 0x0000,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_i486DX_SLENH,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x483,
+ .cpuid_model = 0x483,
+ .cyrix_id = 0x0000,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3 | CPU_PKG_SOCKET3_PC330,
+ .manufacturer = "Intel",
+ .name = "Pentium OverDrive",
+ .internal_name = "pentium_p24t",
+ .cpus = (const CPU[]) {
+ {
+ .name = "63",
+ .cpu_type = CPU_P24T,
+ .fpus = fpus_internal,
+ .rspeed = 62500000,
+ .multi = 2.5,
+ .voltage = 5000,
+ .edx_reset = 0x1531,
+ .cpuid_model = 0x1531,
+ .cyrix_id = 0x0000,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 10,
+ .mem_write_cycles = 10,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 15/2
+ },
+ {
+ .name = "83",
+ .cpu_type = CPU_P24T,
+ .fpus = fpus_internal,
+ .rspeed = 83333333,
+ .multi = 2.5,
+ .voltage = 5000,
+ .edx_reset = 0x1532,
+ .cpuid_model = 0x1532,
+ .cyrix_id = 0x0000,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 8,
+ .cache_write_cycles = 8,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486SX",
+ .internal_name = "am486sx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_Am486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_Am486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486SX2",
+ .internal_name = "am486sx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_Am486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x45b,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_Am486SX,
+ .fpus = fpus_486sx,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x45b,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486DX",
+ .internal_name = "am486dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x412,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x412,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486DX2",
+ .internal_name = "am486dx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ {
+ .name = "80",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486DXL",
+ .internal_name = "am486dxl",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_Am486DXL,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_Am486DXL,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x422,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "AMD",
+ .name = "Am486DXL2",
+ .internal_name = "am486dxl2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_Am486DXL,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_Am486DXL,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ {
+ .name = "80",
+ .cpu_type = CPU_Am486DXL,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "AMD",
+ .name = "Am486DX4",
+ .internal_name = "am486dx4",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "90",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 90000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x432,
+ .cpuid_model = 0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 15
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "AMD",
+ .name = "Am486DX2 (Enhanced)",
+ .internal_name = "am486dx2_slenh",
+ .cpus = (const CPU[]) {
+ {
+ .name = "66",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x435,
+ .cpuid_model = 0x435,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ {
+ .name = "80",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x435,
+ .cpuid_model = 0x435,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "AMD",
+ .name = "Am486DX4 (Enhanced)",
+ .internal_name = "am486dx4_slenh",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x482,
+ .cpuid_model = 0x482,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x482,
+ .cpuid_model = 0x482,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x482,
+ .cpuid_model = 0x482,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 15
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "AMD",
+ .name = "Am5x86",
+ .internal_name = "am5x86",
+ .cpus = (const CPU[]) {
+ {
+ .name = "133 (P75)",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 4.0,
+ .voltage = 5000,
+ .edx_reset = 0x4e0,
+ .cpuid_model = 0x4e0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 16
+ },
+ { /*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/
+ .name = "150 (P75+)",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x482,
+ .cpuid_model = 0x482,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 28,
+ .mem_write_cycles = 28,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 20
+ },
+ { /*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/
+ .name = "160 (P90)",
+ .cpu_type = CPU_ENH_Am486DX,
+ .fpus = fpus_internal,
+ .rspeed = 160000000,
+ .multi = 4.0,
+ .voltage = 5000,
+ .edx_reset = 0x4e0,
+ .cpuid_model = 0x4e0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 28,
+ .mem_write_cycles = 28,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 20
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Cyrix",
+ .name = "Cx486S",
+ .internal_name = "cx486s",
+ .cpus = (const CPU[]) {
+ {
+ .name = "25",
+ .cpu_type = CPU_Cx486S,
+ .fpus = fpus_486sx,
+ .rspeed = 25000000,
+ .multi = 1.0,
+ .voltage = 5000,
+ .edx_reset = 0x420,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0010,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 3
+ },
+ {
+ .name = "33",
+ .cpu_type = CPU_Cx486S,
+ .fpus = fpus_486sx,
+ .rspeed = 33333333,
+ .multi = 1.0,
+ .voltage = 5000,
+ .edx_reset = 0x420,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0010,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_Cx486S,
+ .fpus = fpus_486sx,
+ .rspeed = 40000000,
+ .multi = 1.0,
+ .voltage = 5000,
+ .edx_reset = 0x420,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0010,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Cyrix",
+ .name = "Cx486DX",
+ .internal_name = "cx486dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "33",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 33333333,
+ .multi = 1.0,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x051a,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 4
+ },
+ {
+ .name = "40",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 40000000,
+ .multi = 1.0,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x051a,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET1,
+ .manufacturer = "Cyrix",
+ .name = "Cx486DX2",
+ .internal_name = "cx486dx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 2.0,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x081b,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 6
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 2.0,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0b1b,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ {
+ .name = "80",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2.0,
+ .voltage = 5000,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x311b,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "Cyrix",
+ .name = "Cx486DX4",
+ .internal_name = "cx486dx4",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x361f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 9
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_Cx486DX,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x361f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET3,
+ .manufacturer = "Cyrix",
+ .name = "Cx5x86",
+ .internal_name = "cx5x86",
+ .cpus = (const CPU[]) {
+ { /*If we're including the Pentium 50, might as well include this*/
+ .name = "80",
+ .cpu_type = CPU_Cx5x86,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x002f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_Cx5x86,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x002f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_Cx5x86,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 3.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x002f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 15
+ },
+ {
+ .name = "133",
+ .cpu_type = CPU_Cx5x86,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 4.0,
+ .voltage = 5000,
+ .edx_reset = 0x480,
+ .cpuid_model = 0,
+ .cyrix_id = 0x002f,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 16
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_STPC,
+ .manufacturer = "ST",
+ .name = "STPC-DX",
+ .internal_name = "stpc_dx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "66",
+ .cpu_type = CPU_STPC,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 3300,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x051a,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ {
+ .name = "75",
+ .cpu_type = CPU_STPC,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 1.0,
+ .voltage = 3300,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x051a,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 5
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_STPC,
+ .manufacturer = "ST",
+ .name = "STPC-DX2",
+ .internal_name = "stpc_dx2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "133",
+ .cpu_type = CPU_STPC,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3300,
+ .edx_reset = 0x430,
+ .cpuid_model = 0,
+ .cyrix_id = 0x0b1b,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET4,
+ .manufacturer = "Intel",
+ .name = "Pentium",
+ .internal_name = "pentium_p5",
+ .cpus = (const CPU[]) {
+ {
+ .name = "50 (Q0399)",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 50000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x513,
+ .cpuid_model = 0x513,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 4,
+ .mem_write_cycles = 4,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 6
+ },
+ {
+ .name = "60",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 60000000,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x517,
+ .cpuid_model = 0x517,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 7
+ },
+ {
+ .name = "66",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1,
+ .voltage = 5000,
+ .edx_reset = 0x517,
+ .cpuid_model = 0x517,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET4,
+ .manufacturer = "Intel",
+ .name = "Pentium OverDrive",
+ .internal_name = "pentium_p54c_od5v",
+ .cpus = (const CPU[]) {
+ {
+ .name = "100",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x51A,
+ .cpuid_model = 0x51A,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x51A,
+ .cpuid_model = 0x51A,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2,
+ .voltage = 5000,
+ .edx_reset = 0x51A,
+ .cpuid_model = 0x51A,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Intel",
+ .name = "Pentium",
+ .internal_name = "pentium_p54c",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x522,
+ .cpuid_model = 0x522,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 9
+ },
+ {
+ .name = "90",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 90000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x524,
+ .cpuid_model = 0x524,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 21/2
+ },
+ {
+ .name = "100/50",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x524,
+ .cpuid_model = 0x524,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 10,
+ .mem_write_cycles = 10,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 12
+ },
+ {
+ .name = "100/66",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x526,
+ .cpuid_model = 0x526,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x526,
+ .cpuid_model = 0x526,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "150",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Intel",
+ .name = "Pentium MMX",
+ .internal_name = "pentium_p55c",
+ .cpus = (const CPU[]) {
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2800,
+ .edx_reset = 0x543,
+ .cpuid_model = 0x543,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2800,
+ .edx_reset = 0x543,
+ .cpuid_model = 0x543,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2800,
+ .edx_reset = 0x543,
+ .cpuid_model = 0x543,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Intel",
+ .name = "Mobile Pentium MMX",
+ .internal_name = "pentium_tillamook",
+ .cpus = (const CPU[]) {
+ {
+ .name = "120",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x543,
+ .cpuid_model = 0x543,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x543,
+ .cpuid_model = 0x543,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "150",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 2800,
+ .edx_reset = 0x544,
+ .cpuid_model = 0x544,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2800,
+ .edx_reset = 0x544,
+ .cpuid_model = 0x544,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2800,
+ .edx_reset = 0x581,
+ .cpuid_model = 0x581,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2800,
+ .edx_reset = 0x581,
+ .cpuid_model = 0x581,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2800,
+ .edx_reset = 0x582,
+ .cpuid_model = 0x582,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2800,
+ .edx_reset = 0x582,
+ .cpuid_model = 0x582,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 36
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Intel",
+ .name = "Pentium OverDrive",
+ .internal_name = "pentium_p54c_od3v",
+ .cpus = (const CPU[]) {
+ {
+ .name = "125",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 125000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 15
+ },
+ {
+ .name = "150",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUM,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x52c,
+ .cpuid_model = 0x52c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Intel",
+ .name = "Pentium OverDrive MMX",
+ .internal_name = "pentium_p55c_od",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 9
+ },
+ {
+ .name = "125",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 125000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 15
+ },
+ {
+ .name = "150/60",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 166000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "180",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 180000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 21
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_PENTIUMMMX,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x1542,
+ .cpuid_model = 0x1542,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "IDT",
+ .name = "WinChip",
+ .internal_name = "winchip",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 9
+ },
+ {
+ .name = "90",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 90000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 21/2
+ },
+ {
+ .name = "100",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ {
+ .name = "120",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "150",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 40
+ },
+ {
+ .name = "180",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 180000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 21
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "225",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 225000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 27
+ },
+ {
+ .name = "240",
+ .cpu_type = CPU_WINCHIP,
+ .fpus = fpus_internal,
+ .rspeed = 240000000,
+ .multi = 4.0,
+ .voltage = 3520,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 28
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "IDT",
+ .name = "WinChip 2",
+ .internal_name = "winchip2",
+ .cpus = (const CPU[]) {
+ {
+ .name = "200",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 3*8
+ },
+ {
+ .name = "225",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 225000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 3*9
+ },
+ {
+ .name = "240",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 240000000,
+ .multi = 4.0,
+ .voltage = 3520,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 30
+ },
+ {
+ .name = "250",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 250000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 30
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "IDT",
+ .name = "WinChip 2A",
+ .internal_name = "winchip2a",
+ .cpus = (const CPU[]) {
+ {
+ .name = "200",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x587,
+ .cpuid_model = 0x587,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 3*8
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 3520,
+ .edx_reset = 0x587,
+ .cpuid_model = 0x587,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = (7*8)/2
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 7.0/3.0,
+ .voltage = 3520,
+ .edx_reset = 0x587,
+ .cpuid_model = 0x587,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 28
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_WINCHIP2,
+ .fpus = fpus_internal,
+ .rspeed = 250000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x587,
+ .cpuid_model = 0x587,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 8,
+ .cache_write_cycles = 8,
+ .atclk_div = 30
+ },
+ { .name = "", 0 }
+ }
+ },
+#ifdef USE_AMD_K5
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K5 (Model 0)",
+ .internal_name = "k5_ssa5",
+ .cpus = (const CPU[]) {
+ {
+ .name = "75 (PR75)",
+ .cpu_type = CPU_K5,
+ .fpus = fpus_internal,
+ .rspeed = 75000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x501,
+ .cpuid_model = 0x501,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 9
+ },
+ {
+ .name = "90 (PR90)",
+ .cpu_type = CPU_K5,
+ .fpus = fpus_internal,
+ .rspeed = 90000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x501,
+ .cpuid_model = 0x501,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 21/2
+ },
+ {
+ .name = "100 (PR100)",
+ .cpu_type = CPU_K5,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 3520,
+ .edx_reset = 0x501,
+ .cpuid_model = 0x501,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K5 (Model 1/2/3)",
+ .internal_name = "k5_5k86",
+ .cpus = (const CPU[]) {
+ {
+ .name = "90 (PR120)",
+ .cpu_type = CPU_5K86,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x511,
+ .cpuid_model = 0x511,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "100 (PR133)",
+ .cpu_type = CPU_5K86,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x514,
+ .cpuid_model = 0x514,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "105 (PR150)",
+ .cpu_type = CPU_5K86,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x524,
+ .cpuid_model = 0x524,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "116.7 (PR166)",
+ .cpu_type = CPU_5K86,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3520,
+ .edx_reset = 0x524,
+ .cpuid_model = 0x524,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "133 (PR200)",
+ .cpu_type = CPU_5K86,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3520,
+ .edx_reset = 0x534,
+ .cpuid_model = 0x534,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { .name = "", 0 }
+ }
+ },
+#endif /* USE_AMD_K5 */
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6 (Model 6)",
+ .internal_name = "k6_m6",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2900,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2900,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2900,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2900,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2900,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 3200,
+ .edx_reset = 0x561,
+ .cpuid_model = 0x561,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { .name = "", 0 }
+ }
}, {
- .package = CPU_PKG_SLOT1,
- .manufacturer = "Intel",
- .name = "Celeron (Covington)",
- .internal_name = "celeron_covington",
- .cpus = (const CPU[]) {
- {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 6, 6, 8}, /* out of spec */
- {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 9, 9, 12}, /* out of spec */
- {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,12,12, 16}, /* out of spec */
- {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,15,15, 20}, /* out of spec */
- {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,18,18, 24}, /* out of spec */
- {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,21,21, 28}, /* out of spec */
- {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 2050, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,24,24, 32},
- {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,25,25, 36},
- {"", 0}
- }
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6 (Model 7)",
+ .internal_name = "k6_m7",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2200,
+ .edx_reset = 0x570,
+ .cpuid_model = 0x570,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2200,
+ .edx_reset = 0x570,
+ .cpuid_model = 0x570,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 166666666, .multi = 2.5,
+ .voltage = 2200, .edx_reset = 0x570,
+ .cpuid_model = 0x570, .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 200000000, .multi = 3.0,
+ .voltage = 2200, .edx_reset = 0x570,
+ .cpuid_model = 0x570, .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 233333333, .multi = 3.5,
+ .voltage = 2200, .edx_reset = 0x570,
+ .cpuid_model = 0x570,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x570,
+ .cpuid_model = 0x570,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_K6,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2200,
+ .edx_reset = 0x570,
+ .cpuid_model = 0x570,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 36
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6-2",
+ .internal_name = "k6_2",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ {
+ .name = "333",
+ .cpu_type = CPU_K6_2,
+ .fpus = fpus_internal,
+ .rspeed = 332500000,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x580,
+ .cpuid_model = 0x580,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 30,
+ .mem_write_cycles = 30,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 40
+ },
+ {
+ .name = "350",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 42
+ },
+ {
+ .name = "366",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 44
+ },
+ {
+ .name = "380",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 380000000,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 34,
+ .mem_write_cycles = 34,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 46
+ },
+ {
+ .name = "400/66",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 6.0,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "400/100",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ {
+ .name = "475",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 475000000,
+ .multi = 5.0,
+ .voltage = 2400,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 43,
+ .mem_write_cycles = 43,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 57
+ },
+ {
+ .name = "500",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 500000000,
+ .multi = 5.0,
+ .voltage = 2400,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 45,
+ .mem_write_cycles = 45,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 60
+ },
+ {
+ .name = "533",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 533333333,
+ .multi = 5.5,
+ .voltage = 2200,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 48,
+ .mem_write_cycles = 48,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 64
+ },
+ {
+ .name = "550",
+ .cpu_type = CPU_K6_2C,
+ .fpus = fpus_internal,
+ .rspeed = 550000000,
+ .multi = 5.5,
+ .voltage = 2300,
+ .edx_reset = 0x58c,
+ .cpuid_model = 0x58c,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 50,
+ .mem_write_cycles = 50,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 66
+ },
+ { .name = "", 0 }
+ }
}, {
- .package = CPU_PKG_SLOT2,
- .manufacturer = "Intel",
- .name = "Pentium II Xeon",
- .internal_name = "pentium2_xeon",
- .cpus = (const CPU[]) {
- {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 12}, /* out of spec */
- {"150", CPU_PENTIUM2D, fpus_internal, 150000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 14,14, 4, 4, 18}, /* out of spec */
- {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 6, 6, 24}, /* out of spec */
- {"250", CPU_PENTIUM2D, fpus_internal, 250000000, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 22,22, 7, 7, 30}, /* out of spec */
- {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 3.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, /* out of spec */
- {"350", CPU_PENTIUM2D, fpus_internal, 350000000, 3.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,10,10, 42}, /* out of spec */
- {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48},
- {"450", CPU_PENTIUM2D, fpus_internal, 450000000, 4.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54},
- {"", 0}
- }
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6-2+",
+ .internal_name = "k6_2p",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { /* out of spec */
+ .name = "266",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ { /* out of spec */
+ .name = "300",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ { /* out of spec */
+ .name = "333",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 332500000,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 30,
+ .mem_write_cycles = 30,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 40
+ },
+ { /* out of spec */
+ .name = "350",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 42
+ },
+ { /* out of spec */
+ .name = "366",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 44
+ },
+ { /* out of spec */
+ .name = "380",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 380000000,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 34,
+ .mem_write_cycles = 34,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 46
+ },
+ { /* out of spec */
+ .name = "400/66",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 6.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ { /* out of spec */
+ .name = "400/100",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ {
+ .name = "475",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 475000000,
+ .multi = 5.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 43,
+ .mem_write_cycles = 43,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 57
+ },
+ {
+ .name = "500",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 500000000,
+ .multi = 5.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 45,
+ .mem_write_cycles = 45,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 60
+ },
+ {
+ .name = "533",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 533333333,
+ .multi = 5.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 48,
+ .mem_write_cycles = 48,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 64
+ },
+ {
+ .name = "550",
+ .cpu_type = CPU_K6_2P,
+ .fpus = fpus_internal,
+ .rspeed = 550000000,
+ .multi = 5.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d4,
+ .cpuid_model = 0x5d4,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 50,
+ .mem_write_cycles = 50,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 66
+ },
+ { .name = "", 0 }
+ }
}, {
- .package = CPU_PKG_SOCKET370,
- .manufacturer = "Intel",
- .name = "Celeron (Mendocino)",
- .internal_name = "celeron_mendocino",
- .cpus = (const CPU[]) {
- {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of spec */
- {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 8, 8, 4, 4, 12}, /* out of spec */
- {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 11,11, 5, 5, 16}, /* out of spec */
- {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 14,14, 7, 7, 20}, /* out of spec */
- {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 17,17, 8, 8, 24}, /* out of spec */
- {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 19,19, 9, 9, 28}, /* out of spec */
- {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 22,22,11,11, 32}, /* out of spec */
- {"300A", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 25,25,12,12, 36},
- {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 40},
- {"366", CPU_PENTIUM2D, fpus_internal, 366666666, 5.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 33,33,17,17, 44},
- {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 6.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 36,36,12,12, 48},
- {"433", CPU_PENTIUM2D, fpus_internal, 433333333, 6.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 39,39,13,13, 51},
- {"466", CPU_PENTIUM2D, fpus_internal, 466666666, 7.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 42,42,14,14, 56},
- {"500", CPU_PENTIUM2D, fpus_internal, 500000000, 7.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 45,45,15,15, 60},
- {"533", CPU_PENTIUM2D, fpus_internal, 533333333, 8.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 48,48,17,17, 64},
- {"", 0}
- }
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6-III",
+ .internal_name = "k6_3",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { /* out of spec */
+ .name = "266",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ { /* out of spec */
+ .name = "300",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ { /* out of spec */
+ .name = "333",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 332500000,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 30,
+ .mem_write_cycles = 30,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 40
+ },
+ { /* out of spec */
+ .name = "350",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 42
+ },
+ { /* out of spec */
+ .name = "366",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 44
+ },
+ { /* out of spec */
+ .name = "380",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 380000000,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 34,
+ .mem_write_cycles = 34,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 46
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_K6_3,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2200,
+ .edx_reset = 0x591,
+ .cpuid_model = 0x591,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "AMD",
+ .name = "K6-III+",
+ .internal_name = "k6_3p",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 7,
+ .mem_write_cycles = 7,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 9
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { /* out of spec */
+ .name = "266",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ { /* out of spec */
+ .name = "300",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ { /* out of spec */
+ .name = "333",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 332500000,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 30,
+ .mem_write_cycles = 30,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 40
+ },
+ { /* out of spec */
+ .name = "350",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 42
+ },
+ { /* out of spec */
+ .name = "366",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 44
+ },
+ { /* out of spec */
+ .name = "380",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 380000000,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 34,
+ .mem_write_cycles = 34,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 46
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ {
+ .name = "475",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 475000000,
+ .multi = 5.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 43,
+ .mem_write_cycles = 43,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 57
+ },
+ {
+ .name = "500",
+ .cpu_type = CPU_K6_3P,
+ .fpus = fpus_internal,
+ .rspeed = 500000000,
+ .multi = 5.0,
+ .voltage = 2000,
+ .edx_reset = 0x5d0,
+ .cpuid_model = 0x5d0,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 45,
+ .mem_write_cycles = 45,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 60
+ },
+ { .name = "", 0 }
+ }
+ },
+#ifdef USE_CYRIX_6X86
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Cyrix",
+ .name = "Cx6x86",
+ .internal_name = "cx6x86",
+ .cpus = (const CPU[]) {
+ {
+ .name = "80 (PR90+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 80000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 10
+ },
+ {
+ .name = "100 (PR120+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 10,
+ .mem_write_cycles = 10,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 12
+ },
+ {
+ .name = "110 (PR133+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 110000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 10,
+ .mem_write_cycles = 10,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "120 (PR150+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133 (PR166+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "150 (PR200+)",
+ .cpu_type = CPU_Cx6x86,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.0,
+ .voltage = 3520,
+ .edx_reset = 0x520,
+ .cpuid_model = 0x520,
+ .cyrix_id = 0x1731,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 18
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Cyrix",
+ .name = "Cx6x86L",
+ .internal_name = "cx6x86l",
+ .cpus = (const CPU[]) {
+ {
+ .name = "110 (PR133+)",
+ .cpu_type = CPU_Cx6x86L,
+ .fpus = fpus_internal,
+ .rspeed = 110000000,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0x2231,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 10,
+ .mem_write_cycles = 10,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "120 (PR150+)",
+ .cpu_type = CPU_Cx6x86L,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0x2231,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 14
+ },
+ {
+ .name = "133 (PR166+)",
+ .cpu_type = CPU_Cx6x86L,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0x2231,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "150 (PR200+)",
+ .cpu_type = CPU_Cx6x86L,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x540,
+ .cpuid_model = 0x540,
+ .cyrix_id = 0x2231,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 18
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Cyrix",
+ .name = "Cx6x86MX",
+ .internal_name = "cx6x86mx",
+ .cpus = (const CPU[]) {
+ {
+ .name = "133 (PR166)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2900,
+ .edx_reset = 0x600,
+ .cpuid_model = 0x600,
+ .cyrix_id = 0x0451,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ {
+ .name = "166 (PR200)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2900,
+ .edx_reset = 0x600,
+ .cpuid_model = 0x600,
+ .cyrix_id = 0x0452,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "187.5 (PR233)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 187500000,
+ .multi = 2.5,
+ .voltage = 2900,
+ .edx_reset = 0x600,
+ .cpuid_model = 0x600,
+ .cyrix_id = 0x0452,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 45/2
+ },
+ {
+ .name = "208.3 (PR266)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 208333333,
+ .multi = 2.5,
+ .voltage = 2700,
+ .edx_reset = 0x600,
+ .cpuid_model = 0x600,
+ .cyrix_id = 0x0452,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 17,
+ .mem_write_cycles = 17,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 25
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET5_7,
+ .manufacturer = "Cyrix",
+ .name = "MII",
+ .internal_name = "mii",
+ .cpus = (const CPU[]) {
+ {
+ .name = "233 (PR300)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2900,
+ .edx_reset = 0x601,
+ .cpuid_model = 0x601,
+ .cyrix_id = 0x0852,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 28
+ },
+ {
+ .name = "250/83 (PR333)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 250000000,
+ .multi = 3.0,
+ .voltage = 2900,
+ .edx_reset = 0x601,
+ .cpuid_model = 0x601,
+ .cyrix_id = 0x0853,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 23,
+ .mem_write_cycles = 23,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 30
+ },
+ {
+ .name = "250/100 (PR366)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 250000000,
+ .multi = 2.5,
+ .voltage = 2900,
+ .edx_reset = 0x601,
+ .cpuid_model = 0x601,
+ .cyrix_id = 0x0853,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 23,
+ .mem_write_cycles = 23,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 30
+ },
+ {
+ .name = "285 (PR400)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 285000000,
+ .multi = 3.0,
+ .voltage = 2900,
+ .edx_reset = 0x601,
+ .cpuid_model = 0x601,
+ .cyrix_id = 0x0853,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 34
+ },
+ {
+ .name = "300 (PR433)",
+ .cpu_type = CPU_Cx6x86MX,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2900,
+ .edx_reset = 0x601,
+ .cpuid_model = 0x601,
+ .cyrix_id = 0x0853,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ { .name = "", 0 }
+ }
+ },
+#endif /* USE_CYRIX_6X86 */
+ {
+ .package = CPU_PKG_SOCKET8,
+ .manufacturer = "Intel",
+ .name = "Pentium Pro",
+ .internal_name = "pentiumpro",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "60",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 60000000,
+ .multi = 1.0,
+ .voltage = 3100,
+ .edx_reset = 0x612,
+ .cpuid_model = 0x612,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 1,
+ .cache_write_cycles = 1,
+ .atclk_div = 7
+ },
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 1,
+ .cache_write_cycles = 1,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "90",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 90000000,
+ .multi = 1.5,
+ .voltage = 3100,
+ .edx_reset = 0x612,
+ .cpuid_model = 0x612,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 11
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "120",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 120000000,
+ .multi = 2.0,
+ .voltage = 3100,
+ .edx_reset = 0x612,
+ .cpuid_model = 0x612,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 5,
+ .cache_write_cycles = 5,
+ .atclk_div = 14
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 5,
+ .cache_write_cycles = 5,
+ .atclk_div = 16
+ }, /* out of spec */
+ {
+ .name = "150",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 2.5,
+ .voltage = 3100,
+ .edx_reset = 0x612,
+ .cpuid_model = 0x612,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 35/2
+ },
+ {
+ .name = "166",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ {
+ .name = "180",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 180000000,
+ .multi = 3.0,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 21
+ },
+ {
+ .name = "200",
+ .cpu_type = CPU_PENTIUMPRO,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3300,
+ .edx_reset = 0x617,
+ .cpuid_model = 0x617,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET8,
+ .manufacturer = "Intel",
+ .name = "Pentium II OverDrive",
+ .internal_name = "pentium2_od",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ { /* out of spec */
+ .name = "266",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 5.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 36
+ },
+ {
+ .name = "333",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 333333333,
+ .multi = 5.0,
+ .voltage = 3300,
+ .edx_reset = 0x1632,
+ .cpuid_model = 0x1632,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 40
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SLOT1,
+ .manufacturer = "Intel",
+ .name = "Pentium II (Klamath)",
+ .internal_name = "pentium2_klamath",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ {
+ .name = "233",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_PENTIUM2,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2800,
+ .edx_reset = 0x634,
+ .cpuid_model = 0x634,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 25,
+ .mem_write_cycles = 25,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 36
+ },
+ { .name = "", 0 }
+ }
}, {
- .package = CPU_PKG_SOCKET370,
- .manufacturer = "VIA",
- .name = "Cyrix III",
- .internal_name = "c3_samuel",
- .cpus = (const CPU[]) {
- {"66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of multiplier range */
- {"100", CPU_CYRIX3S, fpus_internal, 100000000, 1.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 9, 9, 4, 4, 12}, /* out of multiplier range */
- {"133", CPU_CYRIX3S, fpus_internal, 133333333, 2.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 12, 12, 6, 6, 16}, /* out of multiplier range */
- {"166", CPU_CYRIX3S, fpus_internal, 166666666, 2.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 15, 15, 7, 7, 20}, /* out of multiplier range */
- {"200", CPU_CYRIX3S, fpus_internal, 200000000, 3.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 18, 18, 8, 8, 24}, /* out of multiplier range */
- {"233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 21, 21, 9, 9, 28}, /* out of multiplier range */
- {"266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 24, 24, 12, 12, 32}, /* out of multiplier range */
- {"300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 27, 27, 13, 13, 36}, /* out of spec */
- {"333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 30, 30, 15, 15, 40}, /* out of spec */
- {"366", CPU_CYRIX3S, fpus_internal, 366666666, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 33, 33, 16, 16, 44}, /* out of spec */
- {"400", CPU_CYRIX3S, fpus_internal, 400000000, 6.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 36, 36, 17, 17, 48},
- {"433", CPU_CYRIX3S, fpus_internal, 433333333, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 39, 39, 18, 18, 52}, /* out of spec */
- {"450", CPU_CYRIX3S, fpus_internal, 450000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 41, 41, 14, 14, 54},
- {"466", CPU_CYRIX3S, fpus_internal, 466666666, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 42, 42, 14, 14, 56}, /* out of spec */
- {"500", CPU_CYRIX3S, fpus_internal, 500000000, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 45, 45, 15, 15, 60},
- {"533", CPU_CYRIX3S, fpus_internal, 533333333, 8.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 48, 48, 15, 15, 64}, /* out of spec */
- {"550", CPU_CYRIX3S, fpus_internal, 550000000, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 50, 50, 17, 17, 66},
- {"600/100", CPU_CYRIX3S, fpus_internal, 600000000, 6.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 18, 18, 72},
- {"600/133", CPU_CYRIX3S, fpus_internal, 600000000, 4.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 13, 13, 72},
- {"650", CPU_CYRIX3S, fpus_internal, 650000000, 6.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 58, 58, 20, 20, 78},
- {"667", CPU_CYRIX3S, fpus_internal, 666666667, 5.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 60, 60, 16, 16, 80},
- {"700", CPU_CYRIX3S, fpus_internal, 700000000, 7.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 63, 63, 21, 21, 84},
- {"733", CPU_CYRIX3S, fpus_internal, 733333333, 5.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 66, 66, 18, 18, 88},
- {"", 0}
- }
+ .package = CPU_PKG_SLOT1,
+ .manufacturer = "Intel",
+ .name = "Pentium II (Deschutes)",
+ .internal_name = "pentium2_deschutes",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 5,
+ .cache_write_cycles = 5,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x651,
+ .cpuid_model = 0x651,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 25,
+ .mem_write_cycles = 25,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 36
+ },
+ {
+ .name = "333",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 333333333,
+ .multi = 5.0,
+ .voltage = 2050,
+ .edx_reset = 0x651,
+ .cpuid_model = 0x651,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 40
+ },
+ {
+ .name = "350",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x651,
+ .cpuid_model = 0x651,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 42
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SLOT1,
+ .manufacturer = "Intel",
+ .name = "Celeron (Covington)",
+ .internal_name = "celeron_covington",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 18,
+ .cache_write_cycles = 18,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 21,
+ .cache_write_cycles = 21,
+ .atclk_div = 28
+ },
+ {
+ .name = "266",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x650,
+ .cpuid_model = 0x650,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 24,
+ .cache_write_cycles = 24,
+ .atclk_div = 32
+ },
+ {
+ .name = "300",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x651,
+ .cpuid_model = 0x651,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 25,
+ .mem_write_cycles = 25,
+ .cache_read_cycles = 25,
+ .cache_write_cycles = 25,
+ .atclk_div = 36
+ },
+ { .name = "", 0 }
+ }
}, {
- .package = 0,
- }
+ .package = CPU_PKG_SLOT2,
+ .manufacturer = "Intel",
+ .name = "Pentium II Xeon",
+ .internal_name = "pentium2_xeon",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "150",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 150000000,
+ .multi = 1.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 18
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 2.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "250",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 250000000,
+ .multi = 2.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 22,
+ .mem_write_cycles = 22,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 30
+ },
+ { /* out of spec */
+ .name = "300",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 3.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 36
+ },
+ { /* out of spec */
+ .name = "350",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 350000000,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 32,
+ .mem_write_cycles = 32,
+ .cache_read_cycles = 10,
+ .cache_write_cycles = 10,
+ .atclk_div = 42
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x652,
+ .cpuid_model = 0x652,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET370,
+ .manufacturer = "Intel",
+ .name = "Celeron (Mendocino)",
+ .internal_name = "celeron_mendocino",
+ .cpus = (const CPU[]) {
+ { /* out of spec */
+ .name = "66",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of spec */
+ .name = "100",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 8,
+ .mem_write_cycles = 8,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of spec */
+ .name = "133",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 11,
+ .mem_write_cycles = 11,
+ .cache_read_cycles = 5,
+ .cache_write_cycles = 5,
+ .atclk_div = 16
+ },
+ { /* out of spec */
+ .name = "166",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 14,
+ .mem_write_cycles = 14,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of spec */
+ .name = "200",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 17,
+ .mem_write_cycles = 17,
+ .cache_read_cycles = 8,
+ .cache_write_cycles = 8,
+ .atclk_div = 24
+ },
+ { /* out of spec */
+ .name = "233",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 19,
+ .mem_write_cycles = 19,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 28
+ },
+ { /* out of spec */
+ .name = "266",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 22,
+ .mem_write_cycles = 22,
+ .cache_read_cycles = 11,
+ .cache_write_cycles = 11,
+ .atclk_div = 32
+ },
+ {
+ .name = "300A",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 25,
+ .mem_write_cycles = 25,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 36
+ },
+ {
+ .name = "333",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 333333333,
+ .multi = 5.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 40
+ },
+ {
+ .name = "366",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 44
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 6.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 48
+ },
+ {
+ .name = "433",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 433333333,
+ .multi = 6.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 39,
+ .mem_write_cycles = 39,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 51
+ },
+ {
+ .name = "466",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 466666666,
+ .multi = 7.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 42,
+ .mem_write_cycles = 42,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 56
+ },
+ {
+ .name = "500",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 500000000,
+ .multi = 7.5,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 45,
+ .mem_write_cycles = 45,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 60
+ },
+ {
+ .name = "533",
+ .cpu_type = CPU_PENTIUM2D,
+ .fpus = fpus_internal,
+ .rspeed = 533333333,
+ .multi = 8.0,
+ .voltage = 2050,
+ .edx_reset = 0x665,
+ .cpuid_model = 0x665,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 48,
+ .mem_write_cycles = 48,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 64
+ },
+ { .name = "", 0 }
+ }
+ },
+ {
+ .package = CPU_PKG_SOCKET370,
+ .manufacturer = "VIA",
+ .name = "Cyrix III",
+ .internal_name = "c3_samuel",
+ .cpus = (const CPU[]) {
+ { /* out of multiplier range */
+ .name = "66",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 66666666,
+ .multi = 1.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 6,
+ .mem_write_cycles = 6,
+ .cache_read_cycles = 3,
+ .cache_write_cycles = 3,
+ .atclk_div = 8
+ },
+ { /* out of multiplier range */
+ .name = "100",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 100000000,
+ .multi = 1.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 9,
+ .mem_write_cycles = 9,
+ .cache_read_cycles = 4,
+ .cache_write_cycles = 4,
+ .atclk_div = 12
+ },
+ { /* out of multiplier range */
+ .name = "133",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 133333333,
+ .multi = 2.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 12,
+ .mem_write_cycles = 12,
+ .cache_read_cycles = 6,
+ .cache_write_cycles = 6,
+ .atclk_div = 16
+ },
+ { /* out of multiplier range */
+ .name = "166",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 166666666,
+ .multi = 2.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 15,
+ .mem_write_cycles = 15,
+ .cache_read_cycles = 7,
+ .cache_write_cycles = 7,
+ .atclk_div = 20
+ },
+ { /* out of multiplier range */
+ .name = "200",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 200000000,
+ .multi = 3.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 18,
+ .mem_write_cycles = 18,
+ .cache_read_cycles = 8,
+ .cache_write_cycles = 8,
+ .atclk_div = 24
+ },
+ { /* out of multiplier range */
+ .name = "233",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 233333333,
+ .multi = 3.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 21,
+ .mem_write_cycles = 21,
+ .cache_read_cycles = 9,
+ .cache_write_cycles = 9,
+ .atclk_div = 28
+ },
+ { /* out of multiplier range */
+ .name = "266",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 266666666,
+ .multi = 4.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 24,
+ .mem_write_cycles = 24,
+ .cache_read_cycles = 12,
+ .cache_write_cycles = 12,
+ .atclk_div = 32
+ },
+ { /* out of spec */
+ .name = "300",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 300000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 27,
+ .mem_write_cycles = 27,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 36
+ },
+ { /* out of spec */
+ .name = "333",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 333333333,
+ .multi = 5.0,
+ .voltage = 2050,
+ .edx_reset = 0x662,
+ .cpuid_model = 0x662,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 30,
+ .mem_write_cycles = 30,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 40
+ },
+ { /* out of spec */
+ .name = "366",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 366666666,
+ .multi = 5.5,
+ .voltage = 2050,
+ .edx_reset = 0x662,
+ .cpuid_model = 0x662,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 33,
+ .mem_write_cycles = 33,
+ .cache_read_cycles = 16,
+ .cache_write_cycles = 16,
+ .atclk_div = 44
+ },
+ {
+ .name = "400",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 400000000,
+ .multi = 6.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 36,
+ .mem_write_cycles = 36,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 48
+ },
+ { /* out of spec */
+ .name = "433",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 433333333,
+ .multi = 6.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 39,
+ .mem_write_cycles = 39,
+ .cache_read_cycles = 18,
+ .cache_write_cycles = 18,
+ .atclk_div = 52
+ },
+ {
+ .name = "450",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 450000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 41,
+ .mem_write_cycles = 41,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 54
+ },
+ { /* out of spec */
+ .name = "466",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 466666666,
+ .multi = 6.5,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 42,
+ .mem_write_cycles = 42,
+ .cache_read_cycles = 14,
+ .cache_write_cycles = 14,
+ .atclk_div = 56
+ },
+ {
+ .name = "500",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 500000000,
+ .multi = 5.0,
+ .voltage = 2050,
+ .edx_reset = 0x662,
+ .cpuid_model = 0x662,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 45,
+ .mem_write_cycles = 45,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 60
+ },
+ { /* out of spec */
+ .name = "533",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 533333333,
+ .multi = 8.0,
+ .voltage = 2050,
+ .edx_reset = 0x660,
+ .cpuid_model = 0x660,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 48,
+ .mem_write_cycles = 48,
+ .cache_read_cycles = 15,
+ .cache_write_cycles = 15,
+ .atclk_div = 64
+ },
+ {
+ .name = "550",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 550000000,
+ .multi = 5.5,
+ .voltage = 2050,
+ .edx_reset = 0x662,
+ .cpuid_model = 0x662,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 50,
+ .mem_write_cycles = 50,
+ .cache_read_cycles = 17,
+ .cache_write_cycles = 17,
+ .atclk_div = 66
+ },
+ {
+ .name = "600/100",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 600000000,
+ .multi = 6.0,
+ .voltage = 2050,
+ .edx_reset = 0x662,
+ .cpuid_model = 0x662,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 54,
+ .mem_write_cycles = 54,
+ .cache_read_cycles = 18,
+ .cache_write_cycles = 18,
+ .atclk_div = 72
+ },
+ {
+ .name = "600/133",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 600000000,
+ .multi = 4.5,
+ .voltage = 2050,
+ .edx_reset = 0x663,
+ .cpuid_model = 0x663,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 54,
+ .mem_write_cycles = 54,
+ .cache_read_cycles = 13,
+ .cache_write_cycles = 13,
+ .atclk_div = 72
+ },
+ {
+ .name = "650",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 650000000,
+ .multi = 6.5,
+ .voltage = 2050,
+ .edx_reset = 0x663,
+ .cpuid_model = 0x663,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 58,
+ .mem_write_cycles = 58,
+ .cache_read_cycles = 20,
+ .cache_write_cycles = 20,
+ .atclk_div = 78
+ },
+ {
+ .name = "667",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 666666667,
+ .multi = 5.0,
+ .voltage = 2050,
+ .edx_reset = 0x663,
+ .cpuid_model = 0x663,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 60,
+ .mem_write_cycles = 60,
+ .cache_read_cycles = 16,
+ .cache_write_cycles = 16,
+ .atclk_div = 80
+ },
+ {
+ .name = "700",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 700000000,
+ .multi = 7.0,
+ .voltage = 2050,
+ .edx_reset = 0x663,
+ .cpuid_model = 0x663,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 63,
+ .mem_write_cycles = 63,
+ .cache_read_cycles = 21,
+ .cache_write_cycles = 21,
+ .atclk_div = 84
+ },
+ {
+ .name = "733",
+ .cpu_type = CPU_CYRIX3S,
+ .fpus = fpus_internal,
+ .rspeed = 733333333,
+ .multi = 5.5,
+ .voltage = 2050,
+ .edx_reset = 0x663,
+ .cpuid_model = 0x663,
+ .cyrix_id = 0,
+ .cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER,
+ .mem_read_cycles = 66,
+ .mem_write_cycles = 66,
+ .cache_read_cycles = 18,
+ .cache_write_cycles = 18,
+ .atclk_div = 88
+ },
+ { .name = "", 0 }
+ }
+ },
+ { .package = 0, 0 }
// clang-format on
};
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..9f9ae06792
--- /dev/null
+++ b/src/cpu/softfloat3e/CMakeLists.txt
@@ -0,0 +1,57 @@
+#
+# 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 primitives.c softfloat-specialize.c
+ 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.c b/src/cpu/softfloat3e/primitives.c
new file mode 100644
index 0000000000..ba5afb76af
--- /dev/null
+++ b/src/cpu/softfloat3e/primitives.c
@@ -0,0 +1,50 @@
+/*============================================================================
+
+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.
+
+=============================================================================*/
+
+#include "primitives.h"
+
+/*----------------------------------------------------------------------------
+| 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;
+}
diff --git a/src/cpu/softfloat3e/primitives.h b/src/cpu/softfloat3e/primitives.h
new file mode 100644
index 0000000000..3c811838e7
--- /dev/null
+++ b/src/cpu/softfloat3e/primitives.h
@@ -0,0 +1,527 @@
+/*============================================================================
+
+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.
+*----------------------------------------------------------------------------*/
+extern struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist);
+
+/*----------------------------------------------------------------------------
+| 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