This changes the implementation of the Value attribute for floating-point types not to use exponentiation to compute the final value, at least for the common bases 2, 4, 8, 10 and 16. The powers of two use the Scaling attribute instead, while a precomputed table of powers is used for 10.
The first reason is that exponentiation is implemented under the hood in Long_Long_Float and we want to avoid using it for Float and Long_Float. The second reason is that the implemetation of exponentiation is not accurage enough for large exponents in Long_Long_Float. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * Makefile.rtl (GNATRTL_NONTASKING_OBJS): Likewise. * exp_imgv.adb (Expand_Value_Attribute): Use RE_Value_Long_Float in lieu of RE_Value_Long_Long_Float as fallback for fixed-point types. Also use it for Long_Long_Float if it has same size as Long_Float. * libgnat/s-imgrea.adb: Replace Powten_Table with Powen_LLF. * libgnat/s-powflt.ads: New file. * libgnat/s-powlfl.ads: Likewise. * libgnat/s-powtab.ads: Rename to... * libgnat/s-powllf.ads: ...this. * libgnat/s-valflt.ads: Add with clause for System.Powten_Flt and pass its table as actual parameter to System.Val_Real. * libgnat/s-vallfl.ads: Likewise for System.Powten_LFlt. * libgnat/s-valllf.ads: Likewise for System.Powten_LLF. * libgnat/s-valrea.ads: Add Maxpow and Powten_Address parameters. * libgnat/s-valrea.adb: Add pragma Warnings (Off). (Need_Extra): New boolean constant. (Precision_Limit): Set it according to Need_Extra. (Impl): Adjust actual parameter. (Integer_to_Rea): Add assertion on the machine radix. Take into account the extra digit only if Need_Extra is true. Reimplement the computation of the final value for bases 2, 4, 8, 10 and 16. * libgnat/s-valued.adb (Impl): Adjust actual parameter. (Scan_Decimal): Add pragma Unreferenced. (Value_Decimal): Likewise. * libgnat/s-valuef.adb (Impl): Adjust actual parameter. * libgnat/s-valuer.ads (Floating): Remove. (Round): New formal parameter. * libgnat/s-valuer.adb (Round_Extra): New procedure. (Scan_Decimal_Digits): Use it to round the extra digit if Round is set to True in the instantiation. (Scan_Integral_Digits): Likewise.
patch.diff.gz
Description: application/gzip