Different gcc versions handle __builtin_memcpy differently.
Add -minline-all-string to force inlining of memcpy on old gcc.
Always use __builtin_memcpy for all memcpy calls.
Use memcpy4() for the option rom case where 4-byte accesses is important.
COMMONCFLAGS = -Wall -Os -MD -m32 -march=i386 -mregparm=3 \
-mpreferred-stack-boundary=2 -mrtd -freg-struct-return \
-ffreestanding -fwhole-program -fomit-frame-pointer \
- -fno-delete-null-pointer-checks -Wno-strict-aliasing
+ -fno-delete-null-pointer-checks -Wno-strict-aliasing \
+ -minline-all-stringops
COMMONCFLAGS += $(call cc-option,$(CC),-nopie,)
COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
}
dprintf(4, "Copying option rom (size %d) from %p to %x\n"
, romsize, rom, next_rom);
- memcpy((void*)next_rom, rom, romsize);
+ memcpy4((void*)next_rom, rom, romsize);
return (struct rom_header *)next_rom;
}
: "cc", "memory");
}
-noinline void *
-__memcpy(void *d1, const void *s1, size_t len)
+// Memcpy that uses 4-byte accesses
+void
+memcpy4(void *d1, const void *s1, size_t len)
{
- void *d = d1;
- if (((u32)d1 | (u32)s1 | len) & 3) {
- // non-aligned memcpy
- asm volatile(
- "rep movsb (%%esi),%%es:(%%edi)\n"
- : "+c"(len), "+S"(s1), "+D"(d)
- : : "cc", "memory");
- return d1;
- }
- // Common case - use 4-byte copy
len /= 4;
asm volatile(
"rep movsl (%%esi),%%es:(%%edi)\n"
- : "+c"(len), "+S"(s1), "+D"(d)
+ : "+c"(len), "+S"(s1), "+D"(d1)
: : "cc", "memory");
- return d1;
}
void *
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
void *memset(void *s, int c, size_t n);
-void *__memcpy(void *d1, const void *s1, size_t len);
-#define memcpy(d1, s1, len) ( \
- (__builtin_constant_p(len) && (len) <= 20) \
- ? __builtin_memcpy((d1), (s1), (len)) \
- : __memcpy((d1), (s1), (len)))
+void memcpy4(void *d1, const void *s1, size_t len);
+#define memcpy(d1, s1, len) __builtin_memcpy((d1), (s1), (len))
inline void memcpy_far(u16 d_seg, void *d_far
, u16 s_seg, const void *s_far, size_t len);
void *memmove(void *d, const void *s, size_t len);