Statistics
| Branch: | Revision:

root / host-utils.h @ cb9c377f

History | View | Annotate | Download (5.5 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 cb9c377f Paolo Bonzini
#ifndef HOST_UTILS_H
26 cb9c377f Paolo Bonzini
#define HOST_UTILS_H 1
27 05f778c8 ths
28 f8b72754 Stefan Weil
#include "compiler.h"   /* QEMU_GNUC_PREREQ */
29 cebdff77 ths
30 7a51ad82 j_mayer
#if defined(__x86_64__)
31 7a51ad82 j_mayer
#define __HAVE_FAST_MULU64__
32 facd2857 Blue Swirl
static inline void mulu64(uint64_t *plow, uint64_t *phigh,
33 facd2857 Blue Swirl
                          uint64_t a, uint64_t b)
34 7a51ad82 j_mayer
{
35 7a51ad82 j_mayer
    __asm__ ("mul %0\n\t"
36 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
37 7a51ad82 j_mayer
             : "a" (a), "0" (b));
38 7a51ad82 j_mayer
}
39 7a51ad82 j_mayer
#define __HAVE_FAST_MULS64__
40 facd2857 Blue Swirl
static inline void muls64(uint64_t *plow, uint64_t *phigh,
41 facd2857 Blue Swirl
                          int64_t a, int64_t b)
42 7a51ad82 j_mayer
{
43 7a51ad82 j_mayer
    __asm__ ("imul %0\n\t"
44 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
45 7a51ad82 j_mayer
             : "a" (a), "0" (b));
46 7a51ad82 j_mayer
}
47 7a51ad82 j_mayer
#else
48 05e1d830 j_mayer
void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
49 7a51ad82 j_mayer
void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
50 7a51ad82 j_mayer
#endif
51 7a51ad82 j_mayer
52 05f778c8 ths
/* Binary search for leading zeros.  */
53 05f778c8 ths
54 facd2857 Blue Swirl
static inline int clz32(uint32_t val)
55 05f778c8 ths
{
56 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
57 7d019980 aurel32
    if (val)
58 7d019980 aurel32
        return __builtin_clz(val);
59 7d019980 aurel32
    else
60 7d019980 aurel32
        return 32;
61 7d019980 aurel32
#else
62 05f778c8 ths
    int cnt = 0;
63 05f778c8 ths
64 05f778c8 ths
    if (!(val & 0xFFFF0000U)) {
65 05f778c8 ths
        cnt += 16;
66 05f778c8 ths
        val <<= 16;
67 05f778c8 ths
    }
68 05f778c8 ths
    if (!(val & 0xFF000000U)) {
69 05f778c8 ths
        cnt += 8;
70 05f778c8 ths
        val <<= 8;
71 05f778c8 ths
    }
72 05f778c8 ths
    if (!(val & 0xF0000000U)) {
73 05f778c8 ths
        cnt += 4;
74 05f778c8 ths
        val <<= 4;
75 05f778c8 ths
    }
76 05f778c8 ths
    if (!(val & 0xC0000000U)) {
77 05f778c8 ths
        cnt += 2;
78 05f778c8 ths
        val <<= 2;
79 05f778c8 ths
    }
80 05f778c8 ths
    if (!(val & 0x80000000U)) {
81 05f778c8 ths
        cnt++;
82 05f778c8 ths
        val <<= 1;
83 05f778c8 ths
    }
84 05f778c8 ths
    if (!(val & 0x80000000U)) {
85 05f778c8 ths
        cnt++;
86 05f778c8 ths
    }
87 05f778c8 ths
    return cnt;
88 7d019980 aurel32
#endif
89 05f778c8 ths
}
90 05f778c8 ths
91 facd2857 Blue Swirl
static inline int clo32(uint32_t val)
92 05f778c8 ths
{
93 05f778c8 ths
    return clz32(~val);
94 05f778c8 ths
}
95 05f778c8 ths
96 facd2857 Blue Swirl
static inline int clz64(uint64_t val)
97 05f778c8 ths
{
98 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
99 7d019980 aurel32
    if (val)
100 7d019980 aurel32
        return __builtin_clzll(val);
101 7d019980 aurel32
    else
102 7d019980 aurel32
        return 64;
103 7d019980 aurel32
#else
104 05f778c8 ths
    int cnt = 0;
105 05f778c8 ths
106 7a51ad82 j_mayer
    if (!(val >> 32)) {
107 05f778c8 ths
        cnt += 32;
108 7a51ad82 j_mayer
    } else {
109 7a51ad82 j_mayer
        val >>= 32;
110 05f778c8 ths
    }
111 7a51ad82 j_mayer
112 7a51ad82 j_mayer
    return cnt + clz32(val);
113 7d019980 aurel32
#endif
114 05f778c8 ths
}
115 05f778c8 ths
116 facd2857 Blue Swirl
static inline int clo64(uint64_t val)
117 05f778c8 ths
{
118 05f778c8 ths
    return clz64(~val);
119 05f778c8 ths
}
120 b9ef45ff j_mayer
121 facd2857 Blue Swirl
static inline int ctz32(uint32_t val)
122 b9ef45ff j_mayer
{
123 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
124 7d019980 aurel32
    if (val)
125 7d019980 aurel32
        return __builtin_ctz(val);
126 7d019980 aurel32
    else
127 7d019980 aurel32
        return 32;
128 7d019980 aurel32
#else
129 b9ef45ff j_mayer
    int cnt;
130 b9ef45ff j_mayer
131 b9ef45ff j_mayer
    cnt = 0;
132 b9ef45ff j_mayer
    if (!(val & 0x0000FFFFUL)) {
133 c8906845 balrog
        cnt += 16;
134 b9ef45ff j_mayer
        val >>= 16;
135 c8906845 balrog
    }
136 b9ef45ff j_mayer
    if (!(val & 0x000000FFUL)) {
137 c8906845 balrog
        cnt += 8;
138 b9ef45ff j_mayer
        val >>= 8;
139 c8906845 balrog
    }
140 b9ef45ff j_mayer
    if (!(val & 0x0000000FUL)) {
141 c8906845 balrog
        cnt += 4;
142 b9ef45ff j_mayer
        val >>= 4;
143 c8906845 balrog
    }
144 b9ef45ff j_mayer
    if (!(val & 0x00000003UL)) {
145 c8906845 balrog
        cnt += 2;
146 b9ef45ff j_mayer
        val >>= 2;
147 c8906845 balrog
    }
148 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
149 c8906845 balrog
        cnt++;
150 b9ef45ff j_mayer
        val >>= 1;
151 c8906845 balrog
    }
152 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
153 c8906845 balrog
        cnt++;
154 c8906845 balrog
    }
