Re: [PATCH 2/3] newlib: riscv: Optimize memchr() and memrchr()
Eric Salem <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
On 5/7/25 8:44 AM, Kito Cheng wrote:
>> - src = (unsigned char *) asrc;
>> + if (src < end_addr)
>> + {
>> + uintxlen_t mask = __libc_splat_byte(d);
>> + uintlslen_t val;
>> +
>> + do
>> + {
>> +#if __riscv_zilsd
>> + asm volatile ("ld %0, 0(%1)"
>> + : "=R" (val)
>> + : "r" (src)
>> + );
>
> I strongly prefer not to use inline asm here, let the compiler do
> that, although I know upstream GCC doesn't implement that yet...
Here's an example trying to use Zilsd/Zclsd in C:
$ cat << EOF > test.c
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint64_t val;
uint64_t *p = &val;
p = &val;
*p = 0x700000005;
printf("%p %llu\n", p, val);
}
EOF
$ clang -march=rv32ic_zclsd_zilsd -O3 -c test.c
$ llvm-objdump --disassemble-symbols=main test.o
test.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <main>:
0: 1141 addi sp, sp, -0x10
2: c606 sw ra, 0xc(sp)
4: 451d li a0, 0x7
6: 4595 li a1, 0x5
8: c02e sw a1, 0x0(sp)
a: c22a sw a0, 0x4(sp)
c: 00000537 lui a0, 0x0
10: 00050513 mv a0, a0
14: 858a mv a1, sp
16: 4615 li a2, 0x5
18: 469d li a3, 0x7
1a: 00000097 auipc ra, 0x0
1e: 000080e7 jalr ra <main+0x1a>
22: 4501 li a0, 0x0
24: 40b2 lw ra, 0xc(sp)
26: 0141 addi sp, sp, 0x10
28: 8082 ret
Clang uses an even-odd register pair, but doesn't place the lower-order
bits in a0, and the higher in a1. If it did, it could use a single sd
instruction instead.
I think once support is better we'll be able to rely upon the compiler,
whether it requires the use of intrinsics or not. But for the time
being I don't see how you can use Zilsd/Zclsd in C without inline
assembly.