summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim
diff options
context:
space:
mode:
authorJohn Ky <newhoggy@gmail.com>2018-01-21 11:55:45 -0500
committerBen Gamari <ben@smart-cactus.org>2018-01-21 11:56:11 -0500
commitf855769690eb998ea25818ee794714957852af48 (patch)
tree969d0c0bafa72929f5ec50f1794d51e6e1799840 /libraries/ghc-prim
parent5e8ea6a62e948bcc0da1279f06844fd1d8e979bd (diff)
downloadhaskell-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/ghc-prim')
-rw-r--r--libraries/ghc-prim/cbits/pdep.c48
-rw-r--r--libraries/ghc-prim/cbits/pext.c44
-rw-r--r--libraries/ghc-prim/ghc-prim.cabal2
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