ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/m68k.h
(Generate patch)

Comparing BasiliskII/src/uae_cpu/m68k.h (file contents):
Revision 1.1.1.1 by cebix, 1999-10-03T14:16:26Z vs.
Revision 1.8 by asvitkine, 2012-03-30T01:25:46Z

# Line 1 | Line 1
1 < /*
2 <  * UAE - The Un*x Amiga Emulator
3 <  *
4 <  * MC68000 emulation - machine dependent bits
5 <  *
6 <  * Copyright 1996 Bernd Schmidt
7 <  */
8 <
9 < #ifdef __i386__
10 <
1 > /*
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 >
23 > #ifndef M68K_FLAGS_H
24 > #define M68K_FLAGS_H
25 >
26 > #ifdef OPTIMIZED_FLAGS
27 >
28 > #if (defined(__i386__) && defined(X86_ASSEMBLY)) || (defined(__x86_64__) && defined(X86_64_ASSEMBLY))
29 >
30 > #ifndef SAHF_SETO_PROFITABLE
31 >
32 > /* 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   struct flag_struct {
36 <    unsigned int cznv;
37 <    unsigned int x;
36 >    unsigned long cznv;
37 >    unsigned long x;
38   };
39  
40 < #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
41 < #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
18 < #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
19 < #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
20 < #define SET_XFLG(y) (regflags.x = (y))
21 <
22 < #define GET_ZFLG ((regflags.cznv >> 6) & 1)
23 < #define GET_CFLG (regflags.cznv & 1)
24 < #define GET_VFLG ((regflags.cznv >> 11) & 1)
25 < #define GET_NFLG ((regflags.cznv >> 7) & 1)
26 < #define GET_XFLG (regflags.x & 1)
40 > #define FLAGVAL_Z       0x40
41 > #define FLAGVAL_N       0x80
42  
43 < #define CLEAR_CZNV (regflags.cznv = 0)
44 < #define COPY_CARRY (regflags.x = regflags.cznv)
43 > #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 > #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 >
60 > #define COPY_CARRY      (regflags.x = regflags.cznv)
61  
62   extern struct flag_struct regflags __asm__ ("regflags");
63  
# Line 58 | Line 89 | static __inline__ int cctrue(int cc)
89      return 0;
90   }
91  
92 < #define x86_flag_testl(v) \
93 <  __asm__ __volatile__ ("testl %1,%1\n\t" \
94 <                        "pushfl\n\t" \
95 <                        "popl %0\n\t" \
92 > #define optflag_testl(v) \
93 >  __asm__ __volatile__ ("andl %1,%1\n\t" \
94 >                        "pushf\n\t" \
95 >                        "pop %0\n\t" \
96                          : "=r" (regflags.cznv) : "r" (v) : "cc")
97  
98 < #define x86_flag_testw(v) \
99 <  __asm__ __volatile__ ("testw %w1,%w1\n\t" \
100 <                        "pushfl\n\t" \
101 <                        "popl %0\n\t" \
98 > #define optflag_testw(v) \
99 >  __asm__ __volatile__ ("andw %w1,%w1\n\t" \
100 >                        "pushf\n\t" \
101 >                        "pop %0\n\t" \
102                          : "=r" (regflags.cznv) : "r" (v) : "cc")
103  
104 < #define x86_flag_testb(v) \
105 <  __asm__ __volatile__ ("testb %b1,%b1\n\t" \
106 <                        "pushfl\n\t" \
107 <                        "popl %0\n\t" \
104 > #define optflag_testb(v) \
105 >  __asm__ __volatile__ ("andb %b1,%b1\n\t" \
106 >                        "pushf\n\t" \
107 >                        "pop %0\n\t" \
108                          : "=r" (regflags.cznv) : "q" (v) : "cc")
109  
110 < #define x86_flag_addl(v, s, d) do { \
110 > #define optflag_addl(v, s, d) do { \
111    __asm__ __volatile__ ("addl %k2,%k1\n\t" \
112 <                        "pushfl\n\t" \
113 <                        "popl %0\n\t" \
112 >                        "pushf\n\t" \
113 >                        "pop %0\n\t" \
114                          : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
115      COPY_CARRY; \
116      } while (0)
117  
118 < #define x86_flag_addw(v, s, d) do { \
118 > #define optflag_addw(v, s, d) do { \
119    __asm__ __volatile__ ("addw %w2,%w1\n\t" \
120 <                        "pushfl\n\t" \
121 <                        "popl %0\n\t" \
120 >                        "pushf\n\t" \
121 >                        "pop %0\n\t" \
122                          : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
123      COPY_CARRY; \
124      } while (0)
125  
126 < #define x86_flag_addb(v, s, d) do { \
126 > #define optflag_addb(v, s, d) do { \
127    __asm__ __volatile__ ("addb %b2,%b1\n\t" \
128 <                        "pushfl\n\t" \
129 <                        "popl %0\n\t" \
128 >                        "pushf\n\t" \
129 >                        "pop %0\n\t" \
130                          : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
131      COPY_CARRY; \
132      } while (0)
133  
134 < #define x86_flag_subl(v, s, d) do { \
134 > #define optflag_subl(v, s, d) do { \
135    __asm__ __volatile__ ("subl %k2,%k1\n\t" \
136 <                        "pushfl\n\t" \
137 <                        "popl %0\n\t" \
136 >                        "pushf\n\t" \
137 >                        "pop %0\n\t" \
138                          : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
139      COPY_CARRY; \
140      } while (0)
141  
142 < #define x86_flag_subw(v, s, d) do { \
142 > #define optflag_subw(v, s, d) do { \
143    __asm__ __volatile__ ("subw %w2,%w1\n\t" \
144 <                        "pushfl\n\t" \
145 <                        "popl %0\n\t" \
144 >                        "pushf\n\t" \
145 >                        "pop %0\n\t" \
146                          : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
147      COPY_CARRY; \
148      } while (0)
149  
150 < #define x86_flag_subb(v, s, d) do { \
150 > #define optflag_subb(v, s, d) do { \
151    __asm__ __volatile__ ("subb %b2,%b1\n\t" \
152 <                        "pushfl\n\t" \
153 <                        "popl %0\n\t" \
152 >                        "pushf\n\t" \
153 >                        "pop %0\n\t" \
154                          : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
155      COPY_CARRY; \
156      } while (0)
157  
158 < #define x86_flag_cmpl(s, d) \
158 > #define optflag_cmpl(s, d) \
159    __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
160 <                        "pushfl\n\t" \
161 <                        "popl %0\n\t" \
160 >                        "pushf\n\t" \
161 >                        "pop %0\n\t" \
162                          : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
163  
164 < #define x86_flag_cmpw(s, d) \
164 > #define optflag_cmpw(s, d) \
165    __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
166 <                        "pushfl\n\t" \
167 <                        "popl %0\n\t" \
166 >                        "pushf\n\t" \
167 >                        "pop %0\n\t" \
168                          : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
169  
170 < #define x86_flag_cmpb(s, d) \
170 > #define optflag_cmpb(s, d) \
171    __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
172 <                        "pushfl\n\t" \
173 <                        "popl %0\n\t" \
172 >                        "pushf\n\t" \
173 >                        "pop %0\n\t" \
174                          : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
175  
176   #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 + /* 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 + /* 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 +                        ASM_LAHF "\n\t" \
248 +                        "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 +                        ASM_LAHF "\n\t" \
256 +                        "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 +                        ASM_LAHF "\n\t" \
264 +                        "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 +                        ASM_LAHF "\n\t" \
272 +                        "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 +                        ASM_LAHF "\n\t" \
282 +                        "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 +                        ASM_LAHF "\n\t" \
292 +                        "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 +                        ASM_LAHF "\n\t" \
302 +                        "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 +                        ASM_LAHF "\n\t" \
312 +                        "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 +                        ASM_LAHF "\n\t" \
322 +                        "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 +                        ASM_LAHF "\n\t" \
332 +                        "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 +                        ASM_LAHF "\n\t" \
340 +                        "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 +                        ASM_LAHF "\n\t" \
348 +                        "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 + #elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
356 +
357 + struct flag_struct {
358 +    unsigned char nzvc;
359 +    unsigned char x;
360 + };
361 +
362 + extern struct flag_struct regflags;
363 +
364 + #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 +
384 + #define COPY_CARRY (regflags.x = regflags.nzvc)
385 +
386 + static __inline__ int cctrue(int cc)
387 + {
388 +    uae_u32 nzvc = regflags.nzvc;
389 +    switch(cc){
390 +     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 +     case 14:
405 +        nzvc &= 0x0e;
406 +        return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
407 +     case 15:
408 +        nzvc &= 0x0e;
409 +        return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
410 +    }
411 +    return 0;
412 + }
413 +
414 + #ifdef SPARC_V8_ASSEMBLY
415 +
416 + static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
417 + {
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 +                "       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 +                "       bvs,a   .+8\n"
431 +                "       or              %%o1, 0x02, %%o1        ! V flag\n"
432 +                "       stb             %%o1, [%1]\n"
433 +        :       "=&r" (value)
434 +        :       "r" (flags), "r" (dst), "r" (src)
435 +        :       "cc", "o0", "o1"
436 +        );
437 +        return value;
438 + }
439 +
440 + static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
441 + {
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 +                "       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 +                "       bvs,a   .+8\n"
455 +                "       or              %%o1, 0x02, %%o1        ! V flag\n"
456 +                "       stb             %%o1, [%1]\n"
457 +        :       "=&r" (value)
458 +        :       "r" (flags), "r" (dst), "r" (src)
459 +        :       "cc", "o0", "o1"
460 +        );
461 +        return value;
462 + }
463 +
464 + static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
465 + {
466 +        uae_u32 value;
467 +        __asm__ ("\n"
468 +                "       addcc   %2, %3, %0\n"
469 +                "       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 +                "       bvs,a   .+8\n"
476 +                "       or              %%o0, 0x02, %%o0        ! V flag\n"
477 +                "       stb             %%o0, [%1]\n"
478 +        :       "=&r" (value)
479 +        :       "r" (flags), "r" (dst), "r" (src)
480 +        :       "cc", "o0"
481 +        );
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 + }
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 + }
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 +
1007 + #endif
1008 +
1009 + #else
1010 +
1011 + struct flag_struct {
1012      unsigned int c;
1013      unsigned int z;
1014      unsigned int n;
# Line 160 | Line 1024 | extern struct flag_struct regflags;
1024   #define VFLG (regflags.v)
1025   #define XFLG (regflags.x)
1026  
1027 + #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   static __inline__ int cctrue(const int cc)
1049   {
1050      switch(cc){
# Line 183 | Line 1068 | static __inline__ int cctrue(const int c
1068      return 0;
1069   }
1070  
1071 < #endif
1071 > #endif /* OPTIMIZED_FLAGS */
1072 >
1073 > #endif /* M68K_FLAGS_H */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines