uCBQN/src/singeli/src/slash.singeli
2022-04-02 17:19:20 +03:00

51 lines
1.5 KiB
Plaintext

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 comp8{w:*u64, X, r:*i8, l:u64} = {
@for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {
pc:= popc{w}
store{reinterpret{*u64,r}, 0, pext{promote{u64,X{}}, pdep{promote{u64, w}, cast{u64,0x0101010101010101}}*255}}
r+= pc
}
}
def tab{n,l} = {
def m=n-1; def t=tab{m,l}
def k = (1<<l - 1) << (m*l)
merge{t, k+t}
}
def tab{n==0,l} = tup{0}
c16lut:*u64 = tab{4,16}
def comp16{w:*u64, X, r:*i16, l:u64} = {
@for(w in reinterpret{*u8,w} over i to cdiv{l,8}) {
def step{w} = {
pc:= popc{w}
store{reinterpret{*u64,r}, 0, pext{promote{u64,X{}}, load{c16lut, w}}}
r+= pc
}
step{w&15}
step{w>>4}
}
}
slash2{F, T}(w:*u64, x:*T, r:*T, l:u64) : void = {
xv:= reinterpret{*u64, x}
F{w, {} => {c:=load{xv,0}; xv+=1; c}, r, l}
}
slash1{F, T, iota, add}(w:*u64, r:*T, l:u64) : void = {
x:u64 = iota
F{w, {} => {c:=x; x+= add; c}, r, l}
}
'bmipopc_2slash8' = slash2{comp8, i8}
'bmipopc_2slash16' = slash2{comp16, i16}
'bmipopc_1slash8' = slash1{comp8, i8, 0x0706050403020100, 0x0808080808080808}
'bmipopc_1slash16' = slash1{comp16, i16, 0x0003000200010000, 0x0004000400040004}