Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2000, 2004, 2021  Maciej W. Rozycki
0003  * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
0004  *
0005  * This file is subject to the terms and conditions of the GNU General Public
0006  * License.  See the file "COPYING" in the main directory of this archive
0007  * for more details.
0008  */
0009 #ifndef __ASM_DIV64_H
0010 #define __ASM_DIV64_H
0011 
0012 #include <asm/bitsperlong.h>
0013 
0014 #if BITS_PER_LONG == 32
0015 
0016 /*
0017  * No traps on overflows for any of these...
0018  */
0019 
0020 #define do_div64_32(res, high, low, base) ({                \
0021     unsigned long __cf, __tmp, __tmp2, __i;             \
0022     unsigned long __quot32, __mod32;                \
0023                                     \
0024     __asm__(                            \
0025     "   .set    push                    \n" \
0026     "   .set    noat                    \n" \
0027     "   .set    noreorder               \n" \
0028     "   move    %2, $0                  \n" \
0029     "   move    %3, $0                  \n" \
0030     "   b   1f                  \n" \
0031     "    li %4, 0x21                \n" \
0032     "0:                         \n" \
0033     "   sll $1, %0, 0x1             \n" \
0034     "   srl %3, %0, 0x1f                \n" \
0035     "   or  %0, $1, %5              \n" \
0036     "   sll %1, %1, 0x1             \n" \
0037     "   sll %2, %2, 0x1             \n" \
0038     "1:                         \n" \
0039     "   bnez    %3, 2f                  \n" \
0040     "    sltu   %5, %0, %z6             \n" \
0041     "   bnez    %5, 3f                  \n" \
0042     "2:                         \n" \
0043     "    addiu  %4, %4, -1              \n" \
0044     "   subu    %0, %0, %z6             \n" \
0045     "   addiu   %2, %2, 1               \n" \
0046     "3:                         \n" \
0047     "   bnez    %4, 0b                  \n" \
0048     "    srl    %5, %1, 0x1f                \n" \
0049     "   .set    pop"                        \
0050     : "=&r" (__mod32), "=&r" (__tmp),               \
0051       "=&r" (__quot32), "=&r" (__cf),               \
0052       "=&r" (__i), "=&r" (__tmp2)                   \
0053     : "Jr" (base), "0" (high), "1" (low));              \
0054                                     \
0055     (res) = __quot32;                       \
0056     __mod32;                            \
0057 })
0058 
0059 #define __div64_32(n, base) ({                      \
0060     unsigned long __upper, __low, __high, __radix;          \
0061     unsigned long long __quot;                  \
0062     unsigned long long __div;                   \
0063     unsigned long __mod;                        \
0064                                     \
0065     __div = (*n);                           \
0066     __radix = (base);                       \
0067                                     \
0068     __high = __div >> 32;                       \
0069     __low = __div;                          \
0070                                     \
0071     if (__high < __radix) {                     \
0072         __upper = __high;                   \
0073         __high = 0;                     \
0074     } else {                            \
0075         __upper = __high % __radix;             \
0076         __high /= __radix;                  \
0077     }                               \
0078                                     \
0079     __mod = do_div64_32(__low, __upper, __low, __radix);        \
0080                                     \
0081     __quot = __high;                        \
0082     __quot = __quot << 32 | __low;                  \
0083     (*n) = __quot;                          \
0084     __mod;                              \
0085 })
0086 
0087 #endif /* BITS_PER_LONG == 32 */
0088 
0089 #include <asm-generic/div64.h>
0090 
0091 #endif /* __ASM_DIV64_H */