@img/sharp-libvips-dev-wasm32 1.3.0-rc.6 → 1.3.0-rc.8

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 (153) 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 +14 -2
  11. package/include/expat_config.h +6 -3
  12. package/include/expat_external.h +3 -2
  13. package/include/glib-2.0/gio/gdbusconnection.h +2 -8
  14. package/include/glib-2.0/gio/gio-visibility.h +34 -0
  15. package/include/glib-2.0/gio/gioenums.h +5 -4
  16. package/include/glib-2.0/glib/glib-visibility.h +34 -0
  17. package/include/glib-2.0/glib/gmacros.h +3 -3
  18. package/include/glib-2.0/glib/gmarkup.h +10 -0
  19. package/include/glib-2.0/glib/gmem.h +4 -4
  20. package/include/glib-2.0/glib/gmessages.h +6 -8
  21. package/include/glib-2.0/glib/gsequence.h +2 -2
  22. package/include/glib-2.0/glib/gstrfuncs.h +190 -0
  23. package/include/glib-2.0/glib/gutils.h +9 -0
  24. package/include/glib-2.0/glib/gvarianttype.h +16 -16
  25. package/include/glib-2.0/glib/gversionmacros.h +22 -0
  26. package/include/glib-2.0/gmodule/gmodule-visibility.h +34 -0
  27. package/include/glib-2.0/gobject/gobject-visibility.h +34 -0
  28. package/include/glib-2.0/gobject/gsignal.h +5 -5
  29. package/include/glib-2.0/gobject/gtype.h +14 -14
  30. package/include/hwy/aligned_allocator.h +44 -2
  31. package/include/hwy/auto_tune.h +22 -6
  32. package/include/hwy/base.h +60 -90
  33. package/include/hwy/bit_set.h +410 -0
  34. package/include/hwy/cache_control.h +3 -2
  35. package/include/hwy/detect_compiler_arch.h +134 -14
  36. package/include/hwy/detect_targets.h +82 -36
  37. package/include/hwy/highway.h +15 -0
  38. package/include/hwy/nanobenchmark.h +12 -3
  39. package/include/hwy/ops/arm_neon-inl.h +96 -25
  40. package/include/hwy/ops/arm_sve-inl.h +250 -95
  41. package/include/hwy/ops/emu128-inl.h +12 -7
  42. package/include/hwy/ops/generic_ops-inl.h +271 -131
  43. package/include/hwy/ops/loongarch_lasx-inl.h +31 -9
  44. package/include/hwy/ops/loongarch_lsx-inl.h +33 -12
  45. package/include/hwy/ops/ppc_vsx-inl.h +99 -19
  46. package/include/hwy/ops/rvv-inl.h +239 -130
  47. package/include/hwy/ops/scalar-inl.h +22 -7
  48. package/include/hwy/ops/set_macros-inl.h +163 -107
  49. package/include/hwy/ops/wasm_128-inl.h +13 -22
  50. package/include/hwy/ops/x86_128-inl.h +223 -120
  51. package/include/hwy/ops/x86_256-inl.h +70 -134
  52. package/include/hwy/ops/x86_512-inl.h +130 -134
  53. package/include/hwy/print-inl.h +2 -0
  54. package/include/hwy/profiler.h +355 -264
  55. package/include/hwy/robust_statistics.h +3 -1
  56. package/include/hwy/timer.h +44 -0
  57. package/include/lcms2.h +34 -4
  58. package/include/libexif/exif-utils.h +1 -1
  59. package/include/libheif/heif.h +2 -0
  60. package/include/libheif/heif_color.h +127 -11
  61. package/include/libheif/heif_components.h +264 -0
  62. package/include/libheif/heif_context.h +2 -1
  63. package/include/libheif/heif_cxx.h +10 -10
  64. package/include/libheif/heif_decoding.h +51 -7
  65. package/include/libheif/heif_encoding.h +15 -9
  66. package/include/libheif/heif_error.h +9 -2
  67. package/include/libheif/heif_export.h +48 -0
  68. package/include/libheif/heif_image.h +81 -66
  69. package/include/libheif/heif_image_handle.h +2 -2
  70. package/include/libheif/heif_items.h +1 -1
  71. package/include/libheif/heif_library.h +8 -16
  72. package/include/libheif/heif_omaf.h +104 -0
  73. package/include/libheif/heif_plugin.h +16 -9
  74. package/include/libheif/heif_properties.h +250 -12
  75. package/include/libheif/heif_security.h +16 -4
  76. package/include/libheif/heif_sequences.h +86 -4
  77. package/include/libheif/heif_tiling.h +2 -2
  78. package/include/libheif/heif_uncompressed.h +44 -324
  79. package/include/libheif/heif_version.h +2 -2
  80. package/include/libpng16/png.h +7 -7
  81. package/include/libpng16/pngconf.h +1 -1
  82. package/include/libpng16/pnglibconf.h +1 -1
  83. package/include/png.h +7 -7
  84. package/include/pngconf.h +1 -1
  85. package/include/pnglibconf.h +1 -1
  86. package/include/tiffconf.h +9 -10
  87. package/include/tiffio.h +10 -9
  88. package/include/tiffvers.h +1 -1
  89. package/include/ultrahdr_api.h +5 -11
  90. package/include/vips/version.h +4 -4
  91. package/lib/glib-2.0/include/glibconfig.h +1 -3
  92. package/lib/libaom.a +0 -0
  93. package/lib/libcgif.a +0 -0
  94. package/lib/libexif.a +0 -0
  95. package/lib/libexif.la +1 -1
  96. package/lib/libexpat.a +0 -0
  97. package/lib/libexpat.la +3 -3
  98. package/lib/libffi.a +0 -0
  99. package/lib/libgio-2.0.a +0 -0
  100. package/lib/libglib-2.0.a +0 -0
  101. package/lib/libgmodule-2.0.a +0 -0
  102. package/lib/libgobject-2.0.a +0 -0
  103. package/lib/libgthread-2.0.a +0 -0
  104. package/lib/libheif.a +0 -0
  105. package/lib/libhwy.a +0 -0
  106. package/lib/libimagequant.a +0 -0
  107. package/lib/libjpeg.a +0 -0
  108. package/lib/liblcms2.a +0 -0
  109. package/lib/libpng.a +0 -0
  110. package/lib/libpng.la +2 -2
  111. package/lib/libpng16.a +0 -0
  112. package/lib/libpng16.la +2 -2
  113. package/lib/libresvg.a +0 -0
  114. package/lib/libsharpyuv.a +0 -0
  115. package/lib/libtiff.a +0 -0
  116. package/lib/libuhdr.a +0 -0
  117. package/lib/libvips-cpp.a +0 -0
  118. package/lib/libvips.a +0 -0
  119. package/lib/libwebp.a +0 -0
  120. package/lib/libwebpdecoder.a +0 -0
  121. package/lib/libwebpdemux.a +0 -0
  122. package/lib/libwebpmux.a +0 -0
  123. package/lib/libz.a +0 -0
  124. package/lib/pkgconfig/aom.pc +2 -2
  125. package/lib/pkgconfig/expat.pc +1 -1
  126. package/lib/pkgconfig/gio-2.0.pc +1 -1
  127. package/lib/pkgconfig/glib-2.0.pc +1 -1
  128. package/lib/pkgconfig/gmodule-2.0.pc +1 -1
  129. package/lib/pkgconfig/gmodule-export-2.0.pc +1 -1
  130. package/lib/pkgconfig/gmodule-no-export-2.0.pc +1 -1
  131. package/lib/pkgconfig/gobject-2.0.pc +1 -1
  132. package/lib/pkgconfig/gthread-2.0.pc +1 -1
  133. package/lib/pkgconfig/lcms2.pc +1 -1
  134. package/lib/pkgconfig/libexif.pc +1 -1
  135. package/lib/pkgconfig/libheif.pc +2 -2
  136. package/lib/pkgconfig/libhwy.pc +3 -4
  137. package/lib/pkgconfig/libpng.pc +1 -1
  138. package/lib/pkgconfig/libpng16.pc +1 -1
  139. package/lib/pkgconfig/libsharpyuv.pc +1 -1
  140. package/lib/pkgconfig/libtiff-4.pc +2 -2
  141. package/lib/pkgconfig/libwebp.pc +1 -1
  142. package/lib/pkgconfig/libwebpdecoder.pc +11 -0
  143. package/lib/pkgconfig/libwebpmux.pc +1 -1
  144. package/lib/pkgconfig/vips-cpp.pc +1 -1
  145. package/lib/pkgconfig/vips.pc +1 -1
  146. package/package.json +1 -1
  147. package/versions.json +12 -12
  148. package/include/libheif/heif_uncompressed_types.h +0 -143
  149. package/lib/libsharpyuv.la +0 -41
  150. package/lib/libtiff.la +0 -41
  151. package/lib/libwebp.la +0 -41
  152. package/lib/libwebpdemux.la +0 -41
  153. package/lib/libwebpmux.la +0 -41
