bugAVR C Runtime Library - Bugs: bug #57071, Fix math.h and function names that...

 
 

bug #57071: Fix math.h and function names that block 64-bit double

Submitted by:  Georg-Johann Lay <gjlayde>
Submitted on:  Thu 17 Oct 2019 07:10:37 AM UTC  
 
Category:  None Severity:  3 - Normal
Priority:  5 - Normal Item Group:  None
Status:  None Percent Complete:  0%
Assigned to:  None Open/Closed:  Open
Release:  2.0.0 Fixed Release:  None

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

( Jump to the original submission)

Fri 17 Jan 2020 10:52:34 AM UTC, comment #13: 

comment #12:

> Here is a small addendum which fixes some problems that I ran into when building avr-libc with avr-gcc v3.4.6:


Note: Just the fact that current avr-libc can be built with avr-gcc v3.4.6 does not mean the result is usable in any way.  Modern avr-libc drags device properties from avr-gcc's built-in macros like __AVR_HAVE_JMP_CALL__ which archaic avr-gcc does not define.

Georg-Johann Lay <gjlayde>
Thu 16 Jan 2020 03:58:00 PM UTC, comment #12: 

Here is a small addendum which fixes some problems that I ran into when building avr-libc with avr-gcc v3.4.6:

1) The compiler might not recognize -Wno-sign-compare or -Wno-maybe-uninitialized which are used to silence some build warnings.

2) Old GCC does not built-in define __SIZEOF_DOUBLE__ and __SIZEOF_LONG_DOUBLE__, hence do it by hand.

