Statistics
| Branch: | Revision:

root / host-utils.h @ 05e1d830

History | View | Annotate | Download (5.1 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 7a51ad82 j_mayer
#if defined(__x86_64__)
27 7a51ad82 j_mayer
#define __HAVE_FAST_MULU64__
28 7a51ad82 j_mayer
static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
29 7a51ad82 j_mayer
                                  uint64_t a, uint64_t b)
30 7a51ad82 j_mayer
{
31 7a51ad82 j_mayer
    __asm__ ("mul %0\n\t"
32 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
33 7a51ad82 j_mayer
             : "a" (a), "0" (b));
34 7a51ad82 j_mayer
}
35 7a51ad82 j_mayer
#define __HAVE_FAST_MULS64__
36 7a51ad82 j_mayer
static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
37 7a51ad82 j_mayer
                                  int64_t a, int64_t b)
38 7a51ad82 j_mayer
{
39 7a51ad82 j_mayer
    __asm__ ("imul %0\n\t"
40 7a51ad82 j_mayer
             : "=d" (*phigh), "=a" (*plow)
41 7a51ad82 j_mayer
             : "a" (a), "0" (b));
42 7a51ad82 j_mayer
}
43 7a51ad82 j_mayer
#else
44 05e1d830 j_mayer
void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
45 7a51ad82 j_mayer
void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
46 7a51ad82 j_mayer
#endif
47 7a51ad82 j_mayer
48 05f778c8 ths
/* Note that some of those functions may end up calling libgcc functions,
49 05f778c8 ths
   depending on the host machine. It is up to the target emulation to
50 05f778c8 ths
   cope with that. */
51 05f778c8 ths
52 05f778c8 ths
/* Binary search for leading zeros.  */
53 05f778c8 ths
54 05f778c8 ths
static always_inline int clz32(uint32_t val)
55 05f778c8 ths
{
56 05f778c8 ths
    int cnt = 0;
57 05f778c8 ths
58 05f778c8 ths
    if (!(val & 0xFFFF0000U)) {
59 05f778c8 ths
        cnt += 16;
60 05f778c8 ths
        val <<= 16;
61 05f778c8 ths
    }
62 05f778c8 ths
    if (!(val & 0xFF000000U)) {
63 05f778c8 ths
        cnt += 8;
64 05f778c8 ths
        val <<= 8;
65 05f778c8 ths
    }
66 05f778c8 ths
    if (!(val & 0xF0000000U)) {
67 05f778c8 ths
        cnt += 4;
68 05f778c8 ths
        val <<= 4;
69 05f778c8 ths
    }
70 05f778c8 ths
    if (!(val & 0xC0000000U)) {
71 05f778c8 ths
        cnt += 2;
72 05f778c8 ths
        val <<= 2;
73 05f778c8 ths
    }
74 05f778c8 ths
    if (!(val & 0x80000000U)) {
75 05f778c8 ths
        cnt++;
76 05f778c8 ths
        val <<= 1;
77 05f778c8 ths
    }
78 05f778c8 ths
    if (!(val & 0x80000000U)) {
79 05f778c8 ths
        cnt++;
80 05f778c8 ths
    }
81 05f778c8 ths
    return cnt;
82 05f778c8 ths
}
83 05f778c8 ths
84 05f778c8 ths
static always_inline int clo32(uint32_t val)
85 05f778c8 ths
{
86 05f778c8 ths
    return clz32(~val);
87 05f778c8 ths
}
88 05f778c8 ths
89 05f778c8 ths
static always_inline int clz64(uint64_t val)
90 05f778c8 ths
{
91 05f778c8 ths
    int cnt = 0;
92 05f778c8 ths
93 7a51ad82 j_mayer
    if (!(val >> 32)) {
94 05f778c8 ths
        cnt += 32;
95 7a51ad82 j_mayer
    } else {
96 7a51ad82 j_mayer
        val >>= 32;
97 05f778c8 ths
    }
98 7a51ad82 j_mayer
99 7a51ad82 j_mayer
    return cnt + clz32(val);
100 05f778c8 ths
}
101 05f778c8 ths
102 05f778c8 ths
static always_inline int clo64(uint64_t val)
103 05f778c8 ths
{
104 05f778c8 ths
    return clz64(~val);
105 05f778c8 ths
}
106 b9ef45ff j_mayer
107 b9ef45ff j_mayer
static always_inline int ctz32 (uint32_t val)
108 b9ef45ff j_mayer
{
109 b9ef45ff j_mayer
    int cnt;
110 b9ef45ff j_mayer
111 b9ef45ff j_mayer
    cnt = 0;
112 b9ef45ff j_mayer
    if (!(val & 0x0000FFFFUL)) {
113 b9ef45ff j_mayer
         cnt += 16;
114 b9ef45ff j_mayer
        val >>= 16;
115 b9ef45ff j_mayer
     }
116 b9ef45ff j_mayer
    if (!(val & 0x000000FFUL)) {
117 b9ef45ff j_mayer
         cnt += 8;
118 b9ef45ff j_mayer
        val >>= 8;
119 b9ef45ff j_mayer
     }
120 b9ef45ff j_mayer
    if (!(val & 0x0000000FUL)) {
121 b9ef45ff j_mayer
         cnt += 4;
122 b9ef45ff j_mayer
        val >>= 4;
123 b9ef45ff j_mayer
     }
124 b9ef45ff j_mayer
    if (!(val & 0x00000003UL)) {
125 b9ef45ff j_mayer
         cnt += 2;
126 b9ef45ff j_mayer
        val >>= 2;
127 b9ef45ff j_mayer
     }
128 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
129 b9ef45ff j_mayer
         cnt++;
130 b9ef45ff j_mayer
        val >>= 1;
131 b9ef45ff j_mayer
     }
