diff options
author | John Ky <newhoggy@gmail.com> | 2018-01-21 11:55:45 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-01-21 11:56:11 -0500 |
commit | f855769690eb998ea25818ee794714957852af48 (patch) | |
tree | 969d0c0bafa72929f5ec50f1794d51e6e1799840 /libraries | |
parent | 5e8ea6a62e948bcc0da1279f06844fd1d8e979bd (diff) | |
download | haskell-f855769690eb998ea25818ee794714957852af48.tar.gz |
Add new mbmi and mbmi2 compiler flags
This adds support for the bit deposit and extraction operations provided
by the BMI and BMI2 instruction set extensions on modern amd64 machines.
Implement x86 code generator for pdep and pext. Properly initialise
bmiVersion field.
pdep and pext test cases
Fix pattern match for pdep and pext instructions
Fix build of pdep and pext code for 32-bit architectures
Test Plan: Validate
Reviewers: austin, simonmar, bgamari, angerman
Reviewed By: bgamari
Subscribers: trommler, carter, angerman, thomie, rwbarton, newhoggy
GHC Trac Issues: #14206
Differential Revision: https://phabricator.haskell.org/D4236
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/ghc-prim/cbits/pdep.c | 48 | ||||
-rw-r--r-- | libraries/ghc-prim/cbits/pext.c | 44 | ||||
-rw-r--r-- | libraries/ghc-prim/ghc-prim.cabal | 2 |
3 files changed, 94 insertions, 0 deletions
diff --git a/libraries/ghc-prim/cbits/pdep.c b/libraries/ghc-prim/cbits/pdep.c new file mode 100644 index 0000000000..8435ffe186 --- /dev/null +++ b/libraries/ghc-prim/cbits/pdep.c @@ -0,0 +1,48 @@ +#include "Rts.h" +#include "MachDeps.h" + +extern StgWord64 hs_pdep64(StgWord64 src, StgWord64 mask); + +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; +} + +extern StgWord hs_pdep32(StgWord src, StgWord mask); +StgWord +hs_pdep32(StgWord src, StgWord mask) +{ + return hs_pdep64(src, mask); +} + +extern StgWord hs_pdep16(StgWord src, StgWord mask); +StgWord +hs_pdep16(StgWord src, StgWord mask) +{ + return hs_pdep64(src, mask); +} + +extern StgWord hs_pdep8(StgWord src, StgWord mask); +StgWord +hs_pdep8(StgWord src, StgWord mask) +{ + return hs_pdep64(src, mask); +} diff --git a/libraries/ghc-prim/cbits/pext.c b/libraries/ghc-prim/cbits/pext.c new file mode 100644 index 0000000000..fe960b1342 --- /dev/null +++ b/libraries/ghc-prim/cbits/pext.c @@ -0,0 +1,44 @@ +#include "Rts.h" +#include "MachDeps.h" + +extern StgWord64 hs_pext64(StgWord64 src, StgWord64 mask); + +StgWord64 +hs_pext64(StgWord64 src, StgWord64 mask) +{ + uint64_t result = 0; + int offset = 0; + + for (int bit = 0; bit != sizeof(uint64_t) * 8; ++bit) { + const uint64_t src_bit = (src >> bit) & 1; + const uint64_t mask_bit = (mask >> bit) & 1; + + if (mask_bit) { + result |= (uint64_t)(src_bit) << offset; + ++offset; + } + } + + return result; +} + +extern StgWord hs_pext32(StgWord src, StgWord mask); +StgWord +hs_pext32(StgWord src, StgWord mask) +{ + return hs_pext64(src, mask); +} + +extern StgWord hs_pext16(StgWord src, StgWord mask); +StgWord +hs_pext16(StgWord src, StgWord mask) +{ + return hs_pext64(src, mask); +} + +extern StgWord hs_pext8(StgWord src, StgWord mask); +StgWord +hs_pext8(StgWord src, StgWord mask) +{ + return hs_pext64(src, mask); +} diff --git a/libraries/ghc-prim/ghc-prim.cabal b/libraries/ghc-prim/ghc-prim.cabal index e99686a10b..9b8c1ac196 100644 --- a/libraries/ghc-prim/ghc-prim.cabal +++ b/libraries/ghc-prim/ghc-prim.cabal @@ -73,6 +73,8 @@ Library cbits/ctz.c cbits/debug.c cbits/longlong.c + cbits/pdep.c + cbits/pext.c cbits/popcnt.c cbits/word2float.c |