source: trunk/lib/carryQ.hpp @ 1584

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

Initial carryQ.hpp check in. CarryArray? implemented. CarryRegister? structure only.

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