132 b9ef45ff j_mayer
    if (!(val & 0x00000001UL)) {
133 b9ef45ff j_mayer
         cnt++;
134 b9ef45ff j_mayer
     }
135 b9ef45ff j_mayer
136 b9ef45ff j_mayer
     return cnt;
137 b9ef45ff j_mayer
 }
138 b9ef45ff j_mayer
 
139 b9ef45ff j_mayer
static always_inline int cto32 (uint32_t val)
140 b9ef45ff j_mayer
 {
141 b9ef45ff j_mayer
    return ctz32(~val);
142 b9ef45ff j_mayer
}
143 b9ef45ff j_mayer
144 b9ef45ff j_mayer
static always_inline int ctz64 (uint64_t val)
145 b9ef45ff j_mayer
{
146 b9ef45ff j_mayer
    int cnt;
147 b9ef45ff j_mayer
148 b9ef45ff j_mayer
    cnt = 0;
149 b9ef45ff j_mayer
    if (!((uint32_t)val)) {
150 b9ef45ff j_mayer
        cnt += 32;
151 b9ef45ff j_mayer
        val >>= 32;
152 b9ef45ff j_mayer
    }
153 b9ef45ff j_mayer
154 b9ef45ff j_mayer
    return cnt + ctz32(val);
155 b9ef45ff j_mayer
}
156 b9ef45ff j_mayer
157 b9ef45ff j_mayer
static always_inline int cto64 (uint64_t val)
158 b9ef45ff j_mayer
{
159 b9ef45ff j_mayer
    return ctz64(~val);
160 b9ef45ff j_mayer
}
161 b9ef45ff j_mayer
162 b9ef45ff j_mayer
static always_inline int ctpop8 (uint8_t val)
163 b9ef45ff j_mayer
{
164 b9ef45ff j_mayer
    val = (val & 0x55) + ((val >> 1) & 0x55);
165 b9ef45ff j_mayer
    val = (val & 0x33) + ((val >> 2) & 0x33);
166 b9ef45ff j_mayer
    val = (val & 0x0f) + ((val >> 4) & 0x0f);
167 b9ef45ff j_mayer
168 b9ef45ff j_mayer
    return val;
169 b9ef45ff j_mayer
}
170 b9ef45ff j_mayer
171 b9ef45ff j_mayer
static always_inline int ctpop16 (uint16_t val)
172 b9ef45ff j_mayer
{
173 b9ef45ff j_mayer
    val = (val & 0x5555) + ((val >> 1) & 0x5555);
174 b9ef45ff j_mayer
    val = (val & 0x3333) + ((val >> 2) & 0x3333);
175 b9ef45ff j_mayer
    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
176 b9ef45ff j_mayer
    val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
177 b9ef45ff j_mayer
178 b9ef45ff j_mayer
    return val;
179 b9ef45ff j_mayer
}
180 b9ef45ff j_mayer
181 b9ef45ff j_mayer
static always_inline int ctpop32 (uint32_t val)
182 b9ef45ff j_mayer
{
183 b9ef45ff j_mayer
    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
184 b9ef45ff j_mayer
    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
185 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
186 b9ef45ff j_mayer
    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
187 b9ef45ff j_mayer
    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
188 b9ef45ff j_mayer
189 b9ef45ff j_mayer
    return val;
190 b9ef45ff j_mayer
}
191 b9ef45ff j_mayer
192 b9ef45ff j_mayer
static always_inline int ctpop64 (uint64_t val)
193 b9ef45ff j_mayer
{
194 b9ef45ff j_mayer
    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
195 b9ef45ff j_mayer
    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
196 b9ef45ff j_mayer
    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
197 b9ef45ff j_mayer
    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL);
198 b9ef45ff j_mayer
    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
199 b9ef45ff j_mayer
    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
200 b9ef45ff j_mayer
201 b9ef45ff j_mayer
    return val;
202 b9ef45ff j_mayer
 }