diff --git a/SingeliClone b/SingeliClone index 3c474f3c..45cf1b94 160000 --- a/SingeliClone +++ b/SingeliClone @@ -1 +1 @@ -Subproject commit 3c474f3ce8ba38e48f51a33c305168cda79fc74c +Subproject commit 45cf1b94d5e7346413766ef53ce5476aeb953091 diff --git a/makefile b/makefile index b2bd6dee..62128f69 100644 --- a/makefile +++ b/makefile @@ -14,7 +14,7 @@ debug1: rtperf: @${MAKE} singeli=0 t=rtperf f="-O3 -DRT_PERF" c rtverify: - @${MAKE} singeli=0 t=rtverify f="-DDEBUG -O3 -DRT_VERIFY" c + @${MAKE} singeli=0 t=rtverify f="-DDEBUG -O3 -DRT_VERIFY -DEEQUAL_NEGZERO" c heapverify: @${MAKE} singeli=0 t=heapverify f="-DDEBUG -g -DHEAP_VERIFY" c o3n-singeli: @@ -32,8 +32,7 @@ c: # custom @mkdir -p ${bd} @if [ "${singeli}" -eq 1 ]; then \ mkdir -p src/singeli/gen; \ - ${MAKE} gen-singeli; \ - echo "post-singeli build:"; \ + ${MAKE} postmsg="post-singeli build:" gen-singeli; \ fi @${MAKE} t=${t} FLAGS="${f}" gen @@ -134,12 +133,12 @@ preSingeliBin: git submodule update --init; \ fi @echo "pre-singeli build:" - @${MAKE} singeli=0 postmsg="singeli sources:" t=presingeli f='' c + @${MAKE} singeli=0 postmsg="singeli sources:" t=presingeli f='-O1' c @mv BQN obj/presingeli/BQN gen-singeli: ${addprefix src/singeli/gen/, cmp.c} - @: + @echo $(postmsg) src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin @echo $< | cut -c 17- | sed 's/^/ /' @obj/presingeli/BQN SingeliMake.bqn "$$(if [ -d Singeli ]; then echo Singeli; else echo SingeliClone; fi)" $< $@ "${bd}" diff --git a/src/builtins/cmp.c b/src/builtins/cmp.c index 8d006441..f6e919e2 100644 --- a/src/builtins/cmp.c +++ b/src/builtins/cmp.c @@ -94,10 +94,10 @@ B NAME##_c2(B t, B w, B x) { \ P2(NAME); \ return m_i32(compare(w, x) OP 0); \ } -CMP("≤", le, ge, ge, x,w, <=, 1, 0, ~wv | xv) -CMP("≥", ge, le, ge, w,x, >=, 0, 1, wv | ~xv) -CMP("<", lt, gt, gt, x,w, < , 1, 0, ~wv & xv) -CMP(">", gt, lt, gt, w,x, > , 0, 1, wv & ~xv) +CMP("≤", le,ge, ge, x,w, <=, 1, 0, ~wv | xv) +CMP("≥", ge,le, ge, w,x, >=, 0, 1, wv | ~xv) +CMP("<", lt,gt, gt, x,w, < , 1, 0, ~wv & xv) +CMP(">", gt,lt, gt, w,x, > , 0, 1, wv & ~xv) #undef CMP B eq_c2(B t, B w, B x) { diff --git a/src/core/stuff.c b/src/core/stuff.c index df498e28..8ab4dae3 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -406,7 +406,10 @@ NOINLINE bool equal(B w, B x) { // doesn't consume bool atomEEqual(B w, B x) { // doesn't consume (not that that matters really currently) if (w.u==x.u) return true; - if(isNum(w)|isNum(x)) return false; + #if EEQUAL_NEGZERO + if (isF64(w)&isF64(x)) return w.f==x.f; + #endif + if(isF64(w)|isF64(x)) return false; if (!isVal(w) | !isVal(x)) return false; if (v(w)->type!=v(x)->type) return false; B2B dcf = TI(w,decompose); diff --git a/src/rtwrap.c b/src/rtwrap.c index 34c72092..6c876632 100644 --- a/src/rtwrap.c +++ b/src/rtwrap.c @@ -23,7 +23,20 @@ B wf_identity(B x) { B f = c(WFun,x)->v; return inc(TI(f,identity)(f)); } -#define CHK(A,B) { if (!eequal(A,B)) { print(f); printf(": failed RT_VERIFY\n"); vm_pstLive(); exit(1); } } +#ifndef RT_VERIFY_ARGS + #define RT_VERIFY_ARGS 1 +#endif + +#define CHK(EXP,GOT,W,X) { if (!eequal(EXP,GOT)) { \ + print(f); printf(": failed RT_VERIFY\n"); fflush(stdout); \ + if (RT_VERIFY_ARGS) { \ + if(!q_N(W)){printf("𝕨:"); print(W); putchar('\n'); fflush(stdout); } \ + { printf("𝕩:"); print(X); putchar('\n'); fflush(stdout); } \ + { printf("got:"); print(GOT); putchar('\n'); fflush(stdout); } \ + { printf("exp:"); print(EXP); putchar('\n'); fflush(stdout); } \ + } \ + vm_pstLive(); exit(1); \ +}} u64 fwTotal; B wf_c1(B t, B x) { WFun* c = c(WFun,t); @@ -38,8 +51,14 @@ B wf_c1(B t, B x) { fwTotal+= e-s+20; #else B exp = c1(c->r1, inc(x)); - B r = fi(f, x); - CHK(exp, r); + #if RT_VERIFY_ARGS + B r = fi(f, inc(x)); + CHK(exp, r, bi_N, x); + dec(x); + #else + B r = fi(f, x); + CHK(exp, r, bi_N, x); + #endif dec(exp); #endif return r; @@ -57,8 +76,14 @@ B wf_c2(B t, B w, B x) { fwTotal+= e-s+20; #else B exp = c2(c->r1, inc(w), inc(x)); - B r = fi(f, w, x); - CHK(exp, r); + #if RT_VERIFY_ARGS + B r = fi(f, inc(w), inc(x)); + CHK(exp, r, w, x); + dec(w); dec(x); + #else + B r = fi(f, w, x); + CHK(exp, r, w, x); + #endif dec(exp); #endif return r; diff --git a/src/singeli/builtins/cmp.c b/src/singeli/builtins/cmp.c index 36d985e2..9f07f32a 100644 --- a/src/singeli/builtins/cmp.c +++ b/src/singeli/builtins/cmp.c @@ -1,52 +1,37 @@ +#include #include "../../core.h" +#include "../../builtins.h" + +static NOINLINE void fillBits(u64* dst, u64 sz, bool v) { + u64 x = 0-(u64)v; + for (usz i = 0; i < (sz+63)/64; i++) dst[i] = x; +} + + +#define BCALL(N, X) N(b(X)) +#define interp_f64(X) b(X).f +#define TMPF(T, N, V) static NOINLINE void def_##N##_##T(u64* dst, u64 len, u64 xu) { if (len) fillBits(dst, len, o2bu(c2(bi_##N, V(0), b(xu)))); } +TMPF(f,eq,m_f64) TMPF(f,ne,m_f64) TMPF(f,gt,m_f64) TMPF(f,ge,m_f64) TMPF(f,lt,m_f64) TMPF(f,le,m_f64) +TMPF(c,eq,m_c32) TMPF(c,ne,m_c32) TMPF(c,gt,m_c32) TMPF(c,ge,m_c32) TMPF(c,lt,m_c32) TMPF(c,le,m_c32) +#undef TMPF +#define defcmp(T, N, dst, len, x) def_##N##_##T(dst, len, x) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #include "../gen/cmp.c" #pragma GCC diagnostic pop -#define avx2_eqAA_u8 avx2_eqAA_i8 -#define avx2_eqAA_u16 avx2_eqAA_i16 -#define avx2_eqAA_u32 avx2_eqAA_i32 -#define avx2_neAA_u8 avx2_neAA_i8 -#define avx2_neAA_u16 avx2_neAA_i16 -#define avx2_neAA_u32 avx2_neAA_i32 - -#define avx2_gtAA_u32 avx2_gtAA_i32 -#define avx2_geAA_u32 avx2_geAA_i32 - -#define avx2_eqAS_u8( d,w,x,l) avx2_eqAS_i8 (d,(i8 *)(w),x,l) -#define avx2_eqAS_u16(d,w,x,l) avx2_eqAS_i16(d,(i16*)(w),x,l) -#define avx2_eqAS_u32(d,w,x,l) avx2_eqAS_i32(d,(i32*)(w),x,l) -#define avx2_neAS_u8( d,w,x,l) avx2_neAS_i8 (d,(i8 *)(w),x,l) -#define avx2_neAS_u16(d,w,x,l) avx2_neAS_i16(d,(i16*)(w),x,l) -#define avx2_neAS_u32(d,w,x,l) avx2_neAS_i32(d,(i32*)(w),x,l) - -#define avx2_ltAA_u1(d,w,x,l) avx2_gtAA_u1(d,x,w,l) -#define avx2_leAA_u1(d,w,x,l) avx2_geAA_u1(d,x,w,l) -#define avx2_ltAA_i8(d,w,x,l) avx2_gtAA_i8(d,x,w,l) -#define avx2_leAA_i8(d,w,x,l) avx2_geAA_i8(d,x,w,l) -#define avx2_ltAA_i16(d,w,x,l) avx2_gtAA_i16(d,x,w,l) -#define avx2_leAA_i16(d,w,x,l) avx2_geAA_i16(d,x,w,l) -#define avx2_ltAA_i32(d,w,x,l) avx2_gtAA_i32(d,x,w,l) -#define avx2_leAA_i32(d,w,x,l) avx2_geAA_i32(d,x,w,l) -#define avx2_leAA_u8( d,w,x,l) avx2_geAA_u8 (d,x,w,l) -#define avx2_leAA_u16(d,w,x,l) avx2_geAA_u16(d,x,w,l) -#define avx2_leAA_u32(d,w,x,l) avx2_geAA_u32(d,x,w,l) -#define avx2_ltAA_u8( d,w,x,l) avx2_gtAA_u8 (d,x,w,l) -#define avx2_ltAA_u16(d,w,x,l) avx2_gtAA_u16(d,x,w,l) -#define avx2_ltAA_u32(d,w,x,l) avx2_gtAA_u32(d,x,w,l) -#define avx2_ltAA_f64(d,w,x,l) avx2_gtAA_f64(d,x,w,l) -#define avx2_leAA_f64(d,w,x,l) avx2_geAA_f64(d,x,w,l) - -typedef void (*CmpFn)(u64*, void*, void*, u64); -#define CMPFN(A,F,S,T) (CmpFn) A##_##F##S##_##T -#define FN_LUT(A,F,S) static CmpFn lut_##A##_##F##AA[] = {CMPFN(A,F,S,u1), CMPFN(A,F,S,i8), CMPFN(A,F,S,i16), CMPFN(A,F,S,i32), CMPFN(A,F,S,f64), CMPFN(A,F,S,u8), CMPFN(A,F,S,u16), CMPFN(A,F,S,u32)}; -FN_LUT(avx2, eq, AA) -FN_LUT(avx2, ne, AA) -FN_LUT(avx2, gt, AA) -FN_LUT(avx2, ge, AA) +typedef void (*CmpAAFn)(u64*, void*, void*, u64); +typedef void (*CmpASFn)(u64*, void*, u64, u64); +#define CMPFN(A,F,S,T) (Cmp##S##Fn) A##_##F##S##_##T +#define FN_LUT(A,F,S) static const Cmp##S##Fn lut_##A##_##F##S[] = {CMPFN(A,F,S,u1), CMPFN(A,F,S,i8), CMPFN(A,F,S,i16), CMPFN(A,F,S,i32), CMPFN(A,F,S,f64), CMPFN(A,F,S,u8), CMPFN(A,F,S,u16), CMPFN(A,F,S,u32)} +FN_LUT(avx2, eq, AS); FN_LUT(avx2, eq, AA); +FN_LUT(avx2, ne, AS); FN_LUT(avx2, ne, AA); +FN_LUT(avx2, gt, AS); FN_LUT(avx2, gt, AA); +FN_LUT(avx2, ge, AS); FN_LUT(avx2, ge, AA); +FN_LUT(avx2, lt, AS); +FN_LUT(avx2, le, AS); static void* tyany_ptr(B x) { u8 t = v(x)->type; @@ -74,29 +59,15 @@ static void* tyany_ptr(B x) { dec(w);dec(x); return r; \ } \ } else { AL(w) \ - switch(we) { default: UD; \ - case el_bit: if (!q_bit(x))break; avx2_##NAME##AS_u1 (rp, bitarr_ptr(w), o2bu(x), ria); dec(w); return r; \ - case el_i8: if (!q_i8 (x))break; avx2_##NAME##AS_i8 (rp, i8any_ptr (w), o2iu(x), ria); dec(w); return r; \ - case el_i16: if (!q_i16(x))break; avx2_##NAME##AS_i16(rp, i16any_ptr(w), o2iu(x), ria); dec(w); return r; \ - case el_i32: if (!q_i32(x))break; avx2_##NAME##AS_i32(rp, i32any_ptr(w), o2iu(x), ria); dec(w); return r; \ - case el_f64: if (!q_f64(x))break; avx2_##NAME##AS_f64(rp, f64any_ptr(w), o2fu(x), ria); dec(w); return r; \ - case el_c8: if (!q_c8 (x))break; avx2_##NAME##AS_u8 (rp, c8any_ptr (w), o2cu(x), ria); dec(w); return r; \ - case el_c16: if (!q_c16(x))break; avx2_##NAME##AS_u16(rp, c16any_ptr(w), o2cu(x), ria); dec(w); return r; \ - case el_c32: if (!q_c32(x))break; avx2_##NAME##AS_i32(rp, (i32*)c32any_ptr(w), o2cu(x), ria); dec(w); return r; \ - } \ - dec(r); \ + /*print(w);printf("@%d "CHR" ",we);print(x);printf(": ");*/ \ + lut_avx2_##NAME##AS[we](rp, tyany_ptr(w), x.u, ria); \ + /*print(r);putchar('\n');*/ \ + dec(w); return r; \ } \ } else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; AL(x) \ - switch(xe) { default: UD; \ - case el_bit: if (!q_bit(w))break; avx2_##RNAME##AS_u1 (rp, bitarr_ptr(x), o2bu(w), ria); dec(x); return r; \ - case el_i8: if (!q_i8 (w))break; avx2_##RNAME##AS_i8 (rp, i8any_ptr (x), o2iu(w), ria); dec(x); return r; \ - case el_i16: if (!q_i16(w))break; avx2_##RNAME##AS_i16(rp, i16any_ptr(x), o2iu(w), ria); dec(x); return r; \ - case el_i32: if (!q_i32(w))break; avx2_##RNAME##AS_i32(rp, i32any_ptr(x), o2iu(w), ria); dec(x); return r; \ - case el_f64: if (!q_f64(w))break; avx2_##RNAME##AS_f64(rp, f64any_ptr(x), o2fu(w), ria); dec(x); return r; \ - case el_c8: if (!q_c8 (w))break; avx2_##RNAME##AS_u8 (rp, c8any_ptr (x), o2cu(w), ria); dec(x); return r; \ - case el_c16: if (!q_c16(w))break; avx2_##RNAME##AS_u16(rp, c16any_ptr(x), o2cu(w), ria); dec(x); return r; \ - case el_c32: if (!q_c32(w))break; avx2_##RNAME##AS_i32(rp, (i32*)c32any_ptr(x), o2cu(w), ria); dec(x); return r; \ - } \ - dec(r); \ + /*print(x);printf(" "CHR" ");print(w);printf("@%d: ", xe);*/ \ + lut_avx2_##RNAME##AS[xe](rp, tyany_ptr(x), w.u, ria); \ + /*print(r);putchar('\n');*/ \ + dec(x); return r; \ } \ end:; diff --git a/src/singeli/src/loops.singeli b/src/singeli/src/base.singeli similarity index 73% rename from src/singeli/src/loops.singeli rename to src/singeli/src/base.singeli index c375f33b..c4461964 100644 --- a/src/singeli/src/loops.singeli +++ b/src/singeli/src/base.singeli @@ -1,3 +1,8 @@ +include 'skin/c' +include 'arch/c' +def cdiv{a,b} = (a+b-1)/b +def rare{x:u1} = emit{u1, '__builtin_expect', x, 0} + def unroll{vars,begin,end,block & match{kind{begin},'number'} & match{kind{end},'number'}} = { def f{i,l & i==l} = 0 def f{i,l & i!=l} = { diff --git a/src/singeli/src/cbqnDefs.singeli b/src/singeli/src/cbqnDefs.singeli new file mode 100644 index 00000000..b084e363 --- /dev/null +++ b/src/singeli/src/cbqnDefs.singeli @@ -0,0 +1,20 @@ +def bcall{T, f, x} = emit{T, 'BCALL', f, x} +def from_B{T, x & T==f64} = bcall{T, 'o2fu', x} +def from_B{T, x & T<=i32} = bcall{T, 'o2iu', x} +def from_B{T, x & T<=u32} = bcall{T, 'o2cu', x} + +def q_f64{x} = bcall{u1, 'q_f64', x} +def q_c32{x} = bcall{u1, 'q_c32', x} +def q_chr{T,x & T==u8 } = bcall{u1, 'q_c8', x} +def q_chr{T,x & T==u16} = bcall{u1, 'q_c16', x} +def q_chr{T,x & T==u32} = bcall{u1, 'q_c32', x} + +def cbqn_elType{T & T==u1 } = 0 +def cbqn_elType{T & T==i8 } = 1 +def cbqn_elType{T & T==i16} = 2 +def cbqn_elType{T & T==i32} = 3 +def cbqn_elType{T & T==f64} = 4 +def cbqn_elType{T & T==u8 } = 5 +def cbqn_elType{T & T==u16} = 6 +def cbqn_elType{T & T==u32} = 7 + diff --git a/src/singeli/src/cmp.singeli b/src/singeli/src/cmp.singeli index 033b48c2..29b94e65 100644 --- a/src/singeli/src/cmp.singeli +++ b/src/singeli/src/cmp.singeli @@ -1,14 +1,69 @@ -include 'skin/c' -include 'arch/c' def Size = u64 +include './base' +include './f64' +include './cbqnDefs' include './avx2' include './bitops' -include './loops' + +def name{T} = 'unknown' +def name{T & match{T,__eq}} = 'eq' +def name{T & match{T,__ne}} = 'ne' +def name{T & match{T,__gt}} = 'gt' +def name{T & match{T,__ge}} = 'ge' +def name{T & match{T,__lt}} = 'lt' +def name{T & match{T,__le}} = 'le' -def cdiv{a,b} = (a+b-1)/b +def cif{v, G} = { show{'cif argument not known at compile time!'}; G{} } +def cif{v, G & match{v,0}} = 0 +def cif{v, G & match{v,1}} = G{0} -def any2bit{VT, unr, op, wS, wV, xS, xV, dst:*u64, len:Size} = { +def fillbits{dst:*u64, len:(Size), v} = { + emit{void, 'fillBits', dst, len, v} + return{} +} +def defcmp{op, ty, dst, len, x} = { + emit{void, 'defcmp', ty, name{op}, dst, len, x} + return{} +} + +def pathAS{dst, len, T, op, x & issigned{T}} = { + def eqne = match{op,__eq}|match{op,__ne} + + def XC{f & eqne} = { + if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}} # also includes check for NaN/sNaN + ftrunc_i64{f} + } + def XC{f & match{op,__lt}|match{op,__ge}} = ftrunc_i64{ceil{f}} + def XC{f & match{op,__gt}|match{op,__le}} = ftrunc_i64{floor{f}} + + xf:f64 = interp_f64{x} + xi64:i64 = XC{xf} + + xT:T = cast_i{T, xi64} + #emit{void, 'printf', '"%lu\n"', xi64} + if (rare{(cast_i{i64, xT}!=xi64) | (xi64==cast_i{i64, cast{u64,1}<<63})}) { + cif{~eqne, {_}=>{ + if (isNaN{xf}) defcmp{op, 'f', dst, len, x} + }} + fillbits{dst, len, op{0,xf}} + } + xT +} + +def pathAS{dst, len, T, op, x & T==f64} = { + if (rare{~q_f64{x}}) defcmp{op, 'f', dst, len, x} # fillbits{dst, len, op{0,1}} + from_B{T,x} +} + +def pathAS{dst, len, T, op, x & isunsigned{T}} = { + if (rare{~q_chr{T,x}}) defcmp{op, 'c', dst, len, x} # fillbits{dst, len, op{0,1}} + from_B{T,x} +} + + + +def any2bit{VT, unr, op, wS, wV, xS, xV, dst:*u64, len:(Size)} = { xi:Size = 0 ri:Size = 0 def bam = vcount{VT}*unr @@ -26,36 +81,59 @@ aa2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:*eltype{VT}, len:Size) : void = { any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>load{x,i}, {i}=>vload{xv,i}, dst, len} } -as2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:eltype{VT}, len:Size) : void = { +as2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:u64, len:Size) : void = { show{VT,unr,name{op}} wv:*VT = cast_vp{VT, w} - xv: VT = broadcast{VT, x} + xv: VT = broadcast{VT, pathAS{dst, len, eltype{VT}, op, x}} any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>x, {i}=>xv, dst, len} } -bitAA{op}(dst:*u64, w:*u64, x:*u64, len:Size) : void = { - @for (dst,w,x over _ from 0 to cdiv{len,64}) dst = op{w,x} +bitAA{bitop}(dst:*u64, w:*u64, x:*u64, len:Size) : void = { + @for (dst,w,x over _ from 0 to cdiv{len,64}) dst = bitop{w,x} } + +not(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = ~x } +cpy(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = x } + bitAS{op}(dst:*u64, w:*u64, x:u64, len:Size) : void = { - x = -x - @for (dst,w over _ from 0 to cdiv{len,64}) dst = op{w,x} + show{'bitAS'} + xf:f64 = interp_f64{x} + if (rare{isNaN{xf}}) { + defcmp{op, 'f', dst, len, x} + return{} + } + r0:u1 = op{0,xf} + r1:u1 = op{1,xf} + if (rare{r0==r1}) { + fillbits{dst, len, r0} + return{} + } + if (r0) call{not, dst, w, len} + else call{cpy, dst, w, len} } -#'avx2_eqAA_f64'=aa2bit{[4]f64,4,__eq} -'avx2_eqAA_i8'=aa2bit{[32]i8,1,__eq}; 'avx2_eqAA_i16'=aa2bit{[16]i16,1,__eq}; 'avx2_eqAA_i32'=aa2bit{[8]i32,1,__eq}; 'avx2_eqAA_u1'=bitAA{{a,b}=>a ^ ~b}; 'avx2_eqAA_f64'=aa2bit{[4]f64,2,__eq} -'avx2_neAA_i8'=aa2bit{[32]i8,1,__ne}; 'avx2_neAA_i16'=aa2bit{[16]i16,1,__ne}; 'avx2_neAA_i32'=aa2bit{[8]i32,1,__ne}; 'avx2_neAA_u1'=bitAA{{a,b}=>a ^ b}; 'avx2_neAA_f64'=aa2bit{[4]f64,2,__ne} -'avx2_gtAA_i8'=aa2bit{[32]i8,1,__gt}; 'avx2_gtAA_i16'=aa2bit{[16]i16,1,__gt}; 'avx2_gtAA_i32'=aa2bit{[8]i32,1,__gt}; 'avx2_gtAA_u1'=bitAA{{a,b}=>a & ~b}; 'avx2_gtAA_f64'=aa2bit{[4]f64,2,__gt} -'avx2_geAA_i8'=aa2bit{[32]i8,1,__ge}; 'avx2_geAA_i16'=aa2bit{[16]i16,1,__ge}; 'avx2_geAA_i32'=aa2bit{[8]i32,1,__ge}; 'avx2_geAA_u1'=bitAA{{a,b}=>a | ~b}; 'avx2_geAA_f64'=aa2bit{[4]f64,2,__ge} -'avx2_gtAA_u8'=aa2bit{[32]u8,1,__gt}; 'avx2_gtAA_u16'=aa2bit{[16]u16,1,__gt} -'avx2_geAA_u8'=aa2bit{[32]u8,1,__ge}; 'avx2_geAA_u16'=aa2bit{[16]u16,1,__ge} +# arr-arr =≠ +'avx2_eqAA_i8','avx2_eqAA_u8'=aa2bit{[32]i8,1,__eq}; 'avx2_eqAA_i16','avx2_eqAA_u16'=aa2bit{[16]i16,1,__eq}; 'avx2_eqAA_i32','avx2_eqAA_u32'=aa2bit{[8]i32,1,__eq} +'avx2_neAA_i8','avx2_neAA_u8'=aa2bit{[32]i8,1,__ne}; 'avx2_neAA_i16','avx2_neAA_u16'=aa2bit{[16]i16,1,__ne}; 'avx2_neAA_i32','avx2_neAA_u32'=aa2bit{[8]i32,1,__ne} +'avx2_eqAA_u1'=bitAA{{a,b}=>a ^ ~b}; 'avx2_eqAA_f64'=aa2bit{[4]f64,2,__eq} +'avx2_neAA_u1'=bitAA{{a,b}=>a ^ b}; 'avx2_neAA_f64'=aa2bit{[4]f64,2,__ne} +# arr-arr >≥ +'avx2_gtAA_i8'=aa2bit{[32]i8,1,__gt}; 'avx2_gtAA_i16'=aa2bit{[16]i16,1,__gt}; 'avx2_gtAA_i32','avx2_gtAA_u32'=aa2bit{[8]i32,1,__gt}; 'avx2_gtAA_f64'=aa2bit{[4]f64,2,__gt} +'avx2_geAA_i8'=aa2bit{[32]i8,1,__ge}; 'avx2_geAA_i16'=aa2bit{[16]i16,1,__ge}; 'avx2_geAA_i32','avx2_geAA_u32'=aa2bit{[8]i32,1,__ge}; 'avx2_geAA_f64'=aa2bit{[4]f64,2,__ge} +'avx2_gtAA_u8'=aa2bit{[32]u8,1,__gt}; 'avx2_gtAA_u16'=aa2bit{[16]u16,1,__gt}; 'avx2_gtAA_u1'=bitAA{{a,b}=>a & ~b} +'avx2_geAA_u8'=aa2bit{[32]u8,1,__ge}; 'avx2_geAA_u16'=aa2bit{[16]u16,1,__ge}; 'avx2_geAA_u1'=bitAA{{a,b}=>a | ~b} -'avx2_eqAS_i8'=as2bit{[32]i8,1,__eq}; 'avx2_eqAS_i16'=as2bit{[16]i16,1,__eq}; 'avx2_eqAS_i32'=as2bit{[8]i32,1,__eq}; 'avx2_eqAS_u1'=bitAS{{a,b}=> a ^ ~b}; 'avx2_eqAS_f64'=as2bit{[4]f64,2,__eq} -'avx2_neAS_i8'=as2bit{[32]i8,1,__ne}; 'avx2_neAS_i16'=as2bit{[16]i16,1,__ne}; 'avx2_neAS_i32'=as2bit{[8]i32,1,__ne}; 'avx2_neAS_u1'=bitAS{{a,b}=> a ^ b}; 'avx2_neAS_f64'=as2bit{[4]f64,2,__ne} -'avx2_gtAS_i8'=as2bit{[32]i8,1,__gt}; 'avx2_gtAS_i16'=as2bit{[16]i16,1,__gt}; 'avx2_gtAS_i32'=as2bit{[8]i32,1,__gt}; 'avx2_gtAS_u1'=bitAS{{a,b}=> a & ~b}; 'avx2_gtAS_f64'=as2bit{[4]f64,2,__gt} -'avx2_geAS_i8'=as2bit{[32]i8,1,__ge}; 'avx2_geAS_i16'=as2bit{[16]i16,1,__ge}; 'avx2_geAS_i32'=as2bit{[8]i32,1,__ge}; 'avx2_geAS_u1'=bitAS{{a,b}=> a | ~b}; 'avx2_geAS_f64'=as2bit{[4]f64,2,__ge} -'avx2_ltAS_i8'=as2bit{[32]i8,1,__lt}; 'avx2_ltAS_i16'=as2bit{[16]i16,1,__lt}; 'avx2_ltAS_i32'=as2bit{[8]i32,1,__lt}; 'avx2_ltAS_u1'=bitAS{{a,b}=> ~a & b}; 'avx2_ltAS_f64'=as2bit{[4]f64,2,__lt} -'avx2_leAS_i8'=as2bit{[32]i8,1,__le}; 'avx2_leAS_i16'=as2bit{[16]i16,1,__le}; 'avx2_leAS_i32'=as2bit{[8]i32,1,__le}; 'avx2_leAS_u1'=bitAS{{a,b}=> ~a | b}; 'avx2_leAS_f64'=as2bit{[4]f64,2,__le} -'avx2_gtAS_u8'=as2bit{[32]u8,1,__gt}; 'avx2_gtAS_u16'=as2bit{[16]u16,1,__gt} -'avx2_geAS_u8'=as2bit{[32]u8,1,__ge}; 'avx2_geAS_u16'=as2bit{[16]u16,1,__ge} -'avx2_ltAS_u8'=as2bit{[32]u8,1,__lt}; 'avx2_ltAS_u16'=as2bit{[16]u16,1,__lt} -'avx2_leAS_u8'=as2bit{[32]u8,1,__le}; 'avx2_leAS_u16'=as2bit{[16]u16,1,__le} +# arr-scalar numeric +'avx2_eqAS_i8'=as2bit{[32]i8,1,__eq}; 'avx2_eqAS_i16'=as2bit{[16]i16,1,__eq}; 'avx2_eqAS_i32'=as2bit{[8]i32,1,__eq}; 'avx2_eqAS_f64'=as2bit{[4]f64,2,__eq} +'avx2_neAS_i8'=as2bit{[32]i8,1,__ne}; 'avx2_neAS_i16'=as2bit{[16]i16,1,__ne}; 'avx2_neAS_i32'=as2bit{[8]i32,1,__ne}; 'avx2_neAS_f64'=as2bit{[4]f64,2,__ne} +'avx2_gtAS_i8'=as2bit{[32]i8,1,__gt}; 'avx2_gtAS_i16'=as2bit{[16]i16,1,__gt}; 'avx2_gtAS_i32'=as2bit{[8]i32,1,__gt}; 'avx2_gtAS_f64'=as2bit{[4]f64,2,__gt} +'avx2_geAS_i8'=as2bit{[32]i8,1,__ge}; 'avx2_geAS_i16'=as2bit{[16]i16,1,__ge}; 'avx2_geAS_i32'=as2bit{[8]i32,1,__ge}; 'avx2_geAS_f64'=as2bit{[4]f64,2,__ge} +'avx2_ltAS_i8'=as2bit{[32]i8,1,__lt}; 'avx2_ltAS_i16'=as2bit{[16]i16,1,__lt}; 'avx2_ltAS_i32'=as2bit{[8]i32,1,__lt}; 'avx2_ltAS_f64'=as2bit{[4]f64,2,__lt} +'avx2_leAS_i8'=as2bit{[32]i8,1,__le}; 'avx2_leAS_i16'=as2bit{[16]i16,1,__le}; 'avx2_leAS_i32'=as2bit{[8]i32,1,__le}; 'avx2_leAS_f64'=as2bit{[4]f64,2,__le} +# arr-scalar character & bit +'avx2_eqAS_u8'=as2bit{[32]u8,1,__eq}; 'avx2_eqAS_u16'=as2bit{[16]u16,1,__eq}; 'avx2_eqAS_u32'=as2bit{[8]u32,1,__eq}; 'avx2_eqAS_u1'=bitAS{__eq} +'avx2_neAS_u8'=as2bit{[32]u8,1,__ne}; 'avx2_neAS_u16'=as2bit{[16]u16,1,__ne}; 'avx2_neAS_u32'=as2bit{[8]u32,1,__ne}; 'avx2_neAS_u1'=bitAS{__ne} +'avx2_gtAS_u8'=as2bit{[32]u8,1,__gt}; 'avx2_gtAS_u16'=as2bit{[16]u16,1,__gt}; 'avx2_gtAS_u32'=as2bit{[8]u32,1,__gt}; 'avx2_gtAS_u1'=bitAS{__gt} +'avx2_geAS_u8'=as2bit{[32]u8,1,__ge}; 'avx2_geAS_u16'=as2bit{[16]u16,1,__ge}; 'avx2_geAS_u32'=as2bit{[8]u32,1,__ge}; 'avx2_geAS_u1'=bitAS{__ge} +'avx2_ltAS_u8'=as2bit{[32]u8,1,__lt}; 'avx2_ltAS_u16'=as2bit{[16]u16,1,__lt}; 'avx2_ltAS_u32'=as2bit{[8]u32,1,__lt}; 'avx2_ltAS_u1'=bitAS{__lt} +'avx2_leAS_u8'=as2bit{[32]u8,1,__le}; 'avx2_leAS_u16'=as2bit{[16]u16,1,__le}; 'avx2_leAS_u32'=as2bit{[8]u32,1,__le}; 'avx2_leAS_u1'=bitAS{__le} diff --git a/src/singeli/src/f64.singeli b/src/singeli/src/f64.singeli new file mode 100644 index 00000000..1b4717ee --- /dev/null +++ b/src/singeli/src/f64.singeli @@ -0,0 +1,10 @@ +def ceil{x:f64} = emit{f64, 'ceil', x} +def floor{x:f64} = emit{f64, 'floor', x} + +def NaN = 0.0/0.0 +def isNaN{x:f64} = x!=x + +def ftrunc_i32{x:f64} = emit{i32, '', x} # maybe explicitly use _mm_cvtsd_si32 +def ftrunc_i64{x:f64} = emit{i64, '', x} + +def interp_f64{x:u64} = emit{f64, 'interp_f64', x} \ No newline at end of file