Changeset 1996 for trunk/lib


Ignore:
Timestamp:
Apr 5, 2012, 12:22:44 PM (7 years ago)
Author:
cameron
Message:

Functions with separate parameters for carry-in and carry-out.

Location:
trunk/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bitblock128.hpp

    r1975 r1996  
    3333static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t & carry, bitblock128_t & rslt);
    3434
     35static IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t carry_in, carry_t & carry_out, bitblock128_t & sum);
     36static IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t borrow_in, carry_t & borrow_out, bitblock128_t & difference);
     37static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t carry_in, carry_t & carry_out, bitblock128_t & rslt);
     38
    3539static IDISA_ALWAYS_INLINE bitblock128_t convert (uint64_t s);
    3640static IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v);
     
    4953}
    5054
     55IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t carry_in, carry_t & carry_out, bitblock128_t & sum)
     56{
     57        bitblock128_t gen = simd_and(x, y);
     58        bitblock128_t prop = simd_or(x, y);
     59        bitblock128_t partial = simd128<64>::add(simd128<64>::add(x, y), carry2bitblock(carry_in));
     60        bitblock128_t c1 = simd128<128>::slli<64>(simd128<64>::srli<63>(simd_or(gen, simd_andc(prop, partial))));
     61        sum = simd128<64>::add(c1, partial);
     62        carry_out = bitblock2carry(simd128<128>::srli<127>(simd_or(gen, simd_andc(prop, sum))));
     63}
     64
    5165IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t & borrow, bitblock128_t & difference)
    5266{
     
    5973}
    6074
     75IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t borrow_in, carry_t & borrow_out, bitblock128_t & difference)
     76{
     77        bitblock128_t gen = simd_andc(y, x);
     78        bitblock128_t prop = simd_not(simd_xor(x, y));
     79        bitblock128_t partial = simd128<64>::sub(simd128<64>::sub(x, y), carry2bitblock(borrow_in));
     80        bitblock128_t b1 = simd128<128>::slli<64>(simd128<64>::srli<63>(simd_or(gen, simd_and(prop, partial))));
     81        difference = simd128<64>::sub(partial, b1);
     82        borrow_out = bitblock2carry(simd128<128>::srli<127>(simd_or(gen, simd_and(prop, difference))));
     83}
     84
    6185IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t & carry, bitblock128_t & rslt)
    6286{
     
    6488bitblock128_t low_bits = esimd128<64>::mergel(shift_out, carry2bitblock(carry));
    6589carry = bitblock2carry(simd128<128>::srli<64>(shift_out));
     90rslt = simd_or(simd128<64>::add(cursor, cursor), low_bits);
     91}
     92
     93IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, carry_t carry_in, carry_t & carry_out, bitblock128_t & rslt)
     94{
     95bitblock128_t shift_out = simd128<64>::srli<63>(cursor);
     96bitblock128_t low_bits = esimd128<64>::mergel(shift_out, carry2bitblock(carry_in));
     97carry_out = bitblock2carry(simd128<128>::srli<64>(shift_out));
    6698rslt = simd_or(simd128<64>::add(cursor, cursor), low_bits);
    6799}
  • trunk/lib/carryQ.hpp

    r1950 r1996  
    4949        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t & pending);
    5050        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_co(BitBlock strm, uint32_t & pending);
     51
     52        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, BitBlock carryin, uint16_t carryno);
     53        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, const uint16_t carryno);
     54        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, uint16_t carryno);
     55
     56        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, BitBlock carryin, uint16_t carryno);
     57        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno);
     58        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t pending_in, uint32_t & pending_out);
     59
    5160        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count);
    5261        IDISA_ALWAYS_INLINE void CarryDequeueEnqueue(uint16_t carryno, uint16_t carry_count);
     
    5463        IDISA_ALWAYS_INLINE void CarryCombine(ICarryQueue carryqueue, uint16_t carryno, uint16_t carry_count);
    5564
     65        IDISA_ALWAYS_INLINE BitBlock get_carry_in(uint16_t carryno) const ;
    5666protected:
    5767        ICarryQueue(){};
     
    177187        */
    178188
     189        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance_ci_co(BitBlock strm, BitBlock carryin, uint16_t carryno)
     190        {
     191                BitBlock rslt;
     192                advance_with_carry(strm, carryin, cq[carryno], rslt);
     193                return rslt;
     194        }
     195
     196        IDISA_ALWAYS_INLINE BitBlock BitBlock_add_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, const uint16_t carryno)
     197        {
     198                BitBlock sum;
     199                adc(strm1, strm2, carryin, cq[carryno], sum);
     200                return sum;
     201        }
     202
     203        IDISA_ALWAYS_INLINE BitBlock BitBlock_sub_ci_co(BitBlock strm1, BitBlock strm2, BitBlock carryin, uint16_t carryno)
     204        {
     205                BitBlock diff;
     206                sbb(strm1, strm2, carryin, cq[carryno], diff);
     207                return diff;
     208        }
     209
     210        IDISA_ALWAYS_INLINE BitBlock BitBlock_scantofirst(BitBlock charclass, BitBlock carryin, uint16_t carryno)
     211        {
     212                BitBlock marker;
     213                BitBlock c = carry_flip(carryin);
     214                adc(simd<BLOCK_SIZE>::constant<0>(), simd_not(charclass), c, marker);
     215                cq[carryno] = carry_flip(c);
     216                return simd_and(marker, charclass);
     217        }
     218
     219        IDISA_ALWAYS_INLINE BitBlock BitBlock_scanthru_ci_co(BitBlock markers0, BitBlock charclass, BitBlock carryin, uint16_t carryno)
     220        {
     221                BitBlock markers1;
     222                adc(markers0, charclass, carryin, cq[carryno], markers1);
     223                return simd_andc(markers1, charclass);
     224        }
     225
     226        IDISA_ALWAYS_INLINE BitBlock BitBlock_advance32_ci_co(BitBlock strm, uint32_t pending_in, uint32_t & pending_out)
     227        {
     228                pending_out = (uint32_t) mvmd<32>::extract< (sizeof(BitBlock)/sizeof(pending_out))-1 >(strm);
     229                return simd_or(simd<BLOCK_SIZE>::slli<32>(strm), mvmd<BLOCK_SIZE>::fill((uint64_t)pending_in));
     230        }
     231
    179232        IDISA_ALWAYS_INLINE bool CarryTest(uint16_t carryno, uint16_t carry_count)
    180233        {
     
    205258        }
    206259
     260        IDISA_ALWAYS_INLINE BitBlock get_carry_in(uint16_t carryno) const
     261        {
     262                return carry2bitblock(cq[carryno]);
     263        }
     264
    207265private:
    208266        BitBlock cq[CarryCount];
Note: See TracChangeset for help on using the changeset viewer.