source: trunk/lib_c/bitblock.h @ 4065

Last change on this file since 4065 was 3391, checked in by linmengl, 6 years ago

check in IDISA C library and other support libraries. Some template features still remain.

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