00001 #include <stdint.h>
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 static inline uint32_t
00027 divl (uint64_t n, uint32_t d)
00028 {
00029 uint32_t n1 = n >> 32;
00030 uint32_t n0 = n;
00031 uint32_t q, r;
00032
00033 asm ("divl %4"
00034 : "=d" (r), "=a" (q)
00035 : "0" (n1), "1" (n0), "rm" (d));
00036
00037 return q;
00038 }
00039
00040
00041
00042 static int
00043 nlz (uint32_t x)
00044 {
00045
00046
00047
00048
00049
00050 int n = 0;
00051 if (x <= 0x0000FFFF)
00052 {
00053 n += 16;
00054 x <<= 16;
00055 }
00056 if (x <= 0x00FFFFFF)
00057 {
00058 n += 8;
00059 x <<= 8;
00060 }
00061 if (x <= 0x0FFFFFFF)
00062 {
00063 n += 4;
00064 x <<= 4;
00065 }
00066 if (x <= 0x3FFFFFFF)
00067 {
00068 n += 2;
00069 x <<= 2;
00070 }
00071 if (x <= 0x7FFFFFFF)
00072 n++;
00073 return n;
00074 }
00075
00076
00077
00078 static uint64_t
00079 udiv64 (uint64_t n, uint64_t d)
00080 {
00081 if ((d >> 32) == 0)
00082 {
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 uint64_t b = 1ULL << 32;
00108 uint32_t n1 = n >> 32;
00109 uint32_t n0 = n;
00110 uint32_t d0 = d;
00111
00112 return divl (b * (n1 % d0) + n0, d0) + b * (n1 / d0);
00113 }
00114 else
00115 {
00116
00117
00118 if (n < d)
00119 return 0;
00120 else
00121 {
00122 uint32_t d1 = d >> 32;
00123 int s = nlz (d1);
00124 uint64_t q = divl (n >> 1, (d << s) >> 32) >> (31 - s);
00125 return n - (q - 1) * d < d ? q - 1 : q;
00126 }
00127 }
00128 }
00129
00130
00131
00132 static uint32_t
00133 umod64 (uint64_t n, uint64_t d)
00134 {
00135 return n - d * udiv64 (n, d);
00136 }
00137
00138
00139
00140 static int64_t
00141 sdiv64 (int64_t n, int64_t d)
00142 {
00143 uint64_t n_abs = n >= 0 ? (uint64_t) n : -(uint64_t) n;
00144 uint64_t d_abs = d >= 0 ? (uint64_t) d : -(uint64_t) d;
00145 uint64_t q_abs = udiv64 (n_abs, d_abs);
00146 return (n < 0) == (d < 0) ? (int64_t) q_abs : -(int64_t) q_abs;
00147 }
00148
00149
00150
00151 static int32_t
00152 smod64 (int64_t n, int64_t d)
00153 {
00154 return n - d * sdiv64 (n, d);
00155 }
00156
00157
00158
00159 long long __divdi3 (long long n, long long d);
00160 long long __moddi3 (long long n, long long d);
00161 unsigned long long __udivdi3 (unsigned long long n, unsigned long long d);
00162 unsigned long long __umoddi3 (unsigned long long n, unsigned long long d);
00163
00164
00165 long long
00166 __divdi3 (long long n, long long d)
00167 {
00168 return sdiv64 (n, d);
00169 }
00170
00171
00172 long long
00173 __moddi3 (long long n, long long d)
00174 {
00175 return smod64 (n, d);
00176 }
00177
00178
00179 unsigned long long
00180 __udivdi3 (unsigned long long n, unsigned long long d)
00181 {
00182 return udiv64 (n, d);
00183 }
00184
00185
00186 unsigned long long
00187 __umoddi3 (unsigned long long n, unsigned long long d)
00188 {
00189 return umod64 (n, d);
00190 }