diff --git a/.github/workflows/risc.yml b/.github/workflows/risc.yml index 2437da81..aa4d000f 100644 --- a/.github/workflows/risc.yml +++ b/.github/workflows/risc.yml @@ -1,4 +1,4 @@ -name: Ubuntu RISC-V rvv VLEN=128 (clang 17) +name: Ubuntu RISC-V rvv (clang 17) on: [push, pull_request] @@ -14,10 +14,15 @@ jobs: - name: Build run: | CXX=clang++-17 CXXFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" \ - cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DCMAKE_BUILD_TYPE=Release -B build + cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DCMAKE_BUILD_TYPE=Release -DFASTFLOAT_TEST=ON -B build cmake --build build/ -j$(nproc) - name: Test VLEN=128 run: | export QEMU_LD_PREFIX="/usr/riscv64-linux-gnu" export QEMU_CPU="rv64,v=on,vlen=128,rvv_ta_all_1s=on,rvv_ma_all_1s=on" ctest --timeout 1800 --output-on-failure --test-dir build -j $(nproc) + - name: Test VLEN=256 + run: | + export QEMU_LD_PREFIX="/usr/riscv64-linux-gnu" + export QEMU_CPU="rv64,v=on,vlen=256,rvv_ta_all_1s=on,rvv_ma_all_1s=on" + ctest --timeout 1800 --output-on-failure --test-dir build -j $(nproc) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 4b705554..eaf6ec1a 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -9,3 +9,4 @@ Jan Pharago Maya Warrier Taha Khokhar Anders Dalvander +Fenghao Li diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index ba6983b8..af99ce86 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -18,6 +18,10 @@ #include #endif +#ifdef FASTFLOAT_RVV +#include +#endif + namespace fast_float { template fastfloat_really_inline constexpr bool has_simd_opt() { @@ -126,6 +130,24 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { FASTFLOAT_SIMD_RESTORE_WARNINGS } +#elif defined(FASTFLOAT_RVV) + +fastfloat_really_inline uint64_t simd_read8_to_u64(vuint16m1_t const data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + vuint8mf2_t const packed = __riscv_vnsrl_wx_u8mf2(data, 0, 8); + uint64_t value; + __riscv_vse8_v_u8mf2(reinterpret_cast(&value), packed, 8); + return value; + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + __riscv_vle16_v_u16m1(reinterpret_cast(chars), 8)); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + #endif // FASTFLOAT_SSE2 // MSVC SFINAE is broken pre-VS2017 @@ -222,6 +244,22 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars, } else return false; FASTFLOAT_SIMD_RESTORE_WARNINGS +#elif defined(FASTFLOAT_RVV) + FASTFLOAT_SIMD_DISABLE_WARNINGS + vuint16m1_t const data = + __riscv_vle16_v_u16m1(reinterpret_cast(chars), 8); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + vuint16m1_t const t0 = __riscv_vsub_vx_u16m1(data, '0', 8); + vbool16_t const nondigit = __riscv_vmsgtu_vx_u16m1_b16(t0, 9, 8); + + if (__riscv_vfirst_m_b16(nondigit, 8) < 0) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS #else static_cast(chars); static_cast(i); diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 2fc35496..1d154280 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -172,7 +172,14 @@ using parse_options = parse_options_t; #define FASTFLOAT_NEON 1 #endif -#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON) +// The RISC-V V extension guarantees VLEN >= 128. The __riscv_-prefixed +// intrinsics used here require version 0.11 or later of the intrinsics spec. +#if defined(__riscv_v) && defined(__riscv_v_intrinsic) && \ + __riscv_v_intrinsic >= 11000 +#define FASTFLOAT_RVV 1 +#endif + +#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON) || defined(FASTFLOAT_RVV) #define FASTFLOAT_HAS_SIMD 1 #endif