1 //===-- src/jitcs_int_bitfuncs.h --------------------------------*- C++ -*-===//
2 // Trailing-Zero/One-Count and population count.
4 // Copyright (C) 2013-2014 Dirk Steinke.
5 // See copyright and license notice in COPYRIGHT or include/jitcs.h
7 // Trailing-Zero-Count is used to find bit positions in bitmasks, and
8 // population count is probably used somewhere too.
9 //===----------------------------------------------------------------------===//
11 #ifndef _JITCS_INT_ADT_BITFUNCS_H_
12 #define _JITCS_INT_ADT_BITFUNCS_H_
14 #include "jitcs_base.h"
18 #pragma intrinsic(_BitScanForward)
20 #pragma intrinsic(_BitScanForward64)
24 #include "x86intrin.h"
29 inline uint
t0cnt32nz_(u32 v
, uint o
) {
32 int index
= __bsfd(v
);
36 u8 ok
= _BitScanForward(&index
, v
);
42 inline uint
t0cnt64nz_(u64 v
, uint o
) {
45 int index
= __bsfq(v
);
49 u8 ok
= _BitScanForward64(&index
, v
);
55 inline uint
t0cnt64nz_(u64 v
, uint o
) {
57 return t0cnt32nz_(((u32
)v
) == 0 ? (u32
)(v
>> 32) : (u32
)v
,
58 o
+ (((u32
)v
) == 0 ? 32 : 0));
62 inline uint
t0cnt32nz(u32 v
, uint o
= 0) { return t0cnt32nz_(v
>> o
, o
); }
63 inline uint
t0cnt64nz(u64 v
, uint o
= 0) { return t0cnt64nz_(v
>> o
, o
); }
65 inline uint
t1cnt32nz(u32 v
, uint o
= 0) { return t0cnt32nz(~v
, o
); }
66 inline uint
t1cnt64nz(u64 v
, uint o
= 0) { return t0cnt64nz(~v
, o
); }
68 // --------------------------
70 inline uint
popcnt32(u32 v
) {
72 M01
= (~(u32
)0) / 255,
77 v
= (v
& M55
) + ((v
>> 1) & M55
);
78 v
= (v
& M33
) + ((v
>> 2) & M33
);
79 v
= (v
& M0F
) + ((v
>> 4) & M0F
);
80 return (v
* M01
) >> 24;
83 inline uint
popcnt64(u64 v
) {
85 M01
= (~(u64
)0) / 255,
90 v
= (v
& M55
) + ((v
>> 1) & M55
);
91 v
= (v
& M33
) + ((v
>> 2) & M33
);
92 v
= (v
& M0F
) + ((v
>> 4) & M0F
);
93 return (v
* M01
) >> 24;
96 inline uint
popcnt64(u64 v
) {
97 return popcnt32((u32
)v
) + popcnt32((u32
)(v
>> 32));
101 // --------------------------
103 inline uint
t0cntnz(i32 v
, uint o
= 0) { return t0cnt32nz((u32
)v
, o
); }
104 inline uint
t0cntnz(u32 v
, uint o
= 0) { return t0cnt32nz(v
, o
); }
105 inline uint
t0cntnz(u64 v
, uint o
= 0) { return t0cnt64nz(v
, o
); }
107 inline uint
t1cntnz(i32 v
, uint o
= 0) { return t1cnt32nz((u32
)v
, o
); }
108 inline uint
t1cntnz(u32 v
, uint o
= 0) { return t1cnt32nz(v
, o
); }
109 inline uint
t1cntnz(u64 v
, uint o
= 0) { return t1cnt64nz(v
, o
); }
111 inline uint
popcnt(i32 v
) { return popcnt32((u32
)v
); }
112 inline uint
popcnt(u32 v
) { return popcnt32(v
); }
113 inline uint
popcnt(u64 v
) { return popcnt64(v
); }
115 } // end of namespace evm
117 // _JITCS_INT_ADT_BITFUNCS_H_