Skip to content

Commit 5b901ba

Browse files
committed
py/misc: Add a popcount(uint32_t) implementation.
This makes the existing popcount(uint32_t) implementation found in the RV32 emitter available to the rest of the codebase. This version of popcount will use intrinsic or builtin implementations if they are available, falling back to a generic implementation if that is not the case. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 4f91060 commit 5b901ba

File tree

2 files changed

+19
-22
lines changed

2 files changed

+19
-22
lines changed

py/asmrv32.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <string.h>
3030

3131
#include "py/emit.h"
32+
#include "py/misc.h"
3233
#include "py/mpconfig.h"
3334

3435
// wrapper around everything in this file
@@ -43,27 +44,6 @@
4344
#define DEBUG_printf(...) (void)0
4445
#endif
4546

46-
#ifndef MP_POPCOUNT
47-
#ifdef _MSC_VER
48-
#include <intrin.h>
49-
#define MP_POPCOUNT __popcnt
50-
#else
51-
#if defined __has_builtin
52-
#if __has_builtin(__builtin_popcount)
53-
#define MP_POPCOUNT __builtin_popcount
54-
#endif
55-
#else
56-
static uint32_t fallback_popcount(uint32_t value) {
57-
value = value - ((value >> 1) & 0x55555555);
58-
value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
59-
value = (value + (value >> 4)) & 0x0F0F0F0F;
60-
return value * 0x01010101;
61-
}
62-
#define MP_POPCOUNT fallback_popcount
63-
#endif
64-
#endif
65-
#endif
66-
6747
#define INTERNAL_TEMPORARY ASM_RV32_REG_S0
6848
#define AVAILABLE_REGISTERS_COUNT 32
6949

@@ -249,7 +229,7 @@ static void adjust_stack(asm_rv32_t *state, mp_int_t stack_size) {
249229
// stack to hold all the tainted registers and an arbitrary amount of space
250230
// for locals.
251231
static void emit_function_prologue(asm_rv32_t *state, mp_uint_t registers) {
252-
mp_uint_t registers_count = MP_POPCOUNT(registers);
232+
mp_uint_t registers_count = mp_popcount(registers);
253233
state->stack_size = (registers_count + state->locals_count) * sizeof(uint32_t);
254234
mp_uint_t old_saved_registers_mask = state->saved_registers_mask;
255235
// Move stack pointer up.

py/misc.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,29 @@ static inline uint32_t mp_ctz(uint32_t x) {
370370
static inline bool mp_check(bool value) {
371371
return value;
372372
}
373+
374+
static inline uint32_t mp_popcount(uint32_t x) {
375+
return __popcnt(x);
376+
}
373377
#else
374378
#define mp_clz(x) __builtin_clz(x)
375379
#define mp_clzl(x) __builtin_clzl(x)
376380
#define mp_clzll(x) __builtin_clzll(x)
377381
#define mp_ctz(x) __builtin_ctz(x)
378382
#define mp_check(x) (x)
383+
#if defined __has_builtin
384+
#if __has_builtin(__builtin_popcount)
385+
#define mp_popcount(x) __builtin_popcount(x)
386+
#endif
387+
#endif
388+
#if !defined(mp_popcount)
389+
static inline uint32_t mp_popcount(uint32_t x) {
390+
x = x - ((x >> 1) & 0x55555555);
391+
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
392+
x = (x + (x >> 4)) & 0x0F0F0F0F;
393+
return x * 0x01010101;
394+
}
395+
#endif
379396
#endif
380397

381398
// mp_int_t can be larger than long, i.e. Windows 64-bit, nan-box variants

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy