diff --git a/src/singeli/src/avx.singeli b/src/singeli/src/avx.singeli index a7c81998..862f2970 100644 --- a/src/singeli/src/avx.singeli +++ b/src/singeli/src/avx.singeli @@ -1,20 +1,9 @@ -# compact casting for the annoying intrinsic type system -def v2i{x:T=[_]E if w256{T}} = if(isint{E}) x else [32]u8 ~~ x -def v2f{x:T if w256{T}} = [8]f32 ~~ x -def v2d{x:T if w256{T}} = [4]f64 ~~ x - def undef_promote{T=[_]E, x:X=[_]E if w128{X} and w256{T}} = T~~emit{[32]u8, '_mm256_castsi128_si256', v2i{x}} def zero_promote{T=[_]E, x:X=[_]E if w128{X} and w256{T}} = T~~emit{[32]u8, '_mm256_zextsi128_si256', v2i{x}} def load{V=[_]E, ptr:*E, vl if w256{V} and vl*width{E}<=128} = undef_promote{V, load{n_h{V}, ptr, vl}} def store{ptr:*E, x:V=[k]E, vl if w256{V} and vl*width{E}<=128} = store{ptr, half{x, 0}, vl} -# float comparison -local def f32cmpAVX{a,b,n} = [8]u32 ~~ emit{[8]f32, '_mm256_cmp_ps', a, b, n} -local def f64cmpAVX{a,b,n} = [4]u64 ~~ emit{[4]f64, '_mm256_cmp_pd', a, b, n} -def unord{a:T, b:T==[8]f32} = f32cmpAVX{a,b,3} -def unord{a:T, b:T==[4]f64} = f64cmpAVX{a,b,3} - # f32 arith def rsqrtE{a:T==[8]f32} = emit{T, '_mm256_rsqrt_ps', a} def rcpE{a:T==[8]f32} = emit{T, '_mm256_rcp_ps', a} diff --git a/src/singeli/src/sse2.singeli b/src/singeli/src/sse2.singeli index 6d6640c3..a3ad9dc6 100644 --- a/src/singeli/src/sse2.singeli +++ b/src/singeli/src/sse2.singeli @@ -1,9 +1,3 @@ -# compact casting for the annoying intrinsic type system -def v2i{x:V=[_]T if w128{V}} = if(isint{T}) x else [16]u8 ~~ x -def v2f{x:T if w128{T}} = [4]f32 ~~ x -def v2d{x:T if w128{T}} = [2]f64 ~~ x - - # load & store def load{V=[_]E, ptr:*E, vl if w128{V} and vl*width{E}==16} = V ~~ emit{[16]u8, '_mm_loadu_si16', ptr} def load{V=[_]E, ptr:*E, vl if w128{V} and vl*width{E}==32} = V ~~ emit{[16]u8, '_mm_loadu_si32', ptr} @@ -15,12 +9,6 @@ def store{ptr:*E, x:V=[_]E, vl if w128{V} and vl*width{E}==64} = emit{void, '_mm -# float comparison -def unord{a:T,b:T==[4]f32} = [4]u32~~emit{[4]f32, '_mm_cmpunord_ps', a, b} -def unord{a:T,b:T==[2]f64} = [2]u64~~emit{[2]f64, '_mm_cmpunord_pd', a, b} - - - # 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} diff --git a/src/singeli/src/x86.singeli b/src/singeli/src/x86.singeli index 7947f561..18e98808 100644 --- a/src/singeli/src/x86.singeli +++ b/src/singeli/src/x86.singeli @@ -1,18 +1,40 @@ include 'arch/iintrinsic/basic' include 'arch/iintrinsic/select' + +# compact casting for the annoying intrinsic type system +def v2i{x:T=[_]E} = if(isint{E}) x else re_el{u8, x} +def v2f{x:T=[_]_} = re_el{f32, x} +def v2d{x:T=[_]_} = re_el{f64, x} + include './sse2' include './sse' include './avx' include './avx2' include './avx512' -def any_bit{x:[_]_} = ~and_bit_none{x, x} local def has_bw{V} = hasarch{match (width{V}) { {128}=>'SSE2'; {256}=>'AVX2'; {512}=>'AVX512BW' }} local def intrin{V, ...rest} = merge{'_mm', if (width{V}==128) '' else fmtnat{width{V}}, '_', ...rest} +local def intrin_t{V=[_]E, ...rest} = intrin{V, ...rest, '_', match (E) { + {(f32)} => 'ps' + {(f64)} => 'pd' + {T} => merge{'ep', quality{T}, fmtnat{width{T}}} +}} + + + +# float stuff +local def avx_cmp{a:V, b:V, imm} = ty_u{emit{V, intrin_t{V, 'cmp'}, a, b, imm}} +def unord{a:V, b:V if w256f{V} and hasarch{'AVX'}} = avx_cmp{a,b,3} +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 absdiff_sum{8, a:V=[k](u8), b:V if has_bw{V}} = { emit{[k/8]u64, intrin{V, 'sad_epu8'}, a, b} } def mul_sum{2, a:V=[k](i16), b:V if has_bw{V}} = { emit{[k/2]i32, intrin{V, 'madd_epi16'}, a, b} -} \ No newline at end of file +}