diff --git a/src/singeli/src/avx2.singeli b/src/singeli/src/avx2.singeli index 4e04e937..ab8ec284 100644 --- a/src/singeli/src/avx2.singeli +++ b/src/singeli/src/avx2.singeli @@ -7,15 +7,7 @@ def packQ{a:T,b:T==[ 8]u32} = emit{[16]u16, '_mm256_packus_epi32', a, b} def packQQ{a:T,b:T==[4]i64} = vec_shuffle{[4]i32, a, 0,2,1,1} | vec_shuffle{[4]i32, b, 1,1,0,2} def packQQ{{a, b}} = packQQ{a, b} - -# arith -def mulh {a:T,b:T==[16]i16} = emit{T, '_mm256_mulhi_epi16', a, b} -def mulh {a:T,b:T==[16]u16} = emit{T, '_mm256_mulhi_epu16', a, b} -def mul32{a:T,b:T==[ 4]i64} = emit{T, '_mm256_mul_epi32', a, b} # reads only low 32 bits of arguments -def mul32{a:T,b:T==[ 4]u64} = emit{T, '_mm256_mul_epu32', a, b} # reads only low 32 bits of arguments - # structural operations - def sel{L, x:T, i:I if w256{T} and lvec{L,8,32} and w256{I,32}} = vec_shuffle{L, x, i} def sel{L, x:T, i:I if w256{T} and lvec{L,16,8} and w256{I, 8}} = vec_shuffle{L, x, i} diff --git a/src/singeli/src/sse2.singeli b/src/singeli/src/sse2.singeli index a3ad9dc6..7fc99472 100644 --- a/src/singeli/src/sse2.singeli +++ b/src/singeli/src/sse2.singeli @@ -10,9 +10,6 @@ def store{ptr:*E, x:V=[_]E, vl if w128{V} and vl*width{E}==64} = emit{void, '_mm # integer arith -def mulh{a:T,b:T if [8]i16==T} = emit{T, '_mm_mulhi_epi16', a, b} -def mulh{a:T,b:T if [8]u16==T} = emit{T, '_mm_mulhi_epu16', a, b} -def mul32{a:T,b:T if [2]u64==T} = emit{T, '_mm_mul_epu32', a, b} # reads only low 32 bits of arguments def __mul{a:T,b:T if [4]i32==T} = { def mu{x, y} = [4]i32 ~~ mul32{[2]u64~~x, [2]u64~~y} def sw{n, ...vs} = each{{c} => vec_shuffle{i32, c, n}, vs} diff --git a/src/singeli/src/x86.singeli b/src/singeli/src/x86.singeli index 34356e24..ca6dd262 100644 --- a/src/singeli/src/x86.singeli +++ b/src/singeli/src/x86.singeli @@ -14,6 +14,15 @@ local def has512 = x86_has512 def x86_has512e{V=[_]E if width{E}>=32} = has512{V} def x86_has512e{V=[_]E if width{E}<=16} = has512{V, 'BW'} def x86_has512e{V=[_]E, post} = x86_has512e{V} and has512{V, post} +local def hase{V=[_]E} = hase{V, 'SSE2'} +local def hase{V=[_]E, min_sse} = hase{V, min_sse, if (isint{E}) 'AVX2' else 'AVX'} +local def hase{V=[_]E, min_sse, min_avx} = hase{V, min_sse, min_avx, {} => x86_has512e{V}} +local def hase{V=[_]E, min_sse, min_avx, avx512_check} = match (width{V}) { + {128} => hasarch{min_sse} + {256} => hasarch{min_avx} + {512} => avx512_check{} + {_} => 0 +} def fmtwidth{T} = fmtnat{width{T}} local def has_bw{V} = hasarch{match (width{V}) { {128}=>'SSE2'; {256}=>'AVX2'; {512}=>'AVX512BW' }} @@ -78,6 +87,12 @@ def unord{a:V, b:V if w128f{V}} = ty_u{emit{V, intrin_t{V, 'cmpunord'}, a, b}} # int stuff def any_bit{x:[_]_} = ~and_bit_none{x, x} +def mulh{a:V, b:V=[_]E if veci{V,16} and hase{V}} = emit{V, intrin_t{V, 'mulhi'}, a, b} + +# multiplies that only read low 32 bits of arguments +def mul32{a:V, b:V=[_](u64) if hase{V }} = emit{V, intrin_t{el_s{V}, 'mul'}, a, b} +def mul32{a:V, b:V=[_](i64) if hase{V, 'SSE4.1'}} = emit{V, intrin_t{el_s{V}, 'mul'}, a, b} + def absdiff_sum{8, a:V=[k](u8), b:V if has_bw{V}} = { emit{[k/8]u64, intrin{V, 'sad_epu8'}, a, b} }