LCOV - code coverage report
Current view: top level - lib - div64.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 60 16.7 %
Date: 2014-02-18 Functions: 2 6 33.3 %
Branches: 5 26 19.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
       3                 :            :  *
       4                 :            :  * Based on former do_div() implementation from asm-parisc/div64.h:
       5                 :            :  *      Copyright (C) 1999 Hewlett-Packard Co
       6                 :            :  *      Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
       7                 :            :  *
       8                 :            :  *
       9                 :            :  * Generic C version of 64bit/32bit division and modulo, with
      10                 :            :  * 64bit result and 32bit remainder.
      11                 :            :  *
      12                 :            :  * The fast case for (n>>32 == 0) is handled inline by do_div(). 
      13                 :            :  *
      14                 :            :  * Code generated for this function might be very inefficient
      15                 :            :  * for some CPUs. __div64_32() can be overridden by linking arch-specific
      16                 :            :  * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S.
      17                 :            :  */
      18                 :            : 
      19                 :            : #include <linux/export.h>
      20                 :            : #include <linux/kernel.h>
      21                 :            : #include <linux/math64.h>
      22                 :            : 
      23                 :            : /* Not needed on 64bit architectures */
      24                 :            : #if BITS_PER_LONG == 32
      25                 :            : 
      26                 :          0 : uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
      27                 :            : {
      28                 :          0 :         uint64_t rem = *n;
      29                 :          0 :         uint64_t b = base;
      30                 :            :         uint64_t res, d = 1;
      31                 :          0 :         uint32_t high = rem >> 32;
      32                 :            : 
      33                 :            :         /* Reduce the thing a bit first */
      34                 :            :         res = 0;
      35         [ #  # ]:          0 :         if (high >= base) {
      36                 :          0 :                 high /= base;
      37                 :          0 :                 res = (uint64_t) high << 32;
      38                 :          0 :                 rem -= (uint64_t) (high*base) << 32;
      39                 :            :         }
      40                 :            : 
      41         [ #  # ]:          0 :         while ((int64_t)b > 0 && b < rem) {
      42                 :          0 :                 b = b+b;
      43                 :          0 :                 d = d+d;
      44                 :            :         }
      45                 :            : 
      46                 :            :         do {
      47         [ #  # ]:          0 :                 if (rem >= b) {
      48                 :          0 :                         rem -= b;
      49                 :          0 :                         res += d;
      50                 :            :                 }
      51                 :          0 :                 b >>= 1;
      52                 :          0 :                 d >>= 1;
      53         [ #  # ]:          0 :         } while (d);
      54                 :            : 
      55                 :          0 :         *n = res;
      56                 :          0 :         return rem;
      57                 :            : }
      58                 :            : 
      59                 :            : EXPORT_SYMBOL(__div64_32);
      60                 :            : 
      61                 :            : #ifndef div_s64_rem
      62                 :          0 : s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
      63                 :            : {
      64                 :            :         u64 quotient;
      65                 :            : 
      66         [ +  + ]:   11802787 :         if (dividend < 0) {
      67                 :       3407 :                 quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
      68                 :       3407 :                 *remainder = -*remainder;
      69         [ +  - ]:       3407 :                 if (divisor > 0)
      70                 :       3407 :                         quotient = -quotient;
      71                 :            :         } else {
      72                 :   11799380 :                 quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
      73         [ -  + ]:   11799380 :                 if (divisor < 0)
      74                 :          0 :                         quotient = -quotient;
      75                 :            :         }
      76                 :          0 :         return quotient;
      77                 :            : }
      78                 :            : EXPORT_SYMBOL(div_s64_rem);
      79                 :            : #endif
      80                 :            : 
      81                 :            : /**
      82                 :            :  * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder
      83                 :            :  * @dividend:   64bit dividend
      84                 :            :  * @divisor:    64bit divisor
      85                 :            :  * @remainder:  64bit remainder
      86                 :            :  *
      87                 :            :  * This implementation is a comparable to algorithm used by div64_u64.
      88                 :            :  * But this operation, which includes math for calculating the remainder,
      89                 :            :  * is kept distinct to avoid slowing down the div64_u64 operation on 32bit
      90                 :            :  * systems.
      91                 :            :  */
      92                 :            : #ifndef div64_u64_rem
      93                 :          0 : u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
      94                 :            : {
      95                 :          0 :         u32 high = divisor >> 32;
      96                 :            :         u64 quot;
      97                 :            : 
      98         [ #  # ]:          0 :         if (high == 0) {
      99                 :            :                 u32 rem32;
     100                 :          0 :                 quot = div_u64_rem(dividend, divisor, &rem32);
     101                 :          0 :                 *remainder = rem32;
     102                 :            :         } else {
     103                 :          0 :                 int n = 1 + fls(high);
     104                 :          0 :                 quot = div_u64(dividend >> n, divisor >> n);
     105                 :            : 
     106         [ #  # ]:          0 :                 if (quot != 0)
     107                 :          0 :                         quot--;
     108                 :            : 
     109                 :          0 :                 *remainder = dividend - quot * divisor;
     110         [ #  # ]:          0 :                 if (*remainder >= divisor) {
     111                 :          0 :                         quot++;
     112                 :          0 :                         *remainder -= divisor;
     113                 :            :                 }
     114                 :            :         }
     115                 :            : 
     116                 :          0 :         return quot;
     117                 :            : }
     118                 :            : EXPORT_SYMBOL(div64_u64_rem);
     119                 :            : #endif
     120                 :            : 
     121                 :            : /**
     122                 :            :  * div64_u64 - unsigned 64bit divide with 64bit divisor
     123                 :            :  * @dividend:   64bit dividend
     124                 :            :  * @divisor:    64bit divisor
     125                 :            :  *
     126                 :            :  * This implementation is a modified version of the algorithm proposed
     127                 :            :  * by the book 'Hacker's Delight'.  The original source and full proof
     128                 :            :  * can be found here and is available for use without restriction.
     129                 :            :  *
     130                 :            :  * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt'
     131                 :            :  */
     132                 :            : #ifndef div64_u64
     133                 :          0 : u64 div64_u64(u64 dividend, u64 divisor)
     134                 :            : {
     135                 :         14 :         u32 high = divisor >> 32;
     136                 :            :         u64 quot;
     137                 :            : 
     138         [ +  - ]:         14 :         if (high == 0) {
     139                 :         14 :                 quot = div_u64(dividend, divisor);
     140                 :            :         } else {
     141                 :          0 :                 int n = 1 + fls(high);
     142                 :          0 :                 quot = div_u64(dividend >> n, divisor >> n);
     143                 :            : 
     144         [ #  # ]:          0 :                 if (quot != 0)
     145                 :          0 :                         quot--;
     146         [ #  # ]:          0 :                 if ((dividend - quot * divisor) >= divisor)
     147                 :          0 :                         quot++;
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         return quot;
     151                 :            : }
     152                 :            : EXPORT_SYMBOL(div64_u64);
     153                 :            : #endif
     154                 :            : 
     155                 :            : /**
     156                 :            :  * div64_s64 - signed 64bit divide with 64bit divisor
     157                 :            :  * @dividend:   64bit dividend
     158                 :            :  * @divisor:    64bit divisor
     159                 :            :  */
     160                 :            : #ifndef div64_s64
     161                 :          0 : s64 div64_s64(s64 dividend, s64 divisor)
     162                 :            : {
     163                 :            :         s64 quot, t;
     164                 :            : 
     165                 :          0 :         quot = div64_u64(abs64(dividend), abs64(divisor));
     166                 :          0 :         t = (dividend ^ divisor) >> 63;
     167                 :            : 
     168                 :          0 :         return (quot ^ t) - t;
     169                 :            : }
     170                 :            : EXPORT_SYMBOL(div64_s64);
     171                 :            : #endif
     172                 :            : 
     173                 :            : #endif /* BITS_PER_LONG == 32 */
     174                 :            : 
     175                 :            : /*
     176                 :            :  * Iterative div/mod for use when dividend is not expected to be much
     177                 :            :  * bigger than divisor.
     178                 :            :  */
     179                 :          0 : u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
     180                 :            : {
     181                 :          0 :         return __iter_div_u64_rem(dividend, divisor, remainder);
     182                 :            : }
     183                 :            : EXPORT_SYMBOL(iter_div_u64_rem);

Generated by: LCOV version 1.9