]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/doc/gccint/sizes-and-offsets-as-runtime-invariants/arithmetic-on-polyints.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gccint / sizes-and-offsets-as-runtime-invariants / arithmetic-on-polyints.rst
1 ..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6 Arithmetic on poly_ints
7 ***********************
8
9 Addition, subtraction, negation and bit inversion all work normally for
10 ``poly_int`` s. Multiplication by a constant multiplier and left
11 shifting by a constant shift amount also work normally. General
12 multiplication of two ``poly_int`` s is not supported and is not
13 useful in practice.
14
15 Other operations are only conditionally supported: the operation
16 might succeed or might fail, depending on the inputs.
17
18 This section describes both types of operation.
19
20 .. toctree::
21 :maxdepth: 2
22
23
24 Using poly_int with C++ arithmetic operators
25 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26
27 The following C++ expressions are supported, where :samp:`{p1}` and :samp:`{p2}`
28 are ``poly_int`` s and where :samp:`{c1}` and :samp:`{c2}` are scalars:
29
30 .. code-block:: c++
31
32 -p1
33 ~p1
34
35 p1 + p2
36 p1 + c2
37 c1 + p2
38
39 p1 - p2
40 p1 - c2
41 c1 - p2
42
43 c1 * p2
44 p1 * c2
45
46 p1 << c2
47
48 p1 += p2
49 p1 += c2
50
51 p1 -= p2
52 p1 -= c2
53
54 p1 *= c2
55 p1 <<= c2
56
57 These arithmetic operations handle integer ranks in a similar way
58 to C++. The main difference is that every coefficient narrower than
59 ``HOST_WIDE_INT`` promotes to ``HOST_WIDE_INT``, whereas in
60 C++ everything narrower than ``int`` promotes to ``int``.
61 For example:
62
63 .. code-block:: c++
64
65 poly_uint16 + int -> poly_int64
66 unsigned int + poly_uint16 -> poly_int64
67 poly_int64 + int -> poly_int64
68 poly_int32 + poly_uint64 -> poly_uint64
69 uint64 + poly_int64 -> poly_uint64
70 poly_offset_int + int32 -> poly_offset_int
71 offset_int + poly_uint16 -> poly_offset_int
72
73 In the first two examples, both coefficients are narrower than
74 ``HOST_WIDE_INT``, so the result has coefficients of type
75 ``HOST_WIDE_INT``. In the other examples, the coefficient
76 with the highest rank 'wins'.
77
78 If one of the operands is ``wide_int`` or ``poly_wide_int``,
79 the rules are the same as for ``wide_int`` arithmetic.
80
81 wi arithmetic on poly_ints
82 ^^^^^^^^^^^^^^^^^^^^^^^^^^
83
84 As well as the C++ operators, ``poly_int`` supports the following
85 ``wi`` routines:
86
87 .. code-block:: c++
88
89 wi::neg (p1, &overflow)
90
91 wi::add (p1, p2)
92 wi::add (p1, c2)
93 wi::add (c1, p1)
94 wi::add (p1, p2, sign, &overflow)
95
96 wi::sub (p1, p2)
97 wi::sub (p1, c2)
98 wi::sub (c1, p1)
99 wi::sub (p1, p2, sign, &overflow)
100
101 wi::mul (p1, c2)
102 wi::mul (c1, p1)
103 wi::mul (p1, c2, sign, &overflow)
104
105 wi::lshift (p1, c2)
106
107 These routines just check whether overflow occurs on any individual
108 coefficient; it is not possible to know at compile time whether the
109 final runtime value would overflow.
110
111 Division of poly_ints
112 ^^^^^^^^^^^^^^^^^^^^^
113
114 Division of ``poly_int`` s is possible for certain inputs. The functions
115 for division return true if the operation is possible and in most cases
116 return the results by pointer. The routines are:
117
118 :samp:`multiple_p ({a}, {b})` :samp:`multiple_p ({a}, {b}, &{quotient})`
119 Return true if :samp:`{a}` is an exact multiple of :samp:`{b}`, storing the result
120 in :samp:`{quotient}` if so. There are overloads for various combinations
121 of polynomial and constant :samp:`{a}`, :samp:`{b}` and :samp:`{quotient}`.
122
123 :samp:`constant_multiple_p ({a}, {b})` :samp:`constant_multiple_p ({a}, {b}, &{quotient})`
124 Like ``multiple_p``, but also test whether the multiple is a
125 compile-time constant.
126
127 :samp:`can_div_trunc_p ({a}, {b}, &{quotient})` :samp:`can_div_trunc_p ({a}, {b}, &{quotient}, &{remainder})`
128 Return true if we can calculate :samp:`trunc ({a} / {b})` at compile
129 time, storing the result in :samp:`{quotient}` and :samp:`{remainder}` if so.
130
131 :samp:`can_div_away_from_zero_p ({a}, {b}, &{quotient})`
132 Return true if we can calculate :samp:`{a} / {b}` at compile time,
133 rounding away from zero. Store the result in :samp:`{quotient}` if so.
134
135 Note that this is true if and only if ``can_div_trunc_p`` is true.
136 The only difference is in the rounding of the result.
137
138 There is also an asserting form of division:
139
140 :samp:`exact_div ({a}, {b})`
141 Assert that :samp:`{a}` is a multiple of :samp:`{b}` and return
142 :samp:`{a} / {b}`. The result is a ``poly_int`` if :samp:`{a}`
143 is a ``poly_int``.
144
145 Other poly_int arithmetic
146 ^^^^^^^^^^^^^^^^^^^^^^^^^
147
148 There are tentative routines for other operations besides division:
149
150 :samp:`can_ior_p ({a}, {b}, &{result})`
151 Return true if we can calculate :samp:`{a} | {b}` at compile time,
152 storing the result in :samp:`{result}` if so.
153
154 Also, ANDs with a value :samp:`(1 << {y}) - 1` or its inverse can be
155 treated as alignment operations. See :ref:`alignment-of-poly_ints`.
156
157 In addition, the following miscellaneous routines are available:
158
159 :samp:`coeff_gcd ({a})`
160 Return the greatest common divisor of all nonzero coefficients in
161 :samp:`{a}`, or zero if :samp:`{a}` is known to be zero.
162
163 :samp:`common_multiple ({a}, {b})`
164 Return a value that is a multiple of both :samp:`{a}` and :samp:`{b}`, where
165 one value is a ``poly_int`` and the other is a scalar. The result
166 will be the least common multiple for some indeterminate values but
167 not necessarily for all.
168
169 :samp:`force_common_multiple ({a}, {b})`
170 Return a value that is a multiple of both ``poly_int`` :samp:`{a}` and
171 ``poly_int`` :samp:`{b}`, asserting that such a value exists. The
172 result will be the least common multiple for some indeterminate values
173 but not necessarily for all.
174
175 When using this routine, please add a comment explaining why the
176 assertion is known to hold.
177
178 Please add any other operations that you find to be useful.