diff --git a/src/builtins/slash.c b/src/builtins/slash.c index 648fa4f3..d35b3f15 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -81,8 +81,6 @@ #if !USE_VALGRIND #define rand_popc64(X) POPC(X) #endif -static void storeu_u64(u64* p, u64 v) { memcpy(p, &v, 8); } -static u64 loadu_u64(u64* p) { u64 v; memcpy(&v, p, 8); return v; } #if SINGELI #define SINGELI_FILE slash diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index 08e80bf0..d056f53f 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -2,18 +2,36 @@ include 'skin/c' include 'arch/c' include 'util/kind' +def Size = u64 +config usz = u32 + +def same = is oper ~~ reinterpret infix right 55 oper ** broadcast infix right 55 -def same = is -def Size = u64 -def load{x} = *x + +def isreg = kreg +def isconst = kcon +def istype = ktyp +def istup = ktup + +def isunsigned{T} = isint{T} & ~issigned{T} + +def isvec {T} = 0; def isvec {T & istype{T}} = same{typekind{T},'vector'} +def isprim{T} = 0; def isprim{T & istype{T}} = same{typekind{T},'primitive'} +def isptr {T} = 0; def isptr {T & istype{T}} = same{typekind{T},'pointer'} +def elwidth{T} = width{eltype{T}} + + + +def load{p:P & isptr{P}} = load{p, 0} +def store{p:P, v:V & isptr{P} & eltype{P}==v} = store{p, 0, v} +def loadu{p:T & isunsigned{eltype{T}}} = emit{eltype{T}, merge{'loadu_u',fmtnat{elwidth{T}}}, p} +def storeu{p:T, v:eltype{T} & isunsigned{eltype{T}}} = emit{void, merge{'storeu_u',fmtnat{elwidth{T}}}, p, v} + def reinterpret{T, x:X & T==X} = x def exportN{f, ...ns} = each{{n} => export{n, f}, ns} def exportT{name, fs} = { v:*type{tupsel{0,fs}} = fs; export{name, v} } -config usz = u32 - -def elwidth{T} = width{eltype{T}} # more arith def cdiv{a,b} = (a+b-1)/b # ceiling divide @@ -62,18 +80,6 @@ def oneVal{{h, ...t}} = { def oneVal{{}} = {} def oneType{x} = oneVal{each{type, x}} -def isreg = kreg -def isconst = kcon -def istype = ktyp -def istup = ktup - -def isunsigned{T} = isint{T} & ~issigned{T} - -def isvec {T} = 0; def isvec {T & istype{T}} = same{typekind{T},'vector'} -def isprim{T} = 0; def isprim{T & istype{T}} = same{typekind{T},'primitive'} -def isptr {T} = 0; def isptr {T & istype{T}} = same{typekind{T},'pointer'} - - def anyNum{x} = isconst{x} | knum{x} def anyNum{x:T} = isprim{T} diff --git a/src/singeli/src/bitops.singeli b/src/singeli/src/bitops.singeli index 9d74a627..ce0fde1c 100644 --- a/src/singeli/src/bitops.singeli +++ b/src/singeli/src/bitops.singeli @@ -82,8 +82,6 @@ def loadBatchBit{T, x:*u64, n:(Size)} = { # vector with type T with each element spreadBits{T, b_getBatchLo{vcount{T}, x, n}} } -def loadu{p:T & *u64==T} = emit{eltype{T}, 'loadu_u64', p} - # load bits starting at bit i, leaving garbage at the top. Only the bottom 57 bits are guaranteed correct; 58 and 60 will be correct if `i` is a multiple of it def loaduBitRaw{x:*u64, i} = { loadu{*u64~~((*u8~~x) + (i>>3))} >> (i&7) diff --git a/src/singeli/src/neon.singeli b/src/singeli/src/neon.singeli index 15032c8d..4e558e6a 100644 --- a/src/singeli/src/neon.singeli +++ b/src/singeli/src/neon.singeli @@ -93,10 +93,6 @@ def vfold{F, x:T & nvec{T} & ~nveci{T,64} & same{F, min}} = fold_min{x} def vfold{F, x:T & nvec{T} & ~nveci{T,64} & same{F, max}} = fold_max{x} def vfold{F, x:T & nvec{T} & same{F, +}} = fold_add{x} -# TODO don't rely on regular stores being unaligned -local def storeu{ptr:P, e:T} = store{ptr, 0, e} -local def loadu{ptr:P} = load{ptr} - def storeLow{ptr:P, w, x:T & nvec{T} & w<=64} = { def E=ty_u{w}; storeu{*E~~ptr, extract{to_el{E,T}~~x, 0}} } def storeLow{ptr:P, w, x:T & nvec{T} & w==width{T}} = store{*T~~ptr, 0, x} diff --git a/src/singeli/src/slash.singeli b/src/singeli/src/slash.singeli index 80d40a94..8ba61b25 100644 --- a/src/singeli/src/slash.singeli +++ b/src/singeli/src/slash.singeli @@ -20,9 +20,6 @@ if (hasarch{'AVX512F'}) { include './mask' include 'util/tup' -def storeu{p:T, i, v:eltype{T} & *u64==T} = emit{void, 'storeu_u64', p+i, v} -def loadu{p:T & *u64==T} = emit{eltype{T}, 'loadu_u64', p} - def popcRand{x:T & isint{T} & width{T}==64} = emit{u8, 'rand_popc64', x} # under valgrind, return a random result in the range of possible ones def popcRand{x:T & isint{T} & width{T}<=32} = emit{u8, 'rand_popc64', x} @@ -141,7 +138,7 @@ fn slash{c==0, T & T<=i16}(w:*u64, x:arg{c,T}, r:*T, l:u64, sum:u64) : void = { def rn = if (has_popc) r+popc{w} else 0 def step{w} = { i := load{tab, w} - storeu{*u64~~r, 0, j + i} + storeu{*u64~~r, j + i} r += popc_alt{w, i, tw} j += inc } diff --git a/src/utils/includeSingeli.h b/src/utils/includeSingeli.h index c97af53e..83d2dfc7 100644 --- a/src/utils/includeSingeli.h +++ b/src/utils/includeSingeli.h @@ -13,6 +13,9 @@ #define _mm_storeu_si32 custom_storeu_si32 #endif + static void storeu_u64(u64* p, u64 v) { memcpy(p, &v, 8); } + static u64 loadu_u64(u64* p) { u64 v; memcpy(&v, p, 8); return v; } + #define BCALL(N, X) N(b(X)) #define interp_f64(X) b(X).f diff --git a/src/utils/mut.c b/src/utils/mut.c index bd6b0859..c4648b3f 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -293,7 +293,6 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x } #if SINGELI_SIMD - static u64 loadu_u64(u64* p) { u64 v; memcpy(&v, p, 8); return v; } #define SINGELI_FILE copy #include "./includeSingeli.h" typedef void (*copy_fn)(void*, void*, u64, void*);