source: trunk/lib/bitblock128.hpp @ 1542

Last change on this file since 1542 was 1542, checked in by ksherdy, 8 years ago

Prefer static function overloading on bitblock128_t types for performance. Methods templated on BitBlock? type do not inline efficiently.

File size: 3.8 KB
Line 
1/*
2    bitblock128 - 128 bit block size - Specific 128 bit implementations.
3
4    Idealized SIMD Operations with SSE versions
5    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy, Hua Huang and Nigel Medforth.
6    Licensed to the public under the Open Software License 3.0.
7    Licensed to International Characters Inc.
8       under the Academic Free License version 3.0.
9
10*/
11#ifndef BITBLOCK128_HPP_
12#define BITBLOCK128_HPP_
13
14static IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, bitblock128_t & carry, bitblock128_t & sum);
15static IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, bitblock128_t & borrow, bitblock128_t & difference);
16static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, bitblock128_t & carry, bitblock128_t & rslt);
17static IDISA_ALWAYS_INLINE bool bitblock_has_bit(bitblock128_t arg1);
18static IDISA_ALWAYS_INLINE uint64_t bitblock_bit_count(bitblock128_t arg1);
19static IDISA_ALWAYS_INLINE void signbitmask(bitblock128_t & v);
20static IDISA_ALWAYS_INLINE bitblock128_t convert (uint64_t s);
21static IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v);
22
23IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, bitblock128_t & carry, bitblock128_t & sum)
24{
25        bitblock128_t gen = simd_and(x, y);
26        bitblock128_t prop = simd_or(x, y);
27        bitblock128_t partial = simd<64>::add(simd<64>::add(x, y), carry);
28        bitblock128_t c1 = simd128<128>::slli<64>(simd<64>::srli<63>(simd_or(gen, simd_andc(prop, partial))));
29        sum = simd<64>::add(c1, partial);
30        // carry = simd_and(hibitmask<bitblock128_t>(), simd_or(gen, simd_andc(prop, sum))); // TODO - set high bit carry via hibitmask
31        carry = simd128<128>::srli<127>(simd_or(gen, simd_andc(prop, sum))); // TODO -
32}
33
34IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, bitblock128_t & borrow, bitblock128_t & difference)
35{
36        bitblock128_t gen = simd_andc(y, x);
37        bitblock128_t prop = simd_not(simd_xor(x, y));
38        bitblock128_t partial = simd<64>::sub(simd<64>::sub(x, y), borrow);
39        bitblock128_t b1 = simd128<128>::slli<64>(simd<64>::srli<63>(simd_or(gen, simd_and(prop, partial))));
40        difference = simd<64>::sub(partial, b1);
41        // borrow = simd_and(hibitmask<bitblock128_t>, simd_or(gen, simd_and(prop, difference))); // TODO - set high bit carry via hibitmask
42        borrow = simd128<128>::srli<127>(simd_or(gen, simd_and(prop, difference)));
43}
44
45IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, bitblock128_t & carry, bitblock128_t & rslt)
46{
47bitblock128_t shift_out = simd<64>::srli<63>(cursor);
48bitblock128_t low_bits = esimd<64>::mergel(shift_out, carry);
49// carry = simd_and(hibitmask<bitblock128_t>, cursor);
50carry = simd128<128>::srli<64>(shift_out);                                              // carry - accumlated 127 shift right locical shift of cursor
51rslt = simd_or(simd<64>::add(cursor, cursor), low_bits);
52}
53
54IDISA_ALWAYS_INLINE bool bitblock_has_bit(bitblock128_t arg1)
55{
56        // TOOD simd128::any(arg1);
57        return bitblock::any(arg1);
58}
59
60IDISA_ALWAYS_INLINE uint64_t bitblock_bit_count(bitblock128_t arg1)
61{
62        // TODO simd128::popcount(arg1)
63        return mvmd<64>::extract<0>(simd128<128>::popcount(arg1));
64}
65
66IDISA_ALWAYS_INLINE void signbitmask(bitblock128_t & v)
67{
68        // TODO simd128::
69        v =  simd128<128>::slli<127>(simd128<128>::constant<1>());
70}
71
72/* Type conversion support */
73union ubitblock128 {
74        //bitblock256_t 256;
75        bitblock128_t _128;
76        uint64_t _64[sizeof(bitblock128_t)/sizeof(uint64_t)];
77        uint32_t _32[sizeof(bitblock128_t)/sizeof(uint32_t)];
78        uint16_t _16[sizeof(bitblock128_t)/sizeof(uint16_t)];
79        uint8_t _8[sizeof(bitblock128_t)/sizeof(uint8_t)];
80};
81
82IDISA_ALWAYS_INLINE bitblock128_t convert(uint64_t s)
83{
84        ubitblock128 b = {b._128 = simd128<128>::constant<0>()}; // = {0};
85        b._64[0] = s;
86        return b._128;
87}
88
89IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v)
90{
91        return (uint64_t) mvmd<64>::extract<0>(v);
92}
93
94
95#endif /* BITBLOCK128_HPP_ */
Note: See TracBrowser for help on using the repository browser.