BMI2 bitarr/i8arr & bitarr/i16arr
This commit is contained in:
parent
54a9000d88
commit
37bf551e54
@ -15,8 +15,8 @@
|
||||
## Configuration options
|
||||
|
||||
- `some-other-bqn-implementation ./genRuntime path/to/mlochbaum/BQN` can be used to avoid pulling precompiled bytecode with git from `remotes/origin/bytecode`.
|
||||
This creates the dummy file `src/gen/customRuntime` and will disable automated bytecode retrieval whenever it's updated.
|
||||
`make clean-runtime` (which is included in `make clean`) can be used to reset to the default state.
|
||||
This creates the dummy file `src/gen/customRuntime`, which will disable automated bytecode retrieval, leading to the bytecode going out-of-sync whenever it needs updating.
|
||||
`make clean-runtime` (which is included in `make clean`) can be used to reset this to the default state.
|
||||
- Different build types:
|
||||
- `make o3` - `-O3`, the default build
|
||||
- `make o3n` - `-O3 -march=native`
|
||||
|
||||
2
makefile
2
makefile
@ -136,7 +136,7 @@ preSingeliBin:
|
||||
@mv BQN obj/presingeli/BQN
|
||||
|
||||
|
||||
gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c}
|
||||
gen-singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c slash.c}
|
||||
@echo $(postmsg)
|
||||
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||
|
||||
@ -498,8 +498,17 @@ B slash_c1(B t, B x) {
|
||||
return r;
|
||||
}
|
||||
#ifdef __BMI2__
|
||||
#include <immintrin.h>
|
||||
#include <immintrin.h>
|
||||
u64 c16lut[] = {0x0000000000000000, 0x000000000000ffff, 0x00000000ffff0000, 0x00000000ffffffff, 0x0000ffff00000000, 0x0000ffff0000ffff, 0x0000ffffffff0000, 0x0000ffffffffffff, 0xffff000000000000, 0xffff00000000ffff, 0xffff0000ffff0000, 0xffff0000ffffffff, 0xffffffff00000000, 0xffffffff0000ffff, 0xffffffffffff0000, 0xffffffffffffffff};
|
||||
|
||||
#if SINGELI
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#include "../singeli/gen/slash.c"
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
B slash_c2(B t, B w, B x) {
|
||||
if (isArr(x) && rnk(x)==1 && isArr(w) && rnk(w)==1 && depth(w)==1) {
|
||||
usz wia = a(w)->ia;
|
||||
@ -518,6 +527,7 @@ B slash_c2(B t, B w, B x) {
|
||||
if (wsum==0) { dec(w); dec(x); return q_N(xf)? emptyHVec() : isF64(xf)? emptyIVec() : isC32(xf)? emptyCVec() : m_emptyFVec(xf); }
|
||||
B r;
|
||||
switch(TI(x,elType)) { default: UD;
|
||||
|
||||
#ifdef __BMI2__
|
||||
case el_bit: { u64* xp = bitarr_ptr(x); u64* rp; r = m_bitarrv(&rp,wsum+128); a(r)->ia = wsum;
|
||||
u64 cw = 0; // current word
|
||||
@ -540,8 +550,15 @@ B slash_c2(B t, B w, B x) {
|
||||
#else
|
||||
case el_bit: { u64* xp = bitarr_ptr(x); u64* rp; r = m_bitarrv(&rp,wsum); for (usz i=0; i<wia; i++) { bitp_set(rp,ri,bitp_get(xp,i)); ri+= bitp_get(wp,i); } break; }
|
||||
#endif
|
||||
|
||||
#if SINGELI && defined(__BMI2__)
|
||||
case el_i8: { i8* xp = i8any_ptr (x); i8* rp; r = m_i8arrv (&rp, wsum+8); a(r)->ia-= 8; comp8 (wp, xp, rp, wia); break; }
|
||||
case el_i16: { i16* xp = i16any_ptr(x); i16* rp; r = m_i16arrv(&rp, wsum+16); a(r)->ia-= 16; comp16(wp, xp, rp, wia); break; }
|
||||
#else
|
||||
case el_i8: { i8* xp = i8any_ptr (x); i8* rp; r = m_i8arrv (&rp,wsum); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); } break; }
|
||||
case el_i16: { i16* xp = i16any_ptr(x); i16* rp; r = m_i16arrv(&rp,wsum); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); } break; }
|
||||
#endif
|
||||
|
||||
case el_i32: { i32* xp = i32any_ptr(x); i32* rp; r = m_i32arrv(&rp,wsum); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); } break; }
|
||||
case el_f64: { f64* xp = f64any_ptr(x); f64* rp; r = m_f64arrv(&rp,wsum); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); } break; }
|
||||
case el_c8: { u8* xp = c8any_ptr (x); u8* rp; r = m_c8arrv (&rp,wsum); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); } break; }
|
||||
|
||||
@ -757,7 +757,7 @@ void g_p(B x) { print(x); putchar(10); fflush(stdout); }
|
||||
void g_i(B x) { B r = info_c2(x, m_f64(1), inc(x)); print(r); dec(r); putchar(10); fflush(stdout); }
|
||||
void g_pv(void* x) { print(tag(x,OBJ_TAG)); putchar(10); fflush(stdout); }
|
||||
void g_iv(void* x) { B xo = tag(x, OBJ_TAG); B r = info_c2(xo, m_f64(1), inc(xo)); print(r); dec(r); putchar(10); fflush(stdout); }
|
||||
void g_pst() { vm_pstLive(); }
|
||||
void g_pst(void) { vm_pstLive(); }
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef OBJ_COUNTER
|
||||
|
||||
49
src/singeli/src/slash.singeli
Normal file
49
src/singeli/src/slash.singeli
Normal file
@ -0,0 +1,49 @@
|
||||
include './base'
|
||||
|
||||
def pdep{x:u64, m:u64} = emit{u64, '_pdep_u64', x, m}
|
||||
def pdep{x:u32, m:u32} = emit{u32, '_pdep_u32', x, m}
|
||||
def pext{x:u64, m:u64} = emit{u64, '_pext_u64', x, m}
|
||||
def pext{x:u32, m:u32} = emit{u32, '_pext_u32', x, m}
|
||||
def popc{x:T & isint{T} & width{T}==64} = emit{u8, '__builtin_popcountll', x}
|
||||
def popc{x:T & isint{T} & width{T}<=32} = emit{u8, '__builtin_popcount', x}
|
||||
|
||||
def compi{r, w, x, m, e} = {
|
||||
pc:= popc{w}
|
||||
store{reinterpret{*u64, r}, 0, pext{x, pdep{promote{u64, w}, cast{u64,m}}*e}}
|
||||
r+= pc
|
||||
}
|
||||
|
||||
comp8(w:*u64, x:*i8, r:*i8, l:u64) : void = {
|
||||
@for(w in reinterpret{*u8,w}, x in reinterpret{*u64,x} over i to cdiv{l,8}) {
|
||||
compi{r, w, x, 0x0101010101010101, 255}
|
||||
}
|
||||
}
|
||||
'comp8'=comp8
|
||||
|
||||
# comp16(w:*u64, x:*i16, r:*i16, l:u64) : void = {
|
||||
# xv:= reinterpret{*u64, x}
|
||||
# @for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {
|
||||
# def step{w} = {
|
||||
# # compi{r, w, load{xv,0}, 0x0001000100010001, 0xffff}
|
||||
# # xv+= 1
|
||||
# }
|
||||
# step{w&15}
|
||||
# step{w>>4}
|
||||
# }
|
||||
# }
|
||||
# 'comp16'=comp16
|
||||
|
||||
comp16(w:*u64, x:*i16, r:*i16, l:u64) : void = {
|
||||
xv:= reinterpret{*u64, x}
|
||||
@for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {
|
||||
def step{w} = {
|
||||
pc:= popc{w}
|
||||
store{reinterpret{*u64,r}, 0, pext{load{xv,0}, load{emit{*u64,'','c16lut'}, w}}}
|
||||
r+= pc
|
||||
xv+= 1
|
||||
}
|
||||
step{w&15}
|
||||
step{w>>4}
|
||||
}
|
||||
}
|
||||
'comp16'=comp16
|
||||
Loading…
Reference in New Issue
Block a user