Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / ada / libgnat / s-aridou.ads
blobb22f0db4248d077b25eb363b533d0da90f4d959a
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . A R I T H _ D O U B L E --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 1992-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 package provides software routines for doing arithmetic on "double"
33 -- signed integer values in cases where either overflow checking is required,
34 -- or intermediate results are longer than the result type.
36 with Ada.Numerics.Big_Numbers.Big_Integers_Ghost;
38 generic
40 type Double_Int is range <>;
42 type Double_Uns is mod <>;
44 type Single_Uns is mod <>;
46 with function Shift_Left (A : Double_Uns; B : Natural) return Double_Uns
47 is <>;
49 with function Shift_Right (A : Double_Uns; B : Natural) return Double_Uns
50 is <>;
52 with function Shift_Left (A : Single_Uns; B : Natural) return Single_Uns
53 is <>;
55 package System.Arith_Double
56 with Pure, SPARK_Mode
58 -- Preconditions in this unit are meant for analysis only, not for run-time
59 -- checking, so that the expected exceptions are raised. This is enforced
60 -- by setting the corresponding assertion policy to Ignore. Postconditions
61 -- and contract cases should not be executed at runtime as well, in order
62 -- not to slow down the execution of these functions.
64 pragma Assertion_Policy (Pre => Ignore,
65 Post => Ignore,
66 Contract_Cases => Ignore,
67 Ghost => Ignore);
69 package BI_Ghost renames Ada.Numerics.Big_Numbers.Big_Integers_Ghost;
70 subtype Big_Integer is BI_Ghost.Big_Integer with Ghost;
71 subtype Big_Natural is BI_Ghost.Big_Natural with Ghost;
72 subtype Big_Positive is BI_Ghost.Big_Positive with Ghost;
73 use type BI_Ghost.Big_Integer;
75 package Signed_Conversion is
76 new BI_Ghost.Signed_Conversions (Int => Double_Int);
78 function Big (Arg : Double_Int) return Big_Integer is
79 (Signed_Conversion.To_Big_Integer (Arg))
80 with
81 Ghost,
82 Annotate => (GNATprove, Inline_For_Proof);
84 package Unsigned_Conversion is
85 new BI_Ghost.Unsigned_Conversions (Int => Double_Uns);
87 function Big (Arg : Double_Uns) return Big_Integer is
88 (Unsigned_Conversion.To_Big_Integer (Arg))
89 with
90 Ghost,
91 Annotate => (GNATprove, Inline_For_Proof);
93 function In_Double_Int_Range (Arg : Big_Integer) return Boolean is
94 (BI_Ghost.In_Range (Arg, Big (Double_Int'First), Big (Double_Int'Last)))
95 with
96 Ghost,
97 Annotate => (GNATprove, Inline_For_Proof);
99 function Add_With_Ovflo_Check (X, Y : Double_Int) return Double_Int
100 with
101 Pre => In_Double_Int_Range (Big (X) + Big (Y)),
102 Post => Add_With_Ovflo_Check'Result = X + Y;
103 -- Raises Constraint_Error if sum of operands overflows Double_Int,
104 -- otherwise returns the signed integer sum.
106 function Subtract_With_Ovflo_Check (X, Y : Double_Int) return Double_Int
107 with
108 Pre => In_Double_Int_Range (Big (X) - Big (Y)),
109 Post => Subtract_With_Ovflo_Check'Result = X - Y;
110 -- Raises Constraint_Error if difference of operands overflows Double_Int,
111 -- otherwise returns the signed integer difference.
113 function Multiply_With_Ovflo_Check (X, Y : Double_Int) return Double_Int
114 with
115 Pre => In_Double_Int_Range (Big (X) * Big (Y)),
116 Post => Multiply_With_Ovflo_Check'Result = X * Y;
117 pragma Convention (C, Multiply_With_Ovflo_Check);
118 -- Raises Constraint_Error if product of operands overflows Double_Int,
119 -- otherwise returns the signed integer product. Gigi may also call this
120 -- routine directly.
122 function Same_Sign (X, Y : Big_Integer) return Boolean is
123 (X = Big (Double_Int'(0))
124 or else Y = Big (Double_Int'(0))
125 or else (X < Big (Double_Int'(0))) = (Y < Big (Double_Int'(0))))
126 with Ghost;
128 function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer is
129 (if abs R > (abs Y - Big (Double_Int'(1))) / Big (Double_Int'(2)) then
130 (if Same_Sign (X, Y) then Q + Big (Double_Int'(1))
131 else Q - Big (Double_Int'(1)))
132 else
134 with
135 Ghost,
136 Pre => Y /= 0 and then Q = X / Y and then R = X rem Y;
138 procedure Scaled_Divide
139 (X, Y, Z : Double_Int;
140 Q, R : out Double_Int;
141 Round : Boolean)
142 with
143 Pre => Z /= 0
144 and then In_Double_Int_Range
145 (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z),
146 Big (X) * Big (Y) / Big (Z),
147 Big (X) * Big (Y) rem Big (Z))
148 else Big (X) * Big (Y) / Big (Z)),
149 Post => Big (R) = Big (X) * Big (Y) rem Big (Z)
150 and then
151 (if Round then
152 Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z),
153 Big (X) * Big (Y) / Big (Z), Big (R))
154 else
155 Big (Q) = Big (X) * Big (Y) / Big (Z));
156 -- Performs the division of (X * Y) / Z, storing the quotient in Q
157 -- and the remainder in R. Constraint_Error is raised if Z is zero,
158 -- or if the quotient does not fit in Double_Int. Round indicates if
159 -- the result should be rounded. If Round is False, then Q, R are
160 -- the normal quotient and remainder from a truncating division.
161 -- If Round is True, then Q is the rounded quotient. The remainder
162 -- R is not affected by the setting of the Round flag.
164 procedure Double_Divide
165 (X, Y, Z : Double_Int;
166 Q, R : out Double_Int;
167 Round : Boolean)
168 with
169 Pre => Y /= 0
170 and then Z /= 0
171 and then In_Double_Int_Range
172 (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z),
173 Big (X) / (Big (Y) * Big (Z)),
174 Big (X) rem (Big (Y) * Big (Z)))
175 else Big (X) / (Big (Y) * Big (Z))),
176 Post => Big (R) = Big (X) rem (Big (Y) * Big (Z))
177 and then
178 (if Round then
179 Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z),
180 Big (X) / (Big (Y) * Big (Z)), Big (R))
181 else
182 Big (Q) = Big (X) / (Big (Y) * Big (Z)));
183 -- Performs the division X / (Y * Z), storing the quotient in Q and
184 -- the remainder in R. Constraint_Error is raised if Y or Z is zero,
185 -- or if the quotient does not fit in Double_Int. Round indicates if the
186 -- result should be rounded. If Round is False, then Q, R are the normal
187 -- quotient and remainder from a truncating division. If Round is True,
188 -- then Q is the rounded quotient. The remainder R is not affected by the
189 -- setting of the Round flag.
191 end System.Arith_Double;