Statistics
| Branch: | Revision:

root / host-utils.h @ a74cdab4

History | View | Annotate | Download (5.4 kB)

1 05f778c8 ths
/*
2 05f778c8 ths
 * Utility compute operations used by translated code.
3 05f778c8 ths
 *
4 05f778c8 ths
 * Copyright (c) 2007 Thiemo Seufer
5 05f778c8 ths
 * Copyright (c) 2007 Jocelyn Mayer
6 05f778c8 ths
 *
7 05f778c8 ths
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 05f778c8 ths
 * of this software and associated documentation files (the "Software"), to deal
9 05f778c8 ths
 * in the Software without restriction, including without limitation the rights
10 05f778c8 ths
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 05f778c8 ths
 * copies of the Software, and to permit persons to whom the Software is
12 05f778c8 ths
 * furnished to do so, subject to the following conditions:
13 05f778c8 ths
 *
14 05f778c8 ths
 * The above copyright notice and this permission notice shall be included in
15 05f778c8 ths
 * all copies or substantial portions of the Software.
16 05f778c8 ths
 *
17 05f778c8 ths
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 05f778c8 ths
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 05f778c8 ths
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 05f778c8 ths
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 05f778c8 ths
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 05f778c8 ths
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 05f778c8 ths
 * THE SOFTWARE.
24 05f778c8 ths
 */
25 05f778c8 ths
26 cebdff77 ths
#include "osdep.h"
27 cebdff77 ths
28 7a51ad82 j_mayer
#if defined(__x86_64__)
29 7a51ad82 j_mayer
#define __HAVE_FAST_MULU64__
30 facd2857 Blue Swirl
static inline void mulu64(uint64_t *plow, uint64_t *phigh,
31 facd2857 Blue Swirl
                          uint64_t a, uint64_t b)
32 7a51ad82 j_mayer
{
33 7a51ad82 j_mayer
    __asm__ ("mul %0\n\t"
34 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
35 7a51ad82 j_mayer
             : "a" (a), "0" (b));
36 7a51ad82 j_mayer
}
37 7a51ad82 j_mayer
#define __HAVE_FAST_MULS64__
38 facd2857 Blue Swirl
static inline void muls64(uint64_t *plow, uint64_t *phigh,
39 facd2857 Blue Swirl
                          int64_t a, int64_t b)
