linux/arch/mips/include/asm/div64.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2000, 2004, 2021  Maciej W. Rozycki
   3 * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
   4 *
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 */
   9#ifndef __ASM_DIV64_H
  10#define __ASM_DIV64_H
  11
  12#include <asm/bitsperlong.h>
  13
  14#if BITS_PER_LONG == 32
  15
  16/*
  17 * No traps on overflows for any of these...
  18 */
  19
  20#define do_div64_32(res, high, low, base) ({                            \
  21        unsigned long __cf, __tmp, __tmp2, __i;                         \
  22        unsigned long __quot32, __mod32;                                \
  23                                                                        \
  24        __asm__(                                                        \
  25        "       .set    push                                    \n"     \
  26        "       .set    noat                                    \n"     \
  27        "       .set    noreorder                               \n"     \
  28        "       move    %2, $0                                  \n"     \
  29        "       move    %3, $0                                  \n"     \
  30        "       b       1f                                      \n"     \
  31        "        li     %4, 0x21                                \n"     \
  32        "0:                                                     \n"     \
  33        "       sll     $1, %0, 0x1                             \n"     \
  34        "       srl     %3, %0, 0x1f                            \n"     \
  35        "       or      %0, $1, %5                              \n"     \
  36        "       sll     %1, %1, 0x1                             \n"     \
  37        "       sll     %2, %2, 0x1                             \n"     \
  38        "1:                                                     \n"     \
  39        "       bnez    %3, 2f                                  \n"     \
  40        "        sltu   %5, %0, %z6                             \n"     \
  41        "       bnez    %5, 3f                                  \n"     \
  42        "2:                                                     \n"     \
  43        "        addiu  %4, %4, -1                              \n"     \
  44        "       subu    %0, %0, %z6                             \n"     \
  45        "       addiu   %2, %2, 1                               \n"     \
  46        "3:                                                     \n"     \
  47        "       bnez    %4, 0b                                  \n"     \
  48        "        srl    %5, %1, 0x1f                            \n"     \
  49        "       .set    pop"                                            \
  50        : "=&r" (__mod32), "=&r" (__tmp),                               \
  51          "=&r" (__quot32), "=&r" (__cf),                               \
  52          "=&r" (__i), "=&r" (__tmp2)                                   \
  53        : "Jr" (base), "0" (high), "1" (low));                          \
  54                                                                        \
  55        (res) = __quot32;                                               \
  56        __mod32;                                                        \
  57})
  58
  59#define __div64_32(n, base) ({                                          \
  60        unsigned long __upper, __low, __high, __radix;                  \
  61        unsigned long long __quot;                                      \
  62        unsigned long long __div;                                       \
  63        unsigned long __mod;                                            \
  64                                                                        \
  65        __div = (*n);                                                   \
  66        __radix = (base);                                               \
  67                                                                        \
  68        __high = __div >> 32;                                           \
  69        __low = __div;                                                  \
  70                                                                        \
  71        if (__high < __radix) {                                         \
  72                __upper = __high;                                       \
  73                __high = 0;                                             \
  74        } else {                                                        \
  75                __upper = __high % __radix;                             \
  76                __high /= __radix;                                      \
  77        }                                                               \
  78                                                                        \
  79        __mod = do_div64_32(__low, __upper, __low, __radix);            \
  80                                                                        \
  81        __quot = __high;                                                \
  82        __quot = __quot << 32 | __low;                                  \
  83        (*n) = __quot;                                                  \
  84        __mod;                                                          \
  85})
  86
  87#endif /* BITS_PER_LONG == 32 */
  88
  89#include <asm-generic/div64.h>
  90
  91#endif /* __ASM_DIV64_H */
  92