From 6fac426f90678014a7cadd2492a4322092152d3c Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 15 Dec 2022 21:57:34 +0200 Subject: [PATCH] add v_dbl & v_half, NEON half{x,n} --- src/singeli/src/avx.singeli | 6 +++--- src/singeli/src/base.singeli | 8 ++++++-- src/singeli/src/neon.singeli | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/singeli/src/avx.singeli b/src/singeli/src/avx.singeli index 00e8a9ec..4abb12a0 100644 --- a/src/singeli/src/avx.singeli +++ b/src/singeli/src/avx.singeli @@ -96,9 +96,9 @@ def floor{a:[4]f64} = emit{[4]f64, '_mm256_floor_pd', a} def ceil{a:[4]f64} = emit{[4]f64, '_mm256_ceil_pd', a} # conversion -def half{x:T, i & w256{T} & knum{i}} = [vcount{T}/2](eltype{T}) ~~ emit{[8]i16, '_mm256_extracti128_si256', v2i{x}, i} -def half{x:T, i==0 & w256{T}} = [vcount{T}/2](eltype{T}) ~~ emit{[8]i16, '_mm256_castsi256_si128', v2i{x}} -def pair{a:T,b:T & width{T}==128} = [vcount{T}*2](eltype{T}) ~~ emit{[8]i32, '_mm256_setr_m128i', a, b} +def half{x:T, i & w256{T} & knum{i}} = v_half{T} ~~ emit{[8]i16, '_mm256_extracti128_si256', v2i{x}, i} +def half{x:T, i==0 & w256{T}} = v_half{T} ~~ emit{[8]i16, '_mm256_castsi256_si128', v2i{x}} +def pair{a:T,b:T & width{T}==128} = v_dbl{T} ~~ emit{[8]i32, '_mm256_setr_m128i', a, b} def pair{x} = pair{tupsel{0,x},tupsel{1,x}} def widen{T==[4]f64, x:X & X==[4]i32} = emit{T, '_mm256_cvtepi32_pd', x} diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index f790b731..e71e1fb4 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -78,14 +78,18 @@ def to_el{E, x:T} = to_el{E,T} ~~ x # change width of primitive type def to_w{T, w} = primtype{quality{T}, w} -# double (element) type width +# double/halve primitive or element type width def ty_dbl {T & isprim{T}} = to_w{T, width{T}*2} def ty_half{T & isprim{T}} = to_w{T, width{T}/2} def ty_dbl {T & isvec{T}} = to_el{ty_dbl {eltype{T}}, T} def ty_half{T & isvec{T}} = to_el{ty_half{eltype{T}}, T} +# double/halve vector count +def v_dbl {T & isvec{T}} = [vcount{T}*2](eltype{T}) +def v_half{T & isvec{T}} = [vcount{T}/2](eltype{T}) + # base vector utility definitions -def widen {T, x:X & T==X} = x +def widen{T, x:X & T==X} = x def narrow{T, x:X & T==eltype{X}} = x def unroll{vars,begin,end,block & knum{begin} & knum{end}} = { diff --git a/src/singeli/src/neon.singeli b/src/singeli/src/neon.singeli index 3aebff38..0479fcc0 100644 --- a/src/singeli/src/neon.singeli +++ b/src/singeli/src/neon.singeli @@ -67,6 +67,8 @@ def fold_addw{a:T & nvec{T}} = emit{ty_dbl{eltype{T}}, ntyp{'vaddlv', T}, a} def fold_min {a:T & nvec{T}} = emit{eltype{T}, ntyp{'vminv', T}, a} def fold_max {a:T & nvec{T}} = emit{eltype{T}, ntyp{'vmaxv', T}, a} +def half{x:T, n==0 & nvec{T} & width{T}==128} = emit{v_half{T}, ntyp{'vget', '_low', v_half{T}}, x} +def half{x:T, n==1 & nvec{T} & width{T}==128} = emit{v_half{T}, ntyp{'vget', '_high', v_half{T}}, x} def extract{x:T,n & nvec{T} & knum{n}} = emit{eltype{T}, ntyp{'vget', '_lane', T}, x, n} # TODO don't rely on regular stores being unaligned