40 7a51ad82 j_mayer
{
41 7a51ad82 j_mayer
    __asm__ ("imul %0\n\t"
42 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
43 7a51ad82 j_mayer
             : "a" (a), "0" (b));
44 7a51ad82 j_mayer
}
45 7a51ad82 j_mayer
#else
46 05e1d830 j_mayer
void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
47 7a51ad82 j_mayer
void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
48 7a51ad82 j_mayer
#endif
49 7a51ad82 j_mayer
50 05f778c8 ths
/* Binary search for leading zeros.  */
51 05f778c8 ths
52 facd2857 Blue Swirl
static inline int clz32(uint32_t val)
53 05f778c8 ths
{
54 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
55 7d019980 aurel32
    if (val)
56 7d019980 aurel32
        return __builtin_clz(val);
57 7d019980 aurel32
    else
58 7d019980 aurel32
        return 32;
59 7d019980 aurel32
#else
60 05f778c8 ths
    int cnt = 0;
61 05f778c8 ths
62 05f778c8 ths
    if (!(val & 0xFFFF0000U)) {
63 05f778c8 ths
        cnt += 16;
64 05f778c8 ths
        val <<= 16;
65 05f778c8 ths
    }
66 05f778c8 ths
    if (!(val & 0xFF000000U)) {
67 05f778c8 ths
        cnt += 8;
68 05f778c8 ths
        val <<= 8;
69 05f778c8 ths
    }
70 05f778c8 ths
    if (!(val & 0xF0000000U)) {
71 05f778c8 ths
        cnt += 4;
72 05f778c8 ths
        val <<= 4;
73 05f778c8 ths
    }
74 05f778c8 ths
    if (!(val & 0xC0000000U)) {
75 05f778c8 ths
        cnt += 2;
76 05f778c8 ths
        val <<= 2;
77 05f778c8 ths
    }
78 05f778c8 ths
    if (!(val & 0x80000000U)) {
79 05f778c8 ths
        cnt++;
80 05f778c8 ths
        val <<= 1;
81 05f778c8 ths
    }
82 05f778c8 ths
    if (!(val & 0x80000000U)) {
83 05f778c8 ths
        cnt++;
84 05f778c8 ths
    }
85 05f778c8 ths
    return cnt;
86 7d019980 aurel32
#endif
87 05f778c8 ths
}
88 05f778c8 ths
89 facd2857 Blue Swirl
static inline int clo32(uint32_t val)
90 05f778c8 ths
{
91 05f778c8 ths
    return clz32(~val);
92 05f778c8 ths
}
93 05f778c8 ths
94 facd2857 Blue Swirl
static inline int clz64(uint64_t val)
95 05f778c8 ths
{
96 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
97 7d019980 aurel32
    if (val)
98 7d019980 aurel32
        return __builtin_clzll(val);
99 7d019980 aurel32
    else
100 7d019980 aurel32
        return 64;
101 7d019980 aurel32
#else
102 05f778c8 ths
    int cnt = 0;
103 05f778c8 ths
104 7a51ad82 j_mayer
    if (!(val >> 32)) {
105 05f778c8 ths
        cnt += 32;
106 7a51ad82 j_mayer
    } else {
107 7a51ad82 j_mayer
        val >>= 32;
108 05f778c8 ths
    }
109 7a51ad82 j_mayer
110 7a51ad82 j_mayer
    return cnt + clz32(val);
111 7d019980 aurel32
#endif
112 05f778c8 ths
}
113 05f778c8 ths
114 facd2857 Blue Swirl
static inline int clo64(uint64_t val)
115 05f778c8 ths
{
116 05f778c8 ths
    return clz64(~val);
117 05f778c8 ths
}
118 b9ef45ff j_mayer
119 facd2857 Blue Swirl
static inline int ctz32(uint32_t val)
120 b9ef45ff j_mayer
{
121 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
122 7d019980 aurel32
    if (val)
123 7d019980 aurel32
        return __builtin_ctz(val);
124 7d019980 aurel32
    else
125 7d019980 aurel32
        return 32;
126 7d019980 aurel32
#else
127 b9ef45ff j_mayer
    int cnt;
128 b9ef45ff j_mayer
129 b9ef45ff j_mayer
    cnt = 0;
130 b9ef45ff j_mayer
    if (!(val & 0x0000FFFFUL)) {
131 c8906845 balrog
        cnt += 16;
132 b9ef45ff j_mayer
        val >>= 16;
133 c8906845 balrog
    }
134 b9ef45ff j_mayer
    if (!(val & 0x000000FFUL)) {
135 c8906845 balrog
        cnt += 8;
136 b9ef45ff j_mayer
        val >>= 8;
137 c8906845 balrog
    }
138 b9ef45ff j_mayer
    if (!(val & 0x0000000FUL)) {
139 c8906845 balrog
        cnt += 4;
140 b9ef45ff j_mayer
        val >>= 4;
141 c8906845 balrog
    }
142 b9ef45ff j_mayer
    if (!(val & 0x00000003UL)) {
143 c8906845 balrog
        cnt += 2;
144 b9ef45ff j_mayer
        val >>= 2;
145 c8906845 balrog
    }
146 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
147 c8906845 balrog
        cnt++;
148 b9ef45ff j_mayer
        val >>= 1;
149 c8906845 balrog
    }
150 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
151 c8906845 balrog
        cnt++;
152 c8906845 balrog
    }
153 b9ef45ff j_mayer
154 c8906845 balrog
    return cnt;
