From 62ebfa527237ba42c9d93032dc008e82d482d271 Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Tue, 11 Dec 2018 11:11:06 +0000 Subject: [PATCH] [Ada] Uintp: add a new UI_From_Integral generic constructor 2018-12-11 Ed Schonberg gcc/ada/ * uintp.ads, uintp.adb (UI_From_Integral): New generic function, to simplify construction of Universal_Integer representations from any Integer type. If type is small enough the code is equivalent to a call to UI_To_Int with appropriate conversions; otherwise the routine uses the existing mechanism of building a vector of suitable integer values and calling Vector_To_Uint. The routine must not be applied to a biased type. From-SVN: r267000 --- gcc/ada/ChangeLog | 10 ++++++++++ gcc/ada/uintp.adb | 46 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/ada/uintp.ads | 7 +++++++ 3 files changed, 63 insertions(+) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 76c6e761e00..c2fef9cbc85 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,13 @@ +2018-12-11 Ed Schonberg + + * uintp.ads, uintp.adb (UI_From_Integral): New generic function, + to simplify construction of Universal_Integer representations + from any Integer type. If type is small enough the code is + equivalent to a call to UI_To_Int with appropriate conversions; + otherwise the routine uses the existing mechanism of building a + vector of suitable integer values and calling Vector_To_Uint. + The routine must not be applied to a biased type. + 2018-12-11 Ed Schonberg * sem_ch3.adb (Build_Itype_Reference): Handle properly an itype diff --git a/gcc/ada/uintp.adb b/gcc/ada/uintp.adb index 28fe22fdf91..04f552e5d96 100644 --- a/gcc/ada/uintp.adb +++ b/gcc/ada/uintp.adb @@ -2324,4 +2324,50 @@ package body Uintp is return Uint_0; end Vector_To_Uint; + ---------------------- + -- UI_From_Integral -- + ---------------------- + + function UI_From_Integral (Input : In_T) return Uint is + U : Uint; + + begin + -- If in range of our normal conversion function, use it so we can + -- use direct access and our cache. + + if In_T'Size <= Int'Size + or else Input in In_T (Int'First) .. In_T (Int'Last) + then + return UI_From_Int (Int (Input)); + + else + -- pragma Warnings (Off); + + -- For values of larger magnitude, compute digits into a vector + -- and call Vector_To_Uint. + + declare + Max_For_In_T : constant Int := 3 * In_T'Size / Int'Size; + Our_Base : constant In_T := In_T (Base); + Temp_Integer : In_T := Input; + -- Base is defined so that 3 Uint digits is sufficient to hold the + -- largest possible Int value. + + V : UI_Vector (1 .. Max_For_In_T); + + begin + for J in reverse V'Range loop + V (J) := Int (abs (Temp_Integer rem Our_Base)); + Temp_Integer := Temp_Integer / Our_Base; + end loop; + + U := Vector_To_Uint (V, Input < 0); + Uints_Min := Uints.Last; + Udigits_Min := Udigits.Last; + return U; + end; + + -- pragma Warnings (On); + end if; + end UI_From_Integral; end Uintp; diff --git a/gcc/ada/uintp.ads b/gcc/ada/uintp.ads index 5e8321325bc..d00d0e19f8f 100644 --- a/gcc/ada/uintp.ads +++ b/gcc/ada/uintp.ads @@ -248,6 +248,13 @@ package Uintp is function UI_From_Int (Input : Int) return Uint; -- Converts Int value to universal integer form + generic + type In_T is range <>; + function UI_From_Integral (Input : In_T) return Uint; + -- Likewise, but converts from any integer type. + -- Must not be applied to biased types (instantiation will provide + -- a warning if actual is a biased type). + function UI_From_CC (Input : Char_Code) return Uint; -- Converts Char_Code value to universal integer form