--- uae/src/md-i386-gcc/support.c 2018/04/24 16:39:33 1.1.1.1 +++ uae/src/md-i386-gcc/support.c 2018/04/24 16:40:31 1.1.1.2 @@ -14,6 +14,12 @@ #include "options.h" #include "machdep/m68k.h" +#ifndef USE_UNDERSCORE +#define LARGE_ALIGNMENT ".align 16\n" +#else +#define LARGE_ALIGNMENT ".align 4,0x90\n" +#endif + struct flag_struct regflags; /* @@ -59,37 +65,32 @@ int fast_memcmp(const void *foo, const v int memcmpy(void *foo, const void *bar, int len) { - int differs, baz = 0, uupzuq = 0; + int differs = 0, baz = 0, uupzuq = 0; __asm__ __volatile__ ("subl %1, %2\n" - "movl $0, %0\n" "subl $16, %3\n" "jc LLB7\n" - + LARGE_ALIGNMENT "LLB8:\n" - "movl (%1),%%ecx\n" "movl (%2,%1),%%ebx\n" - "xorl %%ebx, %%ecx\n" - "movl %%ebx, (%1)\n" - "orl %%ecx, %0\n" + "movl (%1),%%ecx\n" + "cmpl %%ebx, %%ecx\n" + "jne LLC1\n" "movl 4(%2,%1),%%ebx\n" "movl 4(%1),%%ecx\n" - "xorl %%ebx, %%ecx\n" - "movl %%ebx, 4(%1)\n" - "orl %%ecx, %0\n" + "cmpl %%ebx, %%ecx\n" + "jne LLC2\n" "movl 8(%2,%1),%%ebx\n" "movl 8(%1),%%ecx\n" - "xorl %%ebx, %%ecx\n" - "movl %%ebx, 8(%1)\n" - "orl %%ecx, %0\n" + "cmpl %%ebx, %%ecx\n" + "jne LLC3\n" "movl 12(%2,%1),%%ebx\n" "movl 12(%1),%%ecx\n" - "xorl %%ebx, %%ecx\n" - "movl %%ebx, 12(%1)\n" - "orl %%ecx, %0\n" + "cmpl %%ebx, %%ecx\n" + "jne LLC4\n" "addl $16, %1\n" "subl $16, %3\n" @@ -99,35 +100,109 @@ int memcmpy(void *foo, const void *bar, "addl $16, %3\n" "subl $4, %3\n" "jc LLB2\n" - + "LLB1:\n" "movl (%2,%1),%%ebx\n" "movl (%1),%%ecx\n" - "xorl %%ebx, %%ecx\n" - "movl %%ebx, (%1)\n" - "orl %%ecx, %0\n" + "cmpl %%ebx, %%ecx\n" + "jne LLC5\n" "addl $4, %1\n" "subl $4, %3\n" "jnc LLB1\n" "LLB2:\n" "addl $4, %3\n" - "jz LLB6\n" - "xorl %%ecx, %%ecx\n" + "jz LLB9\n" "LLB3:\n" "movb (%2,%1),%%bl\n" "movb (%1),%%cl\n" - "xorb %%bl,%%cl\n" - "movb %%bl,(%1)\n" - "orl %%ecx, %0\n" + "cmpb %%bl,%%cl\n" + "jne LLC6\n" "incl %1\n" "decl %3\n" "jnz LLB3\n" - "LLB6:\n" + "jmp LLB9\n" + + LARGE_ALIGNMENT + /* Once we find a difference, we switch to plain memcpy() */ + "LLC01:\n" + "movl (%2,%1),%%ebx\n" + "LLC1:\n" + "movl %%ebx, (%1)\n" + + "movl 4(%2,%1),%%ebx\n" + "LLC2:\n" + "movl %%ebx, 4(%1)\n" + + "movl 8(%2,%1),%%ebx\n" + "LLC3:\n" + "movl %%ebx, 8(%1)\n" + + "movl 12(%2,%1),%%ebx\n" + "LLC4:\n" + "movl %%ebx, 12(%1)\n" + + "addl $16, %1\n" +#if 0 + "movl $1,%0\n" + + "addl %1,%2\n" + "movl %3,%%ecx\n" + "shrl $2,%%ecx\n" + "je LLC02a\n" + "rep\n" + "movsl\n" + "andl $3,%3\n" + "je LLB9\n" + "LLC02a:\n" + "movb (%2),%%bl\n" + + "movb %%bl,(%1)\n" + "incl %1\n" + "decl %3\n" + "jnz LLC02a\n" + "jmp LLB9\n" +#else +#if 0 + "movl $1,%0\n" + "jnc LLB8\n" +#else + "subl $16, %3\n" + "jnc LLC01\n" +#endif + + "addl $16, %3\n" + "subl $4, %3\n" + "jc LLC03\n" +#endif + + "LLC02:\n" + "movl (%2,%1),%%ebx\n" + "LLC5:\n" + "movl %%ebx, (%1)\n" + "addl $4, %1\n" + "subl $4, %3\n" + "jnc LLC02\n" + + "LLC03:\n" + "addl $4, %3\n" + "jz LLC05\n" + + "LLC04:\n" + "movb (%2,%1),%%bl\n" + "LLC6:\n" + "movb %%bl,(%1)\n" + "incl %1\n" + "decl %3\n" + "jnz LLC04\n" + + "LLC05:\n" + "movl $1,%0\n" + "LLB9:" : "=m" (differs) - : "r" (foo), "r" (bar), "r" (len), "b" (baz), "c" (uupzuq) : "cc", "memory"); + : "D" (foo), "S" (bar), "r" (len), "b" (baz), "c" (uupzuq), "0" (differs) : "cc", "memory"); /* Now tell the compiler that foo, bar and len have been modified * If someone finds a way to express all this cleaner in constraints that * GCC 2.7.2 understands, please FIXME */ @@ -135,3 +210,53 @@ int memcmpy(void *foo, const void *bar, return differs; } + +#ifdef HAVE_RDTSC + +#include + +static volatile frame_time_t last_time, best_time; +static volatile int loops_to_go; + +#ifdef __cplusplus +static RETSIGTYPE alarmhandler(...) +#else +static RETSIGTYPE alarmhandler(int foo) +#endif +{ + frame_time_t bar; + bar = read_processor_time (); + if (bar - last_time < best_time) + best_time = bar - last_time; + if (--loops_to_go > 0) { + signal (SIGALRM, alarmhandler); + last_time = read_processor_time(); + alarm (1); + } +} + +void machdep_init (void) +{ + fprintf(stderr, "Calibrating delay loop.. "); + fflush(stderr); + best_time = (frame_time_t)-1; + loops_to_go = 5; + signal (SIGALRM, alarmhandler); + /* We want exact values... */ + sync (); sync (); sync (); + last_time = read_processor_time(); + alarm (1); + while (loops_to_go != 0) + usleep(1000000); + fprintf (stderr, "ok - %.2f BogoMIPS\n", + ((double)best_time / 1000000), best_time); + vsynctime = best_time / 50; +} + +#else + +void machdep_init (void) +{ +} + +#endif