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