155 7d019980 aurel32
#endif
156 c8906845 balrog
}
157 c8906845 balrog
158 facd2857 Blue Swirl
static inline int cto32(uint32_t val)
159 c8906845 balrog
{
160 b9ef45ff j_mayer
    return ctz32(~val);
161 b9ef45ff j_mayer
}
162 b9ef45ff j_mayer
163 facd2857 Blue Swirl
static inline int ctz64(uint64_t val)
164 b9ef45ff j_mayer
{
165 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
166 7d019980 aurel32
    if (val)
167 06445248 Richard Henderson
        return __builtin_ctzll(val);
168 7d019980 aurel32
    else
169 7d019980 aurel32
        return 64;
170 7d019980 aurel32
#else
171 b9ef45ff j_mayer
    int cnt;
172 b9ef45ff j_mayer
173 b9ef45ff j_mayer
    cnt = 0;
174 b9ef45ff j_mayer
    if (!((uint32_t)val)) {
175 b9ef45ff j_mayer
        cnt += 32;
176 b9ef45ff j_mayer
        val >>= 32;
177 b9ef45ff j_mayer
    }
178 b9ef45ff j_mayer
179 b9ef45ff j_mayer
    return cnt + ctz32(val);
180 7d019980 aurel32
#endif
181 b9ef45ff j_mayer
}
182 b9ef45ff j_mayer
183 facd2857 Blue Swirl
static inline int cto64(uint64_t val)
184 b9ef45ff j_mayer
{
185 b9ef45ff j_mayer
    return ctz64(~val);
186 b9ef45ff j_mayer
}
187 b9ef45ff j_mayer
188 facd2857 Blue Swirl
static inline int ctpop8(uint8_t val)
189 b9ef45ff j_mayer
{
190 b9ef45ff j_mayer
    val = (val & 0x55) + ((val >> 1) & 0x55);
191 b9ef45ff j_mayer
    val = (val & 0x33) + ((val >> 2) & 0x33);
192 b9ef45ff j_mayer
    val = (val & 0x0f) + ((val >> 4) & 0x0f);
193 b9ef45ff j_mayer
194 b9ef45ff j_mayer
    return val;
195 b9ef45ff j_mayer
}
196 b9ef45ff j_mayer
197 facd2857 Blue Swirl
static inline int ctpop16(uint16_t val)
198 b9ef45ff j_mayer
{
199 b9ef45ff j_mayer
    val = (val & 0x5555) + ((val >> 1) & 0x5555);
200 b9ef45ff j_mayer
    val = (val & 0x3333) + ((val >> 2) & 0x3333);
201 b9ef45ff j_mayer
    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
202 b9ef45ff j_mayer
    val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
203 b9ef45ff j_mayer
204 b9ef45ff j_mayer
    return val;
205 b9ef45ff j_mayer
}
206 b9ef45ff j_mayer
207 facd2857 Blue Swirl
static inline int ctpop32(uint32_t val)
208 b9ef45ff j_mayer
{
209 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
210 7d019980 aurel32
    return __builtin_popcount(val);
211 7d019980 aurel32
#else
212 b9ef45ff j_mayer
    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
213 b9ef45ff j_mayer
    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
214 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
215 b9ef45ff j_mayer
    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
216 b9ef45ff j_mayer
    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
217 b9ef45ff j_mayer
218 b9ef45ff j_mayer
    return val;
219 7d019980 aurel32
#endif
220 b9ef45ff j_mayer
}
221 b9ef45ff j_mayer
222 facd2857 Blue Swirl
static inline int ctpop64(uint64_t val)
223 b9ef45ff j_mayer
{
224 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
225 7d019980 aurel32
    return __builtin_popcountll(val);
226 7d019980 aurel32
#else
227 b9ef45ff j_mayer
    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
228 b9ef45ff j_mayer
    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
229 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
230 b9ef45ff j_mayer
    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL);
231 b9ef45ff j_mayer
    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
232 b9ef45ff j_mayer
    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
233 b9ef45ff j_mayer
234 b9ef45ff j_mayer
    return val;
235 7d019980 aurel32
#endif
236 3800af9e ths
}