From 081bcaddc552b649bee9ebea14b6c73448f58a3a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 18 Nov 2020 16:05:43 -0800 Subject: [PATCH] Avoid use of __builtin_popcount for portability --- riscv/arith.h | 11 +++++++++++ riscv/insns/bdep.h | 2 +- riscv/insns/bdepw.h | 2 +- riscv/insns/bext.h | 2 +- riscv/insns/bextw.h | 2 +- riscv/insns/bmatxor.h | 2 +- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/riscv/arith.h b/riscv/arith.h index c9d39796..72bb5157 100644 --- a/riscv/arith.h +++ b/riscv/arith.h @@ -121,6 +121,17 @@ static inline uint64_t make_mask64(int pos, int len) return (UINT64_MAX >> (64 - len)) << pos; } +static inline int popcount(uint64_t val) +{ + val = (val & 0x5555555555555555U) + ((val >> 1) & 0x5555555555555555U); + val = (val & 0x3333333333333333U) + ((val >> 2) & 0x3333333333333333U); + val = (val & 0x0f0f0f0f0f0f0f0fU) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fU); + val = (val & 0x00ff00ff00ff00ffU) + ((val >> 8) & 0x00ff00ff00ff00ffU); + val = (val & 0x0000ffff0000ffffU) + ((val >> 16) & 0x0000ffff0000ffffU); + val = (val & 0x00000000ffffffffU) + ((val >> 32) & 0x00000000ffffffffU); + return val; +} + static inline int ctz(uint64_t val) { if (!val) diff --git a/riscv/insns/bdep.h b/riscv/insns/bdep.h index 92e28543..e71976f4 100644 --- a/riscv/insns/bdep.h +++ b/riscv/insns/bdep.h @@ -3,7 +3,7 @@ uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); c |= (data << (ctz(b) - i)) & b; - i += __builtin_popcountl(b); + i += popcount(b); mask -= b; } WRITE_RD(sext_xlen(c)); diff --git a/riscv/insns/bdepw.h b/riscv/insns/bdepw.h index 882dbdde..1c06251a 100644 --- a/riscv/insns/bdepw.h +++ b/riscv/insns/bdepw.h @@ -4,7 +4,7 @@ uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); c |= (data << (ctz(b) - i)) & b; - i += __builtin_popcountl(b); + i += popcount(b); mask -= b; } WRITE_RD(sext32(c)); diff --git a/riscv/insns/bext.h b/riscv/insns/bext.h index a03ea6f6..b0ed4a87 100644 --- a/riscv/insns/bext.h +++ b/riscv/insns/bext.h @@ -3,7 +3,7 @@ uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); c |= (data & b) >> (ctz(b) - i); - i += __builtin_popcountl(b); + i += popcount(b); mask -= b; } WRITE_RD(sext_xlen(c)); diff --git a/riscv/insns/bextw.h b/riscv/insns/bextw.h index 5e6ee47b..68377142 100644 --- a/riscv/insns/bextw.h +++ b/riscv/insns/bextw.h @@ -4,7 +4,7 @@ uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); c |= (data & b) >> (ctz(b) - i); - i += __builtin_popcountl(b); + i += popcount(b); mask -= b; } WRITE_RD(sext32(c)); diff --git a/riscv/insns/bmatxor.h b/riscv/insns/bmatxor.h index 06d9db0a..e4dedfdb 100644 --- a/riscv/insns/bmatxor.h +++ b/riscv/insns/bmatxor.h @@ -22,7 +22,7 @@ for (int i = 0; i < 8; i++) { uint64_t x = 0; for (int i = 0; i < 64; i++) { - if (__builtin_popcountl(u[i / 8] & v[i % 8]) & 1) + if (popcount(u[i / 8] & v[i % 8]) & 1) x |= 1LL << i; }