Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / ada / libgnat / s-arit64.ads
blob88c8a661a8504a483f764eac9701b825231b0507
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . A R I T H _ 6 4 --
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 unit provides software routines for doing arithmetic on 64-bit
33 -- signed integer values in cases where either overflow checking is
34 -- required, or intermediate results are longer than 64 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_64
54 with Pure, SPARK_Mode
56 use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer;
57 use type Interfaces.Integer_64;
59 subtype Int64 is Interfaces.Integer_64;
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 => Int64);
69 function Big (Arg : Int64) return Big_Integer is
70 (Signed_Conversion.To_Big_Integer (Arg))
71 with Ghost;
73 function In_Int64_Range (Arg : Big_Integer) return Boolean is
74 (Ada.Numerics.Big_Numbers.Big_Integers_Ghost.In_Range
75 (Arg, Big (Int64'First), Big (Int64'Last)))
76 with Ghost;
78 function Add_With_Ovflo_Check64 (X, Y : Int64) return Int64
79 with
80 Pre => In_Int64_Range (Big (X) + Big (Y)),
81 Post => Add_With_Ovflo_Check64'Result = X + Y;
82 -- Raises Constraint_Error if sum of operands overflows 64 bits,
83 -- otherwise returns the 64-bit signed integer sum.
85 function Subtract_With_Ovflo_Check64 (X, Y : Int64) return Int64
86 with
87 Pre => In_Int64_Range (Big (X) - Big (Y)),
88 Post => Subtract_With_Ovflo_Check64'Result = X - Y;
89 -- Raises Constraint_Error if difference of operands overflows 64
90 -- bits, otherwise returns the 64-bit signed integer difference.
92 function Multiply_With_Ovflo_Check64 (X, Y : Int64) return Int64
93 with
94 Pre => In_Int64_Range (Big (X) * Big (Y)),
95 Post => Multiply_With_Ovflo_Check64'Result = X * Y;
96 pragma Export (C, Multiply_With_Ovflo_Check64, "__gnat_mulv64");
97 -- Raises Constraint_Error if product of operands overflows 64
98 -- bits, otherwise returns the 64-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 (Int64'(0))
103 or else Y = Big (Int64'(0))
104 or else (X < Big (Int64'(0))) = (Y < Big (Int64'(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 (Int64'(1))) / Big (Int64'(2)) then
109 (if Same_Sign (X, Y) then Q + Big (Int64'(1))
110 else Q - Big (Int64'(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_Divide64
118 (X, Y, Z : Int64;
119 Q, R : out Int64;
120 Round : Boolean)
121 with
122 Pre => Z /= 0
123 and then In_Int64_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 64 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 Scaled_Divide
144 (X, Y, Z : Int64;
145 Q, R : out Int64;
146 Round : Boolean) renames Scaled_Divide64;
147 -- Renamed procedure to preserve compatibility with earlier versions
149 procedure Double_Divide64
150 (X, Y, Z : Int64;
151 Q, R : out Int64;
152 Round : Boolean)
153 with
154 Pre => Y /= 0
155 and then Z /= 0
156 and then In_Int64_Range
157 (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z),
158 Big (X) / (Big (Y) * Big (Z)),
159 Big (X) rem (Big (Y) * Big (Z)))
160 else Big (X) / (Big (Y) * Big (Z))),
161 Post => Big (R) = Big (X) rem (Big (Y) * Big (Z))
162 and then
163 (if Round then
164 Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z),
165 Big (X) / (Big (Y) * Big (Z)), Big (R))
166 else
167 Big (Q) = Big (X) / (Big (Y) * Big (Z)));
168 -- Performs the division X / (Y * Z), storing the quotient in Q and
169 -- the remainder in R. Constraint_Error is raised if Y or Z is zero,
170 -- or if the quotient does not fit in 64 bits. Round indicates if the
171 -- result should be rounded. If Round is False, then Q, R are the normal
172 -- quotient and remainder from a truncating division. If Round is True,
173 -- then Q is the rounded quotient. The remainder R is not affected by the
174 -- setting of the Round flag.
176 procedure Double_Divide
177 (X, Y, Z : Int64;
178 Q, R : out Int64;
179 Round : Boolean) renames Double_Divide64;
180 -- Renamed procedure to preserve compatibility with earlier versions
182 end System.Arith_64;