diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index bbe45815..acecdf35 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -2,6 +2,7 @@ include 'skin/c' include 'arch/c' include 'util/for' include 'util/kind' +include 'util/tup' def ux = u64 config usz = u32 @@ -18,17 +19,34 @@ def istup = ktup def isunsigned{T} = isint{T} and not issigned{T} -def isvec {T} = istype{T} and same{typekind{T},'vector'} -def isprim{T} = istype{T} and same{typekind{T},'primitive'} -def isptr {T} = istype{T} and same{typekind{T},'pointer'} +def isvec {T} = istype{T} and same{typekind{T}, 'vector'} # TODO rename these to better reflect that they apply to types +def isprim{T} = istype{T} and same{typekind{T}, 'primitive'} +def isptr {T} = istype{T} and same{typekind{T}, 'pointer'} def elwidth{T} = width{eltype{T}} +def reinterpret{T, x:T} = x +def exportN{f, ...ns} = each{export{.,f}, ns} +def exportT{name, fs} = { v:*oneType{fs} = fs; export{name, v} } + oper &~ andnot infix none 35 def andnot{a, b:T if anyNum{a} and isprim{T}} = a & ~b def andnot{a:T, b if isprim{T} and knum{b}} = a & ~T~~b oper &- ({v:T,m:(u1)} => v & -promote{T,m}) infix left 35 +def reverse_scan{G, v} = reverse{scan{{a,b}=>G{b,a}, reverse{v}}} + +def tree_fold{F, x} = { + def h = length{x}>>1 + assert{h>0, 'tree_fold of empty'} + F{tree_fold{F, slice{x,0,h}}, tree_fold{F, slice{x,h,length{x}}}} +} +def tree_fold{F, {x}} = x + +def eachx{F, ...args} = { + def l = tree_fold{max, each{{x} => if(istup{x}) length{x} else 0, args}} + each{F, ...each{{x} => if (istup{x}) x else l**x, args}} +} def load {p:*[_]_, n } = assert{0,'bad load',p,n} @@ -43,10 +61,6 @@ def loadu {p:*T if width{T}==8} = load{p} def storeu{p:*T, v:T if width{T}==8} = store{p, v} -def reinterpret{T, x:T} = x -def exportN{f, ...ns} = each{export{.,f}, ns} -def exportT{name, fs} = { v:*oneType{fs} = fs; export{name, v} } - # hints def rare{x if knum{x}} = x @@ -76,6 +90,15 @@ def allSame{{}} = 1 def try_same_type{_, default} = default def try_same_type{{h:T, ...t} if all{hastype{.,T}, t}, _} = T +def broadcast{T, v if isprim{T}} = v +def broadcast{n, v if knum{n}} = each{{_}=>v, range{n}} + +# type stats +def minvalue{T if isunsigned{T}} = 0 +def maxvalue{T if isunsigned{T}} = (1<isprim{T}; {x} => knum{x} } def anyInt = match { {x:T}=>isint{T} ; {x} => knum{x} and (x>>0) == x } @@ -135,27 +158,6 @@ def el_h{[k]T} = [k]w_h{T} def el_m{V=[_]T} = re_el{w_d{T}, V} # double/halve element width, preserving width def el_s{V=[_]T} = re_el{w_h{T}, V} -# type stats -def minvalue{T if isunsigned{T}} = 0 -def maxvalue{T if isunsigned{T}} = (1<v, range{n}} -def collect{vars,begin,end,iter if knum{begin} and knum{end}} = { - each{iter{., vars}, range{end-begin}+begin} -} - -# convert tuple to number in little-endian base b -def base{b,{}} = 0 -def base{b,{h,...t}} = h + b*base{b,t} - # vector definitions @@ -255,6 +257,10 @@ def ceil_log2{n} = clzc{n-1} def ceil_log2{n if knum{n} and n>0} = ceil_log2{(n+1)>>1}+1 def ceil_log2{1} = 0 +# convert tuple to number in little-endian base b +def base{b,{}} = 0 +def base{b,{h,...t}} = h + b*base{b,t} + def truncBits{n, v if n<=8} = cast_i{u8, v} def truncBits{n, v if n==16} = cast_i{u16, v} def truncBits{n, v if n==32} = cast_i{u32, v} @@ -350,19 +356,6 @@ def makeBranch{Ts, F} = { } def makeOptBranch{enable, Ts, F} = if (enable) makeBranch{Ts, F} else 'not defined' - -def tree_fold{F, x} = { - def h = length{x}>>1 - assert{h>0, 'tree_fold of empty'} - F{tree_fold{F, slice{x,0,h}}, tree_fold{F, slice{x,h,length{x}}}} -} -def tree_fold{F, {x}} = x - -def eachx{F, ...args} = { - def l = tree_fold{max, each{{x} => if(istup{x}) length{x} else 0, args}} - each{F, ...each{{x} => if (istup{x}) x else l**x, args}} -} - def undef{T, n if istype{T}} = @collect(n) undef{T} def undef{Ts if istup{Ts}} = each{undef, Ts} def undef{x:T} = undef{T} diff --git a/src/singeli/src/bins.singeli b/src/singeli/src/bins.singeli index bfe88de0..776c7433 100644 --- a/src/singeli/src/bins.singeli +++ b/src/singeli/src/bins.singeli @@ -1,7 +1,6 @@ include './base' include './cbqnDefs' include './mask' -include 'util/tup' def for_dir{up} = if (up) for else for_backwards diff --git a/src/singeli/src/bitalign.singeli b/src/singeli/src/bitalign.singeli index 5b927ce6..ee4cf722 100644 --- a/src/singeli/src/bitalign.singeli +++ b/src/singeli/src/bitalign.singeli @@ -1,5 +1,3 @@ -local include 'util/tup' - def xrange{s, e} = s + range{e-s} def shuf_imm = shuf diff --git a/src/singeli/src/count.singeli b/src/singeli/src/count.singeli index e82db0e0..fb898b9c 100644 --- a/src/singeli/src/count.singeli +++ b/src/singeli/src/count.singeli @@ -1,5 +1,4 @@ include './base' -include 'util/tup' include './vecfold' if_inline (hasarch{'SSE2'}) { diff --git a/src/singeli/src/dyarith.singeli b/src/singeli/src/dyarith.singeli index 21e52ef7..2e917bb8 100644 --- a/src/singeli/src/dyarith.singeli +++ b/src/singeli/src/dyarith.singeli @@ -3,8 +3,6 @@ include './cbqnDefs' include './f64' include './bitops' include './mask' -include 'util/tup' - def rootty{T if isprim{T}} = T def rootty{[_]T} = T diff --git a/src/singeli/src/fold.singeli b/src/singeli/src/fold.singeli index f6019c71..aca562fd 100644 --- a/src/singeli/src/fold.singeli +++ b/src/singeli/src/fold.singeli @@ -2,7 +2,6 @@ include './base' include './mask' if_inline (hasarch{'BMI2'}) include './bmi2' include './spaced' -include 'util/tup' include './scan_common' def opsh64{op}{v:([4]f64), perm} = op{v, shuf{[4]u64, v, perm}} diff --git a/src/singeli/src/replicate.singeli b/src/singeli/src/replicate.singeli index 7f279186..d4fe0aba 100644 --- a/src/singeli/src/replicate.singeli +++ b/src/singeli/src/replicate.singeli @@ -1,6 +1,5 @@ include './base' include './mask' -include 'util/tup' def ind_types = tup{i8, i16, i32} def dat_types = tup{...ind_types, u64} diff --git a/src/singeli/src/scan.singeli b/src/singeli/src/scan.singeli index f8db3a2e..d1a193d2 100644 --- a/src/singeli/src/scan.singeli +++ b/src/singeli/src/scan.singeli @@ -6,7 +6,6 @@ if_inline (hasarch{'X86_64'}) { include './mask' include './f64' include './spaced' -include 'util/tup' include './scan_common' # Initialized scan, generic implementation diff --git a/src/singeli/src/search.singeli b/src/singeli/src/search.singeli index 26a21deb..ea220f32 100644 --- a/src/singeli/src/search.singeli +++ b/src/singeli/src/search.singeli @@ -2,7 +2,6 @@ include './base' include './mask' include './vecfold' include './hashtab' -include 'util/tup' def findFirst{C, M, F, ...v1} = { def exit = makelabel{} diff --git a/src/singeli/src/select.singeli b/src/singeli/src/select.singeli index a1dce94c..27c1d2a2 100644 --- a/src/singeli/src/select.singeli +++ b/src/singeli/src/select.singeli @@ -3,7 +3,6 @@ include './cbqnDefs' include './mask' include './bitops' include './lut' -include 'util/tup' def arch_minvw = if (hasarch{'AARCH64'}) 64 else 128 def arch_minv{T=[_]E if width{T}< arch_minvw} = [arch_minvw / width{E}]E diff --git a/src/singeli/src/slash.singeli b/src/singeli/src/slash.singeli index f32108e6..186d7f21 100644 --- a/src/singeli/src/slash.singeli +++ b/src/singeli/src/slash.singeli @@ -5,7 +5,6 @@ if_inline (hasarch{'X86_64'}) { if_inline (hasarch{'AVX512F'}) include './avx512' } include './mask' -include 'util/tup' def popcRand{x:T if isint{T} and width{T}==64} = emit{u8, 'rand_popc64', x} # under valgrind, return a random result in the range of possible ones def popcRand{x:T if isint{T} and width{T}<=32} = emit{u8, 'rand_popc64', x} diff --git a/src/singeli/src/squeeze.singeli b/src/singeli/src/squeeze.singeli index d6bb4cfc..7295a9c6 100644 --- a/src/singeli/src/squeeze.singeli +++ b/src/singeli/src/squeeze.singeli @@ -2,7 +2,6 @@ include './debug' include './base' include './mask' include './cbqnDefs' -include 'util/tup' include './vecfold' def is_sNaN{x:[_]u64} = tup{homAny, inRangeLen{x<<1, (0xFFE<<52)+2, (1<<52)-2}}