summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim/cbits/pdep.c
blob: 58e8611ecacd32b052ef3dd519899cef11bd5bf9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "Rts.h"
#include "MachDeps.h"

StgWord64
hs_pdep64(StgWord64 src, StgWord64 mask)
{
  uint64_t result = 0;

  while (1) {
    // Mask out all but the lowest bit
    const uint64_t lowest = (-mask & mask);

    if (lowest == 0) {
      break;
    }

    const uint64_t lsb = (uint64_t)((int64_t)(src << 63) >> 63);

    result |= lsb & lowest;
    mask &= ~lowest;
    src >>= 1;
  }

  return result;
}

StgWord
hs_pdep32(StgWord src, StgWord mask)
{
  return hs_pdep64(src, mask);
}

StgWord
hs_pdep16(StgWord src, StgWord mask)
{
  return hs_pdep64(src, mask);
}

StgWord
hs_pdep8(StgWord src, StgWord mask)
{
  return hs_pdep64(src, mask);
}