From cd431d3338978e426a2c0f92f93ccc9c93a26b66 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 21 Apr 2022 03:51:37 +0300 Subject: [PATCH] singeli +` --- makefile | 2 +- src/builtins/md1.c | 17 +++++++++++++++-- src/singeli/src/avx.singeli | 1 + src/singeli/src/avx2.singeli | 2 +- src/singeli/src/base.singeli | 10 ++++++++++ src/singeli/src/bmi2.singeli | 6 ++++++ src/singeli/src/scan.singeli | 36 +++++++++++++++++++++++++++++++++++ src/singeli/src/slash.singeli | 7 +------ 8 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 src/singeli/src/bmi2.singeli create mode 100644 src/singeli/src/scan.singeli diff --git a/makefile b/makefile index 973fc8da..b369434a 100644 --- a/makefile +++ b/makefile @@ -140,7 +140,7 @@ preSingeliBin: @${MAKE} singeli=0 postmsg="singeli sources:" t=presingeli f='-O1' OUTPUT=obj/presingeli/BQN c -gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c slash.c equal.c} +gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c slash.c equal.c scan.c} @echo $(postmsg) src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin @echo $< | cut -c 17- | sed 's/^/ /' diff --git a/src/builtins/md1.c b/src/builtins/md1.c index 9ee0c071..171b78fb 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -119,6 +119,14 @@ B scan_ne(u64 p, B x, u64 ia) { decG(x); return r; } + +#if SINGELI + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-variable" + #include "../singeli/gen/scan.c" + #pragma GCC diagnostic pop +#endif + B scan_c1(Md1D* d, B x) { B f = d->f; if (isAtm(x) || rnk(x)==0) thrM("`: Argument cannot have rank 0"); ur xr = rnk(x); @@ -129,8 +137,13 @@ B scan_c1(Md1D* d, B x) { B f = d->f; if (xr==1 && xe<=el_f64 && isFun(f) && v(f)->flags) { u8 rtid = v(f)->flags-1; if (rtid==n_add) { // + - if (ia=U} = emit{T, '', x} def trunc{T, x & knum{x}} = cast{T, x} def ext {T, x & knum{x}} = cast{T, x} +# basic ceiling divide def cdiv{a,b} = (a+b-1)/b + +# base-2 log of a constant power of two +def lb{n & knum{n} & (n>>1<<1) == n & n>0} = lb{n>>1}+1 +def lb{n==1} = 0 + +# get the n least significant bits +def lsbs{x, n} = x - (x>>n << n) + def rare{x:u1} = emit{u1, '__builtin_expect', x, 0} def isunsigned{T} = isint{T} & ~issigned{T} def assert{x:u1} = emit{void, 'si_assert', x} @@ -88,6 +97,7 @@ def isfloatv{T} = isfloat{eltype{T}} def issignedv{T} = issigned{eltype{T}} def isunsignedv{T} = isunsigned{eltype{T}} def istype{T} = match{kind{T},'type'} +def istup{T} = match{kind{T},'tuple'} def isvec{T} = 0 def isvec{T & istype{T}} = match{typekind{T},'vector'} diff --git a/src/singeli/src/bmi2.singeli b/src/singeli/src/bmi2.singeli new file mode 100644 index 00000000..b2d13147 --- /dev/null +++ b/src/singeli/src/bmi2.singeli @@ -0,0 +1,6 @@ +def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m} +def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m} +def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m} +def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m} +def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x} +def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x} diff --git a/src/singeli/src/scan.singeli b/src/singeli/src/scan.singeli new file mode 100644 index 00000000..b4bc10be --- /dev/null +++ b/src/singeli/src/scan.singeli @@ -0,0 +1,36 @@ +include '/home/dzaima/D/cbqn/src/singeli/src/base' +# def Size = u64 +include '/home/dzaima/D/cbqn/src/singeli/src/sse3' +include '/home/dzaima/D/cbqn/src/singeli/src/avx' +include '/home/dzaima/D/cbqn/src/singeli/src/avx2' +include '/home/dzaima/D/cbqn/src/singeli/src/bmi2' +include '/home/dzaima/D/cbqn/src/singeli/src/mask' + +avx2_bcs32(x:*u64, r:*i32, l:u64) : void = { + rv:= *[8]u32~~r + xv:= *u8~~x + + def step{x} = { + m:u32 = 2b0001_0001_0001_0001_0001_0001_0001_0001 + a:= pdep{promote{u32,x},m} + d:= a*m # b:= a + a<<16; c:= b + b<<8; d:= c + c<<4 + e:= broadcast{[8]u32, d} + f:= e >> make{[8]u32, iota{8}*4} + tup{f & broadcast{[8]u32, 0xf}, d, e} + } + + c:= broadcast{[8]u32, 0} + e:= l/8 + @for(x in xv, r in rv over _ to e) { + def sr = step{x} + r = tupsel{0, sr}+c + # c+= broadcast{[8]u32, popc{x}} + # c+= broadcast{[8]u32, tupsel{1, sr}>>28} + c+= tupsel{2, sr}>>28 + } + if (e*8 != l) { + r:= c+tupsel{0, step{load{xv, e}}} + maskstoreF{rv, maskOf{[8]i32, l - e*8}, e, r} + } +} +'avx2_bcs32' = avx2_bcs32 \ No newline at end of file diff --git a/src/singeli/src/slash.singeli b/src/singeli/src/slash.singeli index a09dd4f2..5b09a7c8 100644 --- a/src/singeli/src/slash.singeli +++ b/src/singeli/src/slash.singeli @@ -1,11 +1,6 @@ include './base' +include './bmi2' -def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m} -def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m} -def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m} -def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m} -def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x} -def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x} def comp8{w:*u64, X, r:*i8, l:u64} = { @for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {