From 1b1fe2ba57ab3b16da32873243ac921a177e05a8 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 12 Dec 2021 22:58:06 +0200 Subject: [PATCH] BMI2 bitarr/bitarr --- src/builtins/sfns.c | 25 +++++++++++++++++++++++++ src/core/fillarr.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index fe5a881a..285e6090 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -437,6 +437,9 @@ B slash_c1(B t, B x) { dec(x); return r; } +#ifdef __BMI2__ +#include +#endif B slash_c2(B t, B w, B x) { if (isArr(x) && rnk(x)==1 && isArr(w) && rnk(w)==1 && depth(w)==1) { usz wia = a(w)->ia; @@ -452,9 +455,31 @@ B slash_c2(B t, B w, B x) { u64* wp = bitarr_ptr(w); while (wia>0 && !bitp_get(wp,wia-1)) wia--; usz wsum = bit_sum(wp, wia); + if (wsum==0) { dec(w); dec(x); return q_N(xf)? emptyHVec() : isF64(xf)? emptyIVec() : isC32(xf)? emptyCVec() : m_emptyFVec(xf); } B r; switch(TI(x,elType)) { default: UD; + #ifdef __BMI2__ + case el_bit: { u64* xp = bitarr_ptr(x); u64* rp; r = m_bitarrv(&rp,wsum+128); a(r)->ia = wsum; + u64 cw = 0; // current word + u64 ro = 0; // offset in word where next bit should be written; never 64 + for (usz i=0; i=64) { + *(rp++) = cw; + cw = ro? v>>(64-ro) : 0; + } + ro = ro2&63; + } + if (ro) *rp = cw; + break; + } + #else case el_bit: { u64* xp = bitarr_ptr(x); u64* rp; r = m_bitarrv(&rp,wsum); for (usz i=0; itype==t_fillarr); ((FillArr*)x)->fill = fill; } // consumes fill static B* fillarr_ptr(Arr* x) { assert(x->type==t_fillarr); return ((FillArr*)x)->a; } +static B m_emptyFVec(B f) { // consumes f + Arr* r = m_fillarrp(0); + fillarr_setFill(r, f); + arr_shVec(r); + return taga(r); +} static B m_unit(B x) { B xf = asFill(inc(x));