#if !defined  HAVE_BITCOPY_H__
#define       HAVE_BITCOPY_H__

#include "fxttypes.h"



inline ulong copy_bit(ulong a, ulong isrc, ulong idst)
// Copy bit at [isrc] to position [idst].
// Return the modified word.
{
#if 1  // Branch free:
    ulong x = ((a>>isrc) ^ (a>>idst)) & 1;  // one if bits differ
    a ^= (x<<idst); // change if bits differ
#else
    ulong v = a & (1UL << isrc);
    ulong b = 1UL << idst;
    if ( 0==v )  a &= ~b;
    else         a |=  b;
#endif
    return  a;
}
// -------------------------


inline ulong mask_copy_bit(ulong a, ulong msrc, ulong mdst)
// Copy bit according at src-mask (msrc)
//  to the bit according to the dest-mask (mdst).
// Both msrc and mdst must have exactly one bit set.
// Return the modified word.
{
#if 1  // Branch free:
    ulong x = mdst;
    if ( msrc & a )  x = 0;  // zero if source bit set (compiled to cmov)
    x ^= mdst;  // ==mdst if source bit set, else zero
    a &= ~mdst;  // clear dest bit
    a |= x;
#else
    ulong v = a & msrc;
    ulong b = mdst;
    if ( 0==v )  a &= ~b;
    else         a |=  b;
#endif
    return  a;
}
// -------------------------

inline ulong mask_or_bit(ulong a, ulong msrc, ulong mdst)
// Or bit according to src-mask (msrc)
//  to the bit according to the dest-mask (mdst).
// Both msrc and mdst must have exactly one bit set.
// If the mdst-position is known to be zero this function
//  is equivalent to mask_copy_bit().
// Return the modified word.
{
#if 1  // Branch free:
    if ( msrc & a )  mdst = 0;  // zero if source bit set (compiled to cmov)
    a |= mdst;
#else
    if ( a & msrc )  a |= mdst;
#endif
    return  a;
}
// -------------------------


#endif  // !defined HAVE_BITCOPY_H__
