source: trunk/lib/bitblock.hpp @ 1894

Last change on this file since 1894 was 1890, checked in by cameron, 8 years ago

Move count_forward_zeroes et al up to remove 128-bit dependency.

File size: 2.7 KB
Line 
1/*
2    IDISA Library Import - Generic
3    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy
4    Licensed to the public under the Open Software License 3.0.
5    Licensed to International Characters Inc.
6       under the Academic Free License version 3.0.
7*/
8#ifndef BITBLOCK_HPP
9#define BITBLOCK_HPP
10
11#define __STDC_LIMIT_MACROS
12#include <stdint.h>
13#include <stdio.h>
14#include "config.hpp"
15#include "builtins.hpp"
16#include "idisa.hpp"
17
18#define BytePack BitBlock
19#ifndef BLOCK_SIZE
20#define BLOCK_SIZE 128
21#endif
22#define ATTRIBUTE_SIMD_ALIGN __attribute__((aligned(sizeof(BitBlock))))
23
24template<class T> void print_register(const char * var_name, T v);
25
26static IDISA_ALWAYS_INLINE uint32_t count_forward_zeroes(BitBlock v);
27static IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v);
28static IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos);
29
30
31/*  BitBlock union type */
32union ubitblock;
33
34/*  Default BLOCK_SIZE is 128, compatible with SSE, Altivec, SPU */
35#if (BLOCK_SIZE == 128)
36#include "bitblock128.hpp"
37#endif
38
39/*  BLOCK_SIZE 256 for AVX */
40#if (BLOCK_SIZE == 256)
41#include "bitblock256.hpp"
42#endif
43
44IDISA_ALWAYS_INLINE bool all_true(uint64_t r);
45
46template <class T> void print_register(const char * var_name, T v);
47template <class T>
48void print_register(const char * var_name, T v) {
49        unsigned char c;
50        printf("%20s = ", var_name);
51        for(int i=sizeof(T)-1; i>=0; i--) {
52                c = *(((unsigned char *)&v)+i);
53                printf("%02X ", c);
54        }
55        printf("\n");
56}
57
58IDISA_ALWAYS_INLINE uint32_t count_forward_zeroes(BitBlock v) {
59        union {BitBlock bitblock; scanword_t elems[sizeof(BitBlock)/sizeof(scanword_t)];} u;
60        u.bitblock = v;
61        uint32_t so_far = 0;
62        for (int i = 0; i < sizeof(BitBlock)/sizeof(scanword_t); i++) {
63                if (u.elems[i] != 0) return so_far + scan_forward_zeroes(u.elems[i]);
64                so_far += 8 * sizeof(scanword_t);
65        }
66        return so_far;
67}
68
69IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v) {
70        union {BitBlock bitblock; scanword_t elems[sizeof(BitBlock)/sizeof(scanword_t)];} u;
71        u.bitblock = v;
72        uint32_t so_far = 0;
73        for (int i = sizeof(BitBlock)/sizeof(scanword_t) - 1; i >= 0; i--) {
74                if (u.elems[i] != 0) return so_far + scan_backward_zeroes(u.elems[i]);
75                so_far += 8 * sizeof(scanword_t);
76        }
77        return so_far;
78}
79
80IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos) {
81        scanword_t * bitstream_ptr = (scanword_t *) (((intptr_t) v) + pos/8);
82        scanword_t bitstream_slice = ((*bitstream_ptr) >> (pos % 8));
83        if (bitstream_slice != 0) return pos + scan_forward_zeroes(bitstream_slice);
84        else {
85                do {
86                        bitstream_ptr++;
87                        bitstream_slice = *bitstream_ptr;
88                } while (bitstream_slice == 0);
89                uint32_t base_posn = 8*((intptr_t) bitstream_ptr - (intptr_t) v);
90                return base_posn + scan_forward_zeroes(bitstream_slice);
91        }
92}
93
94#endif /* BITBLOCK_HPP */
95
96
Note: See TracBrowser for help on using the repository browser.