Skip to content
This repository was archived by the owner on Jan 25, 2022. It is now read-only.

Commit 67afb9b

Browse files
committed
Optimize ctz32
1 parent 851157c commit 67afb9b

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

emu-rv32i.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -326,16 +326,39 @@ uint32_t load_res; /* for atomic LR/SC */
326326
#define MSTATUS_UXL_MASK ((uint64_t)3 << MSTATUS_UXL_SHIFT)
327327
#define MSTATUS_SXL_MASK ((uint64_t)3 << MSTATUS_SXL_SHIFT)
328328

329-
int ctz32(uint32_t a)
329+
static inline int ctz32(uint32_t val)
330330
{
331-
int i;
332-
if (a == 0)
333-
return 32;
334-
for(i = 0; i < 32; i++) {
335-
if ((a >> i) & 1)
336-
return i;
331+
#if defined(__GNUC__) && __GNUC__ >= 4
332+
return val ? __builtin_ctz(val) : 32;
333+
#else
334+
/* Binary search for the trailing one bit. */
335+
int cnt;
336+
cnt = 0;
337+
if (!(val & 0x0000FFFFUL)) {
338+
cnt += 16;
339+
val >>= 16;
340+
}
341+
if (!(val & 0x000000FFUL)) {
342+
cnt += 8;
343+
val >>= 8;
344+
}
345+
if (!(val & 0x0000000FUL)) {
346+
cnt += 4;
347+
val >>= 4;
348+
}
349+
if (!(val & 0x00000003UL)) {
350+
cnt += 2;
351+
val >>= 2;
337352
}
338-
return 32;
353+
if (!(val & 0x00000001UL)) {
354+
cnt++;
355+
val >>= 1;
356+
}
357+
if (!(val & 0x00000001UL)) {
358+
cnt++;
359+
}
360+
return cnt;
361+
#endif
339362
}
340363

341364
#define SSTATUS_MASK0 (MSTATUS_UIE | MSTATUS_SIE | \

0 commit comments

Comments
 (0)