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