arch,cpu,mem: Replace the mmmapped IPR mechanism with local accesses.
[gem5.git] / src / base / intmath.hh
1 /*
2 * Copyright (c) 2001, 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef __BASE_INTMATH_HH__
30 #define __BASE_INTMATH_HH__
31
32 #include <cassert>
33
34 #include "base/logging.hh"
35 #include "base/types.hh"
36
37 inline uint64_t
38 power(uint32_t n, uint32_t e)
39 {
40 if (e > 20)
41 warn("Warning, power() function is quite slow for large exponents\n");
42
43 if (e == 0)
44 return 1;
45
46 uint64_t result = n;
47 uint64_t old_result = 0;
48 for (int x = 1; x < e; x++) {
49 old_result = result;
50 result *= n;
51 if (old_result > result)
52 warn("power() overflowed!\n");
53 }
54 return result;
55 }
56
57
58 inline int
59 floorLog2(unsigned x)
60 {
61 assert(x > 0);
62
63 int y = 0;
64
65 if (x & 0xffff0000) { y += 16; x >>= 16; }
66 if (x & 0x0000ff00) { y += 8; x >>= 8; }
67 if (x & 0x000000f0) { y += 4; x >>= 4; }
68 if (x & 0x0000000c) { y += 2; x >>= 2; }
69 if (x & 0x00000002) { y += 1; }
70
71 return y;
72 }
73
74 inline int
75 floorLog2(unsigned long x)
76 {
77 assert(x > 0);
78
79 int y = 0;
80
81 #if defined(__LP64__)
82 if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
83 #endif
84 if (x & 0xffff0000) { y += 16; x >>= 16; }
85 if (x & 0x0000ff00) { y += 8; x >>= 8; }
86 if (x & 0x000000f0) { y += 4; x >>= 4; }
87 if (x & 0x0000000c) { y += 2; x >>= 2; }
88 if (x & 0x00000002) { y += 1; }
89
90 return y;
91 }
92
93 inline int
94 floorLog2(unsigned long long x)
95 {
96 assert(x > 0);
97
98 int y = 0;
99
100 if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
101 if (x & ULL(0x00000000ffff0000)) { y += 16; x >>= 16; }
102 if (x & ULL(0x000000000000ff00)) { y += 8; x >>= 8; }
103 if (x & ULL(0x00000000000000f0)) { y += 4; x >>= 4; }
104 if (x & ULL(0x000000000000000c)) { y += 2; x >>= 2; }
105 if (x & ULL(0x0000000000000002)) { y += 1; }
106
107 return y;
108 }
109
110 inline int
111 floorLog2(int x)
112 {
113 assert(x > 0);
114 return floorLog2((unsigned)x);
115 }
116
117 inline int
118 floorLog2(long x)
119 {
120 assert(x > 0);
121 return floorLog2((unsigned long)x);
122 }
123
124 inline int
125 floorLog2(long long x)
126 {
127 assert(x > 0);
128 return floorLog2((unsigned long long)x);
129 }
130
131 template <class T>
132 inline int
133 ceilLog2(const T& n)
134 {
135 assert(n > 0);
136 if (n == 1)
137 return 0;
138
139 return floorLog2(n - (T)1) + 1;
140 }
141
142 template <class T>
143 inline bool
144 isPowerOf2(const T& n)
145 {
146 return n != 0 && floorLog2(n) == ceilLog2(n);
147 }
148
149 template <class T, class U>
150 inline T
151 divCeil(const T& a, const U& b)
152 {
153 return (a + b - 1) / b;
154 }
155
156 /**
157 * This function is used to align addresses in memory.
158 *
159 * @param val is the address to be aligned.
160 * @param align is the alignment. Can only be a power of 2.
161 * @return The aligned address. The smallest number divisible
162 * by @param align which is greater than or equal to @param val.
163 */
164 template <class T, class U>
165 inline T
166 roundUp(const T& val, const U& align)
167 {
168 assert(isPowerOf2(align));
169 T mask = (T)align - 1;
170 return (val + mask) & ~mask;
171 }
172
173 /**
174 * This function is used to align addresses in memory.
175 *
176 * @param val is the address to be aligned.
177 * @param align is the alignment. Can only be a power of 2.
178 * @return The aligned address. The biggest number divisible
179 * by @param align which is less than or equal to @param val.
180 */
181 template <class T, class U>
182 inline T
183 roundDown(const T& val, const U& align)
184 {
185 assert(isPowerOf2(align));
186 T mask = (T)align - 1;
187 return val & ~mask;
188 }
189
190 #endif // __BASE_INTMATH_HH__