diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index eb47fa78..ecdb3726 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -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} diff --git a/src/singeli/src/neon.singeli b/src/singeli/src/neon.singeli index 5ea4dfa5..810a84d4 100644 --- a/src/singeli/src/neon.singeli +++ b/src/singeli/src/neon.singeli @@ -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 & b0 & b 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}