source: trunk/lib/bitblock.hpp @ 1898

Last change on this file since 1898 was 1898, checked in by ksherdy, 7 years ago

Added ASSERTION to test for alignment.

File size: 3.0 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 <cassert>
15//#define NDEBUG // if NDEBUG then disable assertions
16
17#include "config.hpp"
18#include "builtins.hpp"
19#include "idisa.hpp"
20
21#define BytePack BitBlock
22#ifndef BLOCK_SIZE
23#define BLOCK_SIZE 128
24#endif
25#define ATTRIBUTE_SIMD_ALIGN __attribute__((aligned(sizeof(BitBlock))))
26#define ASSERT_BITBLOCK_ALIGN(v) assert(0 == (((uint64_t)(&v)) & (sizeof(BitBlock)-1)) )
27
28template<class T> void print_register(const char * var_name, T v);
29
30static IDISA_ALWAYS_INLINE uint32_t count_forward_zeroes(BitBlock v);
31static IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v);
32static IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos);
33static IDISA_ALWAYS_INLINE BitBlock assert_align(BitBlock v);
34
35/*  BitBlock union type */
36union ubitblock;
37
38/*  Default BLOCK_SIZE is 128, compatible with SSE, Altivec, SPU */
39#if (BLOCK_SIZE == 128)
40#include "bitblock128.hpp"
41#endif
42
43/*  BLOCK_SIZE 256 for AVX */
44#if (BLOCK_SIZE == 256)
45#include "bitblock256.hpp"
46#endif
47
48IDISA_ALWAYS_INLINE bool all_true(uint64_t r);
49
50template <class T> void print_register(const char * var_name, T v);
51template <class T>
52void print_register(const char * var_name, T v) {
53        unsigned char c;
54        printf("%20s = ", var_name);
55        for(int i=sizeof(T)-1; i>=0; i--) {
56                c = *(((unsigned char *)&v)+i);
57                printf("%02X ", c);
58        }
59        printf("\n");
60}
61
62IDISA_ALWAYS_INLINE uint32_t count_forward_zeroes(BitBlock v) {
63        union {BitBlock bitblock; scanword_t elems[sizeof(BitBlock)/sizeof(scanword_t)];} u;
64        u.bitblock = v;
65        uint32_t so_far = 0;
66        for (int i = 0; i < sizeof(BitBlock)/sizeof(scanword_t); i++) {
67                if (u.elems[i] != 0) return so_far + scan_forward_zeroes(u.elems[i]);
68                so_far += 8 * sizeof(scanword_t);
69        }
70        return so_far;
71}
72
73IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v) {
74        union {BitBlock bitblock; scanword_t elems[sizeof(BitBlock)/sizeof(scanword_t)];} u;
75        u.bitblock = v;
76        uint32_t so_far = 0;
77        for (int i = sizeof(BitBlock)/sizeof(scanword_t) - 1; i >= 0; i--) {
78                if (u.elems[i] != 0) return so_far + scan_backward_zeroes(u.elems[i]);
79                so_far += 8 * sizeof(scanword_t);
80        }
81        return so_far;
82}
83
84IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos) {
85        scanword_t * bitstream_ptr = (scanword_t *) (((intptr_t) v) + pos/8);
86        scanword_t bitstream_slice = ((*bitstream_ptr) >> (pos % 8));
87        if (bitstream_slice != 0) return pos + scan_forward_zeroes(bitstream_slice);
88        else {
89                do {
90                        bitstream_ptr++;
91                        bitstream_slice = *bitstream_ptr;
92                } while (bitstream_slice == 0);
93                uint32_t base_posn = 8*((intptr_t) bitstream_ptr - (intptr_t) v);
94                return base_posn + scan_forward_zeroes(bitstream_slice);
95        }
96}
97
98#endif /* BITBLOCK_HPP */
99
100
Note: See TracBrowser for help on using the repository browser.