From 5d76148c51bae426f27aa97e3790aa0aa8fdfd2a Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 22 Oct 2021 00:58:34 +0300 Subject: [PATCH] lazy singeli bit comparison fns --- src/builtins/cmp.c | 2 +- src/singeli/builtins/cmp.c | 9 ++++++--- src/singeli/src/cmp.singeli | 37 ++++++++++++++++++----------------- src/singeli/src/loops.singeli | 15 ++++++++++++++ 4 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 src/singeli/src/loops.singeli diff --git a/src/builtins/cmp.c b/src/builtins/cmp.c index f66e73e4..a47d9a07 100644 --- a/src/builtins/cmp.c +++ b/src/builtins/cmp.c @@ -5,11 +5,11 @@ SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("cmp " #N, w, x); \ return arith_recd(N##_c2, w, x); \ }} -#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=a(r)->ia; usz bia = BIT_N(ria); #if SINGELI #include "../singeli/builtins/cmp.c" #else +#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=a(r)->ia; usz bia = BIT_N(ria); #define CMP_IMPL(CHR, NAME, RNAME, OP, FC, CF, BX) \ if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \ if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \ diff --git a/src/singeli/builtins/cmp.c b/src/singeli/builtins/cmp.c index 5421820c..735d79e8 100644 --- a/src/singeli/builtins/cmp.c +++ b/src/singeli/builtins/cmp.c @@ -16,6 +16,8 @@ #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) @@ -31,6 +33,7 @@ #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) +#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=a(r)->ia; #define CMP_IMPL(CHR, NAME, RNAME, OP, FC, CF, BX) \ if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \ if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \ @@ -48,7 +51,7 @@ } \ AL(x) \ switch(we) { default: UD; \ - case el_bit: { u64* wp=bitarr_ptr(w); u64* xp=bitarr_ptr(x); for(usz i=0;iload{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} +} +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} +} + #'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_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_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_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_f64'=aa2bit{[4]f64,2,__ge} +'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} -'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} +'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} diff --git a/src/singeli/src/loops.singeli b/src/singeli/src/loops.singeli new file mode 100644 index 00000000..c375f33b --- /dev/null +++ b/src/singeli/src/loops.singeli @@ -0,0 +1,15 @@ +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} = { + exec{i, vars, block} + f{i+1, l} + } + f{begin,end} +} +def for{vars,begin,end,block} = { + i:u64 = begin + while (i < end) { + exec{i, vars, block} + i = i+1 + } +}