This changes the implementation of output operations for floating-point
types from using Long_Long_Float for all floating-point types to using
a base type tailored to the type being operated on.

This comprises adjusting Ada.Text_IO.Float_IO and Ada.Text_IO.Complex_IO
to the new approach, as well as sibling packages in the Ada.Wide_Text_IO
and Ada.Wide_Wide_Text_IO hierarchies.

The main issue is the loss of precision in Float (and Long_Float for x86)
so the computations are performed in double precision internally by using
a small generic package implementing a classical "double-double" library.
This means that the precision loss is minimal for Float (12 vs 15 digits)
and that the precision doubles for Long_Float (30 vs 15 digits); in both
cases this is twice the precision required by the Image attribute.

The input routines are also changed to use this double precision, which
finally guarantees correct rounding (0.5ulp) for the Value attribute of
the Float and Long_Float types.

The patch also changes the fallback path of fixed-point support routines
to use Long_Float instead of Long_Long_Float, so as to avoid the x87 FPU
and to yield the same results on all architectures.

In order to avoid breaking backward compatibility with user code, the
System.Img_Real package is preserved as a forwarder to System.Img_LLF.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * Makefile.rtl (GNATRTL_NONTASKING_OBJS): Add s-dourea, s-imager,
        s-imgflt, s-imglfl and s-imgllf.
        (LIBGNAT_TARGET_PAIRS) [PowerPC/VxWorks]: Use s-dorepr__fma.adb.
        (LIBGNAT_TARGET_PAIRS) [PowerPC/VxWorksAE]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [Aarch64/VxWorks]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [Aarch64/QNX]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [Aarch64/FreeBSD]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [PowerPC/Linux]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [Aarch64/Linux]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [IA-64/Linux]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [IA-64/HP-UX]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [RISC-V/Linux]: Likewise.
        (LIBGNAT_TARGET_PAIRS) [PowerPC/Darwin]: Likewise.
        * exp_attr.adb (Expand_N_Attribute_Reference) [Attribute_Fore]: Use
        Fixed suffix and Long_Float type.
        * exp_imgv.adb (Expand_Image_Attribute): For floating-point types,
        use the routine of the corresponding root type.  For ordinary fixed
        point types, use Fixed suffix and Long_Float type.
        (Expand_Value_Attribute): Revert latest change for Long_Long_Float.
        * gcc-interface/Make-lang.in (GNAT_ADA_OBJS): Remove libgnat units
        g-hesora.o and s-imgenu.o, add g-heasor.o, g-table.o and s-pehage.o.
        (GNATBIND_OBJS): Remove libgnat unit s-imgenu.o.
        * rtsfind.ads (RTU_Id): Add System_Img_Flt, System_Img_LFlt and
        System_Img_LLF.  Remove System_Img_Real.
        (RE_Id): Rename RE_Fore_Real to RE_Fore_Fixed.  Add RE_Image_Float,
        RE_Image_Long_Float and RE_Image_Long_Long_Float.  Rename
        RE_Image_Ordinary_Fixed_Point to RE_Image_Fixed.
        (RE_Unit_Table): Adjust to above changes.
        * libgnat/a-nbnbre.adb (Fixed_Conversions): Use Long_Float instead
        of Long_Long_Float.
        * libgnat/a-textio.ads (Field): Remove obsolete comment.
        * libgnat/a-ticoau.ads (Aux): Adjust ancestor package.
        * libgnat/a-ticoau.adb: Remove with/use clause for System.Img_Real.
        (Puts): Call Aux.Set_Image instead of Set_Image_Real.
        * libgnat/a-ticoio.adb: Add with/use clauses for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Scalar_Float): Add third actual parameter.
        (Scalar_Long_Float): Likewise.
        (Scalar_Long_Long_Float): Likewise.
        * libgnat/a-tifiio.adb: Add with/use clauses for System.Img_LFlt
        and System.Val_LFlt.  Remove the one for System.Val_LLF.  Replace
        Long_Long_Float with Long_Float throughout.
        * libgnat/a-tifiio__128.adb: Likewise.
        * libgnat/a-tiflau.ads: Add Set_Image formal parameter.
        * libgnat/a-tiflau.adb: Add with/use clause for System.Img_Util,
        remove the one for System.Img_Real.
        (Put): Call Set_Image instead of Set_Image_Real.
        (Puts): Likewise.
        * libgnat/a-tiflio.adb: Add with/use clause for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Aux_Float): Add third actual parameter.
        (Aux_Long_Float): Likewise.
        (Aux_Long_Long_Float): Likewise.
        * libgnat/a-witeio.ads (Field): Remove obsolete comment.
        * libgnat/a-wtcoau.ads (Aux): Adjust ancestor package.
        * libgnat/a-wtcoau.adb: Remove with/use clause for System.Img_Real.
        (Puts): Call Aux.Set_Image instead of Set_Image_Real.
        * libgnat/a-wtcoio.adb: Add with/use clauses for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Scalar_Float): Add third actual parameter.
        (Scalar_Long_Float): Likewise.
        (Scalar_Long_Long_Float): Likewise.
        * libgnat/a-wtfiio.adb: Add with/use clauses for System.Img_LFlt
        and System.Val_LFlt.  Remove the one for System.Val_LLF.  Replace
        Long_Long_Float with Long_Float throughout.
        * libgnat/a-wtfiio__128.adb: Likewise.
        * libgnat/a-wtflau.ads: Add Set_Image formal parameter.
        * libgnat/a-wtflau.adb: Add with/use clause for System.Img_Util,
        remove the one for System.Img_Real.
        (Put): Call Set_Image instead of Set_Image_Real.
        (Puts): Likewise.
        * libgnat/a-wtflio.adb: Add with/use clause for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Aux_Float): Add third actual parameter.
        (Aux_Long_Float): Likewise.
        (Aux_Long_Long_Float): Likewise.
        * libgnat/a-ztexio.ads (Field): Remove obsolete comment.
        * libgnat/a-ztcoau.ads (Aux): Adjust ancestor package.
        * libgnat/a-ztcoau.adb: Remove with/use clause for System.Img_Real.
        (Puts): Call Aux.Set_Image instead of Set_Image_Real.
        * libgnat/a-ztcoio.adb: Add with/use clauses for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Scalar_Float): Add third actual parameter.
        (Scalar_Long_Float): Likewise.
        (Scalar_Long_Long_Float): Likewise.
        * libgnat/a-ztfiio.adb: Add with/use clauses for System.Img_LFlt
        and System.Val_LFlt.  Remove the one for System.Val_LLF.  Replace
        Long_Long_Float with Long_Float throughout.
        * libgnat/a-ztfiio__128.adb: Likewise.
        * libgnat/a-ztflau.ads: Add Set_Image formal parameter.
        * libgnat/a-ztflau.adb: Add with/use clause for System.Img_Util,
        remove the one for System.Img_Real.
        (Put): Call Set_Image instead of Set_Image_Real.
        (Puts): Likewise.
        * libgnat/a-ztflio.adb: Add with/use clause for System.Img_Flt,
        System.Img_LFlt and System.Img_LLF.
        (Aux_Float): Add third actual parameter.
        (Aux_Long_Float): Likewise.
        (Aux_Long_Long_Float): Likewise.
        * libgnat/s-dorepr.adb: New file.
        * libgnat/s-dorepr__fma.adb: Likewise.
        * libgnat/s-dourea.ads: Likewise.
        * libgnat/s-dourea.adb: Likewise.
        * libgnat/s-forrea.ads (Fore_Real): Rename into...
        (Fore_Fixed): ...this and take Long_Float parameters.
        * libgnat/s-forrea.adb (Fore_Real): Likewise.
        (Fore_Fixed): Likewise.
        * libgnat/s-imgrea.ads: Move to...
        (Set_Image_Real): Turn into mere renaming.
        * libgnat/s-imager.ads: ...here.
        (Image_Ordinary_Fixed_Point): Turn into...
        (Image_Fixed_Point): ...this.
        * libgnat/s-imgrea.adb: Add pragma No_Body.  Move to...
        * libgnat/s-imager.adb: ...here.
        (Image_Ordinary_Fixed_Point): Turn into...
        (Image_Fixed_Point): ...this.
        (Is_Negative): Replace Long_Long_Float with Num.
        (Set_Image_Real): Likewise.  Use Double_T instead of single Num
        throughout the algorithm.
        * libgnat/s-imgflt.ads: New file.
        * libgnat/s-imglfl.ads: Likewise.
        * libgnat/s-imgllf.ads: Likewise.
        * libgnat/s-imagef.ads: Adjust comment.
        * libgnat/s-imguti.ads (Max_Real_Image_Length): New named number.
        * libgnat/s-powflt.ads (Maxpow): Adjust.
        (Powten): Turn into an exact table of double Float.
        * libgnat/s-powlfl.ads (Maxpow): Adjust.
        (Powten): Turn into an exact table of double Long_Float.
        * libgnat/s-powllf.ads (Maxpow): Adjust.
        (Powten): Turn into an exact table of double Long_Long_Float.
        * libgnat/s-valrea.ads: Change order of formal parameters.
        * libgnat/s-valrea.adb: Add with clause for System.Double_Real.
        (Double_Real): New instantiation.
        (Fast2Sum): Delete.
        (Large_Powten): New function.
        (Integer_to_Real): Use Quick_Two_Sum instead of Fast2Sum.  Convert
        the value to Double_T.  Do the scaling in Double_T for base 10.
        * libgnat/s-valflt.ads: Remove with/use clasue for Interfaces,
        add it for System.Unsigned_Types.  Use Unsigned.
        * libgnat/s-vallfl.ads: Remove with/use clasue for Interfaces,
        add it for System.Unsigned_Types.  Use Long_Unsigned.
        * libgnat/s-valllf.ads: Remove with/use clasue for Interfaces,
        add it for System.Unsigned_Types.  Use Long_Long_Unsigned.

Attachment: patch.diff.gz
Description: application/gzip

Reply via email to