Statistics
| Branch: | Revision:

root / host-utils.h @ 8c5e95d8

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