On Tue, 20 Jan 2026 14:58:50 +0800, Feng Jiang wrote: > diff --git a/arch/riscv/lib/strnlen.S b/arch/riscv/lib/strnlen.S
Branches that test maxlen can be replaced with Zbb minu instruction. (see below) > + /* > + * Returns > + * a0 - String length > + * > + * Parameters > + * a0 - String to measure > + * a1 - Max length of string > + * > + * Clobbers > + * t0, t1, t2, t3, t4 > + */ > + > + /* If maxlen is 0, return 0. */ > + beqz a1, 3f > + > + /* Number of irrelevant bytes in the first word. */ > + andi t2, a0, SZREG-1 > + > + /* Align pointer. */ > + andi t0, a0, -SZREG > + > + li t3, SZREG > + sub t3, t3, t2 > + slli t2, t2, 3 > + > + /* Aligned boundary. */ > + add t4, a0, a1 > + andi t4, t4, -SZREG > + > + /* Get the first word. */ > + REG_L t1, 0(t0) > + > + /* > + * Shift away the partial data we loaded to remove the irrelevant bytes > + * preceding the string with the effect of adding NUL bytes at the > + * end of the string's first word. > + */ > + SHIFT t1, t1, t2 > + > + /* Convert non-NUL into 0xff and NUL into 0x00. */ > + orc.b t1, t1 > + > + /* Convert non-NUL into 0x00 and NUL into 0xff. */ > + not t1, t1 > + > + /* > + * Search for the first set bit (corresponding to a NUL byte in the > + * original chunk). > + */ > + CZ t1, t1 > + > + /* > + * The first chunk is special: compare against the number > + * of valid bytes in this chunk. > + */ > + srli a0, t1, 3 > + > + /* Limit the result by maxlen. */ > + bleu a1, a0, 3f minu a0, a0, a1 > + > + bgtu t3, a0, 2f > + > + /* Prepare for the word comparison loop. */ > + addi t2, t0, SZREG > + li t3, -1 > + > + /* > + * Our critical loop is 4 instructions and processes data in > + * 4 byte or 8 byte chunks. > + */ > + .p2align 3 > +1: > + REG_L t1, SZREG(t0) > + addi t0, t0, SZREG > + orc.b t1, t1 > + bgeu t0, t4, 4f > + beq t1, t3, 1b > +4: > + not t1, t1 > + CZ t1, t1 > + srli t1, t1, 3 > + > + /* Get number of processed bytes. */ > + sub t2, t0, t2 > + > + /* Add number of characters in the first word. */ > + add a0, a0, t2 > + > + /* Add number of characters in the last word. */ > + add a0, a0, t1 > + > + /* Ensure the final result does not exceed maxlen. */ > + bgeu a0, a1, 3f minu a0, a0, a1 > +2: > + ret > +3: > + mv a0, a1 > + ret > + > +.option pop -- Qingfang
