Commit 7d01998021e38363d53bc93f198023a05d8a52bf

Authored by aurel32
1 parent bc7b5f87

Optimize some host-utils function with gcc builtins

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5464 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 36 additions and 4 deletions
host-utils.h
... ... @@ -47,14 +47,16 @@ void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
47 47 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
48 48 #endif
49 49  
50   -/* Note that some of those functions may end up calling libgcc functions,
51   - depending on the host machine. It is up to the target emulation to
52   - cope with that. */
53   -
54 50 /* Binary search for leading zeros. */
55 51  
56 52 static always_inline int clz32(uint32_t val)
57 53 {
  54 +#if defined(__GNUC__)
  55 + if (val)
  56 + return __builtin_clz(val);
  57 + else
  58 + return 32;
  59 +#else
58 60 int cnt = 0;
59 61  
60 62 if (!(val & 0xFFFF0000U)) {
... ... @@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val)
81 83 cnt++;
82 84 }
83 85 return cnt;
  86 +#endif
84 87 }
85 88  
86 89 static always_inline int clo32(uint32_t val)
... ... @@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val)
90 93  
91 94 static always_inline int clz64(uint64_t val)
92 95 {
  96 +#if defined(__GNUC__)
  97 + if (val)
  98 + return __builtin_clzll(val);
  99 + else
  100 + return 64;
  101 +#else
93 102 int cnt = 0;
94 103  
95 104 if (!(val >> 32)) {
... ... @@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val)
99 108 }
100 109  
101 110 return cnt + clz32(val);
  111 +#endif
102 112 }
103 113  
104 114 static always_inline int clo64(uint64_t val)
... ... @@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val)
108 118  
109 119 static always_inline int ctz32 (uint32_t val)
110 120 {
  121 +#if defined(__GNUC__)
  122 + if (val)
  123 + return __builtin_ctz(val);
  124 + else
  125 + return 32;
  126 +#else
111 127 int cnt;
112 128  
113 129 cnt = 0;
... ... @@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val)
136 152 }
137 153  
138 154 return cnt;
  155 +#endif
139 156 }
140 157  
141 158 static always_inline int cto32 (uint32_t val)
... ... @@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val)
145 162  
146 163 static always_inline int ctz64 (uint64_t val)
147 164 {
  165 +#if defined(__GNUC__)
  166 + if (val)
  167 + return __builtin_ctz(val);
  168 + else
  169 + return 64;
  170 +#else
148 171 int cnt;
149 172  
150 173 cnt = 0;
... ... @@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val)
154 177 }
155 178  
156 179 return cnt + ctz32(val);
  180 +#endif
157 181 }
158 182  
159 183 static always_inline int cto64 (uint64_t val)
... ... @@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val)
182 206  
183 207 static always_inline int ctpop32 (uint32_t val)
184 208 {
  209 +#if defined(__GNUC__)
  210 + return __builtin_popcount(val);
  211 +#else
185 212 val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
186 213 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
187 214 val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
... ... @@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val)
189 216 val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
190 217  
191 218 return val;
  219 +#endif
192 220 }
193 221  
194 222 static always_inline int ctpop64 (uint64_t val)
195 223 {
  224 +#if defined(__GNUC__)
  225 + return __builtin_popcountll(val);
  226 +#else
196 227 val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
197 228 val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
198 229 val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
... ... @@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val)
201 232 val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
202 233  
203 234 return val;
  235 +#endif
204 236 }
... ...