Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / ada / libgnat / s-arit128.ads
blob3389e3f6d1d3ba630a01977ce113663bba35437c
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . A R I T H _ 1 2 8 --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2020-2023, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
32 -- This unit provides software routines for doing arithmetic on 128-bit
33 -- signed integer values in cases where either overflow checking is
34 -- required, or intermediate results are longer than 128 bits.
36 pragma Restrictions (No_Elaboration_Code);
37 -- Allow direct call from gigi generated code
39 -- Preconditions in this unit are meant for analysis only, not for run-time
40 -- checking, so that the expected exceptions are raised. This is enforced
41 -- by setting the corresponding assertion policy to Ignore. Postconditions
42 -- and contract cases should not be executed at runtime as well, in order
43 -- not to slow down the execution of these functions.
45 pragma Assertion_Policy (Pre => Ignore,
46 Post => Ignore,
47 Contract_Cases => Ignore,
48 Ghost => Ignore);
50 with Ada.Numerics.Big_Numbers.Big_Integers_Ghost;
51 with Interfaces;
53 package System.Arith_128
54 with Pure, SPARK_Mode
56 use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer;
57 use type Interfaces.Integer_128;
59 subtype Int128 is Interfaces.Integer_128;
61 subtype Big_Integer is
62 Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer
63 with Ghost;
65 package Signed_Conversion is new
66 Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Signed_Conversions
67 (Int => Int128);
69 function Big (Arg : Int128) return Big_Integer is
70 (Signed_Conversion.To_Big_Integer (Arg))
71 with Ghost;
73 function In_Int128_Range (Arg : Big_Integer) return Boolean is
74 (Ada.Numerics.Big_Numbers.Big_Integers_Ghost.In_Range
75 (Arg, Big (Int128'First), Big (Int128'Last)))
76 with Ghost;
78 function Add_With_Ovflo_Check128 (X, Y : Int128) return Int128
79 with
80 Pre => In_Int128_Range (Big (X) + Big (Y)),
81 Post => Add_With_Ovflo_Check128'Result = X + Y;
82 -- Raises Constraint_Error if sum of operands overflows 128 bits,
83 -- otherwise returns the 128-bit signed integer sum.
85 function Subtract_With_Ovflo_Check128 (X, Y : Int128) return Int128
86 with
87 Pre => In_Int128_Range (Big (X) - Big (Y)),
88 Post => Subtract_With_Ovflo_Check128'Result = X - Y;
89 -- Raises Constraint_Error if difference of operands overflows 128
90 -- bits, otherwise returns the 128-bit signed integer difference.
92 function Multiply_With_Ovflo_Check128 (X, Y : Int128) return Int128
93 with
94 Pre => In_Int128_Range (Big (X) * Big (Y)),
95 Post => Multiply_With_Ovflo_Check128'Result = X * Y;
96 pragma Export (C, Multiply_With_Ovflo_Check128, "__gnat_mulv128");
97 -- Raises Constraint_Error if product of operands overflows 128
98 -- bits, otherwise returns the 128-bit signed integer product.
99 -- Gigi may also call this routine directly.
101 function Same_Sign (X, Y : Big_Integer) return Boolean is
102 (X = Big (Int128'(0))
103 or else Y = Big (Int128'(0))
104 or else (X < Big (Int128'(0))) = (Y < Big (Int128'(0))))
105 with Ghost;
107 function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer is
108 (if abs R > (abs Y - Big (Int128'(1))) / Big (Int128'(2)) then
109 (if Same_Sign (X, Y) then Q + Big (Int128'(1))
110 else Q - Big (Int128'(1)))
111 else
113 with
114 Ghost,
115 Pre => Y /= 0 and then Q = X / Y and then R = X rem Y;
117 procedure Scaled_Divide128
118 (X, Y, Z : Int128;
119 Q, R : out Int128;
120 Round : Boolean)
121 with
122 Pre => Z /= 0
123 and then In_Int128_Range
124 (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z),
125 Big (X) * Big (Y) / Big (Z),
126 Big (X) * Big (Y) rem Big (Z))
127 else Big (X) * Big (Y) / Big (Z)),
128 Post => Big (R) = Big (X) * Big (Y) rem Big (Z)
129 and then
130 (if Round then
131 Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z),
132 Big (X) * Big (Y) / Big (Z), Big (R))
133 else
134 Big (Q) = Big (X) * Big (Y) / Big (Z));
135 -- Performs the division of (X * Y) / Z, storing the quotient in Q
136 -- and the remainder in R. Constraint_Error is raised if Z is zero,
137 -- or if the quotient does not fit in 128 bits. Round indicates if
138 -- the result should be rounded. If Round is False, then Q, R are
139 -- the normal quotient and remainder from a truncating division.
140 -- If Round is True, then Q is the rounded quotient. The remainder
141 -- R is not affected by the setting of the Round flag.
143 procedure Double_Divide128
144 (X, Y, Z : Int128;
145 Q, R : out Int128;
146 Round : Boolean)
147 with
148 Pre => Y /= 0
149 and then Z /= 0
150 and then In_Int128_Range
151 (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z),
152 Big (X) / (Big (Y) * Big (Z)),
153 Big (X) rem (Big (Y) * Big (Z)))
154 else Big (X) / (Big (Y) * Big (Z))),
155 Post => Big (R) = Big (X) rem (Big (Y) * Big (Z))
156 and then
157 (if Round then
158 Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z),
159 Big (X) / (Big (Y) * Big (Z)), Big (R))
160 else
161 Big (Q) = Big (X) / (Big (Y) * Big (Z)));
162 -- Performs the division X / (Y * Z), storing the quotient in Q and
163 -- the remainder in R. Constraint_Error is raised if Y or Z is zero,
164 -- or if the quotient does not fit in 128 bits. Round indicates if the
165 -- result should be rounded. If Round is False, then Q, R are the normal
166 -- quotient and remainder from a truncating division. If Round is True,
167 -- then Q is the rounded quotient. The remainder R is not affected by the
168 -- setting of the Round flag.
170 end System.Arith_128;