source: trunk/lib_c/bitblock128.h @ 4051

Last change on this file since 4051 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: 6.3 KB
Line 
1/* Generated by cpp2c.rb from ./bitblock128.hpp
2 * Use IDISA C support
3*/
4
5#ifndef BITBLOCK128_H_
6#define BITBLOCK128_H_
7/*=============================================================================
8    bitblock128 - Specific 128 bit IDISA implementations.
9
10    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy, Hua Huang and Nigel Medforth.
11    Licensed to the public under the Open Software License 3.0.
12    Licensed to International Characters Inc.
13       under the Academic Free License version 3.0.
14
15=============================================================================*/
16
17#include "idisa128_c.h"
18#include "builtins.h"
19
20union ubitblock {
21        bitblock128_t _128;
22        uint64_t _64[sizeof(bitblock128_t)/sizeof(uint64_t)];
23        uint32_t _32[sizeof(bitblock128_t)/sizeof(uint32_t)];
24        uint16_t _16[sizeof(bitblock128_t)/sizeof(uint16_t)];
25        uint8_t _8[sizeof(bitblock128_t)/sizeof(uint8_t)];
26};
27
28static IDISA_ALWAYS_INLINE void add_ci_co(bitblock128_t x, bitblock128_t y, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & sum);
29static IDISA_ALWAYS_INLINE void sub_bi_bo(bitblock128_t x, bitblock128_t y, bitblock128_t borrow_in, bitblock128_t & borrow_out, bitblock128_t & difference);
30static IDISA_ALWAYS_INLINE void adv_ci_co(bitblock128_t cursor, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & rslt);
31
32/* The type used to store a carry bit. */
33typedef bitblock128_t carry_t;
34
35
36
37
38
39static IDISA_ALWAYS_INLINE bitblock128_t carry2bitblock(carry_t carry);
40static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock128_t carry);
41
42static IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t & carry, bitblock128_t & sum);
43static IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t & borrow, bitblock128_t & difference);
44static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t & carry, bitblock128_t & rslt);
45
46static IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t carry_in, carry_t & carry_out, bitblock128_t & sum);
47static IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t borrow_in, carry_t & borrow_out, bitblock128_t & difference);
48static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t carry_in, carry_t & carry_out, bitblock128_t & rslt);
49
50static IDISA_ALWAYS_INLINE bitblock128_t convert (uint64_t s);
51static IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v);
52
53static IDISA_ALWAYS_INLINE bitblock128_t carry2bitblock(carry_t carry) {  return carry;} 
54static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock128_t carry) {  return carry;}
55
56
57
58
59static IDISA_ALWAYS_INLINE void add_ci_co(bitblock128_t x, bitblock128_t y, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & sum) {
60        bitblock128_t gen = simd_and(x, y);
61        bitblock128_t prop = simd_or(x, y);
62        bitblock128_t partial = simd_add_64(simd_add_64(x, y), carry_in);
63        bitblock128_t c1 = simd_slli_128(64, simd_srli_64(63, simd_or(gen, simd_andc(prop, partial))));
64        sum = simd_add_64(c1, partial);
65        carry_out = simd_or(gen, simd_andc(prop, sum));
66}
67static IDISA_ALWAYS_INLINE void sub_bi_bo(bitblock128_t x, bitblock128_t y, bitblock128_t borrow_in, bitblock128_t & borrow_out, bitblock128_t & difference){
68        bitblock128_t gen = simd_andc(y, x);
69        bitblock128_t prop = simd_not(simd_xor(x, y));
70        bitblock128_t partial = simd_sub_64(simd_sub_64(x, y), borrow_in);
71        bitblock128_t b1 = simd_slli_128(64, simd_srli_64(63, simd_or(gen, simd_and(prop, partial))));
72        difference = simd_sub_64(partial, b1);
73        borrow_out = simd_or(gen, simd_and(prop, difference));
74}
75static IDISA_ALWAYS_INLINE void adv_ci_co(bitblock128_t cursor, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & rslt){
76        bitblock128_t shift_out = simd_srli_64(63, cursor);
77        bitblock128_t low_bits = esimd_mergel_64(shift_out, carry_in);
78        carry_out = cursor;
79        rslt = simd_or(simd_add_64(cursor, cursor), low_bits);
80}
81
82IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t & carry, bitblock128_t & sum)
83{
84        bitblock128_t gen = simd_and(x, y);
85        bitblock128_t prop = simd_or(x, y);
86        bitblock128_t partial = simd_add_64(simd_add_64(x, y), carry2bitblock(carry));
87        bitblock128_t c1 = simd_slli_128(64, simd_srli_64(63, simd_or(gen, simd_andc(prop, partial))));
88        sum = simd_add_64(c1, partial);
89        carry = bitblock2carry(simd_srli_128(127, simd_or(gen, simd_andc(prop, sum))));
90}
91
92IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t carry_in, carry_t & carry_out, bitblock128_t & sum)
93{
94        bitblock128_t co;
95        add_ci_co(x, y, carry2bitblock(carry_in), co, sum);
96        carry_out = bitblock2carry(simd_srli_128(127, co));
97}
98
99IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t & borrow, bitblock128_t & difference)
100{
101        bitblock128_t gen = simd_andc(y, x);
102        bitblock128_t prop = simd_not(simd_xor(x, y));
103        bitblock128_t partial = simd_sub_64(simd_sub_64(x, y), carry2bitblock(borrow));
104        bitblock128_t b1 = simd_slli_128(64, simd_srli_64(63, simd_or(gen, simd_and(prop, partial))));
105        difference = simd_sub_64(partial, b1);
106        borrow = bitblock2carry(simd_srli_128(127, simd_or(gen, simd_and(prop, difference))));
107}
108
109IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t borrow_in, carry_t & borrow_out, bitblock128_t & difference)
110{
111        bitblock128_t bo;
112        sub_bi_bo(x, y, carry2bitblock(borrow_in), bo, difference);
113        borrow_out = bitblock2carry(simd_srli_128(127, bo));
114}
115
116IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t & carry, bitblock128_t & rslt)
117{
118bitblock128_t shift_out = simd_srli_64(63, cursor);
119bitblock128_t low_bits = esimd_mergel_64(shift_out, carry2bitblock(carry));
120carry = bitblock2carry(simd_srli_128(64, shift_out));
121rslt = simd_or(simd_add_64(cursor, cursor), low_bits);
122}
123
124IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t carry_in, carry_t & carry_out, bitblock128_t & rslt)
125{
126bitblock128_t shift_out = simd_srli_64(63, cursor);
127bitblock128_t low_bits = esimd_mergel_64(shift_out, carry2bitblock(carry_in));
128carry_out = bitblock2carry(simd_srli_128(64, shift_out));
129rslt = simd_or(simd_add_64(cursor, cursor), low_bits);
130}
131
132IDISA_ALWAYS_INLINE bitblock128_t convert(uint64_t s)
133{
134        ubitblock b;
135        b._128 = simd_constant_128(0);
136        b._64[0] = s;
137        return b._128;
138}
139
140IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v)
141{
142        return (uint64_t) mvmd_extract_64(0, v);
143}
144
145#endif // BITBLOCK128_H_
146
Note: See TracBrowser for help on using the repository browser.