Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions libs/libc/machine/risc-v/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,34 @@ if(CONFIG_RISCV_STRCMP)
list(APPEND SRCS arch_strcmp.S)
endif()

if(CONFIG_RISCV_MEMCHR)
list(APPEND SRCS arch_memchr.c)
endif()

if(CONFIG_RISCV_MEMCMP)
list(APPEND SRCS arch_memcmp.c)
endif()

if(CONFIG_RISCV_MEMMOVE)
list(APPEND SRCS arch_memmove.c)
endif()

if(CONFIG_RISCV_STRCPY)
list(APPEND SRCS arch_strcpy.c)
endif()

if(CONFIG_RISCV_STRLCPY)
list(APPEND SRCS arch_strlcpy.c)
endif()

if(CONFIG_RISCV_STRNCMP)
list(APPEND SRCS arch_strncmp.c)
endif()

if(CONFIG_RISCV_STRNLEN)
list(APPEND SRCS arch_strnlen.c)
endif()

if(CONFIG_ARCH_SETJMP_H)
list(APPEND SRCS arch_setjmp.S)
endif()
Expand Down
55 changes: 55 additions & 0 deletions libs/libc/machine/risc-v/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ config RISCV_STRING_FUNCTION
bool "Enable optimized RISC-V specific string function"
default n
depends on ARCH_TOOLCHAIN_GNU
select RISCV_MEMCHR
select RISCV_MEMCMP
select RISCV_MEMCPY
select RISCV_MEMMOVE
select RISCV_MEMSET
select RISCV_STRCMP
select RISCV_STRCPY
select RISCV_STRLCPY
select RISCV_STRNCMP
select RISCV_STRNLEN

config RISCV_MEMCPY
bool "Enable optimized memcpy() for RISC-V"
Expand All @@ -34,3 +41,51 @@ config RISCV_STRCMP
---help---
Enable optimized RISC-V specific strcmp() library function

config RISCV_MEMCHR
bool "Enable optimized memchr() for RISC-V"
default n
select LIBC_ARCH_MEMCHR
---help---
Enable optimized RISC-V specific memchr() library function

config RISCV_MEMCMP
bool "Enable optimized memcmp() for RISC-V"
default n
select LIBC_ARCH_MEMCMP
---help---
Enable optimized RISC-V specific memcmp() library function

config RISCV_MEMMOVE
bool "Enable optimized memmove() for RISC-V"
default n
select LIBC_ARCH_MEMMOVE
---help---
Enable optimized RISC-V specific memmove() library function

config RISCV_STRCPY
bool "Enable optimized strcpy() for RISC-V"
default n
select LIBC_ARCH_STRCPY
---help---
Enable optimized RISC-V specific strcpy() library function

config RISCV_STRNCMP
bool "Enable optimized strncmp() for RISC-V"
default n
select LIBC_ARCH_STRNCMP
---help---
Enable optimized RISC-V specific strncmp() library function

config RISCV_STRNLEN
bool "Enable optimized strnlen() for RISC-V"
default n
select LIBC_ARCH_STRNLEN
---help---
Enable optimized RISC-V specific strnlen() library function

config RISCV_STRLCPY
bool "Enable optimized strlcpy() for RISC-V"
default n
select LIBC_ARCH_STRLCPY
---help---
Enable optimized RISC-V specific strlcpy() library function
31 changes: 31 additions & 0 deletions libs/libc/machine/risc-v/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,37 @@ ifeq ($(CONFIG_RISCV_STRCMP),y)
ASRCS += arch_strcmp.S
endif

ifeq ($(CONFIG_RISCV_MEMCHR),y)
CSRCS += arch_memchr.c
endif

ifeq ($(CONFIG_RISCV_MEMCMP),y)
CSRCS += arch_memcmp.c
endif

ifeq ($(CONFIG_RISCV_MEMMOVE),y)
CSRCS += arch_memmove.c
endif



ifeq ($(CONFIG_RISCV_STRCPY),y)
CSRCS += arch_strcpy.c
endif

