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