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.

File:
1 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}
Note: See TracChangeset for help on using the changeset viewer.