Module Name: src Committed By: martin Date: Sun Dec 31 11:43:42 UTC 2017
Modified Files: src/sys/arch/alpha/alpha: fp_complete.c src/sys/lib/libkern: softfloat.c softfloat.h Log Message: PR port-alpha/52520: provide float64 -> uint64 conversion and use that when converting positive numbers. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/arch/alpha/alpha/fp_complete.c cvs rdiff -u -r1.5 -r1.6 src/sys/lib/libkern/softfloat.c cvs rdiff -u -r1.4 -r1.5 src/sys/lib/libkern/softfloat.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/alpha/alpha/fp_complete.c diff -u src/sys/arch/alpha/alpha/fp_complete.c:1.21 src/sys/arch/alpha/alpha/fp_complete.c:1.22 --- src/sys/arch/alpha/alpha/fp_complete.c:1.21 Mon May 19 07:09:10 2014 +++ src/sys/arch/alpha/alpha/fp_complete.c Sun Dec 31 11:43:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: fp_complete.c,v 1.21 2014/05/19 07:09:10 matt Exp $ */ +/* $NetBSD: fp_complete.c,v 1.22 2017/12/31 11:43:42 martin Exp $ */ /*- * Copyright (c) 2001 Ross Harvey @@ -35,7 +35,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.21 2014/05/19 07:09:10 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.22 2017/12/31 11:43:42 martin Exp $"); #include "opt_compat_osf1.h" @@ -334,7 +334,7 @@ cvt_tq_gq(uint32_t inst_bits, struct lwp inst.bits = inst_bits; stt(inst.float_detail.fb, &tfb, l); - tfc.i = float64_to_int64(tfb.i); + tfc.i = tfb.sign ? float64_to_int64(tfb.i) : float64_to_uint64(tfb.i); alpha_ldt(inst.float_detail.fc, &tfc); /* yes, ldt */ } Index: src/sys/lib/libkern/softfloat.c diff -u src/sys/lib/libkern/softfloat.c:1.5 src/sys/lib/libkern/softfloat.c:1.6 --- src/sys/lib/libkern/softfloat.c:1.5 Sun Nov 3 00:01:43 2013 +++ src/sys/lib/libkern/softfloat.c Sun Dec 31 11:43:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: softfloat.c,v 1.5 2013/11/03 00:01:43 christos Exp $ */ +/* $NetBSD: softfloat.c,v 1.6 2017/12/31 11:43:42 martin Exp $ */ /* * This version hacked for use with gcc -msoft-float by bjh21. @@ -49,7 +49,7 @@ this code that are retained. #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: softfloat.c,v 1.5 2013/11/03 00:01:43 christos Exp $"); +__RCSID("$NetBSD: softfloat.c,v 1.6 2017/12/31 11:43:42 martin Exp $"); #endif /* LIBC_SCCS and not lint */ #ifdef SOFTFLOAT_FOR_GCC @@ -211,6 +211,38 @@ static int64 roundAndPackInt64( flag zSi return z; } + +/* same as above, but for unsigned values */ +static uint64 roundAndPackUInt64( bits64 absZ0, bits64 absZ1 ) +{ + int8 roundingMode; + flag roundNearestEven, increment; + uint64 z; + + roundingMode = float_rounding_mode(); + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) absZ1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + increment = ( roundingMode == float_round_up ) && absZ1; + } + } + if ( increment ) { + ++absZ0; + if ( absZ0 == 0 ) { + float_raise( float_flag_invalid ); + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + } + z = absZ0; + if ( absZ1 ) float_set_inexact(); + return z; + +} #endif /* @@ -2399,6 +2431,44 @@ int64 float64_to_int64( float64 a ) } +/* like above, but result is unsigned */ +uint64 float64_to_uint64( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, aSigExtra; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + + if (aSign) { + return float64_to_int64(a); + } + + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + if ( shiftCount <= 0 ) { + if ( 0x43E < aExp ) { + float_raise( float_flag_invalid ); + if ( ! aSign + || ( ( aExp == 0x7FF ) + && ( aSig != LIT64( 0x0010000000000000 ) ) ) + ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + aSigExtra = 0; + aSig <<= - shiftCount; + } + else { + shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra ); + } + return roundAndPackUInt64( aSig, aSigExtra ); + +} + /* ------------------------------------------------------------------------------- Returns the result of converting the double-precision floating-point value Index: src/sys/lib/libkern/softfloat.h diff -u src/sys/lib/libkern/softfloat.h:1.4 src/sys/lib/libkern/softfloat.h:1.5 --- src/sys/lib/libkern/softfloat.h:1.4 Mon Apr 28 20:24:06 2008 +++ src/sys/lib/libkern/softfloat.h Sun Dec 31 11:43:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: softfloat.h,v 1.4 2008/04/28 20:24:06 martin Exp $ */ +/* $NetBSD: softfloat.h,v 1.5 2017/12/31 11:43:42 martin Exp $ */ /* This is a derivative work. */ @@ -229,6 +229,7 @@ int float64_to_int32( float64 ); int float64_to_int32_round_to_zero( float64 ); #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ int64_t float64_to_int64( float64 ); +uint64_t float64_to_uint64( float64 ); int64_t float64_to_int64_round_to_zero( float64 ); #endif float32 float64_to_float32( float64 );