-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJanC2pAAoJEPMMOL0/L7488rkP/RoqLKJ1KVu77t2ldmW1gtD6 O9OPykgmxjWdX5jSiLFSd69pH7WP+1udn2zNAxHu+Y6mh8ASe4MsM1umwL5fU6J4 FGiZfS8h54cNulQKZ1fdsGfo2+Dvgbs2Hi0DQx3/KyzwZJKkN8iTTZPeBVwMOCIP kYGeSTId6CcpA/CM05rXidI9ocBdaMgdD5Z+do7lewcZNqtpf+uegE9ImP5O4r9m BJgYqsMQTUe1SZ+y5LYiGQt7+QJAEypdjstYplHBZQGvwS6k4+oEL//aSNJcrcEJ 9rV6P5pIlSUA6l+MogJLtcJ4AeNgd36sQmGgrfIQm7GHvGs0cKZAY3CL56erDqVY 3iAwPeUtPgAxVwxsPoL/Pn4fpBM/lN0GMx7vDxj1mctTK5uwyrKock0iVFYcr+pZ rUzrmHgdruH8l728ktNR3362Ttgv0Vy4Jz8vVXszwPBYE3E/DEVls3leNV4+HK0C YClEAXGtPggfrEdCLUXbS5dKcRC4igUgpENq8qve/9rIKohzmLVZxG0rQQjm2oo6 A3nvLs7FbdG+kTIrPdvffJaVpqcMBxy206ZPofbxpGBRsjsmeLd5v8Qa42dLv8kv HmsMkT6GobQdOLlMdLG11bj+wgw24Lrgr665m29wpxOejOs84kxuiGvuGOz4Q43Y 8YOrcZzBpsAVYgN9dTjH =l8ac -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-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 <lvivier@redhat.com>" # gpg: aka "Laurent Vivier <laurent@vivier.eu>" # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" # 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 <peter.maydell@linaro.org>
This commit is contained in:
commit
4a22592e32
@ -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.
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -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;
|
||||
|
130
fpu/softfloat.c
130
fpu/softfloat.c
@ -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
|
||||
@ -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-
|
||||
@ -2490,42 +2471,6 @@ 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
|
||||
@ -2533,30 +2478,14 @@ static inline flag extractFloatx80Sign( floatx80 a )
|
||||
| `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;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
@ -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;
|
||||
@ -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 =
|
||||
@ -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;
|
||||
|
||||
@ -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 );
|
||||
@ -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 );
|
||||
@ -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 );
|
||||
@ -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 );
|
||||
@ -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 );
|
||||
@ -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)) {
|
||||
@ -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 );
|
||||
@ -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)) {
|
||||
@ -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 );
|
||||
}
|
||||
@ -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 );
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
@ -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) {
|
||||
@ -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) {
|
@ -425,6 +425,23 @@ static inline float32 float32_set_sign(float32 a, int sign)
|
||||
#define float32_three make_float32(0x40400000)
|
||||
#define float32_infinity make_float32(0x7f800000)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| 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);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated single-precision NaN.
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -555,6 +572,11 @@ float32 floatx80_to_float32(floatx80, float_status *status);
|
||||
float64 floatx80_to_float64(floatx80, float_status *status);
|
||||
float128 floatx80_to_float128(floatx80, float_status *status);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for an extended double-precision inf.
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern const floatx80 floatx80_infinity;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE extended double-precision operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -595,7 +617,12 @@ static inline floatx80 floatx80_chs(floatx80 a)
|
||||
|
||||
static inline int floatx80_is_infinity(floatx80 a)
|
||||
{
|
||||
return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
|
||||
#if defined(TARGET_M68K)
|
||||
return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
|
||||
#else
|
||||
return (a.high & 0x7fff) == floatx80_infinity.high &&
|
||||
a.low == floatx80_infinity.low;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int floatx80_is_neg(floatx80 a)
|
||||
@ -638,7 +665,110 @@ static inline bool floatx80_invalid_encoding(floatx80 a)
|
||||
#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
|
||||
#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
|
||||
#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
|
||||
#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| 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;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| 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;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Normalizes the subnormal extended double-precision floating-point value
|
||||
| represented by the denormalized significand `aSig'. The normalized exponent
|
||||
| and significand are stored at the locations pointed to by `zExpPtr' and
|
||||
| `zSigPtr', respectively.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
|
||||
uint64_t *zSigPtr);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes two extended double-precision floating-point values `a' and `b', one
|
||||
| of which is a NaN, and returns the appropriate NaN result. If either `a' or
|
||||
| `b' is a signaling NaN, the invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
|
||||
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
|
||||
| and returns the proper extended double-precision floating-point value
|
||||
| corresponding to the abstract input. Ordinarily, the abstract value is
|
||||
| rounded and packed into the extended double-precision format, with the
|
||||
| inexact exception raised if the abstract input cannot be represented
|
||||
| exactly. However, if the abstract value is too large, the overflow and
|
||||
| inexact exceptions are raised and an infinity or maximal finite value is
|
||||
| returned. If the abstract value is too small, the input value is rounded to
|
||||
| a subnormal number, and the underflow and inexact exceptions are raised if
|
||||
| the abstract input cannot be represented exactly as a subnormal extended
|
||||
| double-precision floating-point number.
|
||||
| If `roundingPrecision' is 32 or 64, the result is rounded to the same
|
||||
| number of bits as single or double precision, respectively. Otherwise, the
|
||||
| result is rounded to the full precision of the extended double-precision
|
||||
| format.
|
||||
| The input significand must be normalized or smaller. If the input
|
||||
| significand is not normalized, `zExp' must be 0; in that case, the result
|
||||
| returned is a subnormal number, and it must not require rounding. The
|
||||
| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
|
||||
| Floating-Point Arithmetic.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
|
||||
int32_t zExp, uint64_t zSig0, uint64_t zSig1,
|
||||
float_status *status);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes an abstract floating-point value having sign `zSign', exponent
|
||||
| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
|
||||
| and returns the proper extended double-precision floating-point value
|
||||
| corresponding to the abstract input. This routine is just like
|
||||
| `roundAndPackFloatx80' except that the input significand does not have to be
|
||||
| normalized.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
|
||||
flag zSign, int32_t zExp,
|
||||
uint64_t zSig0, uint64_t zSig1,
|
||||
float_status *status);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated extended double-precision NaN.
|
||||
|
@ -1,4 +1,5 @@
|
||||
obj-y += m68k-semi.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += fpu_helper.o softfloat.o
|
||||
obj-y += gdbstub.o
|
||||
obj-$(CONFIG_SOFTMMU) += monitor.o
|
||||
|
@ -427,6 +427,7 @@ typedef enum {
|
||||
/* Quotient */
|
||||
|
||||
#define FPSR_QT_MASK 0x00ff0000
|
||||
#define FPSR_QT_SHIFT 16
|
||||
|
||||
/* Floating-Point Control Register */
|
||||
/* Rounding mode */
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
#include "fpu/softfloat.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
/* Undefined offsets may be different on various FPU.
|
||||
* On 68040 they return 0.0 (floatx80_zero)
|
||||
@ -509,3 +509,51 @@ uint32_t HELPER(fmovemd_ld_postinc)(CPUM68KState *env, uint32_t addr,
|
||||
{
|
||||
return fmovem_postinc(env, addr, mask, cpu_ld_float64_ra);
|
||||
}
|
||||
|
||||
static void make_quotient(CPUM68KState *env, floatx80 val)
|
||||
{
|
||||
int32_t quotient;
|
||||
int sign;
|
||||
|
||||
if (floatx80_is_any_nan(val)) {
|
||||
return;
|
||||
}
|
||||
|
||||
quotient = floatx80_to_int32(val, &env->fp_status);
|
||||
sign = quotient < 0;
|
||||
if (sign) {
|
||||
quotient = -quotient;
|
||||
}
|
||||
|
||||
quotient = (sign << 7) | (quotient & 0x7f);
|
||||
env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
|
||||
}
|
||||
|
||||
void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
|
||||
{
|
||||
res->d = floatx80_mod(val1->d, val0->d, &env->fp_status);
|
||||
|
||||
make_quotient(env, res->d);
|
||||
}
|
||||
|
||||
void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
|
||||
{
|
||||
res->d = floatx80_rem(val1->d, val0->d, &env->fp_status);
|
||||
|
||||
make_quotient(env, res->d);
|
||||
}
|
||||
|
||||
void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
|
||||
{
|
||||
res->d = floatx80_getexp(val->d, &env->fp_status);
|
||||
}
|
||||
|
||||
void HELPER(fgetman)(CPUM68KState *env, FPReg *res, FPReg *val)
|
||||
{
|
||||
res->d = floatx80_getman(val->d, &env->fp_status);
|
||||
}
|
||||
|
||||
void HELPER(fscale)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
|
||||
{
|
||||
res->d = floatx80_scale(val1->d, val0->d, &env->fp_status);
|
||||
}
|
||||
|
@ -63,6 +63,11 @@ DEF_HELPER_3(fmovemx_ld_postinc, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fmovemd_st_predec, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fmovemd_st_postinc, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fmovemd_ld_postinc, i32, env, i32, i32)
|
||||
DEF_HELPER_4(fmod, void, env, fp, fp, fp)
|
||||
DEF_HELPER_4(frem, void, env, fp, fp, fp)
|
||||
DEF_HELPER_3(fgetexp, void, env, fp, fp)
|
||||
DEF_HELPER_3(fgetman, void, env, fp, fp)
|
||||
DEF_HELPER_4(fscale, void, env, fp, fp, fp)
|
||||
|
||||
DEF_HELPER_3(mac_move, void, env, i32, i32)
|
||||
DEF_HELPER_3(macmulf, i64, env, i32, i32)
|
||||
|
249
target/m68k/softfloat.c
Normal file
249
target/m68k/softfloat.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Ported from a work by Andreas Grabher for Previous, NeXT Computer Emulator,
|
||||
* derived from NetBSD M68040 FPSP functions,
|
||||
* derived from release 2a of the SoftFloat IEC/IEEE Floating-point Arithmetic
|
||||
* Package. Those parts of the code (and some later contributions) are
|
||||
* provided under that license, as detailed below.
|
||||
* It has subsequently been modified by contributors to the QEMU Project,
|
||||
* so some portions are provided under:
|
||||
* the SoftFloat-2a license
|
||||
* the BSD license
|
||||
* GPL-v2-or-later
|
||||
*
|
||||
* Any future contributions to this file will be taken to be licensed under
|
||||
* the Softfloat-2a license unless specifically indicated otherwise.
|
||||
*/
|
||||
|
||||
/* Portions of this work are licensed under the terms of the GNU GPL,
|
||||
* version 2 or later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "softfloat.h"
|
||||
#include "fpu/softfloat-macros.h"
|
||||
|
||||
static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
|
||||
{
|
||||
if (floatx80_is_signaling_nan(a, status)) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
}
|
||||
|
||||
if (status->default_nan_mode) {
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
|
||||
return floatx80_maybe_silence_nan(a, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the modulo remainder of the extended double-precision floating-point
|
||||
| value `a' with respect to the corresponding value `b'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
|
||||
{
|
||||
flag aSign, zSign;
|
||||
int32_t aExp, bExp, expDiff;
|
||||
uint64_t aSig0, aSig1, bSig;
|
||||
uint64_t qTemp, term0, term1;
|
||||
|
||||
aSig0 = extractFloatx80Frac(a);
|
||||
aExp = extractFloatx80Exp(a);
|
||||
aSign = extractFloatx80Sign(a);
|
||||
bSig = extractFloatx80Frac(b);
|
||||
bExp = extractFloatx80Exp(b);
|
||||
|
||||
if (aExp == 0x7FFF) {
|
||||
if ((uint64_t) (aSig0 << 1)
|
||||
|| ((bExp == 0x7FFF) && (uint64_t) (bSig << 1))) {
|
||||
return propagateFloatx80NaN(a, b, status);
|
||||
}
|
||||
goto invalid;
|
||||
}
|
||||
if (bExp == 0x7FFF) {
|
||||
if ((uint64_t) (bSig << 1)) {
|
||||
return propagateFloatx80NaN(a, b, status);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) {
|
||||
invalid:
|
||||
float_raise(float_flag_invalid, status);
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if ((uint64_t) (aSig0 << 1) == 0) {
|
||||
return a;
|
||||
}
|
||||
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
|
||||
}
|
||||
bSig |= LIT64(0x8000000000000000);
|
||||
zSign = aSign;
|
||||
expDiff = aExp - bExp;
|
||||
aSig1 = 0;
|
||||
if (expDiff < 0) {
|
||||
return a;
|
||||
}
|
||||
qTemp = (bSig <= aSig0);
|
||||
if (qTemp) {
|
||||
aSig0 -= bSig;
|
||||
}
|
||||
expDiff -= 64;
|
||||
while (0 < expDiff) {
|
||||
qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
|
||||
qTemp = (2 < qTemp) ? qTemp - 2 : 0;
|
||||
mul64To128(bSig, qTemp, &term0, &term1);
|
||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
||||
shortShift128Left(aSig0, aSig1, 62, &aSig0, &aSig1);
|
||||
}
|
||||
expDiff += 64;
|
||||
if (0 < expDiff) {
|
||||
qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
|
||||
qTemp = (2 < qTemp) ? qTemp - 2 : 0;
|
||||
qTemp >>= 64 - expDiff;
|
||||
mul64To128(bSig, qTemp << (64 - expDiff), &term0, &term1);
|
||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
||||
shortShift128Left(0, bSig, 64 - expDiff, &term0, &term1);
|
||||
while (le128(term0, term1, aSig0, aSig1)) {
|
||||
++qTemp;
|
||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
||||
}
|
||||
}
|
||||
return
|
||||
normalizeRoundAndPackFloatx80(
|
||||
80, zSign, bExp + expDiff, aSig0, aSig1, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the mantissa of the extended double-precision floating-point
|
||||
| value `a'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 floatx80_getman(floatx80 a, float_status *status)
|
||||
{
|
||||
flag aSign;
|
||||
int32_t aExp;
|
||||
uint64_t aSig;
|
||||
|
||||
aSig = extractFloatx80Frac(a);
|
||||
aExp = extractFloatx80Exp(a);
|
||||
aSign = extractFloatx80Sign(a);
|
||||
|
||||
if (aExp == 0x7FFF) {
|
||||
if ((uint64_t) (aSig << 1)) {
|
||||
return propagateFloatx80NaNOneArg(a , status);
|
||||
}
|
||||
float_raise(float_flag_invalid , status);
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) {
|
||||
return packFloatx80(aSign, 0, 0);
|
||||
}
|
||||
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
|
||||
return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign,
|
||||
0x3FFF, aSig, 0, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the exponent of the extended double-precision floating-point
|
||||
| value `a' as an extended double-precision value.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 floatx80_getexp(floatx80 a, float_status *status)
|
||||
{
|
||||
flag aSign;
|
||||
int32_t aExp;
|
||||
uint64_t aSig;
|
||||
|
||||
aSig = extractFloatx80Frac(a);
|
||||
aExp = extractFloatx80Exp(a);
|
||||
aSign = extractFloatx80Sign(a);
|
||||
|
||||
if (aExp == 0x7FFF) {
|
||||
if ((uint64_t) (aSig << 1)) {
|
||||
return propagateFloatx80NaNOneArg(a , status);
|
||||
}
|
||||
float_raise(float_flag_invalid , status);
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) {
|
||||
return packFloatx80(aSign, 0, 0);
|
||||
}
|
||||
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
|
||||
return int32_to_floatx80(aExp - 0x3FFF, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Scales extended double-precision floating-point value in operand `a' by
|
||||
| value `b'. The function truncates the value in the second operand 'b' to
|
||||
| an integral value and adds that value to the exponent of the operand 'a'.
|
||||
| The operation performed according to the IEC/IEEE Standard for Binary
|
||||
| Floating-Point Arithmetic.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
|
||||
{
|
||||
flag aSign, bSign;
|
||||
int32_t aExp, bExp, shiftCount;
|
||||
uint64_t aSig, bSig;
|
||||
|
||||
aSig = extractFloatx80Frac(a);
|
||||
aExp = extractFloatx80Exp(a);
|
||||
aSign = extractFloatx80Sign(a);
|
||||
bSig = extractFloatx80Frac(b);
|
||||
bExp = extractFloatx80Exp(b);
|
||||
bSign = extractFloatx80Sign(b);
|
||||
|
||||
if (bExp == 0x7FFF) {
|
||||
if ((uint64_t) (bSig << 1) ||
|
||||
((aExp == 0x7FFF) && (uint64_t) (aSig << 1))) {
|
||||
return propagateFloatx80NaN(a, b, status);
|
||||
}
|
||||
float_raise(float_flag_invalid , status);
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
if (aExp == 0x7FFF) {
|
||||
if ((uint64_t) (aSig << 1)) {
|
||||
return propagateFloatx80NaN(a, b, status);
|
||||
}
|
||||
return packFloatx80(aSign, floatx80_infinity.high,
|
||||
floatx80_infinity.low);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) {
|
||||
return packFloatx80(aSign, 0, 0);
|
||||
}
|
||||
if (bExp < 0x3FFF) {
|
||||
return a;
|
||||
}
|
||||
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
|
||||
if (bExp < 0x3FFF) {
|
||||
return a;
|
||||
}
|
||||
|
||||
if (0x400F < bExp) {
|
||||
aExp = bSign ? -0x6001 : 0xE000;
|
||||
return roundAndPackFloatx80(status->floatx80_rounding_precision,
|
||||
aSign, aExp, aSig, 0, status);
|
||||
}
|
||||
|
||||
shiftCount = 0x403E - bExp;
|
||||
bSig >>= shiftCount;
|
||||
aExp = bSign ? (aExp - bSig) : (aExp + bSig);
|
||||
|
||||
return roundAndPackFloatx80(status->floatx80_rounding_precision,
|
||||
aSign, aExp, aSig, 0, status);
|
||||
}
|
29
target/m68k/softfloat.h
Normal file
29
target/m68k/softfloat.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Ported from a work by Andreas Grabher for Previous, NeXT Computer Emulator,
|
||||
* derived from NetBSD M68040 FPSP functions,
|
||||
* derived from release 2a of the SoftFloat IEC/IEEE Floating-point Arithmetic
|
||||
* Package. Those parts of the code (and some later contributions) are
|
||||
* provided under that license, as detailed below.
|
||||
* It has subsequently been modified by contributors to the QEMU Project,
|
||||
* so some portions are provided under:
|
||||
* the SoftFloat-2a license
|
||||
* the BSD license
|
||||
* GPL-v2-or-later
|
||||
*
|
||||
* Any future contributions to this file will be taken to be licensed under
|
||||
* the Softfloat-2a license unless specifically indicated otherwise.
|
||||
*/
|
||||
|
||||
/* Portions of this work are licensed under the terms of the GNU GPL,
|
||||
* version 2 or later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef TARGET_M68K_SOFTFLOAT_H
|
||||
#define TARGET_M68K_SOFTFLOAT_H
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status);
|
||||
floatx80 floatx80_getman(floatx80 a, float_status *status);
|
||||
floatx80 floatx80_getexp(floatx80 a, float_status *status);
|
||||
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status);
|
||||
#endif
|
@ -2871,6 +2871,7 @@ DISAS_INSN(unlk)
|
||||
tcg_gen_mov_i32(reg, tmp);
|
||||
tcg_gen_addi_i32(QREG_SP, src, 4);
|
||||
tcg_temp_free(src);
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
@ -3148,6 +3149,9 @@ DISAS_INSN(subx_mem)
|
||||
gen_subx(s, src, dest, opsize);
|
||||
|
||||
gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
|
||||
|
||||
tcg_temp_free(dest);
|
||||
tcg_temp_free(src);
|
||||
}
|
||||
|
||||
DISAS_INSN(mov3q)
|
||||
@ -3354,6 +3358,9 @@ DISAS_INSN(addx_mem)
|
||||
gen_addx(s, src, dest, opsize);
|
||||
|
||||
gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
|
||||
|
||||
tcg_temp_free(dest);
|
||||
tcg_temp_free(src);
|
||||
}
|
||||
|
||||
static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
|
||||
@ -4398,6 +4405,8 @@ DISAS_INSN(chk2)
|
||||
gen_flush_flags(s);
|
||||
gen_helper_chk2(cpu_env, reg, bound1, bound2);
|
||||
tcg_temp_free(reg);
|
||||
tcg_temp_free(bound1);
|
||||
tcg_temp_free(bound2);
|
||||
}
|
||||
|
||||
static void m68k_copy_line(TCGv dst, TCGv src, int index)
|
||||
@ -4547,6 +4556,7 @@ DISAS_INSN(moves)
|
||||
} else {
|
||||
gen_partset_reg(opsize, reg, tmp);
|
||||
}
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
switch (extract32(insn, 3, 3)) {
|
||||
case 3: /* Indirect postincrement. */
|
||||
@ -5062,6 +5072,12 @@ DISAS_INSN(fpu)
|
||||
case 0x5e: /* fdneg */
|
||||
gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
|
||||
break;
|
||||
case 0x1e: /* fgetexp */
|
||||
gen_helper_fgetexp(cpu_env, cpu_dest, cpu_src);
|
||||
break;
|
||||
case 0x1f: /* fgetman */
|
||||
gen_helper_fgetman(cpu_env, cpu_dest, cpu_src);
|
||||
break;
|
||||
case 0x20: /* fdiv */
|
||||
gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
@ -5071,6 +5087,9 @@ DISAS_INSN(fpu)
|
||||
case 0x64: /* fddiv */
|
||||
gen_helper_fddiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
case 0x21: /* fmod */
|
||||
gen_helper_fmod(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
case 0x22: /* fadd */
|
||||
gen_helper_fadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
@ -5092,6 +5111,12 @@ DISAS_INSN(fpu)
|
||||
case 0x24: /* fsgldiv */
|
||||
gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
case 0x25: /* frem */
|
||||
gen_helper_frem(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
case 0x26: /* fscale */
|
||||
gen_helper_fscale(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
case 0x27: /* fsglmul */
|
||||
gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
|
||||
break;
|
||||
@ -5537,6 +5562,7 @@ DISAS_INSN(mac)
|
||||
case 4: /* Pre-decrement. */
|
||||
tcg_gen_mov_i32(AREG(insn, 0), addr);
|
||||
}
|
||||
tcg_temp_free(loadval);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user