diff --git a/src/core/arrFns.h b/src/core/arrFns.h index ed98083b..f80df18d 100644 --- a/src/core/arrFns.h +++ b/src/core/arrFns.h @@ -14,9 +14,9 @@ static B* arrV_bptr(Arr* x) { if (x->type==t_fillslice) return ((FillSlice*)x)->a; return NULL; } -static void* tyarr_ptr(B x) { return c(TyArr,x)->a; } -static void* tyslice_ptr(B x) { return c(TySlice,x)->a; } -static void* tyany_ptr(B x) { +static void* tyarr_ptr(B x) { assert(IS_ARR(v(x)->type)); return c(TyArr,x)->a; } +static void* tyslice_ptr(B x) { assert(IS_SLICE(v(x)->type)); return c(TySlice,x)->a; } +static void* tyany_ptr(B x) { assert(IS_ARR(v(x)->type) || IS_SLICE(v(x)->type)); u8 t = v(x)->type; return IS_SLICE(t)? c(TySlice,x)->a : c(TyArr,x)->a; } @@ -38,4 +38,6 @@ static void* m_tyarrcO(B* rp, usz w, B x, u8 type, usz over) M_TYARR(+over, a extern u8 elType2type[]; #define el2t(X) elType2type[X] // TODO maybe reorganize array types such that this can just be addition? extern u8 elTypeWidth[]; -#define elWidth(X) elTypeWidth[X] \ No newline at end of file +#define elWidth(X) elTypeWidth[X] +extern u8 arrTypeWidthLog[]; +#define arrTypeWidthLog(X) arrTypeWidthLog[X] \ No newline at end of file diff --git a/src/core/tyarr.c b/src/core/tyarr.c index 803776d2..7499787f 100644 --- a/src/core/tyarr.c +++ b/src/core/tyarr.c @@ -13,6 +13,13 @@ u8 elTypeWidth[] = { [el_i32] = 4, [el_c32] = 4, [el_bit] = 0, [el_f64] = 8 }; +u8 arrTypeWidthLog[] = { + [t_bitarr]=99, + [t_i8arr ]=0, [t_i8slice ]=0, [t_c8arr ]=0, [t_c8slice ]=0, + [t_i16arr]=1, [t_i16slice]=1, [t_c16arr]=1, [t_c16slice]=1, + [t_i32arr]=2, [t_i32slice]=2, [t_c32arr]=2, [t_c32slice]=2, + [t_f64arr]=3, [t_f64slice]=3 +}; B m_i8(i8 x) { return m_i32(x); } B m_i16(i16 x) { return m_i32(x); } B m_c8(u8 x) { return m_c32(x); } B m_c16(u16 x) { return m_c32(x); } diff --git a/src/utils/mut.c b/src/utils/mut.c index 5dd8a581..425d6445 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -64,7 +64,7 @@ B vec_join(B w, B x) { #define CHK_S(REQ,X,N,...) CHK(REQ, el_or(m->fns->elType, selfElType(X)), N, __VA_ARGS__) -#define DEF(RT, N, TY, INIT, CHK, EL, ARGS, ...) \ +#define DEF0(RT, N, TY, INIT, CHK, EL, ARGS, ...) \ static RT m_##N##G_##TY ARGS; \ static RT m_##N##_##TY ARGS { INIT \ Mut* m = a; \ @@ -74,7 +74,10 @@ B vec_join(B w, B x) { } else { \ m_##N##G_##TY(m->a, __VA_ARGS__); \ } \ - } \ + } + +#define DEF(RT, N, TY, INIT, CHK, EL, ARGS, ...) \ + DEF0(RT, N, TY, INIT, CHK, EL, ARGS, __VA_ARGS__) \ static RT m_##N##G_##TY ARGS #define DEF_S( RT, N, TY, CHK, X, ARGS, ...) DEF(RT, N, TY, , CHK, selfElType(X), ARGS, __VA_ARGS__) @@ -113,7 +116,14 @@ DEF_G(void, fill, B , (void* a, usz ms, B x, usz l), ms, x, l) { return; } -#define DEF_COPY(TY, BODY) DEF(void, copy, TY, u8 xe=TI(x,elType); u8 ne=el_or(xe,el_##TY);, ne==el_##TY, ne, (void* a, usz ms, B x, usz xs, usz l), ms, x, xs, l) { u8 xt=v(x)->type; (void)xt; BODY } + +#if SINGELI + #define DEF_COPY(TY, BODY) DEF0(void, copy, TY, u8 xe=TI(x,elType); u8 ne=el_or(xe,el_##TY);, ne==el_##TY, ne, (void* a, usz ms, B x, usz xs, usz l), ms, x, xs, l) +#else + #define DEF_COPY(TY, BODY) DEF(void, copy, TY, u8 xe=TI(x,elType); u8 ne=el_or(xe,el_##TY);, ne==el_##TY, ne, (void* a, usz ms, B x, usz xs, usz l), ms, x, xs, l) { u8 xt=v(x)->type; (void)xt; BODY } +#endif + + DEF_COPY(bit, { bit_cpy((u64*)a, ms, bitarr_ptr(x), xs, l); return; }) DEF_COPY(i8 , { i8* rp = ms+(i8*)a; switch (xt) { default: UD; @@ -245,7 +255,37 @@ DEF_G(void, copy, B, (void* a, usz ms, B x, usz xs, usz l), ms, x, x H, {COPY_FN(1,B),COPY_FN(i8,B),COPY_FN(i16,B),COPY_FN(i32,B),COPY_FN(f64,B),COPY_FN(c8,B),COPY_FN(c16,B),COPY_FN(c32,B),cpyHArr_B, COPY_FN(f64,B)}) MAKE_CPY(1, u64* rp; Arr* r = m_bitarrp(&rp, ia), getU, BIT_PUT, rp, H2T_COPY(Bit), Bit, {COPY_FN(1,1),COPY_FN(i8,1),COPY_FN(i16,1),COPY_FN(i32,1),COPY_FN(f64,1),badCopy, badCopy, badCopy, cpyBitArr_B, COPY_FN(f64,1)}) - + + + static copy_fn tcopy_i8Fns [] = {[t_bitarr]=avx2_copy_1_i8, [t_i8arr]=avx2_copy_i8_i8 ,[t_i8slice]=avx2_copy_i8_i8}; + static copy_fn tcopy_i16Fns[] = {[t_bitarr]=avx2_copy_1_i16, [t_i8arr]=avx2_copy_i8_i16,[t_i8slice]=avx2_copy_i8_i16, [t_i16arr]=avx2_copy_i16_i16,[t_i16slice]=avx2_copy_i16_i16}; + static copy_fn tcopy_i32Fns[] = {[t_bitarr]=avx2_copy_1_i32, [t_i8arr]=avx2_copy_i8_i32,[t_i8slice]=avx2_copy_i8_i32, [t_i16arr]=avx2_copy_i16_i32,[t_i16slice]=avx2_copy_i16_i32, [t_i32arr]=avx2_copy_i32_i32,[t_i32slice]=avx2_copy_i32_i32}; + static copy_fn tcopy_f64Fns[] = {[t_bitarr]=avx2_copy_1_f64, [t_i8arr]=avx2_copy_i8_f64,[t_i8slice]=avx2_copy_i8_f64, [t_i16arr]=avx2_copy_i16_f64,[t_i16slice]=avx2_copy_i16_f64, [t_i32arr]=avx2_copy_i32_f64,[t_i32slice]=avx2_copy_i32_f64, [t_f64arr]=avx2_copy_f64_f64,[t_f64slice]=avx2_copy_f64_f64}; + static copy_fn tcopy_c8Fns [] = {[t_c8arr]=avx2_copy_c8_c8 ,[t_c8slice]=avx2_copy_c8_c8}; + static copy_fn tcopy_c16Fns[] = {[t_c8arr]=avx2_copy_c8_c16,[t_c8slice]=avx2_copy_c8_c16, [t_c16arr]=avx2_copy_c16_c16,[t_c16slice]=avx2_copy_c16_c16}; + static copy_fn tcopy_c32Fns[] = {[t_c8arr]=avx2_copy_c8_c32,[t_c8slice]=avx2_copy_c8_c32, [t_c16arr]=avx2_copy_c16_c32,[t_c16slice]=avx2_copy_c16_c32, [t_c32arr]=avx2_copy_c32_c32,[t_c32slice]=avx2_copy_c32_c32}; + + #define TCOPY_FN(T, N) static void m_copyG_##N(void* a, usz ms, B x, usz xs, usz l) { \ + if (l==0) return; \ + u8* xp = tyany_ptr(x); \ + T* rp = ms + (T*)a; \ + u8 xt = v(x)->type; \ + if (xt==t_bitarr) { \ + for (usz i = 0; i < l; i++) rp[i] = bitp_get((u64*)xp, xs+i); \ + } else { \ + tcopy_##N##Fns[xt]((xs << arrTypeWidthLog(xt)) + (u8*)xp, (u8*)rp, l, (u8*)a(x)); \ + } \ + } + TCOPY_FN(i8,i8) + TCOPY_FN(i16,i16) + TCOPY_FN(i32,i32) + TCOPY_FN(u8,c8) + TCOPY_FN(u16,c16) + TCOPY_FN(u32,c32) + TCOPY_FN(f64,f64) + static void m_copyG_bit(void* a, usz ms, B x, usz xs, usz l) { + bit_cpy((u64*)a, ms, bitarr_ptr(x), xs, l); + } #else #define MAKE_ICPY(T,E) T##Arr* cpy##T##Arr(B x) { \ usz ia = a(x)->ia; \