@img/sharp-libvips-dev-wasm32 1.3.0-rc.1 → 1.3.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +23 -23
  2. package/include/aom/aom_codec.h +1 -1
  3. package/include/aom/aom_decoder.h +4 -0
  4. package/include/aom/aom_encoder.h +19 -8
  5. package/include/aom/aom_ext_ratectrl.h +664 -0
  6. package/include/aom/aom_image.h +93 -30
  7. package/include/aom/aom_tpl.h +99 -0
  8. package/include/aom/aomcx.h +89 -16
  9. package/include/aom/aomdx.h +12 -0
  10. package/include/expat.h +15 -3
  11. package/include/expat_config.h +6 -6
  12. package/include/expat_external.h +4 -4
  13. package/include/glib-2.0/gio/gdbusconnection.h +2 -8
  14. package/include/glib-2.0/gio/gfileattribute.h +1 -1
  15. package/include/glib-2.0/gio/gfileinfo.h +5 -0
  16. package/include/glib-2.0/gio/gicon.h +1 -1
  17. package/include/glib-2.0/gio/gio-autocleanups.h +0 -1
  18. package/include/glib-2.0/gio/gio-visibility.h +34 -0
  19. package/include/glib-2.0/gio/gio.h +2 -0
  20. package/include/glib-2.0/gio/gioenums.h +66 -44
  21. package/include/glib-2.0/gio/gioenumtypes.h +2 -0
  22. package/include/glib-2.0/gio/giptosmessage.h +46 -0
  23. package/include/glib-2.0/gio/gipv6tclassmessage.h +46 -0
  24. package/include/glib-2.0/gio/gresolver.h +1 -1
  25. package/include/glib-2.0/gio/gsettings.h +1 -1
  26. package/include/glib-2.0/gio/gsocketcontrolmessage.h +2 -0
  27. package/include/glib-2.0/glib/gatomic.h +26 -2
  28. package/include/glib-2.0/glib/gfileutils.h +2 -2
  29. package/include/glib-2.0/glib/ghook.h +3 -1
  30. package/include/glib-2.0/glib/giochannel.h +1 -1
  31. package/include/glib-2.0/glib/gkeyfile.h +1 -1
  32. package/include/glib-2.0/glib/glib-visibility.h +34 -0
  33. package/include/glib-2.0/glib/gmacros.h +32 -0
  34. package/include/glib-2.0/glib/gmain.h +4 -0
  35. package/include/glib-2.0/glib/gmarkup.h +18 -1
  36. package/include/glib-2.0/glib/gmem.h +4 -4
  37. package/include/glib-2.0/glib/gmessages.h +7 -9
  38. package/include/glib-2.0/glib/gnode.h +1 -1
  39. package/include/glib-2.0/glib/goption.h +1 -1
  40. package/include/glib-2.0/glib/gsequence.h +2 -2
  41. package/include/glib-2.0/glib/gslice.h +12 -4
  42. package/include/glib-2.0/glib/gspawn.h +1 -1
  43. package/include/glib-2.0/glib/gstrfuncs.h +191 -1
  44. package/include/glib-2.0/glib/gtestutils.h +6 -3
  45. package/include/glib-2.0/glib/gtimer.h +1 -0
  46. package/include/glib-2.0/glib/guri.h +3 -3
  47. package/include/glib-2.0/glib/gutils.h +10 -1
  48. package/include/glib-2.0/glib/gvarianttype.h +16 -16
  49. package/include/glib-2.0/glib/gversionmacros.h +22 -0
  50. package/include/glib-2.0/gmodule/gmodule-visibility.h +34 -0
  51. package/include/glib-2.0/gmodule.h +1 -1
  52. package/include/glib-2.0/gobject/gbinding.h +1 -1
  53. package/include/glib-2.0/gobject/gobject-visibility.h +34 -0
  54. package/include/glib-2.0/gobject/gobject.h +1 -1
  55. package/include/glib-2.0/gobject/gparam.h +1 -1
  56. package/include/glib-2.0/gobject/gsignal.h +8 -8
  57. package/include/glib-2.0/gobject/gtype.h +17 -17
  58. package/include/hwy/aligned_allocator.h +44 -2
  59. package/include/hwy/auto_tune.h +22 -6
  60. package/include/hwy/base.h +60 -90
  61. package/include/hwy/bit_set.h +410 -0
  62. package/include/hwy/cache_control.h +3 -2
  63. package/include/hwy/detect_compiler_arch.h +134 -14
  64. package/include/hwy/detect_targets.h +82 -36
  65. package/include/hwy/highway.h +15 -0
  66. package/include/hwy/nanobenchmark.h +12 -3
  67. package/include/hwy/ops/arm_neon-inl.h +96 -25
  68. package/include/hwy/ops/arm_sve-inl.h +250 -95
  69. package/include/hwy/ops/emu128-inl.h +12 -7
  70. package/include/hwy/ops/generic_ops-inl.h +271 -131
  71. package/include/hwy/ops/loongarch_lasx-inl.h +31 -9
  72. package/include/hwy/ops/loongarch_lsx-inl.h +33 -12
  73. package/include/hwy/ops/ppc_vsx-inl.h +99 -19
  74. package/include/hwy/ops/rvv-inl.h +239 -130
  75. package/include/hwy/ops/scalar-inl.h +22 -7
  76. package/include/hwy/ops/set_macros-inl.h +163 -107
  77. package/include/hwy/ops/wasm_128-inl.h +13 -22
  78. package/include/hwy/ops/x86_128-inl.h +223 -120
  79. package/include/hwy/ops/x86_256-inl.h +70 -134
  80. package/include/hwy/ops/x86_512-inl.h +130 -134
  81. package/include/hwy/print-inl.h +2 -0
  82. package/include/hwy/profiler.h +355 -264
  83. package/include/hwy/robust_statistics.h +3 -1
  84. package/include/hwy/timer.h +44 -0
  85. package/include/lcms2.h +35 -5
  86. package/include/lcms2_plugin.h +1 -1
  87. package/include/libexif/exif-utils.h +1 -1
  88. package/include/libheif/heif.h +2 -0
  89. package/include/libheif/heif_aux_images.h +2 -2
  90. package/include/libheif/heif_brands.h +16 -4
  91. package/include/libheif/heif_color.h +147 -25
  92. package/include/libheif/heif_components.h +264 -0
  93. package/include/libheif/heif_context.h +18 -4
  94. package/include/libheif/heif_cxx.h +20 -18
  95. package/include/libheif/heif_decoding.h +63 -9
  96. package/include/libheif/heif_encoding.h +46 -12
  97. package/include/libheif/heif_error.h +15 -6
  98. package/include/libheif/heif_export.h +48 -0
  99. package/include/libheif/heif_image.h +94 -32
  100. package/include/libheif/heif_image_handle.h +54 -3
  101. package/include/libheif/heif_items.h +25 -2
  102. package/include/libheif/heif_library.h +13 -18
  103. package/include/libheif/heif_metadata.h +5 -2
  104. package/include/libheif/heif_omaf.h +104 -0
  105. package/include/libheif/heif_plugin.h +80 -13
  106. package/include/libheif/heif_properties.h +259 -5
  107. package/include/libheif/heif_regions.h +5 -3
  108. package/include/libheif/heif_security.h +24 -2
  109. package/include/libheif/heif_sequences.h +163 -14
  110. package/include/libheif/heif_text.h +161 -0
  111. package/include/libheif/heif_tiling.h +2 -2
  112. package/include/libheif/heif_uncompressed.h +29 -5
  113. package/include/libheif/heif_version.h +2 -2
  114. package/include/libpng16/png.h +637 -488
  115. package/include/libpng16/pngconf.h +2 -2
  116. package/include/libpng16/pnglibconf.h +2 -2
  117. package/include/png.h +637 -488
  118. package/include/pngconf.h +2 -2
  119. package/include/pnglibconf.h +2 -2
  120. package/include/resvg.h +3 -3
  121. package/include/tiffconf.h +9 -10
  122. package/include/tiffio.h +10 -9
  123. package/include/tiffvers.h +1 -1
  124. package/include/ultrahdr_api.h +5 -11
  125. package/include/vips/colour.h +2 -2
  126. package/include/vips/memory.h +1 -1
  127. package/include/vips/version.h +4 -4
  128. package/include/zlib.h +3 -3
  129. package/lib/glib-2.0/include/glibconfig.h +1 -3
  130. package/lib/libaom.a +0 -0
  131. package/lib/libcgif.a +0 -0
  132. package/lib/libexif.a +0 -0
  133. package/lib/libexif.la +1 -1
  134. package/lib/libexpat.a +0 -0
  135. package/lib/libexpat.la +2 -2
  136. package/lib/libffi.a +0 -0
  137. package/lib/libgio-2.0.a +0 -0
  138. package/lib/libglib-2.0.a +0 -0
  139. package/lib/libgmodule-2.0.a +0 -0
  140. package/lib/libgobject-2.0.a +0 -0
  141. package/lib/libgthread-2.0.a +0 -0
  142. package/lib/libheif.a +0 -0
  143. package/lib/libhwy.a +0 -0
  144. package/lib/libimagequant.a +0 -0
  145. package/lib/libjpeg.a +0 -0
  146. package/lib/liblcms2.a +0 -0
  147. package/lib/libpng.a +0 -0
  148. package/lib/libpng.la +2 -2
  149. package/lib/libpng16.a +0 -0
  150. package/lib/libpng16.la +2 -2
  151. package/lib/libresvg.a +0 -0
  152. package/lib/libsharpyuv.a +0 -0
  153. package/lib/libtiff.a +0 -0
  154. package/lib/libuhdr.a +0 -0
  155. package/lib/libvips-cpp.a +0 -0
  156. package/lib/libvips.a +0 -0
  157. package/lib/libwebp.a +0 -0
  158. package/lib/libwebpdecoder.a +0 -0
  159. package/lib/libwebpdemux.a +0 -0
  160. package/lib/libwebpmux.a +0 -0
  161. package/lib/libz.a +0 -0
  162. package/lib/pkgconfig/aom.pc +2 -2
  163. package/lib/pkgconfig/cgif.pc +1 -1
  164. package/lib/pkgconfig/expat.pc +1 -1
  165. package/lib/pkgconfig/gio-2.0.pc +1 -1
  166. package/lib/pkgconfig/glib-2.0.pc +1 -1
  167. package/lib/pkgconfig/gmodule-2.0.pc +1 -1
  168. package/lib/pkgconfig/gmodule-export-2.0.pc +1 -1
  169. package/lib/pkgconfig/gmodule-no-export-2.0.pc +1 -1
  170. package/lib/pkgconfig/gobject-2.0.pc +1 -1
  171. package/lib/pkgconfig/gthread-2.0.pc +1 -1
  172. package/lib/pkgconfig/lcms2.pc +1 -1
  173. package/lib/pkgconfig/libexif.pc +1 -1
  174. package/lib/pkgconfig/libheif.pc +1 -1
  175. package/lib/pkgconfig/libhwy.pc +3 -4
  176. package/lib/pkgconfig/libpng.pc +1 -1
  177. package/lib/pkgconfig/libpng16.pc +1 -1
  178. package/lib/pkgconfig/libsharpyuv.pc +1 -1
  179. package/lib/pkgconfig/libtiff-4.pc +2 -2
  180. package/lib/pkgconfig/libwebp.pc +1 -1
  181. package/lib/pkgconfig/libwebpdecoder.pc +11 -0
  182. package/lib/pkgconfig/libwebpmux.pc +1 -1
  183. package/lib/pkgconfig/vips-cpp.pc +1 -1
  184. package/lib/pkgconfig/vips.pc +1 -1
  185. package/package.json +1 -1
  186. package/versions.json +15 -15
  187. package/lib/libsharpyuv.la +0 -41
  188. package/lib/libtiff.la +0 -41
  189. package/lib/libwebp.la +0 -41
  190. package/lib/libwebpdemux.la +0 -41
  191. package/lib/libwebpmux.la +0 -41
