[Ada] Add support for 128-bit fixed-point types on 64-bit platforms
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 13 Oct 2020 16:15:40 +0000 (18:15 +0200)
committerPierre-Marie de Rodat <derodat@adacore.com>
Thu, 26 Nov 2020 08:40:00 +0000 (03:40 -0500)
gcc/ada/

* Makefile.rtl (GNATRTL_NONTASKING_OBJS): Likewise.
(GNATRTL_128BIT_OBJS): Likewise.
(GNATRTL_128BIT_PAIRS): Add new 128-bit variants.
* cstand.adb (Create_Standard): Create Standard_Integer_128.
* doc/gnat_rm/implementation_defined_characteristics.rst: Document
new limits on 64-bit platforms in entry for 3.5.9(10).
* gnat_rm.texi: Regenerate.
* exp_attr.adb: Add with and use clauses for Urealp.
(Expand_N_Attribute_Reference) <Attribute_Fore>: Call new routines
for decimal fixed-point types and common ordinary fixed-point types.
* exp_ch4.adb (Real_Range_Check): Extend conversion trick to all
ordinary fixed-point types and use Small_Integer_Type_For.
* exp_fixd.adb: Add with and use clauses for Ttypes.
(Build_Divide): Add special case for 32-bit values and deal with
128-bit types.
(Build_Double_Divide): Deal with 128-bit types.
(Build_Double_Divide_Code): Likewise.  Do not apply conversions
before calling Build_Multiply.
(Build_Multiply): Likewise.  Add special case for 32-bit values.
(Build_Scaled_Divide): Deal with 128-bit types.
(Build_Scaled_Divide_Code): Likewise.  Fix size computation.  Do not
apply conversions before calling Build_Multiply.
(Do_Multiply_Fixed_Fixed): Minor tweak.
(Integer_Literal): Deal with 128-bit values.
* exp_imgv.adb (Has_Decimal_Small): Delete.
(Expand_Image_Attribute): Call new routines for common ordinary
fixed-point types.
(Expand_Value_Attribute): Likewise.
(Expand_Width_Attribute): Add new expansion for fixed-point types.
* freeze.adb (Freeze_Entity): Move error checks for ordinary
fixed-point types to...
(Freeze_Fixed_Point_Type): ...here.  Deal with 128-bit types and
adjust limitations for 32-bnt and 64-bit types.
* rtsfind.ads (RTU_Id): Add entries for new System_Fore, System_Img,
and System_Val units and remove them for obsolete units.
(RE_Id): Add entries for Double_Divide128, Scaled_Divide128, the new
Fore, Image, Value routines and remove them for obsolete units.
(RE_Unit_Table): Likewise.
* sem_ch3.adb (Decimal_Fixed_Point_Type_Declaration): Deal with
128-bit types.
* stand.ads (Standard_Entity_Type): Add Standard_Integer_128.
* uintp.ads (Uint_31): New deferred constant.
(Uint_Minus_18): Likewise.
(Uint_Minus_31): Likewise.
(Uint_Minus_76): Likewise.
(Uint_Minus_127): Likewise.
* urealp.ads (Ureal_2_31): New function.
(Ureal_2_63): Likewise.
(Ureal_2_127): Likewise.
(Ureal_2_M_127): Likewise.
(Ureal_2_10_18): Likewise.
(Ureal_M_2_10_18): Likewise.
(Ureal_9_10_36): Likewise.
(Ureal_M_9_10_36): Likewise.
(Ureal_10_76): Likewise.
(Ureal_M_10_76): Likewise.
(Ureal_10_36): Delete.
(Ureal_M_10_36): Likewise.
* urealp.adb (UR_2_10_18): New variable.
(UR_9_10_36): Likewise.
(UR_10_76): Likewise.
(UR_M_2_10_18): Likewise.
(UR_M_9_10_36): Likewise.
(UR_M_10_76): Likewise.
(UR_2_31): Likewise.
(UR_2_63): Likewise.
(UR_2_127): Likewise.
(UR_2_M_127): Likewise.
(UR_10_36): Delete.
(UR_M_10_36): Likewise.
(Initialize): Initialize them.
(UR_Write): Do not use awkward Ada literal style.
(Ureal_2_10_18): New function.
(Ureal_9_10_36): Likewise.
(Ureal_10_76): Likewise.
(Ureal_2_31): Likewise.
(Ureal_2_63): Likewise.
(Ureal_2_127): Likewise.
(Ureal_2_M_127): Likewise.
(Ureal_M_2_10_18): Likewise.
(Ureal_M_9_10_36): Likewise.
(Ureal_10_76): Likewise.
(Ureal_M_10_76): Likewise.
(Ureal_10_36): Delete.
(Ureal_M_10_36): Likewise.
* libgnat/a-decima__128.ads: New file.
* libgnat/a-tideau.ads, libgnat/a-tideau.adb: Reimplement as
generic unit.
* libgnat/a-tideio.adb: Reimplement.
* libgnat/a-tideio__128.adb: New file.
* libgnat/a-tifiau.ads, libgnat/a-tifiau.adb: New generic unit.
* libgnat/a-tifiio.adb: Move bulk of implementation to s-imagef
and reimplement.
* libgnat/a-tifiio__128.adb: New file.
* libgnat/a-tiflau.adb (Get): Minor consistency fix.
(Gets): Likewise.
* libgnat/a-wtdeau.ads, libgnat/a-wtdeau.adb: Reimplement as
generic unit.
* libgnat/a-wtdeio.adb: Reimplement.
* libgnat/a-wtdeio__128.adb: New file.
* libgnat/a-wtfiau.ads, libgnat/a-wtfiau.adb: New generic unit.
* libgnat/a-wtfiio.adb: Reimplement.
* libgnat/a-wtfiio__128.adb: New file.
* libgnat/a-ztdeau.ads, libgnat/a-ztdeau.adb: Reimplement as
generic unit.
* libgnat/a-ztdeio.adb: Reimplement.
* libgnat/a-ztdeio__128.adb: New file.
* libgnat/a-ztfiau.ads, libgnat/a-ztfiau.adb: New generic unit.
* libgnat/a-ztfiio.adb: Reimplement.
* libgnat/a-ztfiio__128.adb: New file.
* libgnat/g-rannum.adb (Random_Decimal_Fixed): Use a subtype of the
appropiate size for the instantiation.
(Random_Ordinary_Fixed): Likewise.
* libgnat/s-arit32.ads, libgnat/s-arit32.adb: New support unit.
* libgnat/s-fode128.ads: New instantiation.
* libgnat/s-fode32.ads: Likewise.
* libgnat/s-fode64.ads: Likewise.
* libgnat/s-fofi128.ads: Likewise.
* libgnat/s-fofi32.ads: Likewise.
* libgnat/s-fofi64.ads: Likewise.
* libgnat/s-fore_d.ads, libgnat/s-fore_d.adb: New generic unit.
* libgnat/s-fore_f.ads, libgnat/s-fore_f.adb: Likewise.
* libgnat/s-fore.ads, libgnat/s-fore.adb: Rename into...
* libgnat/s-forrea.ads, libgnat/s-forrea.adb: ...this.
* libgnat/s-imaged.ads, libgnat/s-imaged.adb: New generic unit.
* libgnat/s-imagef.ads, libgnat/s-imagef.adb: Likewise, taken
from a-tifiio.adb.
* libgnat/s-imde128.ads: New instantiation.
* libgnat/s-imde32.ads: Likewise.
* libgnat/s-imde64.ads: Likewise.
* libgnat/s-imfi128.ads: Likewise.
* libgnat/s-imfi32.ads: Likewise.
* libgnat/s-imfi64.ads: Likewise.
* libgnat/s-imgdec.ads, libgnat/s-imgdec.adb: Delete.
* libgnat/s-imglld.ads, libgnat/s-imglld.adb: Likewise.
* libgnat/s-imgrea.adb (Set_Image_Real): Replace Sign local variable
with Minus local variable for the sake of consistency.
* libgnat/s-imguti.ads, libgnat/s-imguti.adb: New support unit.
* libgnat/s-vade128.ads: New instantiation.
* libgnat/s-vade32.ads: Likewise.
* libgnat/s-vade64.ads: Likewise.
* libgnat/s-vafi128.ads: Likewise.
* libgnat/s-vafi32.ads: Likewise.
* libgnat/s-vafi64.ads: Likewise.
* libgnat/s-valdec.ads, libgnat/s-valdec.adb: Delete.
* libgnat/s-vallld.ads, libgnat/s-vallld.adb: Likewise.
* libgnat/s-valued.ads, libgnat/s-valued.adb: New generic unit.
* libgnat/s-valuef.ads, libgnat/s-valuef.adb: Likewise.
* libgnat/s-valuei.adb: Minor rewording.
* libgnat/s-valrea.adb: Move bulk of implementation to...
* libgnat/s-valuer.ads, libgnat/s-valuer.adb: ...here.  New
generic unit.
* libgnat/system-aix.ads (Max_Mantissa): Adjust.
* libgnat/system-darwin-arm.ads (Max_Mantissa): Likewise.
* libgnat/system-darwin-ppc.ads (Max_Mantissa): Likewise.
* libgnat/system-darwin-x86.ads (Max_Mantissa): Likewise.
* libgnat/system-djgpp.ads (Max_Mantissa): Likewise.
* libgnat/system-dragonfly-x86_64.ads (Max_Mantissa): Likewise.
* libgnat/system-freebsd.ads (Max_Mantissa): Likewise.
* libgnat/system-hpux-ia64.ads (Max_Mantissa): Likewise.
* libgnat/system-hpux.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-alpha.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-arm.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-hppa.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-ia64.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-m68k.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-mips.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-ppc.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-riscv.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-s390.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-sh4.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-sparc.ads (Max_Mantissa): Likewise.
* libgnat/system-linux-x86.ads (Max_Mantissa): Likewise.
* libgnat/system-lynxos178-ppc.ads (Max_Mantissa): Likewise.
* libgnat/system-lynxos178-x86.ads (Max_Mantissa): Likewise.
* libgnat/system-mingw.ads (Max_Mantissa): Likewise.
* libgnat/system-qnx-aarch64.ads (Max_Mantissa): Likewise.
* libgnat/system-rtems.ads (Max_Mantissa): Likewise.
* libgnat/system-solaris-sparc.ads (Max_Mantissa): Likewise.
* libgnat/system-solaris-x86.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-arm-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-arm-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-arm.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-e500-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-e500-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-e500-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-e500-vthread.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc-ravenscar.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc-vthread.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-ppc.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-x86-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-x86-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-x86-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-x86-vthread.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks-x86.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-aarch64-rtp-smp.ads (Max_Mantissa):
Likewise.
* libgnat/system-vxworks7-aarch64.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-arm-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-arm.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-e500-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-e500-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-e500-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-ppc-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-ppc-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-ppc-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-ppc64-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-ppc64-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-x86-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-x86-rtp-smp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-x86-rtp.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-x86_64-kernel.ads (Max_Mantissa): Likewise.
* libgnat/system-vxworks7-x86_64-rtp-smp.ads (Max_Mantissa): Likewise.

gcc/testsuite/

* gnat.dg/multfixed.adb: Robustify.

157 files changed:
gcc/ada/Makefile.rtl
gcc/ada/cstand.adb
gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
gcc/ada/exp_attr.adb
gcc/ada/exp_ch4.adb
gcc/ada/exp_fixd.adb
gcc/ada/exp_imgv.adb
gcc/ada/freeze.adb
gcc/ada/gnat_rm.texi
gcc/ada/libgnat/a-decima__128.ads [new file with mode: 0644]
gcc/ada/libgnat/a-tideau.adb
gcc/ada/libgnat/a-tideau.ads
gcc/ada/libgnat/a-tideio.adb
gcc/ada/libgnat/a-tideio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/a-tifiau.adb [new file with mode: 0644]
gcc/ada/libgnat/a-tifiau.ads [new file with mode: 0644]
gcc/ada/libgnat/a-tifiio.adb
gcc/ada/libgnat/a-tifiio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/a-tiflau.adb
gcc/ada/libgnat/a-wtdeau.adb
gcc/ada/libgnat/a-wtdeau.ads
gcc/ada/libgnat/a-wtdeio.adb
gcc/ada/libgnat/a-wtdeio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/a-wtfiau.adb [new file with mode: 0644]
gcc/ada/libgnat/a-wtfiau.ads [new file with mode: 0644]
gcc/ada/libgnat/a-wtfiio.adb
gcc/ada/libgnat/a-wtfiio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/a-ztdeau.adb
gcc/ada/libgnat/a-ztdeau.ads
gcc/ada/libgnat/a-ztdeio.adb
gcc/ada/libgnat/a-ztdeio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/a-ztfiau.adb [new file with mode: 0644]
gcc/ada/libgnat/a-ztfiau.ads [new file with mode: 0644]
gcc/ada/libgnat/a-ztfiio.adb
gcc/ada/libgnat/a-ztfiio__128.adb [new file with mode: 0644]
gcc/ada/libgnat/g-rannum.adb
gcc/ada/libgnat/s-arit32.adb [new file with mode: 0644]
gcc/ada/libgnat/s-arit32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fode128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fode32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fode64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fofi128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fofi32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fofi64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fore.adb [deleted file]
gcc/ada/libgnat/s-fore.ads [deleted file]
gcc/ada/libgnat/s-fore_d.adb [new file with mode: 0644]
gcc/ada/libgnat/s-fore_d.ads [new file with mode: 0644]
gcc/ada/libgnat/s-fore_f.adb [new file with mode: 0644]
gcc/ada/libgnat/s-fore_f.ads [new file with mode: 0644]
gcc/ada/libgnat/s-forrea.adb [new file with mode: 0644]
gcc/ada/libgnat/s-forrea.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imaged.adb [new file with mode: 0644]
gcc/ada/libgnat/s-imaged.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imagef.adb [new file with mode: 0644]
gcc/ada/libgnat/s-imagef.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imde128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imde32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imde64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imfi128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imfi32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imfi64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-imgdec.adb [deleted file]
gcc/ada/libgnat/s-imgdec.ads [deleted file]
gcc/ada/libgnat/s-imglld.adb [deleted file]
gcc/ada/libgnat/s-imglld.ads [deleted file]
gcc/ada/libgnat/s-imgrea.adb
gcc/ada/libgnat/s-imguti.adb [new file with mode: 0644]
gcc/ada/libgnat/s-imguti.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vade128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vade32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vade64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vafi128.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vafi32.ads [new file with mode: 0644]
gcc/ada/libgnat/s-vafi64.ads [new file with mode: 0644]
gcc/ada/libgnat/s-valdec.adb [deleted file]
gcc/ada/libgnat/s-valdec.ads [deleted file]
gcc/ada/libgnat/s-vallld.adb [deleted file]
gcc/ada/libgnat/s-vallld.ads [deleted file]
gcc/ada/libgnat/s-valrea.adb
gcc/ada/libgnat/s-valued.adb [new file with mode: 0644]
gcc/ada/libgnat/s-valued.ads [new file with mode: 0644]
gcc/ada/libgnat/s-valuef.adb [new file with mode: 0644]
gcc/ada/libgnat/s-valuef.ads [new file with mode: 0644]
gcc/ada/libgnat/s-valuei.adb
gcc/ada/libgnat/s-valuer.adb [new file with mode: 0644]
gcc/ada/libgnat/s-valuer.ads [new file with mode: 0644]
gcc/ada/libgnat/system-aix.ads
gcc/ada/libgnat/system-darwin-arm.ads
gcc/ada/libgnat/system-darwin-ppc.ads
gcc/ada/libgnat/system-darwin-x86.ads
gcc/ada/libgnat/system-djgpp.ads
gcc/ada/libgnat/system-dragonfly-x86_64.ads
gcc/ada/libgnat/system-freebsd.ads
gcc/ada/libgnat/system-hpux-ia64.ads
gcc/ada/libgnat/system-hpux.ads
gcc/ada/libgnat/system-linux-alpha.ads
gcc/ada/libgnat/system-linux-arm.ads
gcc/ada/libgnat/system-linux-hppa.ads
gcc/ada/libgnat/system-linux-ia64.ads
gcc/ada/libgnat/system-linux-m68k.ads
gcc/ada/libgnat/system-linux-mips.ads
gcc/ada/libgnat/system-linux-ppc.ads
gcc/ada/libgnat/system-linux-riscv.ads
gcc/ada/libgnat/system-linux-s390.ads
gcc/ada/libgnat/system-linux-sh4.ads
gcc/ada/libgnat/system-linux-sparc.ads
gcc/ada/libgnat/system-linux-x86.ads
gcc/ada/libgnat/system-lynxos178-ppc.ads
gcc/ada/libgnat/system-lynxos178-x86.ads
gcc/ada/libgnat/system-mingw.ads
gcc/ada/libgnat/system-qnx-aarch64.ads
gcc/ada/libgnat/system-rtems.ads
gcc/ada/libgnat/system-solaris-sparc.ads
gcc/ada/libgnat/system-solaris-x86.ads
gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads
gcc/ada/libgnat/system-vxworks-arm-rtp.ads
gcc/ada/libgnat/system-vxworks-arm.ads
gcc/ada/libgnat/system-vxworks-e500-kernel.ads
gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads
gcc/ada/libgnat/system-vxworks-e500-rtp.ads
gcc/ada/libgnat/system-vxworks-e500-vthread.ads
gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads
gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
gcc/ada/libgnat/system-vxworks-ppc-vthread.ads
gcc/ada/libgnat/system-vxworks-ppc.ads
gcc/ada/libgnat/system-vxworks-x86-kernel.ads
gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads
gcc/ada/libgnat/system-vxworks-x86-rtp.ads
gcc/ada/libgnat/system-vxworks-x86-vthread.ads
gcc/ada/libgnat/system-vxworks-x86.ads
gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-aarch64.ads
gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-arm.ads
gcc/ada/libgnat/system-vxworks7-e500-kernel.ads
gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-e500-rtp.ads
gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads
gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
gcc/ada/libgnat/system-vxworks7-x86-rtp.ads
gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
gcc/ada/rtsfind.ads
gcc/ada/sem_ch3.adb
gcc/ada/stand.ads
gcc/ada/uintp.ads
gcc/ada/urealp.adb
gcc/ada/urealp.ads
gcc/testsuite/gnat.dg/multfixed.adb

index 4774e91fbfc688160a0992939046492ced898181..97792b43e517b737fab83ee3e202e82e3ea8cb32 100644 (file)
@@ -344,6 +344,7 @@ GNATRTL_NONTASKING_OBJS= \
   a-tideio$(objext) \
   a-tienau$(objext) \
   a-tienio$(objext) \
+  a-tifiau$(objext) \
   a-tifiio$(objext) \
   a-tiflau$(objext) \
   a-tiflio$(objext) \
@@ -371,6 +372,7 @@ GNATRTL_NONTASKING_OBJS= \
   a-wtedit$(objext) \
   a-wtenau$(objext) \
   a-wtenio$(objext) \
+  a-wtfiau$(objext) \
   a-wtfiio$(objext) \
   a-wtflau$(objext) \
   a-wtflio$(objext) \
@@ -394,6 +396,7 @@ GNATRTL_NONTASKING_OBJS= \
   a-ztenau$(objext) \
   a-ztenio$(objext) \
   a-ztexio$(objext) \
+  a-ztfiau$(objext) \
   a-ztfiio$(objext) \
   a-ztflau$(objext) \
   a-ztflio$(objext) \
@@ -520,6 +523,7 @@ GNATRTL_NONTASKING_OBJS= \
   s-aomoar$(objext) \
   s-aotase$(objext) \
   s-aridou$(objext) \
+  s-arit32$(objext) \
   s-arit64$(objext) \
   s-assert$(objext) \
   s-atacco$(objext) \
@@ -599,30 +603,41 @@ GNATRTL_NONTASKING_OBJS= \
   s-finmas$(objext) \
   s-finroo$(objext) \
   s-flocon$(objext) \
-  s-fore$(objext)   \
+  s-fode32$(objext) \
+  s-fode64$(objext) \
+  s-fofi32$(objext) \
+  s-fofi64$(objext) \
+  s-fore_d$(objext) \
+  s-fore_f$(objext) \
+  s-forrea$(objext) \
   s-gearop$(objext) \
   s-genbig$(objext) \
   s-geveop$(objext) \
   s-gloloc$(objext) \
   s-htable$(objext) \
   s-imageb$(objext) \
+  s-imaged$(objext) \
+  s-imagef$(objext) \
   s-imagei$(objext) \
   s-imageu$(objext) \
   s-imagew$(objext) \
+  s-imde32$(objext) \
+  s-imde64$(objext) \
   s-imenne$(objext) \
+  s-imfi32$(objext) \
+  s-imfi64$(objext) \
   s-imgbiu$(objext) \
   s-imgboo$(objext) \
   s-imgcha$(objext) \
-  s-imgdec$(objext) \
   s-imgenu$(objext) \
   s-imgint$(objext) \
   s-imgllb$(objext) \
-  s-imglld$(objext) \
   s-imglli$(objext) \
   s-imgllu$(objext) \
   s-imgllw$(objext) \
   s-imgrea$(objext) \
   s-imguns$(objext) \
+  s-imguti$(objext) \
   s-imgwch$(objext) \
   s-imgwiu$(objext) \
   s-io$(objext)     \
@@ -736,14 +751,19 @@ GNATRTL_NONTASKING_OBJS= \
   s-utf_32$(objext) \
   s-valboo$(objext) \
   s-valcha$(objext) \
-  s-valdec$(objext) \
+  s-vade32$(objext) \
+  s-vade64$(objext) \
+  s-vafi32$(objext) \
+  s-vafi64$(objext) \
   s-valenu$(objext) \
   s-valint$(objext) \
-  s-vallld$(objext) \
   s-vallli$(objext) \
   s-valllu$(objext) \
   s-valrea$(objext) \
+  s-valued$(objext) \
+  s-valuef$(objext) \
   s-valuei$(objext) \
+  s-valuer$(objext) \
   s-valueu$(objext) \
   s-valuns$(objext) \
   s-valuti$(objext) \
@@ -885,10 +905,17 @@ TRASYM_DWARF_UNIX_OBJS = $(TRASYM_DWARF_COMMON_OBJS) s-mmauni$(objext)
 TRASYM_DWARF_MINGW_OBJS = $(TRASYM_DWARF_COMMON_OBJS)
 
 GNATRTL_128BIT_PAIRS = \
+  a-decima.ads<libgnat/a-decima__128.ads \
+  a-tideio.adb<libgnat/a-tideio__128.adb \
+  a-tifiio.adb<libgnat/a-tifiio__128.adb \
   a-tiinio.adb<libgnat/a-tiinio__128.adb \
   a-timoio.adb<libgnat/a-timoio__128.adb \
+  a-wtdeio.adb<libgnat/a-wtdeio__128.adb \
+  a-wtfiio.adb<libgnat/a-wtfiio__128.adb \
   a-wtinio.adb<libgnat/a-wtinio__128.adb \
   a-wtmoio.adb<libgnat/a-wtmoio__128.adb \
+  a-ztdeio.adb<libgnat/a-ztdeio__128.adb \
+  a-ztfiio.adb<libgnat/a-ztfiio__128.adb \
   a-ztinio.adb<libgnat/a-ztinio__128.adb \
   a-ztmoio.adb<libgnat/a-ztmoio__128.adb \
   i-cexten.ads<libgnat/i-cexten__128.ads \
@@ -903,6 +930,10 @@ GNATRTL_128BIT_OBJS = \
   s-exnllli$(objext) \
   s-expllli$(objext) \
   s-explllu$(objext) \
+  s-fode128$(objext) \
+  s-fofi128$(objext) \
+  s-imde128$(objext) \
+  s-imfi128$(objext) \
   s-imglllb$(objext) \
   s-imgllli$(objext) \
   s-imglllu$(objext) \
@@ -970,6 +1001,8 @@ GNATRTL_128BIT_OBJS = \
   s-pack125$(objext) \
   s-pack126$(objext) \
   s-pack127$(objext) \
+  s-vade128$(objext) \
+  s-vafi128$(objext) \
   s-valllli$(objext) \
   s-vallllu$(objext) \
   s-widllli$(objext) \
index fa335c101b71862db1578cbfc607d29a31c7177e..36634c796809b591fac9d53edf614bf9a9877dbc 100644 (file)
@@ -1326,6 +1326,12 @@ package body CStand is
       Set_Scope (Standard_Integer_64, Standard_Standard);
       Build_Signed_Integer_Type (Standard_Integer_64, 64);
 
+      Standard_Integer_128 := New_Standard_Entity ("integer_128");
+      Decl := New_Node (N_Full_Type_Declaration, Stloc);
+      Set_Defining_Identifier (Decl, Standard_Integer_128);
+      Set_Scope (Standard_Integer_128, Standard_Standard);
+      Build_Signed_Integer_Type (Standard_Integer_128, 128);
+
       --  Standard_*_Unsigned subtypes are not user visible, but they are
       --  used internally. They are unsigned types with the same length as
       --  the correspondingly named signed integer types.
index 14516e7d523a87502211cbca7e5f8a9a43629aa0..7dc28c2689123dfbed90e2135bbeedec1f88819b 100644 (file)
@@ -153,16 +153,26 @@ The small is the largest power of two that does not exceed the delta.
   "What combinations of small, range, and digits are
   supported for fixed point types.  See 3.5.9(10)."
 
-For an ordinary fixed point type, the small must lie in 2.0**(-80) .. 2.0**80
-and the range in -10.0**36 .. 10.0**36; any combination is permitted that
-does not result in a mantissa larger than 63 bits. However, if the mantissa
-is larger than 53 bits on machines where Long_Long_Float is 64 bits (true
-of all architectures except x86), then the output from Text_IO may be
-accurate to only 53 bits, rather than the full mantissa.  This is because
-floating-point conversions may be used to convert fixed point.
-
-For a decimal fixed point type, the small must lie in 10.0**(-18) .. 10.0**18
-and the digits in 1 .. 18.
+For an ordinary fixed point type, on 32-bit platforms, the small must lie in
+2.0**(-80) .. 2.0**80 and the range in -9.0E+36 .. 9.0E+36; any combination
+is permitted that does not result in a mantissa larger than 63 bits.
+
+On 64-bit platforms, the small must lie in 2.0**(-127) .. 2.0**127 and the
+range in -1.0E+76 .. 1.0E+76; any combination is permitted that does not
+result in a mantissa larger than 63 bits, and any combination is permitted
+that results in a mantissa between 64 and 127 bits if the small is either
+an integer or the reciprocal of an integer.
+
+If the small is either an integer or the reciprocal of an integer, which
+is the case if no ``small`` clause is provided, then the operations of the
+fixed point type are entirely implemented by means of integer instructions.
+In the other cases, some operations, in particular input and output, may be
+implemented by means of floating-point instructions and may be affected by
+accuracy issues on architectures other than x86.
+
+For a decimal fixed point type, on 32-bit platforms, the small must lie in
+1.0E-18 .. 1.0E+18 and the digits in 1 .. 18.  On 64-bit platforms, the
+small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.
 
 *
   "The result of ``Tags.Expanded_Name`` for types declared
index 436de74f557029e8e396eda4cdf5f78cc41279c2..ad47f48651f3c695463f95457ea0c755e91e468b 100644 (file)
@@ -67,6 +67,7 @@ with Tbuild;   use Tbuild;
 with Ttypes;   use Ttypes;
 with Uintp;    use Uintp;
 with Uname;    use Uname;
+with Urealp;   use Urealp;
 with Validsw;  use Validsw;
 
 package body Exp_Attr is
@@ -3615,31 +3616,124 @@ package body Exp_Attr is
 
       --  expands into
 
-      --    Result_Type (System.Fore (Universal_Real (Type'First)),
-      --                              Universal_Real (Type'Last))
+      --    System.Fore_xx (ftyp (Typ'First), ftyp (Typ'Last) [,pm])
+
+      --    For decimal fixed-point types
+      --      xx   = Decimal{32,64,128}
+      --      ftyp = Integer_{32,64,128}
+      --      pm   = Typ'Scale
+
+      --    For the most common ordinary fixed-point types
+      --      xx   = Fixed{32,64,128}
+      --      ftyp = Integer_{32,64,128}
+      --      pm   = Typ'Small
+      --             1.0 / Typ'Small
+
+      --    For other ordinary fixed-point types
+      --      xx   = Real
+      --      ftyp = Universal_Real
+      --      pm   = none
 
       --  Note that we know that the type is a nonstatic subtype, or Fore would
-      --  have itself been computed dynamically in Eval_Attribute.
+      --  have been computed statically in Eval_Attribute.
 
       when Attribute_Fore =>
-         Rewrite (N,
-           Convert_To (Typ,
-             Make_Function_Call (Loc,
-               Name                   =>
-                 New_Occurrence_Of (RTE (RE_Fore), Loc),
+         declare
+            Arg_List : List_Id;
+            Fid      : RE_Id;
+            Ftyp     : Entity_Id;
 
-               Parameter_Associations => New_List (
-                 Convert_To (Universal_Real,
-                   Make_Attribute_Reference (Loc,
-                     Prefix         => New_Occurrence_Of (Ptyp, Loc),
-                     Attribute_Name => Name_First)),
+         begin
+            if Is_Decimal_Fixed_Point_Type (Ptyp) then
+               if Esize (Ptyp) <= 32 then
+                  Fid  := RE_Fore_Decimal32;
+                  Ftyp := RTE (RE_Integer_32);
+               elsif Esize (Ptyp) <= 64 then
+                  Fid  := RE_Fore_Decimal64;
+                  Ftyp := RTE (RE_Integer_64);
+               else
+                  Fid  := RE_Fore_Decimal128;
+                  Ftyp := RTE (RE_Integer_128);
+               end if;
 
-                 Convert_To (Universal_Real,
-                   Make_Attribute_Reference (Loc,
-                     Prefix         => New_Occurrence_Of (Ptyp, Loc),
-                     Attribute_Name => Name_Last))))));
+            else
+               declare
+                  Num : constant Uint := Norm_Num (Small_Value (Ptyp));
+                  Den : constant Uint := Norm_Den (Small_Value (Ptyp));
+                  Max : constant Uint := UI_Max (Num, Den);
+                  Min : constant Uint := UI_Min (Num, Den);
+                  Siz : constant Uint := Esize (Ptyp);
 
-         Analyze_And_Resolve (N, Typ);
+               begin
+                  if Siz <= 32
+                    and then Min = Uint_1
+                    and then Max <= Uint_2 ** 31
+                  then
+                     Fid  := RE_Fore_Fixed32;
+                     Ftyp := RTE (RE_Integer_32);
+                  elsif Siz <= 64
+                    and then Min = Uint_1
+                    and then Max <= Uint_2 ** 63
+                  then
+                     Fid  := RE_Fore_Fixed64;
+                     Ftyp := RTE (RE_Integer_64);
+                  elsif System_Max_Integer_Size = 128
+                    and then Min = Uint_1
+                    and then Max <= Uint_2 ** 127
+                  then
+                     Fid  := RE_Fore_Fixed128;
+                     Ftyp := RTE (RE_Integer_128);
+                  else
+                     Fid  := RE_Fore_Real;
+                     Ftyp := Universal_Real;
+                  end if;
+               end;
+            end if;
+
+            Arg_List := New_List (
+              Convert_To (Ftyp,
+                Make_Attribute_Reference (Loc,
+                  Prefix         => New_Occurrence_Of (Ptyp, Loc),
+                  Attribute_Name => Name_First)));
+
+            Append_To (Arg_List,
+              Convert_To (Ftyp,
+                Make_Attribute_Reference (Loc,
+                  Prefix         => New_Occurrence_Of (Ptyp, Loc),
+                  Attribute_Name => Name_Last)));
+
+            --  For decimal, append Scale and also set to do literal conversion
+
+            if Is_Decimal_Fixed_Point_Type (Ptyp) then
+               Set_Conversion_OK (First (Arg_List));
+               Set_Conversion_OK (Next (First (Arg_List)));
+
+               Append_To (Arg_List,
+                 Make_Integer_Literal (Loc, Scale_Value (Ptyp)));
+
+            --  For ordinary fixed-point types, append Num, Den parameters
+            --  and also set to do literal conversion
+
+            elsif Fid /= RE_Fore_Real then
+               Set_Conversion_OK (First (Arg_List));
+               Set_Conversion_OK (Next (First (Arg_List)));
+
+               Append_To (Arg_List,
+                 Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Ptyp))));
+
+               Append_To (Arg_List,
+                 Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Ptyp))));
+            end if;
+
+            Rewrite (N,
+              Convert_To (Typ,
+                Make_Function_Call (Loc,
+                  Name                   =>
+                    New_Occurrence_Of (RTE (Fid), Loc),
+                  Parameter_Associations => Arg_List)));
+
+            Analyze_And_Resolve (N, Typ);
+         end;
 
       --------------
       -- Fraction --
index e0a62be1c48ed658419eca6eb415307587e1d383..74b8f27eaea45dad546c84d37354a96665517320 100644 (file)
@@ -11879,33 +11879,20 @@ package body Exp_Ch4 is
          --  which used to fail when Fix_Val was a bound of the type and
          --  the 'Small was not a representable number.
          --  This transformation requires an integer type large enough to
-         --  accommodate a fixed-point value. This will not be the case
-         --  in systems where Duration is larger than Long_Integer.
+         --  accommodate a fixed-point value.
 
          if Is_Ordinary_Fixed_Point_Type (Target_Type)
            and then Is_Floating_Point_Type (Etype (Expr))
-           and then RM_Size (Btyp) <= RM_Size (Standard_Long_Integer)
+           and then RM_Size (Btyp) <= System_Max_Integer_Size
            and then Nkind (Lo) = N_Real_Literal
            and then Nkind (Hi) = N_Real_Literal
          then
             declare
                Expr_Id : constant Entity_Id := Make_Temporary (Loc, 'T', Conv);
-               Int_Type : Entity_Id;
+               Int_Typ : constant Entity_Id :=
+                           Small_Integer_Type_For (RM_Size (Btyp), False);
 
             begin
-               --  Find an integer type of the appropriate size to perform an
-               --  unchecked conversion to the target fixed-point type.
-
-               if RM_Size (Btyp) > RM_Size (Standard_Integer) then
-                  Int_Type := Standard_Long_Integer;
-
-               elsif RM_Size (Btyp) > RM_Size (Standard_Short_Integer) then
-                  Int_Type := Standard_Integer;
-
-               else
-                  Int_Type := Standard_Short_Integer;
-               end if;
-
                --  Generate a temporary with the integer value. Required in the
                --  CCG compiler to ensure that run-time checks reference this
                --  integer expression (instead of the resulting fixed-point
@@ -11915,23 +11902,23 @@ package body Exp_Ch4 is
                Insert_Action (N,
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Expr_Id,
-                   Object_Definition   => New_Occurrence_Of (Int_Type, Loc),
+                   Object_Definition   => New_Occurrence_Of (Int_Typ, Loc),
                    Constant_Present    => True,
                    Expression          =>
-                     Convert_To (Int_Type, Expression (Conv))));
+                     Convert_To (Int_Typ, Expression (Conv))));
 
                --  Create integer objects for range checking of result.
 
                Lo_Arg :=
                  Unchecked_Convert_To
-                   (Int_Type, New_Occurrence_Of (Expr_Id, Loc));
+                   (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
 
                Lo_Val :=
                  Make_Integer_Literal (Loc, Corresponding_Integer_Value (Lo));
 
                Hi_Arg :=
                  Unchecked_Convert_To
-                   (Int_Type, New_Occurrence_Of (Expr_Id, Loc));
+                   (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
 
                Hi_Val :=
                  Make_Integer_Literal (Loc, Corresponding_Integer_Value (Hi));
index 42cf626831d2193cf1ea77cb1e19136746c502c7..d6819699c0caeb7d208b5988d28a19232063d871 100644 (file)
@@ -40,6 +40,7 @@ with Sinfo;    use Sinfo;
 with Snames;   use Snames;
 with Stand;    use Stand;
 with Tbuild;   use Tbuild;
+with Ttypes;   use Ttypes;
 with Uintp;    use Uintp;
 with Urealp;   use Urealp;
 
@@ -116,9 +117,8 @@ package body Exp_Fixd is
    --  case the types need not be the same, and Build_Multiply chooses a type
    --  long enough to hold the product (i.e. twice the size of the longer of
    --  the two operand types), and both operands are converted to this type.
-   --  The Etype of the result is also set to this value. However, the result
-   --  can never overflow Integer_64, so this is the largest type that is ever
-   --  generated. On return, the resulting node is analyzed and has Etype set.
+   --  The Etype of the result is also set to this value. On return, the
+   --  resulting node is analyzed and has Etype set.
 
    function Build_Rem (N : Node_Id; L, R : Node_Id) return Node_Id;
    --  Builds an N_Op_Rem node from the given left and right operand
@@ -194,12 +194,13 @@ package body Exp_Fixd is
       V        : Uint;
       Negative : Boolean := False) return Node_Id;
    --  Given a non-negative universal integer value, build a typed integer
-   --  literal node, using the smallest applicable standard integer type. If
-   --  and only if Negative is true a negative literal is built. If V exceeds
-   --  2**63-1, the largest value allowed for perfect result set scaling
-   --  factors (see RM G.2.3(22)), then Empty is returned. The node N provides
-   --  the Sloc value for the constructed literal. The Etype of the resulting
-   --  literal is correctly set, and it is marked as analyzed.
+   --  literal node, using the smallest applicable standard integer type.
+   --  If Negative is true, then a negative literal is built. If V exceeds
+   --  2**(System_Max_Integer_Size - 1) - 1, the largest value allowed for
+   --  perfect result set scaling factors (see RM G.2.3(22)), then Empty is
+   --  returned. The node N provides the Sloc value for the constructed
+   --  literal. The Etype of the resulting literal is correctly set, and it
+   --  is marked as analyzed.
 
    function Real_Literal (N : Node_Id; V : Ureal) return Node_Id;
    --  Build a real literal node from the given value, the Etype of the
@@ -347,11 +348,12 @@ package body Exp_Fixd is
             return L;
          end if;
 
+         --  Otherwise we need to figure out the correct result type size
          --  First figure out the effective sizes of the operands. Normally
          --  the effective size of an operand is the RM_Size of the operand.
          --  But a special case arises with operands whose size is known at
          --  compile time. In this case, we can use the actual value of the
-         --  operand to get its size if it would fit signed in 8 or 16 bits.
+         --  operand to get its size if it would fit in signed 8/16/32 bits.
 
          Left_Size := UI_To_Int (RM_Size (Left_Type));
 
@@ -359,10 +361,12 @@ package body Exp_Fixd is
             declare
                Val : constant Uint := Expr_Value (L);
             begin
-               if Val < Int'(2 ** 7) then
+               if Val < Uint_2 ** 7 then
                   Left_Size := 8;
-               elsif Val < Int'(2 ** 15) then
+               elsif Val < Uint_2 ** 15 then
                   Left_Size := 16;
+               elsif Val < Uint_2 ** 31 then
+                  Left_Size := 32;
                end if;
             end;
          end if;
@@ -394,8 +398,11 @@ package body Exp_Fixd is
          elsif Rsize <= 32 then
             Result_Type := Standard_Integer_32;
 
-         else
+         elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
             Result_Type := Standard_Integer_64;
+
+         else
+            Result_Type := Standard_Integer_128;
          end if;
 
          Rnode :=
@@ -446,18 +453,17 @@ package body Exp_Fixd is
       Expr   : Node_Id;
 
    begin
-      --  If denominator fits in 64 bits, we can build the operations directly
-      --  without causing any intermediate overflow, so that's what we do.
+      --  If the denominator fits in Max_Integer_Size bits, we can build the
+      --  operations directly without causing any intermediate overflow.
 
-      if Nat'Max (Y_Size, Z_Size) <= 32 then
-         return
-           Build_Divide (N, X, Build_Multiply (N, Y, Z));
+      if 2 * Nat'Max (Y_Size, Z_Size) <= System_Max_Integer_Size then
+         return Build_Divide (N, X, Build_Multiply (N, Y, Z));
 
       --  Otherwise we use the runtime routine
 
-      --    [Qnn : Interfaces.Integer_64,
-      --     Rnn : Interfaces.Integer_64;
-      --     Double_Divide (X, Y, Z, Qnn, Rnn, Round);
+      --    [Qnn : Interfaces.Integer_{64|128};
+      --     Rnn : Interfaces.Integer_{64|128};
+      --     Double_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);
       --     Qnn]
 
       else
@@ -489,18 +495,18 @@ package body Exp_Fixd is
    -- Build_Double_Divide_Code --
    ------------------------------
 
-   --  If the denominator can be computed in 64-bits, we build
+   --  If the denominator can be computed in Max_Integer_Size bits, we build
 
    --    [Nnn : constant typ := typ (X);
    --     Dnn : constant typ := typ (Y) * typ (Z)
    --     Qnn : constant typ := Nnn / Dnn;
-   --     Rnn : constant typ := Nnn / Dnn;
+   --     Rnn : constant typ := Nnn rem Dnn;
 
-   --  If the numerator cannot be computed in 64 bits, we build
+   --  If the denominator cannot be computed in Max_Integer_Size bits, we build
 
-   --    [Qnn : typ;
-   --     Rnn : typ;
-   --     Double_Divide (X, Y, Z, Qnn, Rnn, Round);]
+   --    [Qnn : Interfaces.Integer_{64|128};
+   --     Rnn : Interfaces.Integer_{64|128};
+   --     Double_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);]
 
    procedure Build_Double_Divide_Code
      (N        : Node_Id;
@@ -514,6 +520,7 @@ package body Exp_Fixd is
       Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
       Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
 
+      QR_Id  : RE_Id;
       QR_Siz : Nat;
       QR_Typ : Entity_Id;
 
@@ -524,22 +531,36 @@ package body Exp_Fixd is
       Rnd : Entity_Id;
 
    begin
-      --  Find type that will allow computation of numerator
+      --  Find type that will allow computation of denominator
 
       QR_Siz := Nat'Max (X_Size, 2 * Nat'Max (Y_Size, Z_Size));
 
       if QR_Siz <= 16 then
          QR_Typ := Standard_Integer_16;
+         QR_Id  := RE_Null;
+
       elsif QR_Siz <= 32 then
          QR_Typ := Standard_Integer_32;
+         QR_Id  := RE_Null;
+
       elsif QR_Siz <= 64 then
          QR_Typ := Standard_Integer_64;
+         QR_Id  := RE_Null;
+
+      elsif QR_Siz <= 128 and then System_Max_Integer_Size = 128 then
+         QR_Typ := Standard_Integer_128;
+         QR_Id  := RE_Null;
 
-      --  For more than 64, bits, we use the 64-bit integer defined in
+      --  For more than Max_Integer_Size bits, we use the integer defined in
       --  Interfaces, so that it can be handled by the runtime routine.
 
-      else
+      elsif System_Max_Integer_Size < 128 then
          QR_Typ := RTE (RE_Integer_64);
+         QR_Id  := RE_Double_Divide64;
+
+      else
+         QR_Typ := RTE (RE_Integer_128);
+         QR_Id  := RE_Double_Divide128;
       end if;
 
       --  Define quotient and remainder, and set their Etypes, so
@@ -551,9 +572,9 @@ package body Exp_Fixd is
       Set_Etype (Qnn, QR_Typ);
       Set_Etype (Rnn, QR_Typ);
 
-      --  Case that we can compute the denominator in 64 bits
+      --  Case that we can compute the denominator in Max_Integer_Size bits
 
-      if QR_Siz <= 64 then
+      if QR_Siz <= System_Max_Integer_Size then
 
          --  Create temporaries for numerator and denominator and set Etypes,
          --  so that New_Occurrence_Of picks them up for Build_xxx calls.
@@ -569,16 +590,13 @@ package body Exp_Fixd is
              Defining_Identifier => Nnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression => Build_Conversion (N, QR_Typ, X)),
+             Expression          => Build_Conversion (N, QR_Typ, X)),
 
            Make_Object_Declaration (Loc,
              Defining_Identifier => Dnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression =>
-               Build_Multiply (N,
-                 Build_Conversion (N, QR_Typ, Y),
-                 Build_Conversion (N, QR_Typ, Z))));
+             Expression          => Build_Multiply (N, Y, Z)));
 
          Quo :=
            Build_Divide (N,
@@ -604,8 +622,8 @@ package body Exp_Fixd is
                  New_Occurrence_Of (Nnn, Loc),
                  New_Occurrence_Of (Dnn, Loc))));
 
-      --  Case where denominator does not fit in 64 bits, so we have to
-      --  call the runtime routine to compute the quotient and remainder
+      --  Case where denominator does not fit in Max_Integer_Size bits, we have
+      --  to call the runtime routine to compute the quotient and remainder.
 
       else
          Rnd := Boolean_Literals (Rounded_Result_Set (N));
@@ -620,7 +638,7 @@ package body Exp_Fixd is
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc)),
 
            Make_Procedure_Call_Statement (Loc,
-             Name => New_Occurrence_Of (RTE (RE_Double_Divide64), Loc),
+             Name => New_Occurrence_Of (RTE (QR_Id), Loc),
              Parameter_Associations => New_List (
                Build_Conversion (N, QR_Typ, X),
                Build_Conversion (N, QR_Typ, Y),
@@ -674,7 +692,7 @@ package body Exp_Fixd is
          --  the effective size of an operand is the RM_Size of the operand.
          --  But a special case arises with operands whose size is known at
          --  compile time. In this case, we can use the actual value of the
-         --  operand to get its size if it would fit signed in 8 or 16 bits.
+         --  operand to get its size if it would fit in signed 8/16/32 bits.
 
          Left_Size := UI_To_Int (RM_Size (Left_Type));
 
@@ -682,10 +700,12 @@ package body Exp_Fixd is
             declare
                Val : constant Uint := Expr_Value (L);
             begin
-               if Val < Int'(2 ** 7) then
+               if Val < Uint_2 ** 7 then
                   Left_Size := 8;
-               elsif Val < Int'(2 ** 15) then
+               elsif Val < Uint_2 ** 15 then
                   Left_Size := 16;
+               elsif Val < Uint_2 ** 31 then
+                  Left_Size := 32;
                end if;
             end;
          end if;
@@ -718,8 +738,11 @@ package body Exp_Fixd is
          elsif Rsize <= 32 then
             Result_Type := Standard_Integer_32;
 
-         else
+         elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
             Result_Type := Standard_Integer_64;
+
+         else
+            Result_Type := Standard_Integer_128;
          end if;
 
          Rnode :=
@@ -810,18 +833,17 @@ package body Exp_Fixd is
       Expr   : Node_Id;
 
    begin
-      --  If numerator fits in 64 bits, we can build the operations directly
-      --  without causing any intermediate overflow, so that's what we do.
+      --  If the numerator fits in Max_Integer_Size bits, we can build the
+      --  operations directly without causing any intermediate overflow.
 
-      if Nat'Max (X_Size, Y_Size) <= 32 then
-         return
-           Build_Divide (N, Build_Multiply (N, X, Y), Z);
+      if 2 * Nat'Max (X_Size, Y_Size) <= System_Max_Integer_Size then
+         return Build_Divide (N, Build_Multiply (N, X, Y), Z);
 
       --  Otherwise we use the runtime routine
 
-      --    [Qnn : Integer_64,
-      --     Rnn : Integer_64;
-      --     Scaled_Divide (X, Y, Z, Qnn, Rnn, Round);
+      --    [Qnn : Integer_{64|128},
+      --     Rnn : Integer_{64|128};
+      --     Scaled_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);
       --     Qnn]
 
       else
@@ -850,18 +872,18 @@ package body Exp_Fixd is
    -- Build_Scaled_Divide_Code --
    ------------------------------
 
-   --  If the numerator can be computed in 64-bits, we build
+   --  If the numerator can be computed in Max_Integer_Size bits, we build
 
    --    [Nnn : constant typ := typ (X) * typ (Y);
    --     Dnn : constant typ := typ (Z)
    --     Qnn : constant typ := Nnn / Dnn;
-   --     Rnn : constant typ := Nnn / Dnn;
+   --     Rnn : constant typ := Nnn rem Dnn;
 
-   --  If the numerator cannot be computed in 64 bits, we build
+   --  If the numerator cannot be computed in Max_Integer_Size bits, we build
 
-   --    [Qnn : Interfaces.Integer_64;
-   --     Rnn : Interfaces.Integer_64;
-   --     Scaled_Divide (X, Y, Z, Qnn, Rnn, Round);]
+   --    [Qnn : Interfaces.Integer_{64|128};
+   --     Rnn : Interfaces.Integer_{64|128};
+   --     Scaled_Divide_{64|128} (X, Y, Z, Qnn, Rnn, Round);]
 
    procedure Build_Scaled_Divide_Code
      (N        : Node_Id;
@@ -875,6 +897,7 @@ package body Exp_Fixd is
       Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
       Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
 
+      QR_Id  : RE_Id;
       QR_Siz : Nat;
       QR_Typ : Entity_Id;
 
@@ -887,20 +910,34 @@ package body Exp_Fixd is
    begin
       --  Find type that will allow computation of numerator
 
-      QR_Siz := Nat'Max (X_Size, 2 * Nat'Max (Y_Size, Z_Size));
+      QR_Siz := Nat'Max (2 * Nat'Max (X_Size, Y_Size), Z_Size);
 
       if QR_Siz <= 16 then
          QR_Typ := Standard_Integer_16;
+         QR_Id  := RE_Null;
+
       elsif QR_Siz <= 32 then
          QR_Typ := Standard_Integer_32;
+         QR_Id  := RE_Null;
+
       elsif QR_Siz <= 64 then
          QR_Typ := Standard_Integer_64;
+         QR_Id  := RE_Null;
 
-      --  For more than 64, bits, we use the 64-bit integer defined in
+      elsif QR_Siz <= 128 and then System_Max_Integer_Size = 128 then
+         QR_Typ := Standard_Integer_128;
+         QR_Id  := RE_Null;
+
+      --  For more than Max_Integer_Size bits, we use the integer defined in
       --  Interfaces, so that it can be handled by the runtime routine.
 
-      else
+      elsif System_Max_Integer_Size < 128 then
          QR_Typ := RTE (RE_Integer_64);
+         QR_Id  := RE_Scaled_Divide64;
+
+      else
+         QR_Typ := RTE (RE_Integer_128);
+         QR_Id  := RE_Scaled_Divide128;
       end if;
 
       --  Define quotient and remainder, and set their Etypes, so
@@ -912,9 +949,9 @@ package body Exp_Fixd is
       Set_Etype (Qnn, QR_Typ);
       Set_Etype (Rnn, QR_Typ);
 
-      --  Case that we can compute the numerator in 64 bits
+      --  Case that we can compute the numerator in Max_Integer_Size bits
 
-      if QR_Siz <= 64 then
+      if QR_Siz <= System_Max_Integer_Size then
          Nnn := Make_Temporary (Loc, 'N');
          Dnn := Make_Temporary (Loc, 'D');
 
@@ -928,16 +965,13 @@ package body Exp_Fixd is
              Defining_Identifier => Nnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression =>
-               Build_Multiply (N,
-                 Build_Conversion (N, QR_Typ, X),
-                 Build_Conversion (N, QR_Typ, Y))),
+             Expression          => Build_Multiply (N, X, Y)),
 
            Make_Object_Declaration (Loc,
              Defining_Identifier => Dnn,
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc),
              Constant_Present    => True,
-             Expression => Build_Conversion (N, QR_Typ, Z)));
+             Expression          => Build_Conversion (N, QR_Typ, Z)));
 
          Quo :=
            Build_Divide (N,
@@ -961,8 +995,8 @@ package body Exp_Fixd is
                  New_Occurrence_Of (Nnn, Loc),
                  New_Occurrence_Of (Dnn, Loc))));
 
-      --  Case where numerator does not fit in 64 bits, so we have to
-      --  call the runtime routine to compute the quotient and remainder
+      --  Case where numerator does not fit in Max_Integer_Size bits, we have
+      --  to call the runtime routine to compute the quotient and remainder.
 
       else
          Rnd := Boolean_Literals (Rounded_Result_Set (N));
@@ -977,7 +1011,7 @@ package body Exp_Fixd is
              Object_Definition   => New_Occurrence_Of (QR_Typ, Loc)),
 
            Make_Procedure_Call_Statement (Loc,
-             Name => New_Occurrence_Of (RTE (RE_Scaled_Divide64), Loc),
+             Name => New_Occurrence_Of (RTE (QR_Id), Loc),
              Parameter_Associations => New_List (
                Build_Conversion (N, QR_Typ, X),
                Build_Conversion (N, QR_Typ, Y),
@@ -1374,8 +1408,7 @@ package body Exp_Fixd is
 
          if Present (Lit_Int) then
             Set_Result (N,
-              Build_Multiply (N, Build_Multiply (N, Left, Right),
-                Lit_Int));
+              Build_Multiply (N, Build_Multiply (N, Left, Right), Lit_Int));
             return;
          end if;
 
@@ -2380,6 +2413,9 @@ package body Exp_Fixd is
       elsif V < Uint_2 ** 63 then
          T := Standard_Integer_64;
 
+      elsif V < Uint_2 ** 127 and then System_Max_Integer_Size = 128 then
+         T := Standard_Integer_128;
+
       else
          return Empty;
       end if;
index 40cb51462b8352f79c69a92af3c53419f7065b8b..d5db5b3f017abb8380ae3ed108bd7df79216e05e 100644 (file)
@@ -49,11 +49,6 @@ with Urealp;   use Urealp;
 
 package body Exp_Imgv is
 
-   function Has_Decimal_Small (E : Entity_Id) return Boolean;
-   --  Applies to all entities. True for a Decimal_Fixed_Point_Type, or an
-   --  Ordinary_Fixed_Point_Type with a small that is a negative power of ten.
-   --  Shouldn't this be in einfo.adb or sem_aux.adb???
-
    procedure Rewrite_Object_Image
      (N         : Node_Id;
       Pref      : Entity_Id;
@@ -219,21 +214,13 @@ package body Exp_Imgv is
    --      xx = Boolean
    --      tv = Boolean (Expr)
 
-   --    For signed integer types with size <= Integer'Size
-   --      xx = Integer
-   --      tv = Integer (Expr)
-
-   --    For other signed integer types
-   --      xx = Long_Long_Integer
-   --      tv = Long_Long_Integer (Expr)
-
-   --    For modular types with modulus <= System.Unsigned_Types.Unsigned
-   --      xx = Unsigned
-   --      tv = System.Unsigned_Types.Unsigned (Expr)
+   --    For signed integer types
+   --      xx = [Long_Long_[Long_]]Integer
+   --      tv = [Long_Long_[Long_]]Integer (Expr)
 
-   --    For other modular integer types
-   --      xx = Long_Long_Unsigned
-   --      tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
+   --    For modular types
+   --      xx = [Long_Long_[Long_]]Unsigned
+   --      tv = System.Unsigned_Types.[Long_Long_[Long_]]Unsigned (Expr)
 
    --    For types whose root type is Wide_Character
    --      xx = Wide_Character
@@ -249,21 +236,24 @@ package body Exp_Imgv is
    --      tv = Long_Long_Float (Expr)
    --      pm = typ'Digits (typ = subtype of expression)
 
-   --    For ordinary fixed-point types
+   --    For decimal fixed-point types
+   --      xx = Decimal{32,64,128}
+   --      tv = Integer_{32,64,128} (Expr)? [convert with no scaling]
+   --      pm = typ'Scale (typ = subtype of expression)
+
+   --    For the most common ordinary fixed-point types
+   --      xx = Fixed{32,64,128}
+   --      tv = Integer_{32,64,128} (Expr) [convert with no scaling]
+   --      pm = typ'Small (typ = subtype of expression)
+   --           1.0 / typ'Small
+   --           (Integer_{32,64,128} x typ'Small)'Fore
+   --           typ'Aft
+
+   --    For other ordinary fixed-point types
    --      xx = Ordinary_Fixed_Point
    --      tv = Long_Long_Float (Expr)
    --      pm = typ'Aft (typ = subtype of expression)
 
-   --    For decimal fixed-point types with size = Integer'Size
-   --      xx = Decimal
-   --      tv = Integer (Expr)
-   --      pm = typ'Scale (typ = subtype of expression)
-
-   --    For decimal fixed-point types with size > Integer'Size
-   --      xx = Long_Long_Decimal
-   --      tv = Long_Long_Integer?(Expr) [convert with no scaling]
-   --      pm = typ'Scale (typ = subtype of expression)
-
    --  For enumeration types other than those declared in package Standard
    --  or System, Snn, Pnn, are expanded as above, but the call looks like:
 
@@ -593,18 +583,50 @@ package body Exp_Imgv is
             Tent := RTE (RE_Long_Long_Long_Unsigned);
          end if;
 
-      elsif Is_Fixed_Point_Type (Rtyp) and then Has_Decimal_Small (Rtyp) then
-         if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
-            Imid := RE_Image_Decimal;
-            Tent := Standard_Integer;
+      elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
+         if Esize (Rtyp) <= 32 then
+            Imid := RE_Image_Decimal32;
+            Tent := RTE (RE_Integer_32);
+         elsif Esize (Rtyp) <= 64 then
+            Imid := RE_Image_Decimal64;
+            Tent := RTE (RE_Integer_64);
          else
-            Imid := RE_Image_Long_Long_Decimal;
-            Tent := Standard_Long_Long_Integer;
+            Imid := RE_Image_Decimal128;
+            Tent := RTE (RE_Integer_128);
          end if;
 
       elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
-         Imid := RE_Image_Ordinary_Fixed_Point;
-         Tent := Standard_Long_Long_Float;
+         declare
+            Num : constant Uint := Norm_Num (Small_Value (Rtyp));
+            Den : constant Uint := Norm_Den (Small_Value (Rtyp));
+            Max : constant Uint := UI_Max (Num, Den);
+            Min : constant Uint := UI_Min (Num, Den);
+            Siz : constant Uint := Esize (Rtyp);
+
+         begin
+            if Siz <= 32
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 31
+            then
+               Imid := RE_Image_Fixed32;
+               Tent := RTE (RE_Integer_32);
+            elsif Siz <= 64
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 63
+            then
+               Imid := RE_Image_Fixed64;
+               Tent := RTE (RE_Integer_64);
+            elsif System_Max_Integer_Size = 128
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 127
+            then
+               Imid := RE_Image_Fixed128;
+               Tent := RTE (RE_Integer_128);
+            else
+               Imid := RE_Image_Ordinary_Fixed_Point;
+               Tent := Standard_Long_Long_Float;
+            end if;
+         end;
 
       elsif Is_Floating_Point_Type (Rtyp) then
          Imid := RE_Image_Floating_Point;
@@ -746,29 +768,45 @@ package body Exp_Imgv is
              Prefix         => New_Occurrence_Of (Ptyp, Loc),
              Attribute_Name => Name_Digits));
 
-      --  For ordinary fixed-point types, append Aft parameter
+      --  For decimal, append Scale and also set to do literal conversion
 
-      elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
-         Append_To (Arg_List,
-           Make_Attribute_Reference (Loc,
-             Prefix         => New_Occurrence_Of (Ptyp, Loc),
-             Attribute_Name => Name_Aft));
+      elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
+         Set_Conversion_OK (First (Arg_List));
+
+         Append_To (Arg_List, Make_Integer_Literal (Loc, Scale_Value (Ptyp)));
 
-         if Has_Decimal_Small (Rtyp) then
+      --  For ordinary fixed-point types, append Num, Den, Fore, Aft parameters
+      --  and also set to do literal conversion.
+
+      elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
+         if Imid /= RE_Image_Ordinary_Fixed_Point then
             Set_Conversion_OK (First (Arg_List));
-            Set_Etype (First (Arg_List), Tent);
-         end if;
 
-      --  For decimal, append Scale and also set to do literal conversion
+            Append_To (Arg_List,
+              Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Ptyp))));
 
-      elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
-         Append_To (Arg_List,
-           Make_Attribute_Reference (Loc,
-             Prefix         => New_Occurrence_Of (Ptyp, Loc),
-             Attribute_Name => Name_Scale));
+            Append_To (Arg_List,
+              Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Ptyp))));
 
-         Set_Conversion_OK (First (Arg_List));
-         Set_Etype (First (Arg_List), Tent);
+            --  We want to compute the Fore value for the fixed point type
+            --  whose mantissa type is Tent and whose small is typ'Small.
+
+            declare
+               T : Ureal := Uint_2 ** (Esize (Tent) - 1) * Small_Value (Ptyp);
+               F : Nat   := 2;
+
+            begin
+               while T >= Ureal_10 loop
+                  F := F + 1;
+                  T := T / Ureal_10;
+               end loop;
+
+               Append_To (Arg_List,
+                  Make_Integer_Literal (Loc, UI_From_Int (F)));
+            end;
+         end if;
+
+         Append_To (Arg_List, Make_Integer_Literal (Loc, Aft_Value (Ptyp)));
 
       --  For Wide_Character, append Ada 2005 indication
 
@@ -827,35 +865,29 @@ package body Exp_Imgv is
    --    For types whose root type is Boolean
    --      xx = Boolean
 
-   --    For signed integer types with size <= Integer'Size
-   --      xx = Integer
-
-   --    For other signed integer types
-   --      xx = Long_Long_Integer
-
-   --    For modular types with modulus <= System.Unsigned_Types.Unsigned
-   --      xx = Unsigned
+   --    For signed integer types
+   --      xx = [Long_Long_[Long_]]Integer
 
-   --    For other modular integer types
-   --      xx = Long_Long_Unsigned
+   --    For modular types
+   --      xx = [Long_Long_[Long_]]Unsigned
 
-   --    For floating-point types and ordinary fixed-point types
+   --    For floating-point types
    --      xx = Real
 
-   --  For Wide_[Wide_]Character types, typ'Value (X) expands into:
+   --  For decimal fixed-point types, typ'Value (X) expands into
 
-   --    btyp (Value_xx (X, EM))
+   --    btyp?(Value_Decimal{32,64,128} (X, typ'Scale));
 
-   --  where btyp is the base type of the prefix, and EM is the encoding method
+   --  For the most common ordinary fixed-point types
 
-   --  For decimal types with size <= Integer'Size, typ'Value (X)
-   --  expands into
+   --    btyp?(Value_Fixed{32,64,128} (X, S, 1.0 / S));
+   --    where S = typ'Small
 
-   --    btyp?(Value_Decimal (X, typ'Scale));
+   --  For Wide_[Wide_]Character types, typ'Value (X) expands into:
 
-   --  For all other decimal types, typ'Value (X) expands into
+   --    btyp (Value_xx (X, EM))
 
-   --    btyp?(Value_Long_Long_Decimal (X, typ'Scale))
+   --  where btyp is the base type of the prefix, and EM is the encoding method
 
    --  For enumeration types other than those derived from types Boolean,
    --  Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
@@ -923,16 +955,15 @@ package body Exp_Imgv is
          end if;
 
       elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
-         if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
-            Vid := RE_Value_Decimal;
+         if Esize (Rtyp) <= 32 and then abs (Scale_Value (Rtyp)) <= 9 then
+            Vid := RE_Value_Decimal32;
+         elsif Esize (Rtyp) <= 64 and then abs (Scale_Value (Rtyp)) <= 18 then
+            Vid := RE_Value_Decimal64;
          else
-            Vid := RE_Value_Long_Long_Decimal;
+            Vid := RE_Value_Decimal128;
          end if;
 
-         Append_To (Args,
-           Make_Attribute_Reference (Loc,
-             Prefix => New_Occurrence_Of (Typ, Loc),
-             Attribute_Name => Name_Scale));
+         Append_To (Args, Make_Integer_Literal (Loc, Scale_Value (Rtyp)));
 
          Rewrite (N,
            OK_Convert_To (Btyp,
@@ -944,7 +975,54 @@ package body Exp_Imgv is
          Analyze_And_Resolve (N, Btyp);
          return;
 
-      elsif Is_Real_Type (Rtyp) then
+      elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
+         declare
+            Num : constant Uint := Norm_Num (Small_Value (Rtyp));
+            Den : constant Uint := Norm_Den (Small_Value (Rtyp));
+            Max : constant Uint := UI_Max (Num, Den);
+            Min : constant Uint := UI_Min (Num, Den);
+            Siz : constant Uint := Esize (Rtyp);
+
+         begin
+            if Siz <= 32
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 31
+            then
+               Vid := RE_Value_Fixed32;
+            elsif Siz <= 64
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 63
+            then
+               Vid := RE_Value_Fixed64;
+            elsif System_Max_Integer_Size = 128
+              and then Min = Uint_1
+              and then Max <= Uint_2 ** 127
+            then
+               Vid := RE_Value_Fixed128;
+            else
+               Vid := RE_Value_Real;
+            end if;
+
+            if Vid /= RE_Value_Real then
+               Append_To (Args,
+                 Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Rtyp))));
+
+               Append_To (Args,
+                 Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Rtyp))));
+
+               Rewrite (N,
+                 OK_Convert_To (Btyp,
+                   Make_Function_Call (Loc,
+                     Name => New_Occurrence_Of (RTE (Vid), Loc),
+                     Parameter_Associations => Args)));
+
+               Set_Etype (N, Btyp);
+               Analyze_And_Resolve (N, Btyp);
+               return;
+            end if;
+         end;
+
+      elsif Is_Floating_Point_Type (Rtyp) then
          Vid := RE_Value_Real;
 
       --  Only other possibility is user-defined enumeration type
@@ -1286,12 +1364,12 @@ package body Exp_Imgv is
    --      yy = Boolean
 
    --    For signed integer types
-   --      xx = Width_Long_Long_Integer
-   --      yy = Long_Long_Integer
+   --      xx = Width_[Long_Long_[Long_]]Integer
+   --      yy = [Long_Long_[Long_]]Integer
 
    --    For modular integer types
-   --      xx = Width_Long_Long_Unsigned
-   --      yy = Long_Long_Unsigned
+   --      xx = Width_[Long_Long_[Long_]]Unsigned
+   --      yy = [Long_Long_[Long_]]Unsigned
 
    --  For types derived from Wide_Character, typ'Width expands into
 
@@ -1329,7 +1407,11 @@ package body Exp_Imgv is
    --      Wide_Wide_Character (typ'First),
    --      Wide_Wide_Character (typ'Last));
 
-   --  For real types, typ'Width and typ'Wide_[Wide_]Width expand into
+   --  For fixed point types, typ'Width and typ'Wide_[Wide_]Width expand into
+
+   --    if Ptyp'First > Ptyp'Last then 0 else Ptyp'Fore + 1 + Ptyp'Aft end if
+
+   --  and for floating point types, they expand into
 
    --    if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
 
@@ -1451,9 +1533,41 @@ package body Exp_Imgv is
             YY := RTE (RE_Long_Long_Long_Unsigned);
          end if;
 
-      --  Real types
+      --  Fixed point types
 
-      elsif Is_Real_Type (Rtyp) then
+      elsif Is_Fixed_Point_Type (Rtyp) then
+         Rewrite (N,
+           Make_If_Expression (Loc,
+             Expressions => New_List (
+
+               Make_Op_Gt (Loc,
+                 Left_Opnd =>
+                   Make_Attribute_Reference (Loc,
+                     Prefix => New_Occurrence_Of (Ptyp, Loc),
+                     Attribute_Name => Name_First),
+
+                 Right_Opnd =>
+                   Make_Attribute_Reference (Loc,
+                     Prefix => New_Occurrence_Of (Ptyp, Loc),
+                     Attribute_Name => Name_Last)),
+
+               Make_Integer_Literal (Loc, 0),
+
+               Make_Op_Add (Loc,
+                 Make_Attribute_Reference (Loc,
+                   Prefix => New_Occurrence_Of (Ptyp, Loc),
+                   Attribute_Name => Name_Fore),
+
+                 Make_Op_Add (Loc,
+                   Make_Integer_Literal (Loc, 1),
+                   Make_Integer_Literal (Loc, Aft_Value (Ptyp)))))));
+
+         Analyze_And_Resolve (N, Typ);
+         return;
+
+      --  Floating point types
+
+      elsif Is_Floating_Point_Type (Rtyp) then
          Rewrite (N,
            Make_If_Expression (Loc,
              Expressions => New_List (
@@ -1680,18 +1794,6 @@ package body Exp_Imgv is
       Analyze_And_Resolve (N, Typ);
    end Expand_Width_Attribute;
 
-   -----------------------
-   -- Has_Decimal_Small --
-   -----------------------
-
-   function Has_Decimal_Small (E : Entity_Id) return Boolean is
-   begin
-      return Is_Decimal_Fixed_Point_Type (E)
-        or else
-          (Is_Ordinary_Fixed_Point_Type (E)
-             and then Ureal_10**Aft_Value (E) * Small_Value (E) = Ureal_1);
-   end Has_Decimal_Small;
-
    --------------------------
    -- Rewrite_Object_Image --
    --------------------------
index 8183252e1e30c699b88c8c790df674f2da3579a2..ce86fac56154f49189f57c6cc5bea7a1721ed684 100644 (file)
@@ -6339,35 +6339,6 @@ package body Freeze is
          if Is_Fixed_Point_Type (E) then
             Freeze_Fixed_Point_Type (E);
 
-            --  Some error checks required for ordinary fixed-point type. Defer
-            --  these till the freeze-point since we need the small and range
-            --  values. We only do these checks for base types
-
-            if Is_Ordinary_Fixed_Point_Type (E) and then Is_Base_Type (E) then
-               if Small_Value (E) < Ureal_2_M_80 then
-                  Error_Msg_Name_1 := Name_Small;
-                  Error_Msg_N
-                    ("`&''%` too small, minimum allowed is 2.0'*'*(-80)", E);
-
-               elsif Small_Value (E) > Ureal_2_80 then
-                  Error_Msg_Name_1 := Name_Small;
-                  Error_Msg_N
-                    ("`&''%` too large, maximum allowed is 2.0'*'*80", E);
-               end if;
-
-               if Expr_Value_R (Type_Low_Bound (E)) < Ureal_M_10_36 then
-                  Error_Msg_Name_1 := Name_First;
-                  Error_Msg_N
-                    ("`&''%` too small, minimum allowed is -10.0'*'*36", E);
-               end if;
-
-               if Expr_Value_R (Type_High_Bound (E)) > Ureal_10_36 then
-                  Error_Msg_Name_1 := Name_Last;
-                  Error_Msg_N
-                    ("`&''%` too large, maximum allowed is 10.0'*'*36", E);
-               end if;
-            end if;
-
          elsif Is_Enumeration_Type (E) then
             Freeze_Enumeration_Type (E);
 
@@ -8123,6 +8094,12 @@ package body Freeze is
       --  Returns size of type with given bounds. Also leaves these
       --  bounds set as the current bounds of the Typ.
 
+      function Larger (A, B : Ureal) return Boolean;
+      --  Returns true if A > B with a margin of Typ'Small
+
+      function Smaller (A, B : Ureal) return Boolean;
+      --  Returns true if A < B with a margin of Typ'Small
+
       -----------
       -- Fsize --
       -----------
@@ -8134,6 +8111,24 @@ package body Freeze is
          return Minimum_Size (Typ);
       end Fsize;
 
+      ------------
+      -- Larger --
+      ------------
+
+      function Larger (A, B : Ureal) return Boolean is
+      begin
+         return A > B and then A - Small > B;
+      end Larger;
+
+      -------------
+      -- Smaller --
+      -------------
+
+      function Smaller (A, B : Ureal) return Boolean is
+      begin
+         return A < B and then A + Small < B;
+      end Smaller;
+
    --  Start of processing for Freeze_Fixed_Point_Type
 
    begin
@@ -8155,7 +8150,7 @@ package body Freeze is
          if Present (Atype) then
             Set_Esize (Typ, Esize (Atype));
          else
-            Set_Esize (Typ, Esize (Base_Type (Typ)));
+            Set_Esize (Typ, Esize (Btyp));
          end if;
       end if;
 
@@ -8435,6 +8430,110 @@ package body Freeze is
             Set_Realval (Hi, Actual_Hi);
          end Fudge;
 
+         --  Enforce some limitations for ordinary fixed-point types. They come
+         --  from an exact algorithm used to implement Text_IO.Fixed_IO and the
+         --  Fore, Image and Value attributes. The requirement on the Small is
+         --  to lie in the range 2**(-(Siz - 1)) .. 2**(Siz - 1) for a type of
+         --  Siz bits (Siz=32,64,128) and the requirement on the bounds is to
+         --  be smaller in magnitude than 10.0**N * 2**(Siz - 1), where N is
+         --  given by the formula N = floor ((Siz - 1) * log 2 / log 10).
+
+         --  If the bounds of a 32-bit type are too large, force 64-bit type
+
+         if Actual_Size <= 32
+           and then Small <= Ureal_2_31
+           and then (Smaller (Expr_Value_R (Lo), Ureal_M_2_10_18)
+                      or else Larger (Expr_Value_R (Hi), Ureal_2_10_18))
+         then
+            Actual_Size := 33;
+         end if;
+
+         --  If the bounds of a 64-bit type are too large, force 128-bit type
+
+         if System_Max_Integer_Size = 128
+           and then Actual_Size <= 64
+           and then Small <= Ureal_2_63
+           and then (Smaller (Expr_Value_R (Lo), Ureal_M_9_10_36)
+                      or else Larger (Expr_Value_R (Hi), Ureal_9_10_36))
+         then
+            Actual_Size := 65;
+         end if;
+
+         --  Give error messages for first subtypes and not base types, as the
+         --  bounds of base types are always maximum for their size, see below.
+
+         if System_Max_Integer_Size < 128 and then Typ /= Btyp then
+
+            --  See the 128-bit case below for the reason why we cannot test
+            --  against the 2**(-63) .. 2**63 range. This quirk should have
+            --  been kludged around as in the 128-bit case below, but it was
+            --  not and we end up with a ludicrous range as a result???
+
+            if Small < Ureal_2_M_80 then
+               Error_Msg_Name_1 := Name_Small;
+               Error_Msg_N
+                 ("`&''%` too small, minimum allowed is 2.0'*'*(-80)", Typ);
+
+            elsif Small > Ureal_2_80 then
+               Error_Msg_Name_1 := Name_Small;
+               Error_Msg_N
+                 ("`&''%` too large, maximum allowed is 2.0'*'*80", Typ);
+            end if;
+
+            if Smaller (Expr_Value_R (Lo), Ureal_M_9_10_36) then
+               Error_Msg_Name_1 := Name_First;
+               Error_Msg_N
+                 ("`&''%` too small, minimum allowed is -9.0E+36", Typ);
+            end if;
+
+            if Larger (Expr_Value_R (Hi), Ureal_9_10_36) then
+               Error_Msg_Name_1 := Name_Last;
+               Error_Msg_N
+                 ("`&''%` too large, maximum allowed is 9.0E+36", Typ);
+            end if;
+
+         elsif System_Max_Integer_Size = 128 and then Typ /= Btyp then
+
+            --  ACATS c35902d tests a delta equal to 2**(-(Max_Mantissa + 1))
+            --  but we cannot really support anything smaller than Fine_Delta
+            --  because of the way we implement I/O for fixed point types???
+
+            if Small = Ureal_2_M_128 then
+               null;
+
+            elsif Small < Ureal_2_M_127 then
+               Error_Msg_Name_1 := Name_Small;
+               Error_Msg_N
+                 ("`&''%` too small, minimum allowed is 2.0'*'*(-127)", Typ);
+
+            elsif Small > Ureal_2_127 then
+               Error_Msg_Name_1 := Name_Small;
+               Error_Msg_N
+                 ("`&''%` too large, maximum allowed is 2.0'*'*127", Typ);
+            end if;
+
+            if Actual_Size > 64
+              and then Norm_Num (Small) /= Uint_1
+              and then Norm_Den (Small) /= Uint_1
+            then
+               Error_Msg_Name_1 := Name_Small;
+               Error_Msg_N
+                 ("`&''%` not an integer or reciprocal of an integer", Typ);
+            end if;
+
+            if Smaller (Expr_Value_R (Lo), Ureal_M_10_76) then
+               Error_Msg_Name_1 := Name_First;
+               Error_Msg_N
+                 ("`&''%` too small, minimum allowed is -1.0E+76", Typ);
+            end if;
+
+            if Larger (Expr_Value_R (Hi), Ureal_10_76) then
+               Error_Msg_Name_1 := Name_Last;
+               Error_Msg_N
+                 ("`&''%` too large, maximum allowed is 1.0E+76", Typ);
+            end if;
+         end if;
+
       --  For the decimal case, none of this fudging is required, since there
       --  are no end-point problems in the decimal case (the end-points are
       --  always included).
@@ -8446,12 +8545,13 @@ package body Freeze is
       --  At this stage, the actual size has been calculated and the proper
       --  required bounds are stored in the low and high bounds.
 
-      if Actual_Size > 64 then
+      if Actual_Size > System_Max_Integer_Size then
          Error_Msg_Uint_1 := UI_From_Int (Actual_Size);
+         Error_Msg_Uint_2 := UI_From_Int (System_Max_Integer_Size);
          Error_Msg_N
-           ("size required (^) for type& too large, maximum allowed is 64",
+           ("size required (^) for type& too large, maximum allowed is ^",
             Typ);
-         Actual_Size := 64;
+         Actual_Size := System_Max_Integer_Size;
       end if;
 
       --  Check size against explicit given size
@@ -8477,8 +8577,10 @@ package body Freeze is
             Actual_Size := 16;
          elsif Actual_Size <= 32 then
             Actual_Size := 32;
-         else
+         elsif Actual_Size <= 64 then
             Actual_Size := 64;
+         else
+            Actual_Size := 128;
          end if;
 
          Init_Esize (Typ, Actual_Size);
@@ -8489,7 +8591,7 @@ package body Freeze is
       --  the full width of the allocated size in bits, to avoid junk range
       --  checks on intermediate computations.
 
-      if Base_Type (Typ) = Typ then
+      if Typ = Btyp then
          Set_Realval (Lo, -(Small * (Uint_2 ** (Actual_Size - 1))));
          Set_Realval (Hi,  (Small * (Uint_2 ** (Actual_Size - 1) - 1)));
       end if;
index 1169f85a02b0e1789f9c818334bc6ca0a4e2c140..66665206c4c9f56408b8f56867d75e38adc51b2c 100644 (file)
@@ -15709,16 +15709,26 @@ The small is the largest power of two that does not exceed the delta.
 supported for fixed point types.  See 3.5.9(10)."
 @end itemize
 
-For an ordinary fixed point type, the small must lie in 2.0**(-80) .. 2.0**80
-and the range in -10.0**36 .. 10.0**36; any combination is permitted that
-does not result in a mantissa larger than 63 bits. However, if the mantissa
-is larger than 53 bits on machines where Long_Long_Float is 64 bits (true
-of all architectures except x86), then the output from Text_IO may be
-accurate to only 53 bits, rather than the full mantissa.  This is because
-floating-point conversions may be used to convert fixed point.
-
-For a decimal fixed point type, the small must lie in 10.0**(-18) .. 10.0**18
-and the digits in 1 .. 18.
+For an ordinary fixed point type, on 32-bit platforms, the small must lie in
+2.0**(-80) .. 2.0**80 and the range in -9.0E+36 .. 9.0E+36; any combination
+is permitted that does not result in a mantissa larger than 63 bits.
+
+On 64-bit platforms, the small must lie in 2.0**(-127) .. 2.0**127 and the
+range in -1.0E+76 .. 1.0E+76; any combination is permitted that does not
+result in a mantissa larger than 63 bits, and any combination is permitted
+that results in a mantissa between 64 and 127 bits if the small is either
+an integer or the reciprocal of an integer.
+
+If the small is either an integer or the reciprocal of an integer, which
+is the case if no @code{small} clause is provided, then the operations of the
+fixed point type are entirely implemented by means of integer instructions.
+In the other cases, some operations, in particular input and output, may be
+implemented by means of floating-point instructions and may be affected by
+accuracy issues on architectures other than x86.
+
+For a decimal fixed point type, on 32-bit platforms, the small must lie in
+1.0E-18 .. 1.0E+18 and the digits in 1 .. 18.  On 64-bit platforms, the
+small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.
 
 
 @itemize *
diff --git a/gcc/ada/libgnat/a-decima__128.ads b/gcc/ada/libgnat/a-decima__128.ads
new file mode 100644 (file)
index 0000000..b29b010
--- /dev/null
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                          A D A . D E C I M A L                           --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the  contents of the part following the private keyword. --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This is the 128-bit version of this package
+
+package Ada.Decimal is
+   pragma Pure;
+
+   --  The compiler makes a number of assumptions based on the following five
+   --  constants (e.g. there is an assumption that decimal values can always
+   --  be represented in 128-bit signed binary form), so code modifications are
+   --  required to increase these constants.
+
+   Max_Scale : constant := +38;
+   Min_Scale : constant := -38;
+
+   Min_Delta : constant := 1.0E-38;
+   Max_Delta : constant := 1.0E+38;
+
+   Max_Decimal_Digits : constant := 38;
+
+   generic
+      type Dividend_Type  is delta <> digits <>;
+      type Divisor_Type   is delta <> digits <>;
+      type Quotient_Type  is delta <> digits <>;
+      type Remainder_Type is delta <> digits <>;
+
+   procedure Divide
+     (Dividend  : Dividend_Type;
+      Divisor   : Divisor_Type;
+      Quotient  : out Quotient_Type;
+      Remainder : out Remainder_Type);
+
+private
+   pragma Inline (Divide);
+
+end Ada.Decimal;
index caf77e3d07a0a9469d391e95a04d14bf949c960c..5878234dde459c70c9aad9fcec174d2b3e6f7409 100644 (file)
 with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
 with Ada.Text_IO.Float_Aux;   use Ada.Text_IO.Float_Aux;
 
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
 package body Ada.Text_IO.Decimal_Aux is
 
-   -------------
-   -- Get_Dec --
-   -------------
+   ---------
+   -- Get --
+   ---------
 
-   function Get_Dec
+   function Get
      (File  : File_Type;
       Width : Field;
-      Scale : Integer) return Integer
+      Scale : Integer) return Int
    is
       Buf  : String (1 .. Field'Last);
       Ptr  : aliased Integer;
       Stop : Integer := 0;
-      Item : Integer;
+      Item : Int;
 
    begin
       if Width /= 0 then
@@ -62,114 +57,42 @@ package body Ada.Text_IO.Decimal_Aux is
          Ptr := 1;
       end if;
 
-      Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
+      Item := Scan (Buf, Ptr'Access, Stop, Scale);
       Check_End_Of_Field (Buf, Stop, Ptr, Width);
       return Item;
-   end Get_Dec;
-
-   -------------
-   -- Get_LLD --
-   -------------
-
-   function Get_LLD
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Long_Long_Integer
-   is
-      Buf  : String (1 .. Field'Last);
-      Ptr  : aliased Integer;
-      Stop : Integer := 0;
-      Item : Long_Long_Integer;
+   end Get;
 
-   begin
-      if Width /= 0 then
-         Load_Width (File, Width, Buf, Stop);
-         String_Skip (Buf, Ptr);
-      else
-         Load_Real (File, Buf, Stop);
-         Ptr := 1;
-      end if;
+   ----------
+   -- Gets --
+   ----------
 
-      Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
-      Check_End_Of_Field (Buf, Stop, Ptr, Width);
-      return Item;
-   end Get_LLD;
-
-   --------------
-   -- Gets_Dec --
-   --------------
-
-   function Gets_Dec
+   function Gets
      (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer
+      Last  : out Positive;
+      Scale : Integer) return Int
    is
       Pos  : aliased Integer;
-      Item : Integer;
+      Item : Int;
 
    begin
       String_Skip (From, Pos);
-      Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
+      Item := Scan (From, Pos'Access, From'Last, Scale);
+      Last := Pos - 1;
       return Item;
 
    exception
       when Constraint_Error =>
-         Last.all := Pos - 1;
+         Last := Pos - 1;
          raise Data_Error;
-   end Gets_Dec;
-
-   --------------
-   -- Gets_LLD --
-   --------------
-
-   function Gets_LLD
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer
-   is
-      Pos  : aliased Integer;
-      Item : Long_Long_Integer;
-
-   begin
-      String_Skip (From, Pos);
-      Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
-      return Item;
-
-   exception
-      when Constraint_Error =>
-         Last.all := Pos - 1;
-         raise Data_Error;
-   end Gets_LLD;
-
-   -------------
-   -- Put_Dec --
-   -------------
+   end Gets;
 
-   procedure Put_Dec
-     (File  : File_Type;
-      Item  : Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf : String (1 .. Field'Last);
-      Ptr : Natural := 0;
-
-   begin
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-      Put_Item (File, Buf (1 .. Ptr));
-   end Put_Dec;
-
-   -------------
-   -- Put_LLD --
-   -------------
+   ---------
+   -- Put --
+   ---------
 
-   procedure Put_LLD
+   procedure Put
      (File  : File_Type;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
@@ -179,83 +102,51 @@ package body Ada.Text_IO.Decimal_Aux is
       Ptr : Natural := 0;
 
    begin
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
       Put_Item (File, Buf (1 .. Ptr));
-   end Put_LLD;
+   end Put;
 
-   --------------
-   -- Puts_Dec --
-   --------------
+   ----------
+   -- Puts --
+   ----------
 
-   procedure Puts_Dec
+   procedure Puts
      (To    : out String;
-      Item  : Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer)
    is
-      Buf  : String (1 .. Field'Last);
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
       Fore : Integer;
       Ptr  : Natural := 0;
 
    begin
-      --  Compute Fore, allowing for Aft digits and the decimal dot
+      --  Compute Fore, allowing for the decimal dot and Aft digits
 
-      Fore := To'Length - Field'Max (1, Aft) - 1;
+      Fore := To'Length - 1 - Field'Max (1, Aft);
 
-      --  Allow for Exp and two more for E+ or E- if exponent present
+      --  Allow for Exp and one more for E if exponent present
 
       if Exp /= 0 then
-         Fore := Fore - 2 - Exp;
+         Fore := Fore - 1 - Field'Max (2, Exp);
       end if;
 
       --  Make sure we have enough room
 
-      if Fore < 1 then
+      if Fore < 1 + Boolean'Pos (Item < 0) then
          raise Layout_Error;
       end if;
 
       --  Do the conversion and check length of result
 
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
-      if Ptr > To'Length then
-         raise Layout_Error;
-      else
-         To := Buf (1 .. Ptr);
-      end if;
-   end Puts_Dec;
-
-   --------------
-   -- Puts_LLD --
-   --------------
-
-   procedure Puts_LLD
-     (To    : out String;
-      Item  : Long_Long_Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf  : String (1 .. Field'Last);
-      Fore : Integer;
-      Ptr  : Natural := 0;
-
-   begin
-      Fore :=
-        (if Exp = 0 then To'Length - 1 - Aft else To'Length - 2 - Aft - Exp);
-
-      if Fore < 1 then
-         raise Layout_Error;
-      end if;
-
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
 
       if Ptr > To'Length then
          raise Layout_Error;
       else
          To := Buf (1 .. Ptr);
       end if;
-   end Puts_LLD;
+   end Puts;
 
 end Ada.Text_IO.Decimal_Aux;
index e7d7f44004fd3966f32e0f17ac4a57e2f990dd91..522e3515186ed5dcd6a7a46ba89181b7025552ca 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package contains the routines for Ada.Text_IO.Decimal_IO that are
---  shared among separate instantiations of this package. The routines in
---  the package are identical semantically to those declared in Text_IO,
---  except that default values have been supplied by the generic, and the
---  Num parameter has been replaced by Integer or Long_Long_Integer, with
---  an additional Scale parameter giving the value of Num'Scale. In addition
---  the Get routines return the value rather than store it in an Out parameter.
+--  This package contains the implementation for Ada.Text_IO.Decimal_IO. The
+--  routines in this package are identical semantically to those in Decimal_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there is an
+--  additional Scale parameter giving the value of Num'Scale. In addition the
+--  Get routines return the value rather than store it in an Out parameter.
 
-private package Ada.Text_IO.Decimal_Aux is
+private generic
+   type Int is range <>;
 
-   function Get_Dec
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Integer;
+   with function Scan
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int;
 
-   function Get_LLD
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Long_Long_Integer;
+   with procedure Set_Image
+     (V     : Int;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural);
+
+package Ada.Text_IO.Decimal_Aux is
 
-   procedure Put_Dec
+   function Get
      (File  : File_Type;
-      Item  : Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+      Width : Field;
+      Scale : Integer) return Int;
 
-   procedure Put_LLD
+   procedure Put
      (File  : File_Type;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
 
-   function Gets_Dec
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer;
-
-   function Gets_LLD
+   function Gets
      (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer;
-
-   procedure Puts_Dec
-     (To    : out String;
-      Item  : Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+      Last  : out Positive;
+      Scale : Integer) return Int;
 
-   procedure Puts_LLD
+   procedure Puts
      (To    : out String;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
index 0624c2c778fd151c944f8b22dd081a19b9de50f4..f71cf2df85f01a389a6e3ca4a53209c6958c7d1b 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Interfaces;
 with Ada.Text_IO.Decimal_Aux;
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
 
 package body Ada.Text_IO.Decimal_IO is
 
-   package Aux renames Ada.Text_IO.Decimal_Aux;
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Aux32 is new
+     Ada.Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   Need64 : constant Boolean := Num'Size > 32;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
 
    Scale : constant Integer := Num'Scale;
 
@@ -49,10 +73,10 @@ package body Ada.Text_IO.Decimal_IO is
       pragma Unsuppress (Range_Check);
 
    begin
-      if Num'Size > Integer'Size then
-         Item := Num'Fixed_Value (Aux.Get_LLD (File, Width, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
       else
-         Item := Num'Fixed_Value (Aux.Get_Dec (File, Width, Scale));
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
       end if;
 
    exception
@@ -75,12 +99,10 @@ package body Ada.Text_IO.Decimal_IO is
       pragma Unsuppress (Range_Check);
 
    begin
-      if Num'Size > Integer'Size then
-         Item := Num'Fixed_Value
-                   (Aux.Gets_LLD (From, Last'Unrestricted_Access, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (From, Last, Scale));
       else
-         Item := Num'Fixed_Value
-                   (Aux.Gets_Dec (From, Last'Unrestricted_Access, Scale));
+         Item := Num'Fixed_Value (Aux32.Gets (From, Last, Scale));
       end if;
 
    exception
@@ -99,13 +121,12 @@ package body Ada.Text_IO.Decimal_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      if Num'Size > Integer'Size then
-         Aux.Put_LLD
-           (File, Long_Long_Integer'Integer_Value (Item),
-            Fore, Aft, Exp, Scale);
+      if Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
       else
-         Aux.Put_Dec
-           (File, Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
       end if;
    end Put;
 
@@ -126,11 +147,10 @@ package body Ada.Text_IO.Decimal_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      if Num'Size > Integer'Size then
-         Aux.Puts_LLD
-           (To, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
+      if Need64 then
+         Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp, Scale);
       else
-         Aux.Puts_Dec (To, Integer'Integer_Value (Item), Aft, Exp, Scale);
+         Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp, Scale);
       end if;
    end Put;
 
diff --git a/gcc/ada/libgnat/a-tideio__128.adb b/gcc/ada/libgnat/a-tideio__128.adb
new file mode 100644 (file)
index 0000000..a8cdf9f
--- /dev/null
@@ -0,0 +1,177 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--               A D A . T E X T _ I O . D E C I M A L _ I O                --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Text_IO.Decimal_Aux;
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+
+package body Ada.Text_IO.Decimal_IO is
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   package Aux128 is new
+     Ada.Text_IO.Decimal_Aux
+       (Int128,
+        Scan_Decimal128,
+        Set_Image_Decimal128);
+
+   Need64  : constant Boolean := Num'Size > 32;
+   Need128 : constant Boolean := Num'Size > 64;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable, where type Int64 is acceptable and where an Int128
+   --  is needed. These boolean constants are used to test for these cases and
+   --  since it is a constant, only code for the relevant case will be included
+   --  in the instance.
+
+   Scale : constant Integer := Num'Scale;
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_In, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Gets (From, Last, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (From, Last, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Gets (From, Last, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if Need128 then
+         Aux128.Put
+           (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      else
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Out, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if Need128 then
+         Aux128.Puts (To, Int128'Integer_Value (Item), Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp, Scale);
+      else
+         Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp, Scale);
+      end if;
+   end Put;
+
+end Ada.Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-tifiau.adb b/gcc/ada/libgnat/a-tifiau.adb
new file mode 100644 (file)
index 0000000..9259552
--- /dev/null
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 A D A . T E X T _ I O . F I X E D _ A U X                --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
+with Ada.Text_IO.Float_Aux;   use Ada.Text_IO.Float_Aux;
+
+package body Ada.Text_IO.Fixed_Aux is
+
+   ---------
+   -- Get --
+   ---------
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int
+   is
+      Buf  : String (1 .. Field'Last);
+      Ptr  : aliased Integer;
+      Stop : Integer := 0;
+      Item : Int;
+
+   begin
+      if Width /= 0 then
+         Load_Width (File, Width, Buf, Stop);
+         String_Skip (Buf, Ptr);
+      else
+         Load_Real (File, Buf, Stop);
+         Ptr := 1;
+      end if;
+
+      Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+      Check_End_Of_Field (Buf, Stop, Ptr, Width);
+      return Item;
+   end Get;
+
+   ----------
+   -- Gets --
+   ----------
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int
+   is
+      Pos  : aliased Integer;
+      Item : Int;
+
+   begin
+      String_Skip (From, Pos);
+      Item := Scan (From, Pos'Access, From'Last, Num, Den);
+      Last := Pos - 1;
+      return Item;
+
+   exception
+      when Constraint_Error =>
+         Last := Pos - 1;
+         raise Data_Error;
+   end Gets;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf : String (1 .. Field'Last);
+      Ptr : Natural := 0;
+
+   begin
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+      Put_Item (File, Buf (1 .. Ptr));
+   end Put;
+
+   ----------
+   -- Puts --
+   ----------
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
+      Fore : Integer;
+      Ptr  : Natural := 0;
+
+   begin
+      --  Compute Fore, allowing for the decimal dot and Aft digits
+
+      Fore := To'Length - 1 - Field'Max (1, Aft);
+
+      --  Allow for Exp and one more for E if exponent present
+
+      if Exp /= 0 then
+         Fore := Fore - 1 - Field'Max (2, Exp);
+      end if;
+
+      --  Make sure we have enough room
+
+      if Fore < 1 + Boolean'Pos (Item < 0) then
+         raise Layout_Error;
+      end if;
+
+      --  Do the conversion and check length of result
+
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+      if Ptr > To'Length then
+         raise Layout_Error;
+      else
+         To := Buf (1 .. Ptr);
+      end if;
+   end Puts;
+
+end Ada.Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-tifiau.ads b/gcc/ada/libgnat/a-tifiau.ads
new file mode 100644 (file)
index 0000000..32701c5
--- /dev/null
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 A D A . T E X T _ I O . F I X E D _ A U X                --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the implementation for Ada.Text_IO.Fixed_IO. The
+--  routines in this package are identical semantically to those in Fixed_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there are
+--  additional Num and Den parameters giving the value of Num'Small, as well
+--  as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+--  routines return the value rather than store it in an Out parameter.
+
+private generic
+   type Int is range <>;
+
+   with function Scan
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int;
+      Den : Int) return Int;
+
+   with procedure Set_Image
+     (V    : Int;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural);
+
+package Ada.Text_IO.Fixed_Aux is
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int;
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int;
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+end Ada.Text_IO.Fixed_Aux;
index 2d0b47c2c61a07fd9d8ecb5410c56e52a013a8ba..67cb917d5eb46d7c31be4cceea15ccd1996a003a 100644 (file)
 --  solution. The downside however may be a too limited set of acceptable
 --  fixed point types.
 
-with Interfaces;                        use Interfaces;
-with System.Arith_64;                   use System.Arith_64;
-with System.Img_Real;                   use System.Img_Real;
-with Ada.Text_IO;                       use Ada.Text_IO;
+with Interfaces;
+with Ada.Text_IO.Fixed_Aux;
 with Ada.Text_IO.Float_Aux;
-with Ada.Text_IO.Generic_Aux;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
 
 package body Ada.Text_IO.Fixed_IO is
 
-   --  Note: we still use the floating-point I/O routines for input of
-   --  ordinary fixed-point and output using exponent format. This will
-   --  result in inaccuracies for fixed point types with a small that is
-   --  not a power of two, and for types that require more precision than
-   --  is available in Long_Long_Float.
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
 
-   package Aux renames Ada.Text_IO.Float_Aux;
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
 
-   Extra_Layout_Space : constant Field := 5 + Num'Fore;
-   --  Extra space that may be needed for output of sign, decimal point,
-   --  exponent indication and mandatory decimals after and before the
-   --  decimal point. A string with length
+   package Aux32 is new
+     Ada.Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
 
-   --    Fore + Aft + Exp + Extra_Layout_Space
-
-   --  is always long enough for formatting any fixed point number.
-
-   --  Implementation of Put routines
-
-   --  The following section describes a specific implementation choice for
-   --  performing base conversions needed for output of values of a fixed
-   --  point type T with small T'Small. The goal is to be able to output
-   --  all values of types with a precision of 64 bits and a delta of at
-   --  least 2.0**(-63), as these are current GNAT limitations already.
-
-   --  The chosen algorithm uses fixed precision integer arithmetic for
-   --  reasons of simplicity and efficiency. It is important to understand
-   --  in what ways the most simple and accurate approach to fixed point I/O
-   --  is limiting, before considering more complicated schemes.
-
-   --  Without loss of generality assume T has a range (-2.0**63) * T'Small
-   --  .. (2.0**63 - 1) * T'Small, and is output with Aft digits after the
-   --  decimal point and T'Fore - 1 before. If T'Small is integer, or
-   --  1.0 / T'Small is integer, let S = T'Small and E = 0. For other T'Small,
-   --  let S and E be integers such that S / 10**E best approximates T'Small
-   --  and S is in the range 10**17 .. 10**18 - 1. The extra decimal scaling
-   --  factor 10**E can be trivially handled during final output, by adjusting
-   --  the decimal point or exponent.
-
-   --  The idea is to convert a value X * S of type T to a 64-bit integer value
-   --  Q equal to 10.0**D * (X * S) rounded to the nearest integer, using only
-   --  a scaled integer divide of the form
-
-   --     Q := (X * Y) / Z,
-
-   --  where the variables X, Y, Z are 64-bit integers, and both multiplication
-   --  and division are done using full intermediate precision. Then the final
-   --  decimal value to be output is
-
-   --     Q * 10**(E-D)
-
-   --  This value can be written to the output file or to the result string
-   --  according to the format described in RM A.3.10. The details of this
-   --  operation are omitted here.
-
-   --  A 64-bit value can represent all integers with 18 decimal digits, but
-   --  not all with 19 decimal digits. If the total number of requested ouput
-   --  digits (Fore - 1) + Aft is greater than 18 then, for purposes of the
-   --  conversion, Aft is adjusted to 18 - (Fore - 1). In that case, trailing
-   --  zeros can complete the output after writing the first 18 significant
-   --  digits, or the technique described in the next section can be used.
-
-   --  The final expression for D is
-
-   --     D := Integer'Max (-18, Integer'Min (Aft, 18 - (Fore - 1)));
-
-   --  For Y and Z the following expressions can be derived:
-
-   --     Q = X * S * (10.0**D) = (X * Y) / Z
-
-   --     S * 10.0**D = Y / Z;
-
-   --  If S is an integer greater than or equal to one, then Fore must be at
-   --  least 20 in order to print T'First, which is at most -2.0**63. This
-   --  means that D < 0, so use
-
-   --    (1)   Y = -S and Z = -10**(-D)
-
-   --  If 1.0 / S is an integer greater than one, use
-
-   --    (2)   Y = -10**D and Z = -(1.0 / S), for D >= 0
-
-   --  or
-
-   --    (3)   Y = -1 and Z = -(1.0 / S) * 10**(-D), for D < 0
-
-   --  Negative values are used for nominator Y and denominator Z, so that S
-   --  can have a maximum value of 2.0**63 and a minimum of 2.0**(-63).
-   --  For Z in -1 .. -9, Fore will still be 20, and D will be negative, as
-   --  (-2.0**63) / -9 is greater than 10**18. In these cases there is room
-   --  in the denominator for the extra decimal scaling required, so case (3)
-   --  will not overflow.
-
-   --  Extra Precision
-
-   --  Using a scaled divide which truncates and returns a remainder R,
-   --  another K trailing digits can be calculated by computing the value
-   --  (R * (10.0**K)) / Z using another scaled divide. This procedure
-   --  can be repeated to compute an arbitrary number of digits in linear
-   --  time and storage. The last scaled divide should be rounded, with
-   --  a possible carry propagating to the more significant digits, to
-   --  ensure correct rounding of the unit in the last place.
-
-   --  A variant of this technique is to limit the value of Q to 9 decimal
-   --  digits, since 32-bit integers can be much more efficient than 64-bit
-   --  integers to output.
-
-   pragma Assert (System.Fine_Delta >= 2.0**(-63));
-   pragma Assert (Num'Small in 2.0**(-80) .. 2.0**80);
-   pragma Assert (Num'Fore <= 37);
-
-   Max_Digits : constant := 18;
-   --  Maximum number of decimal digits that can be represented in a
-   --  64-bit signed number, see above
-
-   --  The constants E0 .. E5 implement a binary search for the appropriate
-   --  power of ten to scale the small so that it has one digit before the
-   --  decimal point.
-
-   subtype Int is Integer;
-   E0 : constant Int := -(25 * Boolean'Pos (Num'Small >= 1.0E1));
-   E1 : constant Int := E0 + 13 * Boolean'Pos (Num'Small * 10.0**E0 < 1.0E-13);
-   E2 : constant Int := E1 +  6 * Boolean'Pos (Num'Small * 10.0**E1 < 1.0E-6);
-   E3 : constant Int := E2 +  3 * Boolean'Pos (Num'Small * 10.0**E2 < 1.0E-3);
-   E4 : constant Int := E3 +  2 * Boolean'Pos (Num'Small * 10.0**E3 < 1.0E-1);
-   E5 : constant Int := E4 +  1 * Boolean'Pos (Num'Small * 10.0**E4 < 1.0E-0);
-
-   Scale : constant Integer := E5;
-
-   pragma Assert (Num'Small * 10.0**Scale >= 1.0
-                   and then Num'Small * 10.0**Scale < 10.0);
+   package Aux64 is new
+     Ada.Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
 
    Exact : constant Boolean :=
      (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
-        or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small)
-        or else Num'Small >= 10.0**Max_Digits)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
      and then Num'Small >= 2.0**(-63)
      and then Num'Small <= 2.0**63;
-   --  True iff a 64-bit numerator and denominator can be calculated such that
-   --  their ratio exactly represents the small of Num.
-
-   procedure Put
-     (To   : out String;
-      Last : out Natural;
-      Item : Num;
-      Fore : Integer;
-      Aft  : Field;
-      Exp  : Field);
-   --  Actual output function, used internally by all other Put routines.
-   --  The formal Fore is an Integer, not a Field, because the routine is
-   --  also called from the version of Put that performs I/O to a string,
-   --  where the starting position depends on the size of the String, and
-   --  bears no relation to the bounds of Field.
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
+
+   E : constant Natural := 31 + 32 * Boolean'Pos (Need_64);
+   --  T'Size - 1 for the selected Int{32,64}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+   F2 : constant Natural :=
+          F1 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+   F3 : constant Natural :=
+          F2 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+   F4 : constant Natural :=
+          F3 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+   F5 : constant Natural :=
+          F4 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+   F6 : constant Natural :=
+          F5 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F6;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64} and
+   --  whose small is Num'Small.
 
    ---------
    -- Get --
@@ -313,8 +215,22 @@ package body Ada.Text_IO.Fixed_IO is
       Width : Field := 0)
    is
       pragma Unsuppress (Range_Check);
+
    begin
-      Aux.Get (File, Long_Long_Float (Item), Width);
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
    exception
       when Constraint_Error => raise Data_Error;
    end Get;
@@ -323,11 +239,8 @@ package body Ada.Text_IO.Fixed_IO is
      (Item  : out Num;
       Width : Field := 0)
    is
-      pragma Unsuppress (Range_Check);
    begin
-      Aux.Get (Current_In, Long_Long_Float (Item), Width);
-   exception
-      when Constraint_Error => raise Data_Error;
+      Get (Current_Input, Item, Width);
    end Get;
 
    procedure Get
@@ -336,8 +249,22 @@ package body Ada.Text_IO.Fixed_IO is
       Last : out Positive)
    is
       pragma Unsuppress (Range_Check);
+
    begin
-      Aux.Gets (From, Long_Long_Float (Item), Last);
+      if not Exact then
+         Float_Aux.Gets (From, Long_Long_Float (Item), Last);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (From, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (From, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
    exception
       when Constraint_Error => raise Data_Error;
    end Get;
@@ -353,11 +280,20 @@ package body Ada.Text_IO.Fixed_IO is
       Aft  : Field := Default_Aft;
       Exp  : Field := Default_Exp)
    is
-      S    : String (1 .. Fore + Aft + Exp + Extra_Layout_Space);
-      Last : Natural;
    begin
-      Put (S, Last, Item, Fore, Aft, Exp);
-      Generic_Aux.Put_Item (File, S (1 .. Last));
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
    end Put;
 
    procedure Put
@@ -366,11 +302,8 @@ package body Ada.Text_IO.Fixed_IO is
       Aft  : Field := Default_Aft;
       Exp  : Field := Default_Exp)
    is
-      S    : String (1 .. Fore + Aft + Exp + Extra_Layout_Space);
-      Last : Natural;
    begin
-      Put (S, Last, Item, Fore, Aft, Exp);
-      Generic_Aux.Put_Item (Text_IO.Current_Out, S (1 .. Last));
+      Put (Current_Out, Item, Fore, Aft, Exp);
    end Put;
 
    procedure Put
@@ -379,332 +312,20 @@ package body Ada.Text_IO.Fixed_IO is
       Aft  : Field := Default_Aft;
       Exp  : Field := Default_Exp)
    is
-      Fore : constant Integer :=
-        To'Length
-          - 1                      -- Decimal point
-          - Field'Max (1, Aft)     -- Decimal part
-          - Boolean'Pos (Exp /= 0) -- Exponent indicator
-          - Exp;                   -- Exponent
-
-      Last : Natural;
-
-   begin
-      if Fore - Boolean'Pos (Item < 0.0) < 1 then
-         raise Layout_Error;
-      end if;
-
-      Put (To, Last, Item, Fore, Aft, Exp);
-
-      if Last /= To'Last then
-         raise Layout_Error;
-      end if;
-   end Put;
-
-   procedure Put
-     (To   : out String;
-      Last : out Natural;
-      Item : Num;
-      Fore : Integer;
-      Aft  : Field;
-      Exp  : Field)
-   is
-      subtype Digit is Int64 range 0 .. 9;
-
-      X   : constant Int64   := Int64'Integer_Value (Item);
-      A   : constant Field   := Field'Max (Aft, 1);
-      Neg : constant Boolean := (Item < 0.0);
-      Pos : Integer := 0;  -- Next digit X has value X * 10.0**Pos;
-
-      procedure Put_Character (C : Character);
-      pragma Inline (Put_Character);
-      --  Add C to the output string To, updating Last
-
-      procedure Put_Digit (X : Digit);
-      --  Add digit X to the output string (going from left to right), updating
-      --  Last and Pos, and inserting the sign, leading zeros or a decimal
-      --  point when necessary. After outputting the first digit, Pos must not
-      --  be changed outside Put_Digit anymore.
-
-      procedure Put_Int64 (X : Int64; Scale : Integer);
-      --  Output the decimal number abs X * 10**Scale
-
-      procedure Put_Scaled
-        (X, Y, Z : Int64;
-         A       : Field;
-         E       : Integer);
-      --  Output the decimal number (X * Y / Z) * 10**E, producing A digits
-      --  after the decimal point and rounding the final digit. The value
-      --  X * Y / Z is computed with full precision, but must be in the
-      --  range of Int64.
-
-      -------------------
-      -- Put_Character --
-      -------------------
-
-      procedure Put_Character (C : Character) is
-      begin
-         Last := Last + 1;
-
-         --  Never put a character outside of string To. Exception Layout_Error
-         --  will be raised later if Last is greater than To'Last.
-
-         if Last <= To'Last then
-            To (Last) := C;
-         end if;
-      end Put_Character;
-
-      ---------------
-      -- Put_Digit --
-      ---------------
-
-      procedure Put_Digit (X : Digit) is
-         Digs : constant array (Digit) of Character := "0123456789";
-
-      begin
-         if Last = To'First - 1 then
-            if X /= 0 or else Pos <= 0 then
-
-               --  Before outputting first digit, include leading space,
-               --  possible minus sign and, if the first digit is fractional,
-               --  decimal seperator and leading zeros.
-
-               --  The Fore part has Pos + 1 + Boolean'Pos (Neg) characters,
-               --  if Pos >= 0 and otherwise has a single zero digit plus minus
-               --  sign if negative. Add leading space if necessary.
-
-               for J in Integer'Max (0, Pos) + 2 + Boolean'Pos (Neg) .. Fore
-               loop
-                  Put_Character (' ');
-               end loop;
-
-               --  Output minus sign, if number is negative
-
-               if Neg then
-                  Put_Character ('-');
-               end if;
-
-               --  If starting with fractional digit, output leading zeros
-
-               if Pos < 0 then
-                  Put_Character ('0');
-                  Put_Character ('.');
-
-                  for J in Pos .. -2 loop
-                     Put_Character ('0');
-                  end loop;
-               end if;
-
-               Put_Character (Digs (X));
-            end if;
-
-         else
-            --  This is not the first digit to be output, so the only
-            --  special handling is that for the decimal point
-
-            if Pos = -1 then
-               Put_Character ('.');
-            end if;
-
-            Put_Character (Digs (X));
-         end if;
-
-         Pos := Pos - 1;
-      end Put_Digit;
-
-      ---------------
-      -- Put_Int64 --
-      ---------------
-
-      procedure Put_Int64 (X : Int64; Scale : Integer) is
-      begin
-         if X = 0 then
-            return;
-         end if;
-
-         if X not in -9 .. 9 then
-            Put_Int64 (X / 10, Scale + 1);
-         end if;
-
-         --  Use Put_Digit to advance Pos. This fixes a case where the second
-         --  or later Scaled_Divide would omit leading zeroes, resulting in
-         --  too few digits produced and a Layout_Error as result.
-
-         while Pos > Scale loop
-            Put_Digit (0);
-         end loop;
-
-         --  If and only if more than one digit is output before the decimal
-         --  point, pos will be unequal to scale when outputting the first
-         --  digit.
-
-         pragma Assert (Pos = Scale or else Last = To'First - 1);
-
-         Pos := Scale;
-
-         Put_Digit (abs (X rem 10));
-      end Put_Int64;
-
-      ----------------
-      -- Put_Scaled --
-      ----------------
-
-      procedure Put_Scaled
-        (X, Y, Z : Int64;
-         A       : Field;
-         E       : Integer)
-      is
-         pragma Assert (E >= -Max_Digits);
-         AA : constant Field := Integer'Max (E + A, 0);
-         N  : constant Natural := (AA + Max_Digits - 1) / Max_Digits + 1;
-
-         Q  : array (0 .. N - 1) of Int64 := (others => 0);
-         --  Each element of Q has Max_Digits decimal digits, except the
-         --  last, which has AA rem Max_Digits. Only Q (Q'First) may have an
-         --  absolute value equal to or larger than 10**Max_Digits. Only the
-         --  absolute value of the elements is significant, not the sign.
-
-         XX : Int64 := X;
-         YY : Int64 := Y;
-
-      begin
-         for J in Q'Range loop
-            exit when XX = 0;
-
-            if J > 0 then
-               YY := 10**(Integer'Min (Max_Digits, AA - (J - 1) * Max_Digits));
-            end if;
-
-            Scaled_Divide64 (XX, YY, Z, Q (J), R => XX, Round => False);
-         end loop;
-
-         if -E > A then
-            pragma Assert (N = 1);
-
-            Discard_Extra_Digits : declare
-               Factor : constant Int64 := 10**(-E - A);
-
-            begin
-               --  The scaling factors were such that the first division
-               --  produced more digits than requested. So divide away extra
-               --  digits and compute new remainder for later rounding.
-
-               if abs (Q (0) rem Factor) >= Factor / 2 then
-                  Q (0) := abs (Q (0) / Factor) + 1;
-               else
-                  Q (0) := Q (0) / Factor;
-               end if;
-
-               XX := 0;
-            end Discard_Extra_Digits;
-         end if;
-
-         --  At this point XX is a remainder and we need to determine if the
-         --  quotient in Q must be rounded away from zero.
-
-         --  As XX is less than the divisor, it is safe to take its absolute
-         --  without chance of overflow. The check to see if XX is at least
-         --  half the absolute value of the divisor must be done carefully to
-         --  avoid overflow or lose precision.
-
-         XX := abs XX;
-
-         if XX >= 2**62
-            or else (Z < 0 and then (-XX) * 2 <= Z)
-            or else (Z >= 0 and then XX * 2 >= Z)
-         then
-            --  OK, rounding is necessary. As the sign is not significant,
-            --  take advantage of the fact that an extra negative value will
-            --  always be available when propagating the carry.
-
-            Q (Q'Last) := -abs Q (Q'Last) - 1;
-
-            Propagate_Carry :
-            for J in reverse 1 .. Q'Last loop
-               if Q (J) = YY or else Q (J) = -YY then
-                  Q (J) := 0;
-                  Q (J - 1) := -abs Q (J - 1) - 1;
-
-               else
-                  exit Propagate_Carry;
-               end if;
-            end loop Propagate_Carry;
-         end if;
-
-         for J in Q'First .. Q'Last - 1 loop
-            Put_Int64 (Q (J), E - J * Max_Digits);
-         end loop;
-
-         Put_Int64 (Q (Q'Last), -A);
-      end Put_Scaled;
-
-   --  Start of processing for Put
-
    begin
-      Last := To'First - 1;
-
-      if Exp /= 0 then
-
-         --  With the Exp format, it is not known how many output digits to
-         --  generate, as leading zeros must be ignored. Computing too many
-         --  digits and then truncating the output will not give the closest
-         --  output, it is necessary to round at the correct digit.
-
-         --  The general approach is as follows: as long as no digits have
-         --  been generated, compute the Aft next digits (without rounding).
-         --  Once a non-zero digit is generated, determine the exact number
-         --  of digits remaining and compute them with rounding.
-
-         --  Since a large number of iterations might be necessary in case
-         --  of Aft = 1, the following optimization would be desirable.
-
-         --  Count the number Z of leading zero bits in the integer
-         --  representation of X, and start with producing Aft + Z * 1000 /
-         --  3322 digits in the first scaled division.
-
-         --  However, the floating-point routines are still used now ???
-
-         System.Img_Real.Set_Image_Real (Long_Long_Float (Item), To, Last,
-            Fore, Aft, Exp);
-         return;
-      end if;
-
-      if Exact then
-         declare
-            D : constant Integer := Integer'Min (A, Max_Digits
-                                                            - (Num'Fore - 1));
-            Y : constant Int64   := Int64'Min (Int64 (-Num'Small), -1)
-                                     * 10**Integer'Max (0, D);
-            Z : constant Int64   := Int64'Min (Int64 (-(1.0 / Num'Small)), -1)
-                                     * 10**Integer'Max (0, -D);
-         begin
-            Put_Scaled (X, Y, Z, A, -D);
-         end;
-
-      else -- not Exact
-         declare
-            E : constant Integer := Max_Digits - 1 + Scale;
-            D : constant Integer := Scale - 1;
-            Y : constant Int64   := Int64 (-Num'Small * 10.0**E);
-            Z : constant Int64   := -10**Max_Digits;
-         begin
-            Put_Scaled (X, Y, Z, A, -D);
-         end;
+      if not Exact then
+         Float_Aux.Puts (To, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_64 then
+         Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
       end if;
-
-      --  If only zero digits encountered, unit digit has not been output yet
-
-      if Last < To'First then
-         Pos := 0;
-
-      elsif Last > To'Last then
-         raise Layout_Error; -- Not enough room in the output variable
-      end if;
-
-      --  Always output digits up to the first one after the decimal point
-
-      while Pos >= -A loop
-         Put_Digit (0);
-      end loop;
    end Put;
 
 end Ada.Text_IO.Fixed_IO;
diff --git a/gcc/ada/libgnat/a-tifiio__128.adb b/gcc/ada/libgnat/a-tifiio__128.adb
new file mode 100644 (file)
index 0000000..f164209
--- /dev/null
@@ -0,0 +1,365 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 A D A . T E X T _ I O . F I X E D _ I O                  --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  Fixed point I/O
+--  ---------------
+
+--  The following text documents implementation details of the fixed point
+--  input/output routines in the GNAT runtime. The first part describes the
+--  general properties of fixed point types as defined by the Ada standard,
+--  including the Information Systems Annex.
+
+--  Subsequently these are reduced to implementation constraints and the impact
+--  of these constraints on a few possible approaches to input/output is given.
+--  Based on this analysis, a specific implementation is selected for use in
+--  the GNAT runtime. Finally, the chosen algorithm is analyzed numerically in
+--  order to provide user-level documentation on limits for range and precision
+--  of fixed point types as well as accuracy of input/output conversions.
+
+--  -------------------------------------------
+--  - General Properties of Fixed Point Types -
+--  -------------------------------------------
+
+--  Operations on fixed point types, other than input/output, are not important
+--  for the purpose of this document. Only the set of values that a fixed point
+--  type can represent and the input/output operations are significant.
+
+--  Values
+--  ------
+
+--  The set of values of a fixed point type comprise the integral multiples of
+--  a number called the small of the type. The small can be either a power of
+--  two, a power of ten or (if the implementation allows) an arbitrary strictly
+--  positive real value.
+
+--  Implementations need to support ordinary fixed point types with a precision
+--  of at least 24 bits, and (in order to comply with the Information Systems
+--  Annex) decimal fixed point types with at least 18 digits. For the rest, no
+--  requirements exist for the minimal small and range that must be supported.
+
+--  Operations
+--  ----------
+
+--  'Image and 'Wide_Image (see RM 3.5(34))
+
+--          These attributes return a decimal real literal best approximating
+--          the value (rounded away from zero if halfway between) with a
+--          single leading character that is either a minus sign or a space,
+--          one or more digits before the decimal point (with no redundant
+--          leading zeros), a decimal point, and N digits after the decimal
+--          point. For a subtype S, the value of N is S'Aft, the smallest
+--          positive integer such that (10**N)*S'Delta is greater or equal to
+--          one, see RM 3.5.10(5).
+
+--          For an arbitrary small, this means large number arithmetic needs
+--          to be performed.
+
+--  Put (see RM A.10.9(22-26))
+
+--          The requirements for Put add no extra constraints over the image
+--          attributes, although it would be nice to be able to output more
+--          than S'Aft digits after the decimal point for values of subtype S.
+
+--  'Value and 'Wide_Value attribute (RM 3.5(40-55))
+
+--          Since the input can be given in any base in the range 2..16,
+--          accurate conversion to a fixed point number may require
+--          arbitrary precision arithmetic if there is no limit on the
+--          magnitude of the small of the fixed point type.
+
+--  Get (see RM A.10.9(12-21))
+
+--          The requirements for Get are identical to those of the Value
+--          attribute.
+
+--  ------------------------------
+--  - Implementation Constraints -
+--  ------------------------------
+
+--  The requirements listed above for the input/output operations lead to
+--  significant complexity, if no constraints are put on supported smalls.
+
+--  Implementation Strategies
+--  -------------------------
+
+--  * Floating point arithmetic
+--  * Arbitrary-precision integer arithmetic
+--  * Fixed-precision integer arithmetic
+
+--  Although it seems convenient to convert fixed point numbers to floating
+--  point and then print them, this leads to a number of restrictions.
+--  The first one is precision. The widest floating-point type generally
+--  available has 53 bits of mantissa. This means that Fine_Delta cannot
+--  be less than 2.0**(-53).
+
+--  In GNAT, Fine_Delta is 2.0**(-63), and Duration for example is a 64-bit
+--  type. This means that a floating-point type with 63 bits of mantissa needs
+--  to be used, which is only generally available on the x86 architecture. It
+--  would still be possible to use multi-precision floating point to perform
+--  calculations using longer mantissas, but this is a much harder approach.
+
+--  The base conversions needed for input/output of (non-decimal) fixed point
+--  types can be seen as pairs of integer multiplications and divisions.
+
+--  Arbitrary-precision integer arithmetic would be suitable for the job at
+--  hand, but has the drawback that it is very heavy implementation-wise.
+--  Especially in embedded systems, where fixed point types are often used,
+--  it may not be desirable to require large amounts of storage and time
+--  for fixed I/O operations.
+
+--  Fixed-precision integer arithmetic has the advantage of simplicity and
+--  speed. For the most common fixed point types this would be a perfect
+--  solution. The downside however may be a too limited set of acceptable
+--  fixed point types.
+
+with Interfaces;
+with Ada.Text_IO.Fixed_Aux;
+with Ada.Text_IO.Float_Aux;
+with System.Img_Fixed_32;  use System.Img_Fixed_32;
+with System.Img_Fixed_64;  use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32;  use System.Val_Fixed_32;
+with System.Val_Fixed_64;  use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+
+package body Ada.Text_IO.Fixed_IO is
+
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
+
+   subtype Int32  is Interfaces.Integer_32;
+   subtype Int64  is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+   package Aux64 is new
+     Ada.Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+   package Aux128 is new
+     Ada.Text_IO.Fixed_Aux (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+   Exact : constant Boolean :=
+     (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
+     and then Num'Small >= 2.0**(-127)
+     and then Num'Small <= 2.0**127;
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   Need_128 : constant Boolean :=
+     Num'Object_Size > 64
+       or else Num'Small > 2.0**63
+       or else Num'Small < 2.0**(-63);
+   --  Throughout this generic body, we distinguish between the cases where
+   --  type Int32 is acceptable, where type Int64 is acceptable, and where
+   --  type Int128 is needed. These boolean constants are used to test for
+   --  these cases and since they are constant, only code for the relevant
+   --  case will be really included in the instance.
+
+   E : constant Natural :=
+         31 + 32 * Boolean'Pos (Need_64) + 64 * Boolean'Pos (Need_128);
+   --  T'Size - 1 for the selected Int{32,64,128}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+   F2 : constant Natural :=
+          F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+   F3 : constant Natural :=
+          F2 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+   F4 : constant Natural :=
+          F3 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+   F5 : constant Natural :=
+          F4 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+   F6 : constant Natural :=
+          F5 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+   F7 : constant Natural :=
+          F6 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F7;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+   --  whose small is Num'Small.
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Get (File, Width,
+                                Int128 (-Float'Ceiling (Num'Small)),
+                                Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_Input, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if not Exact then
+         Float_Aux.Gets (From, Long_Long_Float (Item), Last);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Gets (From, Last,
+                                 Int128 (-Float'Ceiling (Num'Small)),
+                                 Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (From, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (From, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_128 then
+         Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+                     Int128 (-Float'Ceiling (Num'Small)),
+                     Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Out, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if not Exact then
+         Float_Aux.Puts (To, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_128 then
+         Aux128.Puts (To, Int128'Integer_Value (Item), Aft, Exp,
+                      Int128 (-Float'Ceiling (Num'Small)),
+                      Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                      For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      end if;
+   end Put;
+
+end Ada.Text_IO.Fixed_IO;
index 214b5c8f2c3c4bf697b0cd383205527ebfa7a042..ddb52a5eebf178a6ac98ee1bacb744b6cb2e3f52 100644 (file)
@@ -47,7 +47,7 @@ package body Ada.Text_IO.Float_Aux is
    is
       Buf  : String (1 .. Field'Last);
       Stop : Integer := 0;
-      Ptr  : aliased Integer := 1;
+      Ptr  : aliased Integer;
 
    begin
       if Width /= 0 then
@@ -55,10 +55,10 @@ package body Ada.Text_IO.Float_Aux is
          String_Skip (Buf, Ptr);
       else
          Load_Real (File, Buf, Stop);
+         Ptr := 1;
       end if;
 
       Item := Scan_Real (Buf, Ptr'Access, Stop);
-
       Check_End_Of_Field (Buf, Stop, Ptr, Width);
    end Get;
 
@@ -79,8 +79,7 @@ package body Ada.Text_IO.Float_Aux is
       Last := Pos - 1;
 
    exception
-      when Constraint_Error =>
-         raise Data_Error;
+      when Constraint_Error => raise Data_Error;
    end Gets;
 
    ---------------
index 7bfc6133a27fa048e4e07e181e3d5a5d53217a9d..268ba4da606e9220118d2588136b90fc78c29c60 100644 (file)
 with Ada.Wide_Text_IO.Generic_Aux; use Ada.Wide_Text_IO.Generic_Aux;
 with Ada.Wide_Text_IO.Float_Aux;   use Ada.Wide_Text_IO.Float_Aux;
 
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
 package body Ada.Wide_Text_IO.Decimal_Aux is
 
-   -------------
-   -- Get_Dec --
-   -------------
-
-   function Get_Dec
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Integer
-   is
-      Buf  : String (1 .. Field'Last);
-      Ptr  : aliased Integer;
-      Stop : Integer := 0;
-      Item : Integer;
-
-   begin
-      if Width /= 0 then
-         Load_Width (File, Width, Buf, Stop);
-         String_Skip (Buf, Ptr);
-      else
-         Load_Real (File, Buf, Stop);
-         Ptr := 1;
-      end if;
-
-      Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
-      Check_End_Of_Field (Buf, Stop, Ptr, Width);
-      return Item;
-   end Get_Dec;
-
-   -------------
-   -- Get_LLD --
-   -------------
+   ---------
+   -- Get --
+   ---------
 
-   function Get_LLD
+   function Get
      (File  : File_Type;
       Width : Field;
-      Scale : Integer) return Long_Long_Integer
+      Scale : Integer) return Int
    is
       Buf  : String (1 .. Field'Last);
       Ptr  : aliased Integer;
       Stop : Integer := 0;
-      Item : Long_Long_Integer;
+      Item : Int;
 
    begin
       if Width /= 0 then
@@ -90,68 +57,42 @@ package body Ada.Wide_Text_IO.Decimal_Aux is
          Ptr := 1;
       end if;
 
-      Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
+      Item := Scan (Buf, Ptr'Access, Stop, Scale);
       Check_End_Of_Field (Buf, Stop, Ptr, Width);
       return Item;
-   end Get_LLD;
-
-   --------------
-   -- Gets_Dec --
-   --------------
-
-   function Gets_Dec
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer
-   is
-      Pos  : aliased Integer;
-      Item : Integer;
-
-   begin
-      String_Skip (From, Pos);
-      Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
-      return Item;
+   end Get;
 
-   exception
-      when Constraint_Error =>
-         Last.all := Pos - 1;
-         raise Data_Error;
-
-   end Gets_Dec;
+   ----------
+   -- Gets --
+   ----------
 
-   --------------
-   -- Gets_LLD --
-   --------------
-
-   function Gets_LLD
+   function Gets
      (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer
+      Last  : out Positive;
+      Scale : Integer) return Int
    is
       Pos  : aliased Integer;
-      Item : Long_Long_Integer;
+      Item : Int;
 
    begin
       String_Skip (From, Pos);
-      Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
+      Item := Scan (From, Pos'Access, From'Last, Scale);
+      Last := Pos - 1;
       return Item;
 
    exception
       when Constraint_Error =>
-         Last.all := Pos - 1;
+         Last := Pos - 1;
          raise Data_Error;
+   end Gets;
 
-   end Gets_LLD;
-
-   -------------
-   -- Put_Dec --
-   -------------
+   ---------
+   -- Put --
+   ---------
 
-   procedure Put_Dec
+   procedure Put
      (File  : File_Type;
-      Item  : Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
@@ -161,105 +102,51 @@ package body Ada.Wide_Text_IO.Decimal_Aux is
       Ptr : Natural := 0;
 
    begin
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
       Put_Item (File, Buf (1 .. Ptr));
-   end Put_Dec;
+   end Put;
 
-   -------------
-   -- Put_LLD --
-   -------------
+   ----------
+   -- Puts --
+   ----------
 
-   procedure Put_LLD
-     (File  : File_Type;
-      Item  : Long_Long_Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf : String (1 .. Field'Last);
-      Ptr : Natural := 0;
-
-   begin
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-      Put_Item (File, Buf (1 .. Ptr));
-   end Put_LLD;
-
-   --------------
-   -- Puts_Dec --
-   --------------
-
-   procedure Puts_Dec
+   procedure Puts
      (To    : out String;
-      Item  : Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer)
    is
-      Buf  : String (1 .. Field'Last);
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
       Fore : Integer;
       Ptr  : Natural := 0;
 
    begin
-      --  Compute Fore, allowing for Aft digits and the decimal dot
+      --  Compute Fore, allowing for the decimal dot and Aft digits
 
-      Fore := To'Length - Field'Max (1, Aft) - 1;
+      Fore := To'Length - 1 - Field'Max (1, Aft);
 
-      --  Allow for Exp and two more for E+ or E- if exponent present
+      --  Allow for Exp and one more for E if exponent present
 
       if Exp /= 0 then
-         Fore := Fore - 2 - Exp;
+         Fore := Fore - 1 - Field'Max (2, Exp);
       end if;
 
       --  Make sure we have enough room
 
-      if Fore < 1 then
+      if Fore < 1 + Boolean'Pos (Item < 0) then
          raise Layout_Error;
       end if;
 
       --  Do the conversion and check length of result
 
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
-      if Ptr > To'Length then
-         raise Layout_Error;
-      else
-         To := Buf (1 .. Ptr);
-      end if;
-   end Puts_Dec;
-
-   --------------
-   -- Puts_LLD --
-   --------------
-
-   procedure Puts_LLD
-     (To    : out String;
-      Item  : Long_Long_Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf  : String (1 .. Field'Last);
-      Fore : Integer;
-      Ptr  : Natural := 0;
-
-   begin
-      Fore :=
-        (if Exp = 0
-         then To'Length - 1 - Aft
-         else To'Length - 2 - Aft - Exp);
-
-      if Fore < 1 then
-         raise Layout_Error;
-      end if;
-
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
 
       if Ptr > To'Length then
          raise Layout_Error;
       else
          To := Buf (1 .. Ptr);
       end if;
-   end Puts_LLD;
+   end Puts;
 
 end Ada.Wide_Text_IO.Decimal_Aux;
index 0465455a373e13d82680dc259ed9100266767cf0..5c0c4d6766a301543696c4c877e4e65fa46715a7 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package contains the routines for Ada.Wide_Text_IO.Decimal_IO
---  that are shared among separate instantiations of this package. The
---  routines in the package are identical semantically to those declared
---  in Wide_Text_IO, except that default values have been supplied by the
---  generic, and the Num parameter has been replaced by Integer or
---  Long_Long_Integer, with an additional Scale parameter giving the
---  value of Num'Scale. In addition the Get routines return the value
---  rather than store it in an Out parameter.
+--  This package contains the implementation for Ada.Wide_Text_IO.Decimal_IO.
+--  Routines in this package are identical semantically to those in Decimal_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there is an
+--  additional Scale parameter giving the value of Num'Scale. In addition the
+--  Get routines return the value rather than store it in an Out parameter.
 
-private package Ada.Wide_Text_IO.Decimal_Aux is
+private generic
+   type Int is range <>;
 
-   function Get_Dec
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Integer;
+   with function Scan
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int;
 
-   function Get_LLD
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Long_Long_Integer;
+   with procedure Set_Image
+     (V     : Int;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural);
 
-   function Gets_Dec
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer;
+package Ada.Wide_Text_IO.Decimal_Aux is
 
-   function Gets_LLD
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer;
-
-   procedure Put_Dec
+   function Get
      (File  : File_Type;
-      Item  : Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+      Width : Field;
+      Scale : Integer) return Int;
 
-   procedure Put_LLD
+   procedure Put
      (File  : File_Type;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
 
-   procedure Puts_Dec
-     (To    : out String;
-      Item  : Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+   function Gets
+     (From  : String;
+      Last  : out Positive;
+      Scale : Integer) return Int;
 
-   procedure Puts_LLD
+   procedure Puts
      (To    : out String;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
index 5e328b231bcdf259175f4339eeab2f50101d2d50..b432cac6ce0a10371c70ca273faa131ae4c6ad3f 100644 (file)
 ------------------------------------------------------------------------------
 
 with Ada.Wide_Text_IO.Decimal_Aux;
-
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
 with System.WCh_Con; use System.WCh_Con;
 with System.WCh_WtS; use System.WCh_WtS;
 
 package body Ada.Wide_Text_IO.Decimal_IO is
 
-   package Aux renames Ada.Wide_Text_IO.Decimal_Aux;
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Aux32 is new
+     Ada.Wide_Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Wide_Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   Need64 : constant Boolean := Num'Size > 32;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
 
    Scale : constant Integer := Num'Scale;
 
@@ -49,12 +71,15 @@ package body Ada.Wide_Text_IO.Decimal_IO is
       Item  : out Num;
       Width : Field := 0)
    is
+      pragma Unsuppress (Range_Check);
+
    begin
-      if Num'Size > Integer'Size then
-         Item := Num'Fixed_Value (Aux.Get_LLD (File, Width, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
       else
-         Item := Num'Fixed_Value (Aux.Get_Dec (File, Width, Scale));
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
       end if;
+
    exception
       when Constraint_Error => raise Data_Error;
    end Get;
@@ -72,6 +97,8 @@ package body Ada.Wide_Text_IO.Decimal_IO is
       Item : out Num;
       Last : out Positive)
    is
+      pragma Unsuppress (Range_Check);
+
       S : constant String := Wide_String_To_String (From, WCEM_Upper);
       --  String on which we do the actual conversion. Note that the method
       --  used for wide character encoding is irrelevant, since if there is
@@ -79,16 +106,10 @@ package body Ada.Wide_Text_IO.Decimal_IO is
       --  Aux.Gets will raise Data_Error in any case.
 
    begin
-      if Num'Size > Integer'Size then
-         --  Item := Num'Fixed_Value
-         --  should write above, but gets assert error ???
-         Item := Num
-                   (Aux.Gets_LLD (S, Last'Unrestricted_Access, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
       else
-         --  Item := Num'Fixed_Value
-         --  should write above, but gets assert error ???
-         Item := Num
-                   (Aux.Gets_Dec (S, Last'Unrestricted_Access, Scale));
+         Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
       end if;
 
    exception
@@ -107,13 +128,12 @@ package body Ada.Wide_Text_IO.Decimal_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      if Num'Size > Integer'Size then
-         Aux.Put_LLD
-           (File, Long_Long_Integer'Integer_Value (Item),
-            Fore, Aft, Exp, Scale);
+      if Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
       else
-         Aux.Put_Dec
-           (File, Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
       end if;
    end Put;
 
@@ -136,12 +156,10 @@ package body Ada.Wide_Text_IO.Decimal_IO is
       S : String (To'First .. To'Last);
 
    begin
-      if Num'Size > Integer'Size then
-         Aux.Puts_LLD
-           (S, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
-
+      if Need64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
       else
-         Aux.Puts_Dec (S, Integer'Integer_Value (Item), Aft, Exp, Scale);
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
       end if;
 
       for J in S'Range loop
diff --git a/gcc/ada/libgnat/a-wtdeio__128.adb b/gcc/ada/libgnat/a-wtdeio__128.adb
new file mode 100644 (file)
index 0000000..6e23e08
--- /dev/null
@@ -0,0 +1,190 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--           A D A . W I D E _ T E X T _ I O . D E C I M A L _ I O          --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Text_IO.Decimal_Aux;
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+with System.WCh_Con;  use System.WCh_Con;
+with System.WCh_WtS;  use System.WCh_WtS;
+
+package body Ada.Wide_Text_IO.Decimal_IO is
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Wide_Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Wide_Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   package Aux128 is new
+     Ada.Wide_Text_IO.Decimal_Aux
+       (Int128,
+        Scan_Decimal128,
+        Set_Image_Decimal128);
+
+   Need64  : constant Boolean := Num'Size > 32;
+   Need128 : constant Boolean := Num'Size > 64;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable, where type Int64 is acceptable and where an Int128
+   --  is needed. These boolean constants are used to test for these cases and
+   --  since it is a constant, only code for the relevant case will be included
+   --  in the instance.
+
+   Scale : constant Integer := Num'Scale;
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_Input, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : Wide_String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+      S : constant String := Wide_String_To_String (From, WCEM_Upper);
+      --  String on which we do the actual conversion. Note that the method
+      --  used for wide character encoding is irrelevant, since if there is
+      --  a character outside the Standard.Character range then the call to
+      --  Aux.Gets will raise Data_Error in any case.
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Gets (S, Last, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if Need128 then
+         Aux128.Put
+           (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      else
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Output, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out Wide_String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+      S : String (To'First .. To'Last);
+
+   begin
+      if Need128 then
+         Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
+      end if;
+
+      for J in S'Range loop
+         To (J) := Wide_Character'Val (Character'Pos (S (J)));
+      end loop;
+   end Put;
+
+end Ada.Wide_Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-wtfiau.adb b/gcc/ada/libgnat/a-wtfiau.adb
new file mode 100644 (file)
index 0000000..d4a1534
--- /dev/null
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--             A D A . W I D E _ T E X T _ I O . F I X E D _ I O            --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Text_IO.Generic_Aux; use Ada.Wide_Text_IO.Generic_Aux;
+with Ada.Wide_Text_IO.Float_Aux;   use Ada.Wide_Text_IO.Float_Aux;
+
+package body Ada.Wide_Text_IO.Fixed_Aux is
+
+   ---------
+   -- Get --
+   ---------
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int
+   is
+      Buf  : String (1 .. Field'Last);
+      Ptr  : aliased Integer;
+      Stop : Integer := 0;
+      Item : Int;
+
+   begin
+      if Width /= 0 then
+         Load_Width (File, Width, Buf, Stop);
+         String_Skip (Buf, Ptr);
+      else
+         Load_Real (File, Buf, Stop);
+         Ptr := 1;
+      end if;
+
+      Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+      Check_End_Of_Field (Buf, Stop, Ptr, Width);
+      return Item;
+   end Get;
+
+   ----------
+   -- Gets --
+   ----------
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int
+   is
+      Pos  : aliased Integer;
+      Item : Int;
+
+   begin
+      String_Skip (From, Pos);
+      Item := Scan (From, Pos'Access, From'Last, Num, Den);
+      Last := Pos - 1;
+      return Item;
+
+   exception
+      when Constraint_Error =>
+         Last := Pos - 1;
+         raise Data_Error;
+   end Gets;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf : String (1 .. Field'Last);
+      Ptr : Natural := 0;
+
+   begin
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+      Put_Item (File, Buf (1 .. Ptr));
+   end Put;
+
+   ----------
+   -- Puts --
+   ----------
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
+      Fore : Integer;
+      Ptr  : Natural := 0;
+
+   begin
+      --  Compute Fore, allowing for the decimal dot and Aft digits
+
+      Fore := To'Length - 1 - Field'Max (1, Aft);
+
+      --  Allow for Exp and one more for E if exponent present
+
+      if Exp /= 0 then
+         Fore := Fore - 1 - Field'Max (2, Exp);
+      end if;
+
+      --  Make sure we have enough room
+
+      if Fore < 1 + Boolean'Pos (Item < 0) then
+         raise Layout_Error;
+      end if;
+
+      --  Do the conversion and check length of result
+
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+      if Ptr > To'Length then
+         raise Layout_Error;
+      else
+         To := Buf (1 .. Ptr);
+      end if;
+   end Puts;
+
+end Ada.Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-wtfiau.ads b/gcc/ada/libgnat/a-wtfiau.ads
new file mode 100644 (file)
index 0000000..f487931
--- /dev/null
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--             A D A . W I D E _ T E X T _ I O . F I X E D _ I O            --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the implementation for Ada.Wide_Text_IO.Fixed_IO.
+--  Routines in this package are identical semantically to those in Fixed_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there are
+--  additional Num and Den parameters giving the value of Num'Small, as well
+--  as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+--  routines return the value rather than store it in an Out parameter.
+
+private generic
+   type Int is range <>;
+
+   with function Scan
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int;
+      Den : Int) return Int;
+
+   with procedure Set_Image
+     (V    : Int;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural);
+
+package Ada.Wide_Text_IO.Fixed_Aux is
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int;
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int;
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+end Ada.Wide_Text_IO.Fixed_Aux;
index 9f1e724f6a01103b370bbc41fddb1e0506633f5f..00990af87d26c783ae4ccc97ac37422a17b15837 100644 (file)
@@ -2,7 +2,7 @@
 --                                                                          --
 --                         GNAT RUN-TIME COMPONENTS                         --
 --                                                                          --
---     A D A . T E X T _ I O . W I D E _ T E X T _ I O . F I X E D _ I O    --
+--             A D A . W I D E _ T E X T _ I O . F I X E D _ I O            --
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Interfaces;
+with Ada.Wide_Text_IO.Fixed_Aux;
 with Ada.Wide_Text_IO.Float_Aux;
-with System.WCh_Con; use System.WCh_Con;
-with System.WCh_WtS; use System.WCh_WtS;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.WCh_Con;      use System.WCh_Con;
+with System.WCh_WtS;      use System.WCh_WtS;
 
 package body Ada.Wide_Text_IO.Fixed_IO is
 
-   package Aux renames Ada.Wide_Text_IO.Float_Aux;
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Aux32 is new
+     Ada.Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+   package Aux64 is new
+     Ada.Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+   Exact : constant Boolean :=
+     (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
+     and then Num'Small >= 2.0**(-63)
+     and then Num'Small <= 2.0**63;
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
+
+   E : constant Natural := 31 + 32 * Boolean'Pos (Need_64);
+   --  T'Size - 1 for the selected Int{32,64}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+   F2 : constant Natural :=
+          F1 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+   F3 : constant Natural :=
+          F2 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+   F4 : constant Natural :=
+          F3 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+   F5 : constant Natural :=
+          F4 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+   F6 : constant Natural :=
+          F5 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F6;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64} and
+   --  whose small is Num'Small.
 
    ---------
    -- Get --
@@ -46,8 +105,22 @@ package body Ada.Wide_Text_IO.Fixed_IO is
       Item  : out Num;
       Width : Field := 0)
    is
+      pragma Unsuppress (Range_Check);
+
    begin
-      Aux.Get (File, Long_Long_Float (Item), Width);
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
 
    exception
       when Constraint_Error => raise Data_Error;
@@ -66,6 +139,8 @@ package body Ada.Wide_Text_IO.Fixed_IO is
       Item : out Num;
       Last : out Positive)
    is
+      pragma Unsuppress (Range_Check);
+
       S : constant String := Wide_String_To_String (From, WCEM_Upper);
       --  String on which we do the actual conversion. Note that the method
       --  used for wide character encoding is irrelevant, since if there is
@@ -73,7 +148,19 @@ package body Ada.Wide_Text_IO.Fixed_IO is
       --  Aux.Gets will raise Data_Error in any case.
 
    begin
-      Aux.Gets (S, Long_Long_Float (Item), Last);
+      if not Exact then
+         Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (S, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (S, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
 
    exception
       when Constraint_Error => raise Data_Error;
@@ -91,7 +178,19 @@ package body Ada.Wide_Text_IO.Fixed_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
    end Put;
 
    procedure Put
@@ -113,7 +212,19 @@ package body Ada.Wide_Text_IO.Fixed_IO is
       S : String (To'First .. To'Last);
 
    begin
-      Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      if not Exact then
+         Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      end if;
 
       for J in S'Range loop
          To (J) := Wide_Character'Val (Character'Pos (S (J)));
diff --git a/gcc/ada/libgnat/a-wtfiio__128.adb b/gcc/ada/libgnat/a-wtfiio__128.adb
new file mode 100644 (file)
index 0000000..7607d5c
--- /dev/null
@@ -0,0 +1,267 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--             A D A . W I D E _ T E X T _ I O . F I X E D _ I O            --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Wide_Text_IO.Fixed_Aux;
+with Ada.Wide_Text_IO.Float_Aux;
+with System.Img_Fixed_32;  use System.Img_Fixed_32;
+with System.Img_Fixed_64;  use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32;  use System.Val_Fixed_32;
+with System.Val_Fixed_64;  use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+with System.WCh_Con;       use System.WCh_Con;
+with System.WCh_WtS;       use System.WCh_WtS;
+
+package body Ada.Wide_Text_IO.Fixed_IO is
+
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
+
+   subtype Int32  is Interfaces.Integer_32;
+   subtype Int64  is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+   package Aux64 is new
+     Ada.Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+   package Aux128 is new
+     Ada.Wide_Text_IO.Fixed_Aux (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+   Exact : constant Boolean :=
+     (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
+     and then Num'Small >= 2.0**(-127)
+     and then Num'Small <= 2.0**127;
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   Need_128 : constant Boolean :=
+     Num'Object_Size > 64
+       or else Num'Small > 2.0**63
+       or else Num'Small < 2.0**(-63);
+   --  Throughout this generic body, we distinguish between the cases where
+   --  type Int32 is acceptable, where type Int64 is acceptable, and where
+   --  type Int128 is needed. These boolean constants are used to test for
+   --  these cases and since they are constant, only code for the relevant
+   --  case will be really included in the instance.
+
+   E : constant Natural :=
+         31 + 32 * Boolean'Pos (Need_64) + 64 * Boolean'Pos (Need_128);
+   --  T'Size - 1 for the selected Int{32,64,128}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+   F2 : constant Natural :=
+          F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+   F3 : constant Natural :=
+          F2 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+   F4 : constant Natural :=
+          F3 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+   F5 : constant Natural :=
+          F4 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+   F6 : constant Natural :=
+          F5 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+   F7 : constant Natural :=
+          F6 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F7;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+   --  whose small is Num'Small.
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Get (File, Width,
+                                Int128 (-Float'Ceiling (Num'Small)),
+                                Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_Input, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : Wide_String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+      S : constant String := Wide_String_To_String (From, WCEM_Upper);
+      --  String on which we do the actual conversion. Note that the method
+      --  used for wide character encoding is irrelevant, since if there is
+      --  a character outside the Standard.Character range then the call to
+      --  Aux.Gets will raise Data_Error in any case.
+
+   begin
+      if not Exact then
+         Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Gets (S, Last,
+                                 Int128 (-Float'Ceiling (Num'Small)),
+                                 Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (S, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (S, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_128 then
+         Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+                     Int128 (-Float'Ceiling (Num'Small)),
+                     Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Output, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out Wide_String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+      S : String (To'First .. To'Last);
+
+   begin
+      if not Exact then
+         Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_128 then
+         Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp,
+                      Int128 (-Float'Ceiling (Num'Small)),
+                      Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                      For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      end if;
+      for J in S'Range loop
+         To (J) := Wide_Character'Val (Character'Pos (S (J)));
+      end loop;
+   end Put;
+
+end Ada.Wide_Text_IO.Fixed_IO;
index 3daff0f7f5e739e95c47d2e1014e9f1d2b36fa20..6c2af9f2ce128d572f77ad8e9699239c53327024 100644 (file)
 with Ada.Wide_Wide_Text_IO.Generic_Aux; use Ada.Wide_Wide_Text_IO.Generic_Aux;
 with Ada.Wide_Wide_Text_IO.Float_Aux;   use Ada.Wide_Wide_Text_IO.Float_Aux;
 
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
 package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
 
-   -------------
-   -- Get_Dec --
-   -------------
-
-   function Get_Dec
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Integer
-   is
-      Buf  : String (1 .. Field'Last);
-      Ptr  : aliased Integer;
-      Stop : Integer := 0;
-      Item : Integer;
-
-   begin
-      if Width /= 0 then
-         Load_Width (File, Width, Buf, Stop);
-         String_Skip (Buf, Ptr);
-      else
-         Load_Real (File, Buf, Stop);
-         Ptr := 1;
-      end if;
-
-      Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
-      Check_End_Of_Field (Buf, Stop, Ptr, Width);
-      return Item;
-   end Get_Dec;
-
-   -------------
-   -- Get_LLD --
-   -------------
+   ---------
+   -- Get --
+   ---------
 
-   function Get_LLD
+   function Get
      (File  : File_Type;
       Width : Field;
-      Scale : Integer) return Long_Long_Integer
+      Scale : Integer) return Int
    is
       Buf  : String (1 .. Field'Last);
       Ptr  : aliased Integer;
       Stop : Integer := 0;
-      Item : Long_Long_Integer;
+      Item : Int;
 
    begin
       if Width /= 0 then
@@ -90,68 +57,42 @@ package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
          Ptr := 1;
       end if;
 
-      Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
+      Item := Scan (Buf, Ptr'Access, Stop, Scale);
       Check_End_Of_Field (Buf, Stop, Ptr, Width);
       return Item;
-   end Get_LLD;
-
-   --------------
-   -- Gets_Dec --
-   --------------
-
-   function Gets_Dec
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer
-   is
-      Pos  : aliased Integer;
-      Item : Integer;
-
-   begin
-      String_Skip (From, Pos);
-      Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
-      return Item;
+   end Get;
 
-   exception
-      when Constraint_Error =>
-         Last.all := Pos - 1;
-         raise Data_Error;
-
-   end Gets_Dec;
+   ----------
+   -- Gets --
+   ----------
 
-   --------------
-   -- Gets_LLD --
-   --------------
-
-   function Gets_LLD
+   function Gets
      (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer
+      Last  : out Positive;
+      Scale : Integer) return Int
    is
       Pos  : aliased Integer;
-      Item : Long_Long_Integer;
+      Item : Int;
 
    begin
       String_Skip (From, Pos);
-      Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
-      Last.all := Pos - 1;
+      Item := Scan (From, Pos'Access, From'Last, Scale);
+      Last := Pos - 1;
       return Item;
 
    exception
       when Constraint_Error =>
-         Last.all := Pos - 1;
+         Last := Pos - 1;
          raise Data_Error;
+   end Gets;
 
-   end Gets_LLD;
-
-   -------------
-   -- Put_Dec --
-   -------------
+   ---------
+   -- Put --
+   ---------
 
-   procedure Put_Dec
+   procedure Put
      (File  : File_Type;
-      Item  : Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
@@ -161,103 +102,51 @@ package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
       Ptr : Natural := 0;
 
    begin
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
       Put_Item (File, Buf (1 .. Ptr));
-   end Put_Dec;
+   end Put;
 
-   -------------
-   -- Put_LLD --
-   -------------
+   ----------
+   -- Puts --
+   ----------
 
-   procedure Put_LLD
-     (File  : File_Type;
-      Item  : Long_Long_Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf : String (1 .. Field'Last);
-      Ptr : Natural := 0;
-
-   begin
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-      Put_Item (File, Buf (1 .. Ptr));
-   end Put_LLD;
-
-   --------------
-   -- Puts_Dec --
-   --------------
-
-   procedure Puts_Dec
+   procedure Puts
      (To    : out String;
-      Item  : Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer)
    is
-      Buf  : String (1 .. Field'Last);
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
       Fore : Integer;
       Ptr  : Natural := 0;
 
    begin
-      --  Compute Fore, allowing for Aft digits and the decimal dot
+      --  Compute Fore, allowing for the decimal dot and Aft digits
 
-      Fore := To'Length - Field'Max (1, Aft) - 1;
+      Fore := To'Length - 1 - Field'Max (1, Aft);
 
-      --  Allow for Exp and two more for E+ or E- if exponent present
+      --  Allow for Exp and one more for E if exponent present
 
       if Exp /= 0 then
-         Fore := Fore - 2 - Exp;
+         Fore := Fore - 1 - Field'Max (2, Exp);
       end if;
 
       --  Make sure we have enough room
 
-      if Fore < 1 then
+      if Fore < 1 + Boolean'Pos (Item < 0) then
          raise Layout_Error;
       end if;
 
       --  Do the conversion and check length of result
 
-      Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
-      if Ptr > To'Length then
-         raise Layout_Error;
-      else
-         To := Buf (1 .. Ptr);
-      end if;
-   end Puts_Dec;
-
-   --------------
-   -- Puts_LLD --
-   --------------
-
-   procedure Puts_LLD
-     (To    : out String;
-      Item  : Long_Long_Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer)
-   is
-      Buf  : String (1 .. Field'Last);
-      Fore : Integer;
-      Ptr  : Natural := 0;
-
-   begin
-      Fore :=
-        (if Exp = 0 then To'Length - 1 - Aft else To'Length - 2 - Aft - Exp);
-
-      if Fore < 1 then
-         raise Layout_Error;
-      end if;
-
-      Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+      Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
 
       if Ptr > To'Length then
          raise Layout_Error;
       else
          To := Buf (1 .. Ptr);
       end if;
-   end Puts_LLD;
+   end Puts;
 
 end Ada.Wide_Wide_Text_IO.Decimal_Aux;
index b493b80b193700074f6dbf171df07be1a89a7647..962f47921106d86042581dd9a79cda75e3e4a5d3 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package contains the routines for Ada.Wide_Wide_Text_IO.Decimal_IO
---  that are shared among separate instantiations of this package. The
---  routines in the package are identical semantically to those declared
---  in Wide_Wide_Text_IO, except that default values have been supplied by the
---  generic, and the Num parameter has been replaced by Integer or
---  Long_Long_Integer, with an additional Scale parameter giving the
---  value of Num'Scale. In addition the Get routines return the value
---  rather than store it in an Out parameter.
+--  This package contains implementation for Ada.Wide_Wide_Text_IO.Decimal_IO
+--  Routines in this package are identical semantically to those in Decimal_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there is an
+--  additional Scale parameter giving the value of Num'Scale. In addition the
+--  Get routines return the value rather than store it in an Out parameter.
 
-private package Ada.Wide_Wide_Text_IO.Decimal_Aux is
+private generic
+   type Int is range <>;
 
-   function Get_Dec
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Integer;
+   with function Scan
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int;
 
-   function Get_LLD
-     (File  : File_Type;
-      Width : Field;
-      Scale : Integer) return Long_Long_Integer;
+   with procedure Set_Image
+     (V     : Int;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural);
 
-   function Gets_Dec
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Integer;
+package Ada.Wide_Wide_Text_IO.Decimal_Aux is
 
-   function Gets_LLD
-     (From  : String;
-      Last  : not null access Positive;
-      Scale : Integer) return Long_Long_Integer;
-
-   procedure Put_Dec
+   function Get
      (File  : File_Type;
-      Item  : Integer;
-      Fore  : Field;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+      Width : Field;
+      Scale : Integer) return Int;
 
-   procedure Put_LLD
+   procedure Put
      (File  : File_Type;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Fore  : Field;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
 
-   procedure Puts_Dec
-     (To    : out String;
-      Item  : Integer;
-      Aft   : Field;
-      Exp   : Field;
-      Scale : Integer);
+   function Gets
+     (From  : String;
+      Last  : out Positive;
+      Scale : Integer) return Int;
 
-   procedure Puts_LLD
+   procedure Puts
      (To    : out String;
-      Item  : Long_Long_Integer;
+      Item  : Int;
       Aft   : Field;
       Exp   : Field;
       Scale : Integer);
index 4cc27380ae46614d2094d0335587dec7d3ab2c93..cd269149734e93c91198bf0248253539fc4156fd 100644 (file)
 ------------------------------------------------------------------------------
 
 with Ada.Wide_Wide_Text_IO.Decimal_Aux;
-
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
 with System.WCh_Con; use System.WCh_Con;
 with System.WCh_WtS; use System.WCh_WtS;
 
 package body Ada.Wide_Wide_Text_IO.Decimal_IO is
 
-   package Aux renames Ada.Wide_Wide_Text_IO.Decimal_Aux;
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Aux32 is new
+     Ada.Wide_Wide_Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Wide_Wide_Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   Need64 : constant Boolean := Num'Size > 32;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
 
    Scale : constant Integer := Num'Scale;
 
@@ -49,12 +71,15 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
       Item  : out Num;
       Width : Field := 0)
    is
+      pragma Unsuppress (Range_Check);
+
    begin
-      if Num'Size > Integer'Size then
-         Item := Num'Fixed_Value (Aux.Get_LLD (File, Width, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
       else
-         Item := Num'Fixed_Value (Aux.Get_Dec (File, Width, Scale));
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
       end if;
+
    exception
       when Constraint_Error => raise Data_Error;
    end Get;
@@ -72,6 +97,8 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
       Item : out Num;
       Last : out Positive)
    is
+      pragma Unsuppress (Range_Check);
+
       S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
       --  String on which we do the actual conversion. Note that the method
       --  used for wide character encoding is irrelevant, since if there is
@@ -79,16 +106,10 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
       --  Aux.Gets will raise Data_Error in any case.
 
    begin
-      if Num'Size > Integer'Size then
-         --  Item := Num'Fixed_Value
-         --  should write above, but gets assert error ???
-         Item := Num
-                   (Aux.Gets_LLD (S, Last'Unrestricted_Access, Scale));
+      if Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
       else
-         --  Item := Num'Fixed_Value
-         --  should write above, but gets assert error ???
-         Item := Num
-                   (Aux.Gets_Dec (S, Last'Unrestricted_Access, Scale));
+         Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
       end if;
 
    exception
@@ -107,18 +128,12 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      if Num'Size > Integer'Size then
-         Aux.Put_LLD
---           (File, Long_Long_Integer'Integer_Value (Item),
---  ???
-           (File, Long_Long_Integer (Item),
-            Fore, Aft, Exp, Scale);
+      if Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
       else
-         Aux.Put_Dec
---           (File, Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
---  ???
-           (File, Integer (Item), Fore, Aft, Exp, Scale);
-
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
       end if;
    end Put;
 
@@ -141,16 +156,10 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
       S : String (To'First .. To'Last);
 
    begin
-      if Num'Size > Integer'Size then
---       Aux.Puts_LLD
---         (S, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
---  ???
-         Aux.Puts_LLD
-           (S, Long_Long_Integer (Item), Aft, Exp, Scale);
+      if Need64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
       else
---       Aux.Puts_Dec (S, Integer'Integer_Value (Item), Aft, Exp, Scale);
---  ???
-         Aux.Puts_Dec (S, Integer (Item), Aft, Exp, Scale);
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
       end if;
 
       for J in S'Range loop
diff --git a/gcc/ada/libgnat/a-ztdeio__128.adb b/gcc/ada/libgnat/a-ztdeio__128.adb
new file mode 100644 (file)
index 0000000..e160a01
--- /dev/null
@@ -0,0 +1,190 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--      A D A . W I D E _ W I D E _ T E X T _ I O . D E C I M A L _ I O     --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Wide_Text_IO.Decimal_Aux;
+with System.Img_Decimal_32;  use System.Img_Decimal_32;
+with System.Img_Decimal_64;  use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32;  use System.Val_Decimal_32;
+with System.Val_Decimal_64;  use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+with System.WCh_Con;  use System.WCh_Con;
+with System.WCh_WtS;  use System.WCh_WtS;
+
+package body Ada.Wide_Wide_Text_IO.Decimal_IO is
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Wide_Wide_Text_IO.Decimal_Aux
+       (Int32,
+        Scan_Decimal32,
+        Set_Image_Decimal32);
+
+   package Aux64 is new
+     Ada.Wide_Wide_Text_IO.Decimal_Aux
+       (Int64,
+        Scan_Decimal64,
+        Set_Image_Decimal64);
+
+   package Aux128 is new
+     Ada.Wide_Wide_Text_IO.Decimal_Aux
+       (Int128,
+        Scan_Decimal128,
+        Set_Image_Decimal128);
+
+   Need64  : constant Boolean := Num'Size > 32;
+   Need128 : constant Boolean := Num'Size > 64;
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable, where type Int64 is acceptable and where an Int128
+   --  is needed. These boolean constants are used to test for these cases and
+   --  since it is a constant, only code for the relevant case will be included
+   --  in the instance.
+
+   Scale : constant Integer := Num'Scale;
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_Input, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : Wide_Wide_String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+      S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
+      --  String on which we do the actual conversion. Note that the method
+      --  used for wide character encoding is irrelevant, since if there is
+      --  a character outside the Standard.Character range then the call to
+      --  Aux.Gets will raise Data_Error in any case.
+
+   begin
+      if Need128 then
+         Item := Num'Fixed_Value (Aux128.Gets (S, Last, Scale));
+      elsif Need64 then
+         Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
+      else
+         Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if Need128 then
+         Aux128.Put
+           (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Put
+           (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      else
+         Aux32.Put
+           (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Output, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out Wide_Wide_String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+      S : String (To'First .. To'Last);
+
+   begin
+      if Need128 then
+         Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp, Scale);
+      elsif Need64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
+      end if;
+
+      for J in S'Range loop
+         To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
+      end loop;
+   end Put;
+
+end Ada.Wide_Wide_Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-ztfiau.adb b/gcc/ada/libgnat/a-ztfiau.adb
new file mode 100644 (file)
index 0000000..f26a16a
--- /dev/null
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--        A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O       --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Wide_Text_IO.Generic_Aux; use Ada.Wide_Wide_Text_IO.Generic_Aux;
+with Ada.Wide_Wide_Text_IO.Float_Aux;   use Ada.Wide_Wide_Text_IO.Float_Aux;
+
+package body Ada.Wide_Wide_Text_IO.Fixed_Aux is
+
+   ---------
+   -- Get --
+   ---------
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int
+   is
+      Buf  : String (1 .. Field'Last);
+      Ptr  : aliased Integer;
+      Stop : Integer := 0;
+      Item : Int;
+
+   begin
+      if Width /= 0 then
+         Load_Width (File, Width, Buf, Stop);
+         String_Skip (Buf, Ptr);
+      else
+         Load_Real (File, Buf, Stop);
+         Ptr := 1;
+      end if;
+
+      Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+      Check_End_Of_Field (Buf, Stop, Ptr, Width);
+      return Item;
+   end Get;
+
+   ----------
+   -- Gets --
+   ----------
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int
+   is
+      Pos  : aliased Integer;
+      Item : Int;
+
+   begin
+      String_Skip (From, Pos);
+      Item := Scan (From, Pos'Access, From'Last, Num, Den);
+      Last := Pos - 1;
+      return Item;
+
+   exception
+      when Constraint_Error =>
+         Last := Pos - 1;
+         raise Data_Error;
+   end Gets;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf : String (1 .. Field'Last);
+      Ptr : Natural := 0;
+
+   begin
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+      Put_Item (File, Buf (1 .. Ptr));
+   end Put;
+
+   ----------
+   -- Puts --
+   ----------
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      Buf  : String (1 .. Positive'Max (Field'Last, To'Length));
+      Fore : Integer;
+      Ptr  : Natural := 0;
+
+   begin
+      --  Compute Fore, allowing for the decimal dot and Aft digits
+
+      Fore := To'Length - 1 - Field'Max (1, Aft);
+
+      --  Allow for Exp and one more for E if exponent present
+
+      if Exp /= 0 then
+         Fore := Fore - 1 - Field'Max (2, Exp);
+      end if;
+
+      --  Make sure we have enough room
+
+      if Fore < 1 + Boolean'Pos (Item < 0) then
+         raise Layout_Error;
+      end if;
+
+      --  Do the conversion and check length of result
+
+      Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+      if Ptr > To'Length then
+         raise Layout_Error;
+      else
+         To := Buf (1 .. Ptr);
+      end if;
+   end Puts;
+
+end Ada.Wide_Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-ztfiau.ads b/gcc/ada/libgnat/a-ztfiau.ads
new file mode 100644 (file)
index 0000000..aac4e42
--- /dev/null
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--        A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O       --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the implementation for Ada.Wide_Wide_Text_IO.Fixed_IO
+--  Routines in this package are identical semantically to those in Fixed_IO,
+--  except that the default parameters have been removed because they are
+--  supplied explicitly by the calls from within these units, and there are
+--  additional Num and Den parameters giving the value of Num'Small, as well
+--  as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+--  routines return the value rather than store it in an Out parameter.
+
+private generic
+   type Int is range <>;
+
+   with function Scan
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int;
+      Den : Int) return Int;
+
+   with procedure Set_Image
+     (V    : Int;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural);
+
+package Ada.Wide_Wide_Text_IO.Fixed_Aux is
+
+   function Get
+     (File  : File_Type;
+      Width : Field;
+      Num   : Int;
+      Den   : Int) return Int;
+
+   procedure Put
+     (File : File_Type;
+      Item : Int;
+      Fore : Field;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+   function Gets
+     (From : String;
+      Last : out Positive;
+      Num  : Int;
+      Den  : Int) return Int;
+
+   procedure Puts
+     (To   : out String;
+      Item : Int;
+      Aft  : Field;
+      Exp  : Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+
+end Ada.Wide_Wide_Text_IO.Fixed_Aux;
index bfe24ac3edcef811c7184e07794483f1a3143f49..16e552d9733cc81b76079d42e7094b626c4eb320 100644 (file)
@@ -2,7 +2,7 @@
 --                                                                          --
 --                         GNAT RUN-TIME COMPONENTS                         --
 --                                                                          --
---     A D A . T E X T _ I O . W I D E _ T E X T _ I O . F I X E D _ I O    --
+--        A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O       --
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Interfaces;
+with Ada.Wide_Wide_Text_IO.Fixed_Aux;
 with Ada.Wide_Wide_Text_IO.Float_Aux;
-with System.WCh_Con; use System.WCh_Con;
-with System.WCh_WtS; use System.WCh_WtS;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.WCh_Con;      use System.WCh_Con;
+with System.WCh_WtS;      use System.WCh_WtS;
 
 package body Ada.Wide_Wide_Text_IO.Fixed_IO is
 
-   package Aux renames Ada.Wide_Wide_Text_IO.Float_Aux;
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Aux32 is new
+     Ada.Wide_Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+   package Aux64 is new
+     Ada.Wide_Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+   Exact : constant Boolean :=
+     (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
+     and then Num'Small >= 2.0**(-63)
+     and then Num'Small <= 2.0**63;
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   --  Throughout this generic body, we distinguish between the case where type
+   --  Int32 is acceptable and where type Int64 is needed. This Boolean is used
+   --  to test for these cases and since it is a constant, only code for the
+   --  relevant case will be included in the instance.
+
+   E : constant Natural := 31 + 32 * Boolean'Pos (Need_64);
+   --  T'Size - 1 for the selected Int{32,64}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+   F2 : constant Natural :=
+          F1 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+   F3 : constant Natural :=
+          F2 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+   F4 : constant Natural :=
+          F3 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+   F5 : constant Natural :=
+          F4 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+   F6 : constant Natural :=
+          F5 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F6;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64} and
+   --  whose small is Num'Small.
 
    ---------
    -- Get --
@@ -46,8 +105,22 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
       Item  : out Num;
       Width : Field := 0)
    is
+      pragma Unsuppress (Range_Check);
+
    begin
-      Aux.Get (File, Long_Long_Float (Item), Width);
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
 
    exception
       when Constraint_Error => raise Data_Error;
@@ -66,6 +139,8 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
       Item : out Num;
       Last : out Positive)
    is
+      pragma Unsuppress (Range_Check);
+
       S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
       --  String on which we do the actual conversion. Note that the method
       --  used for wide character encoding is irrelevant, since if there is
@@ -73,7 +148,19 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
       --  Aux.Gets will raise Data_Error in any case.
 
    begin
-      Aux.Gets (S, Long_Long_Float (Item), Last);
+      if not Exact then
+         Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (S, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (S, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
 
    exception
       when Constraint_Error => raise Data_Error;
@@ -91,7 +178,19 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
       Exp  : Field := Default_Exp)
    is
    begin
-      Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
    end Put;
 
    procedure Put
@@ -113,7 +212,19 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
       S : String (To'First .. To'Last);
 
    begin
-      Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      if not Exact then
+         Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      end if;
 
       for J in S'Range loop
          To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
diff --git a/gcc/ada/libgnat/a-ztfiio__128.adb b/gcc/ada/libgnat/a-ztfiio__128.adb
new file mode 100644 (file)
index 0000000..02ad613
--- /dev/null
@@ -0,0 +1,269 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--        A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O       --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Wide_Wide_Text_IO.Fixed_Aux;
+with Ada.Wide_Wide_Text_IO.Float_Aux;
+with System.Img_Fixed_32;  use System.Img_Fixed_32;
+with System.Img_Fixed_64;  use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32;  use System.Val_Fixed_32;
+with System.Val_Fixed_64;  use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+with System.WCh_Con;       use System.WCh_Con;
+with System.WCh_WtS;       use System.WCh_WtS;
+
+package body Ada.Wide_Wide_Text_IO.Fixed_IO is
+
+   --  Note: we still use the floating-point I/O routines for types whose small
+   --  is not a sufficiently small integer or the reciprocal thereof. This will
+   --  result in inaccuracies for fixed point types that require more precision
+   --  than is available in Long_Long_Float.
+
+   subtype Int32  is Interfaces.Integer_32;
+   subtype Int64  is Interfaces.Integer_64;
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Aux32 is new
+     Ada.Wide_Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+   package Aux64 is new
+     Ada.Wide_Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+   package Aux128 is new
+     Ada.Wide_Wide_Text_IO.Fixed_Aux
+      (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+   Exact : constant Boolean :=
+     (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+       or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small))
+     and then Num'Small >= 2.0**(-127)
+     and then Num'Small <= 2.0**127;
+   --  True if the exact algorithm implemented in Fixed_Aux can be used. The
+   --  condition is a Small which is either an integer or the reciprocal of an
+   --  integer with the appropriate magnitude.
+
+   Need_64 : constant Boolean :=
+     Num'Object_Size > 32
+       or else Num'Small > 2.0**31
+       or else Num'Small < 2.0**(-31);
+   Need_128 : constant Boolean :=
+     Num'Object_Size > 64
+       or else Num'Small > 2.0**63
+       or else Num'Small < 2.0**(-63);
+   --  Throughout this generic body, we distinguish between the cases where
+   --  type Int32 is acceptable, where type Int64 is acceptable, and where
+   --  type Int128 is needed. These boolean constants are used to test for
+   --  these cases and since they are constant, only code for the relevant
+   --  case will be really included in the instance.
+
+   E : constant Natural :=
+         31 + 32 * Boolean'Pos (Need_64) + 64 * Boolean'Pos (Need_128);
+   --  T'Size - 1 for the selected Int{32,64,128}
+
+   F0 : constant Natural := 0;
+   F1 : constant Natural :=
+          F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+   F2 : constant Natural :=
+          F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+   F3 : constant Natural :=
+          F2 +  9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+   F4 : constant Natural :=
+          F3 +  5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+   F5 : constant Natural :=
+          F4 +  3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+   F6 : constant Natural :=
+          F5 +  2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+   F7 : constant Natural :=
+          F6 +  1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+   --  Binary search for the number of digits - 1 before the decimal point of
+   --  the product 2.0**E * Num'Small.
+
+   For0 : constant Natural := 2 + F7;
+   --  Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+   --  whose small is Num'Small.
+
+   ---------
+   -- Get --
+   ---------
+
+   procedure Get
+     (File  : File_Type;
+      Item  : out Num;
+      Width : Field := 0)
+   is
+      pragma Unsuppress (Range_Check);
+
+   begin
+      if not Exact then
+         Float_Aux.Get (File, Long_Long_Float (Item), Width);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Get (File, Width,
+                                Int128 (-Float'Ceiling (Num'Small)),
+                                Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Get (File, Width,
+                               Int64 (-Float'Ceiling (Num'Small)),
+                               Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Get (File, Width,
+                               Int32 (-Float'Ceiling (Num'Small)),
+                               Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   procedure Get
+     (Item  : out Num;
+      Width : Field := 0)
+   is
+   begin
+      Get (Current_Input, Item, Width);
+   end Get;
+
+   procedure Get
+     (From : Wide_Wide_String;
+      Item : out Num;
+      Last : out Positive)
+   is
+      pragma Unsuppress (Range_Check);
+
+      S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
+      --  String on which we do the actual conversion. Note that the method
+      --  used for wide character encoding is irrelevant, since if there is
+      --  a character outside the Standard.Character range then the call to
+      --  Aux.Gets will raise Data_Error in any case.
+
+   begin
+      if not Exact then
+         Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+      elsif Need_128 then
+         Item := Num'Fixed_Value
+                   (Aux128.Gets (S, Last,
+                                 Int128 (-Float'Ceiling (Num'Small)),
+                                 Int128 (-Float'Ceiling (1.0 / Num'Small))));
+      elsif Need_64 then
+         Item := Num'Fixed_Value
+                   (Aux64.Gets (S, Last,
+                                Int64 (-Float'Ceiling (Num'Small)),
+                                Int64 (-Float'Ceiling (1.0 / Num'Small))));
+      else
+         Item := Num'Fixed_Value
+                   (Aux32.Gets (S, Last,
+                                Int32 (-Float'Ceiling (Num'Small)),
+                                Int32 (-Float'Ceiling (1.0 / Num'Small))));
+      end if;
+
+   exception
+      when Constraint_Error => raise Data_Error;
+   end Get;
+
+   ---------
+   -- Put --
+   ---------
+
+   procedure Put
+     (File : File_Type;
+      Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      if not Exact then
+         Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+      elsif Need_128 then
+         Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+                     Int128 (-Float'Ceiling (Num'Small)),
+                     Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+                    Int64 (-Float'Ceiling (Num'Small)),
+                    Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      else
+         Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+                    Int32 (-Float'Ceiling (Num'Small)),
+                    Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                    For0, Num'Aft);
+      end if;
+   end Put;
+
+   procedure Put
+     (Item : Num;
+      Fore : Field := Default_Fore;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+   begin
+      Put (Current_Output, Item, Fore, Aft, Exp);
+   end Put;
+
+   procedure Put
+     (To   : out Wide_Wide_String;
+      Item : Num;
+      Aft  : Field := Default_Aft;
+      Exp  : Field := Default_Exp)
+   is
+      S : String (To'First .. To'Last);
+
+   begin
+      if not Exact then
+         Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+      elsif Need_128 then
+         Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp,
+                      Int128 (-Float'Ceiling (Num'Small)),
+                      Int128 (-Float'Ceiling (1.0 / Num'Small)),
+                      For0, Num'Aft);
+      elsif Need_64 then
+         Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+                     Int64 (-Float'Ceiling (Num'Small)),
+                     Int64 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      else
+         Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+                     Int32 (-Float'Ceiling (Num'Small)),
+                     Int32 (-Float'Ceiling (1.0 / Num'Small)),
+                     For0, Num'Aft);
+      end if;
+
+      for J in S'Range loop
+         To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
+      end loop;
+   end Put;
+
+end Ada.Wide_Wide_Text_IO.Fixed_IO;
index 3895cdd0548b384ed1cf3823ab4ccded7a3898ec..9c6693b79a6e27cbc8803db5e2d4cfffef820cc7 100644 (file)
@@ -100,12 +100,37 @@ is
       Min : Result_Subtype := Default_Min;
       Max : Result_Subtype := Result_Subtype'Last) return Result_Subtype
    is
-      subtype IntV is Integer_64 range
-        Integer_64'Integer_Value (Min) ..
-        Integer_64'Integer_Value (Max);
-      function R is new Random_Discrete (Integer_64, IntV'First);
    begin
-      return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+      if Result_Subtype'Base'Size > 64 then
+         declare
+            subtype IntV is Integer_128 range
+              Integer_128'Integer_Value (Min) ..
+              Integer_128'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_128, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+
+      elsif Result_Subtype'Base'Size > 32 then
+         declare
+            subtype IntV is Integer_64 range
+              Integer_64'Integer_Value (Min) ..
+              Integer_64'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_64, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+
+      else
+         declare
+            subtype IntV is Integer_32 range
+              Integer_32'Integer_Value (Min) ..
+              Integer_32'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_32, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+      end if;
    end Random_Decimal_Fixed;
 
    ---------------------------
@@ -117,12 +142,37 @@ is
       Min : Result_Subtype := Default_Min;
       Max : Result_Subtype := Result_Subtype'Last) return Result_Subtype
    is
-      subtype IntV is Integer_64 range
-        Integer_64'Integer_Value (Min) ..
-        Integer_64'Integer_Value (Max);
-      function R is new Random_Discrete (Integer_64, IntV'First);
    begin
-      return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+      if Result_Subtype'Base'Size > 64 then
+         declare
+            subtype IntV is Integer_128 range
+              Integer_128'Integer_Value (Min) ..
+              Integer_128'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_128, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+
+      elsif Result_Subtype'Base'Size > 32 then
+         declare
+            subtype IntV is Integer_64 range
+              Integer_64'Integer_Value (Min) ..
+              Integer_64'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_64, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+
+      else
+         declare
+            subtype IntV is Integer_32 range
+              Integer_32'Integer_Value (Min) ..
+              Integer_32'Integer_Value (Max);
+            function R is new Random_Discrete (Integer_32, IntV'First);
+         begin
+            return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+         end;
+      end if;
    end Random_Ordinary_Fixed;
 
    ------------
diff --git a/gcc/ada/libgnat/s-arit32.adb b/gcc/ada/libgnat/s-arit32.adb
new file mode 100644 (file)
index 0000000..742f2e1
--- /dev/null
@@ -0,0 +1,182 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . A R I T H _ 3 2                       --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Ada.Unchecked_Conversion;
+
+package body System.Arith_32 is
+
+   pragma Suppress (Overflow_Check);
+   pragma Suppress (Range_Check);
+
+   subtype Uns32 is Interfaces.Unsigned_32;
+   subtype Uns64 is Interfaces.Unsigned_64;
+
+   use Interfaces;
+
+   function To_Int is new Ada.Unchecked_Conversion (Uns32, Int32);
+
+   -----------------------
+   -- Local Subprograms --
+   -----------------------
+
+   function "abs" (X : Int32) return Uns32 is
+     (if X = Int32'First
+      then 2**31
+      else Uns32 (Int32'(abs X)));
+   --  Convert absolute value of X to unsigned. Note that we can't just use
+   --  the expression of the Else since it overflows for X = Int32'First.
+
+   function Hi (A : Uns64) return Uns32 is (Uns32 (Shift_Right (A, 32)));
+   --  High order half of 64-bit value
+
+   function To_Neg_Int (A : Uns32) return Int32;
+   --  Convert to negative integer equivalent. If the input is in the range
+   --  0 .. 2**31, then the corresponding nonpositive signed integer (obtained
+   --  by negating the given value) is returned, otherwise constraint error is
+   --  raised.
+
+   function To_Pos_Int (A : Uns32) return Int32;
+   --  Convert to positive integer equivalent. If the input is in the range
+   --  0 .. 2**31 - 1, then the corresponding nonnegative signed integer is
+   --  returned, otherwise constraint error is raised.
+
+   procedure Raise_Error;
+   pragma No_Return (Raise_Error);
+   --  Raise constraint error with appropriate message
+
+   -----------------
+   -- Raise_Error --
+   -----------------
+
+   procedure Raise_Error is
+   begin
+      raise Constraint_Error with "32-bit arithmetic overflow";
+   end Raise_Error;
+
+   -------------------
+   -- Scaled_Divide --
+   -------------------
+
+   procedure Scaled_Divide32
+     (X, Y, Z : Int32;
+      Q, R    : out Int32;
+      Round   : Boolean)
+   is
+      Xu  : constant Uns32 := abs X;
+      Yu  : constant Uns32 := abs Y;
+      Zu  : constant Uns32 := abs Z;
+
+      D   : Uns64;
+      --  The dividend
+
+      Qu : Uns32;
+      Ru : Uns32;
+      --  Unsigned quotient and remainder
+
+   begin
+      --  First do the 64-bit multiplication
+
+      D := Uns64 (Xu) * Uns64 (Yu);
+
+      --  If dividend is too large, raise error
+
+      if Hi (D) >= Zu then
+         Raise_Error;
+
+      --  Then do the 64-bit division
+
+      else
+         Qu := Uns32 (D / Uns64 (Zu));
+         Ru := Uns32 (D rem Uns64 (Zu));
+      end if;
+
+      --  Deal with rounding case
+
+      if Round and then Ru > (Zu - Uns32'(1)) / Uns32'(2) then
+
+         --  Protect against wrapping around when rounding, by signaling
+         --  an overflow when the quotient is too large.
+
+         if Qu = Uns32'Last then
+            Raise_Error;
+         end if;
+
+         Qu := Qu + Uns32'(1);
+      end if;
+
+      --  Set final signs (RM 4.5.5(27-30))
+
+      --  Case of dividend (X * Y) sign positive
+
+      if (X >= 0 and then Y >= 0) or else (X < 0 and then Y < 0) then
+         R := To_Pos_Int (Ru);
+         Q := (if Z > 0 then To_Pos_Int (Qu) else To_Neg_Int (Qu));
+
+      --  Case of dividend (X * Y) sign negative
+
+      else
+         R := To_Neg_Int (Ru);
+         Q := (if Z > 0 then To_Neg_Int (Qu) else To_Pos_Int (Qu));
+      end if;
+   end Scaled_Divide32;
+
+   ----------------
+   -- To_Neg_Int --
+   ----------------
+
+   function To_Neg_Int (A : Uns32) return Int32 is
+      R : constant Int32 :=
+        (if A = 2**31 then Int32'First else -To_Int (A));
+      --  Note that we can't just use the expression of the Else, because it
+      --  overflows for A = 2**31.
+   begin
+      if R <= 0 then
+         return R;
+      else
+         Raise_Error;
+      end if;
+   end To_Neg_Int;
+
+   ----------------
+   -- To_Pos_Int --
+   ----------------
+
+   function To_Pos_Int (A : Uns32) return Int32 is
+      R : constant Int32 := To_Int (A);
+   begin
+      if R >= 0 then
+         return R;
+      else
+         Raise_Error;
+      end if;
+   end To_Pos_Int;
+
+end System.Arith_32;
diff --git a/gcc/ada/libgnat/s-arit32.ads b/gcc/ada/libgnat/s-arit32.ads
new file mode 100644 (file)
index 0000000..5656855
--- /dev/null
@@ -0,0 +1,55 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . A R I T H _ 3 2                       --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This unit provides software routines for doing arithmetic on 32-bit
+--  signed integer values in cases where either overflow checking is
+--  required, or intermediate results are longer than 32 bits.
+
+with Interfaces;
+
+package System.Arith_32 is
+   pragma Pure;
+
+   subtype Int32 is Interfaces.Integer_32;
+
+   procedure Scaled_Divide32
+     (X, Y, Z : Int32;
+      Q, R    : out Int32;
+      Round   : Boolean);
+   --  Performs the division of (X * Y) / Z, storing the quotient in Q
+   --  and the remainder in R. Constraint_Error is raised if Z is zero,
+   --  or if the quotient does not fit in 32 bits. Round indicates if
+   --  the result should be rounded. If Round is False, then Q, R are
+   --  the normal quotient and remainder from a truncating division.
+   --  If Round is True, then Q is the rounded quotient. The remainder
+   --  R is not affected by the setting of the Round flag.
+
+end System.Arith_32;
diff --git a/gcc/ada/libgnat/s-fode128.ads b/gcc/ada/libgnat/s-fode128.ads
new file mode 100644 (file)
index 0000000..200a020
--- /dev/null
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--              S Y S T E M . F O R E _ D E C I M A L _ 1 2 8               --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for decimal
+--  fixed point types up to 128-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_128 is
+   pragma Pure;
+
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Impl is new Fore_D (Int128);
+
+   function Fore_Decimal128 (Lo, Hi : Int128; Scale : Integer) return Natural
+     renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_128;
diff --git a/gcc/ada/libgnat/s-fode32.ads b/gcc/ada/libgnat/s-fode32.ads
new file mode 100644 (file)
index 0000000..15c07a4
--- /dev/null
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--               S Y S T E M . F O R E _ D E C I M A L _ 3 2                --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for decimal
+--  fixed point types up to 32-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_32 is
+   pragma Pure;
+
+   subtype Int32 is Interfaces.Integer_32;
+
+   package Impl is new Fore_D (Int32);
+
+   function Fore_Decimal32 (Lo, Hi : Int32; Scale : Integer) return Natural
+     renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_32;
diff --git a/gcc/ada/libgnat/s-fode64.ads b/gcc/ada/libgnat/s-fode64.ads
new file mode 100644 (file)
index 0000000..7e98185
--- /dev/null
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--               S Y S T E M . F O R E _ D E C I M A L _ 6 4                --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for decimal
+--  fixed point types up to 64-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_64 is
+   pragma Pure;
+
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Impl is new Fore_D (Int64);
+
+   function Fore_Decimal64 (Lo, Hi : Int64; Scale : Integer) return Natural
+     renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_64;
diff --git a/gcc/ada/libgnat/s-fofi128.ads b/gcc/ada/libgnat/s-fofi128.ads
new file mode 100644 (file)
index 0000000..d580ec8
--- /dev/null
@@ -0,0 +1,49 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . F O F I _ 1 2 8                       --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for ordinary
+--  fixed point types up to 128-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_128;
+with System.Fore_F;
+
+package System.Fore_Fixed_128 is
+   pragma Pure;
+
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Impl is new Fore_F (Int128, Arith_128.Scaled_Divide128);
+
+   function Fore_Fixed128 (Lo, Hi, Num, Den : Int128) return Natural
+     renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_128;
diff --git a/gcc/ada/libgnat/s-fofi32.ads b/gcc/ada/libgnat/s-fofi32.ads
new file mode 100644 (file)
index 0000000..5e48f55
--- /dev/null
@@ -0,0 +1,49 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 S Y S T E M . F O R E _ F I X E D _ 3 2                  --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for ordinary
+--  fixed point types up to 32-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_32;
+with System.Fore_F;
+
+package System.Fore_Fixed_32 is
+   pragma Pure;
+
+   subtype Int32 is Interfaces.Integer_32;
+
+   package Impl is new Fore_F (Int32, Arith_32.Scaled_Divide32);
+
+   function Fore_Fixed32 (Lo, Hi, Num, Den : Int32) return Natural
+     renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_32;
diff --git a/gcc/ada/libgnat/s-fofi64.ads b/gcc/ada/libgnat/s-fofi64.ads
new file mode 100644 (file)
index 0000000..588fac4
--- /dev/null
@@ -0,0 +1,49 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 S Y S T E M . F O R E _ F I X E D _ 6 4                  --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the 'Fore attribute for ordinary
+--  fixed point types up to 64-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_64;
+with System.Fore_F;
+
+package System.Fore_Fixed_64 is
+   pragma Pure;
+
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Impl is new Fore_F (Int64, Arith_64.Scaled_Divide64);
+
+   function Fore_Fixed64 (Lo, Hi, Num, Den : Int64) return Natural
+     renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_64;
diff --git a/gcc/ada/libgnat/s-fore.adb b/gcc/ada/libgnat/s-fore.adb
deleted file mode 100644 (file)
index 2a4aa81..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                          S Y S T E M . F O R E                           --
---                                                                          --
---                                 B o d y                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-package body System.Fore is
-
-   ----------
-   -- Fore --
-   ----------
-
-   function Fore (Lo, Hi : Long_Long_Float) return Natural is
-      T : Long_Long_Float := Long_Long_Float'Max (abs Lo, abs Hi);
-      R : Natural;
-
-   begin
-      --  Initial value of 2 allows for sign and mandatory single digit
-
-      R := 2;
-
-      --  Loop to increase Fore as needed to include full range of values
-
-      while T >= 10.0 loop
-         T := T / 10.0;
-         R := R + 1;
-      end loop;
-
-      return R;
-   end Fore;
-end System.Fore;
diff --git a/gcc/ada/libgnat/s-fore.ads b/gcc/ada/libgnat/s-fore.ads
deleted file mode 100644 (file)
index 7d78952..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                          S Y S T E M . F O R E                           --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
---  This package contains the routine used for the 'Fore attribute
-
-package System.Fore is
-   pragma Pure;
-
-   function Fore (Lo, Hi : Long_Long_Float) return Natural;
-   --  Compute Fore attribute value for a fixed-point type. The parameters
-   --  are the low and high bounds values, converted to Long_Long_Float.
-
-end System.Fore;
diff --git a/gcc/ada/libgnat/s-fore_d.adb b/gcc/ada/libgnat/s-fore_d.adb
new file mode 100644 (file)
index 0000000..1141c67
--- /dev/null
@@ -0,0 +1,62 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                        S Y S T E M . F O R E _ D                         --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+package body System.Fore_D is
+
+   ------------------
+   -- Fore_Decimal --
+   ------------------
+
+   function Fore_Decimal (Lo, Hi : Int; Scale : Integer) return Natural is
+
+      function Negative_Abs (Val : Int) return Int is
+        (if Val <= 0 then Val else -Val);
+      --  Return the opposite of the absolute value of Val
+
+      T : Int := Int'Min (Negative_Abs (Lo), Negative_Abs (Hi));
+      F : Natural;
+
+   begin
+      --  Initial value of 2 allows for sign and mandatory single digit
+
+      F := 2;
+
+      --  Loop to increase Fore as needed to include full range of values
+
+      while T <= -10 loop
+         T := T / 10;
+         F := F + 1;
+      end loop;
+
+      return Natural'Max (F - Scale, 2);
+   end Fore_Decimal;
+
+end System.Fore_D;
diff --git a/gcc/ada/libgnat/s-fore_d.ads b/gcc/ada/libgnat/s-fore_d.ads
new file mode 100644 (file)
index 0000000..25e3449
--- /dev/null
@@ -0,0 +1,47 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                        S Y S T E M . F O R E _ D                         --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the Fore attribute of decimal
+--  fixed point types.
+
+generic
+
+   type Int is range <>;
+
+package System.Fore_D is
+   pragma Pure;
+
+   function Fore_Decimal (Lo, Hi : Int; Scale : Integer) return Natural;
+   --  Compute Fore attribute value for a decimal fixed point type. The
+   --  parameters are the low and high bounds (in units of delta) and the
+   --  scale.
+
+end System.Fore_D;
diff --git a/gcc/ada/libgnat/s-fore_f.adb b/gcc/ada/libgnat/s-fore_f.adb
new file mode 100644 (file)
index 0000000..b63d8d4
--- /dev/null
@@ -0,0 +1,109 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                        S Y S T E M . F O R E _ F                         --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+package body System.Fore_F is
+
+   Maxdigs : constant Natural := Int'Width - 2;
+   --  Maximum number of decimal digits that can be represented in an Int.
+   --  The "-2" accounts for the sign and one extra digit, since we need the
+   --  maximum number of 9's that can be represented, e.g. for the 64-bit case,
+   --  Integer_64'Width is 20 since the maximum value is approximately 9.2E+18
+   --  and has 19 digits, but the maximum number of 9's that can be represented
+   --  in Integer_64 is only 18.
+
+   --  The prerequisite of the implementation is that the scaled divide does
+   --  not overflow, which means that the absolute value of the bounds of
+   --  the subtype must be smaller than 10**Maxdigs * 2**(Int'Size - 1).
+   --  Otherwise Constraint_Error is raised by the scaled divide operation.
+
+   ----------------
+   -- Fore_Fixed --
+   ----------------
+
+   function Fore_Fixed (Lo, Hi, Num, Den : Int) return Natural is
+      pragma Assert (Num < 0 and then Den < 0);
+      --  Accept only negative numbers to allow -2**(Int'Size - 1)
+
+      function Negative_Abs (Val : Int) return Int is
+        (if Val <= 0 then Val else -Val);
+      --  Return the opposite of the absolute value of Val
+
+      T : Int := Int'Min (Negative_Abs (Lo), Negative_Abs (Hi));
+      F : Natural;
+
+   begin
+      --  Initial value of 2 allows for sign and mandatory single digit
+
+      F := 2;
+
+      --  If the Small is 1, then no scaling is needed
+
+      if Num = -1 and then Den = -1 then
+         null;
+
+      --  The easy case is when the Small is the reciprocal of an integer
+
+      elsif Num = -1 then
+         T := T / Den;
+
+      --  If the Small is an integer, compute Q and R such that
+
+      --    T * Small = Q * 10**Maxdigs - R
+
+      --  then reason on Q if it is non-zero or else on R.
+
+      else pragma Assert (Den = -1);
+         declare
+            Q, R : Int;
+
+         begin
+            Scaled_Divide (T, Num, -10**Maxdigs, Q, R, Round => False);
+
+            if Q /= 0 then
+               T := Q;
+               F := F + Maxdigs;
+            else
+               T := R;
+            end if;
+         end;
+      end if;
+
+      --  Loop to increase Fore as needed to include full range of values
+
+      while T <= -10 or else T >= 10 loop
+         T := T / 10;
+         F := F + 1;
+      end loop;
+
+      return F;
+   end Fore_Fixed;
+
+end System.Fore_F;
diff --git a/gcc/ada/libgnat/s-fore_f.ads b/gcc/ada/libgnat/s-fore_f.ads
new file mode 100644 (file)
index 0000000..15fcb72
--- /dev/null
@@ -0,0 +1,51 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                        S Y S T E M . F O R E _ F                         --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the Fore attribute of ordinary
+--  fixed point types whose Small is an integer or its reciprocal.
+
+generic
+
+   type Int is range <>;
+
+   with procedure Scaled_Divide
+          (X, Y, Z : Int;
+           Q, R : out Int;
+           Round : Boolean);
+
+package System.Fore_F is
+   pragma Pure;
+
+   function Fore_Fixed (Lo, Hi, Num, Den : Int) return Natural;
+   --  Compute Fore attribute value for an ordinary fixed point type with small
+   --  Num/Den. The parameters are the low and high bounds (in units of small).
+
+end System.Fore_F;
diff --git a/gcc/ada/libgnat/s-forrea.adb b/gcc/ada/libgnat/s-forrea.adb
new file mode 100644 (file)
index 0000000..cb74dc6
--- /dev/null
@@ -0,0 +1,57 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                     S Y S T E M . F O R E _ R E A L                      --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+package body System.Fore_Real is
+
+   ---------------
+   -- Fore_Real --
+   ---------------
+
+   function Fore_Real (Lo, Hi : Long_Long_Float) return Natural is
+      T : Long_Long_Float := Long_Long_Float'Max (abs Lo, abs Hi);
+      F : Natural;
+
+   begin
+      --  Initial value of 2 allows for sign and mandatory single digit
+
+      F := 2;
+
+      --  Loop to increase Fore as needed to include full range of values
+
+      while T >= 10.0 loop
+         T := T / 10.0;
+         F := F + 1;
+      end loop;
+
+      return F;
+   end Fore_Real;
+
+end System.Fore_Real;
diff --git a/gcc/ada/libgnat/s-forrea.ads b/gcc/ada/libgnat/s-forrea.ads
new file mode 100644 (file)
index 0000000..6b0a211
--- /dev/null
@@ -0,0 +1,42 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                     S Y S T E M . F O R E _ R E A L                      --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routine used for the Fore attribute of ordinary
+--  fixed point types whose Small is neither an integer nor its reciprocal.
+
+package System.Fore_Real is
+   pragma Pure;
+
+   function Fore_Real (Lo, Hi : Long_Long_Float) return Natural;
+   --  Compute Fore attribute value for a fixed point type. The parameters
+   --  are the low and high bounds, converted to Long_Long_Float.
+
+end System.Fore_Real;
diff --git a/gcc/ada/libgnat/s-imaged.adb b/gcc/ada/libgnat/s-imaged.adb
new file mode 100644 (file)
index 0000000..726b9d8
--- /dev/null
@@ -0,0 +1,81 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                        S Y S T E M . I M A G E _ D                       --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Img_Util; use System.Img_Util;
+
+package body System.Image_D is
+
+   -------------------
+   -- Image_Decimal --
+   -------------------
+
+   procedure Image_Decimal
+     (V     : Int;
+      S     : in out String;
+      P     : out Natural;
+      Scale : Integer)
+   is
+      pragma Assert (S'First = 1);
+
+   begin
+      --  Add space at start for non-negative numbers
+
+      if V >= 0 then
+         S (1) := ' ';
+         P := 1;
+      else
+         P := 0;
+      end if;
+
+      Set_Image_Decimal (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
+   end Image_Decimal;
+
+   -----------------------
+   -- Set_Image_Decimal --
+   -----------------------
+
+   procedure Set_Image_Decimal
+     (V     : Int;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural)
+   is
+      Digs : String := Int'Image (V);
+      --  Sign and digits of decimal value
+
+   begin
+      Set_Decimal_Digits (Digs, Digs'Length, S, P, Scale, Fore, Aft, Exp);
+   end Set_Image_Decimal;
+
+end System.Image_D;
diff --git a/gcc/ada/libgnat/s-imaged.ads b/gcc/ada/libgnat/s-imaged.ads
new file mode 100644 (file)
index 0000000..5c3f82a
--- /dev/null
@@ -0,0 +1,72 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . I M A G E _ D                        --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  decimal fixed point types, and also for conversion operations required in
+--  Text_IO.Decimal_IO for such types.
+
+generic
+
+   type Int is range <>;
+
+package System.Image_D is
+   pragma Pure;
+
+   procedure Image_Decimal
+     (V     : Int;
+      S     : in out String;
+      P     : out Natural;
+      Scale : Integer);
+   --  Computes fixed_type'Image (V), where V is the integer value (in units of
+   --  delta) of a decimal type whose Scale is as given and stores the result
+   --  S (1 .. P), updating P to the value of L. The image is given by the
+   --  rules in RM 3.5(34) for fixed-point type image functions. The caller
+   --  guarantees that S is long enough to hold the result and has a lower
+   --  bound of 1.
+
+   procedure Set_Image_Decimal
+     (V     : Int;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural);
+   --  Sets the image of V, where V is the integer value (in units of delta)
+   --  of a decimal type with the specified Scale, starting at S (P + 1) and
+   --  updating P to point to the last character stored, the caller promises
+   --  that the buffer is large enough and no check is made. Constraint_Error
+   --  will not necessarily be raised if this requirement is violated, since
+   --  it is perfectly valid to compile this unit with checks off. The Fore,
+   --  Aft and Exp values can be set to any valid values for the case of use
+   --  by Text_IO.Decimal_IO.
+
+end System.Image_D;
diff --git a/gcc/ada/libgnat/s-imagef.adb b/gcc/ada/libgnat/s-imagef.adb
new file mode 100644 (file)
index 0000000..2328474
--- /dev/null
@@ -0,0 +1,287 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . I M A G E _ F                        --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Image_I;
+with System.Img_Util; use System.Img_Util;
+
+package body System.Image_F is
+
+   package Image_I is new System.Image_I (Int);
+
+   procedure Set_Image_Integer
+     (V : Int;
+      S : in out String;
+      P : in out Natural)
+     renames Image_I.Set_Image_Integer;
+
+   --  The following section describes a specific implementation choice for
+   --  performing base conversions needed for output of values of a fixed
+   --  point type T with small T'Small. The goal is to be able to output
+   --  all values of fixed point types with a precision of 64 bits and a
+   --  small in the range 2.0**(-63) .. 2.0**63. The reasoning can easily
+   --  be adapted to fixed point types with a precision of 32 or 128 bits.
+
+   --  The chosen algorithm uses fixed precision integer arithmetic for
+   --  reasons of simplicity and efficiency. It is important to understand
+   --  in what ways the most simple and accurate approach to fixed point I/O
+   --  is limiting, before considering more complicated schemes.
+
+   --  Without loss of generality assume T has a range (-2.0**63) * T'Small
+   --  .. (2.0**63 - 1) * T'Small, and is output with Aft digits after the
+   --  decimal point and T'Fore - 1 before. If T'Small is integer, or
+   --  1.0 / T'Small is integer, let S = T'Small.
+
+   --  The idea is to convert a value X * S of type T to a 64-bit integer value
+   --  Q equal to 10.0**D * (X * S) rounded to the nearest integer, using only
+   --  a scaled integer divide of the form
+
+   --     Q = (X * Y) / Z,
+
+   --  where the variables X, Y, Z are 64-bit integers, and both multiplication
+   --  and division are done using full intermediate precision. Then the final
+   --  decimal value to be output is
+
+   --     Q * 10**(-D)
+
+   --  This value can be written to the output file or to the result string
+   --  according to the format described in RM A.3.10. The details of this
+   --  operation are omitted here.
+
+   --  A 64-bit value can represent all integers with 18 decimal digits, but
+   --  not all with 19 decimal digits. If the total number of requested ouput
+   --  digits (Fore - 1) + Aft is greater than 18 then, for purposes of the
+   --  conversion, Aft is adjusted to 18 - (Fore - 1). In that case, trailing
+   --  zeros can complete the output after writing the first 18 significant
+   --  digits, or the technique described in the next section can be used.
+   --  In addition, D cannot be smaller than -18, in order for 10.0**(-D) to
+   --  fit in a 64-bit integer.
+
+   --  The final expression for D is
+
+   --     D = Integer'Max (-18, Integer'Min (Aft, 18 - (Fore - 1)));
+
+   --  For Y and Z the following expressions can be derived:
+
+   --     Q = X * S * (10.0**D) = (X * Y) / Z
+
+   --  If S is an integer greater than or equal to one, then Fore must be at
+   --  least 20 in order to print T'First, which is at most -2.0**63. This
+   --  means that D < 0, so use
+
+   --    (1)   Y = -S and Z = -10**(-D)
+
+   --  If 1.0 / S is an integer greater than one, use
+
+   --    (2)   Y = -10**D and Z = -(1.0 / S), for D >= 0
+
+   --  or
+
+   --    (3)   Y = -1 and Z = -(1.0 / S) * 10**(-D), for D < 0
+
+   --  Negative values are used for nominator Y and denominator Z, so that S
+   --  can have a maximum value of 2.0**63 and a minimum of 2.0**(-63). For
+   --  -(1.0 / S) in -1 .. -9, Fore will still be 20, and D will be negative,
+   --  as (-2.0**63) / -9 is greater than 10**18. In these cases there is room
+   --  in the denominator for the extra decimal scaling required, so case (3)
+   --  will not overflow.
+
+   --  Using a scaled divide which truncates and returns a remainder R,
+   --  another K trailing digits can be calculated by computing the value
+   --  (R * (10.0**K)) / Z using another scaled divide. This procedure
+   --  can be repeated to compute an arbitrary number of digits in linear
+   --  time and storage. The last scaled divide should be rounded, with
+   --  a possible carry propagating to the more significant digits, to
+   --  ensure correct rounding of the unit in the last place.
+
+   Maxdigs : constant Natural := Int'Width - 2;
+   --  Maximum number of decimal digits that can be represented in an Int.
+   --  The "-2" accounts for the sign and one extra digit, since we need the
+   --  maximum number of 9's that can be represented, e.g. for the 64-bit case,
+   --  Integer_64'Width is 20 since the maximum value is approximately 9.2E+18
+   --  and has 19 digits, but the maximum number of 9's that can be represented
+   --  in Integer_64 is only 18.
+
+   --  The prerequisite of the implementation is that the first scaled divide
+   --  does not overflow, which means that the absolute value of the input X
+   --  must always be smaller than 10**Maxdigs * 2**(Int'Size - 1). Otherwise
+   --  Constraint_Error is raised by the scaled divide operation.
+
+   -----------------
+   -- Image_Fixed --
+   -----------------
+
+   procedure Image_Fixed
+     (V    : Int;
+      S    : in out String;
+      P    : out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural)
+   is
+      pragma Assert (S'First = 1);
+
+   begin
+      --  Add space at start for non-negative numbers
+
+      if V >= 0 then
+         S (1) := ' ';
+         P := 1;
+      else
+         P := 0;
+      end if;
+
+      Set_Image_Fixed (V, S, P, Num, Den, For0, Aft0, 1, Aft0, 0);
+   end Image_Fixed;
+
+   ---------------------
+   -- Set_Image_Fixed --
+   ---------------------
+
+   procedure Set_Image_Fixed
+     (V    : Int;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural)
+   is
+      pragma Assert (Num < 0 and then Den < 0);
+      --  Accept only negative numbers to allow -2**(Int'Size - 1)
+
+      pragma Assert (Num = -1 or else Den = -1);
+      --  Accept only integer or reciprocal of integer to control the
+      --  magnitude of the arithmetic operations below.
+
+      A : constant Natural :=
+            Boolean'Pos (Exp > 0) * Aft0 + Natural'Max (Aft, 1) + 1;
+      --  Number of digits after the decimal point to be computed. If Exp is
+      --  positive, we need to compute Aft decimal digits after the first non
+      --  zero digit and we are guaranteed there is at least one in the first
+      --  Aft0 digits (unless V is zero). In both cases, we compute one more
+      --  digit than requested so that Set_Decimal_Digits can round at Aft.
+
+      D : constant Integer :=
+            Integer'Max (-Maxdigs, Integer'Min (A, Maxdigs - (For0 - 1)));
+      Y : constant Int     := Num * 10**Integer'Max (0, D);
+      Z : constant Int     := Den * 10**Integer'Max (0, -D);
+      --  See the description of the algorithm above
+
+      AF : constant Natural := A - D;
+      --  Number of remaining digits to be computed after the first round. It
+      --  is larger than A if the first round does not compute all the digits
+      --  before the decimal point, i.e. (For0 - 1) larger than Maxdigs.
+
+      N : constant Natural := 1 + (AF + Maxdigs - 1) / Maxdigs;
+      --  Number of rounds of scaled divide to be performed
+
+      Q : Int;
+      --  Quotient of the scaled divide in this round. Only the first round
+      --  may yield more than Maxdigs digits. The sign is not significant.
+
+      Buf : String (1 .. Maxdigs);
+      Len : Natural;
+      --  Buffer for the image of the quotient
+
+      Digs  : String (1 .. N * Maxdigs + 1);
+      Ndigs : Natural := 0;
+      --  Concatenated image of the successive quotients
+
+      Scale : Integer := 0;
+      --  Exponent such that the result is Digs (1 .. NDigs) * 10**(-Scale)
+
+      XX : Int := V;
+      YY : Int := Y;
+      --  First two operands of the scaled divide
+
+   begin
+      --  Set the first character like Image, either minus or space
+
+      Digs (1) := (if V < 0 then '-' else ' ');
+      Ndigs := 1;
+
+      for J in 1 .. N loop
+         exit when XX = 0;
+
+         Scaled_Divide (XX, YY, Z, Q, R => XX, Round => False);
+
+         if J = 1 then
+            if Q /= 0 then
+               Set_Image_Integer (abs Q, Digs, Ndigs);
+            end if;
+
+            Scale := Scale + D;
+
+            --  Prepare for next round, if any
+
+            YY := 10**Maxdigs;
+
+         else
+            Len := 0;
+            Set_Image_Integer (abs Q, Buf, Len);
+
+            if Ndigs = 1 then
+               Digs (2 .. Len + 1) := Buf (1 .. Len);
+               Ndigs := Len + 1;
+
+            else
+               --  Pad the output with zeroes up to Maxdigs
+
+               for K in 1 .. Maxdigs - Len loop
+                  Digs (Ndigs + K) := '0';
+               end loop;
+
+               for K in 1 .. Len loop
+                  Digs (Ndigs + Maxdigs - Len + K) := Buf (K);
+               end loop;
+
+               Ndigs := Ndigs + Maxdigs;
+            end if;
+
+            Scale := Scale + Maxdigs;
+         end if;
+      end loop;
+
+      --  If no digit was output, this is zero
+
+      if Ndigs = 1 then
+         Digs (1 .. 2) := " 0";
+         Ndigs := 2;
+      end if;
+
+      Set_Decimal_Digits (Digs, Ndigs, S, P, Scale, Fore, Aft, Exp);
+   end Set_Image_Fixed;
+
+end System.Image_F;
diff --git a/gcc/ada/libgnat/s-imagef.ads b/gcc/ada/libgnat/s-imagef.ads
new file mode 100644 (file)
index 0000000..bd1fb15
--- /dev/null
@@ -0,0 +1,89 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . I M A G E _ F                        --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  ordinary fixed point types whose Small is an integer or its reciprocal,
+--  and also for conversion operations required in Text_IO.Fixed_IO for such
+--  types.
+
+generic
+
+   type Int is range <>;
+
+   with procedure Scaled_Divide
+          (X, Y, Z : Int;
+           Q, R : out Int;
+           Round : Boolean);
+
+package System.Image_F is
+   pragma Pure;
+
+   procedure Image_Fixed
+     (V    : Int;
+      S    : in out String;
+      P    : out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural);
+   --  Computes fixed_type'Image (V), where V is the integer value (in units of
+   --  small) of an ordinary fixed point type with small Num/Den, and stores
+   --  the result in S (1 .. P), updating P on return. The result is computed
+   --  according to the rules for image for fixed-point types (RM 3.5(34)).
+   --  For0 and Aft0 are the values of the Fore and Aft attributes for the
+   --  fixed point type whose mantissa type is Int and whose small is Num/Den.
+   --  This function is used only for fixed point whose Small is an integer or
+   --  its reciprocal (see package System.Img_Real for the handling of other
+   --  ordinary fixed-point types). The caller guarantees that S is long enough
+   --  to hold the result and has a lower bound of 1.
+
+   procedure Set_Image_Fixed
+     (V    : Int;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int;
+      Den  : Int;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural);
+   --  Sets the image of V, where V is the integer value (in units of small)
+   --  of a fixed point type with small Num/Den, starting at S (P + 1) and
+   --  updating P to point to the last character stored, the caller promises
+   --  that the buffer is large enough and no check is made. Constraint_Error
+   --  will not necessarily be raised if this requirement is violated, since
+   --  it is perfectly valid to compile this unit with checks off. For0 and
+   --  Aft0 are the values of the Fore and Aft attributes for the fixed point
+   --  type whose mantissa type is Int and whose small is Num/Den. The Fore,
+   --  Aft and Exp can be set to any valid values for use by Text_IO.Fixed_IO.
+
+end System.Image_F;
diff --git a/gcc/ada/libgnat/s-imde128.ads b/gcc/ada/libgnat/s-imde128.ads
new file mode 100644 (file)
index 0000000..cffd0c0
--- /dev/null
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--               S Y S T E M . I M G _ D E C I M A L _ 1 2 8                --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  decimal fixed point types up to 128-bit mantissa, and also for conversion
+--  operations required in Text_IO.Decimal_IO for them.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_128 is
+   pragma Pure;
+
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Impl is new Image_D (Int128);
+
+   procedure Image_Decimal128
+     (V     : Int128;
+      S     : in out String;
+      P     : out Natural;
+      Scale : Integer)
+     renames Impl.Image_Decimal;
+
+   procedure Set_Image_Decimal128
+     (V     : Int128;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural)
+     renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_128;
diff --git a/gcc/ada/libgnat/s-imde32.ads b/gcc/ada/libgnat/s-imde32.ads
new file mode 100644 (file)
index 0000000..bf19e9c
--- /dev/null
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                S Y S T E M . I M G _ D E C I M A L _ 3 2                 --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  decimal fixed point types up to 32-bit mantissa, and also for conversion
+--  operations required in Text_IO.Decimal_IO for such types.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_32 is
+   pragma Pure;
+
+   subtype Int32 is Interfaces.Integer_32;
+
+   package Impl is new Image_D (Int32);
+
+   procedure Image_Decimal32
+     (V     : Int32;
+      S     : in out String;
+      P     : out Natural;
+      Scale : Integer)
+     renames Impl.Image_Decimal;
+
+   procedure Set_Image_Decimal32
+     (V     : Int32;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural)
+     renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_32;
diff --git a/gcc/ada/libgnat/s-imde64.ads b/gcc/ada/libgnat/s-imde64.ads
new file mode 100644 (file)
index 0000000..dfc8403
--- /dev/null
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                S Y S T E M . I M G _ D E C I M A L _ 6 4                 --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  decimal fixed point types up to 64-bit mantissa, and also for conversion
+--  operations required in Text_IO.Decimal_IO for such types.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_64 is
+   pragma Pure;
+
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Impl is new Image_D (Int64);
+
+   procedure Image_Decimal64
+     (V     : Int64;
+      S     : in out String;
+      P     : out Natural;
+      Scale : Integer)
+     renames Impl.Image_Decimal;
+
+   procedure Set_Image_Decimal64
+     (V     : Int64;
+      S     : in out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural)
+     renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_64;
diff --git a/gcc/ada/libgnat/s-imfi128.ads b/gcc/ada/libgnat/s-imfi128.ads
new file mode 100644 (file)
index 0000000..24fdf97
--- /dev/null
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                 S Y S T E M . I M G _ F I X E D _ 1 2 8                  --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  ordinary fixed point types up to 128-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_128;
+with System.Image_F;
+
+package System.Img_Fixed_128 is
+   pragma Pure;
+
+   subtype Int128 is Interfaces.Integer_128;
+
+   package Impl is new Image_F (Int128, Arith_128.Scaled_Divide128);
+
+   procedure Image_Fixed128
+     (V    : Int128;
+      S    : in out String;
+      P    : out Natural;
+      Num  : Int128;
+      Den  : Int128;
+      For0 : Natural;
+      Aft0 : Natural)
+     renames Impl.Image_Fixed;
+
+   procedure Set_Image_Fixed128
+     (V    : Int128;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int128;
+      Den  : Int128;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural)
+     renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_128;
diff --git a/gcc/ada/libgnat/s-imfi32.ads b/gcc/ada/libgnat/s-imfi32.ads
new file mode 100644 (file)
index 0000000..8c425df
--- /dev/null
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                  S Y S T E M . I M G _ F I X E D _ 3 2                   --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  ordinary fixed point types up to 32-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_32;
+with System.Image_F;
+
+package System.Img_Fixed_32 is
+   pragma Pure;
+
+   subtype Int32 is Interfaces.Integer_32;
+
+   package Impl is new Image_F (Int32, Arith_32.Scaled_Divide32);
+
+   procedure Image_Fixed32
+     (V    : Int32;
+      S    : in out String;
+      P    : out Natural;
+      Num  : Int32;
+      Den  : Int32;
+      For0 : Natural;
+      Aft0 : Natural)
+     renames Impl.Image_Fixed;
+
+   procedure Set_Image_Fixed32
+     (V    : Int32;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int32;
+      Den  : Int32;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural)
+     renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_32;
diff --git a/gcc/ada/libgnat/s-imfi64.ads b/gcc/ada/libgnat/s-imfi64.ads
new file mode 100644 (file)
index 0000000..9045bf6
--- /dev/null
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                  S Y S T E M . I M G _ F I X E D _ 6 4                   --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Image attribute for
+--  ordinary fixed point types up to 64-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_64;
+with System.Image_F;
+
+package System.Img_Fixed_64 is
+   pragma Pure;
+
+   subtype Int64 is Interfaces.Integer_64;
+
+   package Impl is new Image_F (Int64, Arith_64.Scaled_Divide64);
+
+   procedure Image_Fixed64
+     (V    : Int64;
+      S    : in out String;
+      P    : out Natural;
+      Num  : Int64;
+      Den  : Int64;
+      For0 : Natural;
+      Aft0 : Natural)
+     renames Impl.Image_Fixed;
+
+   procedure Set_Image_Fixed64
+     (V    : Int64;
+      S    : in out String;
+      P    : in out Natural;
+      Num  : Int64;
+      Den  : Int64;
+      For0 : Natural;
+      Aft0 : Natural;
+      Fore : Natural;
+      Aft  : Natural;
+      Exp  : Natural)
+     renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_64;
diff --git a/gcc/ada/libgnat/s-imgdec.adb b/gcc/ada/libgnat/s-imgdec.adb
deleted file mode 100644 (file)
index 840dadb..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                        S Y S T E M . I M G _ D E C                       --
---                                                                          --
---                                 B o d y                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-with System.Img_Int; use System.Img_Int;
-
-package body System.Img_Dec is
-
-   -------------------
-   -- Image_Decimal --
-   -------------------
-
-   procedure Image_Decimal
-     (V     : Integer;
-      S     : in out String;
-      P     : out Natural;
-      Scale : Integer)
-   is
-      pragma Assert (S'First = 1);
-
-   begin
-      --  Add space at start for non-negative numbers
-
-      if V >= 0 then
-         S (1) := ' ';
-         P := 1;
-      else
-         P := 0;
-      end if;
-
-      Set_Image_Decimal (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
-   end Image_Decimal;
-
-   ------------------------
-   -- Set_Decimal_Digits --
-   ------------------------
-
-   procedure Set_Decimal_Digits
-     (Digs  : in out String;
-      NDigs : Natural;
-      S     : out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural)
-   is
-      pragma Assert (NDigs >= 1);
-      pragma Assert (Digs'First = 1);
-      pragma Assert (Digs'First < Digs'Last);
-
-      Minus : constant Boolean := (Digs (Digs'First) = '-');
-      --  Set True if input is negative
-
-      Zero : Boolean := (Digs (Digs'First + 1) = '0');
-      --  Set True if input is exactly zero (only case when a leading zero
-      --  is permitted in the input string given to this procedure). This
-      --  flag can get set later if rounding causes the value to become zero.
-
-      FD : Natural := 2;
-      --  First digit position of digits remaining to be processed
-
-      LD : Natural := NDigs;
-      --  Last digit position of digits remaining to be processed
-
-      ND : Natural := NDigs - 1;
-      --  Number of digits remaining to be processed (LD - FD + 1)
-
-      Digits_Before_Point : Integer := ND - Scale;
-      --  Number of digits before decimal point in the input value. This
-      --  value can be negative if the input value is less than 0.1, so
-      --  it is an indication of the current exponent. Digits_Before_Point
-      --  is adjusted if the rounding step generates an extra digit.
-
-      Digits_After_Point : constant Natural := Integer'Max (1, Aft);
-      --  Digit positions after decimal point in result string
-
-      Expon : Integer;
-      --  Integer value of exponent
-
-      procedure Round (N : Integer);
-      --  Round the number in Digs. N is the position of the last digit to be
-      --  retained in the rounded position (rounding is based on Digs (N + 1)
-      --  FD, LD, ND are reset as necessary if required. Note that if the
-      --  result value rounds up (e.g. 9.99 => 10.0), an extra digit can be
-      --  placed in the sign position as a result of the rounding, this is
-      --  the case in which FD is adjusted. The call to Round has no effect
-      --  if N is outside the range FD .. LD.
-
-      procedure Set (C : Character);
-      pragma Inline (Set);
-      --  Sets character C in output buffer
-
-      procedure Set_Blanks_And_Sign (N : Integer);
-      --  Sets leading blanks and minus sign if needed. N is the number of
-      --  positions to be filled (a minus sign is output even if N is zero
-      --  or negative, For a positive value, if N is non-positive, then
-      --  a leading blank is filled.
-
-      procedure Set_Digits (S, E : Natural);
-      pragma Inline (Set_Digits);
-      --  Set digits S through E from Digs, no effect if S > E
-
-      procedure Set_Zeroes (N : Integer);
-      pragma Inline (Set_Zeroes);
-      --  Set N zeroes, no effect if N is negative
-
-      -----------
-      -- Round --
-      -----------
-
-      procedure Round (N : Integer) is
-         D : Character;
-
-         pragma Assert (NDigs >= 1);
-         pragma Assert (Digs'First = 1);
-         pragma Assert (Digs'First < Digs'Last);
-
-      begin
-         --  Nothing to do if rounding past the last digit we have
-
-         if N >= LD then
-            return;
-
-         --  Cases of rounding before the initial digit
-
-         elsif N < FD then
-
-            --  The result is zero, unless we are rounding just before
-            --  the first digit, and the first digit is five or more.
-
-            if N = 1 and then Digs (Digs'First + 1) >= '5' then
-               Digs (Digs'First) := '1';
-            else
-               Digs (Digs'First) := '0';
-               Zero := True;
-            end if;
-
-            Digits_Before_Point := Digits_Before_Point + 1;
-            FD := 1;
-            LD := 1;
-            ND := 1;
-
-         --  Normal case of rounding an existing digit
-
-         else
-            LD := N;
-            pragma Assert (LD >= 1);
-            --  In this case, we have N < LD and N >= FD. FD is a Natural,
-            --  So we can conclude, LD >= 1
-            ND := LD - 1;
-            pragma Assert (N + 1 <= Digs'Last);
-
-            if Digs (N + 1) >= '5' then
-               for J in reverse Digs'First + 1 .. Digs'First + N - 1 loop
-                  pragma Assert (Digs (J) in '0' .. '9' | ' ' | '-');
-                  --  Because it is a decimal image, we can assume that
-                  --  it can only contain these characters.
-                  D := Character'Succ (Digs (J));
-
-                  if D <= '9' then
-                     Digs (J) := D;
-                     return;
-                  else
-                     Digs (J) := '0';
-                  end if;
-               end loop;
-
-               --  Here the rounding overflows into the sign position. That's
-               --  OK, because we already captured the value of the sign and
-               --  we are in any case destroying the value in the Digs buffer
-
-               Digs (Digs'First) := '1';
-               FD := 1;
-               ND := ND + 1;
-               Digits_Before_Point := Digits_Before_Point + 1;
-            end if;
-         end if;
-      end Round;
-
-      ---------
-      -- Set --
-      ---------
-
-      procedure Set (C : Character) is
-      begin
-         pragma Assert (P >= (S'First - 1) and P < S'Last and
-                        P < Natural'Last);
-         --  No check is done as documented in the header : updating P to
-         --  point to the last character stored, the caller promises that the
-         --  buffer is large enough and no check is made for this.
-         --  Constraint_Error will not necessarily be raised if this
-         --  requirement is violated, since it is perfectly valid to compile
-         --  this unit with checks off.
-         --
-         --  Due to codepeer limitation, codepeer should be used with switch:
-         --   -no-propagation system.img_dec.set_decimal_digits.set
-         P := P + 1;
-         S (P) := C;
-      end Set;
-
-      -------------------------
-      -- Set_Blanks_And_Sign --
-      -------------------------
-
-      procedure Set_Blanks_And_Sign (N : Integer) is
-         W : Integer := N;
-
-      begin
-         if Minus then
-            W := W - 1;
-
-            for J in 1 .. W loop
-               Set (' ');
-            end loop;
-
-            Set ('-');
-
-         else
-            for J in 1 .. W loop
-               Set (' ');
-            end loop;
-         end if;
-      end Set_Blanks_And_Sign;
-
-      ----------------
-      -- Set_Digits --
-      ----------------
-
-      procedure Set_Digits (S, E : Natural) is
-      begin
-         pragma Assert (S >= Digs'First and E <= Digs'Last);
-         --  S and E should be in the Digs array range
-         --  TBC: Analysis should be completed
-         for J in S .. E loop
-            Set (Digs (J));
-         end loop;
-      end Set_Digits;
-
-      ----------------
-      -- Set_Zeroes --
-      ----------------
-
-      procedure Set_Zeroes (N : Integer) is
-      begin
-         for J in 1 .. N loop
-            Set ('0');
-         end loop;
-      end Set_Zeroes;
-
-   --  Start of processing for Set_Decimal_Digits
-
-   begin
-      --  Case of exponent given
-
-      if Exp > 0 then
-         Set_Blanks_And_Sign (Fore - 1);
-         Round (Digits_After_Point + 2);
-
-         Set (Digs (FD));
-         FD := FD + 1;
-         pragma Assert (ND >= 1);
-         ND := ND - 1;
-         Set ('.');
-
-         if ND >= Digits_After_Point then
-            Set_Digits (FD, FD + Digits_After_Point - 1);
-         else
-            Set_Digits (FD, LD);
-            Set_Zeroes (Digits_After_Point - ND);
-         end if;
-
-         --  Calculate exponent. The number of digits before the decimal point
-         --  in the input is Digits_Before_Point, and the number of digits
-         --  before the decimal point in the output is 1, so we can get the
-         --  exponent as the difference between these two values. The one
-         --  exception is for the value zero, which by convention has an
-         --  exponent of +0.
-
-         Expon := (if Zero then 0 else Digits_Before_Point - 1);
-         Set ('E');
-         ND := 0;
-
-         if Expon >= 0 then
-            Set ('+');
-            Set_Image_Integer (Expon, Digs, ND);
-         else
-            Set ('-');
-            Set_Image_Integer (-Expon, Digs, ND);
-         end if;
-
-         Set_Zeroes (Exp - ND - 1);
-         Set_Digits (1, ND);
-         return;
-
-      --  Case of no exponent given. To make these cases clear, we use
-      --  examples. For all the examples, we assume Fore = 2, Aft = 3.
-      --  A P in the example input string is an implied zero position,
-      --  not included in the input string.
-
-      else
-         --  Round at correct position
-         --    Input: 4PP      => unchanged
-         --    Input: 400.03   => unchanged
-         --    Input  3.4567   => 3.457
-         --    Input: 9.9999   => 10.000
-         --    Input: 0.PPP5   => 0.001
-         --    Input: 0.PPP4   => 0
-         --    Input: 0.00003  => 0
-
-         Round (LD - (Scale - Digits_After_Point));
-
-         --  No digits before point in input
-         --    Input: .123   Output: 0.123
-         --    Input: .PP3   Output: 0.003
-
-         if Digits_Before_Point <= 0 then
-            Set_Blanks_And_Sign (Fore - 1);
-            Set ('0');
-            Set ('.');
-
-            declare
-               DA : Natural := Digits_After_Point;
-               --  Digits remaining to output after point
-
-               LZ : constant Integer := Integer'Min (DA, -Digits_Before_Point);
-               --  Number of leading zeroes after point. Note: there used to be
-               --  a Max of this result with zero, but that's redundant, since
-               --  we know DA is positive, and because of the test above, we
-               --  know that -Digits_Before_Point >= 0.
-
-            begin
-               Set_Zeroes (LZ);
-               DA := DA - LZ;
-
-               if DA < ND then
-
-                  --  Note: it is definitely possible for the above condition
-                  --  to be True, for example:
-
-                  --    V => 1234, Scale => 5, Fore => 0, After => 1, Exp => 0
-
-                  --  but in this case DA = 0, ND = 1, FD = 1, FD + DA-1 = 0
-                  --  so the arguments in the call are (1, 0) meaning that no
-                  --  digits are output.
-
-                  --  No obvious example exists where the following call to
-                  --  Set_Digits actually outputs some digits, but we lack a
-                  --  proof that no such example exists.
-
-                  --  So it is safer to retain this call, even though as a
-                  --  result it is hard (or perhaps impossible) to create a
-                  --  coverage test for the inlined code of the call.
-
-                  Set_Digits (FD, FD + DA - 1);
-
-               else
-                  Set_Digits (FD, LD);
-                  Set_Zeroes (DA - ND);
-               end if;
-            end;
-
-         --  At least one digit before point in input
-
-         else
-            --  Less digits in input than are needed before point
-            --    Input: 1PP  Output: 100.000
-
-            if ND < Digits_Before_Point then
-
-               --  Special case, if the input is the single digit 0, then we
-               --  do not want 000.000, but instead 0.000.
-
-               if ND = 1 and then Digs (FD) = '0' then
-                  Set_Blanks_And_Sign (Fore - 1);
-                  Set ('0');
-
-               --  Normal case where we need to output scaling zeroes
-
-               else
-                  Set_Blanks_And_Sign (Fore - Digits_Before_Point);
-                  Set_Digits (FD, LD);
-                  Set_Zeroes (Digits_Before_Point - ND);
-               end if;
-
-               --  Set period and zeroes after the period
-
-               Set ('.');
-               Set_Zeroes (Digits_After_Point);
-
-            --  Input has full amount of digits before decimal point
-
-            else
-               Set_Blanks_And_Sign (Fore - Digits_Before_Point);
-               pragma Assert (FD + Digits_Before_Point - 1 >= 0);
-               --  In this branch, we have Digits_Before_Point > 0. It is the
-               --  else of test (Digits_Before_Point <= 0)
-               Set_Digits (FD, FD + Digits_Before_Point - 1);
-               Set ('.');
-               Set_Digits (FD + Digits_Before_Point, LD);
-               Set_Zeroes (Digits_After_Point - (ND - Digits_Before_Point));
-            end if;
-         end if;
-      end if;
-   end Set_Decimal_Digits;
-
-   -----------------------
-   -- Set_Image_Decimal --
-   -----------------------
-
-   procedure Set_Image_Decimal
-     (V     : Integer;
-      S     : in out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural)
-   is
-      Digs : String := Integer'Image (V);
-      --  Sign and digits of decimal value
-
-   begin
-      Set_Decimal_Digits (Digs, Digs'Length, S, P, Scale, Fore, Aft, Exp);
-   end Set_Image_Decimal;
-
-end System.Img_Dec;
diff --git a/gcc/ada/libgnat/s-imgdec.ads b/gcc/ada/libgnat/s-imgdec.ads
deleted file mode 100644 (file)
index d45a05f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . I M G _ D E C                        --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
---  Image for decimal fixed types where the size of the corresponding integer
---  type does not exceed Integer'Size (also used for Text_IO.Decimal_IO output)
-
-package System.Img_Dec is
-   pragma Pure;
-
-   procedure Image_Decimal
-     (V     : Integer;
-      S     : in out String;
-      P     : out Natural;
-      Scale : Integer);
-   --  Computes fixed_type'Image (V), where V is the integer value (in units of
-   --  delta) of a decimal type whose Scale is as given and stores the result
-   --  S (1 .. P), updating P to the value of L. The image is given by the
-   --  rules in RM 3.5(34) for fixed-point type image functions. The caller
-   --  guarantees that S is long enough to hold the result. S need not have a
-   --  lower bound of 1.
-
-   procedure Set_Image_Decimal
-     (V     : Integer;
-      S     : in out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural);
-   --  Sets the image of V, where V is the integer value (in units of delta)
-   --  of a decimal type with the given Scale, starting at S (P + 1), updating
-   --  P to point to the last character stored, the caller promises that the
-   --  buffer is large enough and no check is made for this. Constraint_Error
-   --  will not necessarily be raised if this requirement is violated, since
-   --  it is perfectly valid to compile this unit with checks off. The Fore,
-   --  Aft and Exp values can be set to any valid values for the case of use
-   --  by Text_IO.Decimal_IO. Note that there is no leading space stored.
-
-   procedure Set_Decimal_Digits
-     (Digs  : in out String;
-      NDigs : Natural;
-      S     : out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural);
-   --  This procedure has the same semantics as Set_Image_Decimal, except that
-   --  the value in Digs (1 .. NDigs) is given as a string of decimal digits
-   --  preceded by either a minus sign or a space (i.e. the integer image of
-   --  the value in units of delta). The call may destroy the value in Digs,
-   --  which is why Digs is in-out (this happens if rounding is required).
-   --  Set_Decimal_Digits is shared by all the decimal image routines.
-
-end System.Img_Dec;
diff --git a/gcc/ada/libgnat/s-imglld.adb b/gcc/ada/libgnat/s-imglld.adb
deleted file mode 100644 (file)
index c70f409..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . I M G _ L L D                        --
---                                                                          --
---                                 B o d y                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-with System.Img_Dec; use System.Img_Dec;
-
-package body System.Img_LLD is
-
-   -----------------------------
-   -- Image_Long_Long_Decimal --
-   ----------------------------
-
-   procedure Image_Long_Long_Decimal
-     (V     : Long_Long_Integer;
-      S     : in out String;
-      P     : out Natural;
-      Scale : Integer)
-   is
-      pragma Assert (S'First = 1);
-
-   begin
-      --  Add space at start for non-negative numbers
-
-      if V >= 0 then
-         S (1) := ' ';
-         P := 1;
-      else
-         P := 0;
-      end if;
-
-      Set_Image_Long_Long_Decimal
-        (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
-   end Image_Long_Long_Decimal;
-
-   ---------------------------------
-   -- Set_Image_Long_Long_Decimal --
-   ---------------------------------
-
-   procedure Set_Image_Long_Long_Decimal
-     (V     : Long_Long_Integer;
-      S     : in out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural)
-   is
-      Digs : String := Long_Long_Integer'Image (V);
-      --  Sign and digits of decimal value
-
-   begin
-      Set_Decimal_Digits (Digs, Digs'Length, S, P, Scale, Fore, Aft, Exp);
-   end Set_Image_Long_Long_Decimal;
-
-end System.Img_LLD;
diff --git a/gcc/ada/libgnat/s-imglld.ads b/gcc/ada/libgnat/s-imglld.ads
deleted file mode 100644 (file)
index fdb25b4..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT RUN-TIME COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . I M G _ L L D                        --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
---  Image for decimal fixed types where the size of the corresponding integer
---  type does exceeds Integer'Size (also used for Text_IO.Decimal_IO output)
-
-package System.Img_LLD is
-   pragma Pure;
-
-   procedure Image_Long_Long_Decimal
-     (V     : Long_Long_Integer;
-      S     : in out String;
-      P     : out Natural;
-      Scale : Integer);
-   --  Computes fixed_type'Image (V), where V is the integer value (in units of
-   --  delta) of a decimal type whose Scale is as given and store the result in
-   --  S (P + 1 .. L), updating P to the value of L. The image is given by the
-   --  rules in RM 3.5(34) for fixed-point type image functions. The caller
-   --  guarantees that S is long enough to hold the result. S need not have a
-   --  lower bound of 1.
-
-   procedure Set_Image_Long_Long_Decimal
-     (V     : Long_Long_Integer;
-      S     : in out String;
-      P     : in out Natural;
-      Scale : Integer;
-      Fore  : Natural;
-      Aft   : Natural;
-      Exp   : Natural);
-   --  Sets the image of V, where V is the integer value (in units of delta)
-   --  of a decimal type with the given Scale, starting at S (P + 1), updating
-   --  P to point to the last character stored, the caller promises that the
-   --  buffer is large enough and no check is made for this. Constraint_Error
-   --  will not necessarily be raised if this requirement is violated, since
-   --  it is perfectly valid to compile this unit with checks off. The Fore,
-   --  Aft and Exp values can be set to any valid values for the case of use
-   --  by Text_IO.Decimal_IO. Note that there is no leading space stored.
-
-end System.Img_LLD;
index 45d0ae59b7bf11d2b1d95be460475d8c7d49208c..03d30bdf9d733c08b623a9e82a2389f9d9274b1d 100644 (file)
@@ -47,10 +47,10 @@ package body System.Img_Real is
    --  in very high precision floating-point output.
 
    --  Note that in the following, the "-2" accounts for the sign and one
-   --  extra digits, since we need the maximum number of 9's that can be
-   --  supported, e.g. for the normal 64 bit case, Long_Long_Integer'Width
-   --  is 21, since the maximum value (approx 1.6 * 10**19) has 20 digits,
-   --  but the maximum number of 9's that can be supported is 19.
+   --  extra digit, since we need the maximum number of 9's that can be
+   --  represented, e.g. for the 64-bit case, Long_Long_Unsigned'Width is
+   --  21, since the maximum value (approx 1.8E+19) has 20 digits, but the
+   --  maximum number of 9's that can be represented is only 19.
 
    Maxdigs : constant :=
                Natural'Min
@@ -58,7 +58,6 @@ package body System.Img_Real is
 
    Unsdigs : constant := Unsigned'Width - 2;
    --  Number of digits that can be converted using type Unsigned
-   --  See above for the explanation of the -2.
 
    Maxscaling : constant := 5000;
    --  Max decimal scaling required during conversion of floating-point
@@ -88,11 +87,8 @@ package body System.Img_Real is
       --  Decide whether a blank should be prepended before the call to
       --  Set_Image_Real. We generate a blank for positive values, and
       --  also for positive zeroes. For negative zeroes, we generate a
-      --  space only if Signed_Zeroes is True (the RM only permits the
-      --  output of -0.0 on targets where this is the case). We can of
-      --  course still see a -0.0 on a target where Signed_Zeroes is
-      --  False (since this attribute refers to the proper handling of
-      --  negative zeroes, not to their existence). We do not generate
+      --  blank only if Signed_Zeros is False (the RM only permits the
+      --  output of -0.0 when Signed_Zeros is True). We do not generate
       --  a blank for positive infinity, since we output an explicit +.
 
       if (not Is_Negative (V) and then V <= Long_Long_Float'Last)
@@ -150,7 +146,7 @@ package body System.Img_Real is
       Exp  : Natural)
    is
       NFrac : constant Natural := Natural'Max (Aft, 1);
-      Sign  : Character;
+      Minus : Boolean;
       X     : Long_Long_Float;
       Scale : Integer;
       Expon : Integer;
@@ -419,7 +415,7 @@ package body System.Img_Real is
 
       procedure Set_Blanks_And_Sign (N : Integer) is
       begin
-         if Sign = '-' then
+         if Minus then
             for J in 1 .. N - 1 loop
                Set (' ');
             end loop;
@@ -483,10 +479,10 @@ package body System.Img_Real is
    --  Start of processing for Set_Image_Real
 
    begin
-      --  We call the floating-point processor reset routine so that we can
-      --  be sure the floating-point processor is properly set for conversion
-      --  calls. This is notably need on Windows, where calls to the operating
-      --  system randomly reset the processor into 64-bit mode.
+      --  We call the floating-point processor reset routine so we can be sure
+      --  that the processor is properly set for conversions. This is notably
+      --  needed on Windows, where calls to the operating system randomly reset
+      --  the processor into 64-bit mode.
 
       System.Float_Control.Reset;
 
@@ -539,21 +535,21 @@ package body System.Img_Real is
 
       if V > 0.0 then
          X := V;
-         Sign := '+';
+         Minus := False;
 
       --  Negative values
 
       elsif V < 0.0 then
          X := -V;
-         Sign := '-';
+         Minus := True;
 
       --  Zero values
 
       elsif V = 0.0 then
          if Long_Long_Float'Signed_Zeros and then Is_Negative (V) then
-            Sign := '-';
+            Minus := True;
          else
-            Sign := '+';
+            Minus := False;
          end if;
 
          Set_Blanks_And_Sign (Fore - 1);
@@ -578,7 +574,7 @@ package body System.Img_Real is
          raise Constraint_Error;
       end if;
 
-      --  X and Sign are set here, and X is known to be a valid,
+      --  X and Minus are set here, and X is known to be a valid,
       --  non-zero floating-point number.
 
       --  Case of non-zero value with Exp = 0
diff --git a/gcc/ada/libgnat/s-imguti.adb b/gcc/ada/libgnat/s-imguti.adb
new file mode 100644 (file)
index 0000000..571fb67
--- /dev/null
@@ -0,0 +1,403 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . I M G _ U T I L                       --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Img_Uns; use System.Img_Uns;
+
+package body System.Img_Util is
+
+   ------------------------
+   -- Set_Decimal_Digits --
+   ------------------------
+
+   procedure Set_Decimal_Digits
+     (Digs  : in out String;
+      NDigs : Natural;
+      S     : out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural)
+   is
+      pragma Assert (NDigs >= 1);
+      pragma Assert (Digs'First = 1);
+      pragma Assert (Digs'First < Digs'Last);
+
+      Minus : constant Boolean := (Digs (Digs'First) = '-');
+      --  Set True if input is negative
+
+      Zero : Boolean := (Digs (Digs'First + 1) = '0');
+      --  Set True if input is exactly zero (only case when a leading zero
+      --  is permitted in the input string given to this procedure). This
+      --  flag can get set later if rounding causes the value to become zero.
+
+      FD : Natural := 2;
+      --  First digit position of digits remaining to be processed
+
+      LD : Natural := NDigs;
+      --  Last digit position of digits remaining to be processed
+
+      ND : Natural := NDigs - 1;
+      --  Number of digits remaining to be processed (LD - FD + 1)
+
+      Digits_Before_Point : Integer := ND - Scale;
+      --  Number of digits before decimal point in the input value. This
+      --  value can be negative if the input value is less than 0.1, so
+      --  it is an indication of the current exponent. Digits_Before_Point
+      --  is adjusted if the rounding step generates an extra digit.
+
+      Digits_After_Point : constant Natural := Integer'Max (1, Aft);
+      --  Digit positions after decimal point in result string
+
+      Expon : Integer;
+      --  Integer value of exponent
+
+      procedure Round (N : Integer);
+      --  Round the number in Digs. N is the position of the last digit to be
+      --  retained in the rounded position (rounding is based on Digs (N + 1)
+      --  FD, LD, ND are reset as necessary if required. Note that if the
+      --  result value rounds up (e.g. 9.99 => 10.0), an extra digit can be
+      --  placed in the sign position as a result of the rounding, this is
+      --  the case in which FD is adjusted. The call to Round has no effect
+      --  if N is outside the range FD .. LD.
+
+      procedure Set (C : Character);
+      pragma Inline (Set);
+      --  Sets character C in output buffer
+
+      procedure Set_Blanks_And_Sign (N : Integer);
+      --  Sets leading blanks and minus sign if needed. N is the number of
+      --  positions to be filled (a minus sign is output even if N is zero
+      --  or negative, but for a positive value, if N is non-positive, then
+      --  the call has no effect).
+
+      procedure Set_Digits (S, E : Natural);
+      pragma Inline (Set_Digits);
+      --  Set digits S through E from Digs, no effect if S > E
+
+      procedure Set_Zeroes (N : Integer);
+      pragma Inline (Set_Zeroes);
+      --  Set N zeroes, no effect if N is negative
+
+      -----------
+      -- Round --
+      -----------
+
+      procedure Round (N : Integer) is
+         D : Character;
+
+         pragma Assert (NDigs >= 1);
+         pragma Assert (Digs'First = 1);
+         pragma Assert (Digs'First < Digs'Last);
+
+      begin
+         --  Nothing to do if rounding past the last digit we have
+
+         if N >= LD then
+            return;
+
+         --  Cases of rounding before the initial digit
+
+         elsif N < FD then
+
+            --  The result is zero, unless we are rounding just before
+            --  the first digit, and the first digit is five or more.
+
+            if N = 1 and then Digs (Digs'First + 1) >= '5' then
+               Digs (Digs'First) := '1';
+            else
+               Digs (Digs'First) := '0';
+               Zero := True;
+            end if;
+
+            Digits_Before_Point := Digits_Before_Point + 1;
+            FD := 1;
+            LD := 1;
+            ND := 1;
+
+         --  Normal case of rounding an existing digit
+
+         else
+            LD := N;
+            pragma Assert (LD >= 1);
+            --  In this case, we have N < LD and N >= FD. FD is a Natural,
+            --  So we can conclude, LD >= 1
+            ND := LD - 1;
+            pragma Assert (N + 1 <= Digs'Last);
+
+            if Digs (N + 1) >= '5' then
+               for J in reverse Digs'First + 1 .. Digs'First + N - 1 loop
+                  pragma Assert (Digs (J) in '0' .. '9' | ' ' | '-');
+                  --  Because it is a decimal image, we can assume that
+                  --  it can only contain these characters.
+                  D := Character'Succ (Digs (J));
+
+                  if D <= '9' then
+                     Digs (J) := D;
+                     return;
+                  else
+                     Digs (J) := '0';
+                  end if;
+               end loop;
+
+               --  Here the rounding overflows into the sign position. That's
+               --  OK, because we already captured the value of the sign and
+               --  we are in any case destroying the value in the Digs buffer
+
+               Digs (Digs'First) := '1';
+               FD := 1;
+               ND := ND + 1;
+               Digits_Before_Point := Digits_Before_Point + 1;
+            end if;
+         end if;
+      end Round;
+
+      ---------
+      -- Set --
+      ---------
+
+      procedure Set (C : Character) is
+      begin
+         pragma Assert (P >= (S'First - 1) and P < S'Last and
+                        P < Natural'Last);
+         --  No check is done as documented in the header : updating P to
+         --  point to the last character stored, the caller promises that the
+         --  buffer is large enough and no check is made for this.
+         --  Constraint_Error will not necessarily be raised if this
+         --  requirement is violated, since it is perfectly valid to compile
+         --  this unit with checks off.
+         P := P + 1;
+         S (P) := C;
+      end Set;
+
+      -------------------------
+      -- Set_Blanks_And_Sign --
+      -------------------------
+
+      procedure Set_Blanks_And_Sign (N : Integer) is
+      begin
+         if Minus then
+            for J in 1 .. N - 1 loop
+               Set (' ');
+            end loop;
+
+            Set ('-');
+
+         else
+            for J in 1 .. N loop
+               Set (' ');
+            end loop;
+         end if;
+      end Set_Blanks_And_Sign;
+
+      ----------------
+      -- Set_Digits --
+      ----------------
+
+      procedure Set_Digits (S, E : Natural) is
+      begin
+         pragma Assert (S >= Digs'First and E <= Digs'Last);
+         --  S and E should be in the Digs array range
+         --  TBC: Analysis should be completed
+         for J in S .. E loop
+            Set (Digs (J));
+         end loop;
+      end Set_Digits;
+
+      ----------------
+      -- Set_Zeroes --
+      ----------------
+
+      procedure Set_Zeroes (N : Integer) is
+      begin
+         for J in 1 .. N loop
+            Set ('0');
+         end loop;
+      end Set_Zeroes;
+
+   --  Start of processing for Set_Decimal_Digits
+
+   begin
+      --  Case of exponent given
+
+      if Exp > 0 then
+         Set_Blanks_And_Sign (Fore - 1);
+         Round (Digits_After_Point + 2);
+
+         Set (Digs (FD));
+         FD := FD + 1;
+         pragma Assert (ND >= 1);
+         ND := ND - 1;
+         Set ('.');
+
+         if ND >= Digits_After_Point then
+            Set_Digits (FD, FD + Digits_After_Point - 1);
+         else
+            Set_Digits (FD, LD);
+            Set_Zeroes (Digits_After_Point - ND);
+         end if;
+
+         --  Calculate exponent. The number of digits before the decimal point
+         --  in the input is Digits_Before_Point, and the number of digits
+         --  before the decimal point in the output is 1, so we can get the
+         --  exponent as the difference between these two values. The one
+         --  exception is for the value zero, which by convention has an
+         --  exponent of +0.
+
+         Expon := (if Zero then 0 else Digits_Before_Point - 1);
+
+         Set ('E');
+         ND := 0;
+
+         if Expon >= 0 then
+            Set ('+');
+            Set_Image_Unsigned (Unsigned (Expon), Digs, ND);
+         else
+            Set ('-');
+            Set_Image_Unsigned (Unsigned (-Expon), Digs, ND);
+         end if;
+
+         Set_Zeroes (Exp - ND - 1);
+         Set_Digits (1, ND);
+         return;
+
+      --  Case of no exponent given. To make these cases clear, we use
+      --  examples. For all the examples, we assume Fore = 2, Aft = 3.
+      --  A P in the example input string is an implied zero position,
+      --  not included in the input string.
+
+      else
+         --  Round at correct position
+         --    Input: 4PP      => unchanged
+         --    Input: 400.03   => unchanged
+         --    Input  3.4567   => 3.457
+         --    Input: 9.9999   => 10.000
+         --    Input: 0.PPP5   => 0.001
+         --    Input: 0.PPP4   => 0
+         --    Input: 0.00003  => 0
+
+         Round (LD - (Scale - Digits_After_Point));
+
+         --  No digits before point in input
+         --    Input: .123   Output: 0.123
+         --    Input: .PP3   Output: 0.003
+
+         if Digits_Before_Point <= 0 then
+            Set_Blanks_And_Sign (Fore - 1);
+            Set ('0');
+            Set ('.');
+
+            declare
+               DA : Natural := Digits_After_Point;
+               --  Digits remaining to output after point
+
+               LZ : constant Integer := Integer'Min (DA, -Digits_Before_Point);
+               --  Number of leading zeroes after point. Note: there used to be
+               --  a Max of this result with zero, but that's redundant, since
+               --  we know DA is positive, and because of the test above, we
+               --  know that -Digits_Before_Point >= 0.
+
+            begin
+               Set_Zeroes (LZ);
+               DA := DA - LZ;
+
+               if DA < ND then
+
+                  --  Note: it is definitely possible for the above condition
+                  --  to be True, for example:
+
+                  --    V => 1234, Scale => 5, Fore => 0, After => 1, Exp => 0
+
+                  --  but in this case DA = 0, ND = 1, FD = 1, FD + DA-1 = 0
+                  --  so the arguments in the call are (1, 0) meaning that no
+                  --  digits are output.
+
+                  --  No obvious example exists where the following call to
+                  --  Set_Digits actually outputs some digits, but we lack a
+                  --  proof that no such example exists.
+
+                  --  So it is safer to retain this call, even though as a
+                  --  result it is hard (or perhaps impossible) to create a
+                  --  coverage test for the inlined code of the call.
+
+                  Set_Digits (FD, FD + DA - 1);
+
+               else
+                  Set_Digits (FD, LD);
+                  Set_Zeroes (DA - ND);
+               end if;
+            end;
+
+         --  At least one digit before point in input
+
+         else
+            --  Less digits in input than are needed before point
+            --    Input: 1PP  Output: 100.000
+
+            if ND < Digits_Before_Point then
+
+               --  Special case, if the input is the single digit 0, then we
+               --  do not want 000.000, but instead 0.000.
+
+               if ND = 1 and then Digs (FD) = '0' then
+                  Set_Blanks_And_Sign (Fore - 1);
+                  Set ('0');
+
+               --  Normal case where we need to output scaling zeroes
+
+               else
+                  Set_Blanks_And_Sign (Fore - Digits_Before_Point);
+                  Set_Digits (FD, LD);
+                  Set_Zeroes (Digits_Before_Point - ND);
+               end if;
+
+               --  Set period and zeroes after the period
+
+               Set ('.');
+               Set_Zeroes (Digits_After_Point);
+
+            --  Input has full amount of digits before decimal point
+
+            else
+               Set_Blanks_And_Sign (Fore - Digits_Before_Point);
+               pragma Assert (FD + Digits_Before_Point - 1 >= 0);
+               --  In this branch, we have Digits_Before_Point > 0. It is the
+               --  else of test (Digits_Before_Point <= 0)
+               Set_Digits (FD, FD + Digits_Before_Point - 1);
+               Set ('.');
+               Set_Digits (FD + Digits_Before_Point, LD);
+               Set_Zeroes (Digits_After_Point - (ND - Digits_Before_Point));
+            end if;
+         end if;
+      end if;
+   end Set_Decimal_Digits;
+
+end System.Img_Util;
diff --git a/gcc/ada/libgnat/s-imguti.ads b/gcc/ada/libgnat/s-imguti.ads
new file mode 100644 (file)
index 0000000..f980bb7
--- /dev/null
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT RUN-TIME COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . I M G _ U T I L                       --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package provides some common utilities used by the s-imgxxx files
+
+package System.Img_Util is
+   pragma Pure;
+
+   procedure Set_Decimal_Digits
+     (Digs  : in out String;
+      NDigs : Natural;
+      S     : out String;
+      P     : in out Natural;
+      Scale : Integer;
+      Fore  : Natural;
+      Aft   : Natural;
+      Exp   : Natural);
+   --  Sets the image of Digs (1 .. NDigs), which is a string of decimal digits
+   --  preceded by either a minus sign or a space, i.e. the integer image of
+   --  the value in units of delta of a decimal fixed point type with the given
+   --  Scale, starting at S (P + 1), updating P to point to the last character
+   --  stored, the caller promises that the buffer is large enough and no check
+   --  is made for this. Constraint_Error will not necessarily be raised if the
+   --  requirement is violated since it is perfectly valid to compile this unit
+   --  with checks off. The Fore, Aft and Exp values can be set to any valid
+   --  values for the case of use by Text_IO.Decimal_IO. Note that there is no
+   --  leading space stored. The call may destroy the value in Digs, which is
+   --  why Digs is in-out (this happens if rounding is required).
+
+end System.Img_Util;
diff --git a/gcc/ada/libgnat/s-vade128.ads b/gcc/ada/libgnat/s-vade128.ads
new file mode 100644 (file)
index 0000000..8edc742
--- /dev/null
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--               S Y S T E M . V A L _ D E C I M A L _ 1 2 8                --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for decimal fixed point
+--  types up to 128-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+--  attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_128;
+with System.Value_D;
+
+package System.Val_Decimal_128 is
+   pragma Preelaborate;
+
+   subtype Int128 is Interfaces.Integer_128;
+   subtype Uns128 is Interfaces.Unsigned_128;
+
+   package Impl is new Value_D (Int128, Uns128, Arith_128.Scaled_Divide128);
+
+   function Scan_Decimal128
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int128
+     renames Impl.Scan_Decimal;
+
+   function Value_Decimal128
+     (Str   : String;
+      Scale : Integer) return Int128
+    renames Impl.Value_Decimal;
+
+end System.Val_Decimal_128;
diff --git a/gcc/ada/libgnat/s-vade32.ads b/gcc/ada/libgnat/s-vade32.ads
new file mode 100644 (file)
index 0000000..b86ae52
--- /dev/null
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                S Y S T E M . V A L _ D E C I M A L _ 3 2                 --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for decimal fixed point
+--  types up to 32-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+--  attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_32;
+with System.Value_D;
+
+package System.Val_Decimal_32 is
+   pragma Preelaborate;
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Uns32 is Interfaces.Unsigned_32;
+
+   package Impl is new Value_D (Int32, Uns32, Arith_32.Scaled_Divide32);
+
+   function Scan_Decimal32
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int32
+     renames Impl.Scan_Decimal;
+
+   function Value_Decimal32 (Str : String; Scale : Integer) return Int32
+     renames Impl.Value_Decimal;
+
+end System.Val_Decimal_32;
diff --git a/gcc/ada/libgnat/s-vade64.ads b/gcc/ada/libgnat/s-vade64.ads
new file mode 100644 (file)
index 0000000..d3a5b4f
--- /dev/null
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                S Y S T E M . V A L _ D E C I M A L _ 6 4                 --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for decimal fixed point
+--  types up to 64-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+--  attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_64;
+with System.Value_D;
+
+package System.Val_Decimal_64 is
+   pragma Preelaborate;
+
+   subtype Int64 is Interfaces.Integer_64;
+   subtype Uns64 is Interfaces.Unsigned_64;
+
+   package Impl is new Value_D (Int64, Uns64, Arith_64.Scaled_Divide64);
+
+   function Scan_Decimal64
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int64
+     renames Impl.Scan_Decimal;
+
+   function Value_Decimal64
+     (Str   : String;
+      Scale : Integer) return Int64
+    renames Impl.Value_Decimal;
+
+end System.Val_Decimal_64;
diff --git a/gcc/ada/libgnat/s-vafi128.ads b/gcc/ada/libgnat/s-vafi128.ads
new file mode 100644 (file)
index 0000000..03fbe80
--- /dev/null
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                 S Y S T E M . V A L _ F I X E D _ 1 2 8                  --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for ordinary fixed point
+--  types up to 128-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+--  the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_128;
+with System.Value_F;
+
+package System.Val_Fixed_128 is
+   pragma Preelaborate;
+
+   subtype Int128 is Interfaces.Integer_128;
+   subtype Uns128 is Interfaces.Unsigned_128;
+
+   package Impl is new Value_F (Int128, Uns128, Arith_128.Scaled_Divide128);
+
+   function Scan_Fixed128
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int128;
+      Den : Int128) return Int128
+     renames Impl.Scan_Fixed;
+
+   function Value_Fixed128
+     (Str : String; Num : Int128; Den : Int128) return Int128
+     renames Impl.Value_Fixed;
+
+end System.Val_Fixed_128;
diff --git a/gcc/ada/libgnat/s-vafi32.ads b/gcc/ada/libgnat/s-vafi32.ads
new file mode 100644 (file)
index 0000000..6235a82
--- /dev/null
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                  S Y S T E M . V A L _ F I X E D _ 3 2                   --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for decimal fixed point
+--  types up to 32-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+--  the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_32;
+with System.Value_F;
+
+package System.Val_Fixed_32 is
+   pragma Preelaborate;
+
+   subtype Int32 is Interfaces.Integer_32;
+   subtype Uns32 is Interfaces.Unsigned_32;
+
+   package Impl is new Value_F (Int32, Uns32, Arith_32.Scaled_Divide32);
+
+   function Scan_Fixed32
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int32;
+      Den : Int32) return Int32
+     renames Impl.Scan_Fixed;
+
+   function Value_Fixed32
+     (Str : String; Num : Int32; Den : Int32) return Int32
+     renames Impl.Value_Fixed;
+
+end System.Val_Fixed_32;
diff --git a/gcc/ada/libgnat/s-vafi64.ads b/gcc/ada/libgnat/s-vafi64.ads
new file mode 100644 (file)
index 0000000..9f98df4
--- /dev/null
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                  S Y S T E M . V A L _ F I X E D _ 6 4                   --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning values for decimal fixed point
+--  types up to 64-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+--  the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_64;
+with System.Value_F;
+
+package System.Val_Fixed_64 is
+   pragma Preelaborate;
+
+   subtype Int64 is Interfaces.Integer_64;
+   subtype Uns64 is Interfaces.Unsigned_64;
+
+   package Impl is new Value_F (Int64, Uns64, Arith_64.Scaled_Divide64);
+
+   function Scan_Fixed64
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int64;
+      Den : Int64) return Int64
+     renames Impl.Scan_Fixed;
+
+   function Value_Fixed64
+     (Str : String; Num : Int64; Den : Int64) return Int64
+     renames Impl.Value_Fixed;
+
+end System.Val_Fixed_64;
diff --git a/gcc/ada/libgnat/s-valdec.adb b/gcc/ada/libgnat/s-valdec.adb
deleted file mode 100644 (file)
index 99fffaf..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT COMPILER COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . V A L _ D E C                        --
---                                                                          --
---                                 B o d y                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-with System.Val_Real; use System.Val_Real;
-
-package body System.Val_Dec is
-
-   ------------------
-   -- Scan_Decimal --
-   ------------------
-
-   --  For decimal types where Size < Integer'Size, it is fine to use
-   --  the floating-point circuit, since it certainly has sufficient
-   --  precision for any reasonable hardware, and we just don't support
-   --  things on junk hardware.
-
-   function Scan_Decimal
-     (Str   : String;
-      Ptr   : not null access Integer;
-      Max   : Integer;
-      Scale : Integer) return Integer
-   is
-      Val : Long_Long_Float;
-   begin
-      Val := Scan_Real (Str, Ptr, Max);
-      return Integer (Val * 10.0 ** Scale);
-   end Scan_Decimal;
-
-   -------------------
-   -- Value_Decimal --
-   -------------------
-
-   --  Again, we use the real circuit for this purpose
-
-   function Value_Decimal (Str : String; Scale : Integer) return Integer is
-   begin
-      return Integer (Value_Real (Str) * 10.0 ** Scale);
-   end Value_Decimal;
-
-end System.Val_Dec;
diff --git a/gcc/ada/libgnat/s-valdec.ads b/gcc/ada/libgnat/s-valdec.ads
deleted file mode 100644 (file)
index 05fab98..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT COMPILER COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . V A L _ D E C                        --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---            Copyright (C) 1992-2020, Free Software Foundation, Inc.       --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
---  This package contains routines for scanning decimal values where the size
---  of the type is no greater than Standard.Integer'Size, for use in Text_IO.
---  Decimal_IO, and the Value attribute for such decimal types.
-
-package System.Val_Dec is
-   pragma Preelaborate;
-
-   function Scan_Decimal
-     (Str   : String;
-      Ptr   : not null access Integer;
-      Max   : Integer;
-      Scale : Integer) return Integer;
-   --  This function scans the string starting at Str (Ptr.all) for a valid
-   --  real literal according to the syntax described in (RM 3.5(43)). The
-   --  substring scanned extends no further than Str (Max). There are three
-   --  cases for the return:
-   --
-   --  If a valid real literal is found after scanning past any initial spaces,
-   --  then Ptr.all is updated past the last character of the literal (but
-   --  trailing spaces are not scanned out). The value returned is the value
-   --  Integer'Integer_Value (decimal-literal-value), using the given Scale
-   --  to determine this value.
-   --
-   --  If no valid real literal is found, then Ptr.all points either to an
-   --  initial non-digit character, or to Max + 1 if the field is all spaces
-   --  and the exception Constraint_Error is raised.
-   --
-   --  If a syntactically valid integer is scanned, but the value is out of
-   --  range, or, in the based case, the base value is out of range or there
-   --  is an out of range digit, then Ptr.all points past the integer, and
-   --  Constraint_Error is raised.
-   --
-   --  Note: these rules correspond to the requirements for leaving the
-   --  pointer positioned in Text_Io.Get
-   --
-   --  Note: if Str is null, i.e. if Max is less than Ptr, then this is a
-   --  special case of an all-blank string, and Ptr is unchanged, and hence
-   --  is greater than Max as required in this case.
-
-   function Value_Decimal (Str : String; Scale : Integer) return Integer;
-   --  Used in computing X'Value (Str) where X is a decimal fixed-point type
-   --  whose size does not exceed Standard.Integer'Size. Str is the string
-   --  argument of the attribute. Constraint_Error is raised if the string
-   --  is malformed or if the value is out of range of Integer (not the
-   --  range of the fixed-point type, that check must be done by the caller.
-   --  Otherwise the value returned is the value Integer'Integer_Value
-   --  (decimal-literal-value), using Scale to determine this value.
-
-end System.Val_Dec;
diff --git a/gcc/ada/libgnat/s-vallld.adb b/gcc/ada/libgnat/s-vallld.adb
deleted file mode 100644 (file)
index 4efa969..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT COMPILER COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . V A L _ L L D                        --
---                                                                          --
---                                 B o d y                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
-with System.Val_Real; use System.Val_Real;
-
-package body System.Val_LLD is
-
-   ----------------------------
-   -- Scan_Long_Long_Decimal --
-   ----------------------------
-
-   --  We use the floating-point circuit for now, this will be OK on a PC,
-   --  but definitely does NOT have the required precision if the longest
-   --  float type is IEEE double. This must be fixed in the future ???
-
-   function Scan_Long_Long_Decimal
-     (Str   : String;
-      Ptr   : not null access Integer;
-      Max   : Integer;
-      Scale : Integer) return Long_Long_Integer
-   is
-      Val : Long_Long_Float;
-   begin
-      Val := Scan_Real (Str, Ptr, Max);
-      return Long_Long_Integer (Val * 10.0 ** Scale);
-   end Scan_Long_Long_Decimal;
-
-   -----------------------------
-   -- Value_Long_Long_Decimal --
-   -----------------------------
-
-   --  Again we cheat and use floating-point ???
-
-   function Value_Long_Long_Decimal
-     (Str   : String;
-      Scale : Integer) return Long_Long_Integer
-   is
-   begin
-      return Long_Long_Integer (Value_Real (Str) * 10.0 ** Scale);
-   end Value_Long_Long_Decimal;
-
-end System.Val_LLD;
diff --git a/gcc/ada/libgnat/s-vallld.ads b/gcc/ada/libgnat/s-vallld.ads
deleted file mode 100644 (file)
index 652362d..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-------------------------------------------------------------------------------
---                                                                          --
---                         GNAT COMPILER COMPONENTS                         --
---                                                                          --
---                       S Y S T E M . V A L _ L L D                        --
---                                                                          --
---                                 S p e c                                  --
---                                                                          --
---          Copyright (C) 1992-2020, Free Software Foundation, Inc.         --
---                                                                          --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
---                                                                          --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception,   --
--- version 3.1, as published by the Free Software Foundation.               --
---                                                                          --
--- You should have received a copy of the GNU General Public License and    --
--- a copy of the GCC Runtime Library Exception along with this program;     --
--- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
--- <http://www.gnu.org/licenses/>.                                          --
---                                                                          --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.      --
---                                                                          --
-------------------------------------------------------------------------------
-
---  This package contains routines for scanning decimal values where the size
---  of the type is greater than Standard.Integer'Size, for use in Text_IO.
---  Decimal_IO, and the Value attribute for such decimal types.
-
-package System.Val_LLD is
-   pragma Preelaborate;
-
-   function Scan_Long_Long_Decimal
-     (Str   : String;
-      Ptr   : not null access Integer;
-      Max   : Integer;
-      Scale : Integer) return Long_Long_Integer;
-   --  This function scans the string starting at Str (Ptr.all) for a valid
-   --  real literal according to the syntax described in (RM 3.5(43)). The
-   --  substring scanned extends no further than Str (Max). There are three
-   --  cases for the return:
-   --
-   --  If a valid real literal is found after scanning past any initial spaces,
-   --  then Ptr.all is updated past the last character of the literal (but
-   --  trailing spaces are not scanned out). The value returned is the value
-   --  Long_Long_Integer'Integer_Value (decimal-literal-value), using the given
-   --  Scale to determine this value.
-   --
-   --  If no valid real literal is found, then Ptr.all points either to an
-   --  initial non-digit character, or to Max + 1 if the field is all spaces
-   --  and the exception Constraint_Error is raised.
-   --
-   --  If a syntactically valid integer is scanned, but the value is out of
-   --  range, or, in the based case, the base value is out of range or there
-   --  is an out of range digit, then Ptr.all points past the integer, and
-   --  Constraint_Error is raised.
-   --
-   --  Note: these rules correspond to the requirements for leaving the
-   --  pointer positioned in Text_Io.Get
-   --
-   --  Note: if Str is null, i.e. if Max is less than Ptr, then this is a
-   --  special case of an all-blank string, and Ptr is unchanged, and hence
-   --  is greater than Max as required in this case.
-
-   function Value_Long_Long_Decimal
-     (Str   : String;
-      Scale : Integer) return Long_Long_Integer;
-   --  Used in computing X'Value (Str) where X is a decimal types whose size
-   --  exceeds Standard.Integer'Size. Str is the string argument of the
-   --  attribute. Constraint_Error is raised if the string is malformed
-   --  or if the value is out of range, otherwise the value returned is the
-   --  value Long_Long_Integer'Integer_Value (decimal-literal-value), using
-   --  the given Scale to determine this value.
-
-end System.Val_LLD;
index 1a47dc2f49f54fcb62fc8523d84ed0805d66da09..693b261657d9617bbe166b5b99192e995fe5fe8d 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with System.Val_Util;      use System.Val_Util;
 with System.Float_Control;
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util;       use System.Val_Util;
+with System.Value_R;
 
 package body System.Val_Real is
 
-   procedure Scan_Integral_Digits
-      (Str            : String;
-       Index          : in out Integer;
-       Max            : Integer;
-       Value          : out Long_Long_Integer;
-       Scale          : out Integer;
-       Base_Violation : in out Boolean;
-       Base           : Long_Long_Integer := 10;
-       Base_Specified : Boolean := False);
-   --  Scan the integral part of a real (i.e: before decimal separator)
-   --
-   --  The string parsed is Str (Index .. Max), and after the call Index will
-   --  point to the first non parsed character.
-   --
-   --  For each digit parsed either value := value * base + digit, or scale
-   --  is incremented by 1.
-   --
-   --  Base_Violation will be set to True a digit found is not part of the Base
-
-   procedure Scan_Decimal_Digits
-      (Str            : String;
-       Index          : in out Integer;
-       Max            : Integer;
-       Value          : in out Long_Long_Integer;
-       Scale          : in out Integer;
-       Base_Violation : in out Boolean;
-       Base           : Long_Long_Integer := 10;
-       Base_Specified : Boolean := False);
-   --  Scan the decimal part of a real (i.e: after decimal separator)
-   --
-   --  The string parsed is Str (Index .. Max), and after the call Index will
-   --  point to the first non parsed character.
-   --
-   --  For each digit parsed value = value * base + digit and scale is
-   --  decremented by 1. If precision limit is reached remaining digits are
-   --  still parsed but ignored.
-   --
-   --  Base_Violation will be set to True a digit found is not part of the Base
-
-   subtype Char_As_Digit is Long_Long_Integer range -2 .. 15;
-   subtype Valid_Digit is Char_As_Digit range 0 .. Char_As_Digit'Last;
-   Underscore : constant Char_As_Digit := -2;
-   E_Digit : constant Char_As_Digit := 14;
-
-   function As_Digit (C : Character) return Char_As_Digit;
-   --  Given a character return the digit it represent. If the character is
-   --  not a digit then a negative value is returned, -2 for underscore and
-   --  -1 for any other character.
-
-   Precision_Limit : constant Long_Long_Integer :=
-      2 ** (Long_Long_Float'Machine_Mantissa - 1) - 1;
-   --  This is an upper bound for the number of bits used to represent the
-   --  mantissa. Beyond that number, any digits parsed are useless.
-
-   --------------
-   -- As_Digit --
-   --------------
-
-   function As_Digit (C : Character) return Char_As_Digit is
-   begin
-      case C is
-         when '0' .. '9' =>
-            return Character'Pos (C) - Character'Pos ('0');
-         when 'a' .. 'f' =>
-            return Character'Pos (C) - (Character'Pos ('a') - 10);
-         when 'A' .. 'F' =>
-            return Character'Pos (C) - (Character'Pos ('A') - 10);
-         when '_' =>
-            return Underscore;
-         when others =>
-            return -1;
-      end case;
-   end As_Digit;
-
-   -------------------------
-   -- Scan_Decimal_Digits --
-   -------------------------
-
-   procedure Scan_Decimal_Digits
-      (Str            : String;
-       Index          : in out Integer;
-       Max            : Integer;
-       Value          : in out Long_Long_Integer;
-       Scale          : in out Integer;
-       Base_Violation : in out Boolean;
-       Base           : Long_Long_Integer := 10;
-       Base_Specified : Boolean := False)
-
+   package Impl is new Value_R (Long_Long_Unsigned, Floating => True);
+
+   function Integer_to_Real
+     (Str   : String;
+      Val   : Long_Long_Unsigned;
+      Base  : Unsigned;
+      Scale : Integer;
+      Minus : Boolean) return Long_Long_Float;
+   --  Convert the real value from integer to real representation
+
+   ---------------------
+   -- Integer_to_Real --
+   ---------------------
+
+   function Integer_to_Real
+     (Str   : String;
+      Val   : Long_Long_Unsigned;
+      Base  : Unsigned;
+      Scale : Integer;
+      Minus : Boolean) return Long_Long_Float
    is
-      Precision_Limit_Reached : Boolean := False;
-      --  Set to True if addition of a digit will cause Value to be superior
-      --  to Precision_Limit.
-
-      Digit : Char_As_Digit;
-      --  The current digit.
+      pragma Unsuppress (Range_Check);
 
-      Trailing_Zeros : Natural := 0;
-      --  Number of trailing zeros at a given point.
+      R_Val : Long_Long_Float;
 
    begin
-      pragma Assert (Base in 2 .. 16);
-
-      --  If initial Scale is not 0 then it means that Precision_Limit was
-      --  reached during integral part scanning.
-      if Scale > 0 then
-         Precision_Limit_Reached := True;
-      end if;
-
-      --  The function precondition is that the first character is a valid
-      --  digit.
-      Digit := As_Digit (Str (Index));
-
-      loop
-         --  Check if base is correct. If the base is not specified the digit
-         --  E or e cannot be considered as a base violation as it can be used
-         --  for exponentiation.
-         if Digit >= Base then
-            if Base_Specified then
-               Base_Violation := True;
-            elsif Digit = E_Digit then
-               return;
-            else
-               Base_Violation := True;
-            end if;
-         end if;
-
-         --  If precision limit has been reached just ignore any remaining
-         --  digits for the computation of Value and Scale. The scanning
-         --  should continue only to assess the validity of the string
-         if not Precision_Limit_Reached then
-            if Digit = 0 then
-               --  Trailing '0' digits are ignored unless a non-zero digit is
-               --  found.
-               Trailing_Zeros := Trailing_Zeros + 1;
-            else
-
-               --  Handle accumulated zeros.
-               for J in 1 .. Trailing_Zeros loop
-                  if Value > Precision_Limit / Base then
-                     Precision_Limit_Reached := True;
-                     exit;
-                  else
-                     Value := Value * Base;
-                     Scale := Scale - 1;
-                  end if;
-               end loop;
-
-               --  Reset trailing zero counter
-               Trailing_Zeros := 0;
-
-               --  Handle current non zero digit
-               if Value > (Precision_Limit - Digit) / Base then
-                  Precision_Limit_Reached := True;
-               else
-                  Value := Value * Base + Digit;
-                  Scale := Scale - 1;
-               end if;
-            end if;
-         end if;
+      --  We call the floating-point processor reset routine so we can be sure
+      --  that the processor is properly set for conversions. This is notably
+      --  needed on Windows, where calls to the operating system randomly reset
+      --  the processor into 64-bit mode.
 
-         --  Check next character
-         Index := Index + 1;
-
-         if Index > Max then
-            return;
-         end if;
-
-         Digit := As_Digit (Str (Index));
-
-         if Digit < 0 then
-            if Digit = Underscore and Index + 1 <= Max then
-               --  Underscore is only allowed if followed by a digit
-               Digit := As_Digit (Str (Index + 1));
-               if Digit in Valid_Digit then
-                  Index := Index + 1;
-               else
-                  return;
-               end if;
-            else
-               --  Neither a valid underscore nor a digit.
-               return;
-            end if;
-         end if;
-      end loop;
-   end Scan_Decimal_Digits;
-
-   --------------------------
-   -- Scan_Integral_Digits --
-   --------------------------
-
-   procedure Scan_Integral_Digits
-      (Str            : String;
-       Index          : in out Integer;
-       Max            : Integer;
-       Value          : out Long_Long_Integer;
-       Scale          : out Integer;
-       Base_Violation : in out Boolean;
-       Base           : Long_Long_Integer := 10;
-       Base_Specified : Boolean := False)
-   is
-      Precision_Limit_Reached : Boolean := False;
-      --  Set to True if addition of a digit will cause Value to be superior
-      --  to Precision_Limit.
-
-      Digit : Char_As_Digit;
-      --  The current digit
-   begin
-
-      --  Initialize Scale and Value
-      Value := 0;
-      Scale := 0;
-
-      --  The function precondition is that the first character is a valid
-      --  digit.
-      Digit := As_Digit (Str (Index));
-
-      loop
-         --  Check if base is correct. If the base is not specified the digit
-         --  E or e cannot be considered as a base violation as it can be used
-         --  for exponentiation.
-         if Digit >= Base then
-            if Base_Specified then
-               Base_Violation := True;
-            elsif Digit = E_Digit then
-               return;
-            else
-               Base_Violation := True;
-            end if;
-         end if;
-
-         if Precision_Limit_Reached then
-            --  Precision limit has been reached so just update the exponent
-            Scale := Scale + 1;
-         else
-            pragma Assert (Base /= 0);
+      System.Float_Control.Reset;
 
-            if Value > (Precision_Limit - Digit) / Base then
-               --  Updating Value will overflow so ignore this digit and any
-               --  following ones. Only update the scale
-               Precision_Limit_Reached := True;
-               Scale := Scale + 1;
-            else
-               Value := Value * Base + Digit;
-            end if;
-         end if;
+      --  Compute the final value
 
-         --  Look for the next character
-         Index := Index + 1;
-         if Index > Max then
-            return;
-         end if;
+      R_Val := Long_Long_Float (Val) * Long_Long_Float (Base) ** Scale;
 
-         Digit := As_Digit (Str (Index));
+      --  Finally deal with initial minus sign, note that this processing is
+      --  done even if Uval is zero, so that -0.0 is correctly interpreted.
 
-         if Digit not in Valid_Digit then
-            --  Next character is not a digit. In that case stop scanning
-            --  unless the next chracter is an underscore followed by a digit.
-            if Digit = Underscore and Index + 1 <= Max then
-               Digit := As_Digit (Str (Index + 1));
-               if Digit in Valid_Digit then
-                  Index := Index + 1;
-               else
-                  return;
-               end if;
-            else
-               return;
-            end if;
-         end if;
-      end loop;
+      return (if Minus then -R_Val else R_Val);
 
-   end Scan_Integral_Digits;
+   exception
+      when Constraint_Error => Bad_Value (Str);
+   end Integer_to_Real;
 
    ---------------
    -- Scan_Real --
@@ -315,197 +91,17 @@ package body System.Val_Real is
        Ptr : not null access Integer;
        Max : Integer)
       return Long_Long_Float
-
    is
-      Start : Positive;
-      --  Position of starting non-blank character
-
+      Base  : Unsigned;
+      Scale : Integer;
+      Extra : Unsigned;
       Minus : Boolean;
-      --  Set to True if minus sign is present, otherwise to False
-
-      Index : Integer;
-      --  Local copy of string pointer
-
-      Int_Value : Long_Long_Integer := -1;
-      --  Mantissa as an Integer
-
-      Int_Scale : Integer := 0;
-      --  Exponent value
-
-      Base_Violation : Boolean := False;
-      --  If True some digits where not in the base. The float is still scan
-      --  till the end even if an error will be raised.
-
-      Uval : Long_Long_Float := 0.0;
-      --  Contain the final value at the end of the function
-
-      After_Point : Boolean := False;
-      --  True if a decimal should be parsed
-
-      Base : Long_Long_Integer := 10;
-      --  Current base (default: 10)
-
-      Base_Char : Character := ASCII.NUL;
-      --  Character used to set the base. If Nul this means that default
-      --  base is used.
+      Val   : Long_Long_Unsigned;
 
    begin
-      --  We do not tolerate strings with Str'Last = Positive'Last
-
-      if Str'Last = Positive'Last then
-         raise Program_Error with
-           "string upper bound is Positive'Last, not supported";
-      end if;
-
-      --  We call the floating-point processor reset routine so that we can
-      --  be sure the floating-point processor is properly set for conversion
-      --  calls. This is notably need on Windows, where calls to the operating
-      --  system randomly reset the processor into 64-bit mode.
-
-      System.Float_Control.Reset;
-
-      --  Scan the optional sign
-      Scan_Sign (Str, Ptr, Max, Minus, Start);
-      Index := Ptr.all;
-      Ptr.all := Start;
-
-      --  First character can be either a decimal digit or a dot.
-      if Str (Index) in '0' .. '9' then
-         pragma Annotate
-           (CodePeer, Intentional,
-            "test always true", "defensive code below");
-
-         --  If this is a digit it can indicates either the float decimal
-         --  part or the base to use
-         Scan_Integral_Digits
-            (Str,
-             Index,
-             Max            => Max,
-             Value          => Int_Value,
-             Scale          => Int_Scale,
-             Base_Violation => Base_Violation,
-             Base           => 10);
-      elsif Str (Index) = '.' and then
-         --  A dot is only allowed if followed by a digit.
-         Index < Max and then
-         Str (Index + 1) in '0' .. '9'
-      then
-         --  Initial point, allowed only if followed by digit (RM 3.5(47))
-         After_Point := True;
-         Index := Index + 1;
-         Int_Value := 0;
-      else
-         Bad_Value (Str);
-      end if;
-
-      --  Check if the first number encountered is a base
-      if Index < Max and then
-         (Str (Index) = '#' or else Str (Index) = ':')
-      then
-         Base_Char := Str (Index);
-         Base := Int_Value;
-
-         --  Reset Int_Value to indicate that parsing of integral value should
-         --  be done
-         Int_Value := -1;
-         if Base < 2 or else Base > 16 then
-            Base_Violation := True;
-            Base := 16;
-         end if;
-
-         Index := Index + 1;
-
-         if Str (Index) = '.' and then
-            Index < Max and then
-            As_Digit (Str (Index + 1)) in Valid_Digit
-         then
-            After_Point := True;
-            Index := Index + 1;
-            Int_Value := 0;
-         end if;
-      end if;
-
-      --  Does scanning of integral part needed
-      if Int_Value < 0 then
-         if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then
-            Bad_Value (Str);
-         end if;
-
-         Scan_Integral_Digits
-            (Str,
-             Index,
-             Max => Max,
-             Value => Int_Value,
-             Scale => Int_Scale,
-             Base_Violation => Base_Violation,
-             Base => Base,
-             Base_Specified => Base_Char /= ASCII.NUL);
-      end if;
-
-      --  Do we have a dot ?
-      if not After_Point and then
-         Index <= Max and then
-         Str (Index) = '.'
-      then
-         --  At this stage if After_Point was not set, this means that an
-         --  integral part has been found. Thus the dot is valid even if not
-         --  followed by a digit.
-         if Index < Max and then As_Digit (Str (Index + 1)) in Valid_Digit then
-            After_Point := True;
-         end if;
-
-         Index := Index + 1;
-      end if;
-
-      if After_Point then
-         --  Parse decimal part
-         Scan_Decimal_Digits
-            (Str,
-             Index,
-             Max => Max,
-             Value => Int_Value,
-             Scale => Int_Scale,
-             Base_Violation => Base_Violation,
-             Base => Base,
-             Base_Specified => Base_Char /= ASCII.NUL);
-      end if;
-
-      --  If an explicit base was specified ensure that the delimiter is found
-      if Base_Char /= ASCII.NUL then
-         if Index > Max or else Str (Index) /= Base_Char then
-            Bad_Value (Str);
-         else
-            Index := Index + 1;
-         end if;
-      end if;
-
-      --  Compute the final value
-      Uval := Long_Long_Float (Int_Value);
-
-      --  Update pointer and scan exponent.
-      Ptr.all := Index;
-
-      Int_Scale := Int_Scale + Scan_Exponent (Str,
-                                              Ptr,
-                                              Max,
-                                              Real => True);
-
-      Uval := Uval * Long_Long_Float (Base) ** Int_Scale;
-
-      --  Here is where we check for a bad based number
-      if Base_Violation then
-         Bad_Value (Str);
-
-      --  If OK, then deal with initial minus sign, note that this processing
-      --  is done even if Uval is zero, so that -0.0 is correctly interpreted.
-      else
-         if Minus then
-            return -Uval;
-         else
-            return Uval;
-         end if;
-      end if;
+      Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scale, Extra, Minus);
 
+      return Integer_to_Real (Str, Val, Base, Scale, Minus);
    end Scan_Real;
 
    ----------------
@@ -513,30 +109,16 @@ package body System.Val_Real is
    ----------------
 
    function Value_Real (Str : String) return Long_Long_Float is
-   begin
-      --  We have to special case Str'Last = Positive'Last because the normal
-      --  circuit ends up setting P to Str'Last + 1 which is out of bounds. We
-      --  deal with this by converting to a subtype which fixes the bounds.
-
-      if Str'Last = Positive'Last then
-         declare
-            subtype NT is String (1 .. Str'Length);
-         begin
-            return Value_Real (NT (Str));
-         end;
+      Base  : Unsigned;
+      Scale : Integer;
+      Extra : Unsigned;
+      Minus : Boolean;
+      Val   : Long_Long_Unsigned;
 
-      --  Normal case where Str'Last < Positive'Last
+   begin
+      Val := Impl.Value_Raw_Real (Str, Base, Scale, Extra, Minus);
 
-      else
-         declare
-            V : Long_Long_Float;
-            P : aliased Integer := Str'First;
-         begin
-            V := Scan_Real (Str, P'Access, Str'Last);
-            Scan_Trailing_Blanks (Str, P);
-            return V;
-         end;
-      end if;
+      return Integer_to_Real (Str, Val, Base, Scale, Minus);
    end Value_Real;
 
 end System.Val_Real;
diff --git a/gcc/ada/libgnat/s-valued.adb b/gcc/ada/libgnat/s-valued.adb
new file mode 100644 (file)
index 0000000..5fa8a99
--- /dev/null
@@ -0,0 +1,257 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . V A L U E _ D                        --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util;       use System.Val_Util;
+with System.Value_R;
+
+package body System.Value_D is
+
+   package Impl is new Value_R (Uns, Floating => False);
+
+   function Integer_to_Decimal
+     (Str    : String;
+      Val    : Uns;
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Minus  : Boolean;
+      Scale  : Integer) return Int;
+   --  Convert the real value from integer to decimal representation
+
+   ------------------------
+   -- Integer_to_Decimal --
+   ------------------------
+
+   function Integer_to_Decimal
+     (Str    : String;
+      Val    : Uns;
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Minus  : Boolean;
+      Scale  : Integer) return Int
+   is
+      function Safe_Expont
+        (Base   : Int;
+         Exp    : in out Natural;
+         Factor : Int) return Int;
+      --  Return (Base ** Exp) * Factor if the computation does not overflow,
+      --  or else the number of the form (Base ** K) * Factor with the largest
+      --  magnitude if the former computation overflows. In both cases, Exp is
+      --  updated to contain the remaining power in the computation. Note that
+      --  Factor is expected to be positive in this context.
+
+      function Unsigned_To_Signed (Val : Uns) return Int;
+      --  Convert an integer value from unsigned to signed representation
+
+      -----------------
+      -- Safe_Expont --
+      -----------------
+
+      function Safe_Expont
+        (Base   : Int;
+         Exp    : in out Natural;
+         Factor : Int) return Int
+      is
+         pragma Assert (Base /= 0 and then Factor > 0);
+
+         Max : constant Int := Int'Last / Base;
+
+         Result : Int := Factor;
+
+      begin
+         while Exp > 0 and then Result <= Max loop
+            Result := Result * Base;
+            Exp    := Exp - 1;
+         end loop;
+
+         return Result;
+      end Safe_Expont;
+
+      ------------------------
+      -- Unsigned_To_Signed --
+      ------------------------
+
+      function Unsigned_To_Signed (Val : Uns) return Int is
+      begin
+         --  Deal with overflow cases, and also with largest negative number
+
+         if Val > Uns (Int'Last) then
+            if Minus and then Val = Uns (-(Int'First)) then
+               return Int'First;
+            else
+               Bad_Value (Str);
+            end if;
+
+         --  Negative values
+
+         elsif Minus then
+            return -(Int (Val));
+
+         --  Positive values
+
+         else
+            return Int (Val);
+         end if;
+      end Unsigned_To_Signed;
+
+   begin
+      --  If the base of the value is 10 or its scaling factor is zero, then
+      --  add the scales (they are defined in the opposite sense) and apply
+      --  the result to the value, checking for overflow in the process.
+
+      if Base = 10 or else ScaleB = 0 then
+         declare
+            S : Integer := ScaleB + Scale;
+            V : Uns     := Val;
+
+         begin
+            while S < 0 loop
+               V := V / 10;
+               S := S + 1;
+            end loop;
+
+            while S > 0 loop
+               if V <= Uns'Last / 10 then
+                  V := V * 10;
+                  S := S - 1;
+               else
+                  Bad_Value (Str);
+               end if;
+            end loop;
+
+            return Unsigned_To_Signed (V);
+         end;
+
+      --  If the base of the value is not 10, use a scaled divide operation
+      --  to compute Val * (Base ** ScaleB) * (10 ** Scale).
+
+      else
+         declare
+            B : constant Int     := Int (Base);
+            S : constant Integer := ScaleB;
+
+            V : Uns := Val;
+
+            Y, Z, Q, R : Int;
+
+         begin
+            --  If S is too negative, then drop trailing digits
+
+            if S < 0 then
+               declare
+                  LS : Integer := -S;
+
+               begin
+                  Y := 10 ** Integer'Max (0, Scale);
+                  Z := Safe_Expont (B, LS, 10 ** Integer'Max (0, -Scale));
+
+                  for J in 1 .. LS loop
+                     V := V / Uns (B);
+                  end loop;
+               end;
+
+            --  If S is too positive, then scale V up, which may then overflow
+
+            elsif S > 0 then
+               declare
+                  LS  : Integer := S;
+
+               begin
+                  Y := Safe_Expont (B, LS, 10 ** Integer'Max (0, Scale));
+                  Z := 10 ** Integer'Max (0, -Scale);
+
+                  for J in 1 .. LS loop
+                     if V <= Uns'Last / Uns (B) then
+                        V := V * Uns (B);
+                     else
+                        Bad_Value (Str);
+                     end if;
+                  end loop;
+               end;
+
+            --  The case S equal to zero should have been handled earlier
+
+            else
+               raise Program_Error;
+            end if;
+
+            --  Perform a scale divide operation with rounding to match 'Image
+
+            Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q, R, Round => True);
+
+            return Q;
+         end;
+      end if;
+
+   exception
+      when Constraint_Error => Bad_Value (Str);
+   end Integer_to_Decimal;
+
+   ------------------
+   -- Scan_Decimal --
+   ------------------
+
+   function Scan_Decimal
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int
+   is
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Val    : Uns;
+
+   begin
+      Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, ScaleB, Extra, Minus);
+
+      return Integer_to_Decimal (Str, Val, Base, ScaleB, Minus, Scale);
+   end Scan_Decimal;
+
+   -------------------
+   -- Value_Decimal --
+   -------------------
+
+   function Value_Decimal (Str : String; Scale : Integer) return Int is
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Val    : Uns;
+
+   begin
+      Val := Impl.Value_Raw_Real (Str, Base, ScaleB, Extra, Minus);
+
+      return Integer_to_Decimal (Str, Val, Base, ScaleB, Minus, Scale);
+   end Value_Decimal;
+
+end System.Value_D;
diff --git a/gcc/ada/libgnat/s-valued.ads b/gcc/ada/libgnat/s-valued.ads
new file mode 100644 (file)
index 0000000..e27e171
--- /dev/null
@@ -0,0 +1,90 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . V A L U E _ D                        --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Value attribute for
+--  decimal fixed point types, and also for conversion operations required in
+--  Text_IO.Decimal_IO for such types.
+
+generic
+
+   type Int is range <>;
+
+   type Uns is mod <>;
+
+   with procedure Scaled_Divide
+          (X, Y, Z : Int;
+           Q, R : out Int;
+           Round : Boolean);
+
+package System.Value_D is
+   pragma Preelaborate;
+
+   function Scan_Decimal
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Scale : Integer) return Int;
+   --  This function scans the string starting at Str (Ptr.all) for a valid
+   --  real literal according to the syntax described in (RM 3.5(43)). The
+   --  substring scanned extends no further than Str (Max). There are three
+   --  cases for the return:
+   --
+   --  If a valid real literal is found after scanning past any initial spaces,
+   --  then Ptr.all is updated past the last character of the literal (but
+   --  trailing spaces are not scanned out). The value returned is the value
+   --  Int'Integer_Value (decimal-literal-value), using the given Scale to
+   --  determine this value.
+   --
+   --  If no valid real literal is found, then Ptr.all points either to an
+   --  initial non-digit character, or to Max + 1 if the field is all spaces
+   --  and the exception Constraint_Error is raised.
+   --
+   --  If a syntactically valid integer is scanned, but the value is out of
+   --  range, or, in the based case, the base value is out of range or there
+   --  is an out of range digit, then Ptr.all points past the integer, and
+   --  Constraint_Error is raised.
+   --
+   --  Note: these rules correspond to the requirements for leaving the
+   --  pointer positioned in Text_Io.Get
+   --
+   --  Note: if Str is null, i.e. if Max is less than Ptr, then this is a
+   --  special case of an all-blank string, and Ptr is unchanged, and hence
+   --  is greater than Max as required in this case.
+
+   function Value_Decimal (Str : String; Scale : Integer) return Int;
+   --  Used in computing X'Value (Str) where X is a decimal fixed-point type.
+   --  Str is the string argument of the attribute. Constraint_Error is raised
+   --  if the string is malformed or if the value is out of range of Int (not
+   --  the range of the fixed-point type, which must be done by the caller).
+   --  Otherwise the value returned is the value Int'Integer_Value
+   --  (decimal-literal-value), using Scale to determine this value.
+
+end System.Value_D;
diff --git a/gcc/ada/libgnat/s-valuef.adb b/gcc/ada/libgnat/s-valuef.adb
new file mode 100644 (file)
index 0000000..f3ed5fa
--- /dev/null
@@ -0,0 +1,332 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . V A L U E _ F                        --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util;       use System.Val_Util;
+with System.Value_R;
+
+package body System.Value_F is
+
+   package Impl is new Value_R (Uns, Floating => False);
+
+   function Integer_To_Fixed
+     (Str    : String;
+      Val    : Uns;
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Num    : Int;
+      Den    : Int) return Int;
+   --  Convert the real value from integer to fixed point representation
+
+   --  The goal is to compute Val * (Base ** ScaleB) / (Num / Den) with correct
+   --  rounding for all decimal values output by Typ'Image, that is to say up
+   --  to Typ'Aft decimal digits. Unlike for the output, the RM does not say
+   --  what the rounding must be for the input, but a reasonable exegesis of
+   --  the intent is that Typ'Value o Typ'Image should be the identity, which
+   --  is made possible because 'Aft is defined such that 'Image is injective.
+
+   --  For a type with a mantissa of M bits including the sign, the number N1
+   --  of decimal digits required to represent all the numbers is given by:
+
+   --    N1 = ceil ((M - 1) * log 2 / log 10) [N1 = 10/19/39 for M = 32/64/128]
+
+   --  but this mantissa can represent any set of contiguous numbers with only
+   --  N2 different decimal digits where:
+
+   --    N2 = floor ((M - 1) * log 2 / log 10) [N2 = 9/18/38 for M = 32/64/128]
+
+   --  Of course N1 = N2 + 1 holds, which means both that Val may not contain
+   --  enough significant bits to represent all the values of the type and that
+   --  1 extra decimal digit contains the information for the missing bits.
+
+   --  Therefore the actual computation to be performed is
+
+   --    V = (Val * Base + Extra) * (Base ** (ScaleB - 1)) / (Num / Den)
+
+   --  using two steps of scaled divide if Extra is non-zero
+
+   --    (1)  Val * ((Base ** ScaleB) * Den) = Q1 * Num + R1
+
+   --    (2)  Extra * ((Base ** ScaleB) * Den) = Q2 * (-Base) + R2
+
+   --  which yields after dividing (1) by Num and (2) by Num * Base and summing
+
+   --    V = Q1 + (R1 - Q2) / Num + R2 / (Num * Base)
+
+   --  but we get rid of the third term by using a rounding divide for (2).
+
+   ----------------------
+   -- Integer_To_Fixed --
+   ----------------------
+
+   function Integer_To_Fixed
+     (Str    : String;
+      Val    : Uns;
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Num    : Int;
+      Den    : Int) return Int
+   is
+      pragma Assert (Base in 2 .. 16);
+
+      pragma Assert (Extra < Base);
+      --  Accept only one extra digit after those used for Val
+
+      pragma Assert (Num < 0 and then Den < 0);
+      --  Accept only negative numbers to allow -2**(Int'Size - 1)
+
+      function Safe_Expont
+        (Base   : Int;
+         Exp    : in out Natural;
+         Factor : Int) return Int;
+      --  Return (Base ** Exp) * Factor if the computation does not overflow,
+      --  or else the number of the form (Base ** K) * Factor with the largest
+      --  magnitude if the former computation overflows. In both cases, Exp is
+      --  updated to contain the remaining power in the computation. Note that
+      --  Factor is expected to be negative in this context.
+
+      function Unsigned_To_Signed (Val : Uns) return Int;
+      --  Convert an integer value from unsigned to signed representation
+
+      -----------------
+      -- Safe_Expont --
+      -----------------
+
+      function Safe_Expont
+        (Base   : Int;
+         Exp    : in out Natural;
+         Factor : Int) return Int
+      is
+         pragma Assert (Base /= 0 and then Factor < 0);
+
+         Min : constant Int := Int'First / Base;
+
+         Result : Int := Factor;
+
+      begin
+         while Exp > 0 and then Result >= Min loop
+            Result := Result * Base;
+            Exp    := Exp - 1;
+         end loop;
+
+         return Result;
+      end Safe_Expont;
+
+      ------------------------
+      -- Unsigned_To_Signed --
+      ------------------------
+
+      function Unsigned_To_Signed (Val : Uns) return Int is
+      begin
+         --  Deal with overflow cases, and also with largest negative number
+
+         if Val > Uns (Int'Last) then
+            if Minus and then Val = Uns (-(Int'First)) then
+               return Int'First;
+            else
+               Bad_Value (Str);
+            end if;
+
+         --  Negative values
+
+         elsif Minus then
+            return -(Int (Val));
+
+         --  Positive values
+
+         else
+            return Int (Val);
+         end if;
+      end Unsigned_To_Signed;
+
+      --  Local variables
+
+      B : constant Int := Int (Base);
+
+      V : Uns     := Val;
+      S : Integer := ScaleB;
+      E : Uns     := Uns (Extra);
+      N : Int     := Num;
+      D : Int     := Den;
+
+      Y, Z, Q1, R1, Q2, R2 : Int;
+
+   begin
+      --  We will use a scaled divide operation for which we must control the
+      --  magnitude of operands so that an overflow exception is not unduly
+      --  raised during the computation. The only real concern is the exponent
+      --  ScaleB so first try to reduce its magnitude in an exact manner.
+
+      while S < 0 and then (D rem B) = 0 loop
+         D := D / B;
+         S := S + 1;
+      end loop;
+
+      while S > 0 and then (N rem B) = 0 loop
+         N := N / B;
+         S := S - 1;
+      end loop;
+
+      --  If S is still too negative, then drop trailing digits, but preserve
+      --  the last dropped digit.
+
+      if S < 0 then
+         declare
+            LS : Integer := -S;
+
+         begin
+            Y := D;
+            Z := Safe_Expont (B, LS, N);
+
+            for J in 1 .. LS loop
+               E := V rem Uns (B);
+               V := V / Uns (B);
+            end loop;
+         end;
+
+      --  If S is still too positive, then scale V up, which may then overflow
+
+      elsif S > 0 then
+         declare
+            LS  : Integer := S;
+
+         begin
+            Y := Safe_Expont (B, LS, D);
+            Z := N;
+
+            for J in 1 .. LS loop
+               if V <= Uns'Last / Uns (B) then
+                  V := V * Uns (B);
+               else
+                  Bad_Value (Str);
+               end if;
+            end loop;
+         end;
+
+      --  If S is zero, then proceed directly
+
+      else
+         Y := D;
+         Z := N;
+      end if;
+
+      --  Perform a scaled divide operation with final rounding to match Image
+      --  using two steps if there is an extra digit available. The second and
+      --  third operands are always negative so the sign of the quotient is the
+      --  sign of the first operand and the sign of the remainder the opposite.
+
+      if E /= 0 then
+         Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => False);
+         Scaled_Divide (Unsigned_To_Signed (E), Y, -B, Q2, R2, Round => True);
+
+         --  Avoid an overflow during the subtraction. Note that Q2 is smaller
+         --  than Y and R1 smaller than Z in magnitude, so it is safe to take
+         --  their absolute value.
+
+         if abs Q2 >= 2 ** (Int'Size - 2)
+           or else abs R1 >= 2 ** (Int'Size - 2)
+         then
+            declare
+               Bit : constant Int := Q2 rem 2;
+
+            begin
+               Q2 := (Q2 - Bit) / 2;
+               R1 := (R1 - Bit) / 2;
+               Y  := -2;
+            end;
+
+         else
+            Y := -1;
+         end if;
+
+         Scaled_Divide (Q2 - R1, Y, Z, Q2, R2, Round => True);
+
+         return Q1 + Q2;
+
+      else
+         Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => True);
+
+         return Q1;
+      end if;
+
+   exception
+      when Constraint_Error => Bad_Value (Str);
+   end Integer_To_Fixed;
+
+   ----------------
+   -- Scan_Fixed --
+   ----------------
+
+   function Scan_Fixed
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int;
+      Den : Int) return Int
+   is
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Val    : Uns;
+
+   begin
+      Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, ScaleB, Extra, Minus);
+
+      return Integer_To_Fixed (Str, Val, Base, ScaleB, Extra, Minus, Num, Den);
+   end Scan_Fixed;
+
+   -----------------
+   -- Value_Fixed --
+   -----------------
+
+   function Value_Fixed
+     (Str : String;
+      Num : Int;
+      Den : Int) return Int
+   is
+      Base   : Unsigned;
+      ScaleB : Integer;
+      Extra  : Unsigned;
+      Minus  : Boolean;
+      Val    : Uns;
+
+   begin
+      Val := Impl.Value_Raw_Real (Str, Base, ScaleB, Extra, Minus);
+
+      return Integer_To_Fixed (Str, Val, Base, ScaleB, Extra, Minus, Num, Den);
+   end Value_Fixed;
+
+end System.Value_F;
diff --git a/gcc/ada/libgnat/s-valuef.ads b/gcc/ada/libgnat/s-valuef.ads
new file mode 100644 (file)
index 0000000..fac8c23
--- /dev/null
@@ -0,0 +1,94 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . V A L U E _ F                        --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains the routines for supporting the Value attribute for
+--  ordinary fixed point types, and also for conversion operations required in
+--  Text_IO.Fixed_IO for such types.
+
+generic
+
+   type Int is range <>;
+
+   type Uns is mod <>;
+
+   with procedure Scaled_Divide
+          (X, Y, Z : Int;
+           Q, R : out Int;
+           Round : Boolean);
+
+package System.Value_F is
+   pragma Preelaborate;
+
+   function Scan_Fixed
+     (Str : String;
+      Ptr : not null access Integer;
+      Max : Integer;
+      Num : Int;
+      Den : Int) return Int;
+   --  This function scans the string starting at Str (Ptr.all) for a valid
+   --  real literal according to the syntax described in (RM 3.5(43)). The
+   --  substring scanned extends no further than Str (Max). There are three
+   --  cases for the return:
+   --
+   --  If a valid real literal is found after scanning past any initial spaces,
+   --  then Ptr.all is updated past the last character of the literal (but
+   --  trailing spaces are not scanned out). The value returned is the value
+   --  Int'Integer_Value (decimal-literal-value), using the given Num/Den to
+   --  determine this value.
+   --
+   --  If no valid real literal is found, then Ptr.all points either to an
+   --  initial non-digit character, or to Max + 1 if the field is all spaces
+   --  and the exception Constraint_Error is raised.
+   --
+   --  If a syntactically valid integer is scanned, but the value is out of
+   --  range, or, in the based case, the base value is out of range or there
+   --  is an out of range digit, then Ptr.all points past the integer, and
+   --  Constraint_Error is raised.
+   --
+   --  Note: these rules correspond to the requirements for leaving the
+   --  pointer positioned in Text_Io.Get
+   --
+   --  Note: if Str is null, i.e. if Max is less than Ptr, then this is a
+   --  special case of an all-blank string, and Ptr is unchanged, and hence
+   --  is greater than Max as required in this case.
+
+   function Value_Fixed
+     (Str : String;
+      Num : Int;
+      Den : Int) return Int;
+   --  Used in computing X'Value (Str) where X is an ordinary fixed-point type.
+   --  Str is the string argument of the attribute. Constraint_Error is raised
+   --  if the string is malformed or if the value is out of range of Int (not
+   --  the range of the fixed-point type, which must be done by the caller).
+   --  Otherwise the value returned is the value Int'Integer_Value
+   --  (decimal-literal-value), using Small Num/Den to determine this value.
+
+end System.Value_F;
index 1bc8b32f8537e36ea842531016c5063040f4de7f..ac5a7761c65c0d07beecb01f81388e6acf921a08 100644 (file)
@@ -61,7 +61,7 @@ package body System.Value_I is
 
       Uval := Scan_Raw_Unsigned (Str, Ptr, Max);
 
-      --  Deal with overflow cases, and also with maximum negative number
+      --  Deal with overflow cases, and also with largest negative number
 
       if Uval > Uns (Int'Last) then
          if Minus and then Uval = Uns (-(Int'First)) then
diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb
new file mode 100644 (file)
index 0000000..a91fbb8
--- /dev/null
@@ -0,0 +1,582 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                      S Y S T E M . V A L U E _ R                         --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with System.Val_Util; use System.Val_Util;
+
+package body System.Value_R is
+
+   F_Limit : constant Uns := 2 ** (Long_Long_Float'Machine_Mantissa - 1);
+   I_Limit : constant Uns := 2 ** (Uns'Size - 1);
+   --  Absolute value of largest representable signed integer
+
+   Precision_Limit : constant Uns := (if Floating then F_Limit else I_Limit);
+   --  Limit beyond which additional digits are dropped
+
+   subtype Char_As_Digit is Unsigned range 0 .. 17;
+   subtype Valid_Digit is Char_As_Digit range 0 .. 15;
+   E_Digit     : constant Char_As_Digit := 14;
+   Underscore  : constant Char_As_Digit := 16;
+   Not_A_Digit : constant Char_As_Digit := 17;
+
+   function As_Digit (C : Character) return Char_As_Digit;
+   --  Given a character return the digit it represents
+
+   procedure Scan_Decimal_Digits
+      (Str            : String;
+       Index          : in out Integer;
+       Max            : Integer;
+       Value          : in out Uns;
+       Scale          : in out Integer;
+       Extra          : in out Char_As_Digit;
+       Base_Violation : in out Boolean;
+       Base           : Unsigned;
+       Base_Specified : Boolean);
+   --  Scan the decimal part of a real (i.e. after decimal separator)
+   --
+   --  The string parsed is Str (Index .. Max) and after the call Index will
+   --  point to the first non-parsed character.
+   --
+   --  For each digit parsed, Value = Value * Base + Digit and Scale is
+   --  decremented by 1. If precision limit is reached, remaining digits are
+   --  still parsed but ignored, except for the first which is stored in Extra.
+   --
+   --  Base_Violation is set to True if a digit found is not part of the Base
+   --
+   --  If Base_Specified is set, then the base was specified in the real
+
+   procedure Scan_Integral_Digits
+      (Str            : String;
+       Index          : in out Integer;
+       Max            : Integer;
+       Value          : out Uns;
+       Scale          : out Integer;
+       Extra          : out Char_As_Digit;
+       Base_Violation : in out Boolean;
+       Base           : Unsigned;
+       Base_Specified : Boolean);
+   --  Scan the integral part of a real (i.e. before decimal separator)
+   --
+   --  The string parsed is Str (Index .. Max) and after the call Index will
+   --  point to the first non-parsed character.
+   --
+   --  For each digit parsed, either Value := Value * Base + Digit or Scale
+   --  is incremented by 1 if precision limit is reached, in which case the
+   --  remaining digits are still parsed but ignored, except for the first
+   --  which is stored in Extra.
+   --
+   --  Base_Violation is set to True if a digit found is not part of the Base
+   --
+   --  If Base_Specified is set, then the base was specified in the real
+
+   --------------
+   -- As_Digit --
+   --------------
+
+   function As_Digit (C : Character) return Char_As_Digit is
+   begin
+      case C is
+         when '0' .. '9' =>
+            return Character'Pos (C) - Character'Pos ('0');
+         when 'a' .. 'f' =>
+            return Character'Pos (C) - (Character'Pos ('a') - 10);
+         when 'A' .. 'F' =>
+            return Character'Pos (C) - (Character'Pos ('A') - 10);
+         when '_' =>
+            return Underscore;
+         when others =>
+            return Not_A_Digit;
+      end case;
+   end As_Digit;
+
+   -------------------------
+   -- Scan_Decimal_Digits --
+   -------------------------
+
+   procedure Scan_Decimal_Digits
+      (Str            : String;
+       Index          : in out Integer;
+       Max            : Integer;
+       Value          : in out Uns;
+       Scale          : in out Integer;
+       Extra          : in out Char_As_Digit;
+       Base_Violation : in out Boolean;
+       Base           : Unsigned;
+       Base_Specified : Boolean)
+
+   is
+      pragma Assert (Base in 2 .. 16);
+
+      Umax : constant Uns := (Precision_Limit - Uns (Base) + 1) / Uns (Base);
+      --  Max value which cannot overflow on accumulating next digit
+
+      UmaxB : constant Uns := Precision_Limit / Uns (Base);
+      --  Numbers bigger than UmaxB overflow if multiplied by base
+
+      Precision_Limit_Reached : Boolean := False;
+      --  Set to True if addition of a digit will cause Value to be superior
+      --  to Precision_Limit.
+
+      Digit : Char_As_Digit;
+      --  The current digit
+
+      Temp : Uns;
+      --  Temporary
+
+      Trailing_Zeros : Natural := 0;
+      --  Number of trailing zeros at a given point
+
+   begin
+      --  If initial Scale is not 0 then it means that Precision_Limit was
+      --  reached during scanning of the integral part.
+
+      if Scale > 0 then
+         Precision_Limit_Reached := True;
+      else
+         Extra := 0;
+      end if;
+
+      --  The function precondition is that the first character is a valid
+      --  digit.
+
+      Digit := As_Digit (Str (Index));
+
+      loop
+         --  Check if base is correct. If the base is not specified, the digit
+         --  E or e cannot be considered as a base violation as it can be used
+         --  for exponentiation.
+
+         if Digit >= Base then
+            if Base_Specified then
+               Base_Violation := True;
+            elsif Digit = E_Digit then
+               return;
+            else
+               Base_Violation := True;
+            end if;
+         end if;
+
+         --  If precision limit has been reached, just ignore any remaining
+         --  digits for the computation of Value and Scale, but store the
+         --  first in Extra. The scanning should continue only to assess the
+         --  validity of the string.
+
+         if not Precision_Limit_Reached then
+
+            --  Trailing '0' digits are ignored until a non-zero digit is found
+
+            if Digit = 0 then
+               Trailing_Zeros := Trailing_Zeros + 1;
+
+            else
+               --  Handle accumulated zeros.
+
+               for J in 1 .. Trailing_Zeros loop
+                  if Value <= UmaxB then
+                     Value := Value * Uns (Base);
+                     Scale := Scale - 1;
+
+                  else
+                     Precision_Limit_Reached := True;
+                     exit;
+                  end if;
+               end loop;
+
+               --  Reset trailing zero counter
+
+               Trailing_Zeros := 0;
+
+               --  Handle current non zero digit
+
+               Temp := Value * Uns (Base) + Uns (Digit);
+
+               if Value <= Umax
+                   or else (Value <= UmaxB and then Temp <= Precision_Limit)
+               then
+                  Value := Temp;
+                  Scale := Scale - 1;
+
+               else
+                  Extra := Digit;
+                  Precision_Limit_Reached := True;
+               end if;
+            end if;
+         end if;
+
+         --  Check next character
+
+         Index := Index + 1;
+
+         if Index > Max then
+            return;
+         end if;
+
+         Digit := As_Digit (Str (Index));
+
+         if Digit not in Valid_Digit then
+
+            --  Underscore is only allowed if followed by a digit
+
+            if Digit = Underscore and Index + 1 <= Max then
+
+               Digit := As_Digit (Str (Index + 1));
+               if Digit in Valid_Digit then
+                  Index := Index + 1;
+               else
+                  return;
+               end if;
+
+            --  Neither a valid underscore nor a digit
+
+            else
+               return;
+            end if;
+         end if;
+      end loop;
+   end Scan_Decimal_Digits;
+
+   --------------------------
+   -- Scan_Integral_Digits --
+   --------------------------
+
+   procedure Scan_Integral_Digits
+      (Str            : String;
+       Index          : in out Integer;
+       Max            : Integer;
+       Value          : out Uns;
+       Scale          : out Integer;
+       Extra          : out Char_As_Digit;
+       Base_Violation : in out Boolean;
+       Base           : Unsigned;
+       Base_Specified : Boolean)
+   is
+      pragma Assert (Base in 2 .. 16);
+
+      Umax : constant Uns := (Precision_Limit - Uns (Base) + 1) / Uns (Base);
+      --  Max value which cannot overflow on accumulating next digit
+
+      UmaxB : constant Uns := Precision_Limit / Uns (Base);
+      --  Numbers bigger than UmaxB overflow if multiplied by base
+
+      Precision_Limit_Reached : Boolean := False;
+      --  Set to True if addition of a digit will cause Value to be superior
+      --  to Precision_Limit.
+
+      Digit : Char_As_Digit;
+      --  The current digit
+
+      Temp : Uns;
+      --  Temporary
+
+   begin
+      --  Initialize Value, Scale and Extra
+
+      Value := 0;
+      Scale := 0;
+      Extra := 0;
+
+      --  The function precondition is that the first character is a valid
+      --  digit.
+
+      Digit := As_Digit (Str (Index));
+
+      loop
+         --  Check if base is correct. If the base is not specified, the digit
+         --  E or e cannot be considered as a base violation as it can be used
+         --  for exponentiation.
+
+         if Digit >= Base then
+            if Base_Specified then
+               Base_Violation := True;
+            elsif Digit = E_Digit then
+               return;
+            else
+               Base_Violation := True;
+            end if;
+         end if;
+
+         --  If precision limit has been reached, just ignore any remaining
+         --  digits for the computation of Value, but update Scale and store
+         --  the first in Extra. The scanning should continue only to assess
+         --  the validity of the string.
+
+         if Precision_Limit_Reached then
+            Scale := Scale + 1;
+
+         else
+            Temp := Value * Uns (Base) + Uns (Digit);
+
+            if Value <= Umax
+              or else (Value <= UmaxB and then Temp <= Precision_Limit)
+            then
+               Value := Temp;
+
+            else
+               Extra := Digit;
+               Precision_Limit_Reached := True;
+               Scale := Scale + 1;
+            end if;
+         end if;
+
+         --  Look for the next character
+
+         Index := Index + 1;
+         if Index > Max then
+            return;
+         end if;
+
+         Digit := As_Digit (Str (Index));
+
+         if Digit not in Valid_Digit then
+
+            --  Next character is not a digit. In that case stop scanning
+            --  unless the next chracter is an underscore followed by a digit.
+
+            if Digit = Underscore and Index + 1 <= Max then
+               Digit := As_Digit (Str (Index + 1));
+               if Digit in Valid_Digit then
+                  Index := Index + 1;
+               else
+                  return;
+               end if;
+            else
+               return;
+            end if;
+         end if;
+      end loop;
+
+   end Scan_Integral_Digits;
+
+   -------------------
+   -- Scan_Raw_Real --
+   -------------------
+
+   function Scan_Raw_Real
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Base  : out Unsigned;
+      Scale : out Integer;
+      Extra : out Unsigned;
+      Minus : out Boolean) return Uns
+   is
+      After_Point : Boolean;
+      --  True if a decimal should be parsed
+
+      Base_Char : Character := ASCII.NUL;
+      --  Character used to set the base. If Nul this means that default
+      --  base is used.
+
+      Base_Violation : Boolean := False;
+      --  If True some digits where not in the base. The real is still scanned
+      --  till the end even if an error will be raised.
+
+      Index : Integer;
+      --  Local copy of string pointer
+
+      Start : Positive;
+      --  Position of starting non-blank character
+
+      Value : Uns;
+      --  Mantissa as an Integer
+
+   begin
+      --  The default base is 10
+
+      Base := 10;
+
+      --  We do not tolerate strings with Str'Last = Positive'Last
+
+      if Str'Last = Positive'Last then
+         raise Program_Error with
+           "string upper bound is Positive'Last, not supported";
+      end if;
+
+      --  Scan the optional sign
+
+      Scan_Sign (Str, Ptr, Max, Minus, Start);
+      Index := Ptr.all;
+      Ptr.all := Start;
+
+      --  First character can be either a decimal digit or a dot
+
+      if Str (Index) in '0' .. '9' then
+         After_Point := False;
+
+         pragma Annotate
+           (CodePeer, Intentional, "test always true", "defensive code below");
+
+         --  If this is a digit it can indicates either the float decimal
+         --  part or the base to use.
+
+         Scan_Integral_Digits
+           (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+            Base_Violation, Base, Base_Specified => False);
+
+      --  A dot is allowed only if followed by a digit (RM 3.5(47))
+
+      elsif Str (Index) = '.'
+        and then Index < Max
+        and then Str (Index + 1) in '0' .. '9'
+      then
+         After_Point := True;
+         Index := Index + 1;
+         Value := 0;
+         Scale := 0;
+         Extra := 0;
+
+      else
+         Bad_Value (Str);
+      end if;
+
+      --  Check if the first number encountered is a base
+
+      if Index < Max
+        and then (Str (Index) = '#' or else Str (Index) = ':')
+      then
+         Base_Char := Str (Index);
+         Base := Unsigned (Value);
+
+         if Base < 2 or else Base > 16 then
+            Base_Violation := True;
+            Base := 16;
+         end if;
+
+         Index := Index + 1;
+
+         if Str (Index) = '.'
+           and then Index < Max
+           and then As_Digit (Str (Index + 1)) in Valid_Digit
+         then
+            After_Point := True;
+            Index := Index + 1;
+            Value := 0;
+         end if;
+      end if;
+
+      --  Scan the integral part if still necessary
+
+      if Base_Char /= ASCII.NUL and then not After_Point then
+         if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then
+            Bad_Value (Str);
+         end if;
+
+         Scan_Integral_Digits
+           (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+            Base_Violation, Base, Base_Specified => Base_Char /= ASCII.NUL);
+      end if;
+
+      --  Do we have a dot?
+
+      if not After_Point and then Index <= Max and then Str (Index) = '.' then
+
+         --  At this stage if After_Point was not set, this means that an
+         --  integral part has been found. Thus the dot is valid even if not
+         --  followed by a digit.
+
+         if Index < Max and then As_Digit (Str (Index + 1)) in Valid_Digit then
+            After_Point := True;
+         end if;
+
+         Index := Index + 1;
+      end if;
+
+      --  Scan the decimal part
+
+      if After_Point then
+         Scan_Decimal_Digits
+           (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+            Base_Violation, Base, Base_Specified => Base_Char /= ASCII.NUL);
+      end if;
+
+      --  If an explicit base was specified ensure that the delimiter is found
+
+      if Base_Char /= ASCII.NUL then
+         if Index > Max or else Str (Index) /= Base_Char then
+            Bad_Value (Str);
+         else
+            Index := Index + 1;
+         end if;
+      end if;
+
+      --  Update pointer and scan exponent
+
+      Ptr.all := Index;
+      Scale := Scale + Scan_Exponent (Str, Ptr, Max, Real => True);
+
+      --  Here is where we check for a bad based number
+
+      if Base_Violation then
+         Bad_Value (Str);
+      else
+         return Value;
+      end if;
+
+   end Scan_Raw_Real;
+
+   --------------------
+   -- Value_Raw_Real --
+   --------------------
+
+   function Value_Raw_Real
+     (Str   : String;
+      Base  : out Unsigned;
+      Scale : out Integer;
+      Extra : out Unsigned;
+      Minus : out Boolean) return Uns
+   is
+   begin
+      --  We have to special case Str'Last = Positive'Last because the normal
+      --  circuit ends up setting P to Str'Last + 1 which is out of bounds. We
+      --  deal with this by converting to a subtype which fixes the bounds.
+
+      if Str'Last = Positive'Last then
+         declare
+            subtype NT is String (1 .. Str'Length);
+         begin
+            return Value_Raw_Real (NT (Str), Base, Scale, Extra, Minus);
+         end;
+
+      --  Normal case where Str'Last < Positive'Last
+
+      else
+         declare
+            V : Uns;
+            P : aliased Integer := Str'First;
+         begin
+            V := Scan_Raw_Real
+                   (Str, P'Access, Str'Last, Base, Scale, Extra, Minus);
+            Scan_Trailing_Blanks (Str, P);
+            return V;
+         end;
+      end if;
+   end Value_Raw_Real;
+
+end System.Value_R;
diff --git a/gcc/ada/libgnat/s-valuer.ads b/gcc/ada/libgnat/s-valuer.ads
new file mode 100644 (file)
index 0000000..8d2f3fd
--- /dev/null
@@ -0,0 +1,99 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                       S Y S T E M . V A L U E _ R                        --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2020, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package contains routines for scanning real values for use in
+--  Text_IO.Decimal_IO, Fixed_IO, Float_IO and the Value attribute.
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+
+generic
+
+   type Uns is mod <>;
+
+   Floating : Boolean;
+
+package System.Value_R is
+   pragma Preelaborate;
+
+   function Scan_Raw_Real
+     (Str   : String;
+      Ptr   : not null access Integer;
+      Max   : Integer;
+      Base  : out Unsigned;
+      Scale : out Integer;
+      Extra : out Unsigned;
+      Minus : out Boolean) return Uns;
+   --  This function scans the string starting at Str (Ptr.all) for a valid
+   --  real literal according to the syntax described in (RM 3.5(43)). The
+   --  substring scanned extends no further than Str (Max). There are three
+   --  cases for the return:
+   --
+   --  If a valid real is found after scanning past any initial spaces, then
+   --  Ptr.all is updated past the last character of the real (but trailing
+   --  spaces are not scanned out) and the Base, Scale, Extra and Minus out
+   --  parameters are set; if Val is the result of the call, then the real
+   --  represented by the literal is equal to
+   --
+   --    (Val * Base + Extra) * (Base ** (Scale - 1))
+   --
+   --  with the negative sign if Minus is true.
+   --
+   --  If no valid real is found, then Ptr.all points either to an initial
+   --  non-blank character, or to Max + 1 if the field is all spaces and the
+   --  exception Constraint_Error is raised.
+   --
+   --  If a syntactically valid real is scanned, but the value is out of
+   --  range, or, in the based case, the base value is out of range or there
+   --  is an out of range digit, then Ptr.all points past the real literal,
+   --  and Constraint_Error is raised.
+   --
+   --  Note: these rules correspond to the requirements for leaving the
+   --  pointer positioned in Text_Io.Get
+   --
+   --  Note: if Str is null, i.e. if Max is less than Ptr, then this is a
+   --  special case of an all-blank string, and Ptr is unchanged, and hence
+   --  is greater than Max as required in this case.
+   --
+   --  Note: this routine should not be called with Str'Last = Positive'Last.
+   --  If this occurs Program_Error is raised with a message noting that this
+   --  case is not supported. Most such cases are eliminated by the caller.
+
+   function Value_Raw_Real
+     (Str   : String;
+      Base  : out Unsigned;
+      Scale : out Integer;
+      Extra : out Unsigned;
+      Minus : out Boolean) return Uns;
+   --  Used in computing X'Value (Str) where X is a real type. Str is the
+   --  string argument of the attribute. Constraint_Error is raised if the
+   --  string is malformed.
+
+end System.Value_R;
index 5bf603d775f3478d92b15890996b9f1183ef3989..e346759c0fe84cc76d1cdaeb3da06f14ca505b95 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 70e02a1245218587c7b300b0b2cbf6591a54b3d9..e1af6825068999d00fed9532fc68b186a362403a 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 4947c6cdc25e8de99f772013a0247f7125778d72..0b746cc2a9f4325fb1f0ed809d92f633add220e9 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 828b310671d167c406465a599479226f20a5ea61..e27379e0ee0f1400671acc1b61e3cfe3af455e58 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 68fdb49698a9497a1a6e2f1f1998a4d997bef5a2..35d9381fd647f069d2c444557be007fb427553d4 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 6bfb5c4929342f35c6afd19d684b9e736c2bc38b..80da5afb02ed1242719b01286e2910242e2e7c4e 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index d4fe60ea0ade60e160fc24dfb76c7482ab111e1a..e8765b82786abc4ddc243100b512664780133b05 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index f11edc61652dbe43d5af982802272cf3e4a96456..12252db584ddceed4ee6fdec791996287fc3d1d0 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index ddf6a82e8bf16cecf9379259138d5a026b98ba34..71a1668b532c9f63ce66a71fca6f40cbb90208a1 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index eebe93a0d9fb2955269cba8ff018e943c8ef3b4e..d639630eec0f1137feef55d94ece8d769cac6711 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 1024.0;
index 4d09d9e2de593e2a26a9a22fb7dfedffc42b31b3..6831aad74ec84771fb39aebf82497c554e14b687 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index 6bc95413a371d9388fabb0b674e9ba4ee0f2d69f..669289db3a72b935d009ae04336a61b819906af3 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index ae9b49a90be4ab6fa52d388f7463299414a3a0bf..1dca30c64f08a14d27518b51503ea7b7a84d2388 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 3fbd78197b9fd943195a4d33a6b97490ba0245ca..6a98466714c9431963556462f4c7a2d731c07c2d 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index d760db815b709f6299142257dec3cbd09f2c02e6..8476f900e37ea5d024c0ca113f06620ed65790c8 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index 0f393707873692c9e6ae0178223d8b9e9cb9435e..9785c9a7d0619c8ce0a3baa79cf4ce0312a7e87b 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index 91eddf29dc56ec6c45842797a25a5fb5e565e63b..a298bcd0a4ae595d439ed473e0854e62c277eaff 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index 374b938b00605e9504cd689f47693b3dac7b060c..3d80ce7748b1922e14f09b70daa431929d45a97c 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index cd811defb55d55acb831937e8ce8986c3fb69a15..6227bdb9f05a93c24d863db603b0236c285707b1 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index e74214bb53c30fe3d78eac79bc081e131def5094..0549a8510d011666d38a4d992a81015f022a38da 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index eb8b5dd68c968e8ba3ee995e686cc46f53df1aa2..5b2b77fd08f334ce25cfd7db090e4108e28aba7f 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index cf516e164ac8ab3abc23b8b2355bc6fb9e059230..70de803a73dca4da9db0c9d1198e236a0e97d4fa 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index c1514722d815b543329d6edfb5ac88c0d81ce729..b14f48b2082b7f518ef2286900f7704c137b08e4 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index cf960da406666899fd9f4deae5a8443cf5796d96..c05dee7e61c8abf3562ab613acb0636d11a9c2db 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 37b8fd124af6305f1e8b76fe2afd33396e085f34..f3316c32366cf4a183b2316fdbab251f3e041e1d 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.000_001;
index 099c234ee6e8244c90391b1847ddc396ccec9937..8907d9e16e33010bd97ad7894f6f17590dbda8d0 100644 (file)
@@ -61,7 +61,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 0e1ce016d834e68280f291aac379d9990f04f6b3..f211eeda8dd35cc928f71dfd2d879de96e037ba7 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 010ce5b30297de6aab5064254c7ab4e18a4a2d63..82fe6568add6993dd4cdfb42b1b6af62e00fa7f7 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 0.01;
index 91806e508357734d1ecadff0baa698c78e590cc7..7412611ceb544f9977565b1b1edabb9de4c177a6 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index de139747e070469b15504ada2171f0a1903e53a6..697f35196b566a03982741446dec668076d42936 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index fac4e7252e8fc43f2fb53b03efaf0b3abcd91be7..5f767b229febc28f0eff1271468b3399cf2261f8 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index cf89c2dc0a8ab8bcd2418d6b2a36804307b11f67..2d64186eb709bc0677dde13c0559d7c3530bfcae 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 862f3f676d3c38335c74536bf123b52658c8fb0b..46cd6e718a43dcbc09f493d8848f70e7ecfdcd2f 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index a3baecb2d39d128abf4f3a9bcc4f99b86e757494..c232fe018e75ae04d1567a3888ecdc189024d15f 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index fc92958f5d851f0f2cab672f2c3a7963a4927679..929a6421c02d45994598bd2d22be1542c959e151 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 383c82078ff454bc8f8256ec4f870864987adee8..63cebb7d8d7f50fee7481cee06dc808e59d4811c 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 53a1f9e5f6fadabf0ef3f51c5848f5473e563a04..4347a01831246d7a2813bfbcb01e3914d311a3f9 100644 (file)
@@ -82,7 +82,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index aa99413142043c563c84640b3ce7ad553a821377..469c0f3e588719959e297892a8cd85180fc3dd4e 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index acb20c48d17c8ea72d3c423acc7bad7d8a1e60cc..8fba1b0f94459dc69d13598de4da01697cd0cf06 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index aca420e72ac5fdc68475f3ca3afb22639c9fef12..a4f4eb2eb86d70d7e334c4d82a10ed291447d2a9 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 99644ee7f2c67c60b36eaa6d5f13655785077058..67d936a7a1ca1422255e30a1506092e91639b5e1 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 3781020fdcccc6f2a560d54b45c0dc74cc3134de..e4d03446d8ee32c80977c70319f6078d7511dc93 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 374041c21f93c3d21a36bd396603ca686a2740ee..f2a41425c0e297f0144ab5c1532afbdc86a9e33a 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index cff7291619bcf00d87f7b5fb5ec0e1b13d051d2f..d597600a1947a556c69447edcf673098434a22f4 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 1867196eda5e706f243dc1ed810922762463a78e..a1eb8f0f6c7aea54f752a8067de8d9a78a22fd7e 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index c82a61f29fe83c745fd58d4a8c4be06b7d18cc2f..226a3dc8dc7468d1d613f777a2ad488cb246400f 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 37bf607d60019ee9a32dc9f133d5266bd0f7bbd6..e2ed214288f92610fa386f07841c00e63a855367 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index c3865008ced4506f1a3142ef82c2b2b3b014df5f..ef1211b36580ea09545a970a024ff06588cde781 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 7e2db7ab4f86907ff5317d3027221cdab84e7a97..2b4c64eba4e6e6ffeec266cd6023eaf2387e2188 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index fac4e7252e8fc43f2fb53b03efaf0b3abcd91be7..5f767b229febc28f0eff1271468b3399cf2261f8 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index e03264ec3f1f5c5fa524a25d6dfab1c2f95c0452..4182a1fd87c06c60f5d17f1d29d91a48abd82eca 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index a9b33178e6c93cdade49ac4978ae71dc3ff732fe..d4a303b03b70db814801268ece6ad92babad2e87 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 3e963d0c80c122caee6c7e488a2e02106a6a6d65..c7acf958c2cf3d913bb276add332d3553b7519a7 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 93b327195ad8478860bba5fc26f82378894e888e..71d06b453b5e4c1eae13ea51e5d6ee9c60aaabc4 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index e5d984b25ea2df9bf9b5d6df95338097f364ef9f..387961426f318c4402209d79f9935dae9d352d50 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index e96d3037fc4b5582fc4722ae7e81a7a7593f7b4d..b5393cd1f53a1029d6ddc26ce44a3aa06f4f0b29 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 90499f63999ec5c56d1cba5d9a96e433670cbde8..94f69eeeabb00b1758dacd56ee2b714287fe0e0e 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 49b22b63ebf722e0acfccac011b12412710b3fae..bafa41d3d82c7128b931ed01728a1d8a74014d1c 100644 (file)
@@ -59,7 +59,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index d7b35dd46dee1d5796d883cdaf8d19b04cf03c67..ae0c39fb0cd55dbd35134443dfe8fb7cbae0a0d5 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 293ede87417beae1d6e663125a8abf80c274fab2..4681bbaf627da89171fba97525107946abb7ccf1 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index caf458fae15806e87bfc2fdac733eb2f7e872b04..6b176d1dea17096e78f2c43566bf7dc65619e5c5 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index a5f00ff9a5e1431fc8d405f37f7a6d2bae29760c..eadf5ee1b84d9ac21ec91409d4e028ac128a1577 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 05e69e5ab0912a087d4d49d5aa1aac85821373bc..a97b80a9290cd7fa3cbdb23dc6aa7b4f53ea3b71 100644 (file)
@@ -57,7 +57,7 @@ package System is
    Max_Base_Digits       : constant := Long_Long_Float'Digits;
    Max_Digits            : constant := Long_Long_Float'Digits;
 
-   Max_Mantissa          : constant := 63;
+   Max_Mantissa          : constant := Standard'Max_Integer_Size - 1;
    Fine_Delta            : constant := 2.0 ** (-Max_Mantissa);
 
    Tick                  : constant := 1.0 / 60.0;
index 42578dbef3202771acdac89a874ed7e44c41f2de..c1ea69511cb1910454a62e45f312716100a072ed 100644 (file)
@@ -249,14 +249,24 @@ package Rtsfind is
       System_Fat_VAX_G_Float,
       System_Finalization_Masters,
       System_Finalization_Root,
-      System_Fore,
+      System_Fore_Decimal_32,
+      System_Fore_Decimal_64,
+      System_Fore_Decimal_128,
+      System_Fore_Fixed_32,
+      System_Fore_Fixed_64,
+      System_Fore_Fixed_128,
+      System_Fore_Real,
       System_Img_Bool,
       System_Img_Char,
-      System_Img_Dec,
+      System_Img_Decimal_32,
+      System_Img_Decimal_64,
+      System_Img_Decimal_128,
       System_Img_Enum,
       System_Img_Enum_New,
+      System_Img_Fixed_32,
+      System_Img_Fixed_64,
+      System_Img_Fixed_128,
       System_Img_Int,
-      System_Img_LLD,
       System_Img_LLI,
       System_Img_LLLI,
       System_Img_LLU,
@@ -417,10 +427,14 @@ package Rtsfind is
       System_Unsigned_Types,
       System_Val_Bool,
       System_Val_Char,
-      System_Val_Dec,
+      System_Val_Decimal_32,
+      System_Val_Decimal_64,
+      System_Val_Decimal_128,
       System_Val_Enum,
+      System_Val_Fixed_32,
+      System_Val_Fixed_64,
+      System_Val_Fixed_128,
       System_Val_Int,
-      System_Val_LLD,
       System_Val_LLI,
       System_Val_LLLI,
       System_Val_LLU,
@@ -756,8 +770,10 @@ package Rtsfind is
      RE_Subtract_With_Ovflo_Check64,     -- System.Arith_64
 
      RE_Add_With_Ovflo_Check128,         -- System.Arith_128
+     RE_Double_Divide128,                -- System.Arith_128
      RE_Multiply_With_Ovflo_Check128,    -- System.Arith_128
      RE_Subtract_With_Ovflo_Check128,    -- System.Arith_128
+     RE_Scaled_Divide128,                -- System.Arith_128
 
      RE_Create_AST_Handler,              -- System.AST_Handling
 
@@ -943,14 +959,30 @@ package Rtsfind is
      RE_Root_Controlled,                 -- System.Finalization_Root
      RE_Root_Controlled_Ptr,             -- System.Finalization_Root
 
-     RE_Fore,                            -- System.Fore
+     RE_Fore_Decimal32,                  -- System.Fore_Decimal_32
+
+     RE_Fore_Decimal64,                  -- System.Fore_Decimal_64
+
+     RE_Fore_Decimal128,                 -- System.Fore_Decimal_128
+
+     RE_Fore_Fixed32,                    -- System.Fore_Fixed_32
+
+     RE_Fore_Fixed64,                    -- System.Fore_Fixed_64
+
+     RE_Fore_Fixed128,                   -- System.Fore_Fixed_128
+
+     RE_Fore_Real,                       -- System.Fore_Real
 
      RE_Image_Boolean,                   -- System.Img_Bool
 
      RE_Image_Character,                 -- System.Img_Char
      RE_Image_Character_05,              -- System.Img_Char
 
-     RE_Image_Decimal,                   -- System.Img_Dec
+     RE_Image_Decimal32,                 -- System.Img_Decimal_32
+
+     RE_Image_Decimal64,                 -- System.Img_Decimal_64
+
+     RE_Image_Decimal128,                -- System.Img_Decimal_128
 
      RE_Image_Enumeration_8,             -- System.Img_Enum_New
      RE_Image_Enumeration_16,            -- System.Img_Enum_New
@@ -958,8 +990,6 @@ package Rtsfind is
 
      RE_Image_Integer,                   -- System.Img_Int
 
-     RE_Image_Long_Long_Decimal,         -- System.Img_LLD
-
      RE_Image_Long_Long_Integer,         -- System.Img_LLI
 
      RE_Image_Long_Long_Long_Integer,    -- System.Img_LLLI
@@ -968,6 +998,10 @@ package Rtsfind is
 
      RE_Image_Long_Long_Long_Unsigned,   -- System.Img_LLLU
 
+     RE_Image_Fixed32,                   -- System.Img_Fixed_32
+     RE_Image_Fixed64,                   -- System.Img_Fixed_64
+     RE_Image_Fixed128,                  -- System.Img_Fixed_128
+
      RE_Image_Ordinary_Fixed_Point,      -- System.Img_Real
      RE_Image_Floating_Point,            -- System.Img_Real
 
@@ -1991,15 +2025,23 @@ package Rtsfind is
 
      RE_Value_Character,                 -- System.Val_Char
 
-     RE_Value_Decimal,                   -- System.Val_Dec
+     RE_Value_Decimal32,                 -- System_Val_Decimal_32
+
+     RE_Value_Decimal64,                 -- System_Val_Decimal_64
+
+     RE_Value_Decimal128,                -- System_Val_Decimal_128
 
      RE_Value_Enumeration_8,             -- System.Val_Enum
      RE_Value_Enumeration_16,            -- System.Val_Enum
      RE_Value_Enumeration_32,            -- System.Val_Enum
 
-     RE_Value_Integer,                   -- System.Val_Int
+     RE_Value_Fixed32,                   -- System_Val_Fixed_32
+
+     RE_Value_Fixed64,                   -- System_Val_Fixed_64
 
-     RE_Value_Long_Long_Decimal,         -- System.Val_LLD
+     RE_Value_Fixed128,                  -- System_Val_Fixed_128
+
+     RE_Value_Integer,                   -- System.Val_Int
 
      RE_Value_Long_Long_Integer,         -- System.Val_LLI
 
@@ -2403,8 +2445,10 @@ package Rtsfind is
      RE_Subtract_With_Ovflo_Check64      => System_Arith_64,
 
      RE_Add_With_Ovflo_Check128          => System_Arith_128,
+     RE_Double_Divide128                 => System_Arith_128,
      RE_Multiply_With_Ovflo_Check128     => System_Arith_128,
      RE_Subtract_With_Ovflo_Check128     => System_Arith_128,
+     RE_Scaled_Divide128                 => System_Arith_128,
 
      RE_Create_AST_Handler               => System_AST_Handling,
 
@@ -2596,14 +2640,30 @@ package Rtsfind is
      RE_Root_Controlled                  => System_Finalization_Root,
      RE_Root_Controlled_Ptr              => System_Finalization_Root,
 
-     RE_Fore                             => System_Fore,
+     RE_Fore_Decimal32                   => System_Fore_Decimal_32,
+
+     RE_Fore_Decimal64                   => System_Fore_Decimal_64,
+
+     RE_Fore_Decimal128                  => System_Fore_Decimal_128,
+
+     RE_Fore_Fixed32                     => System_Fore_Fixed_32,
+
+     RE_Fore_Fixed64                     => System_Fore_Fixed_64,
+
+     RE_Fore_Fixed128                    => System_Fore_Fixed_128,
+
+     RE_Fore_Real                        => System_Fore_Real,
 
      RE_Image_Boolean                    => System_Img_Bool,
 
      RE_Image_Character                  => System_Img_Char,
      RE_Image_Character_05               => System_Img_Char,
 
-     RE_Image_Decimal                    => System_Img_Dec,
+     RE_Image_Decimal32                  => System_Img_Decimal_32,
+
+     RE_Image_Decimal64                  => System_Img_Decimal_64,
+
+     RE_Image_Decimal128                 => System_Img_Decimal_128,
 
      RE_Image_Enumeration_8              => System_Img_Enum_New,
      RE_Image_Enumeration_16             => System_Img_Enum_New,
@@ -2611,8 +2671,6 @@ package Rtsfind is
 
      RE_Image_Integer                    => System_Img_Int,
 
-     RE_Image_Long_Long_Decimal          => System_Img_LLD,
-
      RE_Image_Long_Long_Integer          => System_Img_LLI,
 
      RE_Image_Long_Long_Long_Integer     => System_Img_LLLI,
@@ -2621,6 +2679,10 @@ package Rtsfind is
 
      RE_Image_Long_Long_Long_Unsigned    => System_Img_LLLU,
 
+     RE_Image_Fixed32                    => System_Img_Fixed_32,
+     RE_Image_Fixed64                    => System_Img_Fixed_64,
+     RE_Image_Fixed128                   => System_Img_Fixed_128,
+
      RE_Image_Ordinary_Fixed_Point       => System_Img_Real,
      RE_Image_Floating_Point             => System_Img_Real,
 
@@ -3644,15 +3706,23 @@ package Rtsfind is
 
      RE_Value_Character                  => System_Val_Char,
 
-     RE_Value_Decimal                    => System_Val_Dec,
+     RE_Value_Decimal32                  => System_Val_Decimal_32,
+
+     RE_Value_Decimal64                  => System_Val_Decimal_64,
+
+     RE_Value_Decimal128                 => System_Val_Decimal_128,
 
      RE_Value_Enumeration_8              => System_Val_Enum,
      RE_Value_Enumeration_16             => System_Val_Enum,
      RE_Value_Enumeration_32             => System_Val_Enum,
 
-     RE_Value_Integer                    => System_Val_Int,
+     RE_Value_Fixed32                    => System_Val_Fixed_32,
+
+     RE_Value_Fixed64                    => System_Val_Fixed_64,
 
-     RE_Value_Long_Long_Decimal          => System_Val_LLD,
+     RE_Value_Fixed128                   => System_Val_Fixed_128,
+
+     RE_Value_Integer                    => System_Val_Int,
 
      RE_Value_Long_Long_Integer          => System_Val_LLI,
 
index 8085867dee6994c48a28b3e73d24dcf29800f8b6..f487f7345873c49d825fb2ed7bc666b306bf0bfa 100644 (file)
@@ -14945,6 +14945,10 @@ package body Sem_Ch3 is
       Loc           : constant Source_Ptr := Sloc (Def);
       Digs_Expr     : constant Node_Id    := Digits_Expression (Def);
       Delta_Expr    : constant Node_Id    := Delta_Expression (Def);
+      Max_Digits    : constant Nat        :=
+                        (if System_Max_Integer_Size = 128 then 38 else 18);
+      --  Maximum number of digits that can be represented in an integer
+
       Implicit_Base : Entity_Id;
       Digs_Val      : Uint;
       Delta_Val     : Ureal;
@@ -14982,9 +14986,10 @@ package body Sem_Ch3 is
                Scale_Val := Scale_Val + 1;
             end loop;
 
-            if Scale_Val > 18 then
-               Error_Msg_N ("scale exceeds maximum value of 18", Def);
-               Scale_Val := UI_From_Int (+18);
+            if Scale_Val > Max_Digits then
+               Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
+               Error_Msg_N ("scale exceeds maximum value of ^", Def);
+               Scale_Val := UI_From_Int (Max_Digits);
             end if;
 
          else
@@ -14993,9 +14998,10 @@ package body Sem_Ch3 is
                Scale_Val := Scale_Val - 1;
             end loop;
 
-            if Scale_Val < -18 then
-               Error_Msg_N ("scale is less than minimum value of -18", Def);
-               Scale_Val := UI_From_Int (-18);
+            if Scale_Val < -Max_Digits then
+               Error_Msg_Uint_1 := UI_From_Int (-Max_Digits);
+               Error_Msg_N ("scale is less than minimum value of ^", Def);
+               Scale_Val := UI_From_Int (-Max_Digits);
             end if;
          end if;
 
@@ -15017,9 +15023,10 @@ package body Sem_Ch3 is
       Check_Digits_Expression (Digs_Expr);
       Digs_Val := Expr_Value (Digs_Expr);
 
-      if Digs_Val > 18 then
-         Digs_Val := UI_From_Int (+18);
-         Error_Msg_N ("digits value out of range, maximum is 18", Digs_Expr);
+      if Digs_Val > Max_Digits then
+         Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
+         Error_Msg_N ("digits value out of range, maximum is ^", Digs_Expr);
+         Digs_Val := UI_From_Int (Max_Digits);
       end if;
 
       Set_Digits_Value (Implicit_Base, Digs_Val);
index 5742e51dea2248a14973dac14031dea8b55694fe..848239fafb0cbeb149b6cb63e053b042b4afd1f5 100644 (file)
@@ -451,10 +451,11 @@ package Stand is
    --  universal integer and universal real, it is never used for runtime
    --  calculations).
 
-   Standard_Integer_8  : Entity_Id;
-   Standard_Integer_16 : Entity_Id;
-   Standard_Integer_32 : Entity_Id;
-   Standard_Integer_64 : Entity_Id;
+   Standard_Integer_8   : Entity_Id;
+   Standard_Integer_16  : Entity_Id;
+   Standard_Integer_32  : Entity_Id;
+   Standard_Integer_64  : Entity_Id;
+   Standard_Integer_128 : Entity_Id;
    --  These are signed integer types with the indicated sizes. Used for the
    --  underlying implementation types for fixed-point and enumeration types.
 
index abae0cdda905b2e5dd8d8092dff11b29ba6e0e03..5f1f759a44eec58241d2efd31c36876b87bb2510 100644 (file)
@@ -63,6 +63,7 @@ package Uintp is
    Uint_15  : constant Uint;
    Uint_16  : constant Uint;
    Uint_24  : constant Uint;
+   Uint_31  : constant Uint;
    Uint_32  : constant Uint;
    Uint_63  : constant Uint;
    Uint_64  : constant Uint;
@@ -80,9 +81,13 @@ package Uintp is
    Uint_Minus_8   : constant Uint;
    Uint_Minus_9   : constant Uint;
    Uint_Minus_12  : constant Uint;
+   Uint_Minus_18  : constant Uint;
+   Uint_Minus_31  : constant Uint;
    Uint_Minus_36  : constant Uint;
    Uint_Minus_63  : constant Uint;
+   Uint_Minus_76  : constant Uint;
    Uint_Minus_80  : constant Uint;
+   Uint_Minus_127 : constant Uint;
    Uint_Minus_128 : constant Uint;
 
    type UI_Vector is array (Pos range <>) of Int;
@@ -470,6 +475,7 @@ private
    Uint_15  : constant Uint := Uint (Uint_Direct_Bias + 15);
    Uint_16  : constant Uint := Uint (Uint_Direct_Bias + 16);
    Uint_24  : constant Uint := Uint (Uint_Direct_Bias + 24);
+   Uint_31  : constant Uint := Uint (Uint_Direct_Bias + 31);
    Uint_32  : constant Uint := Uint (Uint_Direct_Bias + 32);
    Uint_63  : constant Uint := Uint (Uint_Direct_Bias + 63);
    Uint_64  : constant Uint := Uint (Uint_Direct_Bias + 64);
@@ -487,9 +493,13 @@ private
    Uint_Minus_8   : constant Uint := Uint (Uint_Direct_Bias - 8);
    Uint_Minus_9   : constant Uint := Uint (Uint_Direct_Bias - 9);
    Uint_Minus_12  : constant Uint := Uint (Uint_Direct_Bias - 12);
+   Uint_Minus_18  : constant Uint := Uint (Uint_Direct_Bias - 18);
+   Uint_Minus_31  : constant Uint := Uint (Uint_Direct_Bias - 31);
    Uint_Minus_36  : constant Uint := Uint (Uint_Direct_Bias - 36);
    Uint_Minus_63  : constant Uint := Uint (Uint_Direct_Bias - 63);
+   Uint_Minus_76  : constant Uint := Uint (Uint_Direct_Bias - 76);
    Uint_Minus_80  : constant Uint := Uint (Uint_Direct_Bias - 80);
+   Uint_Minus_127 : constant Uint := Uint (Uint_Direct_Bias - 127);
    Uint_Minus_128 : constant Uint := Uint (Uint_Direct_Bias - 128);
 
    Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2**15;
index f45f26133b9345d28b3169e974339be4237cc259..88cb6815e080f552f2f0158548a78e3df9a2d597 100644 (file)
@@ -73,20 +73,28 @@ package body Urealp is
    --  The following universal reals are the values returned by the constant
    --  functions. They are initialized by the initialization procedure.
 
-   UR_0       : Ureal;
-   UR_M_0     : Ureal;
-   UR_Tenth   : Ureal;
-   UR_Half    : Ureal;
-   UR_1       : Ureal;
-   UR_2       : Ureal;
-   UR_10      : Ureal;
-   UR_10_36   : Ureal;
-   UR_M_10_36 : Ureal;
-   UR_100     : Ureal;
-   UR_2_128   : Ureal;
-   UR_2_80    : Ureal;
-   UR_2_M_128 : Ureal;
-   UR_2_M_80  : Ureal;
+   UR_0         : Ureal;
+   UR_M_0       : Ureal;
+   UR_Tenth     : Ureal;
+   UR_Half      : Ureal;
+   UR_1         : Ureal;
+   UR_2         : Ureal;
+   UR_10        : Ureal;
+   UR_2_10_18   : Ureal;
+   UR_9_10_36   : Ureal;
+   UR_10_76     : Ureal;
+   UR_M_2_10_18 : Ureal;
+   UR_M_9_10_36 : Ureal;
+   UR_M_10_76   : Ureal;
+   UR_100       : Ureal;
+   UR_2_127     : Ureal;
+   UR_2_128     : Ureal;
+   UR_2_31      : Ureal;
+   UR_2_63      : Ureal;
+   UR_2_80      : Ureal;
+   UR_2_M_127   : Ureal;
+   UR_2_M_128   : Ureal;
+   UR_2_M_80    : Ureal;
 
    Normalized_Real : Ureal := No_Ureal;
    --  Used to memoize Norm_Num and Norm_Den, if either of these functions
@@ -288,20 +296,28 @@ package body Urealp is
    procedure Initialize is
    begin
       Ureals.Init;
-      UR_0       := UR_From_Components (Uint_0, Uint_1,         0, False);
-      UR_M_0     := UR_From_Components (Uint_0, Uint_1,         0, True);
-      UR_Half    := UR_From_Components (Uint_1, Uint_1,         2, False);
-      UR_Tenth   := UR_From_Components (Uint_1, Uint_1,        10, False);
-      UR_1       := UR_From_Components (Uint_1, Uint_1,         0, False);
-      UR_2       := UR_From_Components (Uint_1, Uint_Minus_1,   2, False);
-      UR_10      := UR_From_Components (Uint_1, Uint_Minus_1,  10, False);
-      UR_10_36   := UR_From_Components (Uint_1, Uint_Minus_36, 10, False);
-      UR_M_10_36 := UR_From_Components (Uint_1, Uint_Minus_36, 10, True);
-      UR_100     := UR_From_Components (Uint_1, Uint_Minus_2,  10, False);
-      UR_2_128   := UR_From_Components (Uint_1, Uint_Minus_128, 2, False);
-      UR_2_M_128 := UR_From_Components (Uint_1, Uint_128,       2, False);
-      UR_2_80    := UR_From_Components (Uint_1, Uint_Minus_80,  2, False);
-      UR_2_M_80  := UR_From_Components (Uint_1, Uint_80,        2, False);
+      UR_0         := UR_From_Components (Uint_0, Uint_1,         0, False);
+      UR_M_0       := UR_From_Components (Uint_0, Uint_1,         0, True);
+      UR_Half      := UR_From_Components (Uint_1, Uint_1,         2, False);
+      UR_Tenth     := UR_From_Components (Uint_1, Uint_1,        10, False);
+      UR_1         := UR_From_Components (Uint_1, Uint_1,         0, False);
+      UR_2         := UR_From_Components (Uint_1, Uint_Minus_1,   2, False);
+      UR_10        := UR_From_Components (Uint_1, Uint_Minus_1,  10, False);
+      UR_2_10_18   := UR_From_Components (Uint_2, Uint_Minus_18, 10, False);
+      UR_9_10_36   := UR_From_Components (Uint_9, Uint_Minus_36, 10, False);
+      UR_10_76     := UR_From_Components (Uint_1, Uint_Minus_76, 10, False);
+      UR_M_2_10_18 := UR_From_Components (Uint_2, Uint_Minus_18, 10, True);
+      UR_M_9_10_36 := UR_From_Components (Uint_9, Uint_Minus_36, 10, True);
+      UR_M_10_76   := UR_From_Components (Uint_1, Uint_Minus_76, 10, True);
+      UR_100       := UR_From_Components (Uint_1, Uint_Minus_2,  10, False);
+      UR_2_127     := UR_From_Components (Uint_1, Uint_Minus_127, 2, False);
+      UR_2_M_127   := UR_From_Components (Uint_1, Uint_127,       2, False);
+      UR_2_128     := UR_From_Components (Uint_1, Uint_Minus_128, 2, False);
+      UR_2_M_128   := UR_From_Components (Uint_1, Uint_128,       2, False);
+      UR_2_31      := UR_From_Components (Uint_1, Uint_Minus_31,  2, False);
+      UR_2_63      := UR_From_Components (Uint_1, Uint_Minus_63,  2, False);
+      UR_2_80      := UR_From_Components (Uint_1, Uint_Minus_80,  2, False);
+      UR_2_M_80    := UR_From_Components (Uint_1, Uint_80,        2, False);
    end Initialize;
 
    ----------------
@@ -1408,14 +1424,6 @@ package body Urealp is
             UI_Write (Int (UI_Image_Length - 1) - Val.Den, Decimal);
          end if;
 
-      --  Constants in a base other than 10 can still be easily written in
-      --  normal Ada literal style if the numerator is one.
-
-      elsif Val.Rbase /= 0 and then Val.Num = 1 then
-         Write_Int (Val.Rbase);
-         Write_Str ("#1.0#E");
-         UI_Write (-Val.Den);
-
       --  Other constants with a base other than 10 are written using one of
       --  the following forms, depending on the sign of the number and the
       --  sign of the exponent (= minus denominator value). See that we are
@@ -1525,14 +1533,50 @@ package body Urealp is
       return UR_100;
    end Ureal_100;
 
+   -------------------
+   -- Ureal_2_10_18 --
+   -------------------
+
+   function Ureal_2_10_18 return Ureal is
+   begin
+      return UR_2_10_18;
+   end Ureal_2_10_18;
+
+   -------------------
+   -- Ureal_9_10_36 --
+   -------------------
+
+   function Ureal_9_10_36 return Ureal is
+   begin
+      return UR_9_10_36;
+   end Ureal_9_10_36;
+
    -----------------
-   -- Ureal_10_36 --
+   -- Ureal_10_76 --
    -----------------
 
-   function Ureal_10_36 return Ureal is
+   function Ureal_10_76 return Ureal is
+   begin
+      return UR_10_76;
+   end Ureal_10_76;
+
+   ----------------
+   -- Ureal_2_31 --
+   ----------------
+
+   function Ureal_2_31 return Ureal is
+   begin
+      return UR_2_31;
+   end Ureal_2_31;
+
+   ----------------
+   -- Ureal_2_63 --
+   ----------------
+
+   function Ureal_2_63 return Ureal is
    begin
-      return UR_10_36;
-   end Ureal_10_36;
+      return UR_2_63;
+   end Ureal_2_63;
 
    ----------------
    -- Ureal_2_80 --
@@ -1543,6 +1587,15 @@ package body Urealp is
       return UR_2_80;
    end Ureal_2_80;
 
+   -----------------
+   -- Ureal_2_127 --
+   -----------------
+
+   function Ureal_2_127 return Ureal is
+   begin
+      return UR_2_127;
+   end Ureal_2_127;
+
    -----------------
    -- Ureal_2_128 --
    -----------------
@@ -1561,6 +1614,15 @@ package body Urealp is
       return UR_2_M_80;
    end Ureal_2_M_80;
 
+   -------------------
+   -- Ureal_2_M_127 --
+   -------------------
+
+   function Ureal_2_M_127 return Ureal is
+   begin
+      return UR_2_M_127;
+   end Ureal_2_M_127;
+
    -------------------
    -- Ureal_2_M_128 --
    -------------------
@@ -1588,14 +1650,32 @@ package body Urealp is
       return UR_M_0;
    end Ureal_M_0;
 
+   ---------------------
+   -- Ureal_M_2_10_18 --
+   ---------------------
+
+   function Ureal_M_2_10_18 return Ureal is
+   begin
+      return UR_M_2_10_18;
+   end Ureal_M_2_10_18;
+
+   ---------------------
+   -- Ureal_M_9_10_36 --
+   ---------------------
+
+   function Ureal_M_9_10_36 return Ureal is
+   begin
+      return UR_M_9_10_36;
+   end Ureal_M_9_10_36;
+
    -------------------
-   -- Ureal_M_10_36 --
+   -- Ureal_M_10_76 --
    -------------------
 
-   function Ureal_M_10_36 return Ureal is
+   function Ureal_M_10_76 return Ureal is
    begin
-      return UR_M_10_36;
-   end Ureal_M_10_36;
+      return UR_M_10_76;
+   end Ureal_M_10_76;
 
    -----------------
    -- Ureal_Tenth --
index 5c511efcd1a075b8f3e2fba40bd12433c2906b6f..3f747359ee71ffff8cc9f426e6360b2c34b28dd5 100644 (file)
@@ -106,23 +106,47 @@ package Urealp is
    function Ureal_100 return Ureal;
    --  Returns value 100.0
 
+   function Ureal_2_31 return Ureal;
+   --  Returns value 2.0 ** 31
+
+   function Ureal_2_63 return Ureal;
+   --  Returns value 2.0 ** 63
+
    function Ureal_2_80 return Ureal;
    --  Returns value 2.0 ** 80
 
    function Ureal_2_M_80 return Ureal;
    --  Returns value 2.0 ** (-80)
 
+   function Ureal_2_127 return Ureal;
+   --  Returns value 2.0 ** 127
+
+   function Ureal_2_M_127 return Ureal;
+   --  Returns value 2.0 ** (-127)
+
    function Ureal_2_128 return Ureal;
    --  Returns value 2.0 ** 128
 
    function Ureal_2_M_128 return Ureal;
    --  Returns value 2.0 ** (-128)
 
-   function Ureal_10_36 return Ureal;
-   --  Returns value 10.0 ** 36
+   function Ureal_2_10_18 return Ureal;
+   --  Returns value 2.0 * 10.0 ** 18
+
+   function Ureal_M_2_10_18 return Ureal;
+   --  Returns value -2.0 * 10.0 ** 18
+
+   function Ureal_9_10_36 return Ureal;
+   --  Returns value 9.0 * 10.0 ** 36
+
+   function Ureal_M_9_10_36 return Ureal;
+   --  Returns value -9.0 * 10.0 ** 36
+
+   function Ureal_10_76 return Ureal;
+   --  Returns value 10.0 ** 76
 
-   function Ureal_M_10_36 return Ureal;
-   --  Returns value -10.0 ** 36
+   function Ureal_M_10_76 return Ureal;
+   --  Returns value -10.0 ** 76
 
    -----------------
    -- Subprograms --
index 572cd32c748676c057868b425515004ae6526df7..6eeda8876b6c7e9209d2702d4c4ebd7ffee20eae 100644 (file)
@@ -1,6 +1,7 @@
 --  { dg-do run }
 
 with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
 
 procedure Multfixed is
    Z : constant := 4387648782261400837.0;
@@ -18,7 +19,7 @@ begin
    raise Program_Error;
 exception
    when Exc : Constraint_Error =>
-      if Exception_Message (Exc) /= "System.Arith_64.Impl.Raise_Error: Double arithmetic overflow" then
+      if Count (Exception_Message (Exc), "overflow") = 0 then
          raise Program_Error;
       end if;
 end Multfixed;