gem5  v21.1.0.2
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 
51 namespace gem5
52 {
53 
57 template <class T>
58 static constexpr std::enable_if_t<std::is_integral<T>::value, 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 
82 template <class T>
83 static constexpr int
84 ceilLog2(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 
96 template <class T>
97 static constexpr bool
98 isPowerOf2(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 
108 template <class T, class U>
109 static constexpr T
110 divCeil(const T& a, const U& b)
111 {
112  return (a + b - 1) / b;
113 }
114 
118 template <typename T>
119 static constexpr std::enable_if_t<sizeof(T) <= sizeof(uint32_t)>
120 mulUnsigned(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 
131 template <typename T>
132 static constexpr std::enable_if_t<sizeof(T) <= sizeof(uint32_t)>
133 mulSigned(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 
154 template <typename T>
155 static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
156 mulUnsignedManual(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 
182 template <typename T>
183 static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
184 mulUnsigned(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 
196 template <typename T>
197 static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
198 mulSignedManual(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 
216 template <typename T>
217 static constexpr std::enable_if_t<sizeof(T) == sizeof(uint64_t)>
218 mulSigned(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 
230 template <typename T>
231 static constexpr std::pair<std::make_unsigned_t<T>, std::make_unsigned_t<T>>
232 mulUnsigned(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 
239 template <typename T>
240 static constexpr std::pair<std::make_signed_t<T>, std::make_signed_t<T>>
241 mulSigned(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 
258 template <class T, class U>
259 static constexpr T
260 roundUp(const T& val, const U& align)
261 {
262  assert(isPowerOf2(align));
263  T mask = (T)align - 1;
264  return (val + mask) & ~mask;
265 }
266 
277 template <class T, class U>
278 static constexpr T
279 roundDown(const T& val, const U& align)
280 {
281  assert(isPowerOf2(align));
282  T mask = (T)align - 1;
283  return val & ~mask;
284 }
285 
294 static constexpr int
295 log2i(int value)
296 {
297  assert(isPowerOf2(value) && value > 0);
298  return ctz32(value);
299 }
300 
301 } // namespace gem5
302 
303 #endif // __BASE_INTMATH_HH__
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:775
gem5::ArmISA::a
Bitfield< 8 > a
Definition: misc_types.hh:65
gem5::log2i
static constexpr int log2i(int value)
Calculate the log2 of a power of 2 integer.
Definition: intmath.hh:295
gem5::mulSigned
static constexpr std::enable_if_t< sizeof(T)==sizeof(uint64_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:218
gem5::isPowerOf2
static constexpr bool isPowerOf2(const T &n)
Definition: intmath.hh:98
sc_dt::align
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
Definition: scfx_rep.cc:2083
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::mulUnsigned
static constexpr std::enable_if_t< sizeof(T)==sizeof(uint64_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:184
gem5::high
high
Definition: intmath.hh:176
gem5::ArmISA::b
Bitfield< 7 > b
Definition: misc_types.hh:381
bitfield.hh
gem5::X86ISA::type
type
Definition: misc.hh:733
gem5::MipsISA::ux
Bitfield< 5 > ux
Definition: pra_constants.hh:136
gem5::roundDown
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
std::pair
STL pair class.
Definition: stl.hh:58
gem5::divCeil
static constexpr T divCeil(const T &a, const U &b)
Definition: intmath.hh:110
gem5::ceilLog2
static constexpr int ceilLog2(const T &n)
Definition: intmath.hh:84
gem5::RiscvISA::x
Bitfield< 3 > x
Definition: pagetable.hh:73
gem5::mulSignedManual
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
gem5::c2
c2
Definition: intmath.hh:174
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:455
gem5::ctz32
constexpr int ctz32(uint32_t value)
Count trailing zeros in a 32-bit value.
Definition: bitfield.hh:395
gem5::floorLog2
static constexpr std::enable_if_t< std::is_integral< T >::value, int > floorLog2(T x)
Definition: intmath.hh:59
gem5::roundUp
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:260
gem5::ArmISA::ts
Bitfield< 55, 52 > ts
Definition: misc_types.hh:92
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40

Generated on Tue Sep 21 2021 12:24:57 for gem5 by doxygen 1.8.17