source: trunk/lib/bitblock256.hpp @ 2128

Last change on this file since 2128 was 2018, checked in by cameron, 7 years ago

Simple implementations for 256-bit

File size: 3.6 KB
Line 
1#ifndef BITBLOCK256_HPP_
2#define BITBLOCK256_HPP_
3
4/*=============================================================================
5    bitblock256 - Specific 256 bit IDISA implementations.
6
7    Idealized SIMD Operations with SSE versions
8    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy, Hua Huang and Nigel Medforth.
9    Licensed to the public under the Open Software License 3.0.
10    Licensed to International Characters Inc.
11       under the Academic Free License version 3.0.
12
13=============================================================================*/
14
15#include "idisa128.hpp"
16#include "idisa256.hpp"
17#include "builtins.hpp"
18
19union ubitblock {
20        bitblock256_t _256;
21        bitblock256_t _128[sizeof(bitblock256_t)/sizeof(bitblock256_t)];
22        uint64_t _64[sizeof(bitblock256_t)/sizeof(uint64_t)];
23        uint32_t _32[sizeof(bitblock256_t)/sizeof(uint32_t)];
24        uint16_t _16[sizeof(bitblock256_t)/sizeof(uint16_t)];
25        uint8_t _8[sizeof(bitblock256_t)/sizeof(uint8_t)];
26};
27
28/* The type used to store a carry bit. */
29typedef bitblock256_t carry_t;
30
31static IDISA_ALWAYS_INLINE bitblock256_t carry2bitblock(carry_t carry);
32static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock256_t carry);
33
34static IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t & carry, bitblock256_t & sum);
35static IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t & borrow, bitblock256_t & difference);
36static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t & carry, bitblock256_t & rslt);
37
38static IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t carry_in, carry_t & carry_out, bitblock256_t & sum);
39static IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t borrow_in, carry_t & borrow_out, bitblock256_t & difference);
40static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t carry_in, carry_t & carry_out, bitblock256_t & rslt);
41
42static IDISA_ALWAYS_INLINE bitblock256_t convert (uint64_t s);
43static IDISA_ALWAYS_INLINE uint64_t convert (bitblock256_t v);
44
45static IDISA_ALWAYS_INLINE bitblock256_t carry2bitblock(carry_t carry) {  return carry;}
46static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock256_t carry) {  return carry;}
47
48IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t carry_in, carry_t & carry_out, bitblock256_t & sum)
49{
50        bitblock256_t gen = simd_and(x, y);
51        bitblock256_t prop = simd_or(x, y);
52        sum = simd256<256>::add(simd256<256>::add(x, y), carry2bitblock(carry_in));
53        carry_out = bitblock2carry(simd256<256>::srli<255>(simd_or(gen, simd_andc(prop, sum))));
54}
55
56IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t borrow_in, carry_t & borrow_out, bitblock256_t & difference)
57{
58        bitblock256_t gen = simd_andc(y, x);
59        bitblock256_t prop = simd_not(simd_xor(x, y));
60        difference = simd256<256>::sub(simd256<256>::sub(x, y), carry2bitblock(borrow_in));
61        borrow_out = bitblock2carry(simd256<256>::srli<255>(simd_or(gen, simd_and(prop, difference))));
62}
63
64IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t carry_in, carry_t & carry_out, bitblock256_t & rslt)
65{
66carry_out = simd256<256>::srli<255>(cursor);
67rslt = simd_or(simd256<256>::add(cursor, cursor), carry_in);
68}
69
70IDISA_ALWAYS_INLINE bitblock256_t convert(uint64_t s)
71{
72        ubitblock b = {b._256 = simd256<128>::constant<0>()}; // = {0};
73        b._64[0] = s;
74        return b._256;
75}
76
77IDISA_ALWAYS_INLINE uint64_t convert (bitblock256_t v)
78{
79        return (uint64_t) mvmd256<64>::extract<0>(v);
80}
81
82
83#endif // BITBLOCK256_HPP_
Note: See TracBrowser for help on using the repository browser.