diff --git a/c/common/platform.h b/c/common/platform.h index 8080cbb46..6bfb9e972 100644 --- a/c/common/platform.h +++ b/c/common/platform.h @@ -200,6 +200,10 @@ To apply compiler hint, enclose the branching condition into macros, like this: #define BROTLI_TARGET_RISCV64 #endif +#if defined(BROTLI_TARGET_RISCV64) && defined(__riscv_v) && __riscv_v >= 1000000 +#define BROTLI_RVV_1 +#endif + #if defined(__loongarch_lp64) #define BROTLI_TARGET_LOONGARCH64 #endif diff --git a/c/dec/decode.c b/c/dec/decode.c index 446365adf..80a1f2ad7 100644 --- a/c/dec/decode.c +++ b/c/dec/decode.c @@ -24,6 +24,10 @@ #include #endif +#if defined(BROTLI_RVV_1) +#include +#endif + #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -182,6 +186,10 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s, static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) { #if defined(BROTLI_TARGET_NEON) vst1q_u8(dst, vld1q_u8(src)); +#elif defined(BROTLI_RVV_1) + size_t vl = __riscv_vsetvl_e8m1(16); + vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); + __riscv_vse8_v_u8m1(dst, v, vl); #else uint32_t buffer[4]; memcpy(buffer, src, 16); diff --git a/c/enc/find_match_length.h b/c/enc/find_match_length.h index 096be9331..2be5d2271 100644 --- a/c/enc/find_match_length.h +++ b/c/enc/find_match_length.h @@ -15,8 +15,30 @@ extern "C" { #endif -/* Separate implementation for little-endian 64-bit targets, for speed. */ -#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN +#if defined(BROTLI_RVV_1) +#include + +static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, + const uint8_t* s2, + size_t limit) { + const uint8_t* s1_orig = s1; + while (limit > 0) { + size_t vl = __riscv_vsetvl_e8m1(limit); + vuint8m1_t v1 = __riscv_vle8_v_u8m1(s1, vl); + vuint8m1_t v2 = __riscv_vle8_v_u8m1(s2, vl); + vbool8_t mask = __riscv_vmsne_vv_u8m1_b8(v1, v2, vl); + long first_diff = __riscv_vfirst_m_b8(mask, vl); + if (first_diff >= 0) { + return (size_t)(s1 - s1_orig) + (size_t)first_diff; + } + s1 += vl; + s2 += vl; + limit -= vl; + } + return (size_t)(s1 - s1_orig); +} + +#elif defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, const uint8_t* s2, size_t limit) {