rlib
Convenience library for useful things
Loading...
Searching...
No Matches
rbitops.h
Go to the documentation of this file.
1/* RLIB - Convenience library for useful things
2 * Copyright (C) 2016 Haakon Sporsheim <haakon.sporsheim@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3.0 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library.
16 * See the COPYING file at the root of the source repository.
17 */
18#ifndef __R_BITOPS_H__
19#define __R_BITOPS_H__
20
21#if !defined(__RLIB_H_INCLUDE_GUARD__) && !defined(RLIB_COMPILATION)
22#error "#include <rlib.h> only please."
23#endif
24
25/* This header is included by rtypes.h (@ bottom of file) */
26
63
64#if defined(_MSC_VER)
65#include <intrin.h>
66
67ruint __inline RUINT_CLZ (ruint x)
68{
69 ruint lz;
70 return (_BitScanReverse (&lz, x)) ? 31 - lz : 32;
71}
72
73ruint __inline RUINT_CTZ (ruint x)
74{
75 ruint tz;
76 return (_BitScanForward (&tz, x)) ? tz : 32;
77}
78
79#if RLIB_SIZEOF_LONG == 4
80rulong __inline RULONGLONG_CLZ (ruint64 x)
81{
82 ruint y[2] = { x & RUINT32_MAX, x >> 32 };
83 rulong lz;
84
85 return (_BitScanReverse (&lz, y[1])) ? 31 - lz :
86 ((_BitScanReverse (&lz, y[0])) ? 63 - lz : 64);
87}
88
89rulong __inline RULONGLONG_CTZ (ruint64 x)
90{
91 ruint y[2] = { x & RUINT32_MAX, x >> 32 };
92 rulong tz;
93
94 return (_BitScanForward (&tz, y[0])) ? tz :
95 ((_BitScanForward (&tz, y[1])) ? tz + 32 : 64);
96}
97#else
98rulong __inline RULONGLONG_CLZ (ruint64 x)
99{
100 rulong lz;
101 return (_BitScanReverse64 (&lz, x)) ? 63 - lz : 64;
102}
103
104rulong __inline RULONGLONG_CTZ (ruint64 x)
105{
106 rulong tz;
107 return (_BitScanForward64 (&tz, x)) ? tz : 64;
108}
109#endif
110
111#define RUINT_POPCOUNT(x) (ruint)__popcnt (x)
112#define RUINT_PARITY(x) (__popcnt (x) & 1)
113#if RLIB_SIZEOF_LONG == 4
114ruint __inline RULONGLONG_POPCOUNT (ruint64 x)
115{
116 ruint y[2] = { x & RUINT32_MAX, x >> 32 };
117 return (ruint)__popcnt (y[0]) + __popcnt (y[1]);
118}
119
120rboolean __inline RULONGLONG_PARITY (ruint64 x)
121{
122 ruint y[2] = { x & RUINT32_MAX, x >> 32 };
123 return ((__popcnt (y[0]) + __popcnt (y[1])) & 1) != 0;
124}
125#else
126#define RULONGLONG_POPCOUNT(x) (ruint)__popcnt64 (x)
127#define RULONGLONG_PARITY(x) (__popcnt64 (x) & 1)
128#endif
129#if RLIB_SIZEOF_LONG == 4
130#define RULONG_CLZ(x) RUINT_CLZ (x)
131#define RULONG_CTZ(x) RUINT_CTZ (x)
132#define RULONG_POPCOUNT(x) RUINT_POPCOUNT (x)
133#define RULONG_PARITY(x) RUINT_PARITY (x)
134#else
135#define RULONG_CLZ(x) RULONGLONG_CLZ (x)
136#define RULONG_CTZ(x) RULONGLONG_CTZ (x)
137#define RULONG_POPCOUNT(x) RULONGLONG_POPCOUNT (x)
138#define RULONG_PARITY(x) RULONGLONG_PARITY (x)
139#endif
140
141#elif defined(__GNUC__)
142#define RUINT_CLZ(x) ((x) ? (ruint)__builtin_clz (x) : sizeof (ruint) * 8)
143#define RUINT_CTZ(x) ((x) ? (ruint)__builtin_ctz (x) : sizeof (ruint) * 8)
144#define RUINT_POPCOUNT(x) (ruint)__builtin_popcount (x)
145#define RUINT_PARITY(x) __builtin_parity (x)
146#define RULONG_CLZ(x) ((x) ? (ruint)__builtin_clzl (x) : sizeof (rulong) * 8)
147#define RULONG_CTZ(x) ((x) ? (ruint)__builtin_ctzl (x) : sizeof (rulong) * 8)
148#define RULONG_POPCOUNT(x) (ruint)__builtin_popcountl (x)
149#define RULONG_PARITY(x) __builtin_parityl (x)
150#define RULONGLONG_CLZ(x) ((x) ? (ruint)__builtin_clzll (x) : sizeof (long long) * 8)
151#define RULONGLONG_CTZ(x) ((x) ? (ruint)__builtin_ctzll (x) : sizeof (long long) * 8)
152#define RULONGLONG_POPCOUNT(x) (ruint)__builtin_popcountll (x)
153#define RULONGLONG_PARITY(x) __builtin_parityll (x)
154#endif
155
156#if RLIB_SIZEOF_LONG == 8
157#define RUINT64_CLZ(x) RULONG_CLZ (x)
158#define RUINT64_CTZ(x) RULONG_CTZ (x)
159#define RUINT64_POPCOUNT(x) RULONG_POPCOUNT (x)
160#define RUINT64_PARITY(x) RULONG_PARITY (x)
161#else
162#define RUINT64_CLZ(x) RULONGLONG_CLZ (x)
163#define RUINT64_CTZ(x) RULONGLONG_CTZ (x)
164#define RUINT64_POPCOUNT(x) RULONGLONG_POPCOUNT (x)
165#define RUINT64_PARITY(x) RULONGLONG_PARITY (x)
166#endif
167#define RUINT64_SHL(x, n) (((x) & RUINT64_MAX) << ((n) & 63))
168#define RUINT64_SHR(x, n) (((x) & RUINT64_MAX) >> ((n) & 63))
169#define RUINT64_ROTL(x, n) (RUINT64_SHL (x, n) | RUINT64_SHR (x, 64-(n)))
170#define RUINT64_ROTR(x, n) (RUINT64_SHR (x, n) | RUINT64_SHL (x, 64-(n)))
171
172
173#if RLIB_SIZEOF_INT == 4
175#define RUINT32_CLZ(x) RUINT_CLZ (x)
177#define RUINT32_CTZ(x) RUINT_CTZ (x)
179#define RUINT32_POPCOUNT(x) RUINT_POPCOUNT (x)
181#define RUINT32_PARITY(x) RUINT_PARITY (x)
182#elif RLIB_SIZEOF_LONG == 4
183#define RUINT32_CLZ(x) RULONG_CLZ (x)
184#define RUINT32_CTZ(x) RULONG_CTZ (x)
185#define RUINT32_POPCOUNT(x) RULONG_POPCOUNT (x)
186#define RUINT32_PARITY(x) RULONG_PARITY (x)
187#else
188#define RUINT32_CLZ(x) (RUINT64_CLZ (x & RUINT32_MAX) - 32)
189#define RUINT32_CTZ(x) RUINT64_CTZ (x & RUINT32_MAX)
190#define RUINT32_POPCOUNT(x) RUINT64_POPCOUNT (x & RUINT32_MAX)
191#define RUINT32_PARITY(x) RUINT64_PARITY (x & RUINT32_MAX)
192#endif
194#define RUINT32_SHL(x, n) (((x) & RUINT32_MAX) << ((n) & 31))
196#define RUINT32_SHR(x, n) (((x) & RUINT32_MAX) >> ((n) & 31))
198#define RUINT32_ROTL(x, n) (RUINT32_SHL (x, n) | RUINT32_SHR (x, 32-(n)))
200#define RUINT32_ROTR(x, n) (RUINT32_SHR (x, n) | RUINT32_SHL (x, 32-(n)))
201
202#if RLIB_SIZEOF_INT == 2
203#define RUINT16_CLZ(x) RUINT_CLZ (x)
204#define RUINT16_CTZ(x) RUINT_CTZ (x)
205#define RUINT16_POPCOUNT(x) RUINT_POPCOUNT (x)
206#define RUINT16_PARITY(x) RUINT_PARITY (x)
207#elif RLIB_SIZEOF_LONG == 2
208#define RUINT16_CLZ(x) RULONG_CLZ (x)
209#define RUINT16_CTZ(x) RULONG_CTZ (x)
210#define RUINT16_POPCOUNT(x) RULONG_POPCOUNT (x)
211#define RUINT16_PARITY(x) RULONG_PARITY (x)
212#else
213#define RUINT16_CLZ(x) (RUINT32_CLZ (x & RUINT16_MAX) - 16)
214#define RUINT16_CTZ(x) MIN (RUINT32_CTZ (x & RUINT16_MAX), 16)
215#define RUINT16_POPCOUNT(x) RUINT32_POPCOUNT (x & RUINT16_MAX)
216#define RUINT16_PARITY(x) RUINT32_PARITY (x & RUINT16_MAX)
217#endif
218#define RUINT16_SHL(x, n) (((x) & RUINT16_MAX) << ((n) & 15))
219#define RUINT16_SHR(x, n) (((x) & RUINT16_MAX) >> ((n) & 15))
220#define RUINT16_ROTL(x, n) (RUINT16_SHL (x, n) | RUINT16_SHR (x, 16-(n)))
221#define RUINT16_ROTR(x, n) (RUINT16_SHR (x, n) | RUINT16_SHL (x, 16-(n)))
222
223#define RUINT8_CLZ(x) (RUINT32_CLZ (x & RUINT8_MAX) - 24)
224#define RUINT8_CTZ(x) MIN (RUINT32_CTZ (x & RUINT8_MAX), 8)
225#define RUINT8_POPCOUNT(x) RUINT32_POPCOUNT (x & RUINT8_MAX)
226#define RUINT8_PARITY(x) RUINT32_PARITY (x & RUINT8_MAX)
227#define RUINT8_SHL(x, n) (((x) & RUINT8_MAX) << ((n) & 7))
228#define RUINT8_SHR(x, n) (((x) & RUINT8_MAX) >> ((n) & 7))
229#define RUINT8_ROTL(x, n) (RUINT8_SHL (x, n) | RUINT8_SHR (x, 8-(n)))
230#define RUINT8_ROTR(x, n) (RUINT8_SHR (x, n) | RUINT8_SHL (x, 8-(n)))
231
232#if RLIB_SIZEOF_SIZE_T == 8
233#define RSIZE_CLZ(x) RUINT64_CLZ (x)
234#define RSIZE_CTZ(x) RUINT64_CTZ (x)
235#define RSIZE_POPCOUNT(x) RUINT64_POPCOUNT (x)
236#define RSIZE_PARITY(x) RUINT64_PARITY (x)
237#define RSIZE_SHL(x, n) RUINT64_SHL (x, n)
238#define RSIZE_SHR(x, n) RUINT64_SHR (x, n)
239#define RSIZE_ROTL(x, n) RUINT64_ROTL (x, n)
240#define RSIZE_ROTR(x, n) RUINT64_ROTR (x, n)
241#elif RLIB_SIZEOF_SIZE_T == 4
242#define RSIZE_CLZ(x) RUINT32_CLZ (x)
243#define RSIZE_CTZ(x) RUINT32_CTZ (x)
244#define RSIZE_POPCOUNT(x) RUINT32_POPCOUNT (x)
245#define RSIZE_PARITY(x) RUINT32_PARITY (x)
246#define RSIZE_SHL(x, n) RUINT32_SHL (x, n)
247#define RSIZE_SHR(x, n) RUINT32_SHR (x, n)
248#define RSIZE_ROTL(x, n) RUINT32_ROTL (x, n)
249#define RSIZE_ROTR(x, n) RUINT32_ROTR (x, n)
250#elif RLIB_SIZEOF_SIZE_T == 2
251#define RSIZE_CLZ(x) RUINT16_CLZ (x)
252#define RSIZE_CTZ(x) RUINT16_CTZ (x)
253#define RSIZE_POPCOUNT(x) RUINT16_POPCOUNT (x)
254#define RSIZE_PARITY(x) RUINT16_PARITY (x)
255#define RSIZE_SHL(x, n) RUINT16_SHL (x, n)
256#define RSIZE_SHR(x, n) RUINT16_SHR (x, n)
257#define RSIZE_ROTL(x, n) RUINT16_ROTL (x, n)
258#define RSIZE_ROTR(x, n) RUINT16_ROTR (x, n)
259#endif
260
261R_END_DECLS
262
/* r_bitops */
264
265#endif /* __R_BITOPS_H__ */
#define R_BEGIN_DECLS
Open an extern "C" block under C++ (no-op in C).
Definition rmacros.h:196
unsigned long rulong
Unsigned long.
Definition rtypes.h:155
int rboolean
Boolean type (typedef'd to int).
Definition rtypes.h:59
#define RUINT32_MAX
Maximum value of ruint32.
Definition rtypes.h:224
unsigned int ruint
Unsigned int.
Definition rtypes.h:157
unsigned long ruint64
Unsigned 64-bit integer.
Definition rtypes.h:193