diff --git a/src/builtins/cmp.c b/src/builtins/cmp.c index a47d9a07..8d006441 100644 --- a/src/builtins/cmp.c +++ b/src/builtins/cmp.c @@ -10,7 +10,7 @@ #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) \ +#define CMP_IMPL(CHR, NAME, RNAME, PNAME, L, R, 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); \ if (isF64(w)&isC32(x)) return m_i32(FC); \ @@ -88,27 +88,27 @@ static NOINLINE u8 aMakeEq(B* w, B* x, u8 we, u8 xe) { // returns el_MAX if fail return me; } -#define CMP(CHR,NAME,RNAME,OP,FC,CF,BX) \ +#define CMP(CHR,NAME,RNAME,PNAME,L,R,OP,FC,CF,BX) \ B NAME##_c2(B t, B w, B x) { \ - CMP_IMPL(CHR,NAME,RNAME,OP,FC,CF,BX); \ + CMP_IMPL(CHR,NAME,RNAME,PNAME,L,R,OP,FC,CF,BX); \ P2(NAME); \ return m_i32(compare(w, x) OP 0); \ } -CMP("≤", le, ge, <=, 1, 0, ~wv | xv) -CMP("≥", ge, le, >=, 0, 1, wv | ~xv) -CMP("<", lt, gt, < , 1, 0, ~wv & xv) -CMP(">", gt, lt, > , 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) { - CMP_IMPL("=", eq, eq, ==, 0, 0, ~wv^xv); + CMP_IMPL("=", eq, eq, eq, w,x, ==, 0, 0, ~wv^xv); P2(eq); B r = m_i32(atomEqual(w, x)); dec(w); dec(x); return r; } B ne_c2(B t, B w, B x) { - CMP_IMPL("≠", ne, ne, !=, 1, 1, wv^xv); + CMP_IMPL("≠", ne, ne, ne, w,x, !=, 1, 1, wv^xv); P2(ne); B r = m_i32(!atomEqual(w, x)); dec(w); dec(x); diff --git a/src/h.h b/src/h.h index 0ec98449..898d668a 100644 --- a/src/h.h +++ b/src/h.h @@ -187,8 +187,8 @@ typedef union B { /* 8*/ F(fork) F(atop) \ /*10*/ F(md1D) F(md2D) F(md2H) \ \ - /*13*/ F(harr ) F(i8arr ) F(i16arr ) F(i32arr ) F(fillarr ) F(c8arr ) F(c16arr ) F(c32arr ) F(f64arr ) \ - /*22*/ F(hslice) F(i8slice) F(i16slice) F(i32slice) F(fillslice) F(c8slice) F(c16slice) F(c32slice) F(f64slice) \ + /*13*/ F(hslice) F(fillslice) F(i8slice) F(i16slice) F(i32slice) F(c8slice) F(c16slice) F(c32slice) F(f64slice) \ + /*22*/ F(harr ) F(fillarr ) F(i8arr ) F(i16arr ) F(i32arr ) F(c8arr ) F(c16arr ) F(c32arr ) F(f64arr ) \ /*31*/ F(bitarr) \ \ /*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) \ @@ -203,6 +203,8 @@ enum Type { #undef F t_COUNT }; +#define IS_SLICE(T) ((t)>=t_hslice & (t)<=t_f64slice) +#define IS_ARR(T) ((t)>=t_harr & (t)<=t_bitarr) enum ElType { // a⌈b shall return the type that can store both, if possible el_bit=0, diff --git a/src/singeli/builtins/cmp.c b/src/singeli/builtins/cmp.c index 735d79e8..2bc81e52 100644 --- a/src/singeli/builtins/cmp.c +++ b/src/singeli/builtins/cmp.c @@ -1,14 +1,20 @@ +#include "../../core.h" + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #include "../gen/cmp.c" #pragma GCC diagnostic pop -#define avx2_eqAA_u8( d,w,x,l) avx2_eqAA_i8 (d,(i8 *)(w),(i8 *)(x),l) -#define avx2_eqAA_u16(d,w,x,l) avx2_eqAA_i16(d,(i16*)(w),(i16*)(x),l) -#define avx2_eqAA_u32(d,w,x,l) avx2_eqAA_i32(d,(i32*)(w),(i32*)(x),l) -#define avx2_neAA_u8( d,w,x,l) avx2_neAA_i8 (d,(i8 *)(w),(i8 *)(x),l) -#define avx2_neAA_u16(d,w,x,l) avx2_neAA_i16(d,(i16*)(w),(i16*)(x),l) -#define avx2_neAA_u32(d,w,x,l) avx2_neAA_i32(d,(i32*)(w),(i32*)(x),l) +#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) @@ -33,8 +39,40 @@ #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) + + +static void* tyany_ptr(B x) { + u8 t = v(x)->type; + if (IS_SLICE(t)) switch (t) { default: UD; + case t_i8slice: return c(I8Slice,x)->a; + case t_i16slice: return c(I16Slice,x)->a; + case t_i32slice: return c(I32Slice,x)->a; + case t_c8slice: return c(C8Slice,x)->a; + case t_c16slice: return c(C16Slice,x)->a; + case t_c32slice: return c(C32Slice,x)->a; + case t_f64slice: return c(F64Slice,x)->a; + } + switch (t) { default: UD; + case t_bitarr: return c(BitArr,x)->a; + case t_i8arr: return c(I8Arr, x)->a; + case t_i16arr: return c(I16Arr,x)->a; + case t_i32arr: return c(I32Arr,x)->a; + case t_c8arr: return c(C8Arr, x)->a; + case t_c16arr: return c(C16Arr,x)->a; + case t_c32arr: return c(C32Arr,x)->a; + case t_f64arr: return c(F64Arr,x)->a; + } +} + #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) \ +#define CMP_IMPL(CHR, NAME, RNAME, PNAME, L, R, 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); \ if (isF64(w)&isC32(x)) return m_i32(FC); \ @@ -50,16 +88,7 @@ w=tw; x=tx; \ } \ AL(x) \ - switch(we) { default: UD; \ - case el_bit: avx2_##NAME##AA_u1 (rp, bitarr_ptr(w), bitarr_ptr(x), ria); break; \ - case el_i8: avx2_##NAME##AA_i8 (rp, i8any_ptr (w), i8any_ptr (x), ria); break; \ - case el_i16: avx2_##NAME##AA_i16(rp, i16any_ptr(w), i16any_ptr(x), ria); break; \ - case el_i32: avx2_##NAME##AA_i32(rp, i32any_ptr(w), i32any_ptr(x), ria); break; \ - case el_f64: avx2_##NAME##AA_f64(rp, f64any_ptr(w), f64any_ptr(x), ria); break; \ - case el_c8: avx2_##NAME##AA_u8 (rp, c8any_ptr (w), c8any_ptr (x), ria); break; \ - case el_c16: avx2_##NAME##AA_u16(rp, c16any_ptr(w), c16any_ptr(x), ria); break; \ - case el_c32: avx2_##NAME##AA_i32(rp, (i32*)c32any_ptr(w), (i32*)c32any_ptr(x), ria); break; \ - } \ + lut_avx2_##PNAME##AA[we](rp, tyany_ptr(L), tyany_ptr(R), ria); \ dec(w);dec(x); return r; \ } \ } else { AL(w) \