source: trunk/lib_c/carryQ.h @ 4067

Last change on this file since 4067 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: 8.3 KB
Line 
1/* Generated by cpp2c.rb from ./carryQ.hpp
2 * Use IDISA C support
3*/
4
5#ifndef CARRYQ_H_
6#define CARRYQ_H_
7
8/*=============================================================================
9  carryQ.hpp - Pablo compiler support for carry introduction.
10  Ken Herdy, Robert D. Cameron
11  Copyright (C) 2012, Robert D. Cameron, Kenneth S. Herdy.
12    Licensed to the public under the Open Software License 3.0.
13    Licensed to International Characters Inc.
14       under the Academic Free License version 3.0.
15  April 2012
16=============================================================================*/
17
18#include <string.h>
19#include <stdint.h>
20#include <iostream>
21
22#include "bitblock.h"
23#include "stdio.h"
24
25///////////////////////////////////////////////////////////////////////////////
26//
27// Carry method variants.
28//
29// BitBlock_op_ci_co()  - standard block non while loop statement and in final block if ignore the carry out
30// BitBlock_op_co()     - standard block while loop and in final block while loop if ignore carry out
31// BitBlock_op_ci()             - final block non while loop statement
32// BitBlock_op()                - final while loop statement
33//
34// BitBlock_op_ci(), BitBlock_op() methods not implemented to reduce the total number of
35// methods and Pablo compiler complexity.
36//
37///////////////////////////////////////////////////////////////////////////////
38
39#define interpose32(x,y,pos) interpose32_<pos>(x,y)     
40template<uint32_t n>
41IDISA_ALWAYS_INLINE BitBlock interpose32_(BitBlock s, BitBlock s32) {
42        return simd_or(simd_slli_32(n, s), simd_srli_32(32-n, s32));
43}
44
45template<uint32_t n>
46IDISA_ALWAYS_INLINE BitBlock interpose64_(BitBlock s, BitBlock s64) {
47        return simd_or(simd_slli_64(n, s), simd_srli_64(64-n, s64));
48}
49
50template <uint16_t CarryCount, uint16_t AdvanceNCount> class CarryArray;
51
52#define LocalCarryCombine(carrySet, localCarry, carryNo, carryCount)\
53        carrySet.CarryCombine(localCarry.cq, carryNo, carryCount); 
54
55#define CarryDeclare(name, carry1_count, carryN_count)\
56CarryArray<carry1_count, carryN_count> name;
57
58// Array of BitBlock implementation.
59template <uint16_t CarryCount, uint16_t AdvanceNCount>
60class CarryArray {
61
62public:
63
64#if (BLOCK_SIZE == 128)
65    #define Carry0 simd_constant_128(0)
66    #define Carry1 simd_constant_128(1)
67#else
68    #define Carry0 simd_constant_256(0)
69    #define Carry1 simd_constant_256(1)
70#endif
71 
72        BitBlock cq[CarryCount + AdvanceNCount];
73        //BitBlock pending64[AdvanceNCount];
74        CarryArray()
75        {
76            memset (cq, 0, sizeof(BitBlock) * (CarryCount + AdvanceNCount));
77            //memset(pending64, 0, sizeof(BitBlock) * AdvanceNCount);
78        }
79        ~CarryArray() {}
80
81        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, BitBlock carryin, uint16_t carryno)
82        {
83                BitBlock rslt;
84                advance_with_carry(strm, carryin, cq[carryno], rslt);
85                return rslt;
86        }
87
88        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, const uint16_t carryno)
89        {
90                BitBlock sum;
91                adc(strm1, strm2, carryin, cq[carryno], sum);
92                return sum;
93        }
94
95        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, uint16_t carryno)
96        {
97                BitBlock diff;
98                sbb(strm1, strm2, carryin, cq[carryno], diff);
99                return diff;
100        }
101
102        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, BitBlock carryin, uint16_t carryno)
103        {
104                BitBlock marker;
105//              BitBlock c = carry_flip(carryin);
106#if (BLOCK_SIZE == 128)
107                adc(simd_constant_128(0), simd_not(charclass), carryin, cq[carryno], marker);
108#else
109                adc(simd_constant_256(0), simd_not(charclass), carryin, cq[carryno], marker);
110#endif
111//              cq[carryno] = carry_flip(cq[carryno]);
112                return simd_and(marker, charclass);
113        }
114
115        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno)
116        {
117                BitBlock markers1;
118                adc(markers0, charclass, carryin, cq[carryno], markers1);
119                return simd_andc(markers1, charclass);
120        }
121
122        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_then_scanthru(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno)
123        {
124                BitBlock markers1;
125                //assert(!bitblock_any(simd_and(markers0, charclass)));
126                adc(markers0, simd_or(charclass, markers0), carryin, cq[carryno], markers1);
127                return simd_andc(markers1, charclass);
128        }
129
130        IDISA_ALWAYS_INLINE BitBlock BitBlock_span_upto(BitBlock starts, BitBlock follows, BitBlock carryin, uint16_t carryno)
131        {
132                BitBlock span;
133                sbb(follows, starts, carryin, cq[carryno], span);
134                return span;
135        }
136
137        IDISA_ALWAYS_INLINE BitBlock BitBlock_inclusive_span(BitBlock starts, BitBlock ends, BitBlock carryin, uint16_t carryno)
138        {
139                BitBlock span;
140                sbb(ends, starts, carryin, cq[carryno], span);
141                return simd_or(span, ends);
142        }
143
144        IDISA_ALWAYS_INLINE BitBlock BitBlock_exclusive_span(BitBlock starts, BitBlock ends, BitBlock carryin, uint16_t carryno)
145        {
146                BitBlock span;
147                sbb(ends, starts, carryin, cq[carryno], span);
148                return simd_andc(span, starts);
149        }
150
151
152        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t pending_in, uint32_t & pending_out)
153        {
154                pending_out = (uint32_t) mvmd_extract_32( (sizeof(BitBlock)/sizeof(pending_out))-1 , strm);
155#if (BLOCK_SIZE == 128)
156                return simd_or(simd_slli_128(32, strm), mvmd_fill_128((uint64_t)pending_in));
157#else
158                return simd_or(simd_slli_256(32, strm), mvmd_fill_256((uint64_t)pending_in));
159#endif
160        }
161
162        template <int n> IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_n_(BitBlock strm, BitBlock pending_in, uint16_t pendingno)
163        {
164#if (BLOCK_SIZE == 128)
165                BitBlock half_block_shifted = esimd_mergel_64(strm, pending_in);
166#else
167                BitBlock half_block_shifted = esimd_mergel_128(strm, pending_in);
168#endif
169                cq[CarryCount + pendingno] = bitblock_srli(BLOCK_SIZE/2, strm);
170                //pending64[pendingno] = bitblock_srli(BLOCK_SIZE/2, strm);
171#if (BLOCK_SIZE == 128)
172                BitBlock result = simd_or(simd_srli_64((BLOCK_SIZE/2)-n, half_block_shifted),
173                               simd_slli_64(n, strm));
174#else
175                BitBlock result = simd_or(simd_srli_128((BLOCK_SIZE/2)-n, half_block_shifted),
176                               simd_slli_128(n, strm));
177#endif
178                return result;
179        }
180
181        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count)
182        {
183                  BitBlock c1 = cq[carryno];
184                  int ubound = carryno + carry_count;
185                  for (int i = carryno + 1; i < ubound ; i++) {
186                        c1 = carry_or(c1, cq[i]);
187                  }
188                  return test_carry(c1);
189        }
190
191        IDISA_ALWAYS_INLINE BitBlock CarryRange(uint16_t carryno, uint16_t carry_count)
192        {
193                  BitBlock c1 = cq[carryno];
194                  int ubound = carryno + carry_count;
195                  for (int i = carryno + 1; i < ubound ; i++) {
196                        c1 = carry_or(c1, cq[i]);
197                  }
198                  return c1;
199        }
200
201        IDISA_ALWAYS_INLINE void CarryDequeueEnqueue(uint16_t carryno, uint16_t carry_count)
202        {
203                return;
204        }
205
206        // Deprecated (renamed)
207        IDISA_ALWAYS_INLINE void CarryQ_Adjust(uint16_t carry_count)
208        {
209                return;
210        }
211
212        IDISA_ALWAYS_INLINE void CarryAdjust(uint16_t carry_count)
213        {
214                return;
215        }
216
217        IDISA_ALWAYS_INLINE void CarryCombine(BitBlock local_cq[], uint16_t carryno, uint16_t carry_count)
218        {
219                  for (int i = 0; i < carry_count; i++) {
220                    cq[carryno+i] = carry_or(cq[carryno+i], local_cq[i]);
221                  }
222        }
223
224        IDISA_ALWAYS_INLINE void CarryCombine1(uint16_t carryno, uint16_t carry2)
225        {
226                  cq[carryno] = carry_or(cq[carryno], cq[carry2]);
227                  cq[carry2] = Carry0;
228        }
229
230        IDISA_ALWAYS_INLINE BitBlock get_carry_in(uint16_t carryno) const 
231        {
232                return carry2bitblock(cq[carryno]);
233        }
234
235        // Deprecated (renamed)
236        IDISA_ALWAYS_INLINE BitBlock GetCarry(uint16_t carryno) const
237        {
238                return carry2bitblock(cq[carryno]);
239        }
240
241        IDISA_ALWAYS_INLINE void SetCarry(BitBlock carryVal, uint16_t carryno)
242        {
243                cq[carryno] = carryVal;
244        }
245
246
247        // Deprecated in PabloJ, retained for legacy compiler.
248        IDISA_ALWAYS_INLINE BitBlock get_pending64(uint16_t advance_n_blkno) const 
249        {
250                return cq[CarryCount + advance_n_blkno];
251        }
252
253        IDISA_ALWAYS_INLINE BitBlock Pending64(uint16_t advance_n_blkno) const 
254        {
255                return cq[CarryCount + advance_n_blkno];
256        }
257
258//private:
259        // helpers
260
261        // Deprecated (renamed)
262        IDISA_ALWAYS_INLINE BitBlock carry_flip(BitBlock carry) const
263        {
264                return simd_xor(carry, Carry1);
265        }
266
267        IDISA_ALWAYS_INLINE BitBlock CarryFlip(BitBlock carry) const
268        {
269                return simd_xor(carry, Carry1);
270        }
271
272        IDISA_ALWAYS_INLINE bool test_carry(BitBlock carry) const
273        {
274                return bitblock_any(carry);
275        }
276
277        IDISA_ALWAYS_INLINE BitBlock carry_or(BitBlock carry1, BitBlock carry2) const
278        {
279                return simd_or(carry1, carry2);
280        }
281       
282#undef Carry0
283#undef Carry1
284
285};
286
287#endif // CARRYQ_H_
288
Note: See TracBrowser for help on using the repository browser.