move neon.singeli type checks to w64/w128

This commit is contained in:
dzaima 2023-04-01 22:51:27 +03:00
parent a62c21733e
commit 9826201343
2 changed files with 35 additions and 41 deletions

View File

@ -53,14 +53,12 @@ def anyInt{x & knum{x}} = (x>>0) == x
def anyInt{x & isreg{x}|isconst{x}} = isint{x}
# vector width/type checks
def w128{T} = 0
def w128{T & isvec{T}} = width{T}==128
def w128{T,w} = 0
def w128{T,w & w128{T}} = elwidth{T}==w
def w256{T} = 0
def w256{T & isvec{T}} = width{T}==256
def w256{T,w} = 0
def w256{T,w & w256{T}} = elwidth{T}==w
def w64 {T} = 0; def w64 {T & isvec{T}} = width{T}==64
def w128{T} = 0; def w128{T & isvec{T}} = width{T}==128
def w256{T} = 0; def w256{T & isvec{T}} = width{T}==256
def w64 {T,w} = 0; def w64 {T,w & w64{T}} = elwidth{T}==w
def w128{T,w} = 0; def w128{T,w & w128{T}} = elwidth{T}==w
def w256{T,w} = 0; def w256{T,w & w256{T}} = elwidth{T}==w
# width+type checks
def genchk{B, F} = {
@ -71,14 +69,14 @@ def genchk{B, F} = {
def r{T & ~isvec{T}} = 0
r
}
def w128i = genchk{w128, {T} => isint{T}}
def w128s = genchk{w128, {T} => issigned{T}}
def w128u = genchk{w128, {T} => isunsigned{T}}
def w128f = genchk{w128, {T} => isfloat{T}}
def w256i = genchk{w256, {T} => isint{T}}
def w256s = genchk{w256, {T} => issigned{T}}
def w256u = genchk{w256, {T} => isunsigned{T}}
def w256f = genchk{w256, {T} => isfloat{T}}
def w256i = genchk{w256, {T} => isint{T}}; def w128i = genchk{w128, {T} => isint{T}}; def w64i = genchk{w64, {T} => isint{T}}
def w256s = genchk{w256, {T} => issigned{T}}; def w128s = genchk{w128, {T} => issigned{T}}; def w64s = genchk{w64, {T} => issigned{T}}
def w256u = genchk{w256, {T} => isunsigned{T}}; def w128u = genchk{w128, {T} => isunsigned{T}}; def w64u = genchk{w64, {T} => isunsigned{T}}
def w256f = genchk{w256, {T} => isfloat{T}}; def w128f = genchk{w128, {T} => isfloat{T}}; def w64f = genchk{w64, {T} => isfloat{T}}
def trunc{T, x:U & isint{T} & isint{U} & T<=U} = emit{T, '', x}
def trunc{T, x & knum{x}} = cast{T, x}

View File

@ -7,10 +7,6 @@ def nvecs = genchk{nvec, {T} => issigned{T}}
def nvecu = genchk{nvec, {T} => isunsigned{T}}
def nvecf = genchk{nvec, {T} => isfloat{T}}
def n128{T} = 0
def n128{T&isvec{T}} = width{T}==128
def n64{T} = 0
def n64{T&isvec{T}} = width{T}==64
def reinterpret{T, v & match{'pointer',typekind{T}} & ktup{v}} = { tmp:T=v }
@ -20,8 +16,8 @@ def nty{T==u32} = 'u32'; def nty{T==i32} = 's32'
def nty{T==u64} = 'u64'; def nty{T==i64} = 's64'
def nty{T==f32} = 'f32'; def nty{T==f64} = 'f64'
def nty{T & isvec{T}} = nty{eltype{T}}
def ntyp{S, ...S2, T & n128{T}} = merge{S, 'q', ...S2, '_', nty{T}}
def ntyp{S, ...S2, T & n64{T}} = merge{S, ...S2, '_', nty{T}}
def ntyp{S, ...S2, T & w128{T}} = merge{S, 'q', ...S2, '_', nty{T}}
def ntyp{S, ...S2, T & w64{T}} = merge{S, ...S2, '_', nty{T}}
def ntyp0{S, T} = merge{S, '_', nty{T}}
def load{a:T, n & nvec{eltype{T}}} = emit{eltype{T}, ntyp{'vld1', eltype{T}}, *eltype{eltype{T}} ~~ (a+n)}
@ -29,9 +25,9 @@ def store{a:*V, n, v:V & nvec{V}} = emit{void, ntyp{'vst1', V}, *eltype{V} ~~ (a
def __adds{a:T,b:T & nveci{T}} = emit{T, ntyp{'vqadd', T}, a, b}
def __subs{a:T,b:T & nveci{T}} = emit{T, ntyp{'vqsub', T}, a, b}
def mul1{a:T,b:T & n64{T} & nveci{T}} = emit{ty_dbl{v_dbl{T}}, ntyp{'vmull', T}, a, b}
def mul2{a:T,b:T & n128{T} & nveci{T}} = emit{ty_dbl{T}, ntyp0{'vmull_high', T}, a, b}
def mul12{a:T,b:T & n128{T}} = tup{mul1{half{a,0}, half{b,0}}, mul2{a,b}}
def mul1{a:T,b:T & w64i{T}} = emit{ty_dbl{v_dbl{T}}, ntyp{'vmull', T}, a, b}
def mul2{a:T,b:T & w128i{T}} = emit{ty_dbl{T}, ntyp0{'vmull_high', T}, a, b}
def mul12{a:T,b:T & w128{T}} = tup{mul1{half{a,0}, half{b,0}}, mul2{a,b}}
def __add{a:T,b:T & nvec {T}} = emit{T, ntyp{'vadd', T}, a, b}
def __sub{a:T,b:T & nvec {T}} = emit{T, ntyp{'vsub', T}, a, b}
@ -45,11 +41,11 @@ def ornot{a:T,b:T & nveci{T}} = emit{T, ntyp{'vorn', T}, a, b}
def andnz{a:T,b:T & nveci{T}} = emit{T, ntyp{'vtst', T}, a, b}
def min{a:T,b:T & nvec{T}} = emit{T, ntyp{'vmin', T}, a, b}
def max{a:T,b:T & nvec{T}} = emit{T, ntyp{'vmax', T}, a, b}
def __shl{a:T,b:S & nveci{T} & nveci{S} & elwidth{T}==elwidth{S}} = emit{T, ntyp{'vshl', T}, a, ty_s{b}}
def __shl{a:T,b:S & nveci{T} & nveci{S,elwidth{T}}} = emit{T, ntyp{'vshl', T}, a, ty_s{b}}
def __shl{a:T,b & nveci{T} & knum{b} & b>0 & b<elwidth{T}} = emit{T, ntyp{'vshl', '_n', T}, a, b}; def __shl{a:T,b==0 & nveci{T}} = a
def __shr{a:T,b & nveci{T} & knum{b} & b>0 & b<elwidth{T}} = emit{T, ntyp{'vshr', '_n', T}, a, b}; def __shr{a:T,b==0 & nveci{T}} = a
def bitBlend{f:T, t:T, m:M & nvec{T} & nvecu{M} & width{T}==width{M} & elwidth{T}==elwidth{M}} = emit{T, ntyp{'vbsl', T}, m, t, f}
def bitBlend{f:T, t:T, m:M & nvec{T} & nvecu{M,elwidth{T}} & width{T}==width{M}} = emit{T, ntyp{'vbsl', T}, m, t, f}
def homBlend{f:T, t:T, m:M & nvec{M}} = bitBlend{f, t, m}
def __neg{a:T & (nvecs{T}|nvecf{T})} = emit{T, ntyp{'vneg', T}, a}
@ -93,9 +89,9 @@ def loadLow{ptr:P, w & w==elwidth{P}} = load{ptr}
def undefPromote{T, x:X & n64{X} & n128{T} & eltype{T}==eltype{X}} = emit{T, ntyp{'vcombine', X}, x, x} # arm_neon.h doesn't actually provide a way to do this in a 0-instruction way. ¯\_(ツ)_/¯
def half{x:T, n==0 & n128{T}} = emit{v_half{T}, ntyp0{'vget_low', T}, x}
def half{x:T, n==1 & n128{T}} = emit{v_half{T}, ntyp0{'vget_high', T}, x}
def undefPromote{T, x:X & w64{X} & w128{T} & eltype{T}==eltype{X}} = emit{T, ntyp{'vcombine', X}, x, x} # arm_neon.h doesn't actually provide a way to do this in a 0-instruction way. ¯\_(ツ)_/¯
def half{x:T, n==0 & w128{T}} = emit{v_half{T}, ntyp0{'vget_low', T}, x}
def half{x:T, n==1 & w128{T}} = emit{v_half{T}, ntyp0{'vget_high', T}, x}
def extract{x:T,n & nvec{T} & knum{n}} = emit{eltype{T}, ntyp{'vget', '_lane', T}, x, n}
def packLo{x:T, y:T & nvec{T}} = { def H=ty_half{T}; emit{H, ntyp{'vuzp1', H}, H~~x, H~~y} }
@ -106,7 +102,7 @@ def packHi{x} = packHi{tupsel{0,x}, tupsel{1,x}}
def trn1{x:T, y:T & nvec{T}} = emit{T, ntyp{'vtrn1', T}, x, y}
def trn2{x:T, y:T & nvec{T}} = emit{T, ntyp{'vtrn2', T}, x, y}
def sel{L, x:T, i:I & lvec{L,16,8} & n128{T} & nvec{I, 8}} = to_el{eltype{T}, emit{I, ntyp{'vqtbl1',I}, to_el{eltype{I},x}, i}}
def sel{L, x:T, i:I & lvec{L,16,8} & w128{T} & nvec{I, 8}} = to_el{eltype{T}, emit{I, ntyp{'vqtbl1',I}, to_el{eltype{I},x}, i}}
@ -116,21 +112,21 @@ def cvt{T==f64, x:X & nveci{X,64}} = emit{[vcount{X}]T, ntyp{'vcvt', '_f64', X},
def cvt{T==i64, x:X & nvecf{X,64}} = emit{[vcount{X}]T, ntyp{'vcvt', '_s64', X}, x}
def cvt{T==u64, x:X & nvecf{X,64}} = emit{[vcount{X}]T, ntyp{'vcvt', '_u64', X}, x}
def widen{T, x:X & n64{X} & eqqi{eltype{T},eltype{X}} & elwidth{T}==elwidth{X}*2} = emit{T, ntyp{'vmovl', X}, x}
def widen{T, x:X & n64{X} & eqqi{eltype{T},eltype{X}} & elwidth{T}> elwidth{X}*2} = widen{T, widen{ty_half{T}, x}}
def widen{T, x:X & n64{X} & isfloat{eltype{T}}!=isfloat{eltype{X}} & elwidth{T}>elwidth{X}} = cvt{eltype{T}, widen{[vcount{T}](to_w{eltype{X},elwidth{T}}), x}}
def widen{T, x:X & n128{X} & vcount{X}>vcount{T}} = widen{T, half{x,0}}
def widen{T, x:X & w64{X} & eqqi{eltype{T},eltype{X}} & elwidth{T}==elwidth{X}*2} = emit{T, ntyp{'vmovl', X}, x}
def widen{T, x:X & w64{X} & eqqi{eltype{T},eltype{X}} & elwidth{T}> elwidth{X}*2} = widen{T, widen{ty_half{T}, x}}
def widen{T, x:X & w64{X} & isfloat{eltype{T}}!=isfloat{eltype{X}} & elwidth{T}>elwidth{X}} = cvt{eltype{T}, widen{[vcount{T}](to_w{eltype{X},elwidth{T}}), x}}
def widen{T, x:X & w128{X} & vcount{X}>vcount{T}} = widen{T, half{x,0}}
def narrow{T, x:X & n128{X} & eqqi{T,eltype{X}} & width{T}*2< elwidth{X}} = narrow{T, undefPromote{ty_half{X}, narrow{ty_half{eltype{X}}, x}}}
def narrow{T, x:X & n128{X} & eqqi{T,eltype{X}} & width{T}*2==elwidth{X}} = emit{ty_half{v_half{X}}, ntyp0{'vmovn', X}, x}
def narrow{T, x:X & n128{X} & isfloat{T}!=isfloat{eltype{X}} & width{T}<elwidth{X}} = narrow{T, cvt{to_w{T, elwidth{X}}, x}}
def narrow{T, x:X & w128{X} & eqqi{T,eltype{X}} & width{T}*2< elwidth{X}} = narrow{T, undefPromote{ty_half{X}, narrow{ty_half{eltype{X}}, x}}}
def narrow{T, x:X & w128{X} & eqqi{T,eltype{X}} & width{T}*2==elwidth{X}} = emit{ty_half{v_half{X}}, ntyp0{'vmovn', X}, x}
def narrow{T, x:X & w128{X} & isfloat{T}!=isfloat{eltype{X}} & width{T}<elwidth{X}} = narrow{T, cvt{to_w{T, elwidth{X}}, x}}
def narrowUpper{lowRes:L, x:X & n64{L} & n128{X} & isint{eltype{X}} & ty_dbl{v_dbl{L}}==X} = emit{[vcount{L}*2](eltype{L}), ntyp0{'vmovn_high', X}, lowRes, x}
def narrowUpper{lowRes:L, x:X & w64i{L} & w128{X} & ty_dbl{v_dbl{L}}==X} = emit{[vcount{L}*2](eltype{L}), ntyp0{'vmovn_high', X}, lowRes, x}
def narrowPair{a:T, b:T} = narrowUpper{narrow{ty_half{eltype{T}}, a}, b}
def narrowPair{a:T, b:T & isint{eltype{T}}} = packLo{a, b}
def widenUpper{x:T & n128{T} & isint{eltype{T}}} = emit{ty_dbl{T}, ntyp0{'vmovl_high', T}, x}
def widen{x:T & n128{T}} = tup{widen{ty_dbl{T}, x}, widenUpper{x}}
def widenUpper{x:T & w128i{T}} = emit{ty_dbl{T}, ntyp0{'vmovl_high', T}, x}
def widen{x:T & w128{T}} = tup{widen{ty_dbl{T}, x}, widenUpper{x}}
def bitAny{x:T} = fold_max{to_el{u32, x}}!=0
def bitAll{x:T} = fold_min{to_el{u32, x}}==0xffff_ffff