static zend_always_inline int zend_mm_bitset_is_set(zend_mm_bitset *bitset, int bit)
{
- return (bitset[bit / ZEND_MM_BITSET_LEN] & (Z_L(1) << (bit & (ZEND_MM_BITSET_LEN-1)))) != 0;
+ return ZEND_BIT_TEST(bitset, bit);
}
static zend_always_inline void zend_mm_bitset_set_bit(zend_mm_bitset *bitset, int bit)
static inline zend_bool zend_bitset_in(zend_bitset set, uint32_t n)
{
- return (set[ZEND_BITSET_ELM_NUM(n)] & (Z_UL(1) << ZEND_BITSET_BIT_NUM(n))) != Z_UL(0);
+ return ZEND_BIT_TEST(set, n);
}
static inline void zend_bitset_incl(zend_bitset set, uint32_t n)
#define MAX(a, b) (((a)>(b))?(a):(b))
#define MIN(a, b) (((a)<(b))?(a):(b))
+/* x86 instructions BT, SHL, SHR don't require masking */
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> (bit)) & 1)
+#else
+# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
+#endif
+
/* We always define a function, even if there's a macro or expression we could
* alias, so that using it in contexts where we can't make function calls
* won't fail to compile on some machines and not others.
0xffffffff, 0x500080c4, 0x10000000, 0x00000000};
pos++;
- if (EXPECTED(!((charmap[us >> 5] >> (us & 0x1f)) & 1))) {
+ if (EXPECTED(!ZEND_BIT_TEST(charmap, us))) {
smart_str_appendc(buf, (unsigned char) us);
} else {
switch (us) {
for (i = 0; i < result->row_count; i++) {
/* (i / 8) & the_bit_for_i*/
- if ((initialized[i >> 3] >> (i & 7)) & 1) {
+ if (ZEND_BIT_TEST(initialized, i)) {
continue;
}
if (rc != PASS) {
DBG_RETURN(FAIL);
}
- if (!((set->initialized[set->current_row >> 3] >> (set->current_row & 7)) & 1)) {
+ if (!ZEND_BIT_TEST(set->initialized, set->current_row)) {
set->initialized[set->current_row >> 3] |= (1 << (set->current_row & 7)); /* mark initialized */
++set->initialized_rows;
{
#if 1
/* first 256 bits for first character, and second 256 bits for the next */
- static const uint32_t charset[16] = {
+ static const uint32_t charset[8] = {
/* 31 0 63 32 95 64 127 96 */
0x00000000, 0x00000000, 0x87fffffe, 0x07fffffe,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
+ static const uint32_t charset2[8] = {
/* 31 0 63 32 95 64 127 96 */
0x00000000, 0x03ff0000, 0x87fffffe, 0x07fffffe,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
- };
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
#endif
size_t i;
uint32_t ch;
/* These are allowed as first char: [a-zA-Z_\x7f-\xff] */
ch = (uint32_t)((unsigned char *)var_name)[0];
#if 1
- if (UNEXPECTED(!((charset[ch >> 5] >> (ch & 0x1f)) & 1))) {
+ if (UNEXPECTED(!ZEND_BIT_TEST(charset, ch))) {
#else
if (var_name[0] != '_' &&
(ch < 65 /* A */ || /* Z */ ch > 90) &&
do {
ch = (uint32_t)((unsigned char *)var_name)[i];
#if 1
- if (UNEXPECTED(!((charset[8 + (ch >> 5)] >> (ch & 0x1f)) & 1))) {
+ if (UNEXPECTED(!ZEND_BIT_TEST(charset2, ch))) {
#else
if (var_name[i] != '_' &&
(ch < 48 /* 0 */ || /* 9 */ ch > 57) &&