diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index d9905189..d7111202 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -24,6 +24,11 @@ def ctz{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_ctzll', x} def ctz{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_ctz', x} def clz{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_clzll', x} def clz{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_clz', x} +# count-leading-zeros complement, less type-dependent +def clzc{x:T & isint{T} & width{T}==64} = 64-clz{x} +def clzc{x:T & isint{T} & width{T}<=32} = 32-clz{x} + +def ceil_log2{n} = clzc{n-1} def truncBits{n, v & n<=8} = cast_i{u8, v} def truncBits{n, v & n==16} = cast_i{u16, v} @@ -175,6 +180,7 @@ def cvt{...x} = assert{'cvt not supported', show{...x}} def shuf{...x} = assert{'shuf not supported', show{...x}} def shuf16Lo{...x} = assert{'shuf16Lo not supported', show{...x}} def shuf16Hi{...x} = assert{'shuf16Hi not supported', show{...x}} +def shufHalves{...x} = assert{'shufHalves not supported', show{...x}} def homAll{...x} = assert{'homAll not supported', show{...x}} def homAny{...x} = assert{'homAny not supported', show{...x}} def homMask{...x} = assert{'homMask not supported', show{...x}} @@ -281,6 +287,13 @@ def forNZ{vars,begin,end,iter} = { ++i } } +def for_backwards{vars,begin,end,iter} = { + i:u64 = end + while (i > begin) { + --i + iter{i, vars} + } +} def forUnroll{exp,unr}{vars,begin,end,iter} = { i:u64 = begin while ((i+unr) <= end) { diff --git a/src/singeli/src/bins.singeli b/src/singeli/src/bins.singeli index 062c3db5..16e0558a 100644 --- a/src/singeli/src/bins.singeli +++ b/src/singeli/src/bins.singeli @@ -1,5 +1,5 @@ include './base' -def shufHalves{...x} = assert{'shufHalves not supported', show{...x}} +include './cbqnDefs' if (hasarch{'AVX2'}) { include './sse' include './avx' @@ -8,14 +8,8 @@ if (hasarch{'AVX2'}) { include './mask' include 'util/tup' -def for_backwards{vars,begin,end,iter} = { - i:u64 = end - while (i > begin) { - --i - iter{i, vars} - } -} def for_dir{up} = if (up) for else for_backwards + def for_vec_overlap{vl}{vars,begin==0,n,iter} = { assert{n >= vl} def end = makelabel{} @@ -28,8 +22,6 @@ def for_vec_overlap{vl}{vars,begin==0,n,iter} = { setlabel{end} } -def ceil_log2{n:u64} = 64 - clz{n-1} - # Shift as u16, since x86 is missing 8-bit shifts def shr16{v:V, n} = V~~(to_el{u16, v} >> n) @@ -70,13 +62,6 @@ fn max_scan{T, up}(x:*T, len:u64) : void = { } } -def fmt_type{T} = { - def w = width{T} - merge{quality{T}, if (w==8) '8' else if (w==16) '16' else if (w==32) '32' else '64'} -} -def talloc{T, len} = emit{*T, 'TALLOCP', fmt_type{T}, len} -def tfree{ptr} = emit{void, 'TFREE', ptr} - def getsel{...x} = assert{'shuffling not supported', show{...x}} if (hasarch{'AVX2'}) { def getsel{h:H & lvec{H, 16, 8}} = { @@ -103,6 +88,7 @@ def uninterleave{x:V & hasarch{'AVX2'}} = { def rtypes = tup{i8, i16, i32, f64} # Return index of smallest possible result type given max result value +# (Unused; done in C for now) def get_rtype{len} = { t:u8 = 0 def c{T, ...ts} = if (len>maxvalue{T}) { ++t; c{...ts} } diff --git a/src/singeli/src/cbqnDefs.singeli b/src/singeli/src/cbqnDefs.singeli index 4a89a523..b76ff5f7 100644 --- a/src/singeli/src/cbqnDefs.singeli +++ b/src/singeli/src/cbqnDefs.singeli @@ -31,3 +31,11 @@ def cbqn_elType{T & T==u16} = 6 def cbqn_elType{T & T==u32} = 7 def cbqn_tyArrOffset{} = emit{u64, 'offsetof', 'TyArr', 'a'} + +def talloc{T, len} = emit{*T, 'TALLOCP', fmt_type{T}, len} +def tfree{ptr} = emit{void, 'TFREE', ptr} +def fmt_type{T} = { + def w = match (width{T}) { {_==8}=>'8'; {_==16}=>'16'; {_==32}=>'32'; {_==64}=>'64' } + merge{quality{T}, w} +} +def fmt_type{T & isptr{T}} = merge{'*',fmt_type{eltype{T}}}