diff --git a/src/simd.cpp b/src/simd.cpp index 326ce998..e82df83d 100644 --- a/src/simd.cpp +++ b/src/simd.cpp @@ -12,6 +12,36 @@ namespace HWY_NAMESPACE { namespace hn = hwy::HWY_NAMESPACE; +// SumsOf2 pairwise-adds adjacent lanes into the next-wider type +// (u8 pairs -> u16, u16 pairs -> u32). Available since Highway 1.1.0; +// provide a portable fallback for older versions. +#if !defined(HWY_MAJOR) || HWY_MAJOR < 1 || (HWY_MAJOR == 1 && HWY_MINOR < 1) + +template +HWY_API hn::VFromD>, + hn::DFromV>> +SumsOf2Fallback(V v) { + using T = hn::TFromV; + using TW = hwy::MakeWide; + using D = hn::DFromV; + using DW = hn::Repartition; + const D d; + const DW dw; + const size_t N = hn::Lanes(d); + HWY_ALIGN T buf[hn::MaxLanes(d)]; + hn::Store(v, d, buf); + HWY_ALIGN TW wbuf[hn::MaxLanes(dw)]; + for (size_t i = 0; i < N / 2; ++i) { + wbuf[i] = static_cast(buf[2 * i]) + static_cast(buf[2 * i + 1]); + } + return hn::Load(dw, wbuf); +} +#define SumsOf2 SumsOf2Fallback + +#else +using hn::SumsOf2; +#endif + void CountQualityMetricsImpl(const char* qualstr, const char* seqstr, int len, char qualThreshold, int& lowQualNum, int& nBaseNum, int& totalQual) {