|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Miscellaneous machine dependent support functions and definitions
5: *
6: * Copyright 1996 Bernd Schmidt
7: */
8:
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12:
13: #include "config.h"
14: #include "options.h"
15: #include "machdep/m68k.h"
16: #include "machdep/penguin.h"
17:
18: struct flag_struct regflags;
19:
20: /*
21: * Careful: No unique labels. Unfortunately, not each installation of GCC
22: * comes with GAS. Bletch.
23: */
24:
25: int fast_memcmp(const void *foo, const void *bar, int len)
26: {
27: int differs, baz;
28: __asm__ __volatile__ ("subl $4, %2\n"
29: "jc LLA2\n"
30: "LLA1:\n"
31: "movl (%0),%%ebx\n"
32: "cmpl (%1),%%ebx\n"
33: "jne LLA5\n"
34: "addl $4, %0\n"
35: "addl $4, %1\n"
36: "subl $4, %2\n"
37: "jnc LLA1\n"
38: "LLA2:\n"
39: "addl $4, %2\n"
40: "jz LLA4\n"
41: "LLA3:\n"
42: "movb (%0),%%bl\n"
43: "cmpb (%1),%%bl\n"
44: "jne LLA5\n"
45: "incl %0\n"
46: "incl %1\n"
47: "decl %2\n"
48: "jnz LLA3\n"
49: "LLA4:\n"
50: "movl $0, %3\n"
51: "jmp LLA6\n"
52: "LLA5:\n"
53: "movl $1, %3\n"
54: "LLA6:\n"
55: : "=&r" (foo), "=&r" (bar), "=&rm" (len), "=rm" (differs),
56: "=&b" (baz)
57: : "0" (foo), "1" (bar), "2" (len), "3" (baz) : "cc");
58: return differs;
59: }
60:
61: int memcmpy(void *foo, const void *bar, int len)
62: {
63: int differs, baz = 0, uupzuq = 0;
64:
65: __asm__ __volatile__ ("subl %1, %2\n"
66: "subl $16, %3\n"
67: "jc LLB7\n"
68: ".align 16\n"
69: "LLB8:\n"
70: "movl (%2,%1),%%ebx\n"
71: "movl (%1),%%ecx\n"
72: "cmpl %%ebx, %%ecx\n"
73: "jne LLC1\n"
74:
75: "movl 4(%2,%1),%%ebx\n"
76: "movl 4(%1),%%ecx\n"
77: "cmpl %%ebx, %%ecx\n"
78: "jne LLC2\n"
79:
80: "movl 8(%2,%1),%%ebx\n"
81: "movl 8(%1),%%ecx\n"
82: "cmpl %%ebx, %%ecx\n"
83: "jne LLC3\n"
84:
85: "movl 12(%2,%1),%%ebx\n"
86: "movl 12(%1),%%ecx\n"
87: "cmpl %%ebx, %%ecx\n"
88: "jne LLC4\n"
89:
90: "addl $16, %1\n"
91: "subl $16, %3\n"
92: "jnc LLB8\n"
93:
94: "LLB7:\n"
95: "addl $16, %3\n"
96: "subl $4, %3\n"
97: "jc LLB2\n"
98:
99: "LLB1:\n"
100: "movl (%2,%1),%%ebx\n"
101: "movl (%1),%%ecx\n"
102: "cmpl %%ebx, %%ecx\n"
103: "jne LLC5\n"
104: "addl $4, %1\n"
105: "subl $4, %3\n"
106: "jnc LLB1\n"
107:
108: "LLB2:\n"
109: "addl $4, %3\n"
110: "jz LLB6\n"
111:
112: "LLB3:\n"
113: "movb (%2,%1),%%bl\n"
114: "movb (%1),%%cl\n"
115: "cmpb %%bl,%%cl\n"
116: "jne LLC6\n"
117: "incl %1\n"
118: "decl %3\n"
119: "jnz LLB3\n"
120:
121: "LLB6:\n"
122: "movl $0,%0\n"
123: "jmp LLB9\n"
124:
125: ".align 16\n"
126: /* Once we find a difference, we switch to plain memcpy() */
127: "LLC01:\n"
128: "movl (%2,%1),%%ebx\n"
129: "LLC1:\n"
130: "movl %%ebx, (%1)\n"
131:
132: "movl 4(%2,%1),%%ebx\n"
133: "LLC2:\n"
134: "movl %%ebx, 4(%1)\n"
135:
136: "movl 8(%2,%1),%%ebx\n"
137: "LLC3:\n"
138: "movl %%ebx, 8(%1)\n"
139:
140: "movl 12(%2,%1),%%ebx\n"
141: "LLC4:\n"
142: "movl %%ebx, 12(%1)\n"
143:
144: "addl $16, %1\n"
145: "subl $16, %3\n"
146: /* There's a choice here whether we want to jump to LLB8 or LLC01. Jumping to LLB8
147: * might be a little more efficient if there's little change in the line, but is
148: * probably a loss if the line is completely different. */
149: "jnc LLC01\n"
150:
151: "addl $16, %3\n"
152: "subl $4, %3\n"
153: "jc LLC03\n"
154:
155: "LLC02:\n"
156: "movl (%2,%1),%%ebx\n"
157: "LLC5:\n"
158: "movl %%ebx, (%1)\n"
159: "addl $4, %1\n"
160: "subl $4, %3\n"
161: "jnc LLC02\n"
162:
163: "LLC03:\n"
164: "addl $4, %3\n"
165: "jz LLC05\n"
166:
167: "LLC04:\n"
168: "movb (%2,%1),%%bl\n"
169: "LLC6:\n"
170: "movb %%bl,(%1)\n"
171: "incl %1\n"
172: "decl %3\n"
173: "jnz LLC04\n"
174:
175: "LLC05:\n"
176: "movl $1,%0\n"
177: "LLB9:"
178: : "=m" (differs)
179: : "r" (foo), "r" (bar), "r" (len), "b" (baz), "c" (uupzuq) : "cc", "memory");
180: /* Now tell the compiler that foo, bar and len have been modified
181: * If someone finds a way to express all this cleaner in constraints that
182: * GCC 2.7.2 understands, please FIXME */
183: __asm__ __volatile__ ("" : "=rm" (foo), "=rm" (bar), "=rm" (len) : : "ebx", "ecx", "edx", "eax", "esi", "memory");
184:
185: return differs;
186: }
187:
188: #ifdef SUPPORT_PENGUINS
189:
190: #include <linux/sched.h>
191: #include <linux/unistd.h>
192:
193: static __inline__ _syscall2 (int, clone, unsigned long, flags, void *, sp);
194:
195: penguin_id start_penguin (void (*f) ())
196: {
197: penguin_id n;
198: n = clone (CLONE_VM | CLONE_FILES | CLONE_FS | SIGCHLD, ((char *)malloc (10000)) + 8000 /* Whatever */);
199: if (n == 0) {
200: f();
201: printf("Penguin returned!\n");
202: abort();
203: }
204: return n;
205: }
206: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.