00001
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 #include "osdep.h"
00027
00028 #if defined(__x86_64__)
00029 #define __HAVE_FAST_MULU64__
00030 static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
00031 uint64_t a, uint64_t b)
00032 {
00033 __asm__ ("mul %0\n\t"
00034 : "=d" (*phigh), "=a" (*plow)
00035 : "a" (a), "0" (b));
00036 }
00037 #define __HAVE_FAST_MULS64__
00038 static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
00039 int64_t a, int64_t b)
00040 {
00041 __asm__ ("imul %0\n\t"
00042 : "=d" (*phigh), "=a" (*plow)
00043 : "a" (a), "0" (b));
00044 }
00045 #else
00046 void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
00047 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
00048 #endif
00049
00050
00051
00052 static always_inline int clz32(uint32_t val)
00053 {
00054 #if QEMU_GNUC_PREREQ(3, 4)
00055 if (val)
00056 return __builtin_clz(val);
00057 else
00058 return 32;
00059 #else
00060 int cnt = 0;
00061
00062 if (!(val & 0xFFFF0000U)) {
00063 cnt += 16;
00064 val <<= 16;
00065 }
00066 if (!(val & 0xFF000000U)) {
00067 cnt += 8;
00068 val <<= 8;
00069 }
00070 if (!(val & 0xF0000000U)) {
00071 cnt += 4;
00072 val <<= 4;
00073 }
00074 if (!(val & 0xC0000000U)) {
00075 cnt += 2;
00076 val <<= 2;
00077 }
00078 if (!(val & 0x80000000U)) {
00079 cnt++;
00080 val <<= 1;
00081 }
00082 if (!(val & 0x80000000U)) {
00083 cnt++;
00084 }
00085 return cnt;
00086 #endif
00087 }
00088
00089 static always_inline int clo32(uint32_t val)
00090 {
00091 return clz32(~val);
00092 }
00093
00094 static always_inline int clz64(uint64_t val)
00095 {
00096 #if QEMU_GNUC_PREREQ(3, 4)
00097 if (val)
00098 return __builtin_clzll(val);
00099 else
00100 return 64;
00101 #else
00102 int cnt = 0;
00103
00104 if (!(val >> 32)) {
00105 cnt += 32;
00106 } else {
00107 val >>= 32;
00108 }
00109
00110 return cnt + clz32(val);
00111 #endif
00112 }
00113
00114 static always_inline int clo64(uint64_t val)
00115 {
00116 return clz64(~val);
00117 }
00118
00119 static always_inline int ctz32(uint32_t val)
00120 {
00121 #if QEMU_GNUC_PREREQ(3, 4)
00122 if (val)
00123 return __builtin_ctz(val);
00124 else
00125 return 32;
00126 #else
00127 int cnt;
00128
00129 cnt = 0;
00130 if (!(val & 0x0000FFFFUL)) {
00131 cnt += 16;
00132 val >>= 16;
00133 }
00134 if (!(val & 0x000000FFUL)) {
00135 cnt += 8;
00136 val >>= 8;
00137 }
00138 if (!(val & 0x0000000FUL)) {
00139 cnt += 4;
00140 val >>= 4;
00141 }
00142 if (!(val & 0x00000003UL)) {
00143 cnt += 2;
00144 val >>= 2;
00145 }
00146 if (!(val & 0x00000001UL)) {
00147 cnt++;
00148 val >>= 1;
00149 }
00150 if (!(val & 0x00000001UL)) {
00151 cnt++;
00152 }
00153
00154 return cnt;
00155 #endif
00156 }
00157
00158 static always_inline int cto32(uint32_t val)
00159 {
00160 return ctz32(~val);
00161 }
00162
00163 static always_inline int ctz64(uint64_t val)
00164 {
00165 #if QEMU_GNUC_PREREQ(3, 4)
00166 if (val)
00167 return __builtin_ctz(val);
00168 else
00169 return 64;
00170 #else
00171 int cnt;
00172
00173 cnt = 0;
00174 if (!((uint32_t)val)) {
00175 cnt += 32;
00176 val >>= 32;
00177 }
00178
00179 return cnt + ctz32(val);
00180 #endif
00181 }
00182
00183 static always_inline int cto64(uint64_t val)
00184 {
00185 return ctz64(~val);
00186 }
00187
00188 static always_inline int ctpop8(uint8_t val)
00189 {
00190 val = (val & 0x55) + ((val >> 1) & 0x55);
00191 val = (val & 0x33) + ((val >> 2) & 0x33);
00192 val = (val & 0x0f) + ((val >> 4) & 0x0f);
00193
00194 return val;
00195 }
00196
00197 static always_inline int ctpop16(uint16_t val)
00198 {
00199 val = (val & 0x5555) + ((val >> 1) & 0x5555);
00200 val = (val & 0x3333) + ((val >> 2) & 0x3333);
00201 val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
00202 val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
00203
00204 return val;
00205 }
00206
00207 static always_inline int ctpop32(uint32_t val)
00208 {
00209 #if QEMU_GNUC_PREREQ(3, 4)
00210 return __builtin_popcount(val);
00211 #else
00212 val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
00213 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
00214 val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
00215 val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
00216 val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
00217
00218 return val;
00219 #endif
00220 }
00221
00222 static always_inline int ctpop64(uint64_t val)
00223 {
00224 #if QEMU_GNUC_PREREQ(3, 4)
00225 return __builtin_popcountll(val);
00226 #else
00227 val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
00228 val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
00229 val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
00230 val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
00231 val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
00232 val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
00233
00234 return val;
00235 #endif
00236 }