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,14 +47,16 @@ 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); 47 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
48 #endif 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 /* Binary search for leading zeros. */ 50 /* Binary search for leading zeros. */
55 51
56 static always_inline int clz32(uint32_t val) 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 int cnt = 0; 60 int cnt = 0;
59 61
60 if (!(val & 0xFFFF0000U)) { 62 if (!(val & 0xFFFF0000U)) {
@@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val) @@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val)
81 cnt++; 83 cnt++;
82 } 84 }
83 return cnt; 85 return cnt;
  86 +#endif
84 } 87 }
85 88
86 static always_inline int clo32(uint32_t val) 89 static always_inline int clo32(uint32_t val)
@@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val) @@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val)
90 93
91 static always_inline int clz64(uint64_t val) 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 int cnt = 0; 102 int cnt = 0;
94 103
95 if (!(val >> 32)) { 104 if (!(val >> 32)) {
@@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val) @@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val)
99 } 108 }
100 109
101 return cnt + clz32(val); 110 return cnt + clz32(val);
  111 +#endif
102 } 112 }
103 113
104 static always_inline int clo64(uint64_t val) 114 static always_inline int clo64(uint64_t val)
@@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val) @@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val)
108 118
109 static always_inline int ctz32 (uint32_t val) 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 int cnt; 127 int cnt;
112 128
113 cnt = 0; 129 cnt = 0;
@@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val) @@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val)
136 } 152 }
137 153
138 return cnt; 154 return cnt;
  155 +#endif
139 } 156 }
140 157
141 static always_inline int cto32 (uint32_t val) 158 static always_inline int cto32 (uint32_t val)
@@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val) @@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val)
145 162
146 static always_inline int ctz64 (uint64_t val) 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 int cnt; 171 int cnt;
149 172
150 cnt = 0; 173 cnt = 0;
@@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val) @@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val)
154 } 177 }
155 178
156 return cnt + ctz32(val); 179 return cnt + ctz32(val);
  180 +#endif
157 } 181 }
158 182
159 static always_inline int cto64 (uint64_t val) 183 static always_inline int cto64 (uint64_t val)
@@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val) @@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val)
182 206
183 static always_inline int ctpop32 (uint32_t val) 207 static always_inline int ctpop32 (uint32_t val)
184 { 208 {
  209 +#if defined(__GNUC__)
  210 + return __builtin_popcount(val);
  211 +#else
185 val = (val & 0x55555555) + ((val >> 1) & 0x55555555); 212 val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
186 val = (val & 0x33333333) + ((val >> 2) & 0x33333333); 213 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
187 val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); 214 val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
@@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val) @@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val)
189 val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); 216 val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
190 217
191 return val; 218 return val;
  219 +#endif
192 } 220 }
193 221
194 static always_inline int ctpop64 (uint64_t val) 222 static always_inline int ctpop64 (uint64_t val)
195 { 223 {
  224 +#if defined(__GNUC__)
  225 + return __builtin_popcountll(val);
  226 +#else
196 val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); 227 val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
197 val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); 228 val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
198 val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); 229 val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
@@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val) @@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val)
201 val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); 232 val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
202 233
203 return val; 234 return val;
  235 +#endif
204 } 236 }