[3391] | 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) |
---|
| 40 | template<uint32_t n> |
---|
| 41 | IDISA_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 | |
---|
| 45 | template<uint32_t n> |
---|
| 46 | IDISA_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 | |
---|
| 50 | template <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)\ |
---|
| 56 | CarryArray<carry1_count, carryN_count> name; |
---|
| 57 | |
---|
| 58 | // Array of BitBlock implementation. |
---|
| 59 | template <uint16_t CarryCount, uint16_t AdvanceNCount> |
---|
| 60 | class CarryArray { |
---|
| 61 | |
---|
| 62 | public: |
---|
| 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 | |
---|