Ignore:
Timestamp:
Jul 1, 2013, 11:11:28 AM (6 years ago)
Author:
cameron
Message:

Clear_from: make sure all scan_fields are cleared

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bitblock_iterator.hpp

    r3371 r3377  
    103103        /* Make sure that the number of bits in the mask at least equals
    104104           the number of scanblocks. */
    105         /* Requires flag -std=gnu++0x */
     105        /* Requires flag -std=gnu++0x  */
    106106        static_assert(sizeof(scanblock_t) * 8 >= bitblock_count * sizeof(bitblock_t)/sizeof(scanfield_t),
    107107                      "Too many bitblocks for a single scanword mask");
    108 
     108       
    109109
    110110        BitStreamScanner() {}
     
    115115                remaining._bitblock[i] = b;
    116116                BitBlock mask_i = simd_not(simd<sizeof(scanfield_t)*8>::eq(simd<1>::constant<0>(), b));
    117                 mask |= ((scanblock_t) hsimd<sizeof(scanfield_t)*8>::signmask(mask_i)) << (i * sizeof(bitblock_t)/sizeof(scanfield_t));
     117                mask += ((scanblock_t) hsimd<sizeof(scanfield_t)*8>::signmask(mask_i)) << ((scanblock_t) i * (sizeof(bitblock_t)/sizeof(scanfield_t)));
    118118        }
    119119
     
    142142
    143143        IDISA_ALWAYS_INLINE void clear_from(int pos) {
    144                      int item_pos = pos / (sizeof(scanfield_t) * 8);
    145                      int bitpos = pos % (sizeof(scanfield_t) * 8);
    146                      remaining._scanfield[item_pos] &= (((scanblock_t) 1) << bitpos) - 1;
    147                      item_pos += remaining._scanfield[item_pos] == 0 ? 0 : 1;
    148                      mask = mask & (((scanblock_t) 1) << item_pos) - 1;
    149         }
     144                int item_pos = pos / (sizeof(scanfield_t) * 8);
     145                int bitpos = pos % (sizeof(scanfield_t) * 8);
     146                remaining._scanfield[item_pos] &= ((((scanfield_t) 1) << bitpos) - 1);
     147                item_pos += remaining._scanfield[item_pos] == 0 ? 0 : 1;
     148                mask = mask & (((scanblock_t) 1) << item_pos) - 1;
     149                for (int i = item_pos; i < bitblock_count * 2; i++) remaining._scanfield[i] = 0;
     150        }
     151   
     152        IDISA_ALWAYS_INLINE int count() {
     153                if (mask == 0) return 0;
     154                int ct = 0;
     155#define PARALLEL_COUNT
     156#ifdef PARALLEL_COUNT
     157                BitBlock sum8 = simd<1>::constant<0>();
     158                for (int i = 0; i < bitblock_count/2; i++) {
     159                    BitBlock ct4 = simd<4>::add(simd<4>::popcount(remaining._bitblock[2*i]), simd<4>::popcount(remaining._bitblock[2*i+1]));
     160                    sum8 = simd<8>::add(sum8, simd<8>::add_hl(ct4));
     161                }
     162                if ((bitblock_count & 1) != 0) {  // Should be compiled out if bitblock_count is even.
     163                    sum8 = simd<8>::add(sum8, simd<8>::popcount(remaining._bitblock[bitblock_count]));
     164                }
     165                ct = mvmd<32>::extract<0>(simd<128>::add_hl(simd<64>::add_hl(simd<32>::add_hl(simd<16>::add_hl(sum8)))));
     166#endif
     167#ifndef PARALLEL_COUNT
     168                for (int i = 0; i < bitblock_count; i++) {
     169                    ct += bitblock::popcount(remaining._bitblock[i]);
     170                }
     171#endif
     172                return ct;
     173        }
     174   
     175   
    150176private:
    151177        union {bitblock_t _bitblock[bitblock_count];
    152178               scanfield_t _scanfield[bitblock_count * sizeof(bitblock_t)/sizeof(scanfield_t)];} remaining;
    153         scanblock_t mask;                       
     179        scanblock_t mask;
    154180};
    155181
Note: See TracChangeset for help on using the changeset viewer.