File:  [UNIX Amiga Emulator] / uae / src / md-i386-linux / support.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:39:18 2018 UTC (8 years, 3 months ago) by root
Branches: MAIN, BSchmidt
CVS tags: uae068, HEAD
uae-0.6.8

 /* 
  * UAE - The Un*x Amiga Emulator
  * 
  * Miscellaneous machine dependent support functions and definitions
  *
  * Copyright 1996 Bernd Schmidt
  */


#include "sysconfig.h"
#include "sysdeps.h"

#include "config.h"
#include "options.h"
#include "machdep/m68k.h"
#include "machdep/penguin.h"

struct flag_struct regflags;

/*
 * Careful: No unique labels. Unfortunately, not each installation of GCC 
 * comes with GAS. Bletch.
 */

int fast_memcmp(const void *foo, const void *bar, int len)
{
    int differs, baz;
    __asm__ __volatile__ ("subl $4, %2\n"
			  "jc  LLA2\n"
			  "LLA1:\n"
			  "movl (%0),%%ebx\n"
			  "cmpl (%1),%%ebx\n"
			  "jne LLA5\n"
			  "addl $4, %0\n"
			  "addl $4, %1\n"
			  "subl $4, %2\n"
			  "jnc  LLA1\n"
			  "LLA2:\n"
			  "addl $4, %2\n"
			  "jz LLA4\n"
			  "LLA3:\n"
			  "movb (%0),%%bl\n"
			  "cmpb (%1),%%bl\n"
			  "jne LLA5\n"
			  "incl %0\n"
			  "incl %1\n"
			  "decl %2\n"
			  "jnz LLA3\n"
			  "LLA4:\n"
			  "movl $0, %3\n"
			  "jmp LLA6\n"
			  "LLA5:\n"
			  "movl $1, %3\n"
			  "LLA6:\n"
			  : "=&r" (foo), "=&r" (bar), "=&rm" (len), "=rm" (differs),
			    "=&b" (baz)
			  : "0" (foo), "1" (bar), "2" (len), "3" (baz) : "cc");
    return differs;
}

int memcmpy(void *foo, const void *bar, int len)
{
    int differs, baz = 0, uupzuq = 0;

    __asm__ __volatile__ ("subl %1, %2\n"
			  "subl $16, %3\n"
			  "jc LLB7\n"
			  ".align 16\n"
			  "LLB8:\n"
			  "movl (%2,%1),%%ebx\n"
			  "movl (%1),%%ecx\n"
			  "cmpl %%ebx, %%ecx\n"
			  "jne LLC1\n"
			  
			  "movl 4(%2,%1),%%ebx\n"
			  "movl 4(%1),%%ecx\n"
			  "cmpl %%ebx, %%ecx\n"
			  "jne LLC2\n"
			  
			  "movl 8(%2,%1),%%ebx\n"
			  "movl 8(%1),%%ecx\n"
			  "cmpl %%ebx, %%ecx\n"
			  "jne LLC3\n"
			  
			  "movl 12(%2,%1),%%ebx\n"
			  "movl 12(%1),%%ecx\n"
			  "cmpl %%ebx, %%ecx\n"
			  "jne LLC4\n"
			  
			  "addl $16, %1\n"
			  "subl $16, %3\n"
			  "jnc  LLB8\n"
			  
			  "LLB7:\n"
			  "addl $16, %3\n"
			  "subl $4, %3\n"
			  "jc  LLB2\n"

			  "LLB1:\n"
			  "movl (%2,%1),%%ebx\n"
			  "movl (%1),%%ecx\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"
			  
			  "LLB3:\n"
			  "movb (%2,%1),%%bl\n"
			  "movb (%1),%%cl\n"
			  "cmpb %%bl,%%cl\n"
			  "jne LLC6\n"
			  "incl %1\n"
			  "decl %3\n"
			  "jnz LLB3\n"
			  
			  "LLB6:\n"
			  "movl $0,%0\n"
			  "jmp LLB9\n"

			  ".align 16\n"
			  /* 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"
			  "subl $16, %3\n"
 /* There's a choice here whether we want to jump to LLB8 or LLC01. Jumping to LLB8
  * might be a little more efficient if there's little change in the line, but is
  * probably a loss if the line is completely different. */
			  "jnc  LLC01\n"
			  
			  "addl $16, %3\n"
			  "subl $4, %3\n"
			  "jc  LLC03\n"
			  
			  "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");
    /* 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 */
    __asm__ __volatile__ ("" : "=rm" (foo), "=rm" (bar), "=rm" (len) : :  "ebx", "ecx", "edx", "eax", "esi", "memory");

    return differs;
}

#ifdef SUPPORT_PENGUINS

#include <linux/sched.h>
#include <linux/unistd.h>

static __inline__ _syscall2 (int, clone, unsigned long, flags, void *, sp);

penguin_id start_penguin (void (*f) ())
{
    penguin_id n;
    n = clone (CLONE_VM | CLONE_FILES | CLONE_FS | SIGCHLD, ((char *)malloc (10000)) + 8000 /* Whatever */);
    if (n == 0) {
	f();
	printf("Penguin returned!\n");
	abort();
    }
    return n;
}
#endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.