libc: add risc-v libc function

Porting memory and string optimize functions from newlib and bionic

Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
zhangyuan21 2023-01-05 11:12:09 +08:00 committed by Xiang Xiao
parent fc9aeb8c70
commit f8f29c8147
14 changed files with 409 additions and 128 deletions

14
LICENSE
View file

@ -739,6 +739,20 @@ libs/libc/machine/arm/armv8-m/gnu/arch_strlen.S
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
libs/libc/machine/risc-v/gnu/arch_memset.S
libs/libc/machine/risc-v/gnu/arch_strcmp.S
================================================
Copyright (c) 2017 SiFive Inc. All rights reserved.
This copyrighted material is made available to anyone wishing to use,
modify, copy, or redistribute it subject to the terms and conditions
of the FreeBSD License. This program is distributed in the hope that
it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
including the implied warranties of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. A copy of this license is available at
http://www.opensource.org/licenses.
libs/libc/misc/lib_crc32.c
=========================

View file

@ -3,7 +3,26 @@
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_RV64
source "libs/libc/machine/risc-v/rv64/Kconfig"
endif
config RISCV_MEMCPY
bool "Enable optimized memcpy() for RISC-V"
select LIBC_ARCH_MEMCPY
depends on ARCH_TOOLCHAIN_GNU
---help---
Enable optimized RISC-V specific memcpy() library function
config RISCV_MEMSET
bool "Enable optimized memset() for RISC-V"
default n
select LIBC_ARCH_MEMSET
depends on ARCH_TOOLCHAIN_GNU
---help---
Enable optimized RISC-V specific memset() library function
config RISCV_STRCMP
bool "Enable optimized strcmp() for RISC-V"
default n
select LIBC_ARCH_STRCMP
depends on ARCH_TOOLCHAIN_GNU
---help---
Enable optimized RISC-V specific strcmp() library function

View file

@ -18,12 +18,30 @@
#
############################################################################
include $(TOPDIR)/libs/libc/machine/risc-v/common/Make.defs
ifeq ($(CONFIG_ARCH_RV64),y)
include $(TOPDIR)/libs/libc/machine/risc-v/rv64/Make.defs
ifeq ($(CONFIG_RISCV_MEMCPY),y)
ASRCS += arch_memcpy.S
endif
ifeq ($(CONFIG_ARCH_RV32),y)
include $(TOPDIR)/libs/libc/machine/risc-v/rv32/Make.defs
ifeq ($(CONFIG_RISCV_MEMSET),y)
ASRCS += arch_memset.S
endif
ifeq ($(CONFIG_RISCV_STRCMP),y)
ASRCS += arch_strcmp.S
endif
ifeq ($(CONFIG_ARCH_SETJMP_H),y)
ASRCS += arch_setjmp.S
endif
ifeq ($(CONFIG_LIBC_ARCH_ELF),y)
CSRCS += arch_elf.c
endif
ifeq ($(CONFIG_ARCH_TOOLCHAIN_GNU),y)
DEPPATH += --dep-path machine/risc-v/gnu
VPATH += :machine/risc-v/gnu
endif
DEPPATH += --dep-path machine/risc-v
VPATH += :machine/risc-v

View file

@ -1,5 +1,5 @@
/****************************************************************************
* libs/libc/machine/risc-v/common/arch_elf.c
* libs/libc/machine/risc-v/arch_elf.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with

View file

@ -1,30 +0,0 @@
############################################################################
# libs/libc/machine/risc-v/common/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifeq ($(CONFIG_LIBC_ARCH_ELF),y)
CSRCS += arch_elf.c
endif
ifeq ($(CONFIG_ARCH_SETJMP_H),y)
ASRCS += arch_setjmp.S
endif
DEPPATH += --dep-path machine/risc-v/common
VPATH += :machine/risc-v/common

View file

@ -1,5 +1,5 @@
/****************************************************************************
* libs/libc/machine/risc-v/rv32/arch_memcpy.S
* libs/libc/machine/risc-v/gnu/arch_memcpy.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with

View file

@ -0,0 +1,106 @@
/****************************************************************************
* libs/libc/machine/risc-v/gnu/arch_memset.S
*
* Copyright (c) 2017 SiFive Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the FreeBSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses.
*
****************************************************************************/
.text
.global memset
.type memset, @function
memset:
li t1, 15
move a4, a0
bleu a2, t1, .Ltiny
and a5, a4, 15
bnez a5, .Lmisaligned
.Laligned:
bnez a1, .Lwordify
.Lwordified:
and a3, a2, ~15
and a2, a2, 15
add a3, a3, a4
#if __riscv_xlen == 64
1:
sd a1, 0(a4)
sd a1, 8(a4)
#else
1:
sw a1, 0(a4)
sw a1, 4(a4)
sw a1, 8(a4)
sw a1, 12(a4)
#endif
add a4, a4, 16
bltu a4, a3, 1b
bnez a2, .Ltiny
ret
.Ltiny:
sub a3, t1, a2
sll a3, a3, 2
1:
auipc t0, %pcrel_hi(.Ltable)
add a3, a3, t0
.option push
.option norvc
.Ltable_misaligned:
jr a3, %pcrel_lo(1b)
.Ltable:
sb a1,14(a4)
sb a1,13(a4)
sb a1,12(a4)
sb a1,11(a4)
sb a1,10(a4)
sb a1, 9(a4)
sb a1, 8(a4)
sb a1, 7(a4)
sb a1, 6(a4)
sb a1, 5(a4)
sb a1, 4(a4)
sb a1, 3(a4)
sb a1, 2(a4)
sb a1, 1(a4)
sb a1, 0(a4)
.option pop
ret
.Lwordify:
and a1, a1, 0xFF
sll a3, a1, 8
or a1, a1, a3
sll a3, a1, 16
or a1, a1, a3
#if __riscv_xlen == 64
sll a3, a1, 32
or a1, a1, a3
#endif
j .Lwordified
.Lmisaligned:
sll a3, a5, 2
1:
auipc t0, %pcrel_hi(.Ltable_misaligned)
add a3, a3, t0
mv t0, ra
jalr a3, %pcrel_lo(1b)
mv ra, t0
add a5, a5, -16
sub a4, a4, a5
add a2, a2, a5
bleu a2, t1, .Ltiny
j .Laligned
.size memset, .-memset

View file

@ -1,5 +1,5 @@
############################################################################
# libs/libc/machine/risc-v/common/arch_setjmp.S
# libs/libc/machine/risc-v/gnu/arch_setjmp.S
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
@ -18,31 +18,7 @@
#
############################################################################
#include <nuttx/config.h>
#ifdef CONFIG_ARCH_RV64
# define SZREG 8
# define REG_S sd
# define REG_L ld
#elif defined(CONFIG_ARCH_RV32)
# define SZREG 4
# define REG_S sw
# define REG_L lw
#endif
#ifdef CONFIG_ARCH_QPFPU
# define SZFREG 16
# define FREG_S fsq
# define FREG_L flq
#elif defined(CONFIG_ARCH_DPFPU)
# define SZFREG 8
# define FREG_S fsd
# define FREG_L fld
#elif defined(CONFIG_ARCH_FPU)
# define SZFREG 4
# define FREG_S fsw
# define FREG_L flw
#endif
#include "asm.h"
.section .text
.globl setjmp

View file

@ -0,0 +1,187 @@
/****************************************************************************
* libs/libc/machine/risc-v/gnu/arch_strcmp.S
*
* Copyright (c) 2017 SiFive Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the FreeBSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses.
*
****************************************************************************/
#include "asm.h"
.text
.globl strcmp
.type strcmp, @function
strcmp:
or a4, a0, a1
li t2, -1
and a4, a4, SZREG-1
bnez a4, .Lmisaligned
#if SZREG == 4
li a5, 0x7f7f7f7f
#else
ld a5, mask
#endif
.macro check_one_word i n
REG_L a2, \i*SZREG(a0)
REG_L a3, \i*SZREG(a1)
and t0, a2, a5
or t1, a2, a5
add t0, t0, a5
or t0, t0, t1
bne t0, t2, .Lnull\i
.if \i+1-\n
bne a2, a3, .Lmismatch
.else
add a0, a0, \n*SZREG
add a1, a1, \n*SZREG
beq a2, a3, .Lloop
# fall through to .Lmismatch
.endif
.endm
.macro foundnull i n
.ifne \i
.Lnull\i:
add a0, a0, \i*SZREG
add a1, a1, \i*SZREG
.ifeq \i-1
.Lnull0:
.endif
bne a2, a3, .Lmisaligned
li a0, 0
ret
.endif
.endm
.Lloop:
# examine full words at a time, favoring strings of a couple dozen chars
#if __riscv_xlen == 32
check_one_word 0 5
check_one_word 1 5
check_one_word 2 5
check_one_word 3 5
check_one_word 4 5
#else
check_one_word 0 3
check_one_word 1 3
check_one_word 2 3
#endif
# backwards branch to .Lloop contained above
.Lmismatch:
# words don't match, but a2 has no null byte.
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#if __riscv_xlen == 64
sll a4, a2, 48
sll a5, a3, 48
bne a4, a5, .Lmismatch_upper
sll a4, a2, 32
sll a5, a3, 32
bne a4, a5, .Lmismatch_upper
#endif
sll a4, a2, 16
sll a5, a3, 16
bne a4, a5, .Lmismatch_upper
srl a4, a2, 8*SZREG-16
srl a5, a3, 8*SZREG-16
sub a0, a4, a5
and a1, a0, 0xff
bnez a1, 1f
ret
.Lmismatch_upper:
srl a4, a4, 8*SZREG-16
srl a5, a5, 8*SZREG-16
sub a0, a4, a5
and a1, a0, 0xff
bnez a1, 1f
ret
1:
and a4, a4, 0xff
and a5, a5, 0xff
sub a0, a4, a5
ret
#else
#if __riscv_xlen == 64
srl a4, a2, 48
srl a5, a3, 48
bne a4, a5, .Lmismatch_lower
srl a4, a2, 32
srl a5, a3, 32
bne a4, a5, .Lmismatch_lower
#endif
srl a4, a2, 16
srl a5, a3, 16
bne a4, a5, .Lmismatch_lower
srl a4, a2, 8
srl a5, a3, 8
bne a4, a5, 1f
and a4, a2, 0xff
and a5, a3, 0xff
1:
sub a0, a4, a5
ret
.Lmismatch_lower:
srl a2, a4, 8
srl a3, a5, 8
bne a2, a3, 1f
and a2, a4, 0xff
and a3, a5, 0xff
1:
sub a0, a2, a3
ret
#endif
.Lmisaligned:
# misaligned
lbu a2, 0(a0)
lbu a3, 0(a1)
add a0, a0, 1
add a1, a1, 1
bne a2, a3, 1f
bnez a2, .Lmisaligned
1:
sub a0, a2, a3
ret
# cases in which a null byte was detected
#if __riscv_xlen == 32
foundnull 0 5
foundnull 1 5
foundnull 2 5
foundnull 3 5
foundnull 4 5
#else
foundnull 0 3
foundnull 1 3
foundnull 2 3
#endif
.size strcmp, .-strcmp
#if SZREG == 8
.section .srodata.cst8,"aM",@progbits,8
.align 3
mask:
.dword 0x7f7f7f7f7f7f7f7f
#endif

View file

@ -0,0 +1,52 @@
/****************************************************************************
* libs/libc/machine/risc-v/gnu/asm.h
*
* Copyright (c) 2017 SiFive Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the FreeBSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses.
****************************************************************************/
#ifndef __LIBS_LIBC_MACHINE_RISCV_GNU_ASM_H
#define __LIBS_LIBC_MACHINE_RISCV_GNU_ASM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ARCH_RV64
# define SZREG 8
# define REG_S sd
# define REG_L ld
#else
# define SZREG 4
# define REG_S sw
# define REG_L lw
#endif
#ifdef CONFIG_ARCH_QPFPU
# define SZFREG 16
# define FREG_S fsq
# define FREG_L flq
#elif defined(CONFIG_ARCH_DPFPU)
# define SZFREG 8
# define FREG_S fsd
# define FREG_L fld
#elif defined(CONFIG_ARCH_FPU)
# define SZFREG 4
# define FREG_S fsw
# define FREG_L flw
#endif
#endif /* __LIBS_LIBC_MACHINE_RISCV_GNU_ASM_H */

View file

@ -1,10 +0,0 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config RISCV_MEMCPY
bool "Enable optimized memcpy() for RISC-V"
select LIBC_ARCH_MEMCPY
---help---
Enable optimized RISC-V specific memcpy() library function

View file

@ -1,27 +0,0 @@
############################################################################
# libs/libc/machine/risc-v/rv32/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifeq ($(CONFIG_RISCV_MEMCPY),y)
ASRCS += arch_memcpy.S
endif
DEPPATH += --dep-path machine/risc-v/rv32
VPATH += :machine/risc-v/rv32

View file

@ -1,4 +0,0 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#

View file

@ -1,20 +0,0 @@
############################################################################
# libs/libc/machine/risc-v/rv64/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################