(file #48240)

Georg-Johann Lay <gjlayde>
Mon 09 Dec 2019 05:34:39 PM UTC, comment #11: 

Hi, here is an updated version of the patch.  Compared to the patch proposed in comment #10, it fixes the vfprintf issues:

  • Treat %f like %lf, same for other float printers.  If double is 64 bits, it will only print "?".
  • Support %Lf for long double, same for other float printers.  If long double is 64 bits, it will only print "?".

(file #48029)

Georg-Johann Lay <gjlayde>
Wed 27 Nov 2019 04:51:30 PM UTC, comment #10: 

Here is an updated version of the patch with the following changes:

  • It also defines alias symbols for long double provided long double = float.
  • It provides long double prototypes in math.h.
  • Adds a new file common/alias.h which defines layout-dependent alias macros (C + Asm).
  • Turns double into float in the C-part of the lib (dtostr[ef], vfprintf, atof, ...).
  • vfprintf depends on sizeof ([long] double) and distinguishes between %lf and %f if their layouts differ.  However, we are running out of flags (which are currently 8 at most).
  • It fixes abs / labs implementation so they do no more conflict with stdlib.h.
  • Fixes a bunch of unrelated build warnings so it can be built with CFLAGS=-Werror

(file #47938)

Georg-Johann Lay <gjlayde>
Fri 08 Nov 2019 08:31:47 AM UTC, comment #9: 

The GCC feature is upstream: https://gcc.gnu.org/r277908

The new configure options are:

--with-double={32|64|32,64|64,32}
--with-long-double={32|64|32,64|64,32|double}

For a documentation, see

https://gcc.gnu.org/install/configure.html#avr

Only 14 of the 20 combinations are valid, resulting in 12 different configurations total.  Depending on the configuration, there will be up to 57 = 3*19 multilib variants.

The new compiler options are:

-mdouble={32|64}
-mlong-double={32|64}

For a documentation, see

https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html#index-mdouble

To display the mapping between option sets and multilib variants, use

avr-gcc -print-multi-lib

To show which multilib variant is actually picked for a specific set of options, use

avr-gcc -print-multi-directory <options>

To factor out different floating-point layouts in a target program, you can use -- like always -- the built-in defines

__SIZEOF_DOUBLE__
__SIZEOF_LONG_DOUBLE__

The libgcc build just copies the double64 and long-double64 multilib variants from the vanilla one so that the build times won't go through the roof -- these variants would not contain any differences to the vanilla version, anyway.

There is also the (undocumented, avr) configure option --with-fixed-point=no which skips the build of the thousands of libgcc fixed-point modules.  You can use this during development for sane build times.

Georg-Johann Lay <gjlayde>
Fri 25 Oct 2019 03:52:54 PM UTC, comment #8: 

FYI, there is the according GCC issue + patch

http://gcc.gnu.org/PR92055

From the doc of https://gcc.gnu.org/bugzilla/attachment.cgi?id=47114&action=diff

+@item -mdouble=@var{bits}
+@opindex mdouble
+Set the size (in bits) of the @code{double} type.  Valid values for
+@var{bits} are 32 and 64. This option is only available if the compiler
+is configured with @code{--with-double=32} or with @code{--with-double=64},
+and the argument of @code{--with-double=} specifies the default layout of
+@code{double}.
+
+@item -mlong-double=@var{bits}
+@opindex mlong-double
+Set the size (in bits) of the @code{long double} type.  Valid values for
+@var{bits} are 32 and 64. This option is only available if the compiler
+is configured with @code{--with-long-double=32} or with
+@code{--with-long-double=64}, and the argument of @code{--with-long-double=}
+specifies the default layout of @code{long double}.

Georg-Johann Lay <gjlayde>
Fri 25 Oct 2019 07:18:01 AM UTC, comment #7: 

comment #6:

> The current patch is supposed to be a no-op, so that
> no observable effect should occur.


There are observable effects actually:  The patch should also result in the resolution of bug #49984.

Georg-Johann Lay <gjlayde>
Fri 25 Oct 2019 07:15:16 AM UTC, comment #6: 

comment #5:

> Thanks for the explanation.
>
> I think I'll apply the patch then as is by now, and we might
> add some words about the usage later on, when the configuration
> is settled.


Great.  The current patch is supposed to be a no-op, so that no observable effect should occur.

Georg-Johann Lay <gjlayde>
Thu 24 Oct 2019 05:57:13 PM UTC, comment #5: 

Thanks for the explanation.

I think I'll apply the patch then as is by now, and we might add some words about the usage later on, when the configuration is settled.

Joerg Wunsch <joerg_wunsch>
Project Administrator
Thu 24 Oct 2019 02:26:48 PM UTC, comment #4: 

comment #3:

> Curious, what's the compiler switch to select 32- vs. 64-bit double? I'd like to add a bit of documentation about the entire topic as well.


I didn't settle on an interface yet, my preferred choice would be configure options

--with-double=[32|64]
--with-long-double=[32|64]

where --with-double= triggers availability of, say, -mdouble64 and also sets the default: --with-double=32 would make 64-bit double available, but the default would still be double=float.

But the problem is not with the (configure) option(s), it's the extension of the multilib space:

We currently have float/double/long-double = 32/32/32, and with the new multilib variants we'd also have 32/32/64 and 32/64/64.  This would mean blowing up the number of multilibs to 57 or beyond...

For libgcc I am using a hack to copy the [long-]double multilibs from the traditional one so that the build-times don't go up.  This works because the multilibs are the same: double=64 vs. double=32 is accomplished by referencing __adddf3 instead of __addsf3, not by a different implementation of __adddf3.

For libc, there are only changes in a few places:

  • How and if symbol aliases are provided (i.e. the topic of this issue).
  • How printf et al. interprets %f, %lf, %g etc.
  • For any functions that use open-coded [long-]double like dtostre (which is ftostre actually).  We can implement this as ftostre and provide an alias or a prototype with asm name depending on double layout.
  • And of course the multilib structure.  I still have no clue how to integrate `avr-gcc --print-multi-lib` into the configure process and how to make use of `avr-gcc --print-multi-directory --mmcu=MMCU ...`.  This would be very much appreciated in order to make avr-libc more independent of avr-gcc's version, multilib-structure and multilib-options.  Ideas?
Georg-Johann Lay <gjlayde>
Wed 23 Oct 2019 08:45:12 PM UTC, comment #3: 

Thanks, something "auto-configuring" like the second patch is much appreciated.

Curious, what's the compiler switch to select 32- vs. 64-bit double? I'd like to add a bit of documentation about the entire topic as well.

Joerg Wunsch <joerg_wunsch>
Project Administrator
Fri 18 Oct 2019 01:54:49 PM UTC, comment #2: 

Here is a version without __asm(symbol) that defines a symbol for double only if sizeof(double) == sizeof(float).

        * include/math.h
        (cosf, sinf, tanf, fmodf, modff, sqrtf, cbrtf, hypotf, squaref)
        (floorf, ceilf, frexpf, ldexpf, expf, coshf, sinhf, tanhf, asinf)
        (acosf, atanf, atan2f, logf, log10f, powf, isnanf, isinff)
        (signbitf, fdimf, fmaf, fmaxf, fmin, truncf, roundf, lroundf)
        (lrintf): Turn from macro to proper prototype.
        (fabs, fabsf, isfinite, isfinitef, copysign, copysignf): Implement.

        * libm/fplib/asmdef.h (ALIAS_ENTRY): Remove.
        (ENTRY_DOUBLE32): New .macro that only defines the symbol
        if __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__.
        * libm/fplib/acos.S: Use correct names for functions that deal
        with float, e.g. acosf instead of acos.  Provide double symbol
        only if __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__.
        * libm/fplib/asin.S: Same.
        * libm/fplib/atan.S: Same.
        * libm/fplib/atan2.S: Same.
        * libm/fplib/cbrt.S: Same.
        * libm/fplib/ceil.S: Same.
        * libm/fplib/copysign.S: Same.
        * libm/fplib/cos.S: Same.
        * libm/fplib/cosh.S: Same.
        * libm/fplib/exp.S: Same.
        * libm/fplib/fdim.S: Same.
        * libm/fplib/floor.S: Same.
        * libm/fplib/fma.S: Same.
        * libm/fplib/fmax.S: Same.
        * libm/fplib/fmin.S: Same.
        * libm/fplib/fmod.S: Same.
        * libm/fplib/fp_arccos.S: Same.
        * libm/fplib/frexp.S: Same.
        * libm/fplib/hypot.S: Same.
        * libm/fplib/isfinite.S: Same.
        * libm/fplib/isinf.S: Same.
        * libm/fplib/isnan.S: Same.
        * libm/fplib/ldexp.S: Same.
        * libm/fplib/log.S: Same.
        * libm/fplib/log10.S: Same.
        * libm/fplib/lrint.S: Same.
        * libm/fplib/lround.S: Same.
        * libm/fplib/modf.S: Same.
        * libm/fplib/pow.S: Same.
        * libm/fplib/round.S: Same.
        * libm/fplib/signbit.S: Same.
        * libm/fplib/sin.S: Same.
        * libm/fplib/sinh.S: Same.
        * libm/fplib/sqrt.S: Same.
        * libm/fplib/square.S: Same.
        * libm/fplib/tan.S: Same.
        * libm/fplib/tanh.S: Same.
        * libm/fplib/trunc.S: Same.

(file #47711)

Georg-Johann Lay <gjlayde>
Thu 17 Oct 2019 08:30:43 AM UTC, comment #1: 

        * include/math.h
        (cos, sin, tan, fmod, modf, sqrt, cbrt, hypot, square, floor, ceil)
        (frexp, ldexp, exp, cosh, sinh, tanh, asin, acos, atan, atan2)
        (log, log10, pow, isnan, isinf, signbit, fdim, fma, fmax, fmin)
        (trunc, round, lround, lrint) [double=64-bit]: Provide double
        prototypes.
        [double=32-bit]: Provide protos with assembler names which are
        the corresponding float function name.

        (cosf, sinf, tanf, fmodf, modff, sqrtf, cbrtf, hypotf, squaref)
        (floorf, ceilf, frexpf, ldexpf, expf, coshf, sinhf, tanhf, asinf)
        (acosf, atanf, atan2f, logf, log10f, powf, isnanf, isinff)
        (signbitf, fdimf, fmaf, fmaxf, fmin, truncf, roundf, lroundf)
        (lrintf):
        Turn from macro to proper prototype.
        (fabs, fabsf, isfinite, isfinitef, copysign, copysignf): Implement.

libm/fplib/
        * libm/fplib/acos.S: Use correct names for functions that deal
        with float, e.g. acosf instead of acos.  Adjust comments.
        * libm/fplib/asin.S: Same.
        * libm/fplib/atan.S: Same.
        * libm/fplib/atan2.S: Same.
        * libm/fplib/cbrt.S: Same.
        * libm/fplib/ceil.S: Same.
        * libm/fplib/copysign.S: Same.
        * libm/fplib/cos.S: Same.
        * libm/fplib/cosh.S: Same.
        * libm/fplib/exp.S: Same.
        * libm/fplib/fdim.S: Same.
        * libm/fplib/floor.S: Same.
        * libm/fplib/fma.S: Same.
        * libm/fplib/fmax.S: Same.
        * libm/fplib/fmin.S: Same.
        * libm/fplib/fmod.S: Same.
        * libm/fplib/fp_arccos.S: Same.
        * libm/fplib/frexp.S: Same.
        * libm/fplib/hypot.S: Same.
        * libm/fplib/isfinite.S: Same.
        * libm/fplib/isinf.S: Same.
        * libm/fplib/isnan.S: Same.
        * libm/fplib/ldexp.S: Same.
        * libm/fplib/log.S: Same.
        * libm/fplib/log10.S: Same.
        * libm/fplib/lrint.S: Same.
        * libm/fplib/lround.S: Same.
        * libm/fplib/modf.S: Same.
        * libm/fplib/pow.S: Same.
        * libm/fplib/round.S: Same.
        * libm/fplib/signbit.S: Same.
        * libm/fplib/sin.S: Same.
        * libm/fplib/sinh.S: Same.
        * libm/fplib/sqrt.S: Same.
        * libm/fplib/square.S: Same.
        * libm/fplib/tan.S: Same.
        * libm/fplib/tanh.S: Same.
        * libm/fplib/trunc.S: Same.

(file #47705)

Georg-Johann Lay <gjlayde>
Thu 17 Oct 2019 07:10:37 AM UTC, original submission:  

Implementation of math.h / libm currently blocks 64-bit double, namely:

1) Function names are wrong, e.g. 32-bit implementation of sine is named "sin", not "sinf".

2) There are "aliases" in math.h (macros actually) that define the float version (like "sinf") to the double version (like "sin").  Problem is that this:

2a) This is the wrong way round ("sin" should be alias of "sinf").

2b) There are no proper prototypes.

2c) Macros are bad, e.g. in C++ when some class implements a method for which math.h defines a macro, C++ functions / methods are silently renamed.

3) math.h is unconditional, i.e. treats double != float just like double = float.

Georg-Johann Lay <gjlayde>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #48240:  math64-addend1.diff added by gjlayde (3KiB - text/x-patch - Addendum patch.)
file #48029:  math64-3.diff added by gjlayde (73KiB - text/x-patch - math-3.diff: vfprintf works as expected now.)
file #47938:  math64-2.diff added by gjlayde (72KiB - text/x-patch - Updated version with long double and C-parts.)
file #47711:  math64-syms.diff added by gjlayde (52KiB - text/x-patch)
file #47705:  math64.diff added by gjlayde (53KiB - text/x-patch - Proposed patch.)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by joerg_wunsch (Posted a comment)
  • -email is unavailable- added by gjlayde (Submitted the item)
  •  

     

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-01-16 gjlayde Attached File- => Added math64-addend1.diff, #48240
    2019-12-09 gjlayde Attached File- => Added math64-3.diff, #48029
    2019-11-27 gjlayde Attached File- => Added math64-2.diff, #47938
    2019-10-18 gjlayde Attached File- => Added math64-syms.diff, #47711
    2019-10-17 gjlayde Attached File- => Added math64.diff, #47705

    Back to the top


    Powered by Savane 3.5