Changeset 2605


Ignore:
Timestamp:
Nov 3, 2012, 6:59:21 PM (6 years ago)
Author:
cameron
Message:

Operations preserving carry-out form add_ci_co, sub_bi_bo, adv_ci_co

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bitblock128.hpp

    r2328 r2605  
    44    bitblock128 - Specific 128 bit IDISA implementations.
    55
    6     Idealized SIMD Operations with SSE versions
    76    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy, Hua Huang and Nigel Medforth.
    87    Licensed to the public under the Open Software License 3.0.
     
    2322};
    2423
     24static IDISA_ALWAYS_INLINE void add_ci_co(bitblock128_t x, bitblock128_t y, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & sum);
     25static IDISA_ALWAYS_INLINE void sub_bi_bo(bitblock128_t x, bitblock128_t y, bitblock128_t borrow_in, bitblock128_t & borrow_out, bitblock128_t & difference);
     26static IDISA_ALWAYS_INLINE void adv_ci_co(bitblock128_t cursor, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & rslt);
     27
    2528/* The type used to store a carry bit. */
    2629typedef bitblock128_t carry_t;
     30
     31
     32
     33
    2734
    2835static IDISA_ALWAYS_INLINE bitblock128_t carry2bitblock(carry_t carry);
     
    4350static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock128_t carry) {  return carry;}
    4451
     52
     53
     54
     55static IDISA_ALWAYS_INLINE void add_ci_co(bitblock128_t x, bitblock128_t y, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & sum) {
     56        bitblock128_t gen = simd_and(x, y);
     57        bitblock128_t prop = simd_or(x, y);
     58        bitblock128_t partial = simd128<64>::add(simd128<64>::add(x, y), carry_in);
     59        bitblock128_t c1 = simd128<128>::slli<64>(simd128<64>::srli<63>(simd_or(gen, simd_andc(prop, partial))));
     60        sum = simd128<64>::add(c1, partial);
     61        carry_out = simd_or(gen, simd_andc(prop, sum));
     62}
     63static IDISA_ALWAYS_INLINE void sub_bi_bo(bitblock128_t x, bitblock128_t y, bitblock128_t borrow_in, bitblock128_t & borrow_out, bitblock128_t & difference){
     64        bitblock128_t gen = simd_andc(y, x);
     65        bitblock128_t prop = simd_not(simd_xor(x, y));
     66        bitblock128_t partial = simd128<64>::sub(simd128<64>::sub(x, y), borrow_in);
     67        bitblock128_t b1 = simd128<128>::slli<64>(simd128<64>::srli<63>(simd_or(gen, simd_and(prop, partial))));
     68        difference = simd128<64>::sub(partial, b1);
     69        borrow_out = simd_or(gen, simd_and(prop, difference));
     70}
     71static IDISA_ALWAYS_INLINE void adv_ci_co(bitblock128_t cursor, bitblock128_t carry_in, bitblock128_t & carry_out, bitblock128_t & rslt){
     72        bitblock128_t shift_out = simd128<64>::srli<63>(cursor);
     73        bitblock128_t low_bits = esimd128<64>::mergel(shift_out, carry_in);
     74        carry_out = cursor;
     75        rslt = simd_or(simd128<64>::add(cursor, cursor), low_bits);
     76}
     77
    4578IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t & carry, bitblock128_t & sum)
    4679{
     
    5588IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, carry_t carry_in, carry_t & carry_out, bitblock128_t & sum)
    5689{
    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))));
     90        bitblock128_t co;
     91        add_ci_co(x, y, carry2bitblock(carry_in), co, sum);
     92        carry_out = bitblock2carry(simd128<128>::srli<127>(co));
    6393}
    6494
     
    75105IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, carry_t borrow_in, carry_t & borrow_out, bitblock128_t & difference)
    76106{
    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))));
     107        bitblock128_t bo;
     108        sub_bi_bo(x, y, carry2bitblock(borrow_in), bo, difference);
     109        borrow_out = bitblock2carry(simd128<128>::srli<127>(bo));
    83110}
    84111
Note: See TracChangeset for help on using the changeset viewer.