@@ -1058,12 +1058,6 @@ HWY_API V AndNot(const V not_a, const V b) {
1058
1058
  return And(Not(not_a), b);
1059
1059
  }
1060
1060
 
1061
- // ------------------------------ Xor3
1062
- template <class V>
1063
- HWY_API V Xor3(V x1, V x2, V x3) {
1064
- return Xor(x1, Xor(x2, x3));
1065
- }
1066
-
1067
1061
  // ------------------------------ Or3
1068
1062
  template <class V>
1069
1063
  HWY_API V Or3(V o1, V o2, V o3) {
@@ -1690,10 +1684,17 @@ HWY_API MFromD<D> MaskedIsNaN(const M m, const V v) {
1690
1684
 
1691
1685
  #undef HWY_RVV_RETM_ARGMVV
1692
1686
  #undef HWY_RVV_RETM_ARGVV
1693
- #undef HWY_RVV_RETM_ARGVS
1694
1687
 
1695
1688
  // ------------------------------ Gt/Ge (Lt, Le)
1696
1689
 
1690
+ namespace detail {
1691
+ HWY_RVV_FOREACH_I(HWY_RVV_RETM_ARGVS, GtS, msgt_vx, _ALL)
1692
+ HWY_RVV_FOREACH_U(HWY_RVV_RETM_ARGVS, GtS, msgtu_vx, _ALL)
1693
+ HWY_RVV_FOREACH_F(HWY_RVV_RETM_ARGVS, GtS, mfgt_vf, _ALL)
1694
+ } // namespace detail
1695
+
1696
+ #undef HWY_RVV_RETM_ARGVS
1697
+
1697
1698
  // Swap args to reverse comparisons:
1698
1699
  template <class V>
1699
1700
  HWY_API auto Gt(const V a, const V b) -> decltype(Lt(a, b)) {
@@ -2435,6 +2436,8 @@ HWY_API VFromD<D> PromoteTo(D d, VFromD<Rebind<hwy::bfloat16_t, D>> v) {
2435
2436
 
2436
2437
  // ------------------------------ DemoteTo U
2437
2438
 
2439
+ HWY_INLINE_VAR constexpr size_t kClipShift = 0;
2440
+
2438
2441
  // SEW is for the source so we can use _DEMOTE_VIRT.
2439
2442
  #define HWY_RVV_DEMOTE(BASE, CHAR, SEW, SEWD, SEWH, LMUL, LMULD, LMULH, SHIFT, \
2440
2443
  MLEN, NAME, OP) \
@@ -2442,7 +2445,7 @@ HWY_API VFromD<D> PromoteTo(D d, VFromD<Rebind<hwy::bfloat16_t, D>> v) {
2442
2445
  HWY_API HWY_RVV_V(BASE, SEWH, LMULH) NAME( \
2443
2446
  HWY_RVV_D(BASE, SEWH, N, SHIFT - 1) d, HWY_RVV_V(BASE, SEW, LMUL) v) { \
2444
2447
  return __riscv_v##OP##CHAR##SEWH##LMULH( \
2445
- v, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d))); \
2448
+ v, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d))); \
2446
2449
  }
2447
2450
 
2448
2451
  // Unsigned -> unsigned
@@ -2468,62 +2471,62 @@ HWY_RVV_FOREACH_I16(HWY_RVV_DEMOTE_I_TO_U, DemoteTo, _, _DEMOTE_VIRT)
2468
2471
  template <size_t N>
