react-native-executorch 0.10.5 → 0.10.7

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 (251) hide show
  1. package/README.md +10 -1
  2. package/android/build.gradle.kts +4 -3
  3. package/ios/RnExecutorch.mm +15 -17
  4. package/lib/module/fetcher/fetcher.js +35 -122
  5. package/lib/module/fetcher/fetcher.js.map +1 -1
  6. package/lib/module/fetcher/telemetry.js +1 -1
  7. package/lib/module/index.js +12 -13
  8. package/lib/module/index.js.map +1 -1
  9. package/lib/module/models.js +4 -2
  10. package/lib/module/models.js.map +1 -1
  11. package/lib/typescript/src/fetcher/fetcher.d.ts +3 -7
  12. package/lib/typescript/src/fetcher/fetcher.d.ts.map +1 -1
  13. package/lib/typescript/src/models.d.ts.map +1 -1
  14. package/package.json +9 -7
  15. package/react-native-executorch.podspec +6 -2
  16. package/src/fetcher/fetcher.ts +38 -131
  17. package/src/fetcher/telemetry.ts +1 -1
  18. package/src/models.ts +6 -1
  19. package/third-party/common/phonemis/CMakeLists.txt +70 -14
  20. package/third-party/common/phonemis/README.md +183 -33
  21. package/third-party/common/phonemis/THIRD_PARTY_NOTICES.md +57 -0
  22. package/third-party/common/phonemis/knowledge/code_style.md +642 -0
  23. package/third-party/common/phonemis/licenses/Unicode-3.0.txt +39 -0
  24. package/third-party/common/phonemis/licenses/misaki-Apache-2.0.txt +201 -0
  25. package/third-party/common/phonemis/licenses/nlohmann-json-MIT.txt +21 -0
  26. package/third-party/common/phonemis/licenses/xsimd-BSD-3-Clause.txt +29 -0
  27. package/third-party/common/phonemis/src/phonemis/base/config.h +6 -0
  28. package/third-party/common/phonemis/src/phonemis/base/ipipeline.cpp +75 -0
  29. package/third-party/common/phonemis/src/phonemis/base/ipipeline.h +21 -0
  30. package/third-party/common/phonemis/src/phonemis/base/phonemizer/constants.h +2 -5
  31. package/third-party/common/phonemis/src/phonemis/base/phonemizer/lexicon_phonemizer.cpp +3 -4
  32. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/neural_phonemizer.cpp +17 -8
  33. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/neural_phonemizer.h +4 -0
  34. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/tokenizer.cpp +21 -6
  35. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/tokenizer.h +13 -4
  36. package/third-party/common/phonemis/src/phonemis/base/pipeline.cpp +8 -0
  37. package/third-party/common/phonemis/src/phonemis/base/pipeline.h +19 -0
  38. package/third-party/common/phonemis/src/phonemis/base/processor/common/conditions.cpp +37 -0
  39. package/third-party/common/phonemis/src/phonemis/base/processor/common/conditions.h +45 -0
  40. package/third-party/common/phonemis/src/phonemis/base/processor/common/constants.h +10 -0
  41. package/third-party/common/phonemis/src/phonemis/base/processor/common/context.cpp +105 -0
  42. package/third-party/common/phonemis/src/phonemis/base/processor/common/context.h +49 -0
  43. package/third-party/common/phonemis/src/phonemis/base/processor/common/document.cpp +173 -0
  44. package/third-party/common/phonemis/src/phonemis/base/processor/common/document.h +67 -0
  45. package/third-party/common/phonemis/src/phonemis/base/processor/common/text.cpp +75 -0
  46. package/third-party/common/phonemis/src/phonemis/base/processor/common/text.h +60 -0
  47. package/third-party/common/phonemis/src/phonemis/base/processor/common/types.h +18 -0
  48. package/third-party/common/phonemis/src/phonemis/base/processor/config.h +53 -0
  49. package/third-party/common/phonemis/src/phonemis/base/processor/layer.h +9 -7
  50. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/constants.h +20 -0
  51. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/layer.cpp +89 -0
  52. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/layer.h +35 -0
  53. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/types.h +16 -0
  54. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/kind.h +40 -0
  55. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/layer.h +382 -0
  56. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/notation.h +30 -0
  57. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/numerals.cpp +51 -0
  58. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/numerals.h +31 -0
  59. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern.h +30 -0
  60. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern_set.cpp +17 -0
  61. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern_set.h +31 -0
  62. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/patterns.cpp +811 -0
  63. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/patterns.h +285 -0
  64. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/primitives.cpp +64 -0
  65. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/primitives.h +23 -0
  66. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/types.h +94 -0
  67. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sanitizer/layer.cpp +19 -0
  68. package/third-party/common/phonemis/src/phonemis/base/processor/{sanitizer_layer.h → layers/sanitizer/layer.h} +8 -8
  69. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sym2word/layer.cpp +65 -0
  70. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sym2word/layer.h +29 -0
  71. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/layer.cpp +170 -0
  72. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/layer.h +40 -0
  73. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/types.h +25 -0
  74. package/third-party/common/phonemis/src/phonemis/base/processor/layers/trim/layer.cpp +47 -0
  75. package/third-party/common/phonemis/src/phonemis/base/processor/layers/trim/layer.h +19 -0
  76. package/third-party/common/phonemis/src/phonemis/base/processor/preprocessor.cpp +60 -0
  77. package/third-party/common/phonemis/src/phonemis/base/processor/preprocessor.h +45 -0
  78. package/third-party/common/phonemis/src/phonemis/base/processor/processor.cpp +6 -7
  79. package/third-party/common/phonemis/src/phonemis/base/processor/processor.h +14 -10
  80. package/third-party/common/phonemis/src/phonemis/base/tagger/hmm_tagger.cpp +89 -52
  81. package/third-party/common/phonemis/src/phonemis/base/tagger/hmm_tagger.h +16 -9
  82. package/third-party/common/phonemis/src/phonemis/base/tokenizer/tokenizer.cpp +13 -12
  83. package/third-party/common/phonemis/src/phonemis/lang/de/constants.h +183 -19
  84. package/third-party/common/phonemis/src/phonemis/lang/de/num2word.cpp +355 -309
  85. package/third-party/common/phonemis/src/phonemis/lang/de/num2word.h +42 -17
  86. package/third-party/common/phonemis/src/phonemis/lang/de/patterns.cpp +56 -0
  87. package/third-party/common/phonemis/src/phonemis/lang/de/patterns.h +15 -0
  88. package/third-party/common/phonemis/src/phonemis/lang/de/pipeline.h +3 -3
  89. package/third-party/common/phonemis/src/phonemis/lang/en/constants.h +181 -30
  90. package/third-party/common/phonemis/src/phonemis/lang/en/hmm_tagger.cpp +5 -7
  91. package/third-party/common/phonemis/src/phonemis/lang/en/num2word.cpp +232 -135
  92. package/third-party/common/phonemis/src/phonemis/lang/en/num2word.h +41 -16
  93. package/third-party/common/phonemis/src/phonemis/lang/en/pipeline.h +3 -10
  94. package/third-party/common/phonemis/src/phonemis/lang/es/constants.h +182 -60
  95. package/third-party/common/phonemis/src/phonemis/lang/es/num2word.cpp +247 -212
  96. package/third-party/common/phonemis/src/phonemis/lang/es/num2word.h +38 -18
  97. package/third-party/common/phonemis/src/phonemis/lang/es/patterns.cpp +50 -0
  98. package/third-party/common/phonemis/src/phonemis/lang/es/patterns.h +15 -0
  99. package/third-party/common/phonemis/src/phonemis/lang/es/pipeline.h +3 -3
  100. package/third-party/common/phonemis/src/phonemis/lang/fr/constants.h +152 -26
  101. package/third-party/common/phonemis/src/phonemis/lang/fr/num2word.cpp +252 -179
  102. package/third-party/common/phonemis/src/phonemis/lang/fr/num2word.h +38 -15
  103. package/third-party/common/phonemis/src/phonemis/lang/fr/patterns.cpp +83 -0
  104. package/third-party/common/phonemis/src/phonemis/lang/fr/patterns.h +15 -0
  105. package/third-party/common/phonemis/src/phonemis/lang/fr/pipeline.h +3 -3
  106. package/third-party/common/phonemis/src/phonemis/lang/hi/constants.h +62 -10
  107. package/third-party/common/phonemis/src/phonemis/lang/hi/num2word.cpp +74 -123
  108. package/third-party/common/phonemis/src/phonemis/lang/hi/num2word.h +27 -16
  109. package/third-party/common/phonemis/src/phonemis/lang/hi/pipeline.h +5 -3
  110. package/third-party/common/phonemis/src/phonemis/lang/it/constants.h +122 -42
  111. package/third-party/common/phonemis/src/phonemis/lang/it/num2word.cpp +200 -207
  112. package/third-party/common/phonemis/src/phonemis/lang/it/num2word.h +30 -18
  113. package/third-party/common/phonemis/src/phonemis/lang/it/patterns.cpp +25 -0
  114. package/third-party/common/phonemis/src/phonemis/lang/it/patterns.h +15 -0
  115. package/third-party/common/phonemis/src/phonemis/lang/it/pipeline.h +3 -3
  116. package/third-party/common/phonemis/src/phonemis/lang/pl/constants.h +346 -77
  117. package/third-party/common/phonemis/src/phonemis/lang/pl/num2word.cpp +631 -246
  118. package/third-party/common/phonemis/src/phonemis/lang/pl/num2word.h +47 -15
  119. package/third-party/common/phonemis/src/phonemis/lang/pl/pipeline.h +6 -6
  120. package/third-party/common/phonemis/src/phonemis/lang/pt/constants.h +201 -0
  121. package/third-party/common/phonemis/src/phonemis/lang/pt/num2word.cpp +365 -0
  122. package/third-party/common/phonemis/src/phonemis/lang/pt/num2word.h +53 -0
  123. package/third-party/common/phonemis/src/phonemis/lang/pt/pipeline.h +4 -2
  124. package/third-party/common/phonemis/src/phonemis/main.cpp +42 -11
  125. package/third-party/common/phonemis/src/phonemis/protophone/meta.h +24 -0
  126. package/third-party/common/phonemis/src/phonemis/protophone/numeric.h +26 -0
  127. package/third-party/common/phonemis/src/phonemis/protophone/protophone.cpp +525 -0
  128. package/third-party/common/phonemis/src/phonemis/protophone/protophone.h +80 -0
  129. package/third-party/common/phonemis/src/phonemis/protophone/tensor.h +76 -0
  130. package/third-party/common/phonemis/src/phonemis/protophone/tensor_utils.h +89 -0
  131. package/third-party/common/phonemis/src/phonemis/protophone/tensor_view.h +125 -0
  132. package/third-party/common/phonemis/src/phonemis/protophone/types.h +43 -0
  133. package/third-party/common/phonemis/src/phonemis/utils/strings.h +20 -14
  134. package/third-party/common/phonemis/src/phonemis/utils/unicode.h +15 -1
  135. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_arithmetic.hpp +267 -0
  136. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_bit.hpp +232 -0
  137. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_cast.hpp +43 -0
  138. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_complex.hpp +112 -0
  139. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_details.hpp +386 -0
  140. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_logical.hpp +240 -0
  141. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_math.hpp +2601 -0
  142. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_memory.hpp +1006 -0
  143. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_rounding.hpp +72 -0
  144. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_swizzle.hpp +260 -0
  145. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_trigo.hpp +996 -0
  146. package/third-party/common/phonemis/src/third-party/xsimd/arch/utils/shifts.hpp +82 -0
  147. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx.hpp +2111 -0
  148. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx2.hpp +1591 -0
  149. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx2_128.hpp +170 -0
  150. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512bw.hpp +724 -0
  151. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512cd.hpp +28 -0
  152. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512dq.hpp +270 -0
  153. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512er.hpp +17 -0
  154. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512f.hpp +2919 -0
  155. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512ifma.hpp +17 -0
  156. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512pf.hpp +17 -0
  157. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vbmi.hpp +76 -0
  158. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vbmi2.hpp +130 -0
  159. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vnni_avx512bw.hpp +17 -0
  160. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vnni_avx512vbmi2.hpp +17 -0
  161. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx_128.hpp +164 -0
  162. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avxvnni.hpp +17 -0
  163. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_common.hpp +26 -0
  164. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_common_fwd.hpp +127 -0
  165. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_constants.hpp +393 -0
  166. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_emulated.hpp +787 -0
  167. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_avx.hpp +93 -0
  168. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_avx2.hpp +46 -0
  169. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_sse.hpp +97 -0
  170. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma4.hpp +92 -0
  171. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_i8mm_neon64.hpp +17 -0
  172. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_isa.hpp +148 -0
  173. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_neon.hpp +3580 -0
  174. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_neon64.hpp +1614 -0
  175. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_rvv.hpp +1515 -0
  176. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_scalar.hpp +1210 -0
  177. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse2.hpp +2333 -0
  178. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse3.hpp +66 -0
  179. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse4_1.hpp +510 -0
  180. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse4_2.hpp +44 -0
  181. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_ssse3.hpp +186 -0
  182. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sve.hpp +1186 -0
  183. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_vsx.hpp +947 -0
  184. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_vxe.hpp +787 -0
  185. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_wasm.hpp +1819 -0
  186. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_arch.hpp +242 -0
  187. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_config.hpp +633 -0
  188. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features.hpp +50 -0
  189. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_arm.hpp +132 -0
  190. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_ppc.hpp +54 -0
  191. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_riscv.hpp +95 -0
  192. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_s390x.hpp +56 -0
  193. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_x86.hpp +1121 -0
  194. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpuid.hpp +144 -0
  195. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_getauxval.hpp +159 -0
  196. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_macros.hpp +78 -0
  197. package/third-party/common/phonemis/src/third-party/xsimd/math/xsimd_rem_pio2.hpp +707 -0
  198. package/third-party/common/phonemis/src/third-party/xsimd/memory/xsimd_aligned_allocator.hpp +349 -0
  199. package/third-party/common/phonemis/src/third-party/xsimd/memory/xsimd_alignment.hpp +102 -0
  200. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_all_registers.hpp +57 -0
  201. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_api.hpp +3106 -0
  202. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx2_register.hpp +57 -0
  203. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512bw_register.hpp +51 -0
  204. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512cd_register.hpp +51 -0
  205. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512dq_register.hpp +51 -0
  206. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512er_register.hpp +51 -0
  207. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512f_register.hpp +77 -0
  208. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512ifma_register.hpp +51 -0
  209. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512pf_register.hpp +51 -0
  210. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vbmi2_register.hpp +51 -0
  211. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vbmi_register.hpp +51 -0
  212. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vnni_avx512bw_register.hpp +54 -0
  213. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vnni_avx512vbmi2_register.hpp +53 -0
  214. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx_register.hpp +79 -0
  215. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avxvnni_register.hpp +44 -0
  216. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch.hpp +1666 -0
  217. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch_constant.hpp +572 -0
  218. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch_fwd.hpp +41 -0
  219. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_common_arch.hpp +49 -0
  220. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_emulated_register.hpp +80 -0
  221. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_avx2_register.hpp +50 -0
  222. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_avx_register.hpp +50 -0
  223. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_sse_register.hpp +50 -0
  224. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma4_register.hpp +50 -0
  225. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_i8mm_neon64_register.hpp +55 -0
  226. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_neon64_register.hpp +55 -0
  227. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_neon_register.hpp +130 -0
  228. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_register.hpp +96 -0
  229. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_rvv_register.hpp +491 -0
  230. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse2_register.hpp +59 -0
  231. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse3_register.hpp +49 -0
  232. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse4_1_register.hpp +48 -0
  233. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse4_2_register.hpp +48 -0
  234. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_ssse3_register.hpp +48 -0
  235. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sve_register.hpp +216 -0
  236. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_traits.hpp +409 -0
  237. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_utils.hpp +462 -0
  238. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_vsx_register.hpp +84 -0
  239. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_vxe_register.hpp +86 -0
  240. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_wasm_register.hpp +59 -0
  241. package/third-party/common/phonemis/src/third-party/xsimd/utils/bits.hpp +122 -0
  242. package/third-party/common/phonemis/src/third-party/xsimd/utils/xsimd_type_traits.hpp +145 -0
  243. package/third-party/common/phonemis/src/third-party/xsimd/xsimd.hpp +43 -0
  244. package/third-party/common/phonemis/src/phonemis/base/processor/constants.h +0 -11
  245. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/config.h +0 -16
  246. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/layer.cpp +0 -271
  247. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/layer.h +0 -45
  248. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/types.h +0 -29
  249. package/third-party/common/phonemis/src/phonemis/base/processor/sanitizer_layer.cpp +0 -22
  250. package/third-party/common/phonemis/src/phonemis/base/processor/trim_layer.cpp +0 -40
  251. package/third-party/common/phonemis/src/phonemis/base/processor/trim_layer.h +0 -22
