source: trunk/lib/bitblock.hpp @ 2135

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

Added alignment assertion.

File size: 3.9 KB
Line 
1#ifndef BITBLOCK_HPP
2#define BITBLOCK_HPP
3
4/*=============================================================================
5    IDISA Library Import - Generic
6    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy
7    Licensed to the public under the Open Software License 3.0.
8    Licensed to International Characters Inc.
9       under the Academic Free License version 3.0.
10=============================================================================*/
11
12// #define NDEBUG // if NDEBUG then disable assertions
13
14#define __STDC_LIMIT_MACROS
15#include <stdint.h>
16#include <stdio.h>
17#include <cassert>
18
19#include "config.hpp"
20#include "builtins.hpp"
21#include "idisa.hpp"
22
23#define BytePack BitBlock
24#ifndef BLOCK_SIZE
25#define BLOCK_SIZE 128
26#endif
27#ifndef ATTRIBUTE_SIMD_ALIGN
28    #if defined _MSC_VER
29        //note: MSVC++ cannot accept sizeof or division within __declspec(align(...))
30        #define ATTRIBUTE_SIMD_ALIGN __declspec(align(16))
31    #elif defined __GNUC__
32        #define ATTRIBUTE_SIMD_ALIGN __attribute__((aligned(sizeof(BitBlock))))
33    #else
34        #define ATTRIBUTE_SIMD_ALIGN
35    #endif
36#endif
37
38template<class T> void print_register(const char * var_name, T v);
39
40static IDISA_ALWAYS_INLINE uint32_t count_forward_zeroes(BitBlock v);
41static IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v);
42static IDISA_ALWAYS_INLINE BitBlock mask_forward_zeroes(uint32_t count);
43static IDISA_ALWAYS_INLINE BitBlock mask_reverse_zeroes(uint32_t count);
44static IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos);
45static IDISA_ALWAYS_INLINE void assert_bitblock_align(void * addr);
46static IDISA_ALWAYS_INLINE void assert_bitblock_align(BitBlock v);
47
48/*  BitBlock union type */
49union ubitblock;
50
51/*  Default BLOCK_SIZE is 128, compatible with SSE, Altivec, SPU */
52#if (BLOCK_SIZE == 128)
53#include "bitblock128.hpp"
54#endif
55
56/*  BLOCK_SIZE 256 for AVX */
57#if (BLOCK_SIZE == 256)
58#include "bitblock256.hpp"
59#endif
60
61template <class T> void print_register(const char * var_name, T v);
62template <class T>
63void print_register(const char * var_name, T v) {
64        unsigned char c;
65        printf("%20s = ", var_name);
66        for(int i=sizeof(T)-1; i>=0; i--) {
67                c = *(((unsigned char *)&v)+i);
68                printf("%02X ", c);
69        }
70        printf("\n");
71}
72
73IDISA_ALWAYS_INLINE uint32_t count_forward_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 = 0; i < sizeof(BitBlock)/sizeof(scanword_t); i++) {
78                if (u.elems[i] != 0) return so_far + scan_forward_zeroes(u.elems[i]);
79                so_far += 8 * sizeof(scanword_t);
80        }
81        return so_far;
82}
83
84IDISA_ALWAYS_INLINE BitBlock mask_forward_zeroes(uint32_t count) {
85        if (count >= sizeof(BitBlock) * 8) return simd<1>::constant<0>();
86        else return bitblock::sll(simd<1>::constant<1>(), convert(count));
87}
88
89IDISA_ALWAYS_INLINE uint32_t count_reverse_zeroes(BitBlock v) {
90        union {BitBlock bitblock; scanword_t elems[sizeof(BitBlock)/sizeof(scanword_t)];} u;
91        u.bitblock = v;
92        uint32_t so_far = 0;
93        for (int i = sizeof(BitBlock)/sizeof(scanword_t) - 1; i >= 0; i--) {
94                if (u.elems[i] != 0) return so_far + scan_backward_zeroes(u.elems[i]);
95                so_far += 8 * sizeof(scanword_t);
96        }
97        return so_far;
98}
99
100IDISA_ALWAYS_INLINE BitBlock mask_reverse_zeroes(uint32_t count) {
101        if (count >= sizeof(BitBlock) * 8) return simd<1>::constant<0>();
102        else return bitblock::srl(simd<1>::constant<1>(), convert(count));
103}
104
105IDISA_ALWAYS_INLINE uint32_t bitstream_scan(BitBlock * v, uint32_t pos) {
106        scanword_t * bitstream_ptr = (scanword_t *) (((intptr_t) v) + pos/8);
107        scanword_t bitstream_slice = ((*bitstream_ptr) >> (pos % 8));
108        if (bitstream_slice != 0) return pos + scan_forward_zeroes(bitstream_slice);
109        else {
110                do {
111                        bitstream_ptr++;
112                        bitstream_slice = *bitstream_ptr;
113                } while (bitstream_slice == 0);
114                uint32_t base_posn = 8*((intptr_t) bitstream_ptr - (intptr_t) v);
115                return base_posn + scan_forward_zeroes(bitstream_slice);
116        }
117}
118
119#endif // BITBLOCK_HPP
120
121
Note: See TracBrowser for help on using the repository browser.