arm-trusted-firmware/include/lib/libc/string.h
Boyan Karatotev 34d7f196b4 perf(libc): use builtin implementations where possible
When conditions are right, eg a small memcpy of a known size and
alignment, the compiler may know of a sequence that is optimal for the
given constraints and inline it. If the compiler doesn't find one, it
will emit a call to the generic function (in the libc) which will
implement this in the most generic and unconstrained manner. That
generic function is rarely the most optimal when constraints are known.

So give the compiler a chance to do this. Replace calls to libc
functions that have builtins to the builtin and keep the generic
implementation if it decides to emit a call anyway.

And example of this in action is usage of FEAT_MOPS. When the compiler
is aware of the feature (-march=armv8.8-a) then it will emit the 3 MOPS
instructions instead of calls to our memcpy() and memset()
implementations.

Change-Id: I9860cfada1d941b613ebd4da068e9992c387952e
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
2025-04-04 09:27:33 +01:00

43 lines
1.4 KiB
C

/*
* Copyright (c) 2012-2017 Roberto E. Vargas Caballero
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Portions copyright (c) 2018-2025, Arm Limited and Contributors.
* Portions copyright (c) 2023, Intel Corporation. All rights reserved.
* All rights reserved.
*/
#ifndef STRING_H
#define STRING_H
#include <stddef.h>
/*
* When conditions are right, the compiler may have a baked-in call that can be
* inlined and that will be much more optimal than our generic implementation.
* When it doesn't, it will emit a call to the original function for which we
* provide an implementation.
*/
#define memcpy __builtin_memcpy
#define memset __builtin_memset
#define memcmp __builtin_memcmp
#define memchr __builtin_memchr
#define strcmp __builtin_strcmp
#define strncmp __builtin_strncmp
#define strchr __builtin_strchr
#define strlen __builtin_strlen
#define strrchr __builtin_strrchr
int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize);
void *memmove(void *dst, const void *src, size_t len);
void *memrchr(const void *src, int c, size_t len);
size_t strnlen(const char *s, size_t maxlen);
size_t strlcpy(char * dst, const char * src, size_t dsize);
size_t strlcat(char * dst, const char * src, size_t dsize);
char *strtok_r(char *s, const char *delim, char **last);
size_t strnlen_secure(const char *str, size_t maxlen);
int strcpy_secure(char *restrict dest, size_t dest_size, const char *restrict src);
#endif /* STRING_H */