ifeq ($(CONFIG_RISCV_STRLCPY),y)
CSRCS += arch_strlcpy.c
endif

ifeq ($(CONFIG_RISCV_STRNCMP),y)
CSRCS += arch_strncmp.c
endif

ifeq ($(CONFIG_RISCV_STRNLEN),y)
CSRCS += arch_strnlen.c
endif


ifeq ($(CONFIG_ARCH_SETJMP_H),y)
ASRCS += arch_setjmp.S
endif
Expand Down
83 changes: 83 additions & 0 deletions libs/libc/machine/risc-v/arch_memchr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/****************************************************************************
* libs/libc/machine/risc-v/arch_memchr.c
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <string.h>

#include "arch_word.h"
#include "libc.h"

#ifdef CONFIG_LIBC_ARCH_MEMCHR

/****************************************************************************
* Public Functions
****************************************************************************/

FAR void *memchr(FAR const void *s, int c, size_t n)
{
FAR const unsigned char *p = s;
unsigned char uc = (unsigned char)c;
WORD_T rep = WORD_REPEAT(uc);

if (n >= 2 * WORD_BYTES)
{
while (!WORD_ALIGNED(p))
{
if (n == 0)
{
return NULL;
}

if (*p == uc)
{
return (FAR void *)p;
}

p++;
n--;
}

while (n >= WORD_BYTES &&
!WORD_HASZERO(*(FAR const WORD_T *)p ^ rep))
{
p += WORD_BYTES;
n -= WORD_BYTES;
}
}

while (n-- > 0)
{
if (*p == uc)
{
return (FAR void *)p;
}

p++;
}

return NULL;
}

#endif /* CONFIG_LIBC_ARCH_MEMCHR */
113 changes: 113 additions & 0 deletions libs/libc/machine/risc-v/arch_memcmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/****************************************************************************
* libs/libc/machine/risc-v/arch_memcmp.c
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <string.h>

#include "arch_word.h"
#include "libc.h"

#ifdef CONFIG_LIBC_ARCH_MEMCMP

/****************************************************************************
* Public Functions
****************************************************************************/

int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
{
FAR const unsigned char *a = s1;
FAR const unsigned char *b = s2;

/* Registers at a time when both pointers sit the same distance past a
* boundary; a byte head walks them up to it. Mismatched pointers stay
* byte by byte: a shifting compare pays for itself far later than a
* shifting copy does.
*/

if ((((uintptr_t)a ^ (uintptr_t)b) & (WORD_BYTES - 1)) == 0 &&
n >= 2 * WORD_BYTES)
{
while (!WORD_ALIGNED(a))
{
if (*a != *b)
{
return *a - *b;
}

a++;
b++;
n--;
}

/* Four words a turn, their differences OR-ed together so the
* loop carries a single branch. On a difference, fall out and
* let the byte loop find it: it is within four words of here.
*/

while (n >= 4 * WORD_BYTES)
{
WORD_T x = (((FAR const WORD_T *)a)[0] ^
((FAR const WORD_T *)b)[0]) |
(((FAR const WORD_T *)a)[1] ^
((FAR const WORD_T *)b)[1]) |
(((FAR const WORD_T *)a)[2] ^
((FAR const WORD_T *)b)[2]) |
(((FAR const WORD_T *)a)[3] ^
((FAR const WORD_T *)b)[3]);

if (x != 0)
{
break;
}

a += 4 * WORD_BYTES;
b += 4 * WORD_BYTES;
n -= 4 * WORD_BYTES;
}

while (n >= WORD_BYTES &&
*(FAR const WORD_T *)a == *(FAR const WORD_T *)b)
{
a += WORD_BYTES;
b += WORD_BYTES;
n -= WORD_BYTES;
}
}

while (n-- > 0)
{
if (*a != *b)
{
return *a - *b;
}

a++;
b++;
}

return 0;
}

#endif /* CONFIG_LIBC_ARCH_MEMCMP */
Loading
Loading