@@ -1573,13 +1573,6 @@ HWY_API Vec128<T, N> Xor(Vec128<T, N> a, Vec128<T, N> b) {
1573
1573
  return Vec128<T, N>{wasm_v128_xor(a.raw, b.raw)};
1574
1574
  }
1575
1575
 
1576
- // ------------------------------ Xor3
1577
-
1578
- template <typename T, size_t N>
1579
- HWY_API Vec128<T, N> Xor3(Vec128<T, N> x1, Vec128<T, N> x2, Vec128<T, N> x3) {
1580
- return Xor(x1, Xor(x2, x3));
1581
- }
1582
-
1583
1576
  // ------------------------------ Or3
1584
1577
 
1585
1578
  template <typename T, size_t N>
@@ -3943,6 +3936,17 @@ HWY_API V InterleaveOddBlocks(D, V a, V /*b*/) {
3943
3936
  return a;
3944
3937
  }
3945
3938
 
3939
+ // ------------------------------ InterleaveLowerBlocks
3940
+ template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_LE_D(D, 16)>
3941
+ HWY_API V InterleaveLowerBlocks(D, V a, V /*b*/) {
3942
+ return a;
3943
+ }
3944
+ // ------------------------------ InterleaveUpperBlocks
3945
+ template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_LE_D(D, 16)>
3946
+ HWY_API V InterleaveUpperBlocks(D, V a, V /*b*/) {
3947
+ return a;
3948
+ }
3949
+
3946
3950
  // ------------------------------ ReverseBlocks
