MMgr v1.0.0
Zero-heap memory manager in C11. One borrowed buffer, carved by asserted offset.
Loading...
Searching...
No Matches
clz.h
Go to the documentation of this file.
1/* MMgr - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2 * SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-Commercial OR LicenseRef-Educational
3 *
4 * Every use falls under AGPL-3.0-or-later unless you hold explicit permission, which is either a
5 * negotiated commercial licensing contract or an educator's license issued to you personally.
6 */
7/**
8 * @file clz.h
9 * @brief Leading and trailing zero counts: the argument type, the two calls, and the clz dispatch
10 * table.
11 * @author dstroy0 (Douglas Quigg) <dquigg123@gmail.com>
12 * @date 2026-08-29
13 *
14 * @note A zero count is how a scan turns a lane mask into a lane index, and so these sit under the SWAR
15 * walks instead of being a general utility.
16 * @note Both run branchless and in a fixed number of steps. A caller pays the same whatever the
17 * value is. That is the ground on which they are written out and not reached through a builtin,
18 * which is absent on some targets and a call on others.
19 * @warning Neither distinguishes a value of 0 from a value with one bit set at the end it counts
20 * from. A caller that can be handed 0 tests for it first.
21 */
22#ifndef MMGR_CLZ_H
23#define MMGR_CLZ_H
24
25#include "mmgr.h"
26
27EMBED_BEGIN_DECLS
28
29/**
30 * @brief Argument for both clz calls: the value to count zeros in.
31 */
32typedef struct
33{
34 const embed_u64 val; /**< Value whose leading or trailing zeros are counted. */
35} ClzCfg;
36
37/**
38 * @brief Type of the clz dispatch table.
39 *
40 * @note EMBED_TABLE_LAYOUT asserts the two members sit at consecutive EMBED_FUNCTION_POINTER_BYTES offsets, with
41 * nothing else.
42 */
43typedef struct
44{
45 embed_iword (*lead)(const ClzCfg *args); /**< Leading zero count of val. */
46 embed_iword (*trail)(const ClzCfg *args); /**< Trailing zero count of val. */
47} ClzNs;
48EMBED_TABLE_LAYOUT(ClzNs, lead, trail);
49
50/**
51 * @brief Counts the zero bits above the highest set bit of args->val.
52 *
53 * @param[in] args Value to measure [BORROWS].
54 * @return Leading zero count, 0 through 63.
55 * @note Runs in a fixed number of steps, none of which branches on the value.
56 * @warning An args->val of 0 returns 63, the same answer as an args->val of 1.
57 */
58embed_iword mmgr_clz_lead(const ClzCfg *args);
59
60/**
61 * @brief Counts the zero bits below the lowest set bit of args->val.
62 *
63 * @param[in] args Value to measure [BORROWS].
64 * @return Trailing zero count, 0 through 63.
65 * @note Runs in a fixed number of steps, none of which branches on the value.
66 * @warning An args->val of 0 returns 63, the same answer as an args->val of 2^63.
67 */
68embed_iword mmgr_clz_trail(const ClzCfg *args);
69
70/**
71 * @brief Dispatch table instance named clz, with each member set to its mmgr_clz_ function.
72 */
73EMBED_TABLE_STORAGE ClzNs clz EMBED_UNUSED = {
74 .lead = mmgr_clz_lead,
75 .trail = mmgr_clz_trail,
76};
77
78EMBED_END_DECLS
79
80#endif
embed_iword mmgr_clz_trail(const ClzCfg *args)
Counts the zero bits below the lowest set bit of args->val.
static const ClzNs clz
Dispatch table instance named clz, with each member set to its mmgr_clz_ function.
Definition clz.h:73
embed_iword mmgr_clz_lead(const ClzCfg *args)
Counts the zero bits above the highest set bit of args->val.
The embedded_types headers every module builds on.
Argument for both clz calls: the value to count zeros in.
Definition clz.h:33
const embed_u64 val
Definition clz.h:34
Type of the clz dispatch table.
Definition clz.h:44
embed_iword(*) lead(const ClzCfg *args)
Definition clz.h:45
embed_iword(*) trail(const ClzCfg *args)
Definition clz.h:46