mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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.
This commit is contained in:
parent
cd25f2de50
commit
6957c46998
156
3rdparty/softfloat3/bochs_ext/extF80_scale.c
vendored
Normal file
156
3rdparty/softfloat3/bochs_ext/extF80_scale.c
vendored
Normal file
@ -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);
|
||||
}
|
186
3rdparty/softfloat3/bochs_ext/f2xm1.c
vendored
Normal file
186
3rdparty/softfloat3/bochs_ext/f2xm1.c
vendored
Normal file
@ -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;
|
||||
}
|
||||
}
|
326
3rdparty/softfloat3/bochs_ext/fpatan.c
vendored
Normal file
326
3rdparty/softfloat3/bochs_ext/fpatan.c
vendored
Normal file
@ -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);
|
||||
}
|
255
3rdparty/softfloat3/bochs_ext/fprem.c
vendored
Normal file
255
3rdparty/softfloat3/bochs_ext/fprem.c
vendored
Normal file
@ -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);
|
||||
}
|
80
3rdparty/softfloat3/bochs_ext/fpu_constant.h
vendored
Normal file
80
3rdparty/softfloat3/bochs_ext/fpu_constant.h
vendored
Normal file
@ -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
|
457
3rdparty/softfloat3/bochs_ext/fsincos.c
vendored
Normal file
457
3rdparty/softfloat3/bochs_ext/fsincos.c
vendored
Normal file
@ -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.signExp ^= 0x8000;
|
||||
return reg;
|
||||
}
|
409
3rdparty/softfloat3/bochs_ext/fyl2x.c
vendored
Normal file
409
3rdparty/softfloat3/bochs_ext/fyl2x.c
vendored
Normal file
@ -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);
|
||||
}
|
91
3rdparty/softfloat3/bochs_ext/poly.c
vendored
Normal file
91
3rdparty/softfloat3/bochs_ext/poly.c
vendored
Normal file
@ -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));
|
||||
}
|
||||
|
68
3rdparty/softfloat3/bochs_ext/softfloat-extra.h
vendored
Normal file
68
3rdparty/softfloat3/bochs_ext/softfloat-extra.h
vendored
Normal file
@ -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 ®);
|
||||
|
||||
extFloat80_t packToExtF80(uint16_t signExp, uint64_t sig);
|
||||
extFloat80_t packToExtF80(bool sign, uint16_t exp, uint64_t sig);
|
||||
|
||||
#endif
|
159
3rdparty/softfloat3/bochs_ext/softfloat-helpers.h
vendored
Normal file
159
3rdparty/softfloat3/bochs_ext/softfloat-helpers.h
vendored
Normal file
@ -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
|
223
3rdparty/softfloat3/bochs_ext/softfloat-specialize.h
vendored
Normal file
223
3rdparty/softfloat3/bochs_ext/softfloat-specialize.h
vendored
Normal file
@ -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
|
17
3rdparty/softfloat3/bochs_ext/softfloat3_ext.h
vendored
Normal file
17
3rdparty/softfloat3/bochs_ext/softfloat3_ext.h
vendored
Normal file
@ -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);
|
10
3rdparty/softfloat3/build/MAME/platform.h
vendored
10
3rdparty/softfloat3/build/MAME/platform.h
vendored
@ -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"
|
||||
|
46
3rdparty/softfloat3/source/include/softfloat.h
vendored
46
3rdparty/softfloat3/source/include/softfloat.h
vendored
@ -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 * );
|
||||
|
@ -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
|
||||
|
@ -285,6 +285,7 @@ project "softfloat3"
|
||||
MAME_DIR .. "3rdparty/softfloat3/source",
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/include",
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/8086",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext"
|
||||
}
|
||||
|
||||
configuration { "gmake or ninja" }
|
||||
@ -313,6 +314,11 @@ end
|
||||
"SOFTFLOAT_FAST_INT64"
|
||||
}
|
||||
|
||||
if _OPTIONS["BIGENDIAN"]~="1" then
|
||||
defines {
|
||||
"LITTLEENDIAN=1"
|
||||
}
|
||||
end
|
||||
files {
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/s_eq128.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/s_le128.c",
|
||||
@ -615,6 +621,13 @@ end
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/f128M_eq_signaling.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/f128M_le_quiet.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/source/f128M_lt_quiet.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/f2xm1.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/fpatan.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/fprem.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/fsincos.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/fyl2x.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/poly.c",
|
||||
MAME_DIR .. "3rdparty/softfloat3/bochs_ext/extF80_scale.c",
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,15 +7,8 @@
|
||||
|
||||
#include "m68kcommon.h"
|
||||
|
||||
// SoftFloat 2 lacks an include guard
|
||||
#ifndef softfloat2_h
|
||||
#define softfloat2_h 1
|
||||
#include "softfloat/milieu.h"
|
||||
#include "softfloat/softfloat.h"
|
||||
#endif
|
||||
|
||||
extern flag floatx80_is_nan(floatx80 a);
|
||||
|
||||
#include "softfloat3/source/include/softfloat.h"
|
||||
#include "softfloat3/bochs_ext/softfloat3_ext.h"
|
||||
|
||||
/* MMU constants */
|
||||
constexpr int MMU_ATC_ENTRIES = (22); // 68851 has 64, 030 has 22
|
||||
@ -152,7 +145,7 @@ protected:
|
||||
u32 m_cacr; /* Cache Control Register (m68020, unemulated) */
|
||||
u32 m_caar; /* Cache Address Register (m68020, unemulated) */
|
||||
u32 m_ir; /* Instruction Register */
|
||||
floatx80 m_fpr[8]; /* FPU Data Register (m68030/040) */
|
||||
extFloat80_t m_fpr[8]; /* FPU Data Register (m68030/040) */
|
||||
u32 m_fpiar; /* FPU Instruction Address Register (m68040) */
|
||||
u32 m_fpsr; /* FPU Status Register (m68040) */
|
||||
u32 m_fpcr; /* FPU Control Register (m68040) */
|
||||
@ -329,48 +322,45 @@ protected:
|
||||
#include "m68kops.h"
|
||||
#include "m68kmmu.h"
|
||||
|
||||
static double fx80_to_double(floatx80 fx)
|
||||
static double fx80_to_double(extFloat80_t fx)
|
||||
{
|
||||
u64 d;
|
||||
double *foo;
|
||||
|
||||
foo = (double *)&d;
|
||||
|
||||
d = floatx80_to_float64(fx);
|
||||
const float64_t d = extF80_to_f64(fx);
|
||||
const double *foo = (double *)&d;
|
||||
|
||||
return *foo;
|
||||
}
|
||||
|
||||
static floatx80 double_to_fx80(double in)
|
||||
static extFloat80_t double_to_fx80(double in)
|
||||
{
|
||||
u64 *d;
|
||||
float64_t *d = (float64_t *)∈
|
||||
|
||||
d = (u64 *)∈
|
||||
|
||||
return float64_to_floatx80(*d);
|
||||
return f64_to_extF80(*d);
|
||||
}
|
||||
|
||||
// defined in m68kfpu.cpp
|
||||
static const u32 pkmask2[18];
|
||||
static const u32 pkmask3[18];
|
||||
inline floatx80 load_extended_float80(u32 ea);
|
||||
inline void store_extended_float80(u32 ea, floatx80 fpr);
|
||||
inline floatx80 load_pack_float80(u32 ea);
|
||||
inline void store_pack_float80(u32 ea, int k, floatx80 fpr);
|
||||
inline void SET_CONDITION_CODES(floatx80 reg);
|
||||
inline int TEST_CONDITION(int condition);
|
||||
inline extFloat80_t load_extended_float80(u32 ea);
|
||||
inline void store_extended_float80(u32 ea, extFloat80_t fpr);
|
||||
inline extFloat80_t load_pack_float80(u32 ea);
|
||||
inline void store_pack_float80(u32 ea, int k, extFloat80_t fpr);
|
||||
void set_condition_codes(extFloat80_t reg);
|
||||
int test_condition(int condition);
|
||||
void clear_exception_flags();
|
||||
void sync_exception_flags(extFloat80_t op1, extFloat80_t op2, u32 enables);
|
||||
s32 convert_to_int(extFloat80_t source, s32 lowerLimit, s32 upperLimit);
|
||||
u8 READ_EA_8(int ea);
|
||||
u16 READ_EA_16(int ea);
|
||||
u32 READ_EA_32(int ea);
|
||||
u64 READ_EA_64(int ea);
|
||||
floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea);
|
||||
floatx80 READ_EA_PACK(int ea);
|
||||
extFloat80_t READ_EA_FPE(int mode, int reg, uint32_t di_mode_ea);
|
||||
extFloat80_t READ_EA_PACK(int ea);
|
||||
void WRITE_EA_8(int ea, u8 data);
|
||||
void WRITE_EA_16(int ea, u16 data);
|
||||
void WRITE_EA_32(int ea, u32 data);
|
||||
void WRITE_EA_64(int ea, u64 data);
|
||||
void WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea);
|
||||
void WRITE_EA_PACK(int ea, int k, floatx80 fpr);
|
||||
void WRITE_EA_FPE(int mode, int reg, extFloat80_t fpr, uint32_t di_mode_ea);
|
||||
void WRITE_EA_PACK(int ea, int k, extFloat80_t fpr);
|
||||
void fpgen_rm_reg(u16 w2);
|
||||
void fmove_reg_mem(u16 w2);
|
||||
void fmove_fpcr(u16 w2);
|
||||
|
Loading…
Reference in New Issue
Block a user