155 b9ef45ff j_mayer
156 c8906845 balrog
    return cnt;
157 7d019980 aurel32
#endif
158 c8906845 balrog
}
159 c8906845 balrog
160 facd2857 Blue Swirl
static inline int cto32(uint32_t val)
161 c8906845 balrog
{
162 b9ef45ff j_mayer
    return ctz32(~val);
163 b9ef45ff j_mayer
}
164 b9ef45ff j_mayer
165 facd2857 Blue Swirl
static inline int ctz64(uint64_t val)
166 b9ef45ff j_mayer
{
167 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
168 7d019980 aurel32
    if (val)
169 06445248 Richard Henderson
        return __builtin_ctzll(val);
170 7d019980 aurel32
    else
171 7d019980 aurel32
        return 64;
172 7d019980 aurel32
#else
173 b9ef45ff j_mayer
    int cnt;
174 b9ef45ff j_mayer
175 b9ef45ff j_mayer
    cnt = 0;
176 b9ef45ff j_mayer
    if (!((uint32_t)val)) {
177 b9ef45ff j_mayer
        cnt += 32;
178 b9ef45ff j_mayer
        val >>= 32;
179 b9ef45ff j_mayer
    }
180 b9ef45ff j_mayer
181 b9ef45ff j_mayer
    return cnt + ctz32(val);
182 7d019980 aurel32
#endif
183 b9ef45ff j_mayer
}
184 b9ef45ff j_mayer
185 facd2857 Blue Swirl
static inline int cto64(uint64_t val)
186 b9ef45ff j_mayer
{
187 b9ef45ff j_mayer
    return ctz64(~val);
188 b9ef45ff j_mayer
}
189 b9ef45ff j_mayer
190 facd2857 Blue Swirl
static inline int ctpop8(uint8_t val)
191 b9ef45ff j_mayer
{
192 b9ef45ff j_mayer
    val = (val & 0x55) + ((val >> 1) & 0x55);
193 b9ef45ff j_mayer
    val = (val & 0x33) + ((val >> 2) & 0x33);
194 b9ef45ff j_mayer
    val = (val & 0x0f) + ((val >> 4) & 0x0f);
195 b9ef45ff j_mayer
196 b9ef45ff j_mayer
    return val;
197 b9ef45ff j_mayer
}
198 b9ef45ff j_mayer
199 facd2857 Blue Swirl
static inline int ctpop16(uint16_t val)
200 b9ef45ff j_mayer
{
201 b9ef45ff j_mayer
    val = (val & 0x5555) + ((val >> 1) & 0x5555);
202 b9ef45ff j_mayer
    val = (val & 0x3333) + ((val >> 2) & 0x3333);
203 b9ef45ff j_mayer
    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
204 b9ef45ff j_mayer
    val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
205 b9ef45ff j_mayer
206 b9ef45ff j_mayer
    return val;
207 b9ef45ff j_mayer
}
208 b9ef45ff j_mayer
209 facd2857 Blue Swirl
static inline int ctpop32(uint32_t val)
210 b9ef45ff j_mayer
{
211 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
212 7d019980 aurel32
    return __builtin_popcount(val);
213 7d019980 aurel32
#else
214 b9ef45ff j_mayer
    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
215 b9ef45ff j_mayer
    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
216 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
217 b9ef45ff j_mayer
    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
218 b9ef45ff j_mayer
    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
219 b9ef45ff j_mayer
220 b9ef45ff j_mayer
    return val;
221 7d019980 aurel32
#endif
222 b9ef45ff j_mayer
}
223 b9ef45ff j_mayer
224 facd2857 Blue Swirl
static inline int ctpop64(uint64_t val)
225 b9ef45ff j_mayer
{
226 bad5b1ec aurel32
#if QEMU_GNUC_PREREQ(3, 4)
227 7d019980 aurel32
    return __builtin_popcountll(val);
228 7d019980 aurel32
#else
229 b9ef45ff j_mayer
    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
230 b9ef45ff j_mayer
    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
231 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
232 b9ef45ff j_mayer
    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL);
233 b9ef45ff j_mayer
    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
234 b9ef45ff j_mayer
    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
235 b9ef45ff j_mayer
236 b9ef45ff j_mayer
    return val;
237 7d019980 aurel32
#endif
238 3800af9e ths
}
239 cb9c377f Paolo Bonzini
240 cb9c377f Paolo Bonzini
#endif