1*563a794dSFrançois Tigeot /*- 2*563a794dSFrançois Tigeot * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 3*563a794dSFrançois Tigeot * Copyright (c) 2014 Mellanox Technologies, Ltd. All rights reserved. 4*563a794dSFrançois Tigeot * All rights reserved. 5*563a794dSFrançois Tigeot * 6*563a794dSFrançois Tigeot * Redistribution and use in source and binary forms, with or without 7*563a794dSFrançois Tigeot * modification, are permitted provided that the following conditions 8*563a794dSFrançois Tigeot * are met: 9*563a794dSFrançois Tigeot * 1. Redistributions of source code must retain the above copyright 10*563a794dSFrançois Tigeot * notice unmodified, this list of conditions, and the following 11*563a794dSFrançois Tigeot * disclaimer. 12*563a794dSFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright 13*563a794dSFrançois Tigeot * notice, this list of conditions and the following disclaimer in the 14*563a794dSFrançois Tigeot * documentation and/or other materials provided with the distribution. 15*563a794dSFrançois Tigeot * 16*563a794dSFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17*563a794dSFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18*563a794dSFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19*563a794dSFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20*563a794dSFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21*563a794dSFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22*563a794dSFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23*563a794dSFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*563a794dSFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25*563a794dSFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*563a794dSFrançois Tigeot */ 27*563a794dSFrançois Tigeot 28*563a794dSFrançois Tigeot #ifndef _LINUX_MATH64_H 29*563a794dSFrançois Tigeot #define _LINUX_MATH64_H 30*563a794dSFrançois Tigeot 31*563a794dSFrançois Tigeot #include <linux/types.h> 32*563a794dSFrançois Tigeot #include <linux/bitops.h> 33*563a794dSFrançois Tigeot 34*563a794dSFrançois Tigeot #if BITS_PER_LONG == 64 35*563a794dSFrançois Tigeot 36*563a794dSFrançois Tigeot # define do_div(n, base) ({ \ 37*563a794dSFrançois Tigeot uint32_t __base = (base); \ 38*563a794dSFrançois Tigeot uint32_t __rem; \ 39*563a794dSFrançois Tigeot __rem = ((uint64_t)(n)) % __base; \ 40*563a794dSFrançois Tigeot (n) = ((uint64_t)(n)) / __base; \ 41*563a794dSFrançois Tigeot __rem; \ 42*563a794dSFrançois Tigeot }) 43*563a794dSFrançois Tigeot 44*563a794dSFrançois Tigeot /** 45*563a794dSFrançois Tigeot * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder 46*563a794dSFrançois Tigeot * 47*563a794dSFrançois Tigeot * This is commonly provided by 32bit archs to provide an optimized 64bit 48*563a794dSFrançois Tigeot * divide. 49*563a794dSFrançois Tigeot */ 50*563a794dSFrançois Tigeot static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) 51*563a794dSFrançois Tigeot { 52*563a794dSFrançois Tigeot *remainder = dividend % divisor; 53*563a794dSFrançois Tigeot return dividend / divisor; 54*563a794dSFrançois Tigeot } 55*563a794dSFrançois Tigeot 56*563a794dSFrançois Tigeot 57*563a794dSFrançois Tigeot #elif BITS_PER_LONG == 32 58*563a794dSFrançois Tigeot 59*563a794dSFrançois Tigeot static uint32_t __div64_32(uint64_t *n, uint32_t base) 60*563a794dSFrançois Tigeot { 61*563a794dSFrançois Tigeot uint64_t rem = *n; 62*563a794dSFrançois Tigeot uint64_t b = base; 63*563a794dSFrançois Tigeot uint64_t res, d = 1; 64*563a794dSFrançois Tigeot uint32_t high = rem >> 32; 65*563a794dSFrançois Tigeot 66*563a794dSFrançois Tigeot /* Reduce the thing a bit first */ 67*563a794dSFrançois Tigeot res = 0; 68*563a794dSFrançois Tigeot if (high >= base) { 69*563a794dSFrançois Tigeot high /= base; 70*563a794dSFrançois Tigeot res = (uint64_t) high << 32; 71*563a794dSFrançois Tigeot rem -= (uint64_t) (high*base) << 32; 72*563a794dSFrançois Tigeot } 73*563a794dSFrançois Tigeot 74*563a794dSFrançois Tigeot while ((int64_t)b > 0 && b < rem) { 75*563a794dSFrançois Tigeot b = b+b; 76*563a794dSFrançois Tigeot d = d+d; 77*563a794dSFrançois Tigeot } 78*563a794dSFrançois Tigeot 79*563a794dSFrançois Tigeot do { 80*563a794dSFrançois Tigeot if (rem >= b) { 81*563a794dSFrançois Tigeot rem -= b; 82*563a794dSFrançois Tigeot res += d; 83*563a794dSFrançois Tigeot } 84*563a794dSFrançois Tigeot b >>= 1; 85*563a794dSFrançois Tigeot d >>= 1; 86*563a794dSFrançois Tigeot } while (d); 87*563a794dSFrançois Tigeot 88*563a794dSFrançois Tigeot *n = res; 89*563a794dSFrançois Tigeot return rem; 90*563a794dSFrançois Tigeot } 91*563a794dSFrançois Tigeot 92*563a794dSFrançois Tigeot # define do_div(n, base) ({ \ 93*563a794dSFrançois Tigeot uint32_t __base = (base); \ 94*563a794dSFrançois Tigeot uint32_t __rem; \ 95*563a794dSFrançois Tigeot (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ 96*563a794dSFrançois Tigeot if (likely(((n) >> 32) == 0)) { \ 97*563a794dSFrançois Tigeot __rem = (uint32_t)(n) % __base; \ 98*563a794dSFrançois Tigeot (n) = (uint32_t)(n) / __base; \ 99*563a794dSFrançois Tigeot } else \ 100*563a794dSFrançois Tigeot __rem = __div64_32(&(n), __base); \ 101*563a794dSFrançois Tigeot __rem; \ 102*563a794dSFrançois Tigeot }) 103*563a794dSFrançois Tigeot 104*563a794dSFrançois Tigeot #ifndef div_u64_rem 105*563a794dSFrançois Tigeot static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) 106*563a794dSFrançois Tigeot { 107*563a794dSFrançois Tigeot *remainder = do_div(dividend, divisor); 108*563a794dSFrançois Tigeot return dividend; 109*563a794dSFrançois Tigeot } 110*563a794dSFrançois Tigeot #endif 111*563a794dSFrançois Tigeot 112*563a794dSFrançois Tigeot #endif /* BITS_PER_LONG */ 113*563a794dSFrançois Tigeot 114*563a794dSFrançois Tigeot 115*563a794dSFrançois Tigeot 116*563a794dSFrançois Tigeot /** 117*563a794dSFrançois Tigeot ** div_u64 - unsigned 64bit divide with 32bit divisor 118*563a794dSFrançois Tigeot ** 119*563a794dSFrançois Tigeot ** This is the most common 64bit divide and should be used if possible, 120*563a794dSFrançois Tigeot ** as many 32bit archs can optimize this variant better than a full 64bit 121*563a794dSFrançois Tigeot ** divide. 122*563a794dSFrançois Tigeot * */ 123*563a794dSFrançois Tigeot #ifndef div_u64 124*563a794dSFrançois Tigeot 125*563a794dSFrançois Tigeot static inline u64 div_u64(u64 dividend, u32 divisor) 126*563a794dSFrançois Tigeot { 127*563a794dSFrançois Tigeot u32 remainder; 128*563a794dSFrançois Tigeot return div_u64_rem(dividend, divisor, &remainder); 129*563a794dSFrançois Tigeot } 130*563a794dSFrançois Tigeot #endif 131*563a794dSFrançois Tigeot 132*563a794dSFrançois Tigeot #endif /* _LINUX_MATH64_H */ 133