[3391] | 1 | /*============================================================================= |
---|
| 2 | pabloSupport.hpp - Pablo compiler support for carry introduction. |
---|
| 3 | Will replace deprecated carryQ.hpp |
---|
| 4 | Copyright (C) 2012, Robert D. Cameron |
---|
| 5 | Licensed to the public under the Open Software License 3.0. |
---|
| 6 | Licensed to International Characters Inc. |
---|
| 7 | under the Academic Free License version 3.0. |
---|
| 8 | December 2012 |
---|
| 9 | =============================================================================*/ |
---|
| 10 | #ifndef PABLOSUPPORT_HPP_ |
---|
| 11 | #define PABLOSUPPORT_HPP_ |
---|
| 12 | |
---|
| 13 | #include <simd-lib/bitblock.hpp> |
---|
| 14 | |
---|
| 15 | #define BitBlock_declare(name) BitBlock name |
---|
| 16 | |
---|
| 17 | #define ubitblock_declare(name, n) \ |
---|
| 18 | ubitblock name[n];\ |
---|
| 19 | do {int i;\ |
---|
| 20 | for (i = 0; i < n; i++) name[i]._128 = simd<1>::constant<0>();\ |
---|
| 21 | }\ |
---|
| 22 | while (0) |
---|
| 23 | |
---|
| 24 | |
---|
| 25 | const BitBlock simd_const_1 = mvmd<BLOCK_SIZE/4>::fill4(0,0,0,1); |
---|
| 26 | |
---|
| 27 | const BitBlock simd_sign_bit = bitblock::slli<BLOCK_SIZE-1>(simd_const_1); |
---|
| 28 | |
---|
| 29 | IDISA_ALWAYS_INLINE BitBlock Dequeue_bit(BitBlock & q) { |
---|
| 30 | BitBlock bit = simd_and(q, simd_const_1); |
---|
| 31 | q = simd<64>::srli<1>(q); |
---|
| 32 | return bit; |
---|
| 33 | } |
---|
| 34 | |
---|
| 35 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_Advance(BitBlock strm, BitBlock carryin, BitBlock & rslt) { |
---|
| 36 | BitBlock carryout; |
---|
| 37 | adv_ci_co(strm, carryin, carryout, rslt); |
---|
| 38 | return carryout; |
---|
| 39 | } |
---|
| 40 | |
---|
| 41 | template <int n> IDISA_ALWAYS_INLINE BitBlock pablo_blk_Advance_n_(BitBlock strm, BitBlock pending_in, BitBlock & rslt) { |
---|
| 42 | BitBlock half_block_shifted = esimd<BLOCK_SIZE/2>::mergel(strm, pending_in); |
---|
| 43 | rslt = simd_or(simd<BLOCK_SIZE/2>::srli<(BLOCK_SIZE/2)-n>(half_block_shifted), |
---|
| 44 | simd<BLOCK_SIZE/2>::slli<n>(strm)); |
---|
| 45 | return strm; |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | template <int fw, int n> IDISA_ALWAYS_INLINE BitBlock pablo_blk_Advance_n_(BitBlock strm, BitBlock pending_in, BitBlock & rslt) { |
---|
| 49 | BitBlock shifted = mvmd<fw>::dslli<1>(strm, pending_in); |
---|
| 50 | rslt = simd_or(simd<BLOCK_SIZE/2>::srli<fw-n>(shifted), |
---|
| 51 | simd<BLOCK_SIZE/2>::slli<n>(strm)); |
---|
| 52 | return strm; |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | /* Support for pablo.Lookahead. 2 translation modes: |
---|
| 56 | (a) pablo.Lookahead(ss.strm, n) ==> pablo_blk_Lookahead_n_<n>(ss_curblock.strm, ss_nxtblock.strm); |
---|
| 57 | (b) pablo.Lookahead(ss.strm, n) ==> pablo_blk_Lookahead_n_<n>(ss[0].strm, ss[1].strm); |
---|
| 58 | */ |
---|
| 59 | template <int n> IDISA_ALWAYS_INLINE BitBlock pablo_blk_Lookahead_n_(BitBlock strm, BitBlock lookahead) { |
---|
| 60 | BitBlock half_block_shifted = mvmd<BLOCK_SIZE/2>::dslli<1>(lookahead, strm); |
---|
| 61 | return simd_or(simd<BLOCK_SIZE/2>::slli<(BLOCK_SIZE/2)-n>(half_block_shifted), |
---|
| 62 | simd<BLOCK_SIZE/2>::srli<n>(strm)); |
---|
| 63 | } |
---|
| 64 | |
---|
| 65 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_ScanThru(BitBlock marker, BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 66 | BitBlock carryout, sum; |
---|
| 67 | add_ci_co(marker, charclass, carryin, carryout, sum); |
---|
| 68 | rslt = simd_andc(sum, charclass); |
---|
| 69 | return carryout; |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_MatchStar(BitBlock marker, BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 73 | BitBlock carryout, sum; |
---|
| 74 | add_ci_co(simd_and(charclass, marker), charclass, carryin, carryout, sum); |
---|
| 75 | rslt = simd_or(simd_xor(sum, charclass), marker); |
---|
| 76 | return carryout; |
---|
| 77 | } |
---|
| 78 | |
---|
| 79 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_AdvanceThenScanThru(BitBlock marker, BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 80 | BitBlock carryout, sum; |
---|
| 81 | add_ci_co(marker, simd_or(charclass, marker), carryin, carryout, sum); |
---|
| 82 | rslt = simd_andc(sum, charclass); |
---|
| 83 | return carryout; |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_ScanTo(BitBlock marker, BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 87 | BitBlock carryout, sum; |
---|
| 88 | add_ci_co(marker, simd_not(charclass), carryin, carryout, sum); |
---|
| 89 | rslt = simd_and(sum, charclass); |
---|
| 90 | return carryout; |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_AdvanceThenScanTo(BitBlock marker, BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 94 | BitBlock carryout, sum; |
---|
| 95 | add_ci_co(marker, simd_or(marker, simd_not(charclass)), carryin, carryout, sum); |
---|
| 96 | rslt = simd_and(sum, charclass); |
---|
| 97 | return carryout; |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_ScanToFirst(BitBlock charclass, BitBlock carryin, BitBlock & rslt) { |
---|
| 101 | BitBlock carryout, sum; |
---|
| 102 | add_ci_co(simd<BLOCK_SIZE>::constant<0>(), simd_not(charclass), carryin, carryout, sum); |
---|
| 103 | rslt = simd_and(sum, charclass); |
---|
| 104 | return carryout; |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_SpanUpTo(BitBlock starts, BitBlock follows, BitBlock carryin, BitBlock & rslt) { |
---|
| 108 | BitBlock carryout; |
---|
| 109 | sub_bi_bo(follows, starts, carryin, carryout, rslt); |
---|
| 110 | return carryout; |
---|
| 111 | } |
---|
| 112 | |
---|
| 113 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_InclusiveSpan(BitBlock starts, BitBlock follows, BitBlock carryin, BitBlock & rslt) { |
---|
| 114 | BitBlock carryout, span; |
---|
| 115 | sub_bi_bo(follows, starts, carryin, carryout, span); |
---|
| 116 | rslt = simd_or(span, follows); |
---|
| 117 | return carryout; |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | IDISA_ALWAYS_INLINE BitBlock pablo_blk_ExclusiveSpan(BitBlock starts, BitBlock follows, BitBlock carryin, BitBlock & rslt) { |
---|
| 121 | BitBlock carryout, span; |
---|
| 122 | sub_bi_bo(follows, starts, carryin, carryout, span); |
---|
| 123 | rslt = simd_andc(span, starts); |
---|
| 124 | return carryout; |
---|
| 125 | } |
---|
| 126 | |
---|
| 127 | template <typename T> IDISA_ALWAYS_INLINE BitBlock pablo_blk_match(T bytedata[], const T match_str[], BitBlock v, int len) { |
---|
| 128 | union {BitBlock bitblock; ScanWord elems[sizeof(BitBlock)/sizeof(ScanWord)];} u; |
---|
| 129 | u.bitblock = v; |
---|
| 130 | int pos; |
---|
| 131 | ScanWord s, t, bit; |
---|
| 132 | for (unsigned int i = 0; i < sizeof(BitBlock)/sizeof(ScanWord); i++) { |
---|
| 133 | s = u.elems[i]; |
---|
| 134 | while (s != 0) { |
---|
| 135 | pos = scan_forward_zeroes(s); |
---|
| 136 | t = s; |
---|
| 137 | s = s & (s - 1); // clear rightmost bit |
---|
| 138 | if (memcmp((void *) &bytedata[pos], (void *) match_str, len * sizeof(T))) { |
---|
| 139 | // Strings do not match; filter the result. |
---|
| 140 | bit = s ^ t; |
---|
| 141 | u.elems[i] ^= bit; |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | } |
---|
| 145 | return u.bitblock; |
---|
| 146 | } |
---|
| 147 | |
---|
| 148 | #endif // PABLOSUPPORT_HPP_ |
---|