source: trunk/lib/carryQ.hpp @ 1694

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

Fixed BitBlock_advance32

File size: 7.0 KB
Line 
1/*
2 * carryQ.hpp
3 */
4
5#ifndef CARRYQ_HPP_
6#define CARRYQ_HPP_
7
8#include <stdint.h>
9#include <iostream>
10using namespace std;
11
12#include "bitblock.hpp"
13#include "stdio.h"
14
15/*
16 * Carry method variants.
17 *
18 * BitBlock_op_ci_co()  - standard block non while loop statement and in final block if ignore the carry out
19 * BitBlock_op_co()     - standard block while loop and in final block while loop if ignore carry out
20 * BitBlock_op_ci()             - final block non while loop statement
21 * BitBlock_op()                - final while loop statement
22 *
23 * BitBlock_op_ci(), BitBlock_op() methods not implemented to reduce the total number of
24 * methods and Pablo compiler complexity.
25 *
26 */
27
28#define interpose32(x,y,pos) interpose32_<pos>(x,y)     
29template<uint32_t n>
30IDISA_ALWAYS_INLINE BitBlock interpose32_(BitBlock s, BitBlock s32) {
31        return simd_or(simd<32>::slli<n>(s), simd<32>::srli<32-n>(s32));
32}
33
34// Abstract Base Class
35class ICarryQueue {
36
37        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, uint16_t carryno);
38        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_co(BitBlock strm, uint16_t carryno);
39        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, const uint16_t carryno);
40        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_co(BitBlock strm1, BitBlock strm2, uint16_t carryno);
41        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, uint16_t carryno);
42        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_co(BitBlock strm1, BitBlock strm2, uint16_t carryno);
43        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, uint16_t carryno);
44        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, uint16_t carryno);
45        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_co(BitBlock markers0, BitBlock charclass, uint16_t carryno);
46        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t & pending);
47        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_co(BitBlock strm, uint32_t & pending);
48        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count);
49        IDISA_ALWAYS_INLINE void CarryDequeueEnqueue(uint16_t carryno, uint16_t carry_count);
50        IDISA_ALWAYS_INLINE void CarryQ_Adjust(uint16_t carry_count);
51        IDISA_ALWAYS_INLINE void CarryCombine(ICarryQueue carryqueue, uint16_t carryno, uint16_t carry_count);
52
53protected:
54        ICarryQueue(){};
55        ~ICarryQueue(){};
56        // helpers
57        IDISA_ALWAYS_INLINE BitBlock carry_flip(BitBlock carry) const ;
58        IDISA_ALWAYS_INLINE bool test_carry(BitBlock carry) const ;
59        IDISA_ALWAYS_INLINE BitBlock carry_or(BitBlock carry1, BitBlock carry2) const ;
60};
61
62#include <string.h>
63
64// Array of BitBlock implementation.
65template <uint16_t CarryCount>
66class CarryArray: public ICarryQueue {
67
68public:
69        CarryArray()
70        {
71                Carry0 = simd<BLOCK_SIZE>::constant<0>();
72                Carry1 = simd<BLOCK_SIZE>::constant<1>();
73
74                memset (cq, 0, sizeof(BitBlock) * CarryCount);// size_t num )
75        }
76        ~CarryArray() {}
77
78        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, uint16_t carryno)
79        {
80                BitBlock rslt;
81                advance_with_carry(strm, cq[carryno], rslt);
82                return rslt;
83        }
84
85        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_co(BitBlock strm, uint16_t carryno)
86        {
87                BitBlock rslt;
88                cq[carryno] = Carry0;
89                advance_with_carry(strm, cq[carryno], rslt);
90                return rslt;
91        }
92
93        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, const uint16_t carryno)
94        {
95                BitBlock sum;
96                adc(strm1, strm2, cq[carryno], sum);
97                return sum;
98        }
99
100        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_co(BitBlock strm1, BitBlock strm2, uint16_t carryno)
101        {
102                BitBlock sum;
103                cq[carryno] = Carry0;
104                adc(strm1, strm2, cq[carryno], sum);
105                return sum;
106        }
107
108        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, uint16_t carryno)
109        {
110                BitBlock diff;
111                sbb(strm1, strm2, cq[carryno], diff);
112                return diff;
113        }
114
115        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_co(BitBlock strm1, BitBlock strm2, uint16_t carryno)
116        {
117                BitBlock diff;
118                cq[carryno] = Carry0;
119                sbb(strm1, strm2, cq[carryno], diff);
120                return diff;
121        }
122
123        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, uint16_t carryno)
124        {
125                BitBlock marker;
126                BitBlock c = carry_flip(cq[carryno]);
127                adc(simd<BLOCK_SIZE>::constant<0>(), simd_not(charclass), c, marker);
128                cq[carryno] = carry_flip(c);
129                return simd_and(marker, charclass);
130        }
131
132        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, uint16_t carryno)
133        {
134                BitBlock markers1;
135                adc(markers0, charclass, cq[carryno], markers1);
136                return simd_andc(markers1, charclass);
137        }
138
139        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_co(BitBlock markers0, BitBlock charclass, uint16_t carryno)
140        {
141                BitBlock markers1;
142                cq[carryno] = Carry0;
143                adc(markers0, charclass, cq[carryno], markers1);
144                return simd_andc(markers1, charclass);
145        }
146
147        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t & pending)
148        {
149                uint32_t temp = pending;
150                pending = (uint32_t) mvmd<32>::extract< (sizeof(BitBlock)/sizeof(pending))-1 >(strm);
151                return simd_or(simd<BLOCK_SIZE>::slli<32>(strm), mvmd<BLOCK_SIZE>::fill((uint64_t)temp));
152        }
153
154        /*
155        static inline BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t & pending){
156                uint32_t temp = pending;
157                pending = sisd_to_int(sisd_srli(strm,96));
158                return simd_or(sisd_slli(strm, 32), sisd_from_int(temp));
159        }
160        */
161
162        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_co(BitBlock strm, uint32_t & pending)
163        {
164                pending = (uint32_t) mvmd<32>::extract<(sizeof(BitBlock)/sizeof(pending))-1>(strm);
165                return mvmd<32>::slli<1>(strm);
166        }
167
168        /*
169        static inline BitBlock BitBlock_advance32_co(BitBlock strm, uint32_t & pending) {
170                pending = sisd_to_int(sisd_srli(strm,96));
171                return sisd_slli(strm, 32);
172        }
173        */
174
175        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count)
176        {
177                  BitBlock c1 = cq[carryno];
178                  int ubound = carryno + carry_count;
179                  for (int i = carryno + 1; i < ubound ; i++) {
180                        c1 = carry_or(c1, cq[i]);
181                  }
182                  return test_carry(c1);
183        }
184
185        IDISA_ALWAYS_INLINE void CarryDequeueEnqueue(uint16_t carryno, uint16_t carry_count)
186        {
187                return;
188        }
189
190        IDISA_ALWAYS_INLINE void CarryQ_Adjust(uint16_t carry_count)
191        {
192                return;
193        }
194
195        IDISA_ALWAYS_INLINE void CarryCombine(const BitBlock local_cq[], uint16_t carryno, uint16_t carry_count)
196        {
197                  for (int i = 0; i < carry_count; i++) {
198                    cq[carryno+i] = carry_or(cq[carryno+i], local_cq[i]);
199                  }
200        }
201
202        /* read-only */
203        IDISA_ALWAYS_INLINE const BitBlock * array() const
204        {
205                return cq;
206        }
207
208private:
209        BitBlock cq[CarryCount];
210        BitBlock Carry0;
211        BitBlock Carry1;
212
213        // helpers
214        IDISA_ALWAYS_INLINE BitBlock carry_flip(BitBlock carry) const
215        {
216                return simd_xor(carry, Carry1);
217        }
218
219        IDISA_ALWAYS_INLINE bool test_carry(BitBlock carry) const
220        {
221                return bitblock_has_bit(carry);
222        }
223
224        IDISA_ALWAYS_INLINE BitBlock carry_or(BitBlock carry1, BitBlock carry2) const
225        {
226                return simd_or(carry1, carry2);
227        }
228
229};
230
231// Single bit per carry implementation.
232template <class BitBlock, uint16_t CarryCount>
233class CarryRegister: public ICarryQueue {
234
235public:
236        CarryRegister() {}
237        ~CarryRegister() {}
238
239private:
240        BitBlock cq;
241};
242
243#endif /* CARRYQ_HPP_ */
Note: See TracBrowser for help on using the repository browser.