Skip to content

Commit 32781cc

Browse files
committed
stmhal: Slightly improved memcpy; memset uses word store when aligned.
1 parent 5792500 commit 32781cc

1 file changed

Lines changed: 36 additions & 30 deletions

File tree

stmhal/string0.c

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,31 @@
3030
#define likely(x) __builtin_expect((x), 1)
3131

3232
void *memcpy(void *dst, const void *src, size_t n) {
33-
if (likely(!((long)dst&3) && !((long)src&3))) {
34-
//copy words from aligned pointers first
35-
long *d = dst;
36-
const long *s = src;
33+
if (likely(!(((uint32_t)dst) & 3) && !(((uint32_t)src) & 3))) {
34+
// pointers aligned
35+
uint32_t *d = dst;
36+
const uint32_t *s = src;
3737

38-
for (int i=(n>>2); i; i--) {
38+
// copy words first
39+
for (size_t i = (n >> 2); i; i--) {
3940
*d++ = *s++;
4041
}
4142

42-
//copy remaining bytes
43-
if (n&3) {
44-
char *d8 = (char*)d;
45-
const char *s8 =(char*) s;
46-
47-
switch (n&3) {
48-
case 1:
49-
*d8=*s8;
50-
break;
51-
case 2:
52-
*d8++=*s8++;
53-
*d8=*s8;
54-
break;
55-
case 3:
56-
*d8++=*s8++;
57-
*d8++=*s8++;
58-
*d8=*s8;
59-
break;
60-
}
43+
if (n & 2) {
44+
// copy half-word
45+
*(uint16_t*)d = *(const uint16_t*)s;
46+
d = (uint32_t*)((uint16_t*)d + 1);
47+
s = (const uint32_t*)((const uint16_t*)s + 1);
6148
}
6249

50+
if (n & 1) {
51+
// copy byte
52+
*((uint8_t*)d) = *((const uint8_t*)s);
53+
}
6354
} else {
64-
//unaligned access, copy bytes
65-
char *d = dst;
66-
const char *s = src;
55+
// unaligned access, copy bytes
56+
uint8_t *d = dst;
57+
const uint8_t *s = src;
6758

6859
for (; n; n--) {
6960
*d++ = *s++;
@@ -89,9 +80,24 @@ void *memmove(void *dest, const void *src, size_t n) {
8980
}
9081

9182
void *memset(void *s, int c, size_t n) {
92-
uint8_t *s2 = s;
93-
for (; n > 0; n--) {
94-
*s2++ = c;
83+
if (c == 0 && ((uint32_t)s & 3) == 0) {
84+
// aligned store of 0
85+
uint32_t *s32 = s;
86+
for (size_t i = n >> 2; i > 0; i--) {
87+
*s32++ = 0;
88+
}
89+
if (n & 2) {
90+
*((uint16_t*)s32) = 0;
91+
s32 = (uint32_t*)((uint16_t*)s32 + 1);
92+
}
93+
if (n & 1) {
94+
*((uint8_t*)s32) = 0;
95+
}
96+
} else {
97+
uint8_t *s2 = s;
98+
for (; n > 0; n--) {
99+
*s2++ = c;
100+
}
95101
}
96102
return s;
97103
}

0 commit comments

Comments
 (0)