Ad

Implement C standard function strlen as RISC-V.

Prototype: size_t rvv_strlen(const char* str)

Requirements:
Return the length of the given null-terminated byte string, that is, the number of characters in a character array whose first element is pointed to by str up to and not including the first null character. You don't have to handle illegal input.

Special Requirement:
You should use Vector Extension. The test is trying to check whether you really use Vector Extension.

As of October 2023, Codewars RISC-V RV64 supports Vector Extension 1.0 with VLEN = 128.

.section .text
.global rvv_strlen

# size_t rvv_strlen(const char* str)
rvv_strlen:
  mv a1, a0
  li a0, 0
  
.Loop:
  vsetvli t0, zero, e8, m8, ta, ma
  vle8ff.v v16, (a1)
  vmseq.vi v1, v16, 0
  vfirst.m t0, v1
  vmsbf.m v0, v1
  vcpop.m t1, v0
  add a0, a0, t1
  add a1, a1, t1
  bltz t0, .Loop
  
  ret

The original code used 32-bit system call.
I refactored the code to use 64-bit system call.

Code
Diff
  • global say_hello
    section .text
    say_hello:
      mov rax, 1 ; system call for write (for Linux 64)
      mov rdi, 1 ; file handle 1 is STDOUT
      lea rsi, [rel message] ; memory address of output buffer
      mov rdx, msgLen ; size of output buffer in bytes
      syscall ; invoke OS to do the write
      ret ; Return to the caller
    
    section .data ; Read-only data
    message db "Hello World!", 10 ; message = "Hello World!\n"
    msgLen equ $-message ; msgLen = strlen(message)
    • global say_hello
    • section .text
    • say_hello:
    • mov eax, 4 ; system call for write (for Linux)
    • mov ebx, 1 ; file handle 1 is STDOUT
    • mov ecx, message ; memory address of output buffer
    • mov edx, msgLen ; size of output buffer in bytes
    • int 0x80 ; invoke OS to do the write
    • mov rax, 1 ; system call for write (for Linux 64)
    • mov rdi, 1 ; file handle 1 is STDOUT
    • lea rsi, [rel message] ; memory address of output buffer
    • mov rdx, msgLen ; size of output buffer in bytes
    • syscall ; invoke OS to do the write
    • ret ; Return to the caller
    • section .data ; Read-only data
    • message db "Hello World!", 10 ; message = "Hello World!\n"
    • msgLen equ $-message ; msgLen = strlen(message)