andAllZero → and_bit_none
This commit is contained in:
parent
10ec04a76e
commit
490285f1ca
@ -131,7 +131,7 @@ Some may also support one scalar argument or arguments with different widths.
|
||||
- `shr{U, a:V, n}` - shift vector elements within blocks of `U`
|
||||
- `unord{a:VF, b:VF} : mt{VI}` - `(a==NaN) | (b==NaN)`
|
||||
<!-- -->
|
||||
- `andAllZero{a:VI, b:VI} : u1` - whether `a&b` is all zeroes
|
||||
- `and_bit_none{a:VI, b:VI} : u1` - `~any_bit{a & b}`
|
||||
|
||||
## Structural operations
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ def shufInd{a:T, b:T=[8]E, {...is} if width{E}==32 and length{is}==8 and ({l,h}
|
||||
def shufInd{a:T, b:T=[4]E, {...is} if width{E}==64 and length{is}==4} = T~~shufInd{re_el{u32,a}, re_el{u32,b}, merge{...each{{i} => tup{i*2, i*2+1}, is}}}
|
||||
|
||||
# mask stuff
|
||||
def andAllZero{x:T, y:T if w256i{T}} = emit{u1, '_mm256_testz_si256', x, y}
|
||||
def and_bit_none{x:T, y:T if w256i{T}} = emit{u1, '_mm256_testz_si256', x, y}
|
||||
|
||||
def top_to_int{x:T if w256{T, 32}} = emit{u8, '_mm256_movemask_ps', v2f{x}}
|
||||
def top_to_int{x:T if w256{T, 64}} = emit{u8, '_mm256_movemask_pd', v2d{x}}
|
||||
|
||||
@ -171,7 +171,7 @@ def lvec = match { {[n]T, n, (width{T})} => 1; {T, n, w} => 0 }
|
||||
|
||||
# base cases
|
||||
def {
|
||||
absu,andAllZero,andnz,b_getBatch,blend,blend_units,clmul,cvt,extract,fold_addw,half,
|
||||
absu,and_bit_none,andnz,b_getBatch,blend,blend_units,clmul,cvt,extract,fold_addw,half,
|
||||
all_bit,any_bit,blend_bit,
|
||||
all_hom,any_hom,blend_hom,hom_to_int,store_masked_hom,store_blended_hom,
|
||||
all_top,any_top,blend_top,top_to_int,store_masked_top,store_blended_top,
|
||||
|
||||
@ -41,7 +41,7 @@ def arithChk2{F=(__mul), M, w:T=[_](i8), x:T if hasarch{'X86_64'}} = {
|
||||
} else { # unmasked check; can do check in a simpler way
|
||||
def bad = each{{v} => ty_s{v ^ (v>>15)}, rp}
|
||||
def RU = re_el{u16,T}
|
||||
tup{packQ{rp}, tup{'~andAllZero', RU~~tree_fold{|, bad}, RU**0xff80}}
|
||||
tup{packQ{rp}, tup{'and_some', RU~~tree_fold{|, bad}, RU**0xff80}}
|
||||
}
|
||||
}
|
||||
def arithChk2{F=(__mul), M, w:T=[_](i16), x:T if hasarch{'X86_64'}} = {
|
||||
@ -102,13 +102,13 @@ def runner{u, R, F} = {
|
||||
run
|
||||
}
|
||||
|
||||
# any_hom, any_top already give masked vals; anyne doesn't, and ~andAllZero assumes no masking
|
||||
# any_hom, any_top already give masked vals; anyne doesn't, and and_some assumes no masking
|
||||
def runChecks_any{F, vals} = { F{tree_fold{|, each{select{.,1}, vals}}} }
|
||||
def runChecks{'any_hom', vals, M} = runChecks_any{any_hom, vals}
|
||||
def runChecks{'any_top', vals, M} = runChecks_any{any_top, vals}
|
||||
def runChecks{'none', vals, M} = 0
|
||||
def runChecks{'~andAllZero', vals, M if ~M{0}} = ~tree_fold{&, each{andAllZero, ...slice{flip{vals}, 1}}}
|
||||
def runChecks{'anyne', vals, M} = {
|
||||
def runChecks{'any_hom', vals, M} = runChecks_any{any_hom, vals}
|
||||
def runChecks{'any_top', vals, M} = runChecks_any{any_top, vals}
|
||||
def runChecks{'none', vals, M} = 0
|
||||
def runChecks{'and_some', vals, M if ~M{0}} = ~tree_fold{&, each{and_bit_none, ...slice{flip{vals}, 1}}}
|
||||
def runChecks{'anyne', vals, M} = {
|
||||
def i{vals} = {
|
||||
def {_,xs,ys} = flip{vals}
|
||||
assert{M{0} == 0}
|
||||
|
||||
@ -47,7 +47,7 @@ fn equal{W, X}(w:*void, x:*void, l:u64, d:u64) : u1 = {
|
||||
# TODO compare with doing the comparison in vector registers
|
||||
badBits:= T ** ~(X~~1)
|
||||
@maskedLoop{bulk}(cw in tup{'b',w}, x in *T~~x, M in 'm' over i to l) {
|
||||
if (~andAllZero{M{x}, badBits}) return{0}
|
||||
if (~and_bit_none{M{x}, badBits}) return{0}
|
||||
if (anyne{promote{u64,mask{sh{x}}}, promote{u64,cw}, M}) return{0}
|
||||
}
|
||||
1
|
||||
|
||||
@ -28,9 +28,9 @@ def anynePositive{x:T, y:T, M if M{0}==1 and isvec{T}} = {
|
||||
}
|
||||
|
||||
def maskNone{x} = x
|
||||
def maskNone{x, 'all bits zeroes'} = andAllZero{x, x}
|
||||
def maskNone{x, 'all bits zeroes'} = and_bit_none{x, x}
|
||||
def maskAfter{n} = {
|
||||
def mask{x:X, 'all bits zeroes'} = andAllZero{x, X~~maskOfBit{X,n}}
|
||||
def mask{x:X, 'all bits zeroes'} = and_bit_none{x, X~~maskOfBit{X,n}}
|
||||
def mask{X, 'to sign bits'} = maskOf{X,n}
|
||||
def mask{X, 'to homogeneous bits'} = maskOf{X,n}
|
||||
def mask{'count'} = n
|
||||
|
||||
@ -167,7 +167,7 @@ def hom_to_int{a:V,b:V=[k]E if nvecu{V} and k*2<=width{E}} = {
|
||||
truncBits{k*2, fold_add{shrm{a,width{E}-k,b} & make{V, (1<<iota{k}) | (1<<(iota{k}+k))}}}
|
||||
}
|
||||
|
||||
def andAllZero{x:T, y:T if nveci{T}} = ~any_bit{x&y}
|
||||
def and_bit_none{x:T, y:T if nveci{T}} = ~any_bit{x&y}
|
||||
|
||||
def hom_to_int_ext{a:T=[k]E if E!=u64} = {
|
||||
def h = width{E}/2
|
||||
|
||||
@ -87,7 +87,7 @@ fn squeeze{vw, X, CHR, B}(x0:*void, len:ux) : u32 = {
|
||||
if (any_nonC32{M, ...xs}) return{3}
|
||||
} else {
|
||||
def bad = if (hasarch{'AARCH64'}) any_bit{if (length{xs}==2) pack{...xs,1} else pack{orx,orx,1}}
|
||||
else ~andAllZero{orx, ~XV**maxvalue{w_h{X}}}
|
||||
else ~and_bit_none{orx, ~XV**maxvalue{w_h{X}}}
|
||||
if (bad) return{lb{width{X}}-3}
|
||||
}
|
||||
mt|= orx
|
||||
@ -115,7 +115,7 @@ fn squeeze{vw, X, CHR, B}(x0:*void, len:ux) : u32 = {
|
||||
acc{}
|
||||
} else if (X==i8) {
|
||||
@muLoop{bulk, 2}(xs in xb, M in 'm' over len) {
|
||||
if (~andAllZero{M{tree_fold{|, xs}}, XV ** -2}) return{2}
|
||||
if (~and_bit_none{M{tree_fold{|, xs}}, XV ** -2}) return{2}
|
||||
}
|
||||
0
|
||||
} else if (X==f64) {
|
||||
|
||||
@ -4,7 +4,7 @@ def sel{L=[_]E, x:T, i:I if hasarch{'SSSE3'} and lvec{L,16,8} and w128{T} and w1
|
||||
|
||||
### SSE4.1 ###
|
||||
def packs{a:T,b:T if hasarch{'SSE4.1'} and T==[4]u32} = emit{[ 8]u16, '_mm_packus_epi32', a, b}
|
||||
def andAllZero{x:T, y:T if hasarch{'SSE4.1'} and w128i{T}} = emit{u1, '_mm_testz_si128', x, y}
|
||||
def and_bit_none{x:T, y:T if hasarch{'SSE4.1'} and w128i{T}} = emit{u1, '_mm_testz_si128', x, y}
|
||||
|
||||
# conversion
|
||||
def widen{T==[8]u16, x:X==[16]u8 if hasarch{'SSE4.1'}} = emit{T, '_mm_cvtepu8_epi16', x}; def widen{T==[8]i16, x:X if hasarch{'SSE4.1'} and X==[16]i8} = emit{T, '_mm_cvtepi8_epi16', x}
|
||||
@ -19,6 +19,6 @@ def narrow{(i8 ), x:X if hasarch{'SSE4.1'} and w128i{X,32}} = sel{[16]u8, [16]i8
|
||||
def narrow{(i16), x:X if hasarch{'SSE4.1'} and w128i{X,32}} = sel{[16]u8, [8]i16~~x, make{[16]i8, 0,1,4,5, 8,9,12,13, 0,0,0,0, 0,0,0,0}}
|
||||
|
||||
# mask stuff
|
||||
def andAllZero{x:T, y:T if hasarch{'SSE4.1'} and w128i{T}} = emit{u1, '_mm_testz_si128', x, y}
|
||||
def and_bit_none{x:T, y:T if hasarch{'SSE4.1'} and w128i{T}} = emit{u1, '_mm_testz_si128', x, y}
|
||||
def blend_top{f:T, t:T, m:M if hasarch{'SSE4.1'} and w128i{T} and w128i{M,32}} = T ~~ blend_top{v2f{f}, v2f{t}, m}
|
||||
def blend_top{f:T, t:T, m:M if hasarch{'SSE4.1'} and w128i{T} and w128i{M,64}} = T ~~ blend_top{v2d{f}, v2d{t}, m}
|
||||
|
||||
@ -40,7 +40,7 @@ def rsqrtE{a:([4]f32)} = emit{[4]f32, '_mm_rsqrt_ps', a}
|
||||
def rcpE{a:([4]f32)} = emit{[4]f32, '_mm_rcp_ps', a}
|
||||
|
||||
# mask stuff
|
||||
def andAllZero{x:T, y:T if w128i{T}} = all_hom{(x & y) == T**0}
|
||||
def and_bit_none{x:T, y:T if w128i{T}} = all_hom{(x & y) == T**0}
|
||||
|
||||
def top_to_int{x:T if w128{T, 8}} = emit{u16, '_mm_movemask_epi8', x}
|
||||
def top_to_int{x:T if w128{T, 16}} = top_to_int{packs{[8]i16~~x, [8]i16**0}}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user