Statistics
| Branch: | Revision:

root / host-utils.h @ 80210bcd

History | View | Annotate | Download (4.9 kB)

1
/*
2
 * Utility compute operations used by translated code.
3
 *
4
 * Copyright (c) 2007 Thiemo Seufer
5
 * Copyright (c) 2007 Jocelyn Mayer
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25

    
26
/* Note that some of those functions may end up calling libgcc functions,
27
   depending on the host machine. It is up to the target emulation to
28
   cope with that. */
29

    
30
/* Binary search for leading zeros.  */
31

    
32
static always_inline int clz32(uint32_t val)
33
{
34
    int cnt = 0;
35

    
36
    if (!(val & 0xFFFF0000U)) {
37
        cnt += 16;
38
        val <<= 16;
39
    }
40
    if (!(val & 0xFF000000U)) {
41
        cnt += 8;
42
        val <<= 8;
43
    }
44
    if (!(val & 0xF0000000U)) {
45
        cnt += 4;
46
        val <<= 4;
47
    }
48
    if (!(val & 0xC0000000U)) {
49
        cnt += 2;
50
        val <<= 2;
51
    }
52
    if (!(val & 0x80000000U)) {
53
        cnt++;
54
        val <<= 1;
55
    }
56
    if (!(val & 0x80000000U)) {
57
        cnt++;
58
    }
59
    return cnt;
60
}
61

    
62
static always_inline int clo32(uint32_t val)
63
{
64
    return clz32(~val);
65
}
66

    
67
static always_inline int clz64(uint64_t val)
68
{
69
    int cnt = 0;
70

    
71
    if (!(val & 0xFFFFFFFF00000000ULL)) {
72
        cnt += 32;
73
        val <<= 32;
74
    }
75
    if (!(val & 0xFFFF000000000000ULL)) {
76
        cnt += 16;
77
        val <<= 16;
78
    }
79
    if (!(val & 0xFF00000000000000ULL)) {
80
        cnt += 8;
81
        val <<= 8;
82
    }
83
    if (!(val & 0xF000000000000000ULL)) {
84
        cnt += 4;
85
        val <<= 4;
86
    }
87
    if (!(val & 0xC000000000000000ULL)) {
88
        cnt += 2;
89
        val <<= 2;
90
    }
91
    if (!(val & 0x8000000000000000ULL)) {
92
        cnt++;
93
        val <<= 1;
94
    }
95
    if (!(val & 0x8000000000000000ULL)) {
96
        cnt++;
97
    }
98
    return cnt;
99
}
100

    
101
static always_inline int clo64(uint64_t val)
102
{
103
    return clz64(~val);
104
}
105

    
106
static always_inline int ctz32 (uint32_t val)
107
{
108
    int cnt;
109

    
110
    cnt = 0;
111
    if (!(val & 0x0000FFFFUL)) {
112
         cnt += 16;
113
        val >>= 16;
114
     }
115
    if (!(val & 0x000000FFUL)) {
116
         cnt += 8;
117
        val >>= 8;
118
     }
119
    if (!(val & 0x0000000FUL)) {
120
         cnt += 4;
121
        val >>= 4;
122
     }
123
    if (!(val & 0x00000003UL)) {
124
         cnt += 2;
125
        val >>= 2;
126
     }
127
    if (!(val & 0x00000001UL)) {
128
         cnt++;
129
        val >>= 1;
130
     }
131
    if (!(val & 0x00000001UL)) {
132
         cnt++;
133
     }
134

    
135
     return cnt;
136
 }
137
 
138
static always_inline int cto32 (uint32_t val)
139
 {
140
    return ctz32(~val);
141
}
142

    
143
static always_inline int ctz64 (uint64_t val)
144
{
145
    int cnt;
146

    
147
    cnt = 0;
148
    if (!((uint32_t)val)) {
149
        cnt += 32;
150
        val >>= 32;
151
    }
152

    
153
    return cnt + ctz32(val);
154
}
155

    
156
static always_inline int cto64 (uint64_t val)
157
{
158
    return ctz64(~val);
159
}
160

    
161
static always_inline int ctpop8 (uint8_t val)
162
{
163
    val = (val & 0x55) + ((val >> 1) & 0x55);
164
    val = (val & 0x33) + ((val >> 2) & 0x33);
165
    val = (val & 0x0f) + ((val >> 4) & 0x0f);
166

    
167
    return val;
168
}
169

    
170
static always_inline int ctpop16 (uint16_t val)
171
{
172
    val = (val & 0x5555) + ((val >> 1) & 0x5555);
173
    val = (val & 0x3333) + ((val >> 2) & 0x3333);
174
    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
175
    val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
176

    
177
    return val;
178
}
179

    
180
static always_inline int ctpop32 (uint32_t val)
181
{
182
    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
183
    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
184
    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
185
    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
186
    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
187

    
188
    return val;
189
}
190

    
191
static always_inline int ctpop64 (uint64_t val)
192
{
193
    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
194
    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
195
    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
196
    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL);
197
    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
198
    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
199

    
200
    return val;
201
 }