source: trunk/lib/carryQ.hpp @ 2006

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

clean out old _ci, _ci_co wrappers

File size: 5.9 KB
Line 
1#ifndef CARRYQ_HPP_
2#define CARRYQ_HPP_
3
4/*=============================================================================
5  carryQ.hpp - Pablo compiler support for carry introduction.
6  Ken Herdy, Robert D. Cameron
7  April 2012
8=============================================================================*/
9
10#include <stdint.h>
11#include <iostream>
12using namespace std;
13
14#include "bitblock.hpp"
15#include "stdio.h"
16
17///////////////////////////////////////////////////////////////////////////////
18//
19// Carry method variants.
20//
21// BitBlock_op_ci_co()  - standard block non while loop statement and in final block if ignore the carry out
22// BitBlock_op_co()     - standard block while loop and in final block while loop if ignore carry out
23// BitBlock_op_ci()             - final block non while loop statement
24// BitBlock_op()                - final while loop statement
25//
26// BitBlock_op_ci(), BitBlock_op() methods not implemented to reduce the total number of
27// methods and Pablo compiler complexity.
28//
29///////////////////////////////////////////////////////////////////////////////
30
31#define interpose32(x,y,pos) interpose32_<pos>(x,y)     
32template<uint32_t n>
33IDISA_ALWAYS_INLINE BitBlock interpose32_(BitBlock s, BitBlock s32) {
34        return simd_or(simd<32>::slli<n>(s), simd<32>::srli<32-n>(s32));
35}
36
37// Abstract Base Class
38class ICarryQueue {
39
40        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, BitBlock carryin, uint16_t carryno);
41        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, const uint16_t carryno);
42        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, uint16_t carryno);
43
44        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, BitBlock carryin, uint16_t carryno);
45        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno);
46        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t pending_in, uint32_t & pending_out);
47
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
53        IDISA_ALWAYS_INLINE BitBlock get_carry_in(uint16_t carryno) const ;
54protected:
55        ICarryQueue(){};
56        ~ICarryQueue(){};
57        // helpers
58        IDISA_ALWAYS_INLINE BitBlock carry_flip(BitBlock carry) const ;
59        IDISA_ALWAYS_INLINE bool test_carry(BitBlock carry) const ;
60        IDISA_ALWAYS_INLINE BitBlock carry_or(BitBlock carry1, BitBlock carry2) const ;
61};
62
63#include <string.h>
64
65// Array of BitBlock implementation.
66template <uint16_t CarryCount>
67class CarryArray: public ICarryQueue{
68
69public:
70
71    #define Carry0 simd<BLOCK_SIZE>::constant<0>()
72    #define Carry1 simd<BLOCK_SIZE>::constant<1>()
73 
74        CarryArray()
75        {
76            memset (cq, 0, sizeof(BitBlock) * CarryCount);// size_t num )
77        }
78        ~CarryArray() {}
79
80        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, BitBlock carryin, uint16_t carryno)
81        {
82                BitBlock rslt;
83                advance_with_carry(strm, carryin, cq[carryno], rslt);
84                return rslt;
85        }
86
87        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, const uint16_t carryno)
88        {
89                BitBlock sum;
90                adc(strm1, strm2, carryin, cq[carryno], sum);
91                return sum;
92        }
93
94        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, uint16_t carryno)
95        {
96                BitBlock diff;
97                sbb(strm1, strm2, carryin, cq[carryno], diff);
98                return diff;
99        }
100
101        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, BitBlock carryin, uint16_t carryno)
102        {
103                BitBlock marker;
104                BitBlock c = carry_flip(carryin);
105                adc(simd<BLOCK_SIZE>::constant<0>(), simd_not(charclass), c, marker);
106                cq[carryno] = carry_flip(c);
107                return simd_and(marker, charclass);
108        }
109
110        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno)
111        {
112                BitBlock markers1;
113                adc(markers0, charclass, carryin, cq[carryno], markers1);
114                return simd_andc(markers1, charclass);
115        }
116
117        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t pending_in, uint32_t & pending_out)
118        {
119                pending_out = (uint32_t) mvmd<32>::extract< (sizeof(BitBlock)/sizeof(pending_out))-1 >(strm);
120                return simd_or(simd<BLOCK_SIZE>::slli<32>(strm), mvmd<BLOCK_SIZE>::fill((uint64_t)pending_in));
121        }
122
123        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count)
124        {
125                  BitBlock c1 = cq[carryno];
126                  int ubound = carryno + carry_count;
127                  for (int i = carryno + 1; i < ubound ; i++) {
128                        c1 = carry_or(c1, cq[i]);
129                  }
130                  return test_carry(c1);
131        }
132
133        IDISA_ALWAYS_INLINE void CarryDequeueEnqueue(uint16_t carryno, uint16_t carry_count)
134        {
135                return;
136        }
137
138        IDISA_ALWAYS_INLINE void CarryQ_Adjust(uint16_t carry_count)
139        {
140                return;
141        }
142
143        IDISA_ALWAYS_INLINE void CarryCombine(ICarryQueue * carryqueue, uint16_t carryno, uint16_t carry_count)
144        {
145                  BitBlock * local_cq = ((CarryArray *)carryqueue)->cq;
146                  for (int i = 0; i < carry_count; i++) {
147                    cq[carryno+i] = carry_or(cq[carryno+i], local_cq[i]);
148                  }
149        }
150
151        IDISA_ALWAYS_INLINE BitBlock get_carry_in(uint16_t carryno) const 
152        {
153                return carry2bitblock(cq[carryno]);
154        }
155
156private:
157        BitBlock cq[CarryCount];
158
159        // helpers
160        IDISA_ALWAYS_INLINE BitBlock carry_flip(BitBlock carry) const
161        {
162                return simd_xor(carry, Carry1);
163        }
164
165        IDISA_ALWAYS_INLINE bool test_carry(BitBlock carry) const
166        {
167                return bitblock::any(carry);
168        }
169
170        IDISA_ALWAYS_INLINE BitBlock carry_or(BitBlock carry1, BitBlock carry2) const
171        {
172                return simd_or(carry1, carry2);
173        }
174       
175#undef Carry0
176#undef Carry1
177
178};
179
180// Single bit per carry implementation.
181template <class BitBlock, uint16_t CarryCount>
182class CarryRegister: public ICarryQueue {
183
184public:
185        CarryRegister() {}
186        ~CarryRegister() {}
187
188private:
189        BitBlock cq;
190};
191
192#endif // CARRYQ_HPP_
Note: See TracBrowser for help on using the repository browser.