3947
3951
  template <class D>
3948
3952
  HWY_API VFromD<D> ReverseBlocks(D /* tag */, VFromD<D> v) {
@@ -5888,24 +5892,11 @@ HWY_API VFromD<D32> ReorderWidenMulAccumulate(D32 d32, V16 a, V16 b,
5888
5892
  }
5889
5893
 
5890
5894
  // ------------------------------ RearrangeToOddPlusEven
5891
- template <size_t N>
5892
- HWY_API Vec128<int32_t, N> RearrangeToOddPlusEven(
5893
- const Vec128<int32_t, N> sum0, const Vec128<int32_t, N> /*sum1*/) {
5895
+ template <class VW, HWY_IF_NOT_FLOAT_V(VW)>
5896
+ HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW) {
5894
5897
  return sum0; // invariant already holds
5895
5898
  }
5896
5899
 
5897
- template <size_t N>
5898
- HWY_API Vec128<uint32_t, N> RearrangeToOddPlusEven(
5899
- const Vec128<uint32_t, N> sum0, const Vec128<uint32_t, N> /*sum1*/) {
5900
- return sum0; // invariant already holds
5901
- }
5902
-
5903
- template <size_t N>
5904
- HWY_API Vec128<float, N> RearrangeToOddPlusEven(const Vec128<float, N> sum0,
5905
- const Vec128<float, N> sum1) {
5906
- return Add(sum0, sum1);
5907
- }
5908
-
5909
5900
  // ------------------------------ Reductions
5910
5901
 
5911
5902
  // Nothing native, generic_ops-inl defines SumOfLanes and ReduceSum.
@@ -57,7 +57,7 @@ namespace detail {
57
57
  #undef HWY_AVX3_HAVE_F32_TO_BF16C
58
58
  #if HWY_TARGET <= HWY_AVX3_ZEN4 && !HWY_COMPILER_CLANGCL && \
59
59
  (HWY_COMPILER_GCC_ACTUAL >= 1000 || HWY_COMPILER_CLANG >= 900) && \
60
- !defined(HWY_AVX3_DISABLE_AVX512BF16)
60
+ HWY_AVX3_ENABLE_AVX512BF16
61
61
  #define HWY_AVX3_HAVE_F32_TO_BF16C 1
62
62
  #else
63
63
  #define HWY_AVX3_HAVE_F32_TO_BF16C 0
@@ -71,8 +71,9 @@ namespace detail {
71
71
  #endif
72
72
 
73
73
  #undef HWY_X86_HAVE_AVX10_2_OPS
74
- #if HWY_TARGET_IS_AVX10_2 && \
75
- (HWY_COMPILER_GCC_ACTUAL >= 1501 || HWY_COMPILER3_CLANG >= 200103)
74
+ #if HWY_TARGET_IS_AVX10_2 && \
75
+ (HWY_COMPILER_GCC_ACTUAL >= 1501 || \
76
+ (HWY_COMPILER3_CLANG >= 200103 && HWY_COMPILER_CLANG != 2100))
76
77
  #define HWY_X86_HAVE_AVX10_2_OPS 1
77
78
  #else
78
79
  #define HWY_X86_HAVE_AVX10_2_OPS 0
@@ -715,83 +716,120 @@ HWY_API Vec128<double, N> Xor(Vec128<double, N> a, Vec128<double, N> b) {
715
716
  return Vec128<double, N>{_mm_xor_pd(a.raw, b.raw)};
716
717
  }
717
718
 
718
- // ------------------------------ Not
719
- template <typename T, size_t N>
720
- HWY_API Vec128<T, N> Not(const Vec128<T, N> v) {
721
- const DFromV<decltype(v)> d;
722
- const RebindToUnsigned<decltype(d)> du;
723
- using VU = VFromD<decltype(du)>;
719
+ // ------------------------------ TernaryLogic
720
+
721
+ #undef HWY_X86_HAVE_TERNARY_LOGIC
724
722
  #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
725
- const __m128i vu = BitCast(du, v).raw;
726
- return BitCast(d, VU{_mm_ternarylogic_epi32(vu, vu, vu, 0x55)});
723
+ #define HWY_X86_HAVE_TERNARY_LOGIC 1
727
724
  #else
728
- return Xor(v, BitCast(d, VU{_mm_set1_epi32(-1)}));
725
+ #define HWY_X86_HAVE_TERNARY_LOGIC 0
726
+ #endif
727
+
728
+ #if HWY_X86_HAVE_TERNARY_LOGIC
729
+ namespace detail {
730
+
731
+ // Forward-declare the per-target implementations.
732
+ template <uint8_t kTernLogOp, size_t kVectorBytes>
733
+ struct TernaryLogicImpl;
734
+
735
+ // Interface called from all targets. Without this, the compiler would only
736
+ // examine one of the overloads, because each is templated on kTernLogOp.
737
+ template <uint8_t kTernLogOp, class V>
738
+ HWY_INLINE V TernaryLogic(V a, V b, V c) {
739
+ return TernaryLogicImpl<kTernLogOp, sizeof(V)>()(a, b, c);
740
+ }
741
+
742
+ // Per-target partial specialization.
743
+ template <uint8_t kTernLogOp>
744
+ struct TernaryLogicImpl<kTernLogOp, 16> {
745
+ template <class V>
746
+ HWY_INLINE V operator()(V a, V b, V c) const {
747
+ const DFromV<decltype(a)> d;
748
+ const RebindToUnsigned<decltype(d)> du;
749
+ using VU = VFromD<decltype(du)>;
750
+ const __m128i ret = _mm_ternarylogic_epi64(
751
+ BitCast(du, a).raw, BitCast(du, b).raw, BitCast(du, c).raw, kTernLogOp);
752
+ return BitCast(d, VU{ret});
753
+ }
754
+ };
755
+
756
+ } // namespace detail
757
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
758
+
759
+ // ------------------------------ Not
760
+ template <class V> // generic for all vector lengths
761
+ HWY_API V Not(const V v) {
762
+ #if HWY_X86_HAVE_TERNARY_LOGIC
763
+ return detail::TernaryLogic<0x55>(v, v, v);
764
+ #else
765
+ const DFromV<decltype(v)> d;
766
+ const RebindToSigned<decltype(d)> di;
767
+ return Xor(v, BitCast(d, Set(di, -1)));
729
768
  #endif
730
769
  }
731
770
 
771
+ #if HWY_X86_HAVE_TERNARY_LOGIC
772
+
732
773
  // ------------------------------ Xor3
733
- template <typename T, size_t N>
734
- HWY_API Vec128<T, N> Xor3(Vec128<T, N> x1, Vec128<T, N> x2, Vec128<T, N> x3) {
735
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
736
- const DFromV<decltype(x1)> d;
737
- const RebindToUnsigned<decltype(d)> du;
738
- using VU = VFromD<decltype(du)>;
739
- const __m128i ret = _mm_ternarylogic_epi64(
740
- BitCast(du, x1).raw, BitCast(du, x2).raw, BitCast(du, x3).raw, 0x96);
741
- return BitCast(d, VU{ret});
774
+
775
+ #ifdef HWY_NATIVE_XOR3
776
+ #undef HWY_NATIVE_XOR3
742
777
  #else
743
- return Xor(x1, Xor(x2, x3));
778
+ #define HWY_NATIVE_XOR3
744
779
  #endif
780
+
781
+ template <class V> // generic for all vector lengths
782
+ HWY_API V Xor3(V x1, V x2, V x3) {
783
+ return detail::TernaryLogic<0x96>(x1, x2, x3);
745
784
  }
746
785
 
786
+ // ------------------------------ XorAndNot
787
+
788
+ #ifdef HWY_NATIVE_BCAX
789
+ #undef HWY_NATIVE_BCAX
790
+ #else
791
+ #define HWY_NATIVE_BCAX
792
+ #endif
793
+
794
+ template <class V> // generic for all vector lengths
795
+ HWY_API V XorAndNot(V x, V a1, V a2) {
796
+ return detail::TernaryLogic<0xD2>(x, a1, a2);
797
+ }
798
+
799
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
800
+
747
801
  // ------------------------------ Or3
748
- template <typename T, size_t N>
749
- HWY_API Vec128<T, N> Or3(Vec128<T, N> o1, Vec128<T, N> o2, Vec128<T, N> o3) {
750
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
751
- const DFromV<decltype(o1)> d;
752
- const RebindToUnsigned<decltype(d)> du;
753
- using VU = VFromD<decltype(du)>;
754
- const __m128i ret = _mm_ternarylogic_epi64(
755
- BitCast(du, o1).raw, BitCast(du, o2).raw, BitCast(du, o3).raw, 0xFE);
756
- return BitCast(d, VU{ret});
802
+ template <class V> // generic for all vector lengths
803
+ HWY_API V Or3(V o1, V o2, V o3) {
804
+ #if HWY_X86_HAVE_TERNARY_LOGIC
805
+ return detail::TernaryLogic<0xFE>(o1, o2, o3);
757
806
  #else
758
807
  return Or(o1, Or(o2, o3));
759
808
  #endif
760
809
  }
761
810
 
762
811
  // ------------------------------ OrAnd
763
- template <typename T, size_t N>
764
- HWY_API Vec128<T, N> OrAnd(Vec128<T, N> o, Vec128<T, N> a1, Vec128<T, N> a2) {
765
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
766
- const DFromV<decltype(o)> d;
767
- const RebindToUnsigned<decltype(d)> du;
768
- using VU = VFromD<decltype(du)>;
769
- const __m128i ret = _mm_ternarylogic_epi64(
770
- BitCast(du, o).raw, BitCast(du, a1).raw, BitCast(du, a2).raw, 0xF8);
771
- return BitCast(d, VU{ret});
812
+ template <class V> // generic for all vector lengths
813
+ HWY_API V OrAnd(V o, V a1, V a2) {
814
+ #if HWY_X86_HAVE_TERNARY_LOGIC
815
+ return detail::TernaryLogic<0xF8>(o, a1, a2);
772
816
  #else
773
817
  return Or(o, And(a1, a2));
774
818
  #endif
775
819
  }
776
820
 
777
821
  // ------------------------------ IfVecThenElse
778
- template <typename T, size_t N>
779
- HWY_API Vec128<T, N> IfVecThenElse(Vec128<T, N> mask, Vec128<T, N> yes,
780
- Vec128<T, N> no) {
781
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
782
- const DFromV<decltype(no)> d;
783
- const RebindToUnsigned<decltype(d)> du;
784
- using VU = VFromD<decltype(du)>;
785
- return BitCast(
786
- d, VU{_mm_ternarylogic_epi64(BitCast(du, mask).raw, BitCast(du, yes).raw,
787
- BitCast(du, no).raw, 0xCA)});
822
+ template <class V> // generic for all vector lengths
823
+ HWY_API V IfVecThenElse(V mask, V yes, V no) {
824
+ #if HWY_X86_HAVE_TERNARY_LOGIC
825
+ return detail::TernaryLogic<0xCA>(mask, yes, no);
788
826
  #else
789
827
  return IfThenElse(MaskFromVec(mask), yes, no);
790
828
  #endif
791
829
  }
792
830
 
793
831
  // ------------------------------ BitwiseIfThenElse
794
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
832
+ #if HWY_X86_HAVE_TERNARY_LOGIC
795
833
 
796
834
  #ifdef HWY_NATIVE_BITWISE_IF_THEN_ELSE
797
835
  #undef HWY_NATIVE_BITWISE_IF_THEN_ELSE
@@ -799,12 +837,12 @@ HWY_API Vec128<T, N> IfVecThenElse(Vec128<T, N> mask, Vec128<T, N> yes,
799
837
  #define HWY_NATIVE_BITWISE_IF_THEN_ELSE
800
838
  #endif
801
839
 
802
- template <class V>
840
+ template <class V> // generic for all vector lengths
803
841
  HWY_API V BitwiseIfThenElse(V mask, V yes, V no) {
804
842
  return IfVecThenElse(mask, yes, no);
805
843
  }
806
844
 
807
- #endif
845
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
808
846
 
809
847
  // ------------------------------ Operator overloads (internal-only if float)
810
848
 
@@ -1004,6 +1042,23 @@ HWY_API MFromD<D> MaskFalse(D /*d*/) {
1004
1042
  return MFromD<D>{static_cast<decltype(MFromD<D>().raw)>(0)};
1005
1043
  }
1006
1044
 
1045
+ // ------------------------------ SetMask
1046
+ #ifdef HWY_NATIVE_SET_MASK
1047
+ #undef HWY_NATIVE_SET_MASK
1048
+ #else
1049
+ #define HWY_NATIVE_SET_MASK
1050
+ #endif
1051
+
1052
+ template <class D>
1053
+ HWY_API MFromD<D> SetMask(D /*d*/, bool val) {
1054
+ constexpr uint64_t kMask = (HWY_MAX_LANES_D(D) < 64)
1055
+ ? ((1ULL << (HWY_MAX_LANES_D(D) & 63)) - 1ULL)
1056
+ : LimitsMax<uint64_t>();
1057
+
1058
+ return MFromD<D>{static_cast<decltype(MFromD<D>().raw)>(
1059
+ static_cast<uint64_t>(-static_cast<int64_t>(val)) & kMask)};
1060
+ }
1061
+
1007
1062
  // ------------------------------ IsNegative (MFromD)
1008
1063
  #ifdef HWY_NATIVE_IS_NEGATIVE
1009
1064
  #undef HWY_NATIVE_IS_NEGATIVE
@@ -1939,6 +1994,45 @@ HWY_API Mask128<T, N> ExclusiveNeither(const Mask128<T, N> a, Mask128<T, N> b) {
1939
1994
 
1940
1995
  #endif // HWY_TARGET <= HWY_AVX3
1941
1996
 
1997
+ // MaskedTernaryLogic depends on MFromD.
1998
+ #if HWY_X86_HAVE_TERNARY_LOGIC
1999
+ namespace detail {
2000
+
2001
+ // Forward-declare implementation.
2002
+ template <uint8_t kTernLogOp, size_t kVectorBytes>
2003
+ struct MaskedTernaryLogicImpl;
2004
+
2005
+ // Same as TernaryLogic, but with writemask. If !mask, returns a.
2006
+ template <uint8_t kTernLogOp, class V>
2007
+ HWY_INLINE V MaskedTernaryLogic(MFromD<DFromV<V>> mask, V a, V b, V c) {
2008
+ return MaskedTernaryLogicImpl<kTernLogOp, sizeof(V)>()(mask, a, b, c);
2009
+ }
2010
+
2011
+ template <uint8_t kTernLogOp>
2012
+ struct MaskedTernaryLogicImpl<kTernLogOp, 16> {
2013
+ template <class V, class D = DFromV<V>, HWY_IF_T_SIZE_D(D, 4)>
2014
+ HWY_INLINE V operator()(MFromD<D> mask, V a, V b, V c) const {
2015
+ const D d;
2016
+ const RebindToUnsigned<decltype(d)> du;
2017
+ using VU = VFromD<decltype(du)>;
2018
+ const __m128i ret =
2019
+ _mm_mask_ternarylogic_epi32(a.raw, mask.raw, b.raw, c.raw, kTernLogOp);
2020
+ return BitCast(d, VU{ret});
2021
+ }
2022
+ template <class V, class D = DFromV<V>, HWY_IF_T_SIZE_D(D, 8)>
2023
+ HWY_INLINE V operator()(MFromD<D> mask, V a, V b, V c) const {
2024
+ const D d;
2025
+ const RebindToUnsigned<decltype(d)> du;
2026
+ using VU = VFromD<decltype(du)>;
2027
+ const __m128i ret =
2028
+ _mm_mask_ternarylogic_epi64(a.raw, mask.raw, b.raw, c.raw, kTernLogOp);
2029
+ return BitCast(d, VU{ret});
2030
+ }
2031
+ };
2032
+
2033
+ } // namespace detail
2034
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
2035
+
1942
2036
  // ------------------------------ ShiftLeft
1943
2037
 
1944
2038
  template <int kBits, size_t N>
@@ -4168,7 +4262,7 @@ HWY_API Vec128<int16_t, N> SaturatedAdd(const Vec128<int16_t, N> a,
4168
4262
  return Vec128<int16_t, N>{_mm_adds_epi16(a.raw, b.raw)};
4169
4263
  }
4170
4264
 
4171
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
4265
+ #if HWY_X86_HAVE_TERNARY_LOGIC
4172
4266
  #ifdef HWY_NATIVE_I32_SATURATED_ADDSUB
4173
4267
  #undef HWY_NATIVE_I32_SATURATED_ADDSUB
4174
4268
  #else
@@ -4181,32 +4275,21 @@ HWY_API Vec128<int16_t, N> SaturatedAdd(const Vec128<int16_t, N> a,
4181
4275
  #define HWY_NATIVE_I64_SATURATED_ADDSUB
4182
4276
  #endif
4183
4277
 
4184
- template <size_t N>
4185
- HWY_API Vec128<int32_t, N> SaturatedAdd(Vec128<int32_t, N> a,
4186
- Vec128<int32_t, N> b) {
4187
- const DFromV<decltype(a)> d;
4188
- const auto sum = a + b;
4189
- const auto overflow_mask = MaskFromVec(
4190
- Vec128<int32_t, N>{_mm_ternarylogic_epi32(a.raw, b.raw, sum.raw, 0x42)});
4191
- const auto i32_max = Set(d, LimitsMax<int32_t>());
4192
- const Vec128<int32_t, N> overflow_result{_mm_mask_ternarylogic_epi32(
4193
- i32_max.raw, MaskFromVec(a).raw, i32_max.raw, i32_max.raw, 0x55)};
4278
+ // Generic for all vector lengths.
4279
+ template <class V, class D = DFromV<V>, HWY_IF_SIGNED_D(D),
4280
+ HWY_IF_T_SIZE_ONE_OF_D(D, (1 << 4) | (1 << 8))>
4281
+ HWY_API V SaturatedAdd(V a, V b) {
4282
+ const D d;
4283
+ const V sum = a + b;
4284
+ const MFromD<D> overflow_mask =
4285
+ MaskFromVec(detail::TernaryLogic<0x42>(a, b, sum));
4286
+ const V max = Set(d, LimitsMax<TFromD<D>>());
4287
+ const V overflow_result =
4288
+ detail::MaskedTernaryLogic<0x55>(MaskFromVec(a), max, max, max);
4194
4289
  return IfThenElse(overflow_mask, overflow_result, sum);
4195
4290
  }
4196
4291
 
4197
- template <size_t N>
4198
- HWY_API Vec128<int64_t, N> SaturatedAdd(Vec128<int64_t, N> a,
4199
- Vec128<int64_t, N> b) {
4200
- const DFromV<decltype(a)> d;
4201
- const auto sum = a + b;
4202
- const auto overflow_mask = MaskFromVec(
4203
- Vec128<int64_t, N>{_mm_ternarylogic_epi64(a.raw, b.raw, sum.raw, 0x42)});
4204
- const auto i64_max = Set(d, LimitsMax<int64_t>());
4205
- const Vec128<int64_t, N> overflow_result{_mm_mask_ternarylogic_epi64(
4206
- i64_max.raw, MaskFromVec(a).raw, i64_max.raw, i64_max.raw, 0x55)};
4207
- return IfThenElse(overflow_mask, overflow_result, sum);
4208
- }
4209
- #endif // HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
4292
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
4210
4293
 
4211
4294
  // ------------------------------ SaturatedSub
4212
4295
 
@@ -4236,33 +4319,22 @@ HWY_API Vec128<int16_t, N> SaturatedSub(const Vec128<int16_t, N> a,
4236
4319
  return Vec128<int16_t, N>{_mm_subs_epi16(a.raw, b.raw)};
4237
4320
  }
4238
4321
 
4239
- #if HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
4240
- template <size_t N>
4241
- HWY_API Vec128<int32_t, N> SaturatedSub(Vec128<int32_t, N> a,
4242
- Vec128<int32_t, N> b) {
4243
- const DFromV<decltype(a)> d;
4244
- const auto diff = a - b;
4245
- const auto overflow_mask = MaskFromVec(
4246
- Vec128<int32_t, N>{_mm_ternarylogic_epi32(a.raw, b.raw, diff.raw, 0x18)});
4247
- const auto i32_max = Set(d, LimitsMax<int32_t>());
4248
- const Vec128<int32_t, N> overflow_result{_mm_mask_ternarylogic_epi32(
4249
- i32_max.raw, MaskFromVec(a).raw, i32_max.raw, i32_max.raw, 0x55)};
4322
+ #if HWY_X86_HAVE_TERNARY_LOGIC
4323
+ // Generic for all vector lengths.
4324
+ template <class V, class D = DFromV<V>, HWY_IF_SIGNED_D(D),
4325
+ HWY_IF_T_SIZE_ONE_OF_D(D, (1 << 4) | (1 << 8))>
4326
+ HWY_API V SaturatedSub(V a, V b) {
4327
+ const D d;
4328
+ const V diff = a - b;
4329
+ const MFromD<D> overflow_mask =
4330
+ MaskFromVec(detail::TernaryLogic<0x18>(a, b, diff));
4331
+ const V max = Set(d, LimitsMax<TFromD<D>>());
4332
+ const V overflow_result =
4333
+ detail::MaskedTernaryLogic<0x55>(MaskFromVec(a), max, max, max);
4250
4334
  return IfThenElse(overflow_mask, overflow_result, diff);
4251
4335
  }
4252
4336
 
4253
- template <size_t N>
4254
- HWY_API Vec128<int64_t, N> SaturatedSub(Vec128<int64_t, N> a,
4255
- Vec128<int64_t, N> b) {
4256
- const DFromV<decltype(a)> d;
4257
- const auto diff = a - b;
4258
- const auto overflow_mask = MaskFromVec(
4259
- Vec128<int64_t, N>{_mm_ternarylogic_epi64(a.raw, b.raw, diff.raw, 0x18)});
4260
- const auto i64_max = Set(d, LimitsMax<int64_t>());
4261
- const Vec128<int64_t, N> overflow_result{_mm_mask_ternarylogic_epi64(
4262
- i64_max.raw, MaskFromVec(a).raw, i64_max.raw, i64_max.raw, 0x55)};
4263
- return IfThenElse(overflow_mask, overflow_result, diff);
4264
- }
4265
- #endif // HWY_TARGET <= HWY_AVX3 && !HWY_IS_MSAN
4337
+ #endif // HWY_X86_HAVE_TERNARY_LOGIC
4266
4338
 
4267
4339
  // ------------------------------ AverageRound
4268
4340
 
@@ -4484,7 +4556,7 @@ HWY_API Vec128<int64_t, N> operator*(Vec128<int64_t, N> a,
4484
4556
 
4485
4557
  // ------------------------------ RotateRight (ShiftRight, Or)
4486
4558
 
4487
- // U8 RotateRight implementation on AVX3_DL is now in x86_512-inl.h as U8
4559
+ // U8 RotateRight implementation on AVX3_DL is now in x86_avx3-inl.h as U8
4488
4560
  // RotateRight uses detail::GaloisAffine on AVX3_DL
4489
4561
 
4490
4562
  #if HWY_TARGET > HWY_AVX3_DL
@@ -6962,7 +7034,13 @@ HWY_API Vec128<T, N> Broadcast(const Vec128<T, N> v) {
6962
7034
  template <int kLane, typename T, size_t N, HWY_IF_UI32(T)>
6963
7035
  HWY_API Vec128<T, N> Broadcast(const Vec128<T, N> v) {
6964
7036
  static_assert(0 <= kLane && kLane < N, "Invalid lane");
6965
- return Vec128<T, N>{_mm_shuffle_epi32(v.raw, 0x55 * kLane)};
7037
+ HWY_IF_CONSTEXPR(N == 1) {
7038
+ // Workaround for MSVC compiler bug on single lane integer broadcast
7039
+ return Vec128<T, N>{v};
7040
+ }
7041
+ HWY_IF_CONSTEXPR(N != 1) {
7042
+ return Vec128<T, N>{_mm_shuffle_epi32(v.raw, 0x55 * kLane)};
7043
+ }
6966
7044
  }
6967
7045
 
6968
7046
  template <int kLane, typename T, size_t N, HWY_IF_UI64(T)>
@@ -9115,6 +9193,17 @@ HWY_API V InterleaveOddBlocks(D, V a, V /*b*/) {
9115
9193
  return a;
9116
9194
  }
9117
9195
 
9196
+ // ------------------------------ InterleaveLowerBlocks
9197
+ template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_LE_D(D, 16)>
9198
+ HWY_API V InterleaveLowerBlocks(D, V a, V /*b*/) {
9199
+ return a;
9200
+ }
9201
+ // ------------------------------ InterleaveUpperBlocks
9202
+ template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_LE_D(D, 16)>
9203
+ HWY_API V InterleaveUpperBlocks(D, V a, V /*b*/) {
9204
+ return a;
9205
+ }
9206
+
9118
9207
  // ------------------------------ Shl (ZipLower, Mul)
9119
9208
 
9120
9209
  // Use AVX2/3 variable shifts where available, otherwise multiply by powers of
@@ -9939,6 +10028,12 @@ HWY_API VFromD<DF> ReorderWidenMulAccumulate(DF /*df*/, VBF a, VBF b,
9939
10028
  reinterpret_cast<__m128bh>(b.raw))};
9940
10029
  }
9941
10030
 
10031
+ template <class VW, HWY_IF_FLOAT_V(VW)>
10032
+ HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW) {
10033
+ // Sum1 is unused and the invariant already holds.
10034
+ return sum0;
10035
+ }
10036
+
9942
10037
  #endif // HWY_NATIVE_DOT_BF16
9943
10038
 
9944
10039
  // Even if N=1, the input is always at least 2 lanes, hence madd_epi16 is safe.
@@ -9965,21 +10060,10 @@ HWY_API VFromD<DU32> ReorderWidenMulAccumulate(DU32 d, VU16 a, VU16 b,
9965
10060
  }
9966
10061
 
9967
10062
  // ------------------------------ RearrangeToOddPlusEven
9968
- template <size_t N>
9969
- HWY_API Vec128<int32_t, N> RearrangeToOddPlusEven(const Vec128<int32_t, N> sum0,
9970
- Vec128<int32_t, N> /*sum1*/) {
9971
- return sum0; // invariant already holds
9972
- }
9973
-
9974
- template <size_t N>
9975
- HWY_API Vec128<uint32_t, N> RearrangeToOddPlusEven(
9976
- const Vec128<uint32_t, N> sum0, Vec128<uint32_t, N> /*sum1*/) {
9977
- return sum0; // invariant already holds
9978
- }
9979
-
9980
- template <class VW>
9981
- HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW sum1) {
9982
- return Add(sum0, sum1);
10063
+ template <class VW, HWY_IF_NOT_FLOAT_V(VW)>
10064
+ HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW) {
10065
+ // For integer types, sum1 is unused and the invariant already holds.
10066
+ return sum0;
9983
10067
  }
9984
10068
 
9985
10069
  // ------------------------------ SumOfMulQuadAccumulate
@@ -10003,12 +10087,21 @@ HWY_API VFromD<DI32> SumOfMulQuadAccumulate(
10003
10087
  #else
10004
10088
  #define HWY_NATIVE_I8_I8_SUMOFMULQUADACCUMULATE
10005
10089
  #endif
10090
+
10091
+ #if HWY_X86_HAVE_AVX10_2_OPS
10092
+ template <class DI32, HWY_IF_I32_D(DI32), HWY_IF_V_SIZE_LE_D(DI32, 16)>
10093
+ HWY_API VFromD<DI32> SumOfMulQuadAccumulate(DI32 /*di32*/,
10094
+ VFromD<Repartition<int8_t, DI32>> a,
10095
+ VFromD<Repartition<int8_t, DI32>> b,
10096
+ VFromD<DI32> sum) {
10097
+ return VFromD<DI32>{_mm_dpbssd_epi32(sum.raw, a.raw, b.raw)};
10098
+ }
10099
+ #else // !HWY_X86_HAVE_AVX10_2_OPS
10006
10100
  template <class DI32, HWY_IF_I32_D(DI32)>
10007
10101
  HWY_API VFromD<DI32> SumOfMulQuadAccumulate(DI32 di32,
10008
10102
  VFromD<Repartition<int8_t, DI32>> a,
10009
10103
  VFromD<Repartition<int8_t, DI32>> b,
10010
10104
  VFromD<DI32> sum) {
10011
- // TODO(janwas): AVX-VNNI-INT8 has dpbssd.
10012
10105
  const Repartition<uint8_t, decltype(di32)> du8;
10013
10106
 
10014
10107
  const auto a_u = BitCast(du8, a);
@@ -10017,17 +10110,26 @@ HWY_API VFromD<DI32> SumOfMulQuadAccumulate(DI32 di32,
10017
10110
  SumOfMulQuadAccumulate(di32, ShiftRight<7>(a_u), b, Zero(di32)));
10018
10111
  return result_sum_0 - result_sum_1;
10019
10112
  }
10113
+ #endif // HWY_X86_HAVE_AVX10_2_OPS
10020
10114
 
10021
10115
  #ifdef HWY_NATIVE_U8_U8_SUMOFMULQUADACCUMULATE
10022
10116
  #undef HWY_NATIVE_U8_U8_SUMOFMULQUADACCUMULATE
10023
10117
  #else
10024
10118
  #define HWY_NATIVE_U8_U8_SUMOFMULQUADACCUMULATE
10025
10119
  #endif
10120
+
10121
+ #if HWY_X86_HAVE_AVX10_2_OPS
10122
+ template <class DU32, HWY_IF_U32_D(DU32), HWY_IF_V_SIZE_LE_D(DU32, 16)>
10123
+ HWY_API VFromD<DU32> SumOfMulQuadAccumulate(
10124
+ DU32 /*du32*/, VFromD<Repartition<uint8_t, DU32>> a,
10125
+ VFromD<Repartition<uint8_t, DU32>> b, VFromD<DU32> sum) {
10126
+ return VFromD<DU32>{_mm_dpbuud_epi32(sum.raw, a.raw, b.raw)};
10127
+ }
10128
+ #else // !HWY_X86_HAVE_AVX10_2_OPS
10026
10129
  template <class DU32, HWY_IF_U32_D(DU32)>
10027
10130
  HWY_API VFromD<DU32> SumOfMulQuadAccumulate(
10028
10131
  DU32 du32, VFromD<Repartition<uint8_t, DU32>> a,
10029
10132
  VFromD<Repartition<uint8_t, DU32>> b, VFromD<DU32> sum) {
10030
- // TODO(janwas): AVX-VNNI-INT8 has dpbuud.
10031
10133
  const Repartition<uint8_t, decltype(du32)> du8;
10032
10134
  const RebindToSigned<decltype(du8)> di8;
10033
10135
  const RebindToSigned<decltype(du32)> di32;
@@ -10040,6 +10142,7 @@ HWY_API VFromD<DU32> SumOfMulQuadAccumulate(
10040
10142
 
10041
10143
  return BitCast(du32, result_sum_0 - result_sum_1);
10042
10144
  }
10145
+ #endif // HWY_X86_HAVE_AVX10_2_OPS
10043
10146
 
10044
10147
  #endif // HWY_TARGET <= HWY_AVX3_DL
10045
10148