summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2024-05-27 20:40:42 -0400
committer arbee <rb6502@users.noreply.github.com>2024-05-27 20:40:42 -0400
commit6957c469983fe32c9725eb3787020b6cedd36b75 (patch)
tree7b12ba5d3d6b2a08ec63ae9c72badad521339beb /3rdparty
parentcd25f2de50864c2897ca7f5aa604696c87a49807 (diff)
cpu/m68000: Updated 680x0 FPU to Softfloat 3 from 2. (MT5411 and MT8793). [R. Belmont]
- Update to Softloat 3 from 2 - FREM and FMOD now generate the quotient bits in FPSR, required by Apple's SANE to do sin/cos/tan properly. - FMOVE of a float to a Dx integer register generates the exception status bits, fixing square roots in SANE - Rewrote how FMOVEM instructions are decoded and executed, fixing issues including skipping too few or too many opcode bytes and causing serious weird behavior. - FPU instructions all now have more realistic cycle timings for a 68881. - All FPU instructions now generate exception bits in FPSR. 3rdparty/softfloat3: Updates [R. Belmont] - Softfloat3 was always being built for a big-endian host, causing incorrect math on LE x64 and AArch64 machines. - Fixed up Softfloat3 to build properly as part of MAME and up-ported the Bochs extensions. In latest Bochs, they were only partially up-ported and Softfloat3 had been hacked up to be more like 2; here they're fixed to work with stock Softfloat3.
Diffstat (limited to '3rdparty')
-rw-r--r--3rdparty/softfloat3/bochs_ext/extF80_scale.c156
-rw-r--r--3rdparty/softfloat3/bochs_ext/f2xm1.c186
-rw-r--r--3rdparty/softfloat3/bochs_ext/fpatan.c326
-rw-r--r--3rdparty/softfloat3/bochs_ext/fprem.c255
-rw-r--r--3rdparty/softfloat3/bochs_ext/fpu_constant.h80
-rw-r--r--3rdparty/softfloat3/bochs_ext/fsincos.c457
-rw-r--r--3rdparty/softfloat3/bochs_ext/fyl2x.c409
-rw-r--r--3rdparty/softfloat3/bochs_ext/poly.c91
-rw-r--r--3rdparty/softfloat3/bochs_ext/softfloat-extra.h68
-rw-r--r--3rdparty/softfloat3/bochs_ext/softfloat-helpers.h159
-rw-r--r--3rdparty/softfloat3/bochs_ext/softfloat-specialize.h223
-rw-r--r--3rdparty/softfloat3/bochs_ext/softfloat3_ext.h17
-rw-r--r--3rdparty/softfloat3/build/MAME/platform.h10
-rw-r--r--3rdparty/softfloat3/source/include/softfloat.h46
-rw-r--r--3rdparty/softfloat3/source/include/softfloat_types.h7
15 files changed, 2468 insertions, 22 deletions
diff --git a/3rdparty/softfloat3/bochs_ext/extF80_scale.c b/3rdparty/softfloat3/bochs_ext/extF80_scale.c
new file mode 100644
index 00000000000..6a25764f128
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/extF80_scale.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 <stdbool.h>
+#include <stdint.h>
+
+#include "../source/include/softfloat.h"
+#include "../source/include/internals.h"
+#include "../source/8086/specialize.h"
+
+#include "fpu_constant.h"
+#include "softfloat-helpers.h"
+#include "softfloat-extra.h"
+#include "softfloat-specialize.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 extFloat80_scale(extFloat80_t a, extFloat80_t b)
+{
+ 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_exceptionFlags |= softfloat_flag_invalid;
+ return packToExtF80(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))) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if ((expB == 0x7FFF) && signB) goto invalid;
+ if (sigB && !expB)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actally denormal
+
+ return a;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB<<1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if ((expA | sigA) == 0) {
+ if (! signB) goto invalid;
+ return a;
+ }
+ if (sigA && !expA)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+
+ if (signB) return packToExtF80(signA, 0, 0);
+ return packToExtF80(signA, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ if (! expA) {
+ if (sigB && !expB)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ if (! sigA) return a;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ if (expB < 0x3FFF)
+ return softfloat_normRoundPackToExtF80(signA, expA, sigA, 0, 80);
+ }
+ if (!expB) {
+ if (!sigB) return a;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually 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);
+ }
+
+ 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);
+}
diff --git a/3rdparty/softfloat3/bochs_ext/f2xm1.c b/3rdparty/softfloat3/bochs_ext/f2xm1.c
new file mode 100644
index 00000000000..a8201937660
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/f2xm1.c
@@ -0,0 +1,186 @@
+/*============================================================================
+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]
+ * ==========================================================================*/
+
+#define FLOAT128
+
+#include "../source/include/softfloat.h"
+#include "../source/include/internals.h"
+#include "softfloat-extra.h"
+#include "softfloat-helpers.h"
+#include "softfloat-specialize.h"
+
+static const extFloat80_t floatx80_negone = packFloatx80(1, 0x3fff, uint64_t(0x8000000000000000));
+static const extFloat80_t floatx80_neghalf = packFloatx80(1, 0x3ffe, uint64_t(0x8000000000000000));
+static const float128_t float128_ln2 =
+ packFloat128(uint64_t(0x3ffe62e42fefa39e), uint64_t(0xf35793c7673007e6));
+
+#ifdef BETTER_THAN_PENTIUM
+
+#define LN2_SIG_HI uint64_t(0xb17217f7d1cf79ab)
+#define LN2_SIG_LO uint64_t(0xc9e3b39800000000) /* 96 bit precision */
+
+#else
+
+#define LN2_SIG_HI uint64_t(0xb17217f7d1cf79ab)
+#define LN2_SIG_LO uint64_t(0xc000000000000000) /* 67-bit precision */
+
+#endif
+
+#define EXP_ARR_SIZE 15
+
+static float128_t exp_arr[EXP_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
+ PACK_FLOAT_128(0x3ffc555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
+ PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
+ PACK_FLOAT_128(0x3ff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
+ PACK_FLOAT_128(0x3ff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
+ PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
+ PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
+ PACK_FLOAT_128(0x3fe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
+ PACK_FLOAT_128(0x3fe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
+ PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
+ PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
+ PACK_FLOAT_128(0x3fda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
+ PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
+};
+
+extern float128_t EvalPoly(float128_t x, const float128_t *arr, int n);
+
+/* required -1 < x < 1 */
+static float128_t poly_exp(float128_t x)
+{
+/*
+ // 2 3 4 5 6 7 8 9
+ // x x x x x x x x x
+ // e - 1 ~ x + --- + --- + --- + --- + --- + --- + --- + --- + ...
+ // 2! 3! 4! 5! 6! 7! 8! 9!
+ //
+ // 2 3 4 5 6 7 8
+ // x x x x x x x x
+ // = x [ 1 + --- + --- + --- + --- + --- + --- + --- + --- + ... ]
+ // 2! 3! 4! 5! 6! 7! 8! 9!
+ //
+ // 8 8
+ // -- 2k -- 2k+1
+ // p(x) = > C * x q(x) = > C * x
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // x
+ // e - 1 ~ x * [ p(x) + x * q(x) ]
+ //
+*/
+ float128_t t = EvalPoly(x, (const float128_t*) exp_arr, EXP_ARR_SIZE);
+ return f128_mul(t, x);
+}
+
+// =================================================
+// x
+// FX2M1 Compute 2 - 1
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// x x*ln(2)
+// 2 = e
+//
+// 2. ----------------------------------------------------------
+// 2 3 4 5 n
+// x x x x x x x
+// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
+// 1! 2! 3! 4! 5! n!
+//
+extFloat80_t extFloat80_2xm1(extFloat80_t a)
+{
+ uint64_t zSig0, zSig1, zSig2;
+ struct exp32_sig64 normExpSig;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ return floatx80_default_nan;
+ }
+
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
+
+ if (aExp == 0x7FFF) {
+ if (aSig << 1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, 0, 0);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+
+ return (aSign) ? floatx80_negone : a;
+ }
+
+ if (! aExp) {
+ if (! aSig) return a;
+ softfloat_exceptionFlags |= softfloat_flag_inexact; // denormal also
+ 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 < (int64_t) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --aExp;
+ }
+ return softfloat_roundPackToExtF80(aSign, aExp, zSig0, zSig1, 80);
+ }
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ if (aExp < 0x3FFF)
+ {
+ if (aExp < FLOATX80_EXP_BIAS-68)
+ goto tiny_argument;
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ float128_t x = extF80_to_f128(a);
+ x = f128_mul(x, float128_ln2);
+ x = poly_exp(x);
+ return f128_to_extF80(x);
+ }
+ else
+ {
+ if (a.signExp == 0xBFFF && ! (aSig<<1))
+ return floatx80_neghalf;
+
+ return a;
+ }
+}
diff --git a/3rdparty/softfloat3/bochs_ext/fpatan.c b/3rdparty/softfloat3/bochs_ext/fpatan.c
new file mode 100644
index 00000000000..88bced6bbd3
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/fpatan.c
@@ -0,0 +1,326 @@
+/*============================================================================
+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]
+ * ==========================================================================*/
+
+#define FLOAT128
+
+#include "../source/include/softfloat.h"
+#include "../source/include/internals.h"
+#include "../source/8086/specialize.h"
+
+#include "fpu_constant.h"
+#include "softfloat-helpers.h"
+#include "softfloat-extra.h"
+#include "softfloat-specialize.h"
+
+#define FPATAN_ARR_SIZE 11
+
+static const extFloat80_t floatx80_one = packFloatx80(0, 0x3fff, uint64_t(0x8000000000000000));
+
+static const float128_t float128_one =
+ packFloat128(uint64_t(0x3fff000000000000), uint64_t(0x0000000000000000));
+static const float128_t float128_sqrt3 =
+ packFloat128(uint64_t(0x3fffbb67ae8584ca), uint64_t(0xa73b25742d7078b8));
+static const extFloat80_t floatx80_pi =
+ packFloatx80(0, 0x4000, uint64_t(0xc90fdaa22168c235));
+
+static const float128_t float128_pi2 =
+ packFloat128(uint64_t(0x3fff921fb54442d1), uint64_t(0x8469898CC5170416));
+static const float128_t float128_pi4 =
+ packFloat128(uint64_t(0x3ffe921fb54442d1), uint64_t(0x8469898CC5170416));
+static const float128_t float128_pi6 =
+ packFloat128(uint64_t(0x3ffe0c152382d736), uint64_t(0x58465BB32E0F580F));
+
+static float128_t atan_arr[FPATAN_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
+ PACK_FLOAT_128(0xbffc249249249249, 0x2492492492492492), /* 7 */
+ PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
+ PACK_FLOAT_128(0xbffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
+ PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
+ PACK_FLOAT_128(0xbffb111111111111, 0x1111111111111111), /* 15 */
+ PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2), /* 17 */
+ PACK_FLOAT_128(0xbffaaf286bca1af2, 0x86bca1af286bca1b), /* 19 */
+ PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */
+};
+
+extern float128_t OddPoly(float128_t x, const float128_t *arr, int n);
+
+/* |x| < 1/4 */
+static float128_t poly_atan(float128_t x1)
+{
+/*
+ // 3 5 7 9 11 13 15 17
+ // x x x x x x x x
+ // atan(x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- + ----
+ // 3 5 7 9 11 13 15 17
+ //
+ // 2 4 6 8 10 12 14 16
+ // x x x x x x x x
+ // = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- + ---- ]
+ // 3 5 7 9 11 13 15 17
+ //
+ // 5 5
+ // -- 4k -- 4k+2
+ // p(x) = > C * x q(x) = > C * x
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // atan(x) ~ x * [ p(x) + x * q(x) ]
+ //
+*/
+ return OddPoly(x1, (const float128_t*) atan_arr, FPATAN_ARR_SIZE);
+}
+
+// =================================================
+// FPATAN Compute arctan(y/x)
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+//
+// atan(-x) = -atan(x)
+//
+// 2. ----------------------------------------------------------
+//
+// x + y
+// atan(x) + atan(y) = atan -------, xy < 1
+// 1-xy
+//
+// x + y
+// atan(x) + atan(y) = atan ------- + PI, x > 0, xy > 1
+// 1-xy
+//
+// x + y
+// atan(x) + atan(y) = atan ------- - PI, x < 0, xy > 1
+// 1-xy
+//
+// 3. ----------------------------------------------------------
+//
+// atan(x) = atan(INF) + atan(- 1/x)
+//
+// x-1
+// atan(x) = PI/4 + atan( ----- )
+// x+1
+//
+// x * sqrt(3) - 1
+// atan(x) = PI/6 + atan( ----------------- )
+// x + sqrt(3)
+//
+// 4. ----------------------------------------------------------
+// 3 5 7 9 2n+1
+// x x x x n x
+// atan(x) = x - --- + --- - --- + --- - ... + (-1) ------ + ...
+// 3 5 7 9 2n+1
+//
+
+extFloat80_t extFloat80_atan(extFloat80_t a, extFloat80_t b)
+{
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ return floatx80_default_nan;
+ }
+
+ 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)
+ {
+ extFloat80_t rv;
+ if (bSig<<1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (aExp == 0x7FFF) {
+ if (aSig<<1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (aSign) /* return 3PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80);
+ else /* return PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80);
+ }
+
+ if (aSig && ! aExp)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // denormal actually
+
+ /* return PI/2 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80);
+ }
+ if (aExp == 0x7FFF)
+ {
+ if (aSig<<1) {
+ extFloat80_t rv;
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (bSig && ! bExp)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // denormal actually
+
+return_PI_or_ZERO:
+
+ if (aSign) /* return PI */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80);
+ else /* return 0 */
+ return packToExtF80(bSign, 0, 0);
+ }
+ if (! bExp)
+ {
+ if (! bSig) {
+ if (aSig && ! aExp)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // denormal actually
+
+ goto return_PI_or_ZERO;
+ }
+
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // denormal actually
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
+ }
+ if (! aExp)
+ {
+ if (! aSig) /* return PI/2 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80);
+
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // denormal actually
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
+ }
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ /* |a| = |b| ==> return PI/4 */
+ if (aSig == bSig && aExp == bExp) {
+ if (aSign)
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80);
+ else
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80);
+ }
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ float128_t a128 = softfloat_normRoundPackToF128(0, aExp-0x10, aSig, 0);
+ float128_t b128 = softfloat_normRoundPackToF128(0, bExp-0x10, bSig, 0);
+ float128_t x;
+ int swap = 0, add_pi6 = 0, add_pi4 = 0;
+
+ if (aExp > bExp || (aExp == bExp && aSig > bSig))
+ {
+ x = f128_div(b128, a128);
+ }
+ else {
+ x = f128_div(a128, b128);
+ swap = 1;
+ }
+
+ int32_t xExp = expF128UI64(x.v[1]);
+
+ if (xExp <= FLOATX80_EXP_BIAS-40)
+ goto approximation_completed;
+
+ if (x.v[1] >= uint64_t(0x3ffe800000000000)) // 3/4 < x < 1
+ {
+ /*
+ arctan(x) = arctan((x-1)/(x+1)) + pi/4
+ */
+ float128_t t1 = f128_sub(x, float128_one);
+ float128_t t2 = f128_add(x, float128_one);
+ x = f128_div(t1, t2);
+ add_pi4 = 1;
+ }
+ else
+ {
+ /* argument correction */
+ if (xExp >= 0x3FFD) // 1/4 < x < 3/4
+ {
+ /*
+ arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6
+ */
+ float128_t t1 = f128_mul(x, float128_sqrt3);
+ float128_t t2 = f128_add(x, float128_sqrt3);
+ x = f128_sub(t1, float128_one);
+ x = f128_div(x, t2);
+ add_pi6 = 1;
+ }
+ }
+
+ x = poly_atan(x);
+ if (add_pi6) x = f128_add(x, float128_pi6);
+ if (add_pi4) x = f128_add(x, float128_pi4);
+
+approximation_completed:
+ if (swap) x = f128_sub(float128_pi2, x);
+ extFloat80_t result = f128_to_extF80(x);
+ if (zSign) floatx80_chs(result);
+ int rSign = extF80_sign(result);
+ if (!bSign && rSign)
+ return extF80_add(result, floatx80_pi);
+ if (bSign && !rSign)
+ return extF80_sub(result, floatx80_pi);
+ return result;
+}
+
+extFloat80_t packToExtF80(uint16_t signExp, uint64_t sig)
+{
+ extFloat80_t z;
+ z.signExp = signExp;
+ z.signif = sig;
+ return z;
+}
+
+extFloat80_t packToExtF80(bool sign, uint16_t exp, uint64_t sig)
+{
+ extFloat80_t z;
+ z.signExp = packToExtF80UI64(sign, exp);
+ z.signif = sig;
+ return z;
+}
+
+extFloat80_t extFloat80_68katan(extFloat80_t a)
+{
+ return extFloat80_atan(a, floatx80_one);
+}
diff --git a/3rdparty/softfloat3/bochs_ext/fprem.c b/3rdparty/softfloat3/bochs_ext/fprem.c
new file mode 100644
index 00000000000..16f6cccbc49
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/fprem.c
@@ -0,0 +1,255 @@
+/*============================================================================
+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]
+ * ==========================================================================*/
+
+#define USE_estimateDiv128To64
+#define FLOAT128
+
+#include <stdint.h>
+
+#include "../build/MAME/platform.h"
+#include "../source/include/internals.h"
+#include "../source/include/softfloat.h"
+
+#include "../source/8086/specialize.h"
+
+#include "fpu_constant.h"
+#include "softfloat-extra.h"
+#include "softfloat-helpers.h"
+#include "softfloat-specialize.h"
+
+/* executes single exponent reduction cycle */
+static uint64_t remainder_kernel(uint64_t aSig0, uint64_t bSig, int expDiff, uint64_t *zSig0, uint64_t *zSig1)
+{
+ uint128 term, z;
+ uint64_t aSig1 = 0;
+ shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
+ 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;
+ z = softfloat_add128(z.v64, z.v0, 0, bSig);
+ }
+ *zSig0 = z.v0;
+ *zSig1 = z.v64;
+ return q;
+}
+
+static int do_fprem(extFloat80_t a, extFloat80_t b, extFloat80_t &r, uint64_t &q, int rounding_mode)
+{
+ 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 (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ r = floatx80_default_nan;
+ return -1;
+ }
+
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+ bSig = extF80_fraction(b);
+ bExp = extF80_exp(b);
+
+ if (aExp == 0x7FFF) {
+ if ((aSig0<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif);
+ r.signExp = nan.v64;
+ r.signif = nan.v0;
+ return -1;
+ }
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ r = floatx80_default_nan;
+ return -1;
+ }
+ if (bExp == 0x7FFF) {
+ if (bSig << 1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif);
+ r.signExp = nan.v64;
+ r.signif = nan.v0;
+ return -1;
+ }
+ if (! aExp && aSig0) {
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ r = (a.signif & uint64_t(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
+ return 0;
+ }
+ r = a;
+ return 0;
+
+ }
+ if (! bExp) {
+ if (! bSig) {
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ r = floatx80_default_nan;
+ return -1;
+ }
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
+ }
+ if (! aExp) {
+ if (! aSig0) {
+ r = a;
+ return 0;
+ }
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ }
+
+ expDiff = aExp - bExp;
+ int overflow = 0;
+
+ if (expDiff >= 64) {
+ int n = (expDiff & 0x1f) | 0x20;
+ remainder_kernel(aSig0, bSig, n, &aSig0, &aSig1);
+ zExp = aExp - n;
+ overflow = 1;
+ }
+ else {
+ zExp = bExp;
+
+ if (expDiff < 0) {
+ if (expDiff < -1) {
+ r = (a.signif & uint64_t(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
+ return 0;
+ }
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
+ expDiff = 0;
+ }
+
+ if (expDiff > 0) {
+ q = remainder_kernel(aSig0, bSig, expDiff, &aSig0, &aSig1);
+ }
+ else {
+ if (bSig <= aSig0) {
+ aSig0 -= bSig;
+ q = 1;
+ }
+ }
+
+ 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 = softfloat_normRoundPackToExtF80(aSign, zExp, aSig0, aSig1, 80);
+ return overflow;
+}
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. The operation is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int extFloat80_ieee754_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, uint64_t &q)
+{
+ return do_fprem(a, b, r, q, softfloat_round_near_even);
+}
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. Unlike previous function
+| the function does not compute the remainder specified in the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic. This function operates
+| differently from the previous function in the way that it rounds the
+| quotient of 'a' divided by 'b' to an integer.
+*----------------------------------------------------------------------------*/
+
+int extFloat80_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, uint64_t &q)
+{
+ return do_fprem(a, b, r, q, softfloat_round_minMag);
+}
+
+static extFloat80_t propagateFloatx80NaNOneArg(extFloat80_t a)
+{
+ a.signif |= uint64_t(0x4000000000000000);
+ return a;
+}
+
+extFloat80_t extFloat80_getman(extFloat80_t a)
+{
+ const int aSign = (a.signExp >> 15);
+ int32_t aExp = a.signExp & 0x7fff;
+ uint64_t aFrac = a.signif;
+
+ if (aExp == 0x7fff)
+ {
+ if ((uint64_t)(aFrac << 1))
+ {
+ return propagateFloatx80NaNOneArg(a);
+ }
+
+ softfloat_raiseFlags(softfloat_flag_invalid);
+ return floatx80_default_nan;
+ }
+
+ if (!aExp)
+ {
+ if (!aSign)
+ {
+ return packFloatx80(aSign, 0, 0);
+ }
+ else
+ {
+ // normalize the subnormal value
+ const int leadingZeroes = softfloat_countLeadingZeros64(aFrac);
+ aFrac = aFrac << leadingZeroes;
+ aExp = -leadingZeroes;
+ }
+ }
+
+ return packFloatx80(aSign, 0x3fff, aFrac);
+}
diff --git a/3rdparty/softfloat3/bochs_ext/fpu_constant.h b/3rdparty/softfloat3/bochs_ext/fpu_constant.h
new file mode 100644
index 00000000000..827dbdec514
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/fpu_constant.h
@@ -0,0 +1,80 @@
+/*============================================================================
+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.
+=============================================================================*/
+
+#ifndef _FPU_CONSTANTS_H_
+#define _FPU_CONSTANTS_H_
+
+// Pentium CPU uses only 68-bit precision M_PI approximation
+// #define BETTER_THAN_PENTIUM
+
+/*============================================================================
+ * Written for Bochs (x86 achitecture simulator) by
+ * Stanislav Shwartsman [sshwarts at sourceforge net]
+ * ==========================================================================*/
+
+//////////////////////////////
+// PI, PI/2, PI/4 constants
+//////////////////////////////
+
+#define FLOATX80_PI_EXP (0x4000)
+
+// 128-bit PI fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_PI_HI (uint64_t(0xc90fdaa22168c234))
+#define FLOAT_PI_LO (uint64_t(0xc4c6628b80dc1cd1))
+#else
+#define FLOAT_PI_HI (uint64_t(0xc90fdaa22168c234))
+#define FLOAT_PI_LO (uint64_t(0xC000000000000000))
+#endif
+
+#define FLOATX80_PI2_EXP (0x3FFF)
+#define FLOATX80_PI4_EXP (0x3FFE)
+
+//////////////////////////////
+// 3PI/4 constant
+//////////////////////////////
+
+#define FLOATX80_3PI4_EXP (0x4000)
+
+// 128-bit 3PI/4 fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_3PI4_HI (uint64_t(0x96cbe3f9990e91a7))
+#define FLOAT_3PI4_LO (uint64_t(0x9394c9e8a0a5159c))
+#else
+#define FLOAT_3PI4_HI (uint64_t(0x96cbe3f9990e91a7))
+#define FLOAT_3PI4_LO (uint64_t(0x9000000000000000))
+#endif
+
+//////////////////////////////
+// 1/LN2 constant
+//////////////////////////////
+
+#define FLOAT_LN2INV_EXP (0x3FFF)
+
+// 128-bit 1/LN2 fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_LN2INV_HI (uint64_t(0xb8aa3b295c17f0bb))
+#define FLOAT_LN2INV_LO (uint64_t(0xbe87fed0691d3e89))
+#else
+#define FLOAT_LN2INV_HI (uint64_t(0xb8aa3b295c17f0bb))
+#define FLOAT_LN2INV_LO (uint64_t(0xC000000000000000))
+#endif
+
+#endif
diff --git a/3rdparty/softfloat3/bochs_ext/fsincos.c b/3rdparty/softfloat3/bochs_ext/fsincos.c
new file mode 100644
index 00000000000..303d66cc5b8
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/fsincos.c
@@ -0,0 +1,457 @@
+/*============================================================================
+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]
+ * ==========================================================================*/
+
+#define FLOAT128
+
+#define USE_estimateDiv128To64
+#define FLOAT128
+
+#include "../build/MAME/platform.h"
+#include "../source/include/internals.h"
+#include "../source/include/softfloat.h"
+
+#include "../source/8086/specialize.h"
+
+#include "fpu_constant.h"
+#include "softfloat-extra.h"
+#include "softfloat-helpers.h"
+#include "softfloat-specialize.h"
+
+static const extFloat80_t floatx80_one = packFloatx80(0, 0x3fff, uint64_t(0x8000000000000000));
+
+/* reduce trigonometric function argument using 128-bit precision
+ M_PI approximation */
+static uint64_t argument_reduction_kernel(uint64_t aSig0, int Exp, uint64_t *zSig0, uint64_t *zSig1)
+{
+ uint64_t term0, term1, term2;
+ uint64_t aSig1 = 0;
+
+ shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
+ 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 ((int64_t)(*zSig1) < 0) {
+ --q;
+ add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
+ }
+ *zSig1 = term2;
+ return q;
+}
+
+static int reduce_trig_arg(int expDiff, int &zSign, uint64_t &aSig0, uint64_t &aSig1)
+{
+ uint64_t term0, term1, q = 0;
+
+ if (expDiff < 0) {
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
+ expDiff = 0;
+ }
+ if (expDiff > 0) {
+ q = argument_reduction_kernel(aSig0, expDiff, &aSig0, &aSig1);
+ }
+ else {
+ if (FLOAT_PI_HI <= aSig0) {
+ aSig0 -= FLOAT_PI_HI;
+ q = 1;
+ }
+ }
+
+ shortShift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 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) {
+ zSign = !zSign;
+ ++q;
+ }
+ if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, aSig0, aSig1, &aSig0, &aSig1);
+ }
+
+ return (int)(q & 3);
+}
+
+#define SIN_ARR_SIZE 11
+#define COS_ARR_SIZE 11
+
+static float128_t sin_arr[SIN_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
+ PACK_FLOAT_128(0xbff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
+ PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
+ PACK_FLOAT_128(0xbfe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
+ PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
+ PACK_FLOAT_128(0xbfd6ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 15 */
+ PACK_FLOAT_128(0x3fce952c77030ad4, 0xa6b2605197771b00), /* 17 */
+ PACK_FLOAT_128(0xbfc62f49b4681415, 0x724ca1ec3b7b9675), /* 19 */
+ PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */
+};
+
+static float128_t cos_arr[COS_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */
+ PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */
+ PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
+ PACK_FLOAT_128(0xbff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
+ PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
+ PACK_FLOAT_128(0xbfe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
+ PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
+ PACK_FLOAT_128(0xbfda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
+ PACK_FLOAT_128(0x3fd2ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 16 */
+ PACK_FLOAT_128(0xbfca6827863b97d9, 0x77bb004886a2c2ab), /* 18 */
+ PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */
+};
+
+extern float128_t OddPoly (float128_t x, const float128_t *arr, int n);
+
+/* 0 <= x <= pi/4 */
+inline float128_t poly_sin(float128_t x)
+{
+ // 3 5 7 9 11 13 15
+ // x x x x x x x
+ // sin (x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- =
+ // 3! 5! 7! 9! 11! 13! 15!
+ //
+ // 2 4 6 8 10 12 14
+ // x x x x x x x
+ // = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- ] =
+ // 3! 5! 7! 9! 11! 13! 15!
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(x) = > C * x > 0 q(x) = > C * x < 0
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // sin(x) ~ x * [ p(x) + x * q(x) ]
+ //
+
+ return OddPoly(x, (const float128_t*) sin_arr, SIN_ARR_SIZE);
+}
+
+extern float128_t EvenPoly(float128_t x, const float128_t *arr, int n);
+
+/* 0 <= x <= pi/4 */
+inline float128_t poly_cos(float128_t x)
+{
+ // 2 4 6 8 10 12 14
+ // x x x x x x x
+ // cos (x) ~ 1 - --- + --- - --- + --- - ---- + ---- - ----
+ // 2! 4! 6! 8! 10! 12! 14!
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(x) = > C * x > 0 q(x) = > C * x < 0
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // cos(x) ~ [ p(x) + x * q(x) ]
+ //
+
+ return EvenPoly(x, (const float128_t*) cos_arr, COS_ARR_SIZE);
+}
+
+inline void sincos_invalid(extFloat80_t *sin_a, extFloat80_t *cos_a, extFloat80_t a)
+{
+ if (sin_a) *sin_a = a;
+ if (cos_a) *cos_a = a;
+}
+
+inline void sincos_tiny_argument(extFloat80_t *sin_a, extFloat80_t *cos_a, extFloat80_t a)
+{
+ if (sin_a) *sin_a = a;
+ if (cos_a) *cos_a = floatx80_one;
+}
+
+static extFloat80_t sincos_approximation(int neg, float128_t r, uint64_t quotient)
+{
+ if (quotient & 0x1) {
+ r = poly_cos(r);
+ neg = 0;
+ } else {
+ r = poly_sin(r);
+ }
+
+ extFloat80_t result = f128_to_extF80(r);
+ if (quotient & 0x2)
+ neg = ! neg;
+
+ if (neg)
+ floatx80_chs(result);
+
+ return result;
+}
+
+// =================================================
+// FSINCOS Compute sin(x) and cos(x)
+// =================================================
+
+//
+// Uses the following identities:
+// ----------------------------------------------------------
+//
+// sin(-x) = -sin(x)
+// cos(-x) = cos(x)
+//
+// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
+// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
+//
+// sin(x+ pi/2) = cos(x)
+// sin(x+ pi) = -sin(x)
+// sin(x+3pi/2) = -cos(x)
+// sin(x+2pi) = sin(x)
+//
+
+int extFloat80_sincos(extFloat80_t a, extFloat80_t *sin_a, extFloat80_t *cos_a)
+{
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
+ int aSign, zSign;
+ int q = 0;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ goto invalid;
+ }
+
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+
+ /* invalid argument */
+ if (aExp == 0x7FFF) {
+ if (aSig0 << 1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ sincos_invalid(sin_a, cos_a, rv);
+ return 0;
+ }
+
+ invalid:
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ sincos_invalid(sin_a, cos_a, floatx80_default_nan);
+ return 0;
+ }
+
+ if (! aExp) {
+ if (! aSig0) {
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+
+ /* handle pseudo denormals */
+ if (! (aSig0 & uint64_t(0x8000000000000000)))
+ {
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+ if (sin_a)
+ softfloat_exceptionFlags |= softfloat_flag_underflow;
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ }
+
+ zSign = aSign;
+ zExp = FLOATX80_EXP_BIAS;
+ expDiff = aExp - zExp;
+
+ /* argument is out-of-range */
+ if (expDiff >= 63)
+ return -1;
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ if (expDiff < -1) { // doesn't require reduction
+ if (expDiff <= -68) {
+ a = packFloatx80(aSign, aExp, aSig0);
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+ zExp = aExp;
+ }
+ else {
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
+ }
+
+ /* **************************** */
+ /* argument reduction completed */
+ /* **************************** */
+
+ /* using float128 for approximation */
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1);
+
+ if (aSign) q = -q;
+ if (sin_a) *sin_a = sincos_approximation(zSign, r, q);
+ if (cos_a) *cos_a = sincos_approximation(zSign, r, q+1);
+
+ return 0;
+}
+
+int extFloat80_sin(extFloat80_t &a)
+{
+ return extFloat80_sincos(a, &a, 0);
+}
+
+int extFloat80_cos(extFloat80_t &a)
+{
+ return extFloat80_sincos(a, 0, &a);
+}
+
+// =================================================
+// FPTAN Compute tan(x)
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+//
+// sin(-x) = -sin(x)
+// cos(-x) = cos(x)
+//
+// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
+// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
+//
+// sin(x+ pi/2) = cos(x)
+// sin(x+ pi) = -sin(x)
+// sin(x+3pi/2) = -cos(x)
+// sin(x+2pi) = sin(x)
+//
+// 2. ----------------------------------------------------------
+//
+// sin(x)
+// tan(x) = ------
+// cos(x)
+//
+
+int extFloat80_tan(extFloat80_t &a)
+{
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
+ int aSign, zSign;
+ int q = 0;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ goto invalid;
+ }
+
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+
+ /* invalid argument */
+ if (aExp == 0x7FFF) {
+ if (aSig0 << 1)
+ {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0);
+ a.signExp = nan.v64;
+ a.signif = nan.v0;
+ return 0;
+ }
+
+ invalid:
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ a = floatx80_default_nan;
+ return 0;
+ }
+
+ if (! aExp) {
+ if (! aSig0) return 0;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ /* handle pseudo denormals */
+ if (! (aSig0 & uint64_t(0x8000000000000000)))
+ {
+ softfloat_exceptionFlags |= softfloat_flag_inexact | softfloat_flag_underflow;
+ return 0;
+ }
+
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ }
+
+ zSign = aSign;
+ zExp = FLOATX80_EXP_BIAS;
+ expDiff = aExp - zExp;
+
+ /* argument is out-of-range */
+ if (expDiff >= 63)
+ return -1;
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ if (expDiff < -1) { // doesn't require reduction
+ if (expDiff <= -68) {
+ a = packFloatx80(aSign, aExp, aSig0);
+ return 0;
+ }
+ zExp = aExp;
+ }
+ else {
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
+ }
+
+ /* **************************** */
+ /* argument reduction completed */
+ /* **************************** */
+
+ /* using float128 for approximation */
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1);
+
+ float128_t sin_r = poly_sin(r);
+ float128_t cos_r = poly_cos(r);
+
+ if (q & 0x1) {
+ r = f128_div(cos_r, sin_r);
+ zSign = ! zSign;
+ } else {
+ r = f128_div(sin_r, cos_r);
+ }
+
+ a = f128_to_extF80(r);
+ if (zSign)
+ floatx80_chs(a);
+
+ return 0;
+}
+
+extFloat80_t &floatx80_chs(extFloat80_t &reg)
+{
+ reg.signExp ^= 0x8000;
+ return reg;
+}
diff --git a/3rdparty/softfloat3/bochs_ext/fyl2x.c b/3rdparty/softfloat3/bochs_ext/fyl2x.c
new file mode 100644
index 00000000000..5b9f21bbf11
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/fyl2x.c
@@ -0,0 +1,409 @@
+/*============================================================================
+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]
+ * ==========================================================================*/
+
+#define FLOAT128
+
+#include "../build/MAME/platform.h"
+#include "../source/include/internals.h"
+#include "../source/include/softfloat.h"
+
+#include "fpu_constant.h"
+#include "softfloat-extra.h"
+#include "softfloat-helpers.h"
+#include "softfloat-specialize.h"
+
+static const extFloat80_t floatx80_one = packFloatx80(0, 0x3fff, uint64_t(0x8000000000000000));
+static const extFloat80_t floatx80_ln_2 = packFloatx80(0, 0x3ffe, 0xb17217f7d1cf79acU);
+static const extFloat80_t floatx80_log10_2 = packFloatx80(0, 0x3ffd, 0x9a209a84fbcff798U);
+
+static const float128_t float128_one =
+ packFloat128(uint64_t(0x3fff000000000000), uint64_t(0x0000000000000000));
+static const float128_t float128_two =
+ packFloat128(uint64_t(0x4000000000000000), uint64_t(0x0000000000000000));
+
+static const float128_t float128_ln2inv2 =
+ packFloat128(uint64_t(0x400071547652b82f), uint64_t(0xe1777d0ffda0d23a));
+
+#define SQRT2_HALF_SIG uint64_t(0xb504f333f9de6484)
+
+extern float128_t OddPoly(float128_t x, const float128_t *arr, int n);
+
+#define L2_ARR_SIZE 9
+
+static float128_t ln_arr[L2_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
+ PACK_FLOAT_128(0x3ffc249249249249, 0x2492492492492492), /* 7 */
+ PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
+ PACK_FLOAT_128(0x3ffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
+ PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
+ PACK_FLOAT_128(0x3ffb111111111111, 0x1111111111111111), /* 15 */
+ PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */
+};
+
+static float128_t poly_ln(float128_t x1)
+{
+/*
+ //
+ // 3 5 7 9 11 13 15
+ // 1+u u u u u u u u
+ // 1/2 ln --- ~ u + --- + --- + --- + --- + ---- + ---- + ---- =
+ // 1-u 3 5 7 9 11 13 15
+ //
+ // 2 4 6 8 10 12 14
+ // u u u u u u u
+ // = u * [ 1 + --- + --- + --- + --- + ---- + ---- + ---- ] =
+ // 3 5 7 9 11 13 15
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(u) = > C * u q(u) = > C * u
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 1+u 2
+ // 1/2 ln --- ~ u * [ p(u) + u * q(u) ]
+ // 1-u
+ //
+*/
+ return OddPoly(x1, (const float128_t*) ln_arr, L2_ARR_SIZE);
+}
+
+/* required sqrt(2)/2 < x < sqrt(2) */
+static float128_t poly_l2(float128_t x)
+{
+ /* using float128 for approximation */
+ float128_t x_p1 = f128_add(x, float128_one);
+ float128_t x_m1 = f128_sub(x, float128_one);
+ x = f128_div(x_m1, x_p1);
+ x = poly_ln(x);
+ x = f128_mul(x, float128_ln2inv2);
+ return x;
+}
+
+static float128_t poly_l2p1(float128_t x)
+{
+ /* using float128 for approximation */
+ float128_t x_plus2 = f128_add(x, float128_two);
+ x = f128_div(x, x_plus2);
+ x = poly_ln(x);
+ x = f128_mul(x, float128_ln2inv2);
+ return x;
+}
+
+// =================================================
+// FYL2X Compute y * log (x)
+// 2
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// ln(x)
+// log (x) = -------, ln (x*y) = ln(x) + ln(y)
+// 2 ln(2)
+//
+// 2. ----------------------------------------------------------
+// 1+u x-1
+// ln (x) = ln -----, when u = -----
+// 1-u x+1
+//
+// 3. ----------------------------------------------------------
+// 3 5 7 2n+1
+// 1+u u u u u
+// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
+// 1-u 3 5 7 2n+1
+//
+
+extFloat80_t extFloat80_fyl2x(extFloat80_t a, extFloat80_t b)
+{
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+invalid:
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ return floatx80_default_nan;
+ }
+
+ 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 ((aSig<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (aSign) goto invalid;
+ else {
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ }
+ return packFloatx80(bSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ }
+ if (bExp == 0x7FFF) {
+ if (bSig << 1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (aSign && (uint64_t)(aExp | aSig)) goto invalid;
+ if (aSig && ! aExp)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ if (aExp < 0x3FFF)
+ {
+ return packFloatx80(zSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ if (aExp == 0x3FFF && ! (aSig<<1)) goto invalid;
+ return packFloatx80(bSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ if (! aExp) {
+ if (! aSig) {
+ if ((bExp | bSig) == 0) goto invalid;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // divide by zero
+ return packFloatx80(zSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ if (aSign) goto invalid;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
+ }
+ if (aSign) goto invalid;
+ if (! bExp) {
+ if (! bSig) {
+ if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0);
+ return packFloatx80(bSign, 0, 0);
+ }
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
+ }
+ if (aExp == 0x3FFF && ! (aSig<<1))
+ return packFloatx80(bSign, 0, 0);
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ int ExpDiff = aExp - 0x3FFF;
+ aExp = 0;
+ if (aSig >= SQRT2_HALF_SIG) {
+ ExpDiff++;
+ aExp--;
+ }
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0);
+
+ uint64_t zSig0, zSig1;
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1);
+ x = poly_l2(x);
+ x = f128_add(x, i32_to_f128(ExpDiff));
+ x = f128_mul(x, b128);
+ return f128_to_extF80(x);
+}
+
+// =================================================
+// FYL2XP1 Compute y * log (x + 1)
+// 2
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// ln(x)
+// log (x) = -------
+// 2 ln(2)
+//
+// 2. ----------------------------------------------------------
+// 1+u x
+// ln (x+1) = ln -----, when u = -----
+// 1-u x+2
+//
+// 3. ----------------------------------------------------------
+// 3 5 7 2n+1
+// 1+u u u u u
+// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
+// 1-u 3 5 7 2n+1
+//
+
+extFloat80_t extFloat80_fyl2xp1(extFloat80_t a, extFloat80_t b)
+{
+ int32_t aExp, bExp;
+ uint64_t aSig, bSig, zSig0, zSig1, zSig2;
+ int aSign, bSign;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+invalid:
+ softfloat_exceptionFlags |= softfloat_flag_invalid;
+ return floatx80_default_nan;
+ }
+
+
+ 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 ((aSig<<1) != 0 || ((bExp == 0x7FFF) && (bSig<<1) != 0)) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (aSign) goto invalid;
+ else {
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ }
+ return packFloatx80(bSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ }
+ if (bExp == 0x7FFF)
+ {
+ if (bSig << 1) {
+ const uint128 nan = softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig);
+ extFloat80_t rv;
+ rv.signExp = nan.v64;
+ rv.signif = nan.v0;
+ return rv;
+ }
+ if (! aExp) {
+ if (! aSig) goto invalid;
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ }
+
+ return packFloatx80(zSign, 0x7FFF, uint64_t(0x8000000000000000));
+ }
+ if (! aExp) {
+ if (! aSig) {
+ if (bSig && ! bExp)
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+
+ return packFloatx80(zSign, 0, 0);
+ }
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
+ }
+ if (! bExp) {
+ if (! bSig) return packFloatx80(zSign, 0, 0);
+ softfloat_exceptionFlags |= softfloat_flag_invalid; // actually denormal
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
+ }
+
+ softfloat_exceptionFlags |= softfloat_flag_inexact;
+
+ if (aSign && aExp >= 0x3FFF)
+ return a;
+
+ if (aExp >= 0x3FFC) // big argument
+ {
+ return extFloat80_fyl2x(extF80_add(a, floatx80_one), b);
+ }
+
+ // handle tiny argument
+ if (aExp < FLOATX80_EXP_BIAS-70)
+ {
+ // first order approximation, return (a*b)/ln(2)
+ int32_t zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
+
+ 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 < (int64_t) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --zExp;
+ }
+
+ return softfloat_roundPackToExtF80(aSign ^ bSign, zExp, zSig0, zSig1, 80);
+ }
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0);
+
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(aSign, aExp, zSig0, zSig1);
+ x = poly_l2p1(x);
+ x = f128_mul(x, b128);
+ return f128_to_extF80(x);
+}
+
+extFloat80_t extFloat80_lognp1(extFloat80_t a)
+{
+ return extFloat80_fyl2x(a, floatx80_ln_2);
+}
+
+extFloat80_t extFloat80_logn(extFloat80_t a)
+{
+ return extFloat80_fyl2x(a, floatx80_ln_2);
+}
+
+extFloat80_t extFloat80_log2(extFloat80_t a)
+{
+ return extFloat80_fyl2x(a, floatx80_one);
+}
+
+extFloat80_t extFloat80_log10(extFloat80_t a)
+{
+ return extFloat80_fyl2x(a, floatx80_log10_2);
+}
diff --git a/3rdparty/softfloat3/bochs_ext/poly.c b/3rdparty/softfloat3/bochs_ext/poly.c
new file mode 100644
index 00000000000..3498e29ec4d
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/poly.c
@@ -0,0 +1,91 @@
+/*============================================================================
+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 <assert.h>
+
+#include "../source/include/softfloat.h"
+
+// 2 3 4 n
+// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 2k -- 2k+1
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// f(x) ~ [ p(x) + x * q(x) ]
+//
+
+float128_t EvalPoly(float128_t x, const float128_t *arr, int n)
+{
+ float128_t r = arr[--n];
+
+ do {
+ r = f128_mulAdd(r, x, arr[--n]);
+// r = f128_mul(r, x);
+// r = f128_add(r, arr[--n]);
+
+ } while (n > 0);
+
+ return r;
+}
+
+// 2 4 6 8 2n
+// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 4k -- 4k+2
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// 2
+// f(x) ~ [ p(x) + x * q(x) ]
+//
+
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n)
+{
+ return EvalPoly(f128_mul(x, x), arr, n);
+}
+
+// 3 5 7 9 2n+1
+// f(x) ~ (C * x) + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+// 2 4 6 8 2n
+// = x * [ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 4k -- 4k+2
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// 2
+// f(x) ~ x * [ p(x) + x * q(x) ]
+//
+
+float128_t OddPoly(float128_t x, const float128_t *arr, int n)
+{
+ return f128_mul(x, EvenPoly(x, arr, n));
+}
+
diff --git a/3rdparty/softfloat3/bochs_ext/softfloat-extra.h b/3rdparty/softfloat3/bochs_ext/softfloat-extra.h
new file mode 100644
index 00000000000..087656e5a58
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/softfloat-extra.h
@@ -0,0 +1,68 @@
+/*============================================================================
+
+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 softfloat_extra_h
+#define softfloat_extra_h 1
+
+#include "../source/include/internals.h"
+
+// ======= floatx80 ======= //
+
+inline bool extF80_isUnsupported(extFloat80_t a)
+{
+ return ((a.signExp & 0x7FFF) && !(a.signif & uint64_t(0x8000000000000000)));
+}
+
+inline bool extF80_sign(extFloat80_t a)
+{
+ return signExtF80UI64(a.signExp);
+}
+
+inline int16_t extF80_exp(extFloat80_t a)
+{
+ return expExtF80UI64(a.signExp);
+}
+
+inline uint64_t extF80_fraction(extFloat80_t a)
+{
+ return a.signif;
+}
+
+extFloat80_t &floatx80_chs(extFloat80_t &reg);
+
+extFloat80_t packToExtF80(uint16_t signExp, uint64_t sig);
+extFloat80_t packToExtF80(bool sign, uint16_t exp, uint64_t sig);
+
+#endif
diff --git a/3rdparty/softfloat3/bochs_ext/softfloat-helpers.h b/3rdparty/softfloat3/bochs_ext/softfloat-helpers.h
new file mode 100644
index 00000000000..b8833a126e6
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/softfloat-helpers.h
@@ -0,0 +1,159 @@
+/*============================================================================
+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.
+=============================================================================*/
+
+/*============================================================================
+ * Adapted for Bochs (x86 achitecture simulator) by
+ * Stanislav Shwartsman [sshwarts at sourceforge net]
+ * ==========================================================================*/
+
+#ifndef _SOFTFLOAT_HELPERS_H_
+#define _SOFTFLOAT_HELPERS_H_
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "../source/include/primitives.h"
+#include "../source/include/primitiveTypes.h"
+
+/*----------------------------------------------------------------------------
+| 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'.
+*----------------------------------------------------------------------------*/
+
+inline void mul128By64To192(uint64_t a64, uint64_t a0, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr)
+{
+ uint64_t zPtr[4];
+
+ softfloat_mul128To256M(a64, a0, 0, b, (uint64_t*) zPtr);
+
+ assert(zPtr[indexWord(4, 3)] == 0);
+
+ *z0Ptr = zPtr[indexWord(4, 2)];
+ *z1Ptr = zPtr[indexWord(4, 1)];
+ *z2Ptr = zPtr[indexWord(4, 0)];
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
+| number of bits given in `count'. Any bits shifted off are lost. The value
+| of `count' must be less than 64. The result is broken into two 64-bit
+| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+inline void shortShift128Left(uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
+{
+ *z1Ptr = a1<<count;
+ *z0Ptr = (count == 0) ? a0 : (a0<<count) | (a1>>((-count) & 63));
+}
+
+/*----------------------------------------------------------------------------
+| 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' must be less than 64. The result is broken into two 64-bit pieces
+| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+inline void shortShift128Right(uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr)
+{
+ uint64_t z0 = a0, z1 = a1;
+ int negCount = (-count) & 63;
+
+ if (count != 0) {
+ z1 = (a0<<negCount) | (a1>>count);
+ z0 = a0>>count;
+ }
+ *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 uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b)
+{
+ uint128 term, rem;
+ uint64_t b0, b1;
+ uint64_t z;
+ if (b <= a0) return uint64_t(0xFFFFFFFFFFFFFFFF);
+ b0 = b>>32;
+ z = (b0<<32 <= a0) ? uint64_t(0xFFFFFFFF00000000) : (a0 / b0)<<32;
+ term = softfloat_mul64To128(b, z);
+ rem = softfloat_sub128(a0, a1, term.v64, term.v0);
+ while (((int64_t) rem.v64) < 0) {
+ z -= UINT64_C(0x100000000);
+ b1 = b<<32;
+ rem = softfloat_add128(rem.v64, rem.v0, b0, b1);
+ }
+ rem.v64 = (rem.v64<<32) | (rem.v0>>32);
+ z |= (b0<<32 <= rem.v64) ? 0xFFFFFFFF : rem.v64 / b0;
+ return z;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| 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'.
+*----------------------------------------------------------------------------*/
+
+inline void add192(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t b0, uint64_t b1, uint64_t b2, uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr)
+{
+ uint64_t 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 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'.
+*----------------------------------------------------------------------------*/
+
+inline void sub128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr)
+{
+ *z1Ptr = a1 - b1;
+ *z0Ptr = a0 - b0 - (a1 < b1);
+}
+
+#endif
diff --git a/3rdparty/softfloat3/bochs_ext/softfloat-specialize.h b/3rdparty/softfloat3/bochs_ext/softfloat-specialize.h
new file mode 100644
index 00000000000..f4c5bd2b2cd
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/softfloat-specialize.h
@@ -0,0 +1,223 @@
+/*============================================================================
+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 "../source/include/softfloat_types.h"
+#include "../source/8086/specialize.h"
+
+/*============================================================================
+ * Adapted for Bochs (x86 achitecture simulator) by
+ * Stanislav Shwartsman [sshwarts at sourceforge net]
+ * ==========================================================================*/
+
+const int16_t int16_indefinite = (int16_t) 0x8000;
+const int32_t int32_indefinite = (int32_t) 0x80000000;
+const int64_t int64_indefinite = (int64_t) uint64_t(0x8000000000000000);
+
+const uint16_t uint16_indefinite = 0xffff;
+const uint32_t uint32_indefinite = 0xffffffff;
+const uint64_t uint64_indefinite = uint64_t(0xffffffffffffffff);
+
+/*----------------------------------------------------------------------------
+| Commonly used half-precision floating point constants
+*----------------------------------------------------------------------------*/
+const uint16_t float16_negative_inf = 0xfc00;
+const uint16_t float16_positive_inf = 0x7c00;
+const uint16_t float16_negative_zero = 0x8000;
+const uint16_t float16_positive_zero = 0x0000;
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated half-precision NaN.
+*----------------------------------------------------------------------------*/
+const uint16_t float16_default_nan = 0xFE00;
+
+#define FLOAT16_EXP_BIAS 0xF
+
+/*----------------------------------------------------------------------------
+| 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.
+*----------------------------------------------------------------------------*/
+
+inline uint16_t packFloat16(int zSign, int zExp, uint16_t zSig)
+{
+ return (((uint16_t) zSign)<<15) + (((uint16_t) zExp)<<10) + zSig;
+}
+
+/*----------------------------------------------------------------------------
+| Commonly used single-precision floating point constants
+*----------------------------------------------------------------------------*/
+const uint32_t float32_negative_inf = 0xff800000;
+const uint32_t float32_positive_inf = 0x7f800000;
+const uint32_t float32_negative_zero = 0x80000000;
+const uint32_t float32_positive_zero = 0x00000000;
+const uint32_t float32_negative_one = 0xbf800000;
+const uint32_t float32_positive_one = 0x3f800000;
+const uint32_t float32_max_float = 0x7f7fffff;
+const uint32_t float32_min_float = 0xff7fffff;
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated single-precision NaN.
+*----------------------------------------------------------------------------*/
+const uint32_t float32_default_nan = 0xffc00000;
+
+#define FLOAT32_EXP_BIAS 0x7F
+
+/*----------------------------------------------------------------------------
+| 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.
+*----------------------------------------------------------------------------*/
+
+inline uint32_t packFloat32(int zSign, int16_t zExp, uint32_t zSig)
+{
+ return (((uint32_t) zSign)<<31) + (((uint32_t) zExp)<<23) + zSig;
+}
+
+/*----------------------------------------------------------------------------
+| Commonly used single-precision floating point constants
+*----------------------------------------------------------------------------*/
+const uint64_t float64_negative_inf = uint64_t(0xfff0000000000000);
+const uint64_t float64_positive_inf = uint64_t(0x7ff0000000000000);
+const uint64_t float64_negative_zero = uint64_t(0x8000000000000000);
+const uint64_t float64_positive_zero = uint64_t(0x0000000000000000);
+const uint64_t float64_negative_one = uint64_t(0xbff0000000000000);
+const uint64_t float64_positive_one = uint64_t(0x3ff0000000000000);
+const uint64_t float64_max_float = uint64_t(0x7fefffffffffffff);
+const uint64_t float64_min_float = uint64_t(0xffefffffffffffff);
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated double-precision NaN.
+*----------------------------------------------------------------------------*/
+const uint64_t float64_default_nan = uint64_t(0xFFF8000000000000);
+
+#define FLOAT64_EXP_BIAS 0x3FF
+
+/*----------------------------------------------------------------------------
+| 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.
+*----------------------------------------------------------------------------*/
+
+inline uint64_t packFloat64(int zSign, int16_t zExp, uint64_t zSig)
+{
+ return (((uint64_t) zSign)<<63) + (((uint64_t) zExp)<<52) + zSig;
+}
+
+/*----------------------------------------------------------------------------
+| 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 uint64_t(0xC000000000000000)
+
+#define FLOATX80_EXP_BIAS 0x3FFF
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
+| extended double-precision floating-point value, returning the result.
+*----------------------------------------------------------------------------*/
+
+inline extFloat80_t packFloatx80(int zSign, int32_t zExp, uint64_t zSig)
+{
+ extFloat80_t z;
+ z.signif = zSig;
+ z.signExp = (zSign << 15) + zExp;
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated extended double-precision NaN.
+*----------------------------------------------------------------------------*/
+static const extFloat80_t floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| 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.
+*----------------------------------------------------------------------------*/
+
+inline float128_t packFloat128(int zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1)
+{
+ float128_t z;
+ z.v[0] = zSig1;
+ z.v[1] = (((uint64_t) zSign)<<63) + (((uint64_t) zExp)<<48) + zSig0;
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Packs two 64-bit precision integers into into the quadruple-precision
+| floating-point value, returning the result.
+*----------------------------------------------------------------------------*/
+
+inline float128_t packFloat128(uint64_t zHi, uint64_t zLo)
+{
+ float128_t z;
+ z.v[0] = zLo;
+ z.v[1] = zHi;
+ return z;
+}
+
+#ifdef _MSC_VER
+#define PACK_FLOAT_128(hi,lo) { lo, hi }
+#else
+#define PACK_FLOAT_128(hi,lo) packFloat128(uint64_t(hi),uint64_t(lo))
+#endif
+
+#endif /* FLOAT128 */
+
+#endif
diff --git a/3rdparty/softfloat3/bochs_ext/softfloat3_ext.h b/3rdparty/softfloat3/bochs_ext/softfloat3_ext.h
new file mode 100644
index 00000000000..b6f560bb45a
--- /dev/null
+++ b/3rdparty/softfloat3/bochs_ext/softfloat3_ext.h
@@ -0,0 +1,17 @@
+int extFloat80_ieee754_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, uint64_t &q);
+int extFloat80_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, uint64_t &q);
+int extFloat80_sincos(extFloat80_t a, extFloat80_t *sin_a, extFloat80_t *cos_a);
+int extFloat80_sin(extFloat80_t &a);
+int extFloat80_cos(extFloat80_t &a);
+int extFloat80_tan(extFloat80_t &a);
+extFloat80_t extFloat80_atan(extFloat80_t a, extFloat80_t b);
+extFloat80_t extFloat80_68katan(extFloat80_t a);
+extFloat80_t extFloat80_getman(extFloat80_t a);
+extFloat80_t extFloat80_fyl2x(extFloat80_t a, extFloat80_t b);
+extFloat80_t extFloat80_fyl2xp1(extFloat80_t a, extFloat80_t b);
+extFloat80_t extFloat80_2xm1(extFloat80_t a);
+extFloat80_t extFloat80_lognp1(extFloat80_t a);
+extFloat80_t extFloat80_logn(extFloat80_t a);
+extFloat80_t extFloat80_log2(extFloat80_t a);
+extFloat80_t extFloat80_log10(extFloat80_t a);
+extFloat80_t extFloat80_scale(extFloat80_t a, extFloat80_t b);
diff --git a/3rdparty/softfloat3/build/MAME/platform.h b/3rdparty/softfloat3/build/MAME/platform.h
index 5dfa704955c..6fd29db58fd 100644
--- a/3rdparty/softfloat3/build/MAME/platform.h
+++ b/3rdparty/softfloat3/build/MAME/platform.h
@@ -33,7 +33,7 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
-
+#
/*----------------------------------------------------------------------------
Softfloat 3 MAME modifications
*----------------------------------------------------------------------------*/
@@ -45,11 +45,7 @@ Softfloat 3 MAME modifications
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-#ifdef __GNUC_STDC_INLINE__
-#define INLINE inline
-#else
-#define INLINE extern inline
-#endif
+#define INLINE static inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
@@ -78,4 +74,4 @@ Softfloat 3 MAME modifications
#endif // defined(_MSC_VER)
-#include "opts-GCC.h"
+#include "../../source/include/opts-GCC.h"
diff --git a/3rdparty/softfloat3/source/include/softfloat.h b/3rdparty/softfloat3/source/include/softfloat.h
index 9ed17c1b90d..863796d3b4b 100644
--- a/3rdparty/softfloat3/source/include/softfloat.h
+++ b/3rdparty/softfloat3/source/include/softfloat.h
@@ -46,6 +46,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef softfloat_h
#define softfloat_h 1
+// copy config #defines from 3rdparty.lua to match the build configuration
+#ifndef SOFTFLOAT_FAST_INT64
+#define SOFTFLOAT_FAST_INT64
+#define SOFTFLOAT_FAST_DIV32TO16
+#define SOFTFLOAT_FAST_DIV64TO32
+#define SOFTFLOAT_ROUND_ODD
+#endif
+
+#ifndef INLINE_LEVEL
+#define INLINE_LEVEL (5)
+#endif
+
+#ifndef INLINE
+#define INLINE static inline
+#endif
+
#include <stdbool.h>
#include <stdint.h>
#include "softfloat_types.h"
@@ -59,8 +75,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;
enum {
- softfloat_tininess_beforeRounding = 0,
- softfloat_tininess_afterRounding = 1
+ softfloat_tininess_beforeRounding = 0,
+ softfloat_tininess_afterRounding = 1
};
/*----------------------------------------------------------------------------
@@ -69,12 +85,12 @@ enum {
*----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode;
enum {
- softfloat_round_near_even = 0,
- softfloat_round_minMag = 1,
- softfloat_round_min = 2,
- softfloat_round_max = 3,
- softfloat_round_near_maxMag = 4,
- softfloat_round_odd = 6
+ softfloat_round_near_even = 0,
+ softfloat_round_minMag = 1,
+ softfloat_round_min = 2,
+ softfloat_round_max = 3,
+ softfloat_round_near_maxMag = 4,
+ softfloat_round_odd = 6
};
/*----------------------------------------------------------------------------
@@ -82,11 +98,11 @@ enum {
*----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags;
enum {
- softfloat_flag_inexact = 1,
- softfloat_flag_underflow = 2,
- softfloat_flag_overflow = 4,
- softfloat_flag_infinite = 8,
- softfloat_flag_invalid = 16
+ softfloat_flag_inexact = 1,
+ softfloat_flag_underflow = 2,
+ softfloat_flag_overflow = 4,
+ softfloat_flag_infinite = 8,
+ softfloat_flag_invalid = 16
};
/*----------------------------------------------------------------------------
@@ -290,7 +306,7 @@ float64_t extF80M_to_f64( const extFloat80_t * );
void extF80M_to_f128M( const extFloat80_t *, float128_t * );
void
extF80M_roundToInt(
- const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );
+ const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );
void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
@@ -355,7 +371,7 @@ void f128M_sub( const float128_t *, const float128_t *, float128_t * );
void f128M_mul( const float128_t *, const float128_t *, float128_t * );
void
f128M_mulAdd(
- const float128_t *, const float128_t *, const float128_t *, float128_t *
+ const float128_t *, const float128_t *, const float128_t *, float128_t *
);
void f128M_div( const float128_t *, const float128_t *, float128_t * );
void f128M_rem( const float128_t *, const float128_t *, float128_t * );
diff --git a/3rdparty/softfloat3/source/include/softfloat_types.h b/3rdparty/softfloat3/source/include/softfloat_types.h
index b92d24625eb..3657ac0483d 100644
--- a/3rdparty/softfloat3/source/include/softfloat_types.h
+++ b/3rdparty/softfloat3/source/include/softfloat_types.h
@@ -39,6 +39,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h>
+// MAME: when #included from actual MAME code, we need the endianness to match what the build system set
+#ifdef LSB_FIRST
+#ifndef LITTLEENDIAN
+#define LITTLEENDIAN
+#endif
+#endif
+
/*----------------------------------------------------------------------------
| Types used to pass 16-bit, 32-bit, 64-bit, and 128-bit floating-point
| arguments and results to/from functions. These types must be exactly