diff --git a/src/builtins/slash.c b/src/builtins/slash.c index c8c658c1..c0137fd9 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -261,6 +261,95 @@ static B where(B x, usz xia, u64 s) { return r; } +static B compress(B w, B x, usz wia, B xf) { + usz xia = wia; + usz ri = 0; + B r; + u64* wp = bitarr_ptr(w); + u8 xe = TI(x,elType); + #ifdef __BMI2__ + usz wsum = bit_sum(wp, wia); + switch(xe) { + 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; + return r; + } + #if SINGELI + case el_i8: case el_c8: { i8* xp=tyany_ptr(x); i8* rp=m_tyarrvO(&r,1,wsum,el2t(xe), 8); bmipopc_2slash8 (wp, xp, rp, wia); return r; } + case el_i16:case el_c16: { i16* xp=tyany_ptr(x); i16* rp=m_tyarrvO(&r,2,wsum,el2t(xe), 16); bmipopc_2slash16(wp, xp, rp, wia); return r; } + case el_i32:case el_c32: { + i32* xp=tyany_ptr(x); i32* rp=m_tyarrv(&r,4,wsum,el2t(xe)); + usz b = 1<<7; + TALLOC(i8, buf, b); + i32* rq=rp; i32* end=xp+xia-b; + while (xp < end) { + bmipopc_1slash8(wp, buf, b); + usz bs = bit_sum(wp, b); + for (usz j=0; j0 && !bitp_get(wp,wia-1)) wia--; + #ifndef __BMI2__ + usz wsum = bit_sum(wp, wia); + #endif + if (wsum==0) { return q_N(xf)? emptyHVec() : isF64(xf)? emptyIVec() : isC32(xf)? emptyCVec() : m_emptyFVec(xf); } + switch(xe) { default: UD; + + #if !SINGELI + case el_i8: case el_c8: { i8* xp=tyany_ptr(x); i8* rp=m_tyarrv(&r,1,wsum,el2t(xe)); for (usz i=0; iia = 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; - goto bit_ret; - } - #if SINGELI - case el_i8: case el_c8: { i8* xp=tyany_ptr(x); i8* rp=m_tyarrvO(&r,1,wsum,el2t(xe), 8); bmipopc_2slash8 (wp, xp, rp, wia); goto bit_ret; } - case el_i16:case el_c16: { i16* xp=tyany_ptr(x); i16* rp=m_tyarrvO(&r,2,wsum,el2t(xe), 16); bmipopc_2slash16(wp, xp, rp, wia); goto bit_ret; } - case el_i32:case el_c32: { - i32* xp=tyany_ptr(x); i32* rp=m_tyarrv(&r,4,wsum,el2t(xe)); - usz b = 1<<7; - TALLOC(i8, buf, b); - i32* rq=rp; i32* end=xp+xia-b; - while (xp < end) { - bmipopc_1slash8(wp, buf, b); - usz bs = bit_sum(wp, b); - for (usz j=0; j0 && !bitp_get(wp,wia-1)) wia--; - #ifndef __BMI2__ - usz wsum = bit_sum(wp, wia); - #endif - if (wsum==0) { decG(w); decG(x); return q_N(xf)? emptyHVec() : isF64(xf)? emptyIVec() : isC32(xf)? emptyCVec() : m_emptyFVec(xf); } - switch(xe) { default: UD; - - #if !SINGELI - case el_i8: case el_c8: { i8* xp=tyany_ptr(x); i8* rp=m_tyarrv(&r,1,wsum,el2t(xe)); for (usz i=0; i