| | 28 | /* The type used to store a carry bit. */ |
| | 29 | typedef bitblock256_t carry_t; |
| | 30 | |
| | 31 | static IDISA_ALWAYS_INLINE bitblock256_t carry2bitblock(carry_t carry); |
| | 32 | static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock256_t carry); |
| | 33 | |
| | 34 | static IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t & carry, bitblock256_t & sum); |
| | 35 | static IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t & borrow, bitblock256_t & difference); |
| | 36 | static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t & carry, bitblock256_t & rslt); |
| | 37 | |
| | 38 | static IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t carry_in, carry_t & carry_out, bitblock256_t & sum); |
| | 39 | static IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t borrow_in, carry_t & borrow_out, bitblock256_t & difference); |
| | 40 | static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t carry_in, carry_t & carry_out, bitblock256_t & rslt); |
| | 41 | |
| | 42 | static IDISA_ALWAYS_INLINE bitblock256_t convert (uint64_t s); |
| | 43 | static IDISA_ALWAYS_INLINE uint64_t convert (bitblock256_t v); |
| | 44 | |
| | 45 | static IDISA_ALWAYS_INLINE bitblock256_t carry2bitblock(carry_t carry) { return carry;} |
| | 46 | static IDISA_ALWAYS_INLINE carry_t bitblock2carry(bitblock256_t carry) { return carry;} |
| | 47 | |
| | 48 | IDISA_ALWAYS_INLINE void adc(bitblock256_t x, bitblock256_t y, carry_t carry_in, carry_t & carry_out, bitblock256_t & sum) |
| | 49 | { |
| | 50 | bitblock256_t gen = simd_and(x, y); |
| | 51 | bitblock256_t prop = simd_or(x, y); |
| | 52 | sum = simd256<256>::add(simd256<256>::add(x, y), carry2bitblock(carry_in)); |
| | 53 | carry_out = bitblock2carry(simd256<256>::srli<255>(simd_or(gen, simd_andc(prop, sum)))); |
| | 54 | } |
| | 55 | |
| | 56 | IDISA_ALWAYS_INLINE void sbb(bitblock256_t x, bitblock256_t y, carry_t borrow_in, carry_t & borrow_out, bitblock256_t & difference) |
| | 57 | { |
| | 58 | bitblock256_t gen = simd_andc(y, x); |
| | 59 | bitblock256_t prop = simd_not(simd_xor(x, y)); |
| | 60 | difference = simd256<256>::sub(simd256<256>::sub(x, y), carry2bitblock(borrow_in)); |
| | 61 | borrow_out = bitblock2carry(simd256<256>::srli<255>(simd_or(gen, simd_and(prop, difference)))); |
| | 62 | } |
| | 63 | |
| | 64 | IDISA_ALWAYS_INLINE void advance_with_carry(bitblock256_t cursor, carry_t carry_in, carry_t & carry_out, bitblock256_t & rslt) |
| | 65 | { |
| | 66 | carry_out = simd256<256>::srli<255>(cursor); |
| | 67 | rslt = simd_or(simd256<256>::add(cursor, cursor), carry_in); |
| | 68 | } |
| | 69 | |
| | 70 | IDISA_ALWAYS_INLINE bitblock256_t convert(uint64_t s) |
| | 71 | { |
| | 72 | ubitblock b = {b._256 = simd256<128>::constant<0>()}; // = {0}; |
| | 73 | b._64[0] = s; |
| | 74 | return b._256; |
| | 75 | } |
| | 76 | |
| | 77 | IDISA_ALWAYS_INLINE uint64_t convert (bitblock256_t v) |
| | 78 | { |
| | 79 | return (uint64_t) mvmd256<64>::extract<0>(v); |
| | 80 | } |
| | 81 | |
| | 82 | |