@@ -0,0 +1,1515 @@
1
+ /***************************************************************************
2
+
3
+ * Copyright (c) Rivos Inc. *
4
+ * *
5
+ * Distributed under the terms of the BSD 3-Clause License. *
6
+ * *
7
+ * The full license is in the file LICENSE, distributed with this software. *
8
+ ****************************************************************************/
9
+
10
+ #ifndef XSIMD_RVV_HPP
11
+ #define XSIMD_RVV_HPP
12
+
13
+ #include <complex>
14
+ #include <type_traits>
15
+
16
+ #include "../config/xsimd_macros.hpp"
17
+ #include "../types/xsimd_batch_constant.hpp"
18
+ #include "../types/xsimd_rvv_register.hpp"
19
+ #include "../types/xsimd_utils.hpp"
20
+ #include "../utils/xsimd_type_traits.hpp"
21
+ #include "./xsimd_constants.hpp"
22
+
23
+ // This set of macros allows the synthesis of identifiers using a template and
24
+ // variable macro arguments. A single template can then be used by multiple
25
+ // macros, or multiple instances of a macro to define the same logic for
26
+ // different data types.
27
+ //
28
+ // First some logic to paste text together...
29
+ //
30
+ #define XSIMD_RVV_PREFIX_T(T, S, then) XSIMD_CONCAT(T, then)
31
+ #define XSIMD_RVV_PREFIX_S(T, S, then) XSIMD_CONCAT(S, then)
32
+ #define XSIMD_RVV_PREFIX_M(T, S, then) XSIMD_CONCAT(m1, then)
33
+ #define XSIMD_RVV_PREFIX(T, S, then) then
34
+ //
35
+ // XSIMD_RVV_IDENTIFIER accepts type and size parameters, and a template for
36
+ // the identifier. The template is a comma-separated list of alternating
37
+ // literal and parameter segments. Each parameter is appended to XSIMD_RVV_PREFIX to
38
+ // form a new macro name which decides which parameter should be inserted.
39
+ // Then a literal segment is inserted after that. Empty literals are used to
40
+ // join two or more variables together.
41
+ //
42
+ #define XSIMD_RVV_IDENTIFIER9(T, S, t, ...) t
43
+ #define XSIMD_RVV_IDENTIFIER8(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER9(T, S, __VA_ARGS__)))
44
+ #define XSIMD_RVV_IDENTIFIER7(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER8(T, S, __VA_ARGS__)))
45
+ #define XSIMD_RVV_IDENTIFIER6(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER7(T, S, __VA_ARGS__)))
46
+ #define XSIMD_RVV_IDENTIFIER5(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER6(T, S, __VA_ARGS__)))
47
+ #define XSIMD_RVV_IDENTIFIER4(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER5(T, S, __VA_ARGS__)))
48
+ #define XSIMD_RVV_IDENTIFIER3(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER4(T, S, __VA_ARGS__)))
49
+ #define XSIMD_RVV_IDENTIFIER2(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER3(T, S, __VA_ARGS__)))
50
+ #define XSIMD_RVV_IDENTIFIER1(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER2(T, S, __VA_ARGS__)))
51
+ #define XSIMD_RVV_IDENTIFIER0(T, S, t, p, ...) XSIMD_CONCAT(t, XSIMD_RVV_PREFIX##p(T, S, XSIMD_RVV_IDENTIFIER1(T, S, __VA_ARGS__)))
52
+ //
53
+ // UNBRACKET and REPARSE force the preprocessor to handle expansion in a
54
+ // specific order. XSIMD_RVV_UNBRACKET strips the parentheses from the template
55
+ // (which were necessary to keep the template as a single, named macro
56
+ // parameter up to this point). XSIMD_RVV_ARG_LIST then forms the new parameter list
57
+ // to pass to XSIMD_RVV_IDENTIFIER0, with trailing commas to ensure the unrolled
58
+ // XSIMD_RVV_IDENTIFIER loop runs to completion adding empty strings.
59
+ //
60
+ // However XSIMD_RVV_IDENTIFIER0 is not expanded immediately because it does not
61
+ // match a function-like macro in this pass. XSIMD_RVV_REPARSE forces another
62
+ // evaluation after the expansion of XSIMD_RVV_ARG_LIST, where XSIMD_RVV_IDENTIFIER0 will
63
+ // now match as a function-like macro, and the cycle of substitutions and
64
+ // insertions can begin.
65
+ //
66
+ #define XSIMD_RVV_REPARSE(v) (v)
67
+ #define XSIMD_RVV_UNBRACKET(...) __VA_ARGS__
68
+ #define XSIMD_RVV_ARG_LIST(T, S, name) (T, S, XSIMD_RVV_UNBRACKET name, , , , , , , , , , , , , , , , , , , , , )
69
+ #define XSIMD_RVV_IDENTIFIER(T, S, name) XSIMD_RVV_REPARSE(XSIMD_RVV_IDENTIFIER0 XSIMD_RVV_ARG_LIST(T, S, name))
70
+ //
71
+ // To avoid comma-counting bugs, replace the variable references with macros
72
+ // which include enough commas to keep proper phase, and then use no commas at
73
+ // all in the templates.
74
+ //
75
+ #define XSIMD_RVV_T , _T,
76
+ #define XSIMD_RVV_S , _S,
77
+ #define XSIMD_RVV_M , _M,
78
+ #define XSIMD_RVV_TSM XSIMD_RVV_T XSIMD_RVV_S XSIMD_RVV_M
79
+
80
+ // XSIMD_RVV_OVERLOAD, below, expands to a head section, a number of body sections
81
+ // (depending on which types are supported), and a tail section. Different
82
+ // variants of these sections are implemented with different suffixes on the
83
+ // three macro names XSIMD_RVV_WRAPPER_HEAD, XSIMD_RVV_WRAPPER, and XSIMD_RVV_WRAPPER_TAIL and
84
+ // specified as an argument to XSIMD_RVV_OVERLOAD (the empty string is the default,
85
+ // but still needs an extra comma to hold its place).
86
+ //
87
+ // The default XSIMD_RVV_WRAPPER_HEAD provides a class containing convenient names
88
+ // for the function signature argument(s) to XSIMD_RVV_OVERLOAD. That signature can
89
+ // also reference the template argument T, because it's a text substitution
90
+ // into the template.
91
+ #define XSIMD_RVV_WRAPPER_HEAD(NAME, SIGNATURE, ...) \
92
+ namespace NAME##_cruft \
93
+ { \
94
+ template <class T> \
95
+ struct ctx \
96
+ { \
97
+ static constexpr size_t width = XSIMD_RVV_BITS; \
98
+ static constexpr size_t vl = width / (sizeof(T) * 8); \
99
+ using vec = rvv_reg_t<T, width>; \
100
+ using uvec = rvv_reg_t<xsimd::sized_uint_t<sizeof(T)>, width>; \
101
+ using svec = rvv_reg_t<xsimd::sized_int_t<sizeof(T)>, width>; \
102
+ using fvec = rvv_reg_t<as_float_relaxed_t<T>, width>; \
103
+ using bvec = rvv_bool_t<T, width>; \
104
+ using scalar_vec = rvv_reg_t<T, types::detail::rvv_width_m1>; \
105
+ using wide_vec = rvv_reg_t<T, width * 2>; \
106
+ using narrow_vec = rvv_reg_t<T, width / 2>; \
107
+ using type = SIGNATURE; \
108
+ }; \
109
+ template <class T> \
110
+ using sig_t = typename ctx<T>::type; \
111
+ template <class K, class T> \
112
+ struct impl \
113
+ { \
114
+ void operator()() const noexcept {}; \
115
+ }; \
116
+ template <class K> \
117
+ using impl_t = impl<K, sig_t<K>>;
118
+
119
+ #define XSIMD_RVV_WRAPPER_HEAD_NOVL(...) XSIMD_RVV_WRAPPER_HEAD(__VA_ARGS__)
120
+ #define XSIMD_RVV_WRAPPER_HEAD_DROP_1ST(...) XSIMD_RVV_WRAPPER_HEAD(__VA_ARGS__)
121
+ #define XSIMD_RVV_WRAPPER_HEAD_DROP_1ST_CUSTOM_ARGS(...) XSIMD_RVV_WRAPPER_HEAD(__VA_ARGS__)
122
+ #define XSIMD_RVV_WRAPPER_HEAD_DROP_1ST_CUSTOM_ARGS_NOVL(...) XSIMD_RVV_WRAPPER_HEAD(__VA_ARGS__)
123
+
124
+ // The body of the wrapper defines a functor (because partial specialisation of
125
+ // functions is not legal) which forwards its arguments to the named intrinsic
126
+ // with a few manipulations. In general, vector types are handled as
127
+ // rvv_reg_t<> and rely on the conversion operators in that class for
128
+ // compatibility with the intrinsics.
129
+ //
130
+ // The function signature is not mentioned here. Instead it's provided in the
131
+ // tail code as the template argument for which this is a specialisation, which
132
+ // overcomes the problem of converting a function signature type to an argument
133
+ // list to pass to another function.
134
+ //
135
+ #define XSIMD_RVV_WRAPPER(KEY, CALLEE, ...) \
136
+ template <class Ret, class... Args> \
137
+ struct impl<KEY, Ret(Args...)> \
138
+ { \
139
+ constexpr Ret operator()(Args... args) const noexcept \
140
+ { \
141
+ return CALLEE(args..., ctx<KEY>::vl); \
142
+ }; \
143
+ };
144
+ #define XSIMD_RVV_WRAPPER_NOVL(KEY, CALLEE, ...) \
145
+ template <class Ret, class... Args> \
146
+ struct impl<KEY, Ret(Args...)> \
147
+ { \
148
+ constexpr Ret operator()(Args... args) const noexcept \
149
+ { \
150
+ return CALLEE(args...); \
151
+ }; \
152
+ };
153
+ #define XSIMD_RVV_WRAPPER_DROP_1ST(KEY, CALLEE, ...) \
154
+ template <class Ret, class First, class... Args> \
155
+ struct impl<KEY, Ret(First, Args...)> \
156
+ { \
157
+ constexpr Ret operator()(First, Args... args) const noexcept \
158
+ { \
159
+ return CALLEE(args..., ctx<KEY>::vl); \
160
+ }; \
161
+ };
162
+ #define XSIMD_RVV_WRAPPER_DROP_1ST_CUSTOM_ARGS(KEY, CALLEE, SIGNATURE, ...) \
163
+ template <class Ret, class First, class... Args> \
164
+ struct impl<KEY, Ret(First, Args...)> \
165
+ { \
166
+ constexpr Ret operator()(First, Args... args) const noexcept \
167
+ { \
168
+ return CALLEE(__VA_ARGS__, ctx<KEY>::vl); \
169
+ }; \
170
+ };
171
+ #define XSIMD_RVV_WRAPPER_DROP_1ST_CUSTOM_ARGS_NOVL(KEY, CALLEE, SIGNATURE, ...) \
172
+ template <class Ret, class First, class... Args> \
173
+ struct impl<KEY, Ret(First, Args...)> \
174
+ { \
175
+ constexpr Ret operator()(First, Args... args) const noexcept \
176
+ { \
177
+ return CALLEE(__VA_ARGS__); \
178
+ }; \
179
+ };
180
+
181
+ // This part folds all the above templates down into a single functor instance
182
+ // with all the different function signatures available under the one name.
183
+ // Not all of the base classes necessarily contain useful code, but there's a
184
+ // default implementation so that filtering them out isn't really necessary.
185
+ #define XSIMD_RVV_WRAPPER_TAIL(NAME, ...) \
186
+ } /* namespace NAME##_cruft */ \
187
+ static constexpr struct : NAME##_cruft::impl_t<int8_t>, \
188
+ NAME##_cruft::impl_t<uint8_t>, \
189
+ NAME##_cruft::impl_t<int16_t>, \
190
+ NAME##_cruft::impl_t<uint16_t>, \
191
+ NAME##_cruft::impl_t<int32_t>, \
192
+ NAME##_cruft::impl_t<uint32_t>, \
193
+ NAME##_cruft::impl_t<int64_t>, \
194
+ NAME##_cruft::impl_t<uint64_t>, \
195
+ NAME##_cruft::impl_t<float>, \
196
+ NAME##_cruft::impl_t<double> \
197
+ { \
198
+ using NAME##_cruft::impl_t<int8_t>::operator(); \
199
+ using NAME##_cruft::impl_t<uint8_t>::operator(); \
200
+ using NAME##_cruft::impl_t<int16_t>::operator(); \
201
+ using NAME##_cruft::impl_t<uint16_t>::operator(); \
202
+ using NAME##_cruft::impl_t<int32_t>::operator(); \
203
+ using NAME##_cruft::impl_t<uint32_t>::operator(); \
204
+ using NAME##_cruft::impl_t<int64_t>::operator(); \
205
+ using NAME##_cruft::impl_t<uint64_t>::operator(); \
206
+ using NAME##_cruft::impl_t<float>::operator(); \
207
+ using NAME##_cruft::impl_t<double>::operator(); \
208
+ } NAME {};
209
+ #define XSIMD_RVV_WRAPPER_TAIL_NOVL(...) XSIMD_RVV_WRAPPER_TAIL(__VA_ARGS__)
210
+ #define XSIMD_RVV_WRAPPER_TAIL_DROP_1ST(...) XSIMD_RVV_WRAPPER_TAIL(__VA_ARGS__)
211
+ #define XSIMD_RVV_WRAPPER_TAIL_DROP_1ST_CUSTOM_ARGS(...) XSIMD_RVV_WRAPPER_TAIL(__VA_ARGS__)
212
+ #define XSIMD_RVV_WRAPPER_TAIL_DROP_1ST_CUSTOM_ARGS_NOVL(...) XSIMD_RVV_WRAPPER_TAIL(__VA_ARGS__)
213
+
214
+ // clang-format off
215
+
216
+ #define XSIMD_RVV_OVERLOAD_head(my_name, variant, ...) \
217
+ XSIMD_RVV_WRAPPER_HEAD##variant(my_name, __VA_ARGS__)
218
+ #define XSIMD_RVV_OVERLOAD_i(name, variant, ...) \
219
+ XSIMD_RVV_WRAPPER##variant(int8_t, XSIMD_RVV_IDENTIFIER(i, 8, name), __VA_ARGS__) \
220
+ XSIMD_RVV_WRAPPER##variant(int16_t, XSIMD_RVV_IDENTIFIER(i, 16, name), __VA_ARGS__) \
221
+ XSIMD_RVV_WRAPPER##variant(int32_t, XSIMD_RVV_IDENTIFIER(i, 32, name), __VA_ARGS__) \
222
+ XSIMD_RVV_WRAPPER##variant(int64_t, XSIMD_RVV_IDENTIFIER(i, 64, name), __VA_ARGS__)
223
+ #define XSIMD_RVV_OVERLOAD_u(name, variant, ...) \
224
+ XSIMD_RVV_WRAPPER##variant(uint8_t, XSIMD_RVV_IDENTIFIER(u, 8, name), __VA_ARGS__) \
225
+ XSIMD_RVV_WRAPPER##variant(uint16_t, XSIMD_RVV_IDENTIFIER(u, 16, name), __VA_ARGS__) \
226
+ XSIMD_RVV_WRAPPER##variant(uint32_t, XSIMD_RVV_IDENTIFIER(u, 32, name), __VA_ARGS__) \
227
+ XSIMD_RVV_WRAPPER##variant(uint64_t, XSIMD_RVV_IDENTIFIER(u, 64, name), __VA_ARGS__)
228
+ #define XSIMD_RVV_OVERLOAD_f(name, variant, ...) \
229
+ XSIMD_RVV_WRAPPER##variant(float, XSIMD_RVV_IDENTIFIER(f, 32, name), __VA_ARGS__) \
230
+ XSIMD_RVV_WRAPPER##variant(double, XSIMD_RVV_IDENTIFIER(f, 64, name), __VA_ARGS__)
231
+ #define XSIMD_RVV_OVERLOAD_tail(my_name, variant, ...) \
232
+ XSIMD_RVV_WRAPPER_TAIL##variant(my_name, __VA_ARGS__)
233
+
234
+ // Use these to create function (actually functor, sorry) wrappers overloaded
235
+ // for whichever types are supported. Being functors means they can't take a
236
+ // template argument (until C++14), so if a type can't be deduced then a junk
237
+ // value can be passed as the first argument and discarded by using the
238
+ // _DROP_1ST variant, instead.
239
+ //
240
+ // The wrappers use the rvv_reg_t<> types for template accessibility, and
241
+ // because some types (eg., vfloat64mf2_t) don't exist and need extra
242
+ // abstraction to emulate.
243
+ //
244
+ // In many cases the intrinsic names are different for signed, unsigned, or
245
+ // float variants, the macros OVERLOAD2 and OVERLOAD3 (depending on whether or
246
+ // not a float variant exists) take multiple intrinsic names and bring them
247
+ // together under a single overloaded identifier where they can be used within
248
+ // templates.
249
+ //
250
+ #define XSIMD_RVV_OVERLOAD2(my_name, name_i, name_u, variant, ...) \
251
+ XSIMD_RVV_OVERLOAD_head(my_name, variant, __VA_ARGS__) \
252
+ XSIMD_RVV_OVERLOAD_i(name_i, variant, __VA_ARGS__) \
253
+ XSIMD_RVV_OVERLOAD_u(name_u, variant, __VA_ARGS__) \
254
+ XSIMD_RVV_OVERLOAD_tail(my_name, variant, __VA_ARGS__)
255
+
256
+ #define XSIMD_RVV_OVERLOAD3(my_name, name_i, name_u, name_f, variant, ...) \
257
+ XSIMD_RVV_OVERLOAD_head(my_name, variant, __VA_ARGS__) \
258
+ XSIMD_RVV_OVERLOAD_i(name_i, variant, __VA_ARGS__) \
259
+ XSIMD_RVV_OVERLOAD_u(name_u, variant, __VA_ARGS__) \
260
+ XSIMD_RVV_OVERLOAD_f(name_f, variant, __VA_ARGS__) \
261
+ XSIMD_RVV_OVERLOAD_tail(my_name, variant, __VA_ARGS__)
262
+
263
+ #define XSIMD_RVV_OVERLOAD(my_name, name, ...) XSIMD_RVV_OVERLOAD3(my_name, name, name, name, __VA_ARGS__)
264
+ #define XSIMD_RVV_OVERLOAD_INTS(my_name, name, ...) XSIMD_RVV_OVERLOAD2(my_name, name, name, __VA_ARGS__)
265
+
266
+ #define XSIMD_RVV_OVERLOAD_SINTS(my_name, name, variant, ...) \
267
+ XSIMD_RVV_OVERLOAD_head(my_name, variant, __VA_ARGS__) \
268
+ XSIMD_RVV_OVERLOAD_i(name, variant, __VA_ARGS__) \
269
+ XSIMD_RVV_OVERLOAD_tail(my_name, variant, __VA_ARGS__)
270
+
271
+ #define XSIMD_RVV_OVERLOAD_UINTS(my_name, name, variant, ...) \
272
+ XSIMD_RVV_OVERLOAD_head(my_name, variant, __VA_ARGS__) \
273
+ XSIMD_RVV_OVERLOAD_u(name, variant, __VA_ARGS__) \
274
+ XSIMD_RVV_OVERLOAD_tail(my_name, variant, __VA_ARGS__)
275
+
276
+ #define XSIMD_RVV_OVERLOAD_FLOATS(my_name, name, variant, ...) \
277
+ XSIMD_RVV_OVERLOAD_head(my_name, variant, __VA_ARGS__) \
278
+ XSIMD_RVV_OVERLOAD_f(name, variant, __VA_ARGS__) \
279
+ XSIMD_RVV_OVERLOAD_tail(my_name, variant, __VA_ARGS__)
280
+
281
+ // clang-format on
282
+
283
+ namespace xsimd
284
+ {
285
+ template <typename T, class A, T... Values>
286
+ struct batch_constant;
287
+
288
+ namespace kernel
289
+ {
290
+ namespace detail_rvv
291
+ {
292
+ template <class T, size_t Width = XSIMD_RVV_BITS>
293
+ using rvv_reg_t = types::detail::rvv_reg_t<T, Width>;
294
+ template <class T, size_t Width = XSIMD_RVV_BITS>
295
+ using rvv_bool_t = types::detail::rvv_bool_t<T, Width>;
296
+
297
+ template <std::size_t S>
298
+ struct as_float_relaxed
299
+ {
300
+ using type = xsimd::sized_fp_t<S>;
301
+ };
302
+ template <>
303
+ struct as_float_relaxed<1>
304
+ {
305
+ using type = int8_t;
306
+ };
307
+ template <>
308
+ struct as_float_relaxed<2>
309
+ {
310
+ using type = int16_t;
311
+ };
312
+ template <class T>
313
+ using as_float_relaxed_t = typename as_float_relaxed<sizeof(T)>::type;
314
+
315
+ template <class T, class U>
316
+ XSIMD_INLINE rvv_reg_t<T, U::width> rvvreinterpret(U const& arg) noexcept
317
+ {
318
+ return rvv_reg_t<T, U::width>(arg, types::detail::XSIMD_RVV_BITCAST);
319
+ }
320
+ template <class T, class A, class U>
321
+ XSIMD_INLINE rvv_reg_t<T, A::width> rvvreinterpret(batch<U, A> const& arg) noexcept
322
+ {
323
+ typename batch<U, A>::register_type r = arg;
324
+ return rvvreinterpret<T>(r);
325
+ }
326
+
327
+ template <class A, class T, class U = as_unsigned_integer_t<T>>
328
+ XSIMD_INLINE batch<U, A> rvv_to_unsigned_batch(batch<T, A> const& arg) noexcept
329
+ {
330
+ return rvvreinterpret<U>(arg.data);
331
+ }
332
+
333
+ XSIMD_RVV_OVERLOAD(rvvid,
334
+ (__riscv_vid_v_u XSIMD_RVV_S XSIMD_RVV_M), _DROP_1ST, uvec(T))
335
+
336
+ XSIMD_RVV_OVERLOAD3(rvvmv_splat,
337
+ (__riscv_vmv_v_x_ XSIMD_RVV_TSM),
338
+ (__riscv_vmv_v_x_ XSIMD_RVV_TSM),
339
+ (__riscv_vfmv_v_f_ XSIMD_RVV_TSM), , vec(T))
340
+
341
+ XSIMD_RVV_OVERLOAD3(rvvmv_lane0,
342
+ (__riscv_vmv_x),
343
+ (__riscv_vmv_x),
344
+ (__riscv_vfmv_f), _NOVL, T(vec))
345
+
346
+ XSIMD_RVV_OVERLOAD(rvvmerge, (__riscv_vmerge), , vec(vec, vec, bvec))
347
+ XSIMD_RVV_OVERLOAD3(rvvmerge_splat,
348
+ (__riscv_vmerge),
349
+ (__riscv_vmerge),
350
+ (__riscv_vfmerge), , vec(vec, T, bvec))
351
+
352
+ // count active lanes in a predicate
353
+ XSIMD_RVV_OVERLOAD(rvvcpop, (__riscv_vcpop),
354
+ , size_t(bvec));
355
+
356
+ template <class T, size_t Width>
357
+ XSIMD_INLINE rvv_bool_t<T, Width> pmask8(uint8_t mask) noexcept
358
+ {
359
+ return rvv_bool_t<T, Width>(mask);
360
+ }
361
+ template <class T, size_t Width>
362
+ XSIMD_INLINE rvv_bool_t<T, Width> pmask(uint64_t mask) noexcept
363
+ {
364
+ return rvv_bool_t<T, Width>(mask);
365
+ }
366
+
367
+ template <class A, class T, size_t offset = 0, int shift = 0>
368
+ XSIMD_INLINE rvv_reg_t<T, A::width> vindex() noexcept
369
+ {
370
+ auto index = rvvid(T {});
371
+ if (shift < 0)
372
+ index = __riscv_vsrl(index, -shift, batch<T, A>::size);
373
+ else
374
+ index = __riscv_vsll(index, shift, batch<T, A>::size);
375
+ return __riscv_vadd(index, T(offset), batch<T, A>::size);
376
+ }
377
+ } // namespace detail
378
+
379
+ /********************
380
+ * Scalar to vector *
381
+ ********************/
382
+
383
+ namespace detail_rvv
384
+ {
385
+ template <class T, size_t Width>
386
+ XSIMD_INLINE rvv_reg_t<T, Width> broadcast(T arg) noexcept
387
+ {
388
+ // A bit of a dance, here, because rvvmv_splat has no other
389
+ // argument from which to deduce type, and T=char is not
390
+ // supported.
391
+ map_to_sized_type_t<T> arg_not_char(arg);
392
+ const auto splat = rvvmv_splat(arg_not_char);
393
+ return rvv_reg_t<T, Width>(splat.get_bytes(), types::detail::XSIMD_RVV_BITCAST);
394
+ }
395
+ }
396
+
397
+ // broadcast
398
+ template <class A, class T>
399
+ XSIMD_INLINE batch<T, A> broadcast(T arg, requires_arch<rvv>) noexcept
400
+ {
401
+ return detail_rvv::broadcast<T, A::width>(arg);
402
+ }
403
+
404
+ /*********
405
+ * Load *
406
+ *********/
407
+
408
+ namespace detail_rvv
409
+ {
410
+ XSIMD_RVV_OVERLOAD(rvvle, (__riscv_vle XSIMD_RVV_S _v_ XSIMD_RVV_TSM), , vec(T const*))
411
+ XSIMD_RVV_OVERLOAD(rvvse, (__riscv_vse XSIMD_RVV_S _v_ XSIMD_RVV_TSM), , void(T*, vec))
412
+ }
413
+
414
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
415
+ XSIMD_INLINE batch<T, A> load_aligned(T const* src, convert<T>, requires_arch<rvv>) noexcept
416
+ {
417
+ return detail_rvv::rvvle(reinterpret_cast<map_to_sized_type_t<T> const*>(src));
418
+ }
419
+
420
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
421
+ XSIMD_INLINE batch<T, A> load_unaligned(T const* src, convert<T>, requires_arch<rvv>) noexcept
422
+ {
423
+ return load_aligned<A>(src, convert<T>(), rvv {});
424
+ }
425
+
426
+ // load_complex
427
+ namespace detail_rvv
428
+ {
429
+ template <class T, size_t W, std::enable_if_t<W >= types::detail::rvv_width_m1, int> = 0>
430
+ XSIMD_INLINE rvv_reg_t<T, W * 2> rvvabut(rvv_reg_t<T, W> const& lo, rvv_reg_t<T, W> const& hi) noexcept
431
+ {
432
+ typename rvv_reg_t<T, W * 2>::register_type tmp;
433
+ tmp = __riscv_vset(tmp, 0, lo);
434
+ return __riscv_vset(tmp, 1, hi);
435
+ }
436
+
437
+ template <class T, size_t W, std::enable_if_t<W<types::detail::rvv_width_m1, int> = 0> XSIMD_INLINE rvv_reg_t<T, W * 2> rvvabut(rvv_reg_t<T, W> const& lo, rvv_reg_t<T, W> const& hi) noexcept
438
+ {
439
+ return __riscv_vslideup(lo, hi, lo.vl, lo.vl * 2);
440
+ }
441
+
442
+ XSIMD_RVV_OVERLOAD(rvvget_lo_, (__riscv_vget_ XSIMD_RVV_TSM), _DROP_1ST_CUSTOM_ARGS_NOVL, vec(T, wide_vec), args..., 0)
443
+ XSIMD_RVV_OVERLOAD(rvvget_hi_, (__riscv_vget_ XSIMD_RVV_TSM), _DROP_1ST_CUSTOM_ARGS_NOVL, vec(T, wide_vec), args..., 1)
444
+
445
+ template <class T, size_t W, std::enable_if_t<W >= types::detail::rvv_width_m1, int> = 0>
446
+ XSIMD_INLINE rvv_reg_t<T, W> rvvget_lo(rvv_reg_t<T, W * 2> const& vv) noexcept
447
+ {
448
+ typename rvv_reg_t<T, W>::register_type tmp = rvvget_lo_(T {}, vv);
449
+ return tmp;
450
+ }
451
+ template <class T, size_t W, std::enable_if_t<W >= types::detail::rvv_width_m1, int> = 0>
452
+ XSIMD_INLINE rvv_reg_t<T, W> rvvget_hi(rvv_reg_t<T, W * 2> const& vv) noexcept
453
+ {
454
+ typename rvv_reg_t<T, W>::register_type tmp = rvvget_hi_(T {}, vv);
455
+ return tmp;
456
+ }
457
+ template <class T, size_t W, std::enable_if_t<W<types::detail::rvv_width_m1, int> = 0> XSIMD_INLINE rvv_reg_t<T, W> rvvget_lo(rvv_reg_t<T, W * 2> const& vv) noexcept
458
+ {
459
+ typename rvv_reg_t<T, W>::register_type tmp = vv;
460
+ return tmp;
461
+ }
462
+ template <class T, size_t W, std::enable_if_t<W<types::detail::rvv_width_m1, int> = 0> XSIMD_INLINE rvv_reg_t<T, W> rvvget_hi(rvv_reg_t<T, W * 2> const& vv) noexcept
463
+ {
464
+ return __riscv_vslidedown(vv, vv.vl / 2, vv.vl);
465
+ }
466
+
467
+ }
468
+
469
+ // Must be in detail::load_complex for use by common memory.
470
+ // ODR violation are prevented because the size of the register is encoded
471
+ // in batch.
472
+ namespace detail
473
+ {
474
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
475
+ XSIMD_INLINE batch<std::complex<T>, A> load_complex(batch<T, A> const& lo, batch<T, A> const& hi, requires_arch<rvv>) noexcept
476
+ {
477
+ const auto real_index = detail_rvv::vindex<A, as_unsigned_integer_t<T>, 0, 1>();
478
+ const auto imag_index = detail_rvv::vindex<A, as_unsigned_integer_t<T>, 1, 1>();
479
+ const auto index = detail_rvv::rvvabut<as_unsigned_integer_t<T>, A::width>(real_index, imag_index);
480
+ const auto input = detail_rvv::rvvabut<T, A::width>(lo.data, hi.data);
481
+ const detail_rvv::rvv_reg_t<T, A::width * 2> result = __riscv_vrgather(input, index, index.vl);
482
+
483
+ return { detail_rvv::rvvget_lo<T, A::width>(result), detail_rvv::rvvget_hi<T, A::width>(result) };
484
+ }
485
+ }
486
+
487
+ /*********
488
+ * Store *
489
+ *********/
490
+
491
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
492
+ XSIMD_INLINE void store_aligned(T* dst, batch<T, A> const& src, requires_arch<rvv>) noexcept
493
+ {
494
+ detail_rvv::rvvse(reinterpret_cast<map_to_sized_type_t<T>*>(dst), src);
495
+ }
496
+
497
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
498
+ XSIMD_INLINE void store_unaligned(T* dst, batch<T, A> const& src, requires_arch<rvv>) noexcept
499
+ {
500
+ store_aligned<A>(dst, src, rvv {});
501
+ }
502
+
503
+ /******************
504
+ * scatter/gather *
505
+ ******************/
506
+
507
+ namespace detail_rvv
508
+ {
509
+ template <class T, class U>
510
+ using rvv_enable_sg_t = std::enable_if_t<(sizeof(T) == sizeof(U) && (sizeof(T) == 4 || sizeof(T) == 8)), int>;
511
+ XSIMD_RVV_OVERLOAD(rvvloxei, (__riscv_vloxei XSIMD_RVV_S), , vec(T const*, uvec))
512
+ XSIMD_RVV_OVERLOAD(rvvsoxei, (__riscv_vsoxei XSIMD_RVV_S), , void(T*, uvec, vec))
513
+ XSIMD_RVV_OVERLOAD3(rvvmul_splat,
514
+ (__riscv_vmul),
515
+ (__riscv_vmul),
516
+ (__riscv_vfmul), , vec(vec, T))
517
+ }
518
+
519
+ // scatter
520
+ template <class A, class T, class U, detail_rvv::rvv_enable_sg_t<T, U> = 0>
521
+ XSIMD_INLINE void scatter(batch<T, A> const& vals, T* dst, batch<U, A> const& index, kernel::requires_arch<rvv>) noexcept
522
+ {
523
+ using UU = as_unsigned_integer_t<U>;
524
+ const auto uindex = detail_rvv::rvv_to_unsigned_batch(index);
525
+ auto* base = reinterpret_cast<map_to_sized_type_t<T>*>(dst);
526
+ // or rvvsuxei
527
+ const auto bi = detail_rvv::rvvmul_splat(uindex, sizeof(T));
528
+ detail_rvv::rvvsoxei(base, bi, vals);
529
+ }
530
+
531
+ // gather
532
+ template <class A, class T, class U, detail_rvv::rvv_enable_sg_t<T, U> = 0>
533
+ XSIMD_INLINE batch<T, A> gather(batch<T, A> const&, T const* src, batch<U, A> const& index, kernel::requires_arch<rvv>) noexcept
534
+ {
535
+ using UU = as_unsigned_integer_t<U>;
536
+ const auto uindex = detail_rvv::rvv_to_unsigned_batch(index);
537
+ auto const* base = reinterpret_cast<map_to_sized_type_t<T> const*>(src);
538
+ // or rvvluxei
539
+ const auto bi = detail_rvv::rvvmul_splat(uindex, sizeof(T));
540
+ return detail_rvv::rvvloxei(base, bi);
541
+ }
542
+
543
+ /**************
544
+ * Arithmetic *
545
+ **************/
546
+
547
+ namespace detail_rvv
548
+ {
549
+ XSIMD_RVV_OVERLOAD3(rvvadd,
550
+ (__riscv_vadd),
551
+ (__riscv_vadd),
552
+ (__riscv_vfadd), , vec(vec, vec))
553
+ XSIMD_RVV_OVERLOAD2(rvvsadd,
554
+ (__riscv_vsadd),
555
+ (__riscv_vsaddu), , vec(vec, vec))
556
+ XSIMD_RVV_OVERLOAD3(rvvsub,
557
+ (__riscv_vsub),
558
+ (__riscv_vsub),
559
+ (__riscv_vfsub), , vec(vec, vec))
560
+ XSIMD_RVV_OVERLOAD2(rvvssub,
561
+ (__riscv_vssub),
562
+ (__riscv_vssubu), , vec(vec, vec))
563
+ XSIMD_RVV_OVERLOAD2(rvvaadd,
564
+ (__riscv_vaadd),
565
+ (__riscv_vaaddu), , vec(vec, vec))
566
+ XSIMD_RVV_OVERLOAD3(rvvmul,
567
+ (__riscv_vmul),
568
+ (__riscv_vmul),
569
+ (__riscv_vfmul), , vec(vec, vec))
570
+ XSIMD_RVV_OVERLOAD3(rvvdiv,
571
+ (__riscv_vdiv),
572
+ (__riscv_vdivu),
573
+ (__riscv_vfdiv), , vec(vec, vec))
574
+ XSIMD_RVV_OVERLOAD3(rvvmax,
575
+ (__riscv_vmax),
576
+ (__riscv_vmaxu),
577
+ (__riscv_vfmax), , vec(vec, vec))
578
+ XSIMD_RVV_OVERLOAD3(rvvmin,
579
+ (__riscv_vmin),
580
+ (__riscv_vminu),
581
+ (__riscv_vfmin), , vec(vec, vec))
582
+ XSIMD_RVV_OVERLOAD3(rvvneg,
583
+ (__riscv_vneg),
584
+ (abort),
585
+ (__riscv_vfneg), , vec(vec))
586
+ XSIMD_RVV_OVERLOAD_FLOATS(rvvabs,
587
+ (__riscv_vfabs), , vec(vec))
588
+ XSIMD_RVV_OVERLOAD3(rvvmacc,
589
+ (__riscv_vmacc),
590
+ (__riscv_vmacc),
591
+ (__riscv_vfmacc), , vec(vec, vec, vec))
592
+ XSIMD_RVV_OVERLOAD3(rvvnmsac,
593
+ (__riscv_vnmsac),
594
+ (__riscv_vnmsac),
595
+ (__riscv_vfnmsac), , vec(vec, vec, vec))
596
+ XSIMD_RVV_OVERLOAD3(rvvmadd,
597
+ (__riscv_vmadd),
598
+ (__riscv_vmadd),
599
+ (__riscv_vfmadd), , vec(vec, vec, vec))
600
+ XSIMD_RVV_OVERLOAD3(rvvnmsub,
601
+ (__riscv_vnmsub),
602
+ (__riscv_vnmsub),
603
+ (__riscv_vfnmsub), , vec(vec, vec, vec))
604
+
605
+ #define RISCV_VMSXX(XX) \
606
+ XSIMD_RVV_OVERLOAD3(rvvms##XX, \
607
+ (__riscv_vms##XX), \
608
+ (__riscv_vms##XX##u), \
609
+ (__riscv_vmf##XX), , bvec(vec, vec)) \
610
+ XSIMD_RVV_OVERLOAD3(rvvms##XX##_splat, \
611
+ (__riscv_vms##XX), \
612
+ (__riscv_vms##XX##u), \
613
+ (__riscv_vmf##XX), , bvec(vec, T))
614
+ #define __riscv_vmsequ __riscv_vmseq
615
+ #define __riscv_vmsneu __riscv_vmsne
616
+ RISCV_VMSXX(eq)
617
+ RISCV_VMSXX(ne)
618
+ RISCV_VMSXX(lt)
619
+ RISCV_VMSXX(le)
620
+ RISCV_VMSXX(gt)
621
+ RISCV_VMSXX(ge)
622
+ #undef __riscv_vmsequ
623
+ #undef __riscv_vmsneu
624
+ #undef RISCV_VMSXX
625
+ } // namespace detail
626
+
627
+ // add
628
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
629
+ XSIMD_INLINE batch<T, A> add(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
630
+ {
631
+ return detail_rvv::rvvadd(lhs, rhs);
632
+ }
633
+
634
+ // sadd
635
+ template <class A, class T, detail::enable_integral_t<T> = 0>
636
+ XSIMD_INLINE batch<T, A> sadd(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
637
+ {
638
+ return detail_rvv::rvvsadd(lhs, rhs);
639
+ }
640
+
641
+ // sub
642
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
643
+ XSIMD_INLINE batch<T, A> sub(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
644
+ {
645
+ return detail_rvv::rvvsub(lhs, rhs);
646
+ }
647
+
648
+ // ssub
649
+ template <class A, class T, detail::enable_integral_t<T> = 0>
650
+ XSIMD_INLINE batch<T, A> ssub(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
651
+ {
652
+ return detail_rvv::rvvssub(lhs, rhs);
653
+ }
654
+
655
+ // mul
656
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
657
+ XSIMD_INLINE batch<T, A> mul(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
658
+ {
659
+ return detail_rvv::rvvmul(lhs, rhs);
660
+ }
661
+
662
+ // div
663
+ template <class A, class T, typename detail::enable_arithmetic_t<T> = 0>
664
+ XSIMD_INLINE batch<T, A> div(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
665
+ {
666
+ return detail_rvv::rvvdiv(lhs, rhs);
667
+ }
668
+
669
+ // max
670
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
671
+ XSIMD_INLINE batch<T, A> max(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
672
+ {
673
+ return detail_rvv::rvvmax(lhs, rhs);
674
+ }
675
+
676
+ // min
677
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
678
+ XSIMD_INLINE batch<T, A> min(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
679
+ {
680
+ return detail_rvv::rvvmin(lhs, rhs);
681
+ }
682
+
683
+ // neg
684
+ template <class A, class T, detail::enable_unsigned_integral_t<T> = 0>
685
+ XSIMD_INLINE batch<T, A> neg(batch<T, A> const& arg, requires_arch<rvv>) noexcept
686
+ {
687
+ using S = as_signed_integer_t<T>;
688
+ const auto as_signed = detail_rvv::rvvreinterpret<S>(arg);
689
+ const auto result = detail_rvv::rvvneg(as_signed);
690
+ return detail_rvv::rvvreinterpret<T>(result);
691
+ }
692
+
693
+ template <class A, class T, detail::enable_signed_numeral_t<T> = 0>
694
+ XSIMD_INLINE batch<T, A> neg(batch<T, A> const& arg, requires_arch<rvv>) noexcept
695
+ {
696
+ return detail_rvv::rvvneg(arg);
697
+ }
698
+
699
+ // abs
700
+ template <class A, class T, detail::enable_unsigned_integral_t<T> = 0>
701
+ XSIMD_INLINE batch<T, A> abs(batch<T, A> const& arg, requires_arch<rvv>) noexcept
702
+ {
703
+ return arg;
704
+ }
705
+
706
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
707
+ XSIMD_INLINE batch<T, A> abs(batch<T, A> const& arg, requires_arch<rvv>) noexcept
708
+ {
709
+ return detail_rvv::rvvabs(arg);
710
+ }
711
+
712
+ // fma: x * y + z
713
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
714
+ XSIMD_INLINE batch<T, A> fma(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z, requires_arch<rvv>) noexcept
715
+ {
716
+ // also detail_rvv::rvvmadd(x, y, z);
717
+ return detail_rvv::rvvmacc(z, x, y);
718
+ }
719
+
720
+ // fnma: z - x * y
721
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
722
+ XSIMD_INLINE batch<T, A> fnma(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z, requires_arch<rvv>) noexcept
723
+ {
724
+ // also detail_rvv::rvvnmsub(x, y, z);
725
+ return detail_rvv::rvvnmsac(z, x, y);
726
+ }
727
+
728
+ // fms: x * y - z
729
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
730
+ XSIMD_INLINE batch<T, A> fms(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z, requires_arch<rvv>) noexcept
731
+ {
732
+ // also vfmsac(z, x, y), but lacking integer version
733
+ // also vfmsub(x, y, z), but lacking integer version
734
+ return -fnma(x, y, z);
735
+ }
736
+
737
+ // fnms: - x * y - z
738
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
739
+ XSIMD_INLINE batch<T, A> fnms(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z, requires_arch<rvv>) noexcept
740
+ {
741
+ // also vfnmacc(z, x, y), but lacking integer version
742
+ // also vfnmadd(x, y, z), but lacking integer version
743
+ return -fma(z, x, y);
744
+ }
745
+
746
+ /**********************
747
+ * Logical operations *
748
+ **********************/
749
+
750
+ namespace detail_rvv
751
+ {
752
+ XSIMD_RVV_OVERLOAD_INTS(rvvand, (__riscv_vand), , vec(vec, vec))
753
+ XSIMD_RVV_OVERLOAD_INTS(rvvor, (__riscv_vor), , vec(vec, vec))
754
+ XSIMD_RVV_OVERLOAD_INTS(rvvor_splat, (__riscv_vor), , vec(vec, T))
755
+ XSIMD_RVV_OVERLOAD_INTS(rvvxor, (__riscv_vxor), , vec(vec, vec))
756
+ XSIMD_RVV_OVERLOAD_INTS(rvvnot, (__riscv_vnot), , vec(vec))
757
+ XSIMD_RVV_OVERLOAD(rvvmand, (__riscv_vmand_mm_b XSIMD_RVV_S), , bvec(bvec, bvec))
758
+ XSIMD_RVV_OVERLOAD(rvvmor, (__riscv_vmor_mm_b XSIMD_RVV_S), , bvec(bvec, bvec))
759
+ XSIMD_RVV_OVERLOAD(rvvmxor, (__riscv_vmxor_mm_b XSIMD_RVV_S), , bvec(bvec, bvec))
760
+ XSIMD_RVV_OVERLOAD(rvvmandn, (__riscv_vmandn_mm_b XSIMD_RVV_S), , bvec(bvec, bvec))
761
+ XSIMD_RVV_OVERLOAD(rvvmnot, (__riscv_vmnot), , bvec(bvec))
762
+ }
763
+
764
+ // bitwise_and
765
+ template <class A, class T, detail::enable_integral_t<T> = 0>
766
+ XSIMD_INLINE batch<T, A> bitwise_and(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
767
+ {
768
+ return detail_rvv::rvvand(lhs, rhs);
769
+ }
770
+
771
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
772
+ XSIMD_INLINE batch<T, A> bitwise_and(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
773
+ {
774
+ const auto lhs_bits = detail_rvv::rvv_to_unsigned_batch(lhs);
775
+ const auto rhs_bits = detail_rvv::rvv_to_unsigned_batch(rhs);
776
+ const auto result_bits = detail_rvv::rvvand(lhs_bits, rhs_bits);
777
+ return detail_rvv::rvvreinterpret<T>(result_bits);
778
+ }
779
+
780
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
781
+ XSIMD_INLINE batch_bool<T, A> bitwise_and(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
782
+ {
783
+ return detail_rvv::rvvmand(lhs, rhs);
784
+ }
785
+
786
+ // bitwise_andnot
787
+ template <class A, class T, detail::enable_integral_t<T> = 0>
788
+ XSIMD_INLINE batch<T, A> bitwise_andnot(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
789
+ {
790
+ const auto not_rhs = detail_rvv::rvvnot(rhs);
791
+ return detail_rvv::rvvand(lhs, not_rhs);
792
+ }
793
+
794
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
795
+ XSIMD_INLINE batch<T, A> bitwise_andnot(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
796
+ {
797
+ const auto lhs_bits = detail_rvv::rvv_to_unsigned_batch(lhs);
798
+ const auto rhs_bits = detail_rvv::rvv_to_unsigned_batch(rhs);
799
+ const auto not_rhs = detail_rvv::rvvnot(rhs_bits);
800
+ const auto result_bits = detail_rvv::rvvand(lhs_bits, not_rhs);
801
+ return detail_rvv::rvvreinterpret<T>(result_bits);
802
+ }
803
+
804
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
805
+ XSIMD_INLINE batch_bool<T, A> bitwise_andnot(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
806
+ {
807
+ return detail_rvv::rvvmandn(lhs, rhs);
808
+ }
809
+
810
+ // bitwise_or
811
+ template <class A, class T, detail::enable_integral_t<T> = 0>
812
+ XSIMD_INLINE batch<T, A> bitwise_or(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
813
+ {
814
+ return detail_rvv::rvvor(lhs, rhs);
815
+ }
816
+
817
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
818
+ XSIMD_INLINE batch<T, A> bitwise_or(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
819
+ {
820
+ const auto lhs_bits = detail_rvv::rvv_to_unsigned_batch(lhs);
821
+ const auto rhs_bits = detail_rvv::rvv_to_unsigned_batch(rhs);
822
+ const auto result_bits = detail_rvv::rvvor(lhs_bits, rhs_bits);
823
+ return detail_rvv::rvvreinterpret<T>(result_bits);
824
+ }
825
+
826
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
827
+ XSIMD_INLINE batch_bool<T, A> bitwise_or(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
828
+ {
829
+ return detail_rvv::rvvmor(lhs, rhs);
830
+ }
831
+
832
+ // bitwise_xor
833
+ template <class A, class T, detail::enable_integral_t<T> = 0>
834
+ XSIMD_INLINE batch<T, A> bitwise_xor(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
835
+ {
836
+ return detail_rvv::rvvxor(lhs, rhs);
837
+ }
838
+
839
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
840
+ XSIMD_INLINE batch<T, A> bitwise_xor(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
841
+ {
842
+ const auto lhs_bits = detail_rvv::rvv_to_unsigned_batch(lhs);
843
+ const auto rhs_bits = detail_rvv::rvv_to_unsigned_batch(rhs);
844
+ const auto result_bits = detail_rvv::rvvxor(lhs_bits, rhs_bits);
845
+ return detail_rvv::rvvreinterpret<T>(result_bits);
846
+ }
847
+
848
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
849
+ XSIMD_INLINE batch_bool<T, A> bitwise_xor(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
850
+ {
851
+ return detail_rvv::rvvmxor(lhs, rhs);
852
+ }
853
+
854
+ // bitwise_not
855
+ template <class A, class T, detail::enable_integral_t<T> = 0>
856
+ XSIMD_INLINE batch<T, A> bitwise_not(batch<T, A> const& arg, requires_arch<rvv>) noexcept
857
+ {
858
+ return detail_rvv::rvvnot(arg);
859
+ }
860
+
861
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
862
+ XSIMD_INLINE batch<T, A> bitwise_not(batch<T, A> const& arg, requires_arch<rvv>) noexcept
863
+ {
864
+ const auto arg_bits = detail_rvv::rvv_to_unsigned_batch(arg);
865
+ const auto result_bits = detail_rvv::rvvnot(arg_bits);
866
+ return detail_rvv::rvvreinterpret<T>(result_bits);
867
+ }
868
+
869
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
870
+ XSIMD_INLINE batch_bool<T, A> bitwise_not(batch_bool<T, A> const& arg, requires_arch<rvv>) noexcept
871
+ {
872
+ return detail_rvv::rvvmnot(arg);
873
+ }
874
+
875
+ /**********
876
+ * Shifts *
877
+ **********/
878
+
879
+ namespace detail_rvv
880
+ {
881
+ XSIMD_RVV_OVERLOAD_INTS(rvvsll_splat, (__riscv_vsll), , vec(vec, size_t))
882
+ XSIMD_RVV_OVERLOAD_INTS(rvvsll, (__riscv_vsll), , vec(vec, uvec))
883
+ XSIMD_RVV_OVERLOAD2(rvvsr_splat,
884
+ (__riscv_vsra),
885
+ (__riscv_vsrl), , vec(vec, size_t))
886
+ XSIMD_RVV_OVERLOAD2(rvvsr,
887
+ (__riscv_vsra),
888
+ (__riscv_vsrl), , vec(vec, uvec))
889
+ } // namespace detail
890
+
891
+ // bitwise_lshift
892
+ template <class A, class T, detail::enable_integral_t<T> = 0>
893
+ XSIMD_INLINE batch<T, A> bitwise_lshift(batch<T, A> const& arg, int n, requires_arch<rvv>) noexcept
894
+ {
895
+ constexpr size_t size = sizeof(typename batch<T, A>::value_type) * 8;
896
+ assert(0 <= n && static_cast<size_t>(n) < size && "index in bounds");
897
+ return detail_rvv::rvvsll_splat(arg, n);
898
+ }
899
+
900
+ template <class A, class T, detail::enable_integral_t<T> = 0>
901
+ XSIMD_INLINE batch<T, A> bitwise_lshift(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
902
+ {
903
+ return detail_rvv::rvvsll(lhs, detail_rvv::rvv_to_unsigned_batch<A, T>(rhs));
904
+ }
905
+
906
+ // bitwise_rshift
907
+ template <class A, class T, detail::enable_integral_t<T> = 0>
908
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& arg, int n, requires_arch<rvv>) noexcept
909
+ {
910
+ constexpr size_t size = sizeof(typename batch<T, A>::value_type) * 8;
911
+ assert(0 <= n && static_cast<size_t>(n) < size && "index in bounds");
912
+ return detail_rvv::rvvsr_splat(arg, n);
913
+ }
914
+
915
+ template <class A, class T, detail::enable_integral_t<T> = 0>
916
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
917
+ {
918
+ return detail_rvv::rvvsr(lhs, detail_rvv::rvv_to_unsigned_batch<A, T>(rhs));
919
+ }
920
+
921
+ /**************
922
+ * Reductions *
923
+ **************/
924
+
925
+ namespace detail_rvv
926
+ {
927
+ XSIMD_RVV_OVERLOAD3(rvvredsum,
928
+ (__riscv_vredsum),
929
+ (__riscv_vredsum),
930
+ (__riscv_vfredosum), // or __riscv_vfredusum
931
+ , scalar_vec(vec, scalar_vec))
932
+ XSIMD_RVV_OVERLOAD3(rvvredmax,
933
+ (__riscv_vredmax),
934
+ (__riscv_vredmaxu),
935
+ (__riscv_vfredmax), , scalar_vec(vec, scalar_vec))
936
+ XSIMD_RVV_OVERLOAD3(rvvredmin,
937
+ (__riscv_vredmin),
938
+ (__riscv_vredminu),
939
+ (__riscv_vfredmin), , scalar_vec(vec, scalar_vec))
940
+ XSIMD_RVV_OVERLOAD3(rvvslide1up,
941
+ (__riscv_vslide1up),
942
+ (__riscv_vslide1up),
943
+ (__riscv_vfslide1up), , vec(vec, vec))
944
+ XSIMD_RVV_OVERLOAD3(rvvslide1down,
945
+ (__riscv_vslide1down),
946
+ (__riscv_vslide1down),
947
+ (__riscv_vfslide1down), , vec(vec, T))
948
+
949
+ template <class A, class T>
950
+ XSIMD_INLINE T reduce_scalar(rvv_reg_t<T, types::detail::rvv_width_m1> const& arg)
951
+ {
952
+ return detail_rvv::rvvmv_lane0(rvv_reg_t<T, A::width>(arg.get_bytes(), types::detail::XSIMD_RVV_BITCAST));
953
+ }
954
+ }
955
+ // reduce_add
956
+ template <class A, class T, class V = typename batch<T, A>::value_type, detail::enable_arithmetic_t<T> = 0>
957
+ XSIMD_INLINE V reduce_add(batch<T, A> const& arg, requires_arch<rvv>) noexcept
958
+ {
959
+ const auto zero = detail_rvv::broadcast<T, types::detail::rvv_width_m1>(T(0));
960
+ const auto r = detail_rvv::rvvredsum(arg, zero);
961
+ return detail_rvv::reduce_scalar<A, T>(r);
962
+ }
963
+
964
+ // reduce_max
965
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
966
+ XSIMD_INLINE T reduce_max(batch<T, A> const& arg, requires_arch<rvv>) noexcept
967
+ {
968
+ const auto lowest = detail_rvv::broadcast<T, types::detail::rvv_width_m1>(std::numeric_limits<T>::lowest());
969
+ const auto r = detail_rvv::rvvredmax(arg, lowest);
970
+ return detail_rvv::reduce_scalar<A, T>(r);
971
+ }
972
+
973
+ // reduce_min
974
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
975
+ XSIMD_INLINE T reduce_min(batch<T, A> const& arg, requires_arch<rvv>) noexcept
976
+ {
977
+ const auto max = detail_rvv::broadcast<T, types::detail::rvv_width_m1>(std::numeric_limits<T>::max());
978
+ const auto r = detail_rvv::rvvredmin(arg, max);
979
+ return detail_rvv::reduce_scalar<A, T>(r);
980
+ }
981
+
982
+ // haddp
983
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
984
+ XSIMD_INLINE batch<T, A> haddp(const batch<T, A>* row, requires_arch<rvv>) noexcept
985
+ {
986
+ constexpr std::size_t size = batch<T, A>::size;
987
+ T sums[size];
988
+ #pragma unroll size
989
+ for (std::size_t i = 0; i < size; ++i)
990
+ {
991
+ sums[i] = reduce_add(row[i], rvv {});
992
+ }
993
+ return load_aligned<A>(sums, convert<T>(), rvv {});
994
+ }
995
+
996
+ /***************
997
+ * Comparisons *
998
+ ***************/
999
+
1000
+ // eq
1001
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1002
+ XSIMD_INLINE batch_bool<T, A> eq(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1003
+ {
1004
+ return detail_rvv::rvvmseq(lhs, rhs);
1005
+ }
1006
+
1007
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1008
+ XSIMD_INLINE batch_bool<T, A> eq(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
1009
+ {
1010
+ const auto neq_result = detail_rvv::rvvmxor(lhs, rhs);
1011
+ return detail_rvv::rvvmnot(neq_result);
1012
+ }
1013
+
1014
+ // neq
1015
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1016
+ XSIMD_INLINE batch_bool<T, A> neq(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1017
+ {
1018
+ return detail_rvv::rvvmsne(lhs, rhs);
1019
+ }
1020
+
1021
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1022
+ XSIMD_INLINE batch_bool<T, A> neq(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<rvv>) noexcept
1023
+ {
1024
+ return detail_rvv::rvvmxor(lhs, rhs);
1025
+ }
1026
+
1027
+ // lt
1028
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1029
+ XSIMD_INLINE batch_bool<T, A> lt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1030
+ {
1031
+ return detail_rvv::rvvmslt(lhs, rhs);
1032
+ }
1033
+
1034
+ // le
1035
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1036
+ XSIMD_INLINE batch_bool<T, A> le(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1037
+ {
1038
+ return detail_rvv::rvvmsle(lhs, rhs);
1039
+ }
1040
+
1041
+ // gt
1042
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1043
+ XSIMD_INLINE batch_bool<T, A> gt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1044
+ {
1045
+ return detail_rvv::rvvmsgt(lhs, rhs);
1046
+ }
1047
+
1048
+ // ge
1049
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1050
+ XSIMD_INLINE batch_bool<T, A> ge(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1051
+ {
1052
+ return detail_rvv::rvvmsge(lhs, rhs);
1053
+ }
1054
+
1055
+ /*************
1056
+ * Selection *
1057
+ *************/
1058
+ namespace detail_rvv
1059
+ {
1060
+ XSIMD_RVV_OVERLOAD(rvvcompress, (__riscv_vcompress_tu), , vec(vec, vec, bvec))
1061
+ }
1062
+ // compress
1063
+ template <class A, class T>
1064
+ XSIMD_INLINE batch<T, A> compress(batch<T, A> const& x, batch_bool<T, A> const& mask, requires_arch<rvv>) noexcept
1065
+ {
1066
+ auto zero = broadcast<A>(T(0), rvv {});
1067
+ return detail_rvv::rvvcompress(zero, x, mask);
1068
+ }
1069
+
1070
+ /***************
1071
+ * Permutation *
1072
+ ***************/
1073
+ namespace detail_rvv
1074
+ {
1075
+ XSIMD_RVV_OVERLOAD(rvvrgather, (__riscv_vrgather), , vec(vec, uvec))
1076
+ XSIMD_RVV_OVERLOAD(rvvslideup, (__riscv_vslideup), , vec(vec, vec, size_t))
1077
+ XSIMD_RVV_OVERLOAD(rvvslidedown, (__riscv_vslidedown), , vec(vec, size_t))
1078
+ }
1079
+
1080
+ // swizzle
1081
+ template <class A, class T, class I, I... idx>
1082
+ XSIMD_INLINE batch<T, A> swizzle(batch<T, A> const& arg, batch_constant<I, A, idx...>, requires_arch<rvv>) noexcept
1083
+ {
1084
+ static_assert(batch<T, A>::size == sizeof...(idx), "invalid swizzle indices");
1085
+ const batch<I, A> indices { idx... };
1086
+ return detail_rvv::rvvrgather(arg, indices);
1087
+ }
1088
+
1089
+ template <class A, class T, class I, I... idx>
1090
+ XSIMD_INLINE batch<std::complex<T>, A> swizzle(batch<std::complex<T>, A> const& self,
1091
+ batch_constant<I, A, idx...>,
1092
+ requires_arch<rvv>) noexcept
1093
+ {
1094
+ const auto real = swizzle(self.real(), batch_constant<I, A, idx...> {}, rvv {});
1095
+ const auto imag = swizzle(self.imag(), batch_constant<I, A, idx...> {}, rvv {});
1096
+ return batch<std::complex<T>>(real, imag);
1097
+ }
1098
+
1099
+ /*************
1100
+ * Selection *
1101
+ *************/
1102
+
1103
+ // extract_pair
1104
+
1105
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1106
+ XSIMD_INLINE batch<T, A> extract_pair(batch<T, A> const& lhs, batch<T, A> const& rhs, size_t n, requires_arch<rvv>) noexcept
1107
+ {
1108
+ const auto tmp = detail_rvv::rvvslidedown(rhs, n);
1109
+ return detail_rvv::rvvslideup(tmp, lhs, lhs.size - n);
1110
+ }
1111
+
1112
+ // select
1113
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1114
+ XSIMD_INLINE batch<T, A> select(batch_bool<T, A> const& cond, batch<T, A> const& a, batch<T, A> const& b, requires_arch<rvv>) noexcept
1115
+ {
1116
+ return detail_rvv::rvvmerge(b, a, cond);
1117
+ }
1118
+
1119
+ template <class A, class T, bool... b>
1120
+ XSIMD_INLINE batch<T, A> select(batch_bool_constant<T, A, b...> const&, batch<T, A> const& true_br, batch<T, A> const& false_br, requires_arch<rvv>) noexcept
1121
+ {
1122
+ return select(batch_bool<T, A> { b... }, true_br, false_br, rvv {});
1123
+ }
1124
+
1125
+ // zip_lo
1126
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1127
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1128
+ {
1129
+ const auto index = detail_rvv::vindex<A, as_unsigned_integer_t<T>, 0, -1>();
1130
+ const auto mask = detail_rvv::pmask8<T, A::width>(0xaa);
1131
+ return detail_rvv::rvvmerge(detail_rvv::rvvrgather(lhs, index),
1132
+ detail_rvv::rvvrgather(rhs, index),
1133
+ mask);
1134
+ }
1135
+
1136
+ // zip_hi
1137
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1138
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<rvv>) noexcept
1139
+ {
1140
+ const auto index = detail_rvv::vindex<A, as_unsigned_integer_t<T>, batch<T, A>::size / 2, -1>();
1141
+ const auto mask = detail_rvv::pmask8<T, A::width>(0xaa);
1142
+ return detail_rvv::rvvmerge(detail_rvv::rvvrgather(lhs, index),
1143
+ detail_rvv::rvvrgather(rhs, index),
1144
+ mask);
1145
+ }
1146
+
1147
+ // store_complex
1148
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1149
+ XSIMD_INLINE void store_complex_aligned(std::complex<T>* dst, batch<std::complex<T>, A> const& src, requires_arch<rvv>) noexcept
1150
+ {
1151
+ const auto lo = zip_lo(src.real(), src.imag());
1152
+ const auto hi = zip_hi(src.real(), src.imag());
1153
+ T* buf = reinterpret_cast<T*>(dst);
1154
+ store_aligned(buf, lo, rvv {});
1155
+ store_aligned(buf + lo.size, hi, rvv {});
1156
+ }
1157
+
1158
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1159
+ XSIMD_INLINE void store_complex_unaligned(std::complex<T>* dst, batch<std::complex<T>, A> const& src, requires_arch<rvv>) noexcept
1160
+ {
1161
+ store_complex_aligned(dst, src, rvv {});
1162
+ }
1163
+
1164
+ /*****************************
1165
+ * Floating-point arithmetic *
1166
+ *****************************/
1167
+
1168
+ namespace detail_rvv
1169
+ {
1170
+ XSIMD_RVV_OVERLOAD_FLOATS(rvvfsqrt, (__riscv_vfsqrt), , vec(vec))
1171
+ XSIMD_RVV_OVERLOAD_FLOATS(rvvfrec7, (__riscv_vfrec7), , vec(vec))
1172
+ XSIMD_RVV_OVERLOAD_FLOATS(rvvfrsqrt7, (__riscv_vfrsqrt7), , vec(vec))
1173
+ }
1174
+
1175
+ // rsqrt
1176
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1177
+ XSIMD_INLINE batch<T, A> rsqrt(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1178
+ {
1179
+ auto approx = detail_rvv::rvvfrsqrt7(arg);
1180
+ approx = approx * (1.5 - (0.5 * arg * approx * approx));
1181
+ return approx;
1182
+ }
1183
+
1184
+ // sqrt
1185
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1186
+ XSIMD_INLINE batch<T, A> sqrt(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1187
+ {
1188
+ return detail_rvv::rvvfsqrt(arg);
1189
+ }
1190
+
1191
+ // reciprocal
1192
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1193
+ XSIMD_INLINE batch<T, A> reciprocal(const batch<T, A>& arg, requires_arch<rvv>) noexcept
1194
+ {
1195
+ return detail_rvv::rvvfrec7(arg);
1196
+ }
1197
+
1198
+ /******************************
1199
+ * Floating-point conversions *
1200
+ ******************************/
1201
+
1202
+ // fast_cast
1203
+ namespace detail_rvv
1204
+ {
1205
+ XSIMD_RVV_OVERLOAD2(rvvfcvt_rtz, // truncating conversion, like C.
1206
+ (__riscv_vfcvt_rtz_x),
1207
+ (__riscv_vfcvt_rtz_xu), _DROP_1ST, vec(T, fvec))
1208
+ XSIMD_RVV_OVERLOAD2(rvvfcvt_rne, // round to nearest, ties to even
1209
+ (__riscv_vfcvt_x),
1210
+ (__riscv_vfcvt_xu), _DROP_1ST_CUSTOM_ARGS, vec(T, fvec), args..., __RISCV_FRM_RNE)
1211
+ XSIMD_RVV_OVERLOAD2(rvvfcvt_rmm, // round to nearest, ties to max magnitude
1212
+ (__riscv_vfcvt_x),
1213
+ (__riscv_vfcvt_xu), _DROP_1ST_CUSTOM_ARGS, vec(T, fvec), args..., __RISCV_FRM_RMM)
1214
+ XSIMD_RVV_OVERLOAD2(rvvfcvt, // round to current rounding mode.
1215
+ (__riscv_vfcvt_x),
1216
+ (__riscv_vfcvt_xu), _DROP_1ST, vec(T, fvec))
1217
+ XSIMD_RVV_OVERLOAD_INTS(rvvfcvt_f, (__riscv_vfcvt_f), , fvec(vec))
1218
+
1219
+ template <class T, class U>
1220
+ using rvv_enable_ftoi_t = std::enable_if_t<(sizeof(T) == sizeof(U) && std::is_floating_point<T>::value && !std::is_floating_point<U>::value), int>;
1221
+ template <class T, class U>
1222
+ using rvv_enable_itof_t = std::enable_if_t<(sizeof(T) == sizeof(U) && !std::is_floating_point<T>::value && std::is_floating_point<U>::value), int>;
1223
+
1224
+ template <class A, class T, class U, rvv_enable_ftoi_t<T, U> = 0>
1225
+ XSIMD_INLINE batch<U, A> fast_cast(batch<T, A> const& arg, batch<U, A> const&, requires_arch<rvv>) noexcept
1226
+ {
1227
+ return rvvfcvt_rtz(U {}, arg);
1228
+ }
1229
+ template <class A, class T, class U, rvv_enable_itof_t<T, U> = 0>
1230
+ XSIMD_INLINE batch<U, A> fast_cast(batch<T, A> const& arg, batch<U, A> const&, requires_arch<rvv>) noexcept
1231
+ {
1232
+ return rvvfcvt_f(arg);
1233
+ }
1234
+ }
1235
+
1236
+ /*********
1237
+ * Miscs *
1238
+ *********/
1239
+
1240
+ // set
1241
+ template <class A, class T, class... Args>
1242
+ XSIMD_INLINE batch<T, A> set(batch<T, A> const&, requires_arch<rvv>, Args... args) noexcept
1243
+ {
1244
+ const std::array<T, batch<T, A>::size> tmp { args... };
1245
+ return load_unaligned<A>(tmp.data(), convert<T>(), rvv {});
1246
+ }
1247
+
1248
+ template <class A, class T, class... Args>
1249
+ XSIMD_INLINE batch<std::complex<T>, A> set(batch<std::complex<T>, A> const&, requires_arch<rvv>,
1250
+ Args... args_complex) noexcept
1251
+ {
1252
+ return batch<std::complex<T>>(set(batch<T, rvv> {}, rvv {}, args_complex.real()...),
1253
+ set(batch<T, rvv> {}, rvv {}, args_complex.imag()...));
1254
+ }
1255
+
1256
+ template <class A, class T, class... Args>
1257
+ XSIMD_INLINE batch_bool<T, A> set(batch_bool<T, A> const&, requires_arch<rvv>, Args... args) noexcept
1258
+ {
1259
+ using U = as_unsigned_integer_t<T>;
1260
+ const auto values = set(batch<U, rvv> {}, rvv {}, static_cast<U>(args)...);
1261
+ const auto zero = broadcast<A>(U(0), rvv {});
1262
+ detail_rvv::rvv_bool_t<T> result = detail_rvv::rvvmsne(values, zero);
1263
+ return result;
1264
+ }
1265
+
1266
+ // first
1267
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1268
+ XSIMD_INLINE T first(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1269
+ {
1270
+ return detail_rvv::rvvmv_lane0(arg);
1271
+ }
1272
+
1273
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1274
+ XSIMD_INLINE std::complex<T> first(batch<std::complex<T>, A> const& arg, requires_arch<rvv>) noexcept
1275
+ {
1276
+ return std::complex<T> { detail_rvv::rvvmv_lane0(arg.real()), detail_rvv::rvvmv_lane0(arg.imag()) };
1277
+ }
1278
+
1279
+ // insert
1280
+ template <class A, class T, size_t I, detail::enable_arithmetic_t<T> = 0>
1281
+ XSIMD_INLINE batch<T, A> insert(batch<T, A> const& arg, T val, index<I>, requires_arch<rvv>) noexcept
1282
+ {
1283
+ const auto mask = detail_rvv::pmask<T, A::width>(uint64_t(1) << I);
1284
+ return detail_rvv::rvvmerge_splat(arg, val, mask);
1285
+ }
1286
+
1287
+ // get
1288
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1289
+ XSIMD_INLINE T get(batch<T, A> const& arg, size_t i, requires_arch<rvv>) noexcept
1290
+ {
1291
+ const auto tmp = detail_rvv::rvvslidedown(arg, i);
1292
+ return detail_rvv::rvvmv_lane0(tmp);
1293
+ }
1294
+
1295
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1296
+ XSIMD_INLINE std::complex<T> get(batch<std::complex<T>, A> const& arg, size_t i, requires_arch<rvv>) noexcept
1297
+ {
1298
+ const auto tmpr = detail_rvv::rvvslidedown(arg.real(), i);
1299
+ const auto tmpi = detail_rvv::rvvslidedown(arg.imag(), i);
1300
+ return std::complex<T> { detail_rvv::rvvmv_lane0(tmpr), detail_rvv::rvvmv_lane0(tmpi) };
1301
+ }
1302
+
1303
+ // get (compile-time index): skip the slidedown when I == 0; lane 0 maps straight to the scalar move.
1304
+ template <class A, size_t I, class T, detail::enable_arithmetic_t<T> = 0>
1305
+ XSIMD_INLINE T get(batch<T, A> const& arg, index<I>, requires_arch<rvv>) noexcept
1306
+ {
1307
+ XSIMD_IF_CONSTEXPR(I == 0)
1308
+ {
1309
+ return detail_rvv::rvvmv_lane0(arg);
1310
+ }
1311
+ return get(arg, I, rvv {});
1312
+ }
1313
+
1314
+ template <class A, size_t I, class T, detail::enable_arithmetic_t<T> = 0>
1315
+ XSIMD_INLINE std::complex<T> get(batch<std::complex<T>, A> const& arg, index<I>, requires_arch<rvv>) noexcept
1316
+ {
1317
+ XSIMD_IF_CONSTEXPR(I == 0)
1318
+ {
1319
+ return std::complex<T> { detail_rvv::rvvmv_lane0(arg.real()), detail_rvv::rvvmv_lane0(arg.imag()) };
1320
+ }
1321
+ return get(arg, I, rvv {});
1322
+ }
1323
+
1324
+ // all
1325
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1326
+ XSIMD_INLINE bool all(batch_bool<T, A> const& arg, requires_arch<rvv>) noexcept
1327
+ {
1328
+ return detail_rvv::rvvcpop(arg) == batch_bool<T, A>::size;
1329
+ }
1330
+
1331
+ // any
1332
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1333
+ XSIMD_INLINE bool any(batch_bool<T, A> const& arg, requires_arch<rvv>) noexcept
1334
+ {
1335
+ return detail_rvv::rvvcpop(arg) > 0;
1336
+ }
1337
+
1338
+ // bitwise_cast
1339
+ template <class A, class T, class R, detail::enable_arithmetic_t<T> = 0, detail::enable_arithmetic_t<R> = 0>
1340
+ XSIMD_INLINE batch<R, A> bitwise_cast(batch<T, A> const& arg, batch<R, A> const&, requires_arch<rvv>) noexcept
1341
+ {
1342
+ return detail_rvv::rvv_reg_t<R, A::width>(arg.data.get_bytes(), types::detail::XSIMD_RVV_BITCAST);
1343
+ }
1344
+
1345
+ // batch_bool_cast
1346
+ template <class A, class T_out, class T_in, detail::enable_arithmetic_t<T_in> = 0>
1347
+ XSIMD_INLINE batch_bool<T_out, A> batch_bool_cast(batch_bool<T_in, A> const& arg, batch_bool<T_out, A> const&, requires_arch<rvv>) noexcept
1348
+ {
1349
+ using intermediate_t = typename detail_rvv::rvv_bool_t<T_out>;
1350
+ return intermediate_t(arg.data);
1351
+ }
1352
+
1353
+ // from_bool
1354
+ template <class A, class T, detail::enable_arithmetic_t<T> = 0>
1355
+ XSIMD_INLINE batch<T, A> from_bool(batch_bool<T, A> const& arg, requires_arch<rvv>) noexcept
1356
+ {
1357
+ const auto zero = broadcast<A>(T(0), rvv {});
1358
+ return detail_rvv::rvvmerge_splat(zero, T(1), arg);
1359
+ }
1360
+
1361
+ namespace detail_rvv
1362
+ {
1363
+ template <size_t Width>
1364
+ XSIMD_INLINE vuint8m1_t rvvslidedownbytes(vuint8m1_t arg, size_t i)
1365
+ {
1366
+ return __riscv_vslidedown(arg, i, types::detail::rvv_width_m1 / 8);
1367
+ }
1368
+ template <>
1369
+ XSIMD_INLINE vuint8m1_t rvvslidedownbytes<types::detail::rvv_width_mf2>(vuint8m1_t arg, size_t i)
1370
+ {
1371
+ const auto bytes = __riscv_vlmul_trunc_u8mf2(arg);
1372
+ const auto result = __riscv_vslidedown(bytes, i, types::detail::rvv_width_mf2 / 8);
1373
+ return __riscv_vlmul_ext_u8m1(result);
1374
+ }
1375
+ template <>
1376
+ XSIMD_INLINE vuint8m1_t rvvslidedownbytes<types::detail::rvv_width_mf4>(vuint8m1_t arg, size_t i)
1377
+ {
1378
+ const auto bytes = __riscv_vlmul_trunc_u8mf4(arg);
1379
+ const auto result = __riscv_vslidedown(bytes, i, types::detail::rvv_width_mf4 / 8);
1380
+ return __riscv_vlmul_ext_u8m1(result);
1381
+ }
1382
+ template <>
1383
+ XSIMD_INLINE vuint8m1_t rvvslidedownbytes<types::detail::rvv_width_mf8>(vuint8m1_t arg, size_t i)
1384
+ {
1385
+ const auto bytes = __riscv_vlmul_trunc_u8mf8(arg);
1386
+ const auto result = __riscv_vslidedown(bytes, i, types::detail::rvv_width_mf8 / 8);
1387
+ return __riscv_vlmul_ext_u8m1(result);
1388
+ }
1389
+ }
1390
+
1391
+ // slide_left
1392
+ template <size_t N, class A, class T, detail::enable_arithmetic_t<T> = 0>
1393
+ XSIMD_INLINE batch<T, A> slide_left(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1394
+ {
1395
+ const auto zero = broadcast<A>(uint8_t(0), rvv {});
1396
+ const auto bytes = arg.data.get_bytes();
1397
+ return detail_rvv::rvvreinterpret<T>(detail_rvv::rvvslideup(zero, bytes, N));
1398
+ }
1399
+
1400
+ // slide_right
1401
+ template <size_t N, class A, class T, detail::enable_arithmetic_t<T> = 0>
1402
+ XSIMD_INLINE batch<T, A> slide_right(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1403
+ {
1404
+ using reg_t = detail_rvv::rvv_reg_t<T, A::width>;
1405
+ const auto bytes = arg.data.get_bytes();
1406
+ return reg_t(detail_rvv::rvvslidedownbytes<A::width>(bytes, N), types::detail::XSIMD_RVV_BITCAST);
1407
+ }
1408
+
1409
+ // isnan
1410
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1411
+ XSIMD_INLINE batch_bool<T, A> isnan(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1412
+ {
1413
+ return !(arg == arg);
1414
+ }
1415
+
1416
+ namespace detail_rvv
1417
+ {
1418
+ template <class T>
1419
+ using rvv_as_signed_integer_t = as_signed_integer_t<as_unsigned_integer_t<T>>;
1420
+
1421
+ template <class A, class T, class U = rvv_as_signed_integer_t<T>>
1422
+ XSIMD_INLINE batch<U, A> rvvfcvt_default(batch<T, A> const& arg) noexcept
1423
+ {
1424
+ return rvvfcvt_rne(U {}, arg);
1425
+ }
1426
+
1427
+ template <class A, class T, class U = rvv_as_signed_integer_t<T>>
1428
+ XSIMD_INLINE batch<U, A> rvvfcvt_afz(batch<T, A> const& arg) noexcept
1429
+ {
1430
+ return rvvfcvt_rmm(U {}, arg);
1431
+ }
1432
+ }
1433
+
1434
+ // nearbyint_as_int
1435
+ template <class A, class T, class U = detail_rvv::rvv_as_signed_integer_t<T>>
1436
+ XSIMD_INLINE batch<U, A> nearbyint_as_int(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1437
+ {
1438
+ // Reference rounds ties to nearest even
1439
+ return detail_rvv::rvvfcvt_default(arg);
1440
+ }
1441
+
1442
+ // round
1443
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1444
+ XSIMD_INLINE batch<T, A> round(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1445
+ {
1446
+ // Round ties away from zero.
1447
+ const auto mask = abs(arg) < constants::maxflint<batch<T, A>>();
1448
+ return select(mask, to_float(detail_rvv::rvvfcvt_afz(arg)), arg, rvv {});
1449
+ }
1450
+
1451
+ // nearbyint
1452
+ template <class A, class T, detail::enable_floating_point_t<T> = 0>
1453
+ XSIMD_INLINE batch<T, A> nearbyint(batch<T, A> const& arg, requires_arch<rvv>) noexcept
1454
+ {
1455
+ // Round according to current rounding mode.
1456
+ const auto mask = abs(arg) < constants::maxflint<batch<T, A>>();
1457
+ return select(mask, to_float(detail_rvv::rvvfcvt_default(arg)), arg, rvv {});
1458
+ }
1459
+
1460
+ // mask
1461
+ template <class A, class T>
1462
+ XSIMD_INLINE uint64_t mask(batch_bool<T, A> const& self, requires_arch<common>) noexcept;
1463
+
1464
+ template <class A, class T>
1465
+ XSIMD_INLINE uint64_t mask(batch_bool<T, A> const& self, requires_arch<rvv>) noexcept
1466
+ {
1467
+ XSIMD_IF_CONSTEXPR((8 * sizeof(T)) >= batch_bool<T, A>::size)
1468
+ {
1469
+ // (A) Easy case: the number of slots fits in T.
1470
+ const auto zero = detail_rvv::broadcast<as_unsigned_integer_t<T>, types::detail::rvv_width_m1>(T(0));
1471
+ auto ones = detail_rvv::broadcast<as_unsigned_integer_t<T>, A::width>(1);
1472
+ auto iota = detail_rvv::rvvid(as_unsigned_integer_t<T> {});
1473
+ auto upowers = detail_rvv::rvvsll(ones, iota);
1474
+ auto r = __riscv_vredor(self.data.as_mask(), upowers, (typename decltype(zero)::register_type)zero, batch_bool<T, A>::size);
1475
+ return detail_rvv::reduce_scalar<A, as_unsigned_integer_t<T>>(r);
1476
+ }
1477
+ else XSIMD_IF_CONSTEXPR((2 * 8 * sizeof(T)) == batch_bool<T, A>::size)
1478
+ {
1479
+ // (B) We need two rounds, one for the low part, one for the high part.
1480
+
1481
+ struct LowerHalf
1482
+ {
1483
+ static constexpr bool get(unsigned i, unsigned n) { return i < n / 2; }
1484
+ };
1485
+ struct UpperHalf
1486
+ {
1487
+ static constexpr bool get(unsigned i, unsigned n) { return i >= n / 2; }
1488
+ };
1489
+
1490
+ // The low part is similar to the approach in (A).
1491
+ const auto zero = detail_rvv::broadcast<as_unsigned_integer_t<T>, types::detail::rvv_width_m1>(T(0));
1492
+ auto ones = detail_rvv::broadcast<as_unsigned_integer_t<T>, A::width>(1);
1493
+ auto iota = detail_rvv::rvvid(as_unsigned_integer_t<T> {});
1494
+ auto upowers = detail_rvv::rvvsll(ones, iota);
1495
+ auto low_mask = self & make_batch_bool_constant<T, LowerHalf, A>();
1496
+ auto r_low = __riscv_vredor(low_mask.data.as_mask(), upowers, (typename decltype(zero)::register_type)zero, batch_bool<T, A>::size);
1497
+
1498
+ // The high part requires to slide the upower filter to match the high mask.
1499
+ upowers = detail_rvv::rvvslideup(upowers, upowers, 8 * sizeof(T));
1500
+ auto high_mask = self & make_batch_bool_constant<T, UpperHalf, A>();
1501
+ auto r_high = __riscv_vredor(high_mask.data.as_mask(), upowers, (typename decltype(zero)::register_type)zero, batch_bool<T, A>::size);
1502
+
1503
+ // Concatenate the two parts.
1504
+ return (uint64_t)detail_rvv::reduce_scalar<A, as_unsigned_integer_t<T>>(r_low) | ((uint64_t)detail_rvv::reduce_scalar<A, as_unsigned_integer_t<T>>(r_high) << (8 * sizeof(T)));
1505
+ }
1506
+ else
1507
+ {
1508
+ // (C) we could generalize (B) but we already cover a lot of case now.
1509
+ return mask(self, common {});
1510
+ }
1511
+ }
1512
+ } // namespace kernel
1513
+ } // namespace xsimd
1514
+
1515
+ #endif