|
|
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"
1.1.1.3 root 16: #include "events.h"
1.1.1.5 ! root 17: #include "custom.h"
1.1 root 18:
1.1.1.2 root 19: #ifndef USE_UNDERSCORE
20: #define LARGE_ALIGNMENT ".align 16\n"
21: #else
22: #define LARGE_ALIGNMENT ".align 4,0x90\n"
23: #endif
24:
1.1 root 25: struct flag_struct regflags;
26:
27: /*
28: * Careful: No unique labels. Unfortunately, not each installation of GCC
29: * comes with GAS. Bletch.
30: */
31:
32: int fast_memcmp(const void *foo, const void *bar, int len)
33: {
34: int differs, baz;
35: __asm__ __volatile__ ("subl $4, %2\n"
36: "jc LLA2\n"
37: "LLA1:\n"
38: "movl (%0),%%ebx\n"
39: "cmpl (%1),%%ebx\n"
40: "jne LLA5\n"
41: "addl $4, %0\n"
42: "addl $4, %1\n"
43: "subl $4, %2\n"
44: "jnc LLA1\n"
45: "LLA2:\n"
46: "addl $4, %2\n"
47: "jz LLA4\n"
48: "LLA3:\n"
49: "movb (%0),%%bl\n"
50: "cmpb (%1),%%bl\n"
51: "jne LLA5\n"
52: "incl %0\n"
53: "incl %1\n"
54: "decl %2\n"
55: "jnz LLA3\n"
56: "LLA4:\n"
57: "movl $0, %3\n"
58: "jmp LLA6\n"
59: "LLA5:\n"
60: "movl $1, %3\n"
61: "LLA6:\n"
62: : "=&r" (foo), "=&r" (bar), "=&rm" (len), "=rm" (differs),
63: "=&b" (baz)
64: : "0" (foo), "1" (bar), "2" (len), "3" (baz) : "cc");
65: return differs;
66: }
67:
68: int memcmpy(void *foo, const void *bar, int len)
69: {
1.1.1.2 root 70: int differs = 0, baz = 0, uupzuq = 0;
1.1 root 71:
72: __asm__ __volatile__ ("subl %1, %2\n"
73: "subl $16, %3\n"
74: "jc LLB7\n"
1.1.1.2 root 75: LARGE_ALIGNMENT
1.1 root 76: "LLB8:\n"
77: "movl (%2,%1),%%ebx\n"
1.1.1.2 root 78: "movl (%1),%%ecx\n"
79: "cmpl %%ebx, %%ecx\n"
80: "jne LLC1\n"
1.1 root 81:
82: "movl 4(%2,%1),%%ebx\n"
83: "movl 4(%1),%%ecx\n"
1.1.1.2 root 84: "cmpl %%ebx, %%ecx\n"
85: "jne LLC2\n"
1.1 root 86:
87: "movl 8(%2,%1),%%ebx\n"
88: "movl 8(%1),%%ecx\n"
1.1.1.2 root 89: "cmpl %%ebx, %%ecx\n"
90: "jne LLC3\n"
1.1 root 91:
92: "movl 12(%2,%1),%%ebx\n"
93: "movl 12(%1),%%ecx\n"
1.1.1.2 root 94: "cmpl %%ebx, %%ecx\n"
95: "jne LLC4\n"
1.1 root 96:
97: "addl $16, %1\n"
98: "subl $16, %3\n"
99: "jnc LLB8\n"
100:
101: "LLB7:\n"
102: "addl $16, %3\n"
103: "subl $4, %3\n"
104: "jc LLB2\n"
1.1.1.2 root 105:
1.1 root 106: "LLB1:\n"
107: "movl (%2,%1),%%ebx\n"
108: "movl (%1),%%ecx\n"
1.1.1.2 root 109: "cmpl %%ebx, %%ecx\n"
110: "jne LLC5\n"
1.1 root 111: "addl $4, %1\n"
112: "subl $4, %3\n"
113: "jnc LLB1\n"
114:
115: "LLB2:\n"
116: "addl $4, %3\n"
1.1.1.2 root 117: "jz LLB9\n"
1.1 root 118:
119: "LLB3:\n"
120: "movb (%2,%1),%%bl\n"
121: "movb (%1),%%cl\n"
1.1.1.2 root 122: "cmpb %%bl,%%cl\n"
123: "jne LLC6\n"
1.1 root 124: "incl %1\n"
125: "decl %3\n"
126: "jnz LLB3\n"
127:
1.1.1.2 root 128: "jmp LLB9\n"
129:
130: LARGE_ALIGNMENT
131: /* Once we find a difference, we switch to plain memcpy() */
132: "LLC01:\n"
133: "movl (%2,%1),%%ebx\n"
134: "LLC1:\n"
135: "movl %%ebx, (%1)\n"
136:
137: "movl 4(%2,%1),%%ebx\n"
138: "LLC2:\n"
139: "movl %%ebx, 4(%1)\n"
140:
141: "movl 8(%2,%1),%%ebx\n"
142: "LLC3:\n"
143: "movl %%ebx, 8(%1)\n"
144:
145: "movl 12(%2,%1),%%ebx\n"
146: "LLC4:\n"
147: "movl %%ebx, 12(%1)\n"
148:
149: "addl $16, %1\n"
150: #if 0
151: "movl $1,%0\n"
152:
153: "addl %1,%2\n"
154: "movl %3,%%ecx\n"
155: "shrl $2,%%ecx\n"
156: "je LLC02a\n"
157: "rep\n"
158: "movsl\n"
159: "andl $3,%3\n"
160: "je LLB9\n"
161: "LLC02a:\n"
162: "movb (%2),%%bl\n"
163:
164: "movb %%bl,(%1)\n"
165: "incl %1\n"
166: "decl %3\n"
167: "jnz LLC02a\n"
168: "jmp LLB9\n"
169: #else
170: #if 0
171: "movl $1,%0\n"
172: "jnc LLB8\n"
173: #else
174: "subl $16, %3\n"
175: "jnc LLC01\n"
176: #endif
177:
178: "addl $16, %3\n"
179: "subl $4, %3\n"
180: "jc LLC03\n"
181: #endif
182:
183: "LLC02:\n"
184: "movl (%2,%1),%%ebx\n"
185: "LLC5:\n"
186: "movl %%ebx, (%1)\n"
187: "addl $4, %1\n"
188: "subl $4, %3\n"
189: "jnc LLC02\n"
190:
191: "LLC03:\n"
192: "addl $4, %3\n"
193: "jz LLC05\n"
194:
195: "LLC04:\n"
196: "movb (%2,%1),%%bl\n"
197: "LLC6:\n"
198: "movb %%bl,(%1)\n"
199: "incl %1\n"
200: "decl %3\n"
201: "jnz LLC04\n"
202:
203: "LLC05:\n"
204: "movl $1,%0\n"
205: "LLB9:"
1.1 root 206: : "=m" (differs)
1.1.1.2 root 207: : "D" (foo), "S" (bar), "r" (len), "b" (baz), "c" (uupzuq), "0" (differs) : "cc", "memory");
1.1 root 208: /* Now tell the compiler that foo, bar and len have been modified
209: * If someone finds a way to express all this cleaner in constraints that
210: * GCC 2.7.2 understands, please FIXME */
211: __asm__ __volatile__ ("" : "=rm" (foo), "=rm" (bar), "=rm" (len) : : "ebx", "ecx", "edx", "eax", "esi", "memory");
212:
213: return differs;
214: }
1.1.1.2 root 215:
1.1.1.3 root 216: /* All the Win32 configurations handle this in od-win32/win32.c */
217: #ifndef _WIN32
1.1.1.2 root 218:
219: #include <signal.h>
220:
221: static volatile frame_time_t last_time, best_time;
222: static volatile int loops_to_go;
223:
224: #ifdef __cplusplus
225: static RETSIGTYPE alarmhandler(...)
226: #else
227: static RETSIGTYPE alarmhandler(int foo)
228: #endif
229: {
230: frame_time_t bar;
231: bar = read_processor_time ();
232: if (bar - last_time < best_time)
233: best_time = bar - last_time;
234: if (--loops_to_go > 0) {
235: signal (SIGALRM, alarmhandler);
236: last_time = read_processor_time();
237: alarm (1);
238: }
239: }
240:
1.1.1.4 root 241: #include <setjmp.h>
242: jmp_buf catch_test;
243:
1.1.1.3 root 244: #ifdef __cplusplus
245: static RETSIGTYPE illhandler(...)
246: #else
247: static RETSIGTYPE illhandler(int foo)
248: #endif
249: {
250: rpt_available = 0;
1.1.1.4 root 251: longjmp(catch_test,1);
1.1.1.3 root 252: }
253:
1.1.1.2 root 254: void machdep_init (void)
255: {
1.1.1.3 root 256: rpt_available = 1;
1.1.1.5 ! root 257: fprintf (stderr,"Testing the RDTSC instruction ... ");
1.1.1.3 root 258: signal (SIGILL, illhandler);
1.1.1.5 ! root 259: if (setjmp (catch_test) == 0)
! 260: read_processor_time ();
1.1.1.3 root 261: signal (SIGILL, SIG_DFL);
1.1.1.5 ! root 262: fprintf (stderr,"done.\n");
1.1.1.3 root 263: if (! rpt_available) {
264: fprintf (stderr, "Your processor does not support the RDTSC instruction.\n");
265: return;
266: }
267: fprintf (stderr, "Calibrating delay loop.. ");
268: fflush (stderr);
1.1.1.2 root 269: best_time = (frame_time_t)-1;
270: loops_to_go = 5;
271: signal (SIGALRM, alarmhandler);
272: /* We want exact values... */
273: sync (); sync (); sync ();
274: last_time = read_processor_time();
275: alarm (1);
276: while (loops_to_go != 0)
1.1.1.3 root 277: usleep (1000000);
1.1.1.2 root 278: fprintf (stderr, "ok - %.2f BogoMIPS\n",
279: ((double)best_time / 1000000), best_time);
1.1.1.5 ! root 280: syncbase = best_time;
1.1.1.2 root 281: }
282:
283: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.