/* Минимальная LD_PRELOAD-замена memcpy/memmove для 32-битных процессов (диагностика).
 *
 * Запись идёт через "rep movsb" и приёмник перед записью не читается.
 * Применена, чтобы показать: замена только memcpy/memmove на нативной ALT p11
 * (i586-glibc-core 2.38.0.223.f053ff-alt1.p11.1) возвращает FPS нативной
 * Half-Life 2 с 20-30 до 180 в "тяжёлой" сцене, без других изменений.
 * Это не исправление glibc и не оптимизированная реализация (нет memset и др.).
 *
 * Сборка:
 *   gcc -m32 -O2 -shared -fPIC -fno-builtin -fno-tree-loop-distribute-patterns \
 *       -fno-stack-protector -o libfastmemcpy.so fastmemcpy.c
 * Использование (параметры запуска Steam-игры):
 *   LD_PRELOAD=/путь/libfastmemcpy.so %command%
 */
#include <stddef.h>

void *memcpy(void *restrict d, const void *restrict s, size_t n) {
    void *r = d;
    __asm__ volatile("cld; rep movsb" : "+D"(d), "+S"(s), "+c"(n) : : "memory");
    return r;
}

void *memmove(void *d, const void *s, size_t n) {
    unsigned char *dd = d; const unsigned char *ss = s;
    if (dd <= ss || dd >= ss + n) { return memcpy(d, s, n); }
    while (n >= 4) { n -= 4; *(unsigned int *)(dd + n) = *(const unsigned int *)(ss + n); }
    while (n) { n--; dd[n] = ss[n]; }
    return d;
}
