Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-…
Browse files Browse the repository at this point in the history
…request' into staging

# gpg: Signature made Sun 04 Mar 2018 17:32:25 GMT
# gpg:                using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <[email protected]>"
# gpg:                 aka "Laurent Vivier <[email protected]>"
# gpg:                 aka "Laurent Vivier (Red Hat) <[email protected]>"
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/m68k-for-2.12-pull-request:
  target/m68k: add fscale, fgetman and fgetexp
  softfloat: use floatx80_infinity in softfloat
  target/m68k: add fmod/frem
  softfloat: export some functions
  target/m68k: TCGv returned by gen_load() must be freed

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed Mar 5, 2018
2 parents 7fceeb1 + 0d379c1 commit 4a22592
Show file tree
Hide file tree
Showing 11 changed files with 548 additions and 106 deletions.
17 changes: 15 additions & 2 deletions fpu/softfloat-specialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@ floatx80 floatx80_default_nan(float_status *status)
return r;
}

/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision inf.
*----------------------------------------------------------------------------*/

#define floatx80_infinity_high 0x7FFF
#if defined(TARGET_M68K)
#define floatx80_infinity_low LIT64(0x0000000000000000)
#else
#define floatx80_infinity_low LIT64(0x8000000000000000)
#endif

const floatx80 floatx80_infinity
= make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);

/*----------------------------------------------------------------------------
| The pattern for a default generated quadruple-precision NaN.
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -1011,8 +1025,7 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/

static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
float_status *status)
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
{
flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
flag aIsLargerSignificand;
Expand Down
130 changes: 35 additions & 95 deletions fpu/softfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ this code that are retained.
| division and square root approximations. (Can be specialized to target if
| desired.)
*----------------------------------------------------------------------------*/
#include "softfloat-macros.h"
#include "fpu/softfloat-macros.h"

/*----------------------------------------------------------------------------
| Functions and definitions to determine: (1) whether tininess for underflow
Expand Down Expand Up @@ -2192,25 +2192,6 @@ static void

}

/*----------------------------------------------------------------------------
| 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.
*----------------------------------------------------------------------------*/

static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
{

return make_float32(
( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);

}

/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper single-precision floating-
Expand Down Expand Up @@ -2490,73 +2471,21 @@ static float64

}

/*----------------------------------------------------------------------------
| Returns the fraction bits of the extended double-precision floating-point
| value `a'.
*----------------------------------------------------------------------------*/

static inline uint64_t extractFloatx80Frac( floatx80 a )
{

return a.low;

}

/*----------------------------------------------------------------------------
| Returns the exponent bits of the extended double-precision floating-point
| value `a'.
*----------------------------------------------------------------------------*/

static inline int32_t extractFloatx80Exp( floatx80 a )
{

return a.high & 0x7FFF;

}

/*----------------------------------------------------------------------------
| Returns the sign bit of the extended double-precision floating-point value
| `a'.
*----------------------------------------------------------------------------*/

static inline flag extractFloatx80Sign( floatx80 a )
{

return a.high>>15;

}

/*----------------------------------------------------------------------------
| Normalizes the subnormal extended double-precision floating-point value
| represented by the denormalized significand `aSig'. The normalized exponent
| and significand are stored at the locations pointed to by `zExpPtr' and
| `zSigPtr', respectively.
*----------------------------------------------------------------------------*/

static void
normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr )
void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
uint64_t *zSigPtr)
{
int8_t shiftCount;

shiftCount = countLeadingZeros64( aSig );
*zSigPtr = aSig<<shiftCount;
*zExpPtr = 1 - shiftCount;

}

/*----------------------------------------------------------------------------
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
| extended double-precision floating-point value, returning the result.
*----------------------------------------------------------------------------*/

static inline floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
{
floatx80 z;

z.low = zSig;
z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
return z;

}

/*----------------------------------------------------------------------------
Expand All @@ -2583,9 +2512,9 @@ static inline floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
int32_t zExp, uint64_t zSig0, uint64_t zSig1,
float_status *status)
floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
int32_t zExp, uint64_t zSig0, uint64_t zSig1,
float_status *status)
{
int8_t roundingMode;
flag roundNearestEven, increment, isTiny;
Expand Down Expand Up @@ -2707,7 +2636,9 @@ static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
) {
return packFloatx80( zSign, 0x7FFE, ~ roundMask );
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign,
floatx80_infinity_high,
floatx80_infinity_low);
}
if ( zExp <= 0 ) {
isTiny =
Expand Down Expand Up @@ -2779,10 +2710,10 @@ static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
| normalized.
*----------------------------------------------------------------------------*/

static floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
flag zSign, int32_t zExp,
uint64_t zSig0, uint64_t zSig1,
float_status *status)
floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
flag zSign, int32_t zExp,
uint64_t zSig0, uint64_t zSig1,
float_status *status)
{
int8_t shiftCount;

Expand Down Expand Up @@ -3253,7 +3184,9 @@ floatx80 float32_to_floatx80(float32 a, float_status *status)
if (aSig) {
return commonNaNToFloatx80(float32ToCommonNaN(a, status), status);
}
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(aSign,
floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
Expand Down Expand Up @@ -4108,7 +4041,9 @@ floatx80 float64_to_floatx80(float64 a, float_status *status)
if (aSig) {
return commonNaNToFloatx80(float64ToCommonNaN(a, status), status);
}
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(aSign,
floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
Expand Down Expand Up @@ -4620,10 +4555,7 @@ int64_t floatx80_to_int64(floatx80 a, float_status *status)
if ( shiftCount <= 0 ) {
if ( shiftCount ) {
float_raise(float_flag_invalid, status);
if ( ! aSign
|| ( ( aExp == 0x7FFF )
&& ( aSig != LIT64( 0x8000000000000000 ) ) )
) {
if (!aSign || floatx80_is_any_nan(a)) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
return (int64_t) LIT64( 0x8000000000000000 );
Expand Down Expand Up @@ -4929,7 +4861,9 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
if ((uint64_t)(bSig << 1)) {
return propagateFloatx80NaN(a, b, status);
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign,
floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) ++expDiff;
shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
Expand Down Expand Up @@ -5004,7 +4938,8 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
if ((uint64_t)(bSig << 1)) {
return propagateFloatx80NaN(a, b, status);
}
return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign ^ 1, floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) ++expDiff;
shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
Expand Down Expand Up @@ -5109,7 +5044,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
return propagateFloatx80NaN(a, b, status);
}
if ( ( bExp | bSig ) == 0 ) goto invalid;
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign, floatx80_infinity_high,
floatx80_infinity_low);
}
if ( bExp == 0x7FFF ) {
if ((uint64_t)(bSig << 1)) {
Expand All @@ -5120,7 +5056,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
float_raise(float_flag_invalid, status);
return floatx80_default_nan(status);
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign, floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
Expand Down Expand Up @@ -5174,7 +5111,8 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
}
goto invalid;
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign, floatx80_infinity_high,
floatx80_infinity_low);
}
if ( bExp == 0x7FFF ) {
if ((uint64_t)(bSig << 1)) {
Expand All @@ -5190,7 +5128,8 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
return floatx80_default_nan(status);
}
float_raise(float_flag_divbyzero, status);
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(zSign, floatx80_infinity_high,
floatx80_infinity_low);
}
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
}
Expand Down Expand Up @@ -6013,7 +5952,8 @@ floatx80 float128_to_floatx80(float128 a, float_status *status)
if ( aSig0 | aSig1 ) {
return commonNaNToFloatx80(float128ToCommonNaN(a, status), status);
}
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
return packFloatx80(aSign, floatx80_infinity_high,
floatx80_infinity_low);
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
Expand Down
10 changes: 5 additions & 5 deletions fpu/softfloat-macros.h → include/fpu/softfloat-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ static inline void
| unsigned integer is returned.
*----------------------------------------------------------------------------*/

static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b )
static inline uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b)
{
uint64_t b0, b1;
uint64_t rem0, rem1, term0, term1;
Expand All @@ -630,7 +630,7 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b )
*
* Licensed under the GPLv2/LGPLv3
*/
static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
{
uint64_t d0, d1, q0, q1, r1, r0, m;

Expand Down Expand Up @@ -683,7 +683,7 @@ static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
| value.
*----------------------------------------------------------------------------*/

static uint32_t estimateSqrt32(int aExp, uint32_t a)
static inline uint32_t estimateSqrt32(int aExp, uint32_t a)
{
static const uint16_t sqrtOddAdjustments[] = {
0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
Expand Down Expand Up @@ -717,7 +717,7 @@ static uint32_t estimateSqrt32(int aExp, uint32_t a)
| `a'. If `a' is zero, 32 is returned.
*----------------------------------------------------------------------------*/

static int8_t countLeadingZeros32( uint32_t a )
static inline int8_t countLeadingZeros32(uint32_t a)
{
#if SOFTFLOAT_GNUC_PREREQ(3, 4)
if (a) {
Expand Down Expand Up @@ -765,7 +765,7 @@ static int8_t countLeadingZeros32( uint32_t a )
| `a'. If `a' is zero, 64 is returned.
*----------------------------------------------------------------------------*/

static int8_t countLeadingZeros64( uint64_t a )
static inline int8_t countLeadingZeros64(uint64_t a)
{
#if SOFTFLOAT_GNUC_PREREQ(3, 4)
if (a) {
Expand Down
Loading

0 comments on commit 4a22592

Please sign in to comment.