string.c: make it 64-bit compatible
Casting a pointer to an int produces warnings with 64-bit targets. Furthermore, an int is not always the optimal memory element that can be copied in that case. Let's use uintptr_t to cast pointers to integers for alignment determination purposes, and mem_word_t to denote the optimal memory "word" that can be copied on the platform. The mem_word_t definition is equivalent to uintptr_t by default. However, some 32-bit targets such as ARM platforms with the LDRD/STRD instructions could benefit from word_t being an uint64_t. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
98627ccc20
commit
03170c040c
2 changed files with 31 additions and 11 deletions
|
@ -45,4 +45,18 @@ typedef int off_t;
|
|||
typedef int64_t time_t;
|
||||
typedef int32_t suseconds_t;
|
||||
|
||||
#if !defined(__mem_word_t_defined)
|
||||
#define __mem_word_t_defined
|
||||
|
||||
/*
|
||||
* The mem_word_t should match the optimal memory access word width
|
||||
* on the target platform. Here we defaults it to uintptr_t.
|
||||
*/
|
||||
|
||||
typedef uintptr_t mem_word_t;
|
||||
|
||||
#define Z_MEM_WORD_T_WIDTH __INTPTR_WIDTH__
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_SYS_TYPES_H_ */
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -241,12 +243,13 @@ void *memcpy(void *_MLIBC_RESTRICT d, const void *_MLIBC_RESTRICT s, size_t n)
|
|||
|
||||
unsigned char *d_byte = (unsigned char *)d;
|
||||
const unsigned char *s_byte = (const unsigned char *)s;
|
||||
const uintptr_t mask = sizeof(mem_word_t) - 1;
|
||||
|
||||
if ((((unsigned int)d ^ (unsigned int)s_byte) & 0x3) == 0U) {
|
||||
if ((((uintptr_t)d ^ (uintptr_t)s_byte) & mask) == 0) {
|
||||
|
||||
/* do byte-sized copying until word-aligned or finished */
|
||||
|
||||
while (((unsigned int)d_byte) & 0x3) {
|
||||
while (((uintptr_t)d_byte) & mask) {
|
||||
if (n == 0) {
|
||||
return d;
|
||||
}
|
||||
|
@ -256,12 +259,12 @@ void *memcpy(void *_MLIBC_RESTRICT d, const void *_MLIBC_RESTRICT s, size_t n)
|
|||
|
||||
/* do word-sized copying as long as possible */
|
||||
|
||||
unsigned int *d_word = (unsigned int *)d_byte;
|
||||
const unsigned int *s_word = (const unsigned int *)s_byte;
|
||||
mem_word_t *d_word = (mem_word_t *)d_byte;
|
||||
const mem_word_t *s_word = (const mem_word_t *)s_byte;
|
||||
|
||||
while (n >= sizeof(unsigned int)) {
|
||||
while (n >= sizeof(mem_word_t)) {
|
||||
*(d_word++) = *(s_word++);
|
||||
n -= sizeof(unsigned int);
|
||||
n -= sizeof(mem_word_t);
|
||||
}
|
||||
|
||||
d_byte = (unsigned char *)d_word;
|
||||
|
@ -292,7 +295,7 @@ void *memset(void *buf, int c, size_t n)
|
|||
unsigned char *d_byte = (unsigned char *)buf;
|
||||
unsigned char c_byte = (unsigned char)c;
|
||||
|
||||
while (((unsigned int)d_byte) & 0x3) {
|
||||
while (((uintptr_t)d_byte) & (sizeof(mem_word_t) - 1)) {
|
||||
if (n == 0) {
|
||||
return buf;
|
||||
}
|
||||
|
@ -302,15 +305,18 @@ void *memset(void *buf, int c, size_t n)
|
|||
|
||||
/* do word-sized initialization as long as possible */
|
||||
|
||||
unsigned int *d_word = (unsigned int *)d_byte;
|
||||
unsigned int c_word = (unsigned int)(unsigned char)c;
|
||||
mem_word_t *d_word = (mem_word_t *)d_byte;
|
||||
mem_word_t c_word = (mem_word_t)c_byte;
|
||||
|
||||
c_word |= c_word << 8;
|
||||
c_word |= c_word << 16;
|
||||
#if Z_MEM_WORD_T_WIDTH > 32
|
||||
c_word |= c_word << 32;
|
||||
#endif
|
||||
|
||||
while (n >= sizeof(unsigned int)) {
|
||||
while (n >= sizeof(mem_word_t)) {
|
||||
*(d_word++) = c_word;
|
||||
n -= sizeof(unsigned int);
|
||||
n -= sizeof(mem_word_t);
|
||||
}
|
||||
|
||||
/* do byte-sized initialization until finished */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue