diff --git a/src/singeli/README.md b/src/singeli/README.md index fae42648..ad3cdfd9 100644 --- a/src/singeli/README.md +++ b/src/singeli/README.md @@ -164,6 +164,7 @@ Homogeneous definitions (i.e. ones with `hom` in their name) assume that each el - `homBlend{f:V, t:V, m:mt{V}} : V` - blend by `m`, setting to `f` where `0` and `t` where `1` - `topBlend{f:V, t:V, m:V} : V` - blend by top bit of `m` - `homMask{a:VI} : uint` - integer mask of whether each element is set (assumes each element has all its bits equal) +- `homMask{...vs} : uint` - merged mask of `each{homMask,vs}` - `topMask{a:VI} : uint` - integer mask of the top bit of each element - `homMaskX{a:VI} : tup{knum, uint}` - integer mask where each element is represented by `knum` bits (possibly more efficient to calculate than `homMask`) - `ctzX{tup{knum, uint}}` - count trailing zeroes from a result of `homMaskX` diff --git a/src/singeli/src/cmp.singeli b/src/singeli/src/cmp.singeli index 21cf4150..28c11ae3 100644 --- a/src/singeli/src/cmp.singeli +++ b/src/singeli/src/cmp.singeli @@ -61,21 +61,11 @@ def pathAS{dst, len, T, op, x & isunsigned{T}} = { def any2bit{VT, unr, op, wS, wV, xS, xV, dst:*u64, len:(ux)} = { - xi:ux = 0 - ri:ux = 0 def bulk = vcount{VT}*unr - am:ux = cdiv{len,bulk} - assert{am>0} - while (ri < am) { - r:u64 = 0 - if (hasarch{'AARCH64'}) { - r = promote{u64, homMask{...each{{j}=>op{wV{xi+j}, xV{xi+j}}, iota{unr}}}} - } else { - @unroll (j to unr) r|= promote{u64, homMask{op{wV{xi+j}, xV{xi+j}}}} << (j*vcount{VT}) - } - b_setBatch{bulk, dst, ri, r} + xi:ux = 0 + @forNZ (ri to cdiv{len,bulk}) { + b_setBatch{bulk, dst, ri, homMask{...each{{j}=>op{wV{xi+j}, xV{xi+j}}, iota{unr}}}} xi+= unr - ri+= 1 } } fn aa2bit{VT, unr, op}(dst:*u64, wr:*void, xr:*void, len:ux) : void = { diff --git a/src/singeli/src/copy.singeli b/src/singeli/src/copy.singeli index a029b44f..d9b9623f 100644 --- a/src/singeli/src/copy.singeli +++ b/src/singeli/src/copy.singeli @@ -42,11 +42,16 @@ fn copy{X, R}(x: *void, r: *void, l:u64, xRaw: *void) : void = { copyFromBits{[bulk]R, loadBatchBit{., xp, .}, r, l} } else if (R==u1) { # show{'R==u1', X, R} + def XU = ty_u{XV} - @forNZ (i to cdiv{l,vcount{XV}}) { - v:= loadBatch{xp, i, XV} - r:= homMask{(XU~~v) == XU~~XV**1} - b_setBatch{vcount{XV}, rp, i, r} # TODO something more special for f64 + def op{x} = (XU~~x) == XU~~XV**1 + + def unr = max{8/bulk, 1} + def bulk2 = bulk*unr + xi:ux = 0 + @forNZ (i to cdiv{l,bulk2}) { + b_setBatch{bulk2, rp, i, homMask{...each{{i} => op{loadBatch{xp, xi+i, XV}}, iota{unr}}}} + xi+= unr } } else if (width{X}<=width{R}) { # show{'w{X}<=w{R}', X, R}