2469
2472
  HWY_API vuint8mf8_t DemoteTo(Simd<uint8_t, N, -3> d, const vint32mf2_t v) {
2470
2473
  return __riscv_vnclipu_wx_u8mf8(
2471
- DemoteTo(Simd<uint16_t, N, -2>(), v), 0,
2474
+ DemoteTo(Simd<uint16_t, N, -2>(), v), kClipShift,
2472
2475
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2473
2476
  }
2474
2477
  template <size_t N>
2475
2478
  HWY_API vuint8mf4_t DemoteTo(Simd<uint8_t, N, -2> d, const vint32m1_t v) {
2476
2479
  return __riscv_vnclipu_wx_u8mf4(
2477
- DemoteTo(Simd<uint16_t, N, -1>(), v), 0,
2480
+ DemoteTo(Simd<uint16_t, N, -1>(), v), kClipShift,
2478
2481
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2479
2482
  }
2480
2483
  template <size_t N>
2481
2484
  HWY_API vuint8mf2_t DemoteTo(Simd<uint8_t, N, -1> d, const vint32m2_t v) {
2482
2485
  return __riscv_vnclipu_wx_u8mf2(
2483
- DemoteTo(Simd<uint16_t, N, 0>(), v), 0,
2486
+ DemoteTo(Simd<uint16_t, N, 0>(), v), kClipShift,
2484
2487
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2485
2488
  }
2486
2489
  template <size_t N>
2487
2490
  HWY_API vuint8m1_t DemoteTo(Simd<uint8_t, N, 0> d, const vint32m4_t v) {
2488
2491
  return __riscv_vnclipu_wx_u8m1(
2489
- DemoteTo(Simd<uint16_t, N, 1>(), v), 0,
2492
+ DemoteTo(Simd<uint16_t, N, 1>(), v), kClipShift,
2490
2493
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2491
2494
  }
2492
2495
  template <size_t N>
2493
2496
  HWY_API vuint8m2_t DemoteTo(Simd<uint8_t, N, 1> d, const vint32m8_t v) {
2494
2497
  return __riscv_vnclipu_wx_u8m2(
2495
- DemoteTo(Simd<uint16_t, N, 2>(), v), 0,
2498
+ DemoteTo(Simd<uint16_t, N, 2>(), v), kClipShift,
2496
2499
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2497
2500
  }
2498
2501
 
2499
2502
  template <size_t N>
2500
2503
  HWY_API vuint8mf8_t DemoteTo(Simd<uint8_t, N, -3> d, const vuint32mf2_t v) {
2501
2504
  return __riscv_vnclipu_wx_u8mf8(
2502
- DemoteTo(Simd<uint16_t, N, -2>(), v), 0,
2505
+ DemoteTo(Simd<uint16_t, N, -2>(), v), kClipShift,
2503
2506
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2504
2507
  }
2505
2508
  template <size_t N>
2506
2509
  HWY_API vuint8mf4_t DemoteTo(Simd<uint8_t, N, -2> d, const vuint32m1_t v) {
2507
2510
  return __riscv_vnclipu_wx_u8mf4(
2508
- DemoteTo(Simd<uint16_t, N, -1>(), v), 0,
2511
+ DemoteTo(Simd<uint16_t, N, -1>(), v), kClipShift,
2509
2512
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2510
2513
  }
2511
2514
  template <size_t N>
2512
2515
  HWY_API vuint8mf2_t DemoteTo(Simd<uint8_t, N, -1> d, const vuint32m2_t v) {
2513
2516
  return __riscv_vnclipu_wx_u8mf2(
2514
- DemoteTo(Simd<uint16_t, N, 0>(), v), 0,
2517
+ DemoteTo(Simd<uint16_t, N, 0>(), v), kClipShift,
2515
2518
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2516
2519
  }
2517
2520
  template <size_t N>
2518
2521
  HWY_API vuint8m1_t DemoteTo(Simd<uint8_t, N, 0> d, const vuint32m4_t v) {
2519
2522
  return __riscv_vnclipu_wx_u8m1(
2520
- DemoteTo(Simd<uint16_t, N, 1>(), v), 0,
2523
+ DemoteTo(Simd<uint16_t, N, 1>(), v), kClipShift,
2521
2524
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2522
2525
  }
2523
2526
  template <size_t N>
2524
2527
  HWY_API vuint8m2_t DemoteTo(Simd<uint8_t, N, 1> d, const vuint32m8_t v) {
2525
2528
  return __riscv_vnclipu_wx_u8m2(
2526
- DemoteTo(Simd<uint16_t, N, 2>(), v), 0,
2529
+ DemoteTo(Simd<uint16_t, N, 2>(), v), kClipShift,
2527
2530
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, Lanes(d)));
2528
2531
  }
2529
2532
 
@@ -2550,37 +2553,37 @@ HWY_API VFromD<D> DemoteTo(D d, VFromD<Rebind<uint64_t, D>> v) {
2550
2553
  HWY_API vuint8mf8_t U8FromU32(const vuint32mf2_t v) {
2551
2554
  const size_t avl = Lanes(ScalableTag<uint8_t, -3>());
2552
2555
  return __riscv_vnclipu_wx_u8mf8(
2553
- __riscv_vnclipu_wx_u16mf4(v, 0,
2556
+ __riscv_vnclipu_wx_u16mf4(v, kClipShift,
2554
2557
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl)),
2555
- 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2558
+ kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2556
2559
  }
2557
2560
  HWY_API vuint8mf4_t U8FromU32(const vuint32m1_t v) {
2558
2561
  const size_t avl = Lanes(ScalableTag<uint8_t, -2>());
2559
2562
  return __riscv_vnclipu_wx_u8mf4(
2560
- __riscv_vnclipu_wx_u16mf2(v, 0,
2563
+ __riscv_vnclipu_wx_u16mf2(v, kClipShift,
2561
2564
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl)),
2562
- 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2565
+ kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2563
2566
  }
2564
2567
  HWY_API vuint8mf2_t U8FromU32(const vuint32m2_t v) {
2565
2568
  const size_t avl = Lanes(ScalableTag<uint8_t, -1>());
2566
2569
  return __riscv_vnclipu_wx_u8mf2(
2567
- __riscv_vnclipu_wx_u16m1(v, 0,
2570
+ __riscv_vnclipu_wx_u16m1(v, kClipShift,
2568
2571
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl)),
2569
- 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2572
+ kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2570
2573
  }
2571
2574
  HWY_API vuint8m1_t U8FromU32(const vuint32m4_t v) {
2572
2575
  const size_t avl = Lanes(ScalableTag<uint8_t, 0>());
2573
2576
  return __riscv_vnclipu_wx_u8m1(
2574
- __riscv_vnclipu_wx_u16m2(v, 0,
2577
+ __riscv_vnclipu_wx_u16m2(v, kClipShift,
2575
2578
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl)),
2576
- 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2579
+ kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2577
2580
  }
2578
2581
  HWY_API vuint8m2_t U8FromU32(const vuint32m8_t v) {
2579
2582
  const size_t avl = Lanes(ScalableTag<uint8_t, 1>());
2580
2583
  return __riscv_vnclipu_wx_u8m2(
2581
- __riscv_vnclipu_wx_u16m4(v, 0,
2584
+ __riscv_vnclipu_wx_u16m4(v, kClipShift,
2582
2585
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl)),
2583
- 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2586
+ kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2584
2587
  }
2585
2588
 
2586
2589
  // ------------------------------ Truncations
@@ -2591,10 +2594,10 @@ HWY_API vuint8mf8_t TruncateTo(Simd<uint8_t, N, -3> d,
2591
2594
  const size_t avl = Lanes(d);
2592
2595
  const vuint64m1_t v1 = __riscv_vand(v, 0xFF, avl);
2593
2596
  const vuint32mf2_t v2 = __riscv_vnclipu_wx_u32mf2(
2594
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2597
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2595
2598
  const vuint16mf4_t v3 = __riscv_vnclipu_wx_u16mf4(
2596
- v2, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2597
- return __riscv_vnclipu_wx_u8mf8(v3, 0,
2599
+ v2, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2600
+ return __riscv_vnclipu_wx_u8mf8(v3, kClipShift,
2598
2601
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2599
2602
  }
2600
2603
 
@@ -2604,10 +2607,10 @@ HWY_API vuint8mf4_t TruncateTo(Simd<uint8_t, N, -2> d,
2604
2607
  const size_t avl = Lanes(d);
2605
2608
  const vuint64m2_t v1 = __riscv_vand(v, 0xFF, avl);
2606
2609
  const vuint32m1_t v2 = __riscv_vnclipu_wx_u32m1(
2607
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2610
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2608
2611
  const vuint16mf2_t v3 = __riscv_vnclipu_wx_u16mf2(
2609
- v2, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2610
- return __riscv_vnclipu_wx_u8mf4(v3, 0,
2612
+ v2, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2613
+ return __riscv_vnclipu_wx_u8mf4(v3, kClipShift,
2611
2614
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2612
2615
  }
2613
2616
 
@@ -2617,10 +2620,10 @@ HWY_API vuint8mf2_t TruncateTo(Simd<uint8_t, N, -1> d,
2617
2620
  const size_t avl = Lanes(d);
2618
2621
  const vuint64m4_t v1 = __riscv_vand(v, 0xFF, avl);
2619
2622
  const vuint32m2_t v2 = __riscv_vnclipu_wx_u32m2(
2620
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2623
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2621
2624
  const vuint16m1_t v3 = __riscv_vnclipu_wx_u16m1(
2622
- v2, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2623
- return __riscv_vnclipu_wx_u8mf2(v3, 0,
2625
+ v2, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2626
+ return __riscv_vnclipu_wx_u8mf2(v3, kClipShift,
2624
2627
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2625
2628
  }
2626
2629
 
@@ -2630,10 +2633,10 @@ HWY_API vuint8m1_t TruncateTo(Simd<uint8_t, N, 0> d,
2630
2633
  const size_t avl = Lanes(d);
2631
2634
  const vuint64m8_t v1 = __riscv_vand(v, 0xFF, avl);
2632
2635
  const vuint32m4_t v2 = __riscv_vnclipu_wx_u32m4(
2633
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2636
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2634
2637
  const vuint16m2_t v3 = __riscv_vnclipu_wx_u16m2(
2635
- v2, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2636
- return __riscv_vnclipu_wx_u8m1(v3, 0,
2638
+ v2, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2639
+ return __riscv_vnclipu_wx_u8m1(v3, kClipShift,
2637
2640
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2638
2641
  }
2639
2642
 
@@ -2643,8 +2646,8 @@ HWY_API vuint16mf4_t TruncateTo(Simd<uint16_t, N, -3> d,
2643
2646
  const size_t avl = Lanes(d);
2644
2647
  const vuint64m1_t v1 = __riscv_vand(v, 0xFFFF, avl);
2645
2648
  const vuint32mf2_t v2 = __riscv_vnclipu_wx_u32mf2(
2646
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2647
- return __riscv_vnclipu_wx_u16mf4(v2, 0,
2649
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2650
+ return __riscv_vnclipu_wx_u16mf4(v2, kClipShift,
2648
2651
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2649
2652
  }
2650
2653
 
@@ -2654,8 +2657,8 @@ HWY_API vuint16mf4_t TruncateTo(Simd<uint16_t, N, -2> d,
2654
2657
  const size_t avl = Lanes(d);
2655
2658
  const vuint64m1_t v1 = __riscv_vand(v, 0xFFFF, avl);
2656
2659
  const vuint32mf2_t v2 = __riscv_vnclipu_wx_u32mf2(
2657
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2658
- return __riscv_vnclipu_wx_u16mf4(v2, 0,
2660
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2661
+ return __riscv_vnclipu_wx_u16mf4(v2, kClipShift,
2659
2662
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2660
2663
  }
2661
2664
 
@@ -2665,8 +2668,8 @@ HWY_API vuint16mf2_t TruncateTo(Simd<uint16_t, N, -1> d,
2665
2668
  const size_t avl = Lanes(d);
2666
2669
  const vuint64m2_t v1 = __riscv_vand(v, 0xFFFF, avl);
2667
2670
  const vuint32m1_t v2 = __riscv_vnclipu_wx_u32m1(
2668
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2669
- return __riscv_vnclipu_wx_u16mf2(v2, 0,
2671
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2672
+ return __riscv_vnclipu_wx_u16mf2(v2, kClipShift,
2670
2673
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2671
2674
  }
2672
2675
 
@@ -2676,8 +2679,8 @@ HWY_API vuint16m1_t TruncateTo(Simd<uint16_t, N, 0> d,
2676
2679
  const size_t avl = Lanes(d);
2677
2680
  const vuint64m4_t v1 = __riscv_vand(v, 0xFFFF, avl);
2678
2681
  const vuint32m2_t v2 = __riscv_vnclipu_wx_u32m2(
2679
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2680
- return __riscv_vnclipu_wx_u16m1(v2, 0,
2682
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2683
+ return __riscv_vnclipu_wx_u16m1(v2, kClipShift,
2681
2684
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2682
2685
  }
2683
2686
 
@@ -2687,8 +2690,8 @@ HWY_API vuint16m2_t TruncateTo(Simd<uint16_t, N, 1> d,
2687
2690
  const size_t avl = Lanes(d);
2688
2691
  const vuint64m8_t v1 = __riscv_vand(v, 0xFFFF, avl);
2689
2692
  const vuint32m4_t v2 = __riscv_vnclipu_wx_u32m4(
2690
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2691
- return __riscv_vnclipu_wx_u16m2(v2, 0,
2693
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2694
+ return __riscv_vnclipu_wx_u16m2(v2, kClipShift,
2692
2695
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2693
2696
  }
2694
2697
 
@@ -2697,7 +2700,7 @@ HWY_API vuint32mf2_t TruncateTo(Simd<uint32_t, N, -2> d,
2697
2700
  const VFromD<Simd<uint64_t, N, -1>> v) {
2698
2701
  const size_t avl = Lanes(d);
2699
2702
  const vuint64m1_t v1 = __riscv_vand(v, 0xFFFFFFFFu, avl);
2700
- return __riscv_vnclipu_wx_u32mf2(v1, 0,
2703
+ return __riscv_vnclipu_wx_u32mf2(v1, kClipShift,
2701
2704
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2702
2705
  }
2703
2706
 
@@ -2706,7 +2709,7 @@ HWY_API vuint32mf2_t TruncateTo(Simd<uint32_t, N, -1> d,
2706
2709
  const VFromD<Simd<uint64_t, N, 0>> v) {
2707
2710
  const size_t avl = Lanes(d);
2708
2711
  const vuint64m1_t v1 = __riscv_vand(v, 0xFFFFFFFFu, avl);
2709
- return __riscv_vnclipu_wx_u32mf2(v1, 0,
2712
+ return __riscv_vnclipu_wx_u32mf2(v1, kClipShift,
2710
2713
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2711
2714
  }
2712
2715
 
@@ -2715,7 +2718,7 @@ HWY_API vuint32m1_t TruncateTo(Simd<uint32_t, N, 0> d,
2715
2718
  const VFromD<Simd<uint64_t, N, 1>> v) {
2716
2719
  const size_t avl = Lanes(d);
2717
2720
  const vuint64m2_t v1 = __riscv_vand(v, 0xFFFFFFFFu, avl);
2718
- return __riscv_vnclipu_wx_u32m1(v1, 0,
2721
+ return __riscv_vnclipu_wx_u32m1(v1, kClipShift,
2719
2722
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2720
2723
  }
2721
2724
 
@@ -2724,7 +2727,7 @@ HWY_API vuint32m2_t TruncateTo(Simd<uint32_t, N, 1> d,
2724
2727
  const VFromD<Simd<uint64_t, N, 2>> v) {
2725
2728
  const size_t avl = Lanes(d);
2726
2729
  const vuint64m4_t v1 = __riscv_vand(v, 0xFFFFFFFFu, avl);
2727
- return __riscv_vnclipu_wx_u32m2(v1, 0,
2730
+ return __riscv_vnclipu_wx_u32m2(v1, kClipShift,
2728
2731
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2729
2732
  }
2730
2733
 
@@ -2733,7 +2736,7 @@ HWY_API vuint32m4_t TruncateTo(Simd<uint32_t, N, 2> d,
2733
2736
  const VFromD<Simd<uint64_t, N, 3>> v) {
2734
2737
  const size_t avl = Lanes(d);
2735
2738
  const vuint64m8_t v1 = __riscv_vand(v, 0xFFFFFFFFu, avl);
2736
- return __riscv_vnclipu_wx_u32m4(v1, 0,
2739
+ return __riscv_vnclipu_wx_u32m4(v1, kClipShift,
2737
2740
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2738
2741
  }
2739
2742
 
@@ -2743,8 +2746,8 @@ HWY_API vuint8mf8_t TruncateTo(Simd<uint8_t, N, -3> d,
2743
2746
  const size_t avl = Lanes(d);
2744
2747
  const vuint32mf2_t v1 = __riscv_vand(v, 0xFF, avl);
2745
2748
  const vuint16mf4_t v2 = __riscv_vnclipu_wx_u16mf4(
2746
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2747
- return __riscv_vnclipu_wx_u8mf8(v2, 0,
2749
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2750
+ return __riscv_vnclipu_wx_u8mf8(v2, kClipShift,
2748
2751
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2749
2752
  }
2750
2753
 
@@ -2754,8 +2757,8 @@ HWY_API vuint8mf4_t TruncateTo(Simd<uint8_t, N, -2> d,
2754
2757
  const size_t avl = Lanes(d);
2755
2758
  const vuint32m1_t v1 = __riscv_vand(v, 0xFF, avl);
2756
2759
  const vuint16mf2_t v2 = __riscv_vnclipu_wx_u16mf2(
2757
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2758
- return __riscv_vnclipu_wx_u8mf4(v2, 0,
2760
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2761
+ return __riscv_vnclipu_wx_u8mf4(v2, kClipShift,
2759
2762
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2760
2763
  }
2761
2764
 
@@ -2765,8 +2768,8 @@ HWY_API vuint8mf2_t TruncateTo(Simd<uint8_t, N, -1> d,
2765
2768
  const size_t avl = Lanes(d);
2766
2769
  const vuint32m2_t v1 = __riscv_vand(v, 0xFF, avl);
2767
2770
  const vuint16m1_t v2 = __riscv_vnclipu_wx_u16m1(
2768
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2769
- return __riscv_vnclipu_wx_u8mf2(v2, 0,
2771
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2772
+ return __riscv_vnclipu_wx_u8mf2(v2, kClipShift,
2770
2773
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2771
2774
  }
2772
2775
 
@@ -2776,8 +2779,8 @@ HWY_API vuint8m1_t TruncateTo(Simd<uint8_t, N, 0> d,
2776
2779
  const size_t avl = Lanes(d);
2777
2780
  const vuint32m4_t v1 = __riscv_vand(v, 0xFF, avl);
2778
2781
  const vuint16m2_t v2 = __riscv_vnclipu_wx_u16m2(
2779
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2780
- return __riscv_vnclipu_wx_u8m1(v2, 0,
2782
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2783
+ return __riscv_vnclipu_wx_u8m1(v2, kClipShift,
2781
2784
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2782
2785
  }
2783
2786
 
@@ -2787,8 +2790,8 @@ HWY_API vuint8m2_t TruncateTo(Simd<uint8_t, N, 1> d,
2787
2790
  const size_t avl = Lanes(d);
2788
2791
  const vuint32m8_t v1 = __riscv_vand(v, 0xFF, avl);
2789
2792
  const vuint16m4_t v2 = __riscv_vnclipu_wx_u16m4(
2790
- v1, 0, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2791
- return __riscv_vnclipu_wx_u8m2(v2, 0,
2793
+ v1, kClipShift, HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2794
+ return __riscv_vnclipu_wx_u8m2(v2, kClipShift,
2792
2795
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2793
2796
  }
2794
2797
 
@@ -2797,7 +2800,7 @@ HWY_API vuint16mf4_t TruncateTo(Simd<uint16_t, N, -3> d,
2797
2800
  const VFromD<Simd<uint32_t, N, -2>> v) {
2798
2801
  const size_t avl = Lanes(d);
2799
2802
  const vuint32mf2_t v1 = __riscv_vand(v, 0xFFFF, avl);
2800
- return __riscv_vnclipu_wx_u16mf4(v1, 0,
2803
+ return __riscv_vnclipu_wx_u16mf4(v1, kClipShift,
2801
2804
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2802
2805
  }
2803
2806
 
@@ -2806,7 +2809,7 @@ HWY_API vuint16mf4_t TruncateTo(Simd<uint16_t, N, -2> d,
2806
2809
  const VFromD<Simd<uint32_t, N, -1>> v) {
2807
2810
  const size_t avl = Lanes(d);
2808
2811
  const vuint32mf2_t v1 = __riscv_vand(v, 0xFFFF, avl);
2809
- return __riscv_vnclipu_wx_u16mf4(v1, 0,
2812
+ return __riscv_vnclipu_wx_u16mf4(v1, kClipShift,
2810
2813
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2811
2814
  }
2812
2815
 
@@ -2815,7 +2818,7 @@ HWY_API vuint16mf2_t TruncateTo(Simd<uint16_t, N, -1> d,
2815
2818
  const VFromD<Simd<uint32_t, N, 0>> v) {
2816
2819
  const size_t avl = Lanes(d);
2817
2820
  const vuint32m1_t v1 = __riscv_vand(v, 0xFFFF, avl);
2818
- return __riscv_vnclipu_wx_u16mf2(v1, 0,
2821
+ return __riscv_vnclipu_wx_u16mf2(v1, kClipShift,
2819
2822
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2820
2823
  }
2821
2824
 
@@ -2824,7 +2827,7 @@ HWY_API vuint16m1_t TruncateTo(Simd<uint16_t, N, 0> d,
2824
2827
  const VFromD<Simd<uint32_t, N, 1>> v) {
2825
2828
  const size_t avl = Lanes(d);
2826
2829
  const vuint32m2_t v1 = __riscv_vand(v, 0xFFFF, avl);
2827
- return __riscv_vnclipu_wx_u16m1(v1, 0,
2830
+ return __riscv_vnclipu_wx_u16m1(v1, kClipShift,
2828
2831
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2829
2832
  }
2830
2833
 
@@ -2833,7 +2836,7 @@ HWY_API vuint16m2_t TruncateTo(Simd<uint16_t, N, 1> d,
2833
2836
  const VFromD<Simd<uint32_t, N, 2>> v) {
2834
2837
  const size_t avl = Lanes(d);
2835
2838
  const vuint32m4_t v1 = __riscv_vand(v, 0xFFFF, avl);
2836
- return __riscv_vnclipu_wx_u16m2(v1, 0,
2839
+ return __riscv_vnclipu_wx_u16m2(v1, kClipShift,
2837
2840
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2838
2841
  }
2839
2842
 
@@ -2842,7 +2845,7 @@ HWY_API vuint16m4_t TruncateTo(Simd<uint16_t, N, 2> d,
2842
2845
  const VFromD<Simd<uint32_t, N, 3>> v) {
2843
2846
  const size_t avl = Lanes(d);
2844
2847
  const vuint32m8_t v1 = __riscv_vand(v, 0xFFFF, avl);
2845
- return __riscv_vnclipu_wx_u16m4(v1, 0,
2848
+ return __riscv_vnclipu_wx_u16m4(v1, kClipShift,
2846
2849
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2847
2850
  }
2848
2851
 
@@ -2851,7 +2854,7 @@ HWY_API vuint8mf8_t TruncateTo(Simd<uint8_t, N, -3> d,
2851
2854
  const VFromD<Simd<uint16_t, N, -2>> v) {
2852
2855
  const size_t avl = Lanes(d);
2853
2856
  const vuint16mf4_t v1 = __riscv_vand(v, 0xFF, avl);
2854
- return __riscv_vnclipu_wx_u8mf8(v1, 0,
2857
+ return __riscv_vnclipu_wx_u8mf8(v1, kClipShift,
2855
2858
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2856
2859
  }
2857
2860
 
@@ -2860,7 +2863,7 @@ HWY_API vuint8mf4_t TruncateTo(Simd<uint8_t, N, -2> d,
2860
2863
  const VFromD<Simd<uint16_t, N, -1>> v) {
2861
2864
  const size_t avl = Lanes(d);
2862
2865
  const vuint16mf2_t v1 = __riscv_vand(v, 0xFF, avl);
2863
- return __riscv_vnclipu_wx_u8mf4(v1, 0,
2866
+ return __riscv_vnclipu_wx_u8mf4(v1, kClipShift,
2864
2867
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2865
2868
  }
2866
2869
 
@@ -2869,7 +2872,7 @@ HWY_API vuint8mf2_t TruncateTo(Simd<uint8_t, N, -1> d,
2869
2872
  const VFromD<Simd<uint16_t, N, 0>> v) {
2870
2873
  const size_t avl = Lanes(d);
2871
2874
  const vuint16m1_t v1 = __riscv_vand(v, 0xFF, avl);
2872
- return __riscv_vnclipu_wx_u8mf2(v1, 0,
2875
+ return __riscv_vnclipu_wx_u8mf2(v1, kClipShift,
2873
2876
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2874
2877
  }
2875
2878
 
@@ -2878,7 +2881,7 @@ HWY_API vuint8m1_t TruncateTo(Simd<uint8_t, N, 0> d,
2878
2881
  const VFromD<Simd<uint16_t, N, 1>> v) {
2879
2882
  const size_t avl = Lanes(d);
2880
2883
  const vuint16m2_t v1 = __riscv_vand(v, 0xFF, avl);
2881
- return __riscv_vnclipu_wx_u8m1(v1, 0,
2884
+ return __riscv_vnclipu_wx_u8m1(v1, kClipShift,
2882
2885
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2883
2886
  }
2884
2887
 
@@ -2887,7 +2890,7 @@ HWY_API vuint8m2_t TruncateTo(Simd<uint8_t, N, 1> d,
2887
2890
  const VFromD<Simd<uint16_t, N, 2>> v) {
2888
2891
  const size_t avl = Lanes(d);
2889
2892
  const vuint16m4_t v1 = __riscv_vand(v, 0xFF, avl);
2890
- return __riscv_vnclipu_wx_u8m2(v1, 0,
2893
+ return __riscv_vnclipu_wx_u8m2(v1, kClipShift,
2891
2894
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2892
2895
  }
2893
2896
 
@@ -2896,7 +2899,7 @@ HWY_API vuint8m4_t TruncateTo(Simd<uint8_t, N, 2> d,
2896
2899
  const VFromD<Simd<uint16_t, N, 3>> v) {
2897
2900
  const size_t avl = Lanes(d);
2898
2901
  const vuint16m8_t v1 = __riscv_vand(v, 0xFF, avl);
2899
- return __riscv_vnclipu_wx_u8m4(v1, 0,
2902
+ return __riscv_vnclipu_wx_u8m4(v1, kClipShift,
2900
2903
  HWY_RVV_INSERT_VXRM(__RISCV_VXRM_RDN, avl));
2901
2904
  }
2902
2905
 
@@ -3186,7 +3189,7 @@ namespace detail {
3186
3189
  // For x86-compatible behaviour mandated by Highway API: TableLookupBytes
3187
3190
  // offsets are implicitly relative to the start of their 128-bit block.
3188
3191
  template <typename T, size_t N, int kPow2>
3189
- HWY_INLINE size_t LanesPerBlock(Simd<T, N, kPow2> d) {
3192
+ HWY_LANES_CONSTEXPR HWY_INLINE size_t LanesPerBlock(Simd<T, N, kPow2> d) {
3190
3193
  // kMinVecBytes is the minimum size of VFromD<decltype(d)> in bytes
3191
3194
  constexpr size_t kMinVecBytes =
3192
3195
  ScaleByPower(16, HWY_MAX(HWY_MIN(kPow2, 3), -3));
@@ -3673,7 +3676,7 @@ HWY_API V SwapAdjacentBlocks(const V v) {
3673
3676
 
3674
3677
  template <class D, class V = VFromD<D>>
3675
3678
  HWY_API V InterleaveEvenBlocks(D d, V a, V b) {
3676
- const size_t lpb = detail::LanesPerBlock(d);
3679
+ HWY_LANES_CONSTEXPR size_t lpb = detail::LanesPerBlock(d);
3677
3680
  return OddEvenBlocks(SlideUpLanes(d, b, lpb), a);
3678
3681
  }
3679
3682
 
@@ -3682,7 +3685,7 @@ HWY_API V InterleaveEvenBlocks(D d, V a, V b) {
3682
3685
 
3683
3686
  template <class D, class V = VFromD<D>>
3684
3687
  HWY_API V InterleaveOddBlocks(D d, V a, V b) {
3685
- const size_t lpb = detail::LanesPerBlock(d);
3688
+ HWY_LANES_CONSTEXPR size_t lpb = detail::LanesPerBlock(d);
3686
3689
  return OddEvenBlocks(b, SlideDownLanes(d, a, lpb));
3687
3690
  }
3688
3691
 
@@ -3764,6 +3767,83 @@ HWY_RVV_FOREACH_UI08(HWY_RVV_MASKED_TABLE16, MaskedTableLookupLanes16,
3764
3767
 
3765
3768
  } // namespace detail
3766
3769
 
3770
+ // ------------------------------ InterleaveLowerBlocks
3771
+ // (ConcatLowerLower, OddEvenBlocks, TableLookupLanes)
3772
+
3773
+ namespace detail {
3774
+
3775
+ // Given a concatenated vector of (either upper or lower) half of `b` and `a`,
3776
+ // permutes the vector to return interleaved blocks from both.
3777
+ template <class D, class V = VFromD<D>, HWY_IF_NOT_T_SIZE_D(D, 1)>
3778
+ HWY_INLINE V InterleaveBlocks(D d, const V ba) {
3779
+ const RebindToUnsigned<decltype(d)> du;
3780
+ using VU = VFromD<decltype(du)>;
3781
+ using TU = TFromD<decltype(du)>;
3782
+ HWY_LANES_CONSTEXPR size_t lpb = detail::LanesPerBlock(d);
3783
+ const VU iota = detail::Iota0(du);
3784
+ // Divide the block index by 2, without affecting the within-block lane.
3785
+ const VU idx_blocks =
3786
+ detail::AndS(ShiftRight<1>(iota), static_cast<TU>(~(lpb - 1)));
3787
+ VU idx = Or(idx_blocks, detail::AndS(iota, static_cast<TU>(lpb - 1)));
3788
+ // Odd blocks from from `b`, i.e. the upper half of `ba`.
3789
+ idx = OddEvenBlocks(Add(idx, Set(du, static_cast<TU>(Lanes(d) / 2))), idx);
3790
+
3791
+ return TableLookupLanes(ba, IndicesFromVec(d, idx));
3792
+ }
3793
+
3794
+ // As above, but uses 16-bit indices because 8-bit lanes might overflow.
3795
+ // Identical except for for `du` and the `TableLookupLanes16` call.
3796
+ template <class D, class V = VFromD<D>, HWY_IF_T_SIZE_D(D, 1)>
3797
+ HWY_INLINE V InterleaveBlocks(D d, const V ba) {
3798
+ const Rebind<uint16_t, decltype(d)> du; // Increases LMUL
3799
+ using VU = VFromD<decltype(du)>;
3800
+ using TU = TFromD<decltype(du)>;
3801
+ HWY_LANES_CONSTEXPR size_t lpb = detail::LanesPerBlock(d);
3802
+ const VU iota = detail::Iota0(du);
3803
+ // Divide the block index by 2, without affecting the within-block lane.
3804
+ const VU idx_blocks =
3805
+ detail::AndS(ShiftRight<1>(iota), static_cast<TU>(~(lpb - 1)));
3806
+ VU idx = Or(idx_blocks, detail::AndS(iota, static_cast<TU>(lpb - 1)));
3807
+ // Odd blocks from from `b`, i.e. the upper half of `ba`.
3808
+ idx = OddEvenBlocks(Add(idx, Set(du, static_cast<TU>(Lanes(d) / 2))), idx);
3809
+
3810
+ return detail::TableLookupLanes16(ba, idx);
3811
+ }
3812
+
3813
+ } // namespace detail
3814
+
3815
+ template <class D, class V = VFromD<D>, HWY_IF_POW2_GT_D(DFromV<V>, -3)>
3816
+ HWY_INLINE V InterleaveLowerBlocks(D d, const V a, const V b) {
3817
+ // Blocks are independent of type, hence cast to a type where indices will not
3818
+ // overflow.
3819
+ const Repartition<uint16_t, decltype(d)> du;
3820
+ return BitCast(
3821
+ d, detail::InterleaveBlocks(du, BitCast(du, ConcatLowerLower(d, b, a))));
3822
+ }
3823
+
3824
+ template <class D, class V = VFromD<D>, HWY_IF_POW2_LE_D(DFromV<V>, -3)>
3825
+ HWY_INLINE V InterleaveLowerBlocks(D d, const V a, const V b) {
3826
+ // Might be bytes; if so, the second overload will call TableLookupLanes16.
3827
+ return detail::InterleaveBlocks(d, ConcatLowerLower(d, b, a));
3828
+ }
3829
+
3830
+ // ------------------------------ InterleaveUpperBlocks
3831
+
3832
+ template <class D, class V = VFromD<D>, HWY_IF_POW2_GT_D(DFromV<V>, -3)>
3833
+ HWY_INLINE V InterleaveUpperBlocks(D d, const V a, const V b) {
3834
+ // Blocks are independent of type, hence cast to a type where indices will not
3835
+ // overflow.
3836
+ const Repartition<uint16_t, decltype(d)> du;
3837
+ return BitCast(
3838
+ d, detail::InterleaveBlocks(du, BitCast(du, ConcatUpperUpper(d, b, a))));
3839
+ }
3840
+
3841
+ template <class D, class V = VFromD<D>, HWY_IF_POW2_LE_D(DFromV<V>, -3)>
3842
+ HWY_INLINE V InterleaveUpperBlocks(D d, const V a, const V b) {
3843
+ // Might be bytes; if so, the second overload will call TableLookupLanes16.
3844
+ return detail::InterleaveBlocks(d, ConcatUpperUpper(d, b, a));
3845
+ }
3846
+
3767
3847
  // ------------------------------ Reverse (TableLookupLanes)
3768
3848
  template <class D, HWY_IF_T_SIZE_D(D, 1), HWY_IF_POW2_LE_D(D, 2)>
3769
3849
  HWY_API VFromD<D> Reverse(D d, VFromD<D> v) {
@@ -4419,11 +4499,14 @@ HWY_API V BroadcastBlock(V v) {
4419
4499
  return BitCast(d, detail::TableLookupLanes16(BitCast(du8, v), idx));
4420
4500
  }
4421
4501
 
4422
- template <int kBlockIdx, class V, HWY_IF_POW2_GT_D(DFromV<V>, -3)>
4502
+ namespace detail {
4503
+
4504
+ // Called for at least 16-bit lanes to ensure indices do not overflow.
4505
+ template <int kBlockIdx, class V>
4423
4506
  HWY_API V BroadcastBlock(V v) {
4424
4507
  const DFromV<decltype(v)> d;
4425
- using TU = If<sizeof(TFromV<V>) == 1, uint16_t, MakeUnsigned<TFromV<V>>>;
4426
- const Repartition<TU, decltype(d)> du;
4508
+ const RebindToUnsigned<decltype(d)> du;
4509
+ using TU = TFromD<decltype(du)>;
4427
4510
 
4428
4511
  static_assert(0 <= kBlockIdx && kBlockIdx < d.MaxBlocks(),
4429
4512
  "Invalid block index");
@@ -4435,6 +4518,17 @@ HWY_API V BroadcastBlock(V v) {
4435
4518
  return BitCast(d, TableLookupLanes(BitCast(du, v), idx));
4436
4519
  }
4437
4520
 
4521
+ } // namespace detail
4522
+
4523
+ template <int kBlockIdx, class V, HWY_IF_POW2_GT_D(DFromV<V>, -3)>
4524
+ HWY_API V BroadcastBlock(V v) {
4525
+ // Because we are broadcasting 128-bit blocks, the type does not matter.
4526
+ // We can cast to uint16_t to ensure indices do not overflow.
4527
+ const DFromV<decltype(v)> d;
4528
+ const Repartition<uint16_t, decltype(d)> du16;
4529
+ return BitCast(d, detail::BroadcastBlock<kBlockIdx>(BitCast(du16, v)));
4530
+ }
4531
+
4438
4532
  // ------------------------------ ExtractBlock
4439
4533
  template <int kBlockIdx, class V>
4440
4534
  HWY_API VFromD<BlockDFromD<DFromV<V>>> ExtractBlock(V v) {
@@ -4498,7 +4592,7 @@ HWY_API V ShiftRightLanes(const Simd<T, N, kPow2> d, V v) {
4498
4592
 
4499
4593
  const auto shifted = detail::SlideDown(v, kLanes);
4500
4594
  // Match x86 semantics by zeroing upper lanes in 128-bit blocks
4501
- const size_t lpb = detail::LanesPerBlock(di);
4595
+ HWY_LANES_CONSTEXPR size_t lpb = detail::LanesPerBlock(di);
4502
4596
  const auto idx_mod =
4503
4597
  detail::AndS(BitCast(di, detail::Iota0(du)), static_cast<TI>(lpb - 1));
4504
4598
  const auto keep = detail::LtS(idx_mod, static_cast<TI>(lpb - kLanes));
@@ -4513,10 +4607,10 @@ HWY_API V ShiftRightBytes(const D d, const V v) {
4513
4607
  }
4514
4608
 
4515
4609
  // ------------------------------ InterleaveWholeLower
4516
- #ifdef HWY_NATIVE_INTERLEAVE_WHOLE
4517
- #undef HWY_NATIVE_INTERLEAVE_WHOLE
4610
+ #ifdef HWY_TOGGLE_INTERLEAVE_WHOLE
4611
+ #undef HWY_TOGGLE_INTERLEAVE_WHOLE
4518
4612
  #else
4519
- #define HWY_NATIVE_INTERLEAVE_WHOLE
4613
+ #define HWY_TOGGLE_INTERLEAVE_WHOLE
4520
4614
  #endif
4521
4615
 
4522
4616
  namespace detail {
@@ -4607,7 +4701,7 @@ namespace detail {
4607
4701
  // Definitely at least 128 bit: match x86 semantics (independent blocks). Using
4608
4702
  // InterleaveWhole and 64-bit Compress avoids 8-bit overflow.
4609
4703
  template <class D, class V, HWY_IF_POW2_LE_D(D, 2)>
4610
- HWY_INLINE V InterleaveLowerBlocks(D d, const V a, const V b) {
4704
+ HWY_INLINE V InterleaveLowerImpl(D d, const V a, const V b) {
4611
4705
  static_assert(IsSame<TFromD<D>, TFromV<V>>(), "D/V mismatch");
4612
4706
  const Twice<D> dt;
4613
4707
  const RebindToUnsigned<decltype(dt)> dt_u;
@@ -4622,18 +4716,18 @@ HWY_INLINE V InterleaveLowerBlocks(D d, const V a, const V b) {
4622
4716
  return BitCast(d, LowerHalf(Compress(BitCast(dt_u, interleaved), is_even)));
4623
4717
  }
4624
4718
  template <class D, class V, HWY_IF_POW2_GT_D(D, 2)>
4625
- HWY_INLINE V InterleaveLowerBlocks(D d, const V a, const V b) {
4719
+ HWY_INLINE V InterleaveLowerImpl(D d, const V a, const V b) {
4626
4720
  const Half<D> dh;
4627
4721
  const VFromD<decltype(dh)> i0 =
4628
- InterleaveLowerBlocks(dh, LowerHalf(dh, a), LowerHalf(dh, b));
4722
+ InterleaveLowerImpl(dh, LowerHalf(dh, a), LowerHalf(dh, b));
4629
4723
  const VFromD<decltype(dh)> i1 =
4630
- InterleaveLowerBlocks(dh, UpperHalf(dh, a), UpperHalf(dh, b));
4724
+ InterleaveLowerImpl(dh, UpperHalf(dh, a), UpperHalf(dh, b));
4631
4725
  return Combine(d, i1, i0);
4632
4726
  }
4633
4727
 
4634
4728
  // As above, for the upper half of blocks.
4635
4729
  template <class D, class V, HWY_IF_POW2_LE_D(D, 2)>
4636
- HWY_INLINE V InterleaveUpperBlocks(D d, const V a, const V b) {
4730
+ HWY_INLINE V InterleaveUpperImpl(D d, const V a, const V b) {
4637
4731
  static_assert(IsSame<TFromD<D>, TFromV<V>>(), "D/V mismatch");
4638
4732
  const Twice<D> dt;
4639
4733
  const RebindToUnsigned<decltype(dt)> dt_u;
@@ -4648,12 +4742,12 @@ HWY_INLINE V InterleaveUpperBlocks(D d, const V a, const V b) {
4648
4742
  return BitCast(d, LowerHalf(Compress(BitCast(dt_u, interleaved), is_odd)));
4649
4743
  }
4650
4744
  template <class D, class V, HWY_IF_POW2_GT_D(D, 2)>
4651
- HWY_INLINE V InterleaveUpperBlocks(D d, const V a, const V b) {
4745
+ HWY_INLINE V InterleaveUpperImpl(D d, const V a, const V b) {
4652
4746
  const Half<D> dh;
4653
4747
  const VFromD<decltype(dh)> i0 =
4654
- InterleaveUpperBlocks(dh, LowerHalf(dh, a), LowerHalf(dh, b));
4748
+ InterleaveUpperImpl(dh, LowerHalf(dh, a), LowerHalf(dh, b));
4655
4749
  const VFromD<decltype(dh)> i1 =
4656
- InterleaveUpperBlocks(dh, UpperHalf(dh, a), UpperHalf(dh, b));
4750
+ InterleaveUpperImpl(dh, UpperHalf(dh, a), UpperHalf(dh, b));
4657
4751
  return Combine(d, i1, i0);
4658
4752
  }
4659
4753
 
@@ -4680,7 +4774,7 @@ constexpr bool IsLT128(Simd<T, N, kPow2> /* d */) {
4680
4774
 
4681
4775
  template <class D, class V, HWY_RVV_IF_GE128_D(D)>
4682
4776
  HWY_API V InterleaveLower(D d, const V a, const V b) {
4683
- return detail::InterleaveLowerBlocks(d, a, b);
4777
+ return detail::InterleaveLowerImpl(d, a, b);
4684
4778
  }
4685
4779
 
4686
4780
  // Single block: interleave without extra Compress.
@@ -4698,8 +4792,8 @@ HWY_API V InterleaveLower(D d, const V a, const V b) {
4698
4792
  }
4699
4793
  // Fractional LMUL: use LMUL=1 to ensure we can cast to u64.
4700
4794
  const ScalableTag<TFromD<D>, HWY_MAX(d.Pow2(), 0)> d1;
4701
- return ResizeBitCast(d, detail::InterleaveLowerBlocks(
4702
- d1, ResizeBitCast(d1, a), ResizeBitCast(d1, b)));
4795
+ return ResizeBitCast(d, detail::InterleaveLowerImpl(d1, ResizeBitCast(d1, a),
4796
+ ResizeBitCast(d1, b)));
4703
4797
  }
4704
4798
 
4705
4799
  template <class V>
@@ -4711,7 +4805,7 @@ HWY_API V InterleaveLower(const V a, const V b) {
4711
4805
 
4712
4806
  template <class D, class V, HWY_RVV_IF_GE128_D(D)>
4713
4807
  HWY_API V InterleaveUpper(D d, const V a, const V b) {
4714
- return detail::InterleaveUpperBlocks(d, a, b);
4808
+ return detail::InterleaveUpperImpl(d, a, b);
4715
4809
  }
4716
4810
 
4717
4811
  // Single block: interleave without extra Compress.
@@ -4729,8 +4823,8 @@ HWY_API V InterleaveUpper(D d, const V a, const V b) {
4729
4823
  }
4730
4824
  // Fractional LMUL: use LMUL=1 to ensure we can cast to u64.
4731
4825
  const ScalableTag<TFromD<D>, HWY_MAX(d.Pow2(), 0)> d1;
4732
- return ResizeBitCast(d, detail::InterleaveUpperBlocks(
4733
- d1, ResizeBitCast(d1, a), ResizeBitCast(d1, b)));
4826
+ return ResizeBitCast(d, detail::InterleaveUpperImpl(d1, ResizeBitCast(d1, a),
4827
+ ResizeBitCast(d1, b)));
4734
4828
  }
4735
4829
 
4736
4830
  // ------------------------------ ZipLower
@@ -5266,18 +5360,6 @@ HWY_API VFromD<D> Dup128VecFromValues(D d, TFromD<D> t0, TFromD<D> t1,
5266
5360
  detail::Vec64ValsWrapper<TFromD<D>>{{t2, t3}})));
5267
5361
  }
5268
5362
 
5269
- // ------------------------------ PopulationCount (ShiftRight)
5270
-
5271
- // Handles LMUL < 2 or capped vectors, which generic_ops-inl cannot.
5272
- template <typename V, class D = DFromV<V>, HWY_IF_U8_D(D),
5273
- hwy::EnableIf<D().Pow2() < 1 || D().MaxLanes() < 16>* = nullptr>
5274
- HWY_API V PopulationCount(V v) {
5275
- // See https://arxiv.org/pdf/1611.07612.pdf, Figure 3
5276
- v = Sub(v, detail::AndS(ShiftRight<1>(v), 0x55));
5277
- v = Add(detail::AndS(ShiftRight<2>(v), 0x33), detail::AndS(v, 0x33));
5278
- return detail::AndS(Add(v, ShiftRight<4>(v)), 0x0F);
5279
- }
5280
-
5281
5363
  // ------------------------------ LoadDup128
5282
5364
 
5283
5365
  template <class D>
@@ -5304,7 +5386,7 @@ HWY_API VFromD<D> LoadDup128(D d, const TFromD<D>* const HWY_RESTRICT p) {
5304
5386
 
5305
5387
  // idx must be unsigned for TableLookupLanes.
5306
5388
  using TU = TFromD<decltype(du)>;
5307
- const TU mask = static_cast<TU>(detail::LanesPerBlock(d) - 1);
5389
+ HWY_LANES_CONSTEXPR TU mask = static_cast<TU>(detail::LanesPerBlock(d) - 1);
5308
5390
  // Broadcast the first block.
5309
5391
  const VFromD<RebindToUnsigned<D>> idx = detail::AndS(detail::Iota0(du), mask);
5310
5392
  // Safe even for 8-bit lanes because indices never exceed 15.
@@ -5565,6 +5647,15 @@ constexpr int SufficientPow2ForMask() {
5565
5647
  return HWY_MAX(
5566
5648
  D().Pow2() - 3 - static_cast<int>(FloorLog2(sizeof(TFromD<D>))), -3);
5567
5649
  }
5650
+
5651
+ template <class M>
5652
+ static HWY_INLINE HWY_MAYBE_UNUSED M RvvVmmv(M mask) {
5653
+ // The below And operation is equivalent to the RVV vmmv instruction and
5654
+ // ensures that mask is not in the same register as a vector operand when used
5655
+ // in RVV instructions that take both a vector operand and a mask operand.
5656
+ return And(mask, mask);
5657
+ }
5658
+
5568
5659
  } // namespace detail
5569
5660
 
5570
5661
  template <class D, HWY_IF_T_SIZE_D(D, 1), HWY_IF_LANES_LE_D(D, 8)>
@@ -5573,8 +5664,10 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5573
5664
  if (kN < 8) mask_bits &= detail::MaxMaskBits<kN>();
5574
5665
 
5575
5666
  #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
5576
- return detail::U8MaskBitsVecToMask(
5577
- d, Set(ScalableTag<uint8_t>(), static_cast<uint8_t>(mask_bits)));
5667
+ const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5668
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5669
+ d, detail::ChangeLMUL(ScalableTag<uint8_t>(),
5670
+ Set(du8, static_cast<uint8_t>(mask_bits)))));
5578
5671
  #else
5579
5672
  const RebindToUnsigned<decltype(d)> du8;
5580
5673
  const detail::AdjustSimdTagToMinVecPow2<Repartition<uint64_t, decltype(du8)>>
@@ -5594,10 +5687,10 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5594
5687
  const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5595
5688
  const ScalableTag<uint16_t, detail::SufficientPow2ForMask<D>()> du16;
5596
5689
  // There are exactly 16 mask bits for 128 vector bits of 8-bit lanes.
5597
- return detail::U8MaskBitsVecToMask(
5690
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5598
5691
  d, detail::ChangeLMUL(
5599
5692
  ScalableTag<uint8_t>(),
5600
- BitCast(du8, Set(du16, static_cast<uint16_t>(mask_bits)))));
5693
+ BitCast(du8, Set(du16, static_cast<uint16_t>(mask_bits))))));
5601
5694
  #else
5602
5695
  // Slow fallback for completeness; the above bits to mask cast is preferred.
5603
5696
  const RebindToUnsigned<decltype(d)> du8;
@@ -5626,9 +5719,9 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5626
5719
  #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
5627
5720
  const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5628
5721
  // There are exactly 8 mask bits for 128 vector bits of 16-bit lanes.
5629
- return detail::U8MaskBitsVecToMask(
5722
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5630
5723
  d, detail::ChangeLMUL(ScalableTag<uint8_t>(),
5631
- Set(du8, static_cast<uint8_t>(mask_bits))));
5724
+ Set(du8, static_cast<uint8_t>(mask_bits)))));
5632
5725
  #else
5633
5726
  // Slow fallback for completeness; the above bits to mask cast is preferred.
5634
5727
  const RebindToUnsigned<D> du;
@@ -5645,9 +5738,9 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5645
5738
 
5646
5739
  #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
5647
5740
  const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5648
- return detail::U8MaskBitsVecToMask(
5741
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5649
5742
  d, detail::ChangeLMUL(ScalableTag<uint8_t>(),
5650
- Set(du8, static_cast<uint8_t>(mask_bits * 0x11))));
5743
+ Set(du8, static_cast<uint8_t>(mask_bits * 0x11)))));
5651
5744
  #else
5652
5745
  // Slow fallback for completeness; the above bits to mask cast is preferred.
5653
5746
  const RebindToUnsigned<D> du;
@@ -5663,9 +5756,9 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5663
5756
 
5664
5757
  #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
5665
5758
  const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5666
- return detail::U8MaskBitsVecToMask(
5759
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5667
5760
  d, detail::ChangeLMUL(ScalableTag<uint8_t>(),
5668
- Set(du8, static_cast<uint8_t>(mask_bits * 0x55))));
5761
+ Set(du8, static_cast<uint8_t>(mask_bits * 0x55)))));
5669
5762
  #else
5670
5763
  // Slow fallback for completeness; the above bits to mask cast is preferred.
5671
5764
  const RebindToUnsigned<D> du;
@@ -5674,6 +5767,27 @@ HWY_API MFromD<D> Dup128MaskFromMaskBits(D d, unsigned mask_bits) {
5674
5767
  #endif
5675
5768
  }
5676
5769
 
5770
+ // ------------------------------ SetMask
5771
+
5772
+ #ifdef HWY_NATIVE_SET_MASK
5773
+ #undef HWY_NATIVE_SET_MASK
5774
+ #else
5775
+ #define HWY_NATIVE_SET_MASK
5776
+ #endif
5777
+
5778
+ template <class D>
5779
+ HWY_API MFromD<D> SetMask(D d, bool val) {
5780
+ const uint8_t u8_mask_val = static_cast<uint8_t>(-static_cast<int>(val));
5781
+ #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
5782
+ const ScalableTag<uint8_t, detail::SufficientPow2ForMask<D>()> du8;
5783
+ return detail::RvvVmmv(detail::U8MaskBitsVecToMask(
5784
+ d, detail::ChangeLMUL(ScalableTag<uint8_t>(), Set(du8, u8_mask_val))));
5785
+ #else
5786
+ const Rebind<uint8_t, DFromV<VFromD<decltype(d)>>> du8;
5787
+ return MaskFromVec(Set(du8, u8_mask_val));
5788
+ #endif
5789
+ }
5790
+
5677
5791
  // ------------------------------ Abs (Max, Neg)
5678
5792
 
5679
5793
  template <class V, HWY_IF_SIGNED_V(V)>
@@ -5947,7 +6061,7 @@ HWY_API V64 BitShuffle(V64 values, VI idx) {
5947
6061
  template <class V, HWY_IF_T_SIZE_ONE_OF_V(V, (1 << 1) | (1 << 2) | (1 << 4)),
5948
6062
  class D = DFromV<V>, class DW = RepartitionToWide<D>>
5949
6063
  HWY_API VFromD<DW> MulEven(const V a, const V b) {
5950
- constexpr int maskVal = sizeof(TFromD<D>) == 4 ? 5
6064
+ constexpr int maskVal = sizeof(TFromD<D>) == 4 ? 5
5951
6065
  : sizeof(TFromD<D>) == 2 ? 0x55
5952
6066
  : 0x5555;
5953
6067
  const auto mask = Dup128MaskFromMaskBits(D(), maskVal);
@@ -6245,11 +6359,6 @@ HWY_API vuint32m8_t RearrangeToOddPlusEven(vuint32m8_t sum0, vuint32m8_t sum1) {
6245
6359
  return Combine(d, hi, lo);
6246
6360
  }
6247
6361
 
6248
- template <class VW, HWY_IF_FLOAT_V(VW)> // vfloat*
6249
- HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW sum1) {
6250
- return Add(sum0, sum1); // invariant already holds
6251
- }
6252
-
6253
6362
  // ------------------------------ Lt128
6254
6363
  #if HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400
6255
6364