intmath.hh revision 1642
15081Sgblack@eecs.umich.edu/*
25081Sgblack@eecs.umich.edu * Copyright (c) 2001, 2003 The Regents of The University of Michigan
35081Sgblack@eecs.umich.edu * All rights reserved.
45081Sgblack@eecs.umich.edu *
55081Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65081Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75081Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85081Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95081Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105081Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115081Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125081Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135081Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145081Sgblack@eecs.umich.edu * this software without specific prior written permission.
155081Sgblack@eecs.umich.edu *
165081Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175081Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185081Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195081Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205081Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215081Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225081Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235081Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245081Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255081Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265081Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275081Sgblack@eecs.umich.edu */
285081Sgblack@eecs.umich.edu
295081Sgblack@eecs.umich.edu#ifndef __INTMATH_HH__
305081Sgblack@eecs.umich.edu#define __INTMATH_HH__
315081Sgblack@eecs.umich.edu
325081Sgblack@eecs.umich.edu#include <assert.h>
335081Sgblack@eecs.umich.edu
345081Sgblack@eecs.umich.edu#include "sim/host.hh"
355081Sgblack@eecs.umich.edu
365081Sgblack@eecs.umich.edu// Returns the prime number one less than n.
375081Sgblack@eecs.umich.eduint PrevPrime(int n);
385081Sgblack@eecs.umich.edu
395081Sgblack@eecs.umich.edu// Determine if a number is prime
405081Sgblack@eecs.umich.edutemplate <class T>
415081Sgblack@eecs.umich.eduinline bool
425081Sgblack@eecs.umich.eduIsPrime(T n)
435081Sgblack@eecs.umich.edu{
445081Sgblack@eecs.umich.edu    T i;
455081Sgblack@eecs.umich.edu
465081Sgblack@eecs.umich.edu    if (n == 2 || n == 3)
475081Sgblack@eecs.umich.edu        return true;
485081Sgblack@eecs.umich.edu
495081Sgblack@eecs.umich.edu    // Don't try every odd number to prove if it is a prime.
505081Sgblack@eecs.umich.edu    // Toggle between every 2nd and 4th number.
515081Sgblack@eecs.umich.edu    // (This is because every 6th odd number is divisible by 3.)
525081Sgblack@eecs.umich.edu    for (i = 5; i*i <= n; i += 6) {
535081Sgblack@eecs.umich.edu        if (((n % i) == 0 ) || ((n % (i + 2)) == 0) ) {
545081Sgblack@eecs.umich.edu            return false;
555081Sgblack@eecs.umich.edu        }
565081Sgblack@eecs.umich.edu    }
575081Sgblack@eecs.umich.edu
585081Sgblack@eecs.umich.edu    return true;
595081Sgblack@eecs.umich.edu}
605081Sgblack@eecs.umich.edu
615081Sgblack@eecs.umich.edutemplate <class T>
625081Sgblack@eecs.umich.eduinline T
635081Sgblack@eecs.umich.eduLeastSigBit(T n)
645119Sgblack@eecs.umich.edu{
655081Sgblack@eecs.umich.edu    return n & ~(n - 1);
665081Sgblack@eecs.umich.edu}
675081Sgblack@eecs.umich.edu
685081Sgblack@eecs.umich.edutemplate <class T>
695081Sgblack@eecs.umich.eduinline bool
705081Sgblack@eecs.umich.eduIsPowerOf2(T n)
715081Sgblack@eecs.umich.edu{
725119Sgblack@eecs.umich.edu    return n != 0 && LeastSigBit(n) == n;
735081Sgblack@eecs.umich.edu}
745081Sgblack@eecs.umich.edu
755081Sgblack@eecs.umich.eduinline int
765081Sgblack@eecs.umich.eduFloorLog2(unsigned x)
776091Sgblack@eecs.umich.edu{
786091Sgblack@eecs.umich.edu    assert(x > 0);
796091Sgblack@eecs.umich.edu
806091Sgblack@eecs.umich.edu    int y = 0;
816091Sgblack@eecs.umich.edu
826091Sgblack@eecs.umich.edu    if (x & 0xffff0000) { y += 16; x >>= 16; }
836091Sgblack@eecs.umich.edu    if (x & 0x0000ff00) { y +=  8; x >>=  8; }
846091Sgblack@eecs.umich.edu    if (x & 0x000000f0) { y +=  4; x >>=  4; }
856091Sgblack@eecs.umich.edu    if (x & 0x0000000c) { y +=  2; x >>=  2; }
866091Sgblack@eecs.umich.edu    if (x & 0x00000002) { y +=  1; }
876091Sgblack@eecs.umich.edu
886091Sgblack@eecs.umich.edu    return y;
896091Sgblack@eecs.umich.edu}
906091Sgblack@eecs.umich.edu
916091Sgblack@eecs.umich.eduinline int
925081Sgblack@eecs.umich.eduFloorLog2(unsigned long x)
935081Sgblack@eecs.umich.edu{
945081Sgblack@eecs.umich.edu    assert(x > 0);
955081Sgblack@eecs.umich.edu
965081Sgblack@eecs.umich.edu    int y = 0;
975081Sgblack@eecs.umich.edu
985081Sgblack@eecs.umich.edu#if defined(__LP64__)
995119Sgblack@eecs.umich.edu    if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
1005081Sgblack@eecs.umich.edu#endif
1015081Sgblack@eecs.umich.edu    if (x & 0xffff0000) { y += 16; x >>= 16; }
1025081Sgblack@eecs.umich.edu    if (x & 0x0000ff00) { y +=  8; x >>=  8; }
1035081Sgblack@eecs.umich.edu    if (x & 0x000000f0) { y +=  4; x >>=  4; }
1045081Sgblack@eecs.umich.edu    if (x & 0x0000000c) { y +=  2; x >>=  2; }
1055081Sgblack@eecs.umich.edu    if (x & 0x00000002) { y +=  1; }
1065081Sgblack@eecs.umich.edu
1075119Sgblack@eecs.umich.edu    return y;
1085081Sgblack@eecs.umich.edu}
1095081Sgblack@eecs.umich.edu
1105081Sgblack@eecs.umich.eduinline int
1116092Sgblack@eecs.umich.eduFloorLog2(unsigned long long x)
1126092Sgblack@eecs.umich.edu{
1136092Sgblack@eecs.umich.edu    assert(x > 0);
1146092Sgblack@eecs.umich.edu
1156092Sgblack@eecs.umich.edu    int y = 0;
1166092Sgblack@eecs.umich.edu
1176092Sgblack@eecs.umich.edu    if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
1186092Sgblack@eecs.umich.edu    if (x & ULL(0x00000000ffff0000)) { y += 16; x >>= 16; }
1196092Sgblack@eecs.umich.edu    if (x & ULL(0x000000000000ff00)) { y +=  8; x >>=  8; }
1206092Sgblack@eecs.umich.edu    if (x & ULL(0x00000000000000f0)) { y +=  4; x >>=  4; }
1216092Sgblack@eecs.umich.edu    if (x & ULL(0x000000000000000c)) { y +=  2; x >>=  2; }
1226092Sgblack@eecs.umich.edu    if (x & ULL(0x0000000000000002)) { y +=  1; }
1236092Sgblack@eecs.umich.edu
1246092Sgblack@eecs.umich.edu    return y;
1256092Sgblack@eecs.umich.edu}
1265081Sgblack@eecs.umich.edu
127inline int
128FloorLog2(int x)
129{
130    assert(x > 0);
131    return FloorLog2((unsigned)x);
132}
133
134inline int
135FloorLog2(long x)
136{
137    assert(x > 0);
138    return FloorLog2((unsigned long)x);
139}
140
141inline int
142FloorLog2(long long x)
143{
144    assert(x > 0);
145    return FloorLog2((unsigned long long)x);
146}
147
148#if defined(__APPLE__)
149inline int
150FloorLog2(size_t x)
151{
152    assert(x > 0);
153    assert(sizeof(size_t) == 4 || sizeof(size_t) == 8);
154
155    // It's my hope that this is optimized away?
156    if (sizeof(size_t) == 4)
157        return FloorLog2((uint32_t)x);
158     else if (sizeof(size_t) == 8)
159        return FloorLog2((uint64_t)x);
160
161}
162#endif
163
164template <class T>
165inline int
166CeilLog2(T n)
167{
168    if (n == 1)
169        return 0;
170
171    return FloorLog2(n - (T)1) + 1;
172}
173
174template <class T>
175inline T
176FloorPow2(T n)
177{
178    return (T)1 << FloorLog2(n);
179}
180
181template <class T>
182inline T
183CeilPow2(T n)
184{
185    return (T)1 << CeilLog2(n);
186}
187
188template <class T>
189inline T
190DivCeil(T a, T b)
191{
192    return (a + b - 1) / b;
193}
194
195template <class T>
196inline T
197RoundUp(T val, T align)
198{
199    T mask = align - 1;
200    return (val + mask) & ~mask;
201}
202
203template <class T>
204inline T
205RoundDown(T val, T align)
206{
207    T mask = align - 1;
208    return val & ~mask;
209}
210
211inline bool
212IsHex(char c)
213{
214    return c >= '0' && c <= '9' ||
215        c >= 'A' && c <= 'F' ||
216        c >= 'a' && c <= 'f';
217}
218
219inline bool
220IsOct(char c)
221{
222    return c >= '0' && c <= '7';
223}
224
225inline bool
226IsDec(char c)
227{
228    return c >= '0' && c <= '9';
229}
230
231inline int
232Hex2Int(char c)
233{
234  if (c >= '0' && c <= '9')
235    return (c - '0');
236
237  if (c >= 'A' && c <= 'F')
238    return (c - 'A') + 10;
239
240  if (c >= 'a' && c <= 'f')
241    return (c - 'a') + 10;
242
243  return 0;
244}
245
246#endif // __INTMATH_HH__
247