gem5 v24.0.0.0
Loading...
Searching...
No Matches
intmath.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2001, 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#ifndef __BASE_INTMATH_HH__
42#define __BASE_INTMATH_HH__
43
44#include <cassert>
45#include <cstdint>
46#include <type_traits>
47#include <utility>
48
49#include "base/bitfield.hh"
50
51namespace gem5
52{
53
57template <class T>
58static constexpr std::enable_if_t<std::is_integral_v<T>, int>
60{
61 assert(x > 0);
62
63 // A guaranteed unsigned version of x.
64 uint64_t ux = (typename std::make_unsigned<T>::type)x;
65
66 int y = 0;
67 constexpr auto ts = sizeof(T);
68
69 if (ts >= 8 && (ux & 0xffffffff00000000ULL)) { y += 32; ux >>= 32; }
70 if (ts >= 4 && (ux & 0x00000000ffff0000ULL)) { y += 16; ux >>= 16; }
71 if (ts >= 2 && (ux & 0x000000000000ff00ULL)) { y += 8; ux >>= 8; }
72 if (ux & 0x00000000000000f0ULL) { y += 4; ux >>= 4; }
73 if (ux & 0x000000000000000cULL) { y += 2; ux >>= 2; }
74 if (ux & 0x0000000000000002ULL) { y += 1; }
75
76 return y;
77}
78
82template <class T>
83static constexpr int
84ceilLog2(const T& n)
85{
86 assert(n > 0);
87 if (n == 1)
88 return 0;
89
90 return floorLog2(n - (T)1) + 1;
91}
92
96template <class T>
97static constexpr bool
98isPowerOf2(const T& n)
99{
100 // If n is non-zero, and subtracting one borrows all the way to the MSB
101 // and flips all bits, then this is a power of 2.
102 return n && !(n & (n - 1));
103}
104
108template <class T, class U>
109static constexpr T
110divCeil(const T& a, const U& b)
111{
112 return (a + b - 1) / b;
113}
114
118template <typename T>
119static constexpr std::enable_if_t<sizeof(T) <= sizeof(uint32_t)>
120mulUnsigned(std::make_unsigned_t<T> &high, std::make_unsigned_t<T> &low,
121 std::make_unsigned_t<T> val_a, std::make_unsigned_t<T> val_b)
122{
123 uint64_t product = (uint64_t)val_a * (uint64_t)val_b;
124 low = product;
125 high = (product >> (sizeof(low) * 8));
126};
127
131template <typename T>
132static constexpr std::enable_if_t<sizeof(T) <= sizeof(uint32_t)>
133mulSigned(std::make_signed_t<T> &high, std::make_signed_t<T> &low,
134 std::make_signed_t<T> val_a, std::make_signed_t<T> val_b)
135{
136 uint64_t product = (int64_t)val_a * (int64_t)val_b;
137 low = product;
138 high = (product >> (sizeof(low) * 8));
139};
140
154template <typename T>
155static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
156mulUnsignedManual(std::make_unsigned_t<T> &high, std::make_unsigned_t<T> &low,
157 std::make_unsigned_t<T> val_a, std::make_unsigned_t<T> val_b)
158{
159 low = val_a * val_b;
160
161 uint64_t A = (uint32_t)(val_a >> 32);
162 uint64_t a = (uint32_t)val_a;
163 uint64_t B = (uint32_t)(val_b >> 32);
164 uint64_t b = (uint32_t)val_b;
165
166 uint64_t c1 = 0, c2 = 0; // Carry between place values.
167 uint64_t ab = a * b, Ab = A * b, aB = a * B, AB = A * B;
168
169 c1 = (uint32_t)(ab >> 32);
170
171 // Be careful to avoid overflow.
172 c2 = (c1 >> 1) + (Ab >> 1) + (aB >> 1);
173 c2 += ((c1 & 0x1) + (Ab & 0x1) + (aB & 0x1)) >> 1;
174 c2 >>= 31;
175
176 high = AB + c2;
177}
178
182template <typename T>
183static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
184mulUnsigned(std::make_unsigned_t<T> &high, std::make_unsigned_t<T> &low,
185 std::make_unsigned_t<T> val_a, std::make_unsigned_t<T> val_b)
186{
187#ifdef __SIZEOF_INT128__
188 __uint128_t val = (__uint128_t)val_a * (__uint128_t)val_b;
189 low = val;
190 high = (val >> 64);
191#else
192 mulUnsignedManual<T>(high, low, val_a, val_b);
193#endif
194}
195
196template <typename T>
197static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
198mulSignedManual(std::make_signed_t<T> &high, std::make_signed_t<T> &low,
199 std::make_signed_t<T> val_a, std::make_signed_t<T> val_b)
200{
201 uint64_t u_high = 0, u_low = 0;
202 mulUnsigned<T>(u_high, u_low, val_a, val_b);
203
204 if (val_a < 0)
205 u_high -= val_b;
206 if (val_b < 0)
207 u_high -= val_a;
208
209 high = u_high;
210 low = u_low;
211}
212
216template <typename T>
217static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
218mulSigned(std::make_signed_t<T> &high, std::make_signed_t<T> &low,
219 std::make_signed_t<T> val_a, std::make_signed_t<T> val_b)
220{
221#ifdef __SIZEOF_INT128__
222 __int128_t val = (__int128_t)val_a * (__int128_t)val_b;
223 low = val;
224 high = (val >> 64);
225#else
226 mulSignedManual<T>(high, low, val_a, val_b);
227#endif
228}
229
230template <typename T>
231static constexpr std::pair<std::make_unsigned_t<T>, std::make_unsigned_t<T>>
232mulUnsigned(std::make_unsigned_t<T> val_a, std::make_unsigned_t<T> val_b)
233{
234 std::make_unsigned_t<T> hi{}, low{};
235 mulUnsigned<T>(hi, low, val_a, val_b);
236 return {hi, low};
237};
238
239template <typename T>
240static constexpr std::pair<std::make_signed_t<T>, std::make_signed_t<T>>
241mulSigned(std::make_signed_t<T> val_a, std::make_signed_t<T> val_b)
242{
243 std::make_signed_t<T> hi{}, low{};
244 mulSigned<T>(hi, low, val_a, val_b);
245 return {hi, low};
246};
247
258template <class T, class U>
259static constexpr T
260roundUp(const T& val, const U& align)
261{
262 assert(isPowerOf2(align));
263 T mask = (T)align - 1;
264 return (val + mask) & ~mask;
265}
266
277template <class T, class U>
278static constexpr T
279roundDown(const T& val, const U& align)
280{
281 assert(isPowerOf2(align));
282 T mask = (T)align - 1;
283 return val & ~mask;
284}
285
294static constexpr int
295log2i(int value)
296{
297 assert(isPowerOf2(value) && value > 0);
298 return ctz32(value);
299}
300
301} // namespace gem5
302
303#endif // __BASE_INTMATH_HH__
STL pair class.
Definition stl.hh:58
static constexpr int log2i(int value)
Calculate the log2 of a power of 2 integer.
Definition intmath.hh:295
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
static constexpr int ceilLog2(const T &n)
Definition intmath.hh:84
static constexpr std::enable_if_t< sizeof(T)<=sizeof(uint32_t)> mulUnsigned(std::make_unsigned_t< T > &high, std::make_unsigned_t< T > &low, std::make_unsigned_t< T > val_a, std::make_unsigned_t< T > val_b)
Definition intmath.hh:120
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
static constexpr T divCeil(const T &a, const U &b)
Definition intmath.hh:110
static constexpr std::enable_if_t< sizeof(T)<=sizeof(uint32_t)> mulSigned(std::make_signed_t< T > &high, std::make_signed_t< T > &low, std::make_signed_t< T > val_a, std::make_signed_t< T > val_b)
Definition intmath.hh:133
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:279
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:260
constexpr int ctz32(uint32_t value)
Count trailing zeros in a 32-bit value.
Definition bitfield.hh:473
Bitfield< 31 > n
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > b
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 55, 52 > ts
Bitfield< 5 > ux
Bitfield< 6 > c2
Bitfield< 3 > x
Definition pagetable.hh:73
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
static constexpr std::enable_if_t< sizeof(T)==sizeof(uint64_t)> mulSignedManual(std::make_signed_t< T > &high, std::make_signed_t< T > &low, std::make_signed_t< T > val_a, std::make_signed_t< T > val_b)
Definition intmath.hh:198
static constexpr std::enable_if_t< sizeof(T)==sizeof(uint64_t)> mulUnsignedManual(std::make_unsigned_t< T > &high, std::make_unsigned_t< T > &low, std::make_unsigned_t< T > val_a, std::make_unsigned_t< T > val_b)
Multiply two values with place value p.
Definition intmath.hh:156

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0