array-scalar comparison function lookup table
This commit is contained in:
parent
d42dd3dcf9
commit
3e372620a2
@ -1 +1 @@
|
||||
Subproject commit 3c474f3ce8ba38e48f51a33c305168cda79fc74c
|
||||
Subproject commit 45cf1b94d5e7346413766ef53ce5476aeb953091
|
||||
9
makefile
9
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}"
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
35
src/rtwrap.c
35
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;
|
||||
|
||||
@ -1,52 +1,37 @@
|
||||
#include <math.h>
|
||||
#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:;
|
||||
|
||||
@ -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} = {
|
||||
20
src/singeli/src/cbqnDefs.singeli
Normal file
20
src/singeli/src/cbqnDefs.singeli
Normal file
@ -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
|
||||
|
||||
@ -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}
|
||||
|
||||
10
src/singeli/src/f64.singeli
Normal file
10
src/singeli/src/f64.singeli
Normal file
@ -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}
|
||||
Loading…
Reference in New Issue
Block a user