From 6fe335b9e98ce48c1ef6608007ef406f4038c10a Mon Sep 17 00:00:00 2001 From: tevorbl <38593695+tevorbl@users.noreply.github.com> Date: Tue, 2 Jun 2020 13:00:03 +0100 Subject: [PATCH] another fix for printf(float) on m68k platform bug caused by this instruction: fmove.l fp0,d0 problem was caused by a conflict between the fpu emulator (softfloat) and the compiler. the emulator implemented this as a purely arithmetic move & conversion, but the compiler assumed that the result could be interpreted as a logical (ie unsigned) conversion. rightly or wrongly. for example, if fp0 contained the value 2576980377.0 which is unsigned integer -1717987328 the emulator would treat this as an integer overflow and move 0x7fffffff (INT_MAX) into d0. The complier on the other hand would assume that d0 contained 2576980377 (the unsigned value). I don't know which is correct, but this is my fix for the time being. --- plat/linux68k/emu/musashi/softfloat/softfloat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/linux68k/emu/musashi/softfloat/softfloat.c b/plat/linux68k/emu/musashi/softfloat/softfloat.c index e2bad5963..4669b08a9 100644 --- a/plat/linux68k/emu/musashi/softfloat/softfloat.c +++ b/plat/linux68k/emu/musashi/softfloat/softfloat.c @@ -95,7 +95,7 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ ) if ( zSign ) z = - z; if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { float_raise( float_flag_invalid ); - return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + return z /* zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF*/; } if ( roundBits ) float_exception_flags |= float_flag_inexact; return z; @@ -146,9 +146,9 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) if ( z && ( ( z < 0 ) ^ zSign ) ) { overflow: float_raise( float_flag_invalid ); - return - zSign ? (sbits64) LIT64( 0x8000000000000000 ) - : (sbits64)( 0x7FFFFFFFFFFFFFFF ); + return z + /* zSign ? (sbits64) LIT64( 0x8000000000000000 ) + : (sbits64)( 0x7FFFFFFFFFFFFFFF )*/; } if ( absZ1 ) float_exception_flags |= float_flag_inexact; return z;