ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/m68k.h
Revision: 1.8
Committed: 2012-03-30T01:25:46Z (12 years, 2 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +21 -7 lines
Log Message:
Add GPLv2 notices to files from UAE Amiga Emulator, as retrieved from the
COPYING file of uae-0.8.29, retrieved from http://www.amigaemulator.org/
via uae-0.8.29.tar.bz2 (MD5 = 54abbabb5e8580b679c52de019141d61).

File Contents

# User Rev Content
1 asvitkine 1.8 /*
2     * UAE - The Un*x Amiga Emulator
3     *
4     * MC68000 emulation - machine dependent bits
5     *
6     * Copyright 1996 Bernd Schmidt
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     */
22 cebix 1.1
23 gbeauche 1.5 #ifndef M68K_FLAGS_H
24     #define M68K_FLAGS_H
25    
26     #ifdef OPTIMIZED_FLAGS
27    
28 gbeauche 1.6 #if (defined(__i386__) && defined(X86_ASSEMBLY)) || (defined(__x86_64__) && defined(X86_64_ASSEMBLY))
29 cebix 1.1
30 gbeauche 1.5 #ifndef SAHF_SETO_PROFITABLE
31    
32 gbeauche 1.6 /* PUSH/POP instructions are naturally 64-bit sized on x86-64, thus
33     unsigned long hereunder is either 64-bit or 32-bit wide depending
34     on the target. */
35 cebix 1.1 struct flag_struct {
36 gbeauche 1.6 unsigned long cznv;
37     unsigned long x;
38 cebix 1.1 };
39    
40 gbeauche 1.5 #define FLAGVAL_Z 0x40
41     #define FLAGVAL_N 0x80
42    
43 gbeauche 1.6 #define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x40) | (((y) & 1) << 6))
44     #define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~1) | ((y) & 1))
45     #define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x800) | (((y) & 1) << 11))
46     #define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x80) | (((y) & 1) << 7))
47 gbeauche 1.5 #define SET_XFLG(y) (regflags.x = (y))
48    
49     #define GET_ZFLG ((regflags.cznv >> 6) & 1)
50     #define GET_CFLG (regflags.cznv & 1)
51     #define GET_VFLG ((regflags.cznv >> 11) & 1)
52     #define GET_NFLG ((regflags.cznv >> 7) & 1)
53     #define GET_XFLG (regflags.x & 1)
54    
55     #define CLEAR_CZNV (regflags.cznv = 0)
56     #define GET_CZNV (regflags.cznv)
57     #define IOR_CZNV(X) (regflags.cznv |= (X))
58     #define SET_CZNV(X) (regflags.cznv = (X))
59 cebix 1.1
60 gbeauche 1.5 #define COPY_CARRY (regflags.x = regflags.cznv)
61 cebix 1.1
62     extern struct flag_struct regflags __asm__ ("regflags");
63    
64     static __inline__ int cctrue(int cc)
65     {
66     uae_u32 cznv = regflags.cznv;
67     switch(cc){
68     case 0: return 1; /* T */
69     case 1: return 0; /* F */
70     case 2: return (cznv & 0x41) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
71     case 3: return (cznv & 0x41) != 0; /* GET_CFLG || GET_ZFLG; LS */
72     case 4: return (cznv & 1) == 0; /* !GET_CFLG; CC */
73     case 5: return (cznv & 1) != 0; /* GET_CFLG; CS */
74     case 6: return (cznv & 0x40) == 0; /* !GET_ZFLG; NE */
75     case 7: return (cznv & 0x40) != 0; /* GET_ZFLG; EQ */
76     case 8: return (cznv & 0x800) == 0;/* !GET_VFLG; VC */
77     case 9: return (cznv & 0x800) != 0;/* GET_VFLG; VS */
78     case 10:return (cznv & 0x80) == 0; /* !GET_NFLG; PL */
79     case 11:return (cznv & 0x80) != 0; /* GET_NFLG; MI */
80     case 12:return (((cznv << 4) ^ cznv) & 0x800) == 0; /* GET_NFLG == GET_VFLG; GE */
81     case 13:return (((cznv << 4) ^ cznv) & 0x800) != 0;/* GET_NFLG != GET_VFLG; LT */
82     case 14:
83     cznv &= 0x8c0;
84     return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
85     case 15:
86     cznv &= 0x8c0;
87     return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
88     }
89     return 0;
90     }
91    
92 gbeauche 1.5 #define optflag_testl(v) \
93     __asm__ __volatile__ ("andl %1,%1\n\t" \
94 gbeauche 1.6 "pushf\n\t" \
95     "pop %0\n\t" \
96 cebix 1.1 : "=r" (regflags.cznv) : "r" (v) : "cc")
97    
98 gbeauche 1.5 #define optflag_testw(v) \
99     __asm__ __volatile__ ("andw %w1,%w1\n\t" \
100 gbeauche 1.6 "pushf\n\t" \
101     "pop %0\n\t" \
102 cebix 1.1 : "=r" (regflags.cznv) : "r" (v) : "cc")
103    
104 gbeauche 1.5 #define optflag_testb(v) \
105     __asm__ __volatile__ ("andb %b1,%b1\n\t" \
106 gbeauche 1.6 "pushf\n\t" \
107     "pop %0\n\t" \
108 cebix 1.1 : "=r" (regflags.cznv) : "q" (v) : "cc")
109    
110 gbeauche 1.5 #define optflag_addl(v, s, d) do { \
111 cebix 1.1 __asm__ __volatile__ ("addl %k2,%k1\n\t" \
112 gbeauche 1.6 "pushf\n\t" \
113     "pop %0\n\t" \
114 cebix 1.1 : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
115     COPY_CARRY; \
116     } while (0)
117    
118 gbeauche 1.5 #define optflag_addw(v, s, d) do { \
119 cebix 1.1 __asm__ __volatile__ ("addw %w2,%w1\n\t" \
120 gbeauche 1.6 "pushf\n\t" \
121     "pop %0\n\t" \
122 cebix 1.1 : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
123     COPY_CARRY; \
124     } while (0)
125    
126 gbeauche 1.5 #define optflag_addb(v, s, d) do { \
127 cebix 1.1 __asm__ __volatile__ ("addb %b2,%b1\n\t" \
128 gbeauche 1.6 "pushf\n\t" \
129     "pop %0\n\t" \
130 cebix 1.1 : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
131     COPY_CARRY; \
132     } while (0)
133    
134 gbeauche 1.5 #define optflag_subl(v, s, d) do { \
135 cebix 1.1 __asm__ __volatile__ ("subl %k2,%k1\n\t" \
136 gbeauche 1.6 "pushf\n\t" \
137     "pop %0\n\t" \
138 cebix 1.1 : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
139     COPY_CARRY; \
140     } while (0)
141    
142 gbeauche 1.5 #define optflag_subw(v, s, d) do { \
143 cebix 1.1 __asm__ __volatile__ ("subw %w2,%w1\n\t" \
144 gbeauche 1.6 "pushf\n\t" \
145     "pop %0\n\t" \
146 cebix 1.1 : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
147     COPY_CARRY; \
148     } while (0)
149    
150 gbeauche 1.5 #define optflag_subb(v, s, d) do { \
151 cebix 1.1 __asm__ __volatile__ ("subb %b2,%b1\n\t" \
152 gbeauche 1.6 "pushf\n\t" \
153     "pop %0\n\t" \
154 cebix 1.1 : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
155     COPY_CARRY; \
156     } while (0)
157    
158 gbeauche 1.5 #define optflag_cmpl(s, d) \
159 cebix 1.1 __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
160 gbeauche 1.6 "pushf\n\t" \
161     "pop %0\n\t" \
162 cebix 1.1 : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
163    
164 gbeauche 1.5 #define optflag_cmpw(s, d) \
165 cebix 1.1 __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
166 gbeauche 1.6 "pushf\n\t" \
167     "pop %0\n\t" \
168 cebix 1.1 : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
169    
170 gbeauche 1.5 #define optflag_cmpb(s, d) \
171 cebix 1.1 __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
172 gbeauche 1.6 "pushf\n\t" \
173     "pop %0\n\t" \
174 cebix 1.1 : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
175 cebix 1.2
176 gbeauche 1.5 #else
177    
178     struct flag_struct {
179     uae_u32 cznv;
180     uae_u32 x;
181     };
182    
183     #define FLAGVAL_Z 0x4000
184     #define FLAGVAL_N 0x8000
185    
186     #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x4000) | (((y) & 1) << 14))
187     #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~0x100) | (((y) & 1) << 8))
188     #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x1) | (((y) & 1)))
189     #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x8000) | (((y) & 1) << 15))
190     #define SET_XFLG(y) (regflags.x = (y))
191    
192     #define GET_ZFLG ((regflags.cznv >> 14) & 1)
193     #define GET_CFLG ((regflags.cznv >> 8) & 1)
194     #define GET_VFLG ((regflags.cznv >> 0) & 1)
195     #define GET_NFLG ((regflags.cznv >> 15) & 1)
196     #define GET_XFLG (regflags.x & 1)
197    
198     #define CLEAR_CZNV (regflags.cznv = 0)
199     #define GET_CZNV (regflags.cznv)
200     #define IOR_CZNV(X) (regflags.cznv |= (X))
201     #define SET_CZNV(X) (regflags.cznv = (X))
202    
203     #define COPY_CARRY (regflags.x = (regflags.cznv)>>8)
204    
205     extern struct flag_struct regflags __asm__ ("regflags");
206    
207     static __inline__ int cctrue(int cc)
208     {
209     uae_u32 cznv = regflags.cznv;
210     switch(cc){
211     case 0: return 1; /* T */
212     case 1: return 0; /* F */
213     case 2: return (cznv & 0x4100) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
214     case 3: return (cznv & 0x4100) != 0; /* GET_CFLG || GET_ZFLG; LS */
215     case 4: return (cznv & 0x100) == 0; /* !GET_CFLG; CC */
216     case 5: return (cznv & 0x100) != 0; /* GET_CFLG; CS */
217     case 6: return (cznv & 0x4000) == 0; /* !GET_ZFLG; NE */
218     case 7: return (cznv & 0x4000) != 0; /* GET_ZFLG; EQ */
219     case 8: return (cznv & 0x01) == 0; /* !GET_VFLG; VC */
220     case 9: return (cznv & 0x01) != 0; /* GET_VFLG; VS */
221     case 10:return (cznv & 0x8000) == 0; /* !GET_NFLG; PL */
222     case 11:return (cznv & 0x8000) != 0; /* GET_NFLG; MI */
223     case 12:return (((cznv << 15) ^ cznv) & 0x8000) == 0; /* GET_NFLG == GET_VFLG; GE */
224     case 13:return (((cznv << 15) ^ cznv) & 0x8000) != 0;/* GET_NFLG != GET_VFLG; LT */
225     case 14:
226     cznv &= 0xc001;
227     return (((cznv << 15) ^ cznv) & 0xc000) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
228     case 15:
229     cznv &= 0xc001;
230     return (((cznv << 15) ^ cznv) & 0xc000) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
231     }
232     abort();
233     return 0;
234     }
235    
236 gbeauche 1.7 /* Manually emit LAHF instruction so that 64-bit assemblers can grok it */
237     #if defined __x86_64__ && defined __GNUC__
238     #define ASM_LAHF ".byte 0x9f"
239     #else
240     #define ASM_LAHF "lahf"
241     #endif
242    
243 gbeauche 1.5 /* Is there any way to do this without declaring *all* memory clobbered?
244     I.e. any way to tell gcc that some byte-sized value is in %al? */
245     #define optflag_testl(v) \
246     __asm__ __volatile__ ("andl %0,%0\n\t" \
247 gbeauche 1.7 ASM_LAHF "\n\t" \
248 gbeauche 1.5 "seto %%al\n\t" \
249     "movb %%al,regflags\n\t" \
250     "movb %%ah,regflags+1\n\t" \
251     : : "r" (v) : "%eax","cc","memory")
252    
253     #define optflag_testw(v) \
254     __asm__ __volatile__ ("andw %w0,%w0\n\t" \
255 gbeauche 1.7 ASM_LAHF "\n\t" \
256 gbeauche 1.5 "seto %%al\n\t" \
257     "movb %%al,regflags\n\t" \
258     "movb %%ah,regflags+1\n\t" \
259     : : "r" (v) : "%eax","cc","memory")
260    
261     #define optflag_testb(v) \
262     __asm__ __volatile__ ("andb %b0,%b0\n\t" \
263 gbeauche 1.7 ASM_LAHF "\n\t" \
264 gbeauche 1.5 "seto %%al\n\t" \
265     "movb %%al,regflags\n\t" \
266     "movb %%ah,regflags+1\n\t" \
267     : : "q" (v) : "%eax","cc","memory")
268    
269     #define optflag_addl(v, s, d) do { \
270     __asm__ __volatile__ ("addl %k1,%k0\n\t" \
271 gbeauche 1.7 ASM_LAHF "\n\t" \
272 gbeauche 1.5 "seto %%al\n\t" \
273     "movb %%al,regflags\n\t" \
274     "movb %%ah,regflags+1\n\t" \
275     : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
276     COPY_CARRY; \
277     } while (0)
278    
279     #define optflag_addw(v, s, d) do { \
280     __asm__ __volatile__ ("addw %w1,%w0\n\t" \
281 gbeauche 1.7 ASM_LAHF "\n\t" \
282 gbeauche 1.5 "seto %%al\n\t" \
283     "movb %%al,regflags\n\t" \
284     "movb %%ah,regflags+1\n\t" \
285     : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
286     COPY_CARRY; \
287     } while (0)
288    
289     #define optflag_addb(v, s, d) do { \
290     __asm__ __volatile__ ("addb %b1,%b0\n\t" \
291 gbeauche 1.7 ASM_LAHF "\n\t" \
292 gbeauche 1.5 "seto %%al\n\t" \
293     "movb %%al,regflags\n\t" \
294     "movb %%ah,regflags+1\n\t" \
295     : "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
296     COPY_CARRY; \
297     } while (0)
298    
299     #define optflag_subl(v, s, d) do { \
300     __asm__ __volatile__ ("subl %k1,%k0\n\t" \
301 gbeauche 1.7 ASM_LAHF "\n\t" \
302 gbeauche 1.5 "seto %%al\n\t" \
303     "movb %%al,regflags\n\t" \
304     "movb %%ah,regflags+1\n\t" \
305     : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
306     COPY_CARRY; \
307     } while (0)
308    
309     #define optflag_subw(v, s, d) do { \
310     __asm__ __volatile__ ("subw %w1,%w0\n\t" \
311 gbeauche 1.7 ASM_LAHF "\n\t" \
312 gbeauche 1.5 "seto %%al\n\t" \
313     "movb %%al,regflags\n\t" \
314     "movb %%ah,regflags+1\n\t" \
315     : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
316     COPY_CARRY; \
317     } while (0)
318    
319     #define optflag_subb(v, s, d) do { \
320     __asm__ __volatile__ ("subb %b1,%b0\n\t" \
321 gbeauche 1.7 ASM_LAHF "\n\t" \
322 gbeauche 1.5 "seto %%al\n\t" \
323     "movb %%al,regflags\n\t" \
324     "movb %%ah,regflags+1\n\t" \
325     : "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
326     COPY_CARRY; \
327     } while (0)
328    
329     #define optflag_cmpl(s, d) \
330     __asm__ __volatile__ ("cmpl %k0,%k1\n\t" \
331 gbeauche 1.7 ASM_LAHF "\n\t" \
332 gbeauche 1.5 "seto %%al\n\t" \
333     "movb %%al,regflags\n\t" \
334     "movb %%ah,regflags+1\n\t" \
335     : : "rmi" (s), "r" (d) : "%eax","cc","memory")
336    
337     #define optflag_cmpw(s, d) \
338     __asm__ __volatile__ ("cmpw %w0,%w1\n\t" \
339 gbeauche 1.7 ASM_LAHF "\n\t" \
340 gbeauche 1.5 "seto %%al\n\t" \
341     "movb %%al,regflags\n\t" \
342     "movb %%ah,regflags+1\n\t" \
343     : : "rmi" (s), "r" (d) : "%eax","cc","memory");
344    
345     #define optflag_cmpb(s, d) \
346     __asm__ __volatile__ ("cmpb %b0,%b1\n\t" \
347 gbeauche 1.7 ASM_LAHF "\n\t" \
348 gbeauche 1.5 "seto %%al\n\t" \
349     "movb %%al,regflags\n\t" \
350     "movb %%ah,regflags+1\n\t" \
351     : : "qmi" (s), "q" (d) : "%eax","cc","memory")
352    
353     #endif
354    
355 cebix 1.2 #elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
356    
357     struct flag_struct {
358 cebix 1.4 unsigned char nzvc;
359     unsigned char x;
360 cebix 1.2 };
361    
362 cebix 1.4 extern struct flag_struct regflags;
363 cebix 1.2
364 gbeauche 1.5 #define FLAGVAL_Z 0x04
365     #define FLAGVAL_N 0x08
366    
367     #define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2))
368     #define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1))
369     #define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1))
370     #define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3))
371     #define SET_XFLG(y) (regflags.x = (y))
372    
373     #define GET_ZFLG ((regflags.nzvc >> 2) & 1)
374     #define GET_CFLG (regflags.nzvc & 1)
375     #define GET_VFLG ((regflags.nzvc >> 1) & 1)
376     #define GET_NFLG ((regflags.nzvc >> 3) & 1)
377     #define GET_XFLG (regflags.x & 1)
378    
379     #define CLEAR_CZNV (regflags.nzvc = 0)
380     #define GET_CZNV (reflags.nzvc)
381     #define IOR_CZNV(X) (refglags.nzvc |= (X))
382     #define SET_CZNV(X) (regflags.nzvc = (X))
383 cebix 1.2
384 cebix 1.4 #define COPY_CARRY (regflags.x = regflags.nzvc)
385 cebix 1.2
386     static __inline__ int cctrue(int cc)
387     {
388 cebix 1.4 uae_u32 nzvc = regflags.nzvc;
389 cebix 1.2 switch(cc){
390 cebix 1.4 case 0: return 1; /* T */
391     case 1: return 0; /* F */
392     case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
393     case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG; LS */
394     case 4: return (nzvc & 1) == 0; /* !GET_CFLG; CC */
395     case 5: return (nzvc & 1) != 0; /* GET_CFLG; CS */
396     case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG; NE */
397     case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG; EQ */
398     case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG; VC */
399     case 9: return (nzvc & 0x02) != 0;/* GET_VFLG; VS */
400     case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG; PL */
401     case 11:return (nzvc & 0x08) != 0; /* GET_NFLG; MI */
402     case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG; GE */
403     case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG; LT */
404 cebix 1.2 case 14:
405 cebix 1.4 nzvc &= 0x0e;
406     return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
407 cebix 1.2 case 15:
408 cebix 1.4 nzvc &= 0x0e;
409     return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
410 cebix 1.2 }
411     return 0;
412     }
413    
414     #ifdef SPARC_V8_ASSEMBLY
415    
416 cebix 1.4 static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
417 cebix 1.2 {
418     uae_u32 value;
419     __asm__ ("\n"
420     " sll %2, 24, %%o0\n"
421     " sll %3, 24, %%o1\n"
422     " addcc %%o0, %%o1, %%o0\n"
423 cebix 1.4 " addx %%g0, %%g0, %%o1 ! X,C flags\n"
424     " srl %%o0, 24, %0\n"
425     " stb %%o1, [%1 + 1]\n"
426     " bl,a .+8\n"
427     " or %%o1, 0x08, %%o1 ! N flag\n"
428     " bz,a .+8\n"
429     " or %%o1, 0x04, %%o1 ! Z flag\n"
430 cebix 1.2 " bvs,a .+8\n"
431 cebix 1.4 " or %%o1, 0x02, %%o1 ! V flag\n"
432     " stb %%o1, [%1]\n"
433 cebix 1.2 : "=&r" (value)
434 cebix 1.4 : "r" (flags), "r" (dst), "r" (src)
435 cebix 1.2 : "cc", "o0", "o1"
436     );
437     return value;
438     }
439    
440 cebix 1.4 static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
441 cebix 1.2 {
442     uae_u32 value;
443     __asm__ ("\n"
444     " sll %2, 16, %%o0\n"
445     " sll %3, 16, %%o1\n"
446     " addcc %%o0, %%o1, %%o0\n"
447 cebix 1.4 " addx %%g0, %%g0, %%o1 ! X,C flags\n"
448     " srl %%o0, 16, %0\n"
449     " stb %%o1, [%1 + 1]\n"
450     " bl,a .+8\n"
451     " or %%o1, 0x08, %%o1 ! N flag\n"
452     " bz,a .+8\n"
453     " or %%o1, 0x04, %%o1 ! Z flag\n"
454 cebix 1.2 " bvs,a .+8\n"
455 cebix 1.4 " or %%o1, 0x02, %%o1 ! V flag\n"
456     " stb %%o1, [%1]\n"
457 cebix 1.2 : "=&r" (value)
458 cebix 1.4 : "r" (flags), "r" (dst), "r" (src)
459 cebix 1.2 : "cc", "o0", "o1"
460     );
461     return value;
462     }
463    
464 cebix 1.4 static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
465 cebix 1.2 {
466     uae_u32 value;
467     __asm__ ("\n"
468     " addcc %2, %3, %0\n"
469 cebix 1.4 " addx %%g0, %%g0, %%o0 ! X,C flags\n"
470     " stb %%o0, [%1 + 1]\n"
471     " bl,a .+8\n"
472     " or %%o0, 0x08, %%o0 ! N flag\n"
473     " bz,a .+8\n"
474     " or %%o0, 0x04, %%o0 ! Z flag\n"
475 cebix 1.2 " bvs,a .+8\n"
476 cebix 1.4 " or %%o0, 0x02, %%o0 ! V flag\n"
477     " stb %%o0, [%1]\n"
478 cebix 1.2 : "=&r" (value)
479 cebix 1.4 : "r" (flags), "r" (dst), "r" (src)
480     : "cc", "o0"
481 cebix 1.2 );
482     return value;
483     }
484    
485     static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
486     {
487     uae_u32 value;
488     __asm__ ("\n"
489     " sll %2, 24, %%o0\n"
490     " sll %3, 24, %%o1\n"
491     " subcc %%o0, %%o1, %%o0\n"
492     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
493     " srl %%o0, 24, %0\n"
494     " stb %%o1, [%1 + 1]\n"
495     " bl,a .+8\n"
496     " or %%o1, 0x08, %%o1 ! N flag\n"
497     " bz,a .+8\n"
498     " or %%o1, 0x04, %%o1 ! Z flag\n"
499     " bvs,a .+8\n"
500     " or %%o1, 0x02, %%o1 ! V flag\n"
501     " stb %%o1, [%1]\n"
502     : "=&r" (value)
503     : "r" (flags), "r" (dst), "r" (src)
504     : "cc", "o0", "o1"
505     );
506     return value;
507     }
508    
509     static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
510     {
511     uae_u32 value;
512     __asm__ ("\n"
513     " sll %2, 16, %%o0\n"
514     " sll %3, 16, %%o1\n"
515     " subcc %%o0, %%o1, %%o0\n"
516     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
517     " srl %%o0, 16, %0\n"
518     " stb %%o1, [%1 + 1]\n"
519     " bl,a .+8\n"
520     " or %%o1, 0x08, %%o1 ! N flag\n"
521     " bz,a .+8\n"
522     " or %%o1, 0x04, %%o1 ! Z flag\n"
523     " bvs,a .+8\n"
524     " or %%o1, 0x02, %%o1 ! V flag\n"
525     " stb %%o1, [%1]\n"
526     : "=&r" (value)
527     : "r" (flags), "r" (dst), "r" (src)
528     : "cc", "o0", "o1"
529     );
530     return value;
531     }
532    
533     static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
534     {
535     uae_u32 value;
536     __asm__ ("\n"
537     " subcc %2, %3, %0\n"
538     " addx %%g0, %%g0, %%o0 ! X,C flags\n"
539     " stb %%o0, [%1 + 1]\n"
540     " bl,a .+8\n"
541     " or %%o0, 0x08, %%o0 ! N flag\n"
542     " bz,a .+8\n"
543     " or %%o0, 0x04, %%o0 ! Z flag\n"
544     " bvs,a .+8\n"
545     " or %%o0, 0x02, %%o0 ! V flag\n"
546     " stb %%o0, [%1]\n"
547     : "=&r" (value)
548     : "r" (flags), "r" (dst), "r" (src)
549     : "cc", "o0"
550     );
551     return value;
552     }
553    
554     static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
555     {
556     __asm__ ("\n"
557     " sll %1, 24, %%o0\n"
558     " sll %2, 24, %%o1\n"
559     " subcc %%o0, %%o1, %%g0\n"
560     " addx %%g0, %%g0, %%o0 ! C flag\n"
561     " bl,a .+8\n"
562     " or %%o0, 0x08, %%o0 ! N flag\n"
563     " bz,a .+8\n"
564     " or %%o0, 0x04, %%o0 ! Z flag\n"
565     " bvs,a .+8\n"
566     " or %%o0, 0x02, %%o0 ! V flag\n"
567     " stb %%o0, [%0]\n"
568     : /* no outputs */
569     : "r" (flags), "r" (dst), "r" (src)
570     : "cc", "o0", "o1"
571     );
572     }
573    
574     static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
575     {
576     __asm__ ("\n"
577     " sll %1, 16, %%o0\n"
578     " sll %2, 16, %%o1\n"
579     " subcc %%o0, %%o1, %%g0\n"
580     " addx %%g0, %%g0, %%o0 ! C flag\n"
581     " bl,a .+8\n"
582     " or %%o0, 0x08, %%o0 ! N flag\n"
583     " bz,a .+8\n"
584     " or %%o0, 0x04, %%o0 ! Z flag\n"
585     " bvs,a .+8\n"
586     " or %%o0, 0x02, %%o0 ! V flag\n"
587     " stb %%o0, [%0]\n"
588     : /* no outputs */
589     : "r" (flags), "r" (dst), "r" (src)
590     : "cc", "o0", "o1"
591     );
592     }
593    
594     static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
595     {
596     __asm__ ("\n"
597     " subcc %1, %2, %%o1\n"
598     " srl %%o1, 31, %%o0\n"
599     " sll %%o0, 3, %%o0\n"
600     " addx %%o0, %%g0, %%o0\n"
601     " bvs,a .+8\n"
602     " or %%o0, 0x02, %%o0\n"
603     " subcc %%g0, %%o1, %%g0\n"
604     " addx %%g0, 7, %%o1\n"
605     " and %%o1, 0x04, %%o1\n"
606     " or %%o0, %%o1, %%o0\n"
607     " stb %%o0, [%0]\n"
608     : /* no outputs */
609     : "r" (flags), "r" (dst), "r" (src)
610     : "cc", "o0", "o1"
611     );
612 cebix 1.4 }
613    
614     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
615     {
616     uae_u32 value;
617     __asm__ ("\n"
618     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
619     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
620     " addxcc %2, %3, %0\n"
621     : "=&r" (value)
622     : "r" (flags), "r" (dst), "r" (src)
623     : "cc", "o0", "o1"
624     );
625     return value;
626     }
627    
628     #if 0
629     VERY SLOW...
630     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
631     {
632     uae_u32 value;
633     __asm__ ("\n"
634     " sll %2, 24, %%o0\n"
635     " sll %3, 24, %%o1\n"
636     " addcc %%o0, %%o1, %%o0\n"
637     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
638     " bvs,a .+8\n"
639     " or %%o1, 0x02, %%o1 ! V flag\n"
640     " ldub [%1 + 1], %%o2\n"
641     " subcc %%g0, %%o2, %%g0\n"
642     " addx %%g0, %%g0, %%o2\n"
643     " sll %%o2, 24, %%o2\n"
644     " addcc %%o0, %%o2, %%o0\n"
645     " srl %%o0, 24, %0\n"
646     " addx %%g0, %%g0, %%o2\n"
647     " or %%o1, %%o2, %%o1 ! update X,C flags\n"
648     " bl,a .+8\n"
649     " or %%o1, 0x08, %%o1 ! N flag\n"
650     " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n"
651     " bvs,a .+8\n"
652     " or %%o1, 0x02, %%o1 ! update V flag\n"
653     " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n"
654     " and %%o1, 1, %%o2 ! keep C flag in %%o2\n"
655     " bnz,a .+8\n"
656     " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n"
657     " stb %%o2, [%1 + 1] ! store the X flag\n"
658     " or %%o1, %%o0, %%o1\n"
659     " stb %%o1, [%1]\n"
660     : "=&r" (value)
661     : "r" (flags), "r" (dst), "r" (src)
662     : "cc", "o0", "o1", "o2"
663     );
664     return value;
665     }
666     #endif
667    
668     static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
669     {
670     uae_u32 value;
671     __asm__ ("\n"
672     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
673     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
674     " addxcc %2, %3, %0\n"
675     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
676     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
677     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
678     " bl,a .+8\n"
679     " or %%o0, 0x08, %%o0 ! N flag\n"
680     " bvs,a .+8\n"
681     " or %%o0, 0x02, %%o0 ! V flag\n"
682     " bnz,a .+8\n"
683     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
684     " stb %%o0, [%1]\n"
685     " stb %%o0, [%1 + 1]\n"
686     : "=&r" (value)
687     : "r" (flags), "r" (dst), "r" (src)
688     : "cc", "o0"
689     );
690     return value;
691 cebix 1.2 }
692    
693     #endif /* SPARC_V8_ASSEMBLY */
694    
695     #ifdef SPARC_V9_ASSEMBLY
696    
697     static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
698     {
699     uae_u32 value;
700     __asm__ ("\n"
701     " sll %2, 24, %%o0\n"
702     " sll %3, 24, %%o1\n"
703     " addcc %%o0, %%o1, %%o0\n"
704     " rd %%ccr, %%o1\n"
705     " srl %%o0, 24, %0\n"
706     " stb %%o1, [%1]\n"
707     " stb %%o1, [%1+1]\n"
708     : "=&r" (value)
709     : "r" (flags), "r" (dst), "r" (src)
710     : "cc", "o0", "o1"
711     );
712     return value;
713     }
714    
715     static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
716     {
717     uae_u32 value;
718     __asm__ ("\n"
719     " sll %2, 16, %%o0\n"
720     " sll %3, 16, %%o1\n"
721     " addcc %%o0, %%o1, %%o0\n"
722     " rd %%ccr, %%o1\n"
723     " srl %%o0, 16, %0\n"
724     " stb %%o1, [%1]\n"
725     " stb %%o1, [%1+1]\n"
726     : "=&r" (value)
727     : "r" (flags), "r" (dst), "r" (src)
728     : "cc", "o0", "o1"
729     );
730     return value;
731     }
732    
733     static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
734     {
735     uae_u32 value;
736     __asm__ ("\n"
737     " addcc %2, %3, %0\n"
738     " rd %%ccr, %%o0\n"
739     " stb %%o0, [%1]\n"
740     " stb %%o0, [%1+1]\n"
741     : "=&r" (value)
742     : "r" (flags), "r" (dst), "r" (src)
743     : "cc", "o0"
744     );
745     return value;
746     }
747    
748     static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
749     {
750     uae_u32 value;
751     __asm__ ("\n"
752     " sll %2, 24, %%o0\n"
753     " sll %3, 24, %%o1\n"
754     " subcc %%o0, %%o1, %%o0\n"
755     " rd %%ccr, %%o1\n"
756     " srl %%o0, 24, %0\n"
757     " stb %%o1, [%1]\n"
758     " stb %%o1, [%1+1]\n"
759     : "=&r" (value)
760     : "r" (flags), "r" (dst), "r" (src)
761     : "cc", "o0", "o1"
762     );
763     return value;
764     }
765    
766     static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
767     {
768     uae_u32 value;
769     __asm__ ("\n"
770     " sll %2, 16, %%o0\n"
771     " sll %3, 16, %%o1\n"
772     " subcc %%o0, %%o1, %%o0\n"
773     " rd %%ccr, %%o1\n"
774     " srl %%o0, 16, %0\n"
775     " stb %%o1, [%1]\n"
776     " stb %%o1, [%1+1]\n"
777     : "=&r" (value)
778     : "r" (flags), "r" (dst), "r" (src)
779     : "cc", "o0", "o1"
780     );
781     return value;
782     }
783    
784     static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
785     {
786     uae_u32 value;
787     __asm__ ("\n"
788     " subcc %2, %3, %0\n"
789     " rd %%ccr, %%o0\n"
790     " stb %%o0, [%1]\n"
791     " stb %%o0, [%1+1]\n"
792     : "=&r" (value)
793     : "r" (flags), "r" (dst), "r" (src)
794     : "cc", "o0"
795     );
796     return value;
797     }
798    
799     static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
800     {
801     __asm__ ("\n"
802     " sll %1, 24, %%o0\n"
803     " sll %2, 24, %%o1\n"
804     " subcc %%o0, %%o1, %%g0\n"
805     " rd %%ccr, %%o0\n"
806     " stb %%o0, [%0]\n"
807     : /* no outputs */
808     : "r" (flags), "r" (dst), "r" (src)
809     : "cc", "o0", "o1"
810     );
811     }
812    
813     static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
814     {
815     __asm__ ("\n"
816     " sll %1, 16, %%o0\n"
817     " sll %2, 16, %%o1\n"
818     " subcc %%o0, %%o1, %%g0\n"
819     " rd %%ccr, %%o0\n"
820     " stb %%o0, [%0]\n"
821     : /* no outputs */
822     : "r" (flags), "r" (dst), "r" (src)
823     : "cc", "o0", "o1"
824     );
825     }
826    
827     static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
828     {
829     __asm__ ("\n"
830     " subcc %1, %2, %%g0\n"
831     #if 0
832     " subcc %1, %2, %%o1\n"
833     " srl %%o1, 31, %%o0\n"
834     " sll %%o0, 3, %%o0\n"
835     " addx %%o0, %%g0, %%o0\n"
836     " bvs,a .+8\n"
837     " or %%o0, 0x02, %%o0\n"
838     " subcc %%g0, %%o1, %%g0\n"
839     " addx %%g0, 7, %%o1\n"
840     " and %%o1, 0x04, %%o1\n"
841     " or %%o0, %%o1, %%o0\n"
842     #endif
843     #if 0
844     " subcc %1, %2, %%o1\n"
845     " srl %%o1, 31, %%o0\n"
846     " sll %%o0, 3, %%o0\n"
847     " addx %%o0, %%g0, %%o0\n"
848     " bvs,pt,a .+8\n"
849     " or %%o0, 0x02, %%o0\n"
850     " subcc %%g0, %%o1, %%g0\n"
851     " addx %%g0, 7, %%o1\n"
852     " and %%o1, 0x04, %%o1\n"
853     " or %%o0, %%o1, %%o0\n"
854     " stb %%o0, [%0]\n"
855     #endif
856     " rd %%ccr, %%o0\n"
857     " stb %%o0, [%0]\n"
858     : /* no outputs */
859     : "r" (flags), "r" (dst), "r" (src)
860     : "cc", "o0", "o1"
861     );
862     }
863    
864     #if 1
865     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
866     {
867     __asm__ ("\n"
868     " sll %1, 24, %%o0\n"
869     " subcc %%o0, %%g0, %%g0\n"
870     " rd %%ccr, %%o0\n"
871     " stb %%o0, [%0]\n"
872     : /* no outputs */
873     : "r" (flags), "r" (val)
874     : "cc", "o0"
875     );
876     }
877    
878     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
879     {
880     __asm__ ("\n"
881     " sll %1, 16, %%o0\n"
882     " subcc %%o0, %%g0, %%g0\n"
883     " rd %%ccr, %%o0\n"
884     " stb %%o0, [%0]\n"
885     : /* no outputs */
886     : "r" (flags), "r" (val)
887     : "cc", "o0"
888     );
889     }
890    
891     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
892     {
893     __asm__ ("\n"
894     " subcc %1, %%g0, %%g0\n"
895     " rd %%ccr, %%o0\n"
896     " stb %%o0, [%0]\n"
897     : /* no outputs */
898     : "r" (flags), "r" (val)
899     : "cc", "o0"
900     );
901     }
902     #else
903     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
904     {
905     __asm__ ("\n"
906     " sll %1, 24, %%o0\n"
907     " subcc %%o0, %%g0, %%o1\n"
908     " srl %%o1, 31, %%o0\n"
909     " sll %%o0, 3, %%o0\n"
910     " addx %%o0, %%g0, %%o0\n"
911     " bvs,a .+8\n"
912     " or %%o0, 0x02, %%o0\n"
913     " subcc %%g0, %%o1, %%g0\n"
914     " addx %%g0, 7, %%o1\n"
915     " and %%o1, 0x04, %%o1\n"
916     " or %%o0, %%o1, %%o0\n"
917     " stb %%o0, [%0]\n"
918     : /* no outputs */
919     : "r" (flags), "r" (val)
920     : "cc", "o0", "o1"
921     );
922     }
923    
924     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
925     {
926     __asm__ ("\n"
927     " sll %1, 16, %%o0\n"
928     " subcc %%o0, %%g0, %%o1\n"
929     " srl %%o1, 31, %%o0\n"
930     " sll %%o0, 3, %%o0\n"
931     " addx %%o0, %%g0, %%o0\n"
932     " bvs,a .+8\n"
933     " or %%o0, 0x02, %%o0\n"
934     " subcc %%g0, %%o1, %%g0\n"
935     " addx %%g0, 7, %%o1\n"
936     " and %%o1, 0x04, %%o1\n"
937     " or %%o0, %%o1, %%o0\n"
938     " stb %%o0, [%0]\n"
939     : /* no outputs */
940     : "r" (flags), "r" (val)
941     : "cc", "o0", "o1"
942     );
943     }
944    
945     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
946     {
947     __asm__ ("\n"
948     " subcc %1, %%g0, %%o1\n"
949     " srl %%o1, 31, %%o0\n"
950     " sll %%o0, 3, %%o0\n"
951     " addx %%o0, %%g0, %%o0\n"
952     " bvs,a .+8\n"
953     " or %%o0, 0x02, %%o0\n"
954     " subcc %%g0, %%o1, %%g0\n"
955     " addx %%g0, 7, %%o1\n"
956     " and %%o1, 0x04, %%o1\n"
957     " or %%o0, %%o1, %%o0\n"
958     " stb %%o0, [%0]\n"
959     : /* no outputs */
960     : "r" (flags), "r" (val)
961     : "cc", "o0", "o1"
962     );
963     }
964     #endif
965    
966     static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
967     {
968     uae_u32 value;
969     __asm__ ("\n"
970     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
971     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
972     " addxcc %2, %3, %0\n"
973     : "=&r" (value)
974     : "r" (flags), "r" (dst), "r" (src)
975     : "cc", "o0", "o1"
976     );
977     return value;
978     }
979    
980     static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
981     {
982     uae_u32 value;
983     __asm__ ("\n"
984     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
985     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
986     " addxcc %2, %3, %0\n"
987     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
988     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
989     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
990     " bl,a .+8\n"
991     " or %%o0, 0x08, %%o0 ! N flag\n"
992     " bvs,a .+8\n"
993     " or %%o0, 0x02, %%o0 ! V flag\n"
994     " bnz,a .+8\n"
995     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
996     " stb %%o0, [%1]\n"
997     " stb %%o0, [%1 + 1]\n"
998     : "=&r" (value)
999     : "r" (flags), "r" (dst), "r" (src)
1000     : "cc", "o0"
1001     );
1002     return value;
1003     }
1004    
1005     #endif /* SPARC_V9_ASSEMBLY */
1006 cebix 1.1
1007 gbeauche 1.5 #endif
1008    
1009 cebix 1.1 #else
1010    
1011     struct flag_struct {
1012     unsigned int c;
1013     unsigned int z;
1014     unsigned int n;
1015     unsigned int v;
1016     unsigned int x;
1017     };
1018    
1019     extern struct flag_struct regflags;
1020    
1021     #define ZFLG (regflags.z)
1022     #define NFLG (regflags.n)
1023     #define CFLG (regflags.c)
1024     #define VFLG (regflags.v)
1025     #define XFLG (regflags.x)
1026    
1027 gbeauche 1.5 #define SET_CFLG(x) (CFLG = (x))
1028     #define SET_NFLG(x) (NFLG = (x))
1029     #define SET_VFLG(x) (VFLG = (x))
1030     #define SET_ZFLG(x) (ZFLG = (x))
1031     #define SET_XFLG(x) (XFLG = (x))
1032    
1033     #define GET_CFLG CFLG
1034     #define GET_NFLG NFLG
1035     #define GET_VFLG VFLG
1036     #define GET_ZFLG ZFLG
1037     #define GET_XFLG XFLG
1038    
1039     #define CLEAR_CZNV do { \
1040     SET_CFLG (0); \
1041     SET_ZFLG (0); \
1042     SET_NFLG (0); \
1043     SET_VFLG (0); \
1044     } while (0)
1045    
1046     #define COPY_CARRY (SET_XFLG (GET_CFLG))
1047    
1048 cebix 1.1 static __inline__ int cctrue(const int cc)
1049     {
1050     switch(cc){
1051     case 0: return 1; /* T */
1052     case 1: return 0; /* F */
1053     case 2: return !CFLG && !ZFLG; /* HI */
1054     case 3: return CFLG || ZFLG; /* LS */
1055     case 4: return !CFLG; /* CC */
1056     case 5: return CFLG; /* CS */
1057     case 6: return !ZFLG; /* NE */
1058     case 7: return ZFLG; /* EQ */
1059     case 8: return !VFLG; /* VC */
1060     case 9: return VFLG; /* VS */
1061     case 10:return !NFLG; /* PL */
1062     case 11:return NFLG; /* MI */
1063     case 12:return NFLG == VFLG; /* GE */
1064     case 13:return NFLG != VFLG; /* LT */
1065     case 14:return !ZFLG && (NFLG == VFLG); /* GT */
1066     case 15:return ZFLG || (NFLG != VFLG); /* LE */
1067     }
1068     return 0;
1069     }
1070    
1071 gbeauche 1.5 #endif /* OPTIMIZED_FLAGS */
1072    
1073     #endif /* M68K_FLAGS_H */