2
* UAE - The Un*x Amiga Emulator
4
* MC68000 emulation - machine dependent bits
6
* Copyright 1996 Bernd Schmidt
12
#ifdef OPTIMIZED_FLAGS
14
#if (defined(__i386__) && defined(X86_ASSEMBLY)) || (defined(__x86_64__) && defined(X86_64_ASSEMBLY))
16
#ifndef SAHF_SETO_PROFITABLE
18
/* PUSH/POP instructions are naturally 64-bit sized on x86-64, thus
19
unsigned long hereunder is either 64-bit or 32-bit wide depending
26
#define FLAGVAL_Z 0x40
27
#define FLAGVAL_N 0x80
29
#define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x40) | (((y) & 1) << 6))
30
#define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~1) | ((y) & 1))
31
#define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x800) | (((y) & 1) << 11))
32
#define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~0x80) | (((y) & 1) << 7))
33
#define SET_XFLG(y) (regflags.x = (y))
35
#define GET_ZFLG ((regflags.cznv >> 6) & 1)
36
#define GET_CFLG (regflags.cznv & 1)
37
#define GET_VFLG ((regflags.cznv >> 11) & 1)
38
#define GET_NFLG ((regflags.cznv >> 7) & 1)
39
#define GET_XFLG (regflags.x & 1)
41
#define CLEAR_CZNV (regflags.cznv = 0)
42
#define GET_CZNV (regflags.cznv)
43
#define IOR_CZNV(X) (regflags.cznv |= (X))
44
#define SET_CZNV(X) (regflags.cznv = (X))
46
#define COPY_CARRY (regflags.x = regflags.cznv)
48
extern struct flag_struct regflags __asm__ ("regflags");
50
static __inline__ int cctrue(int cc)
52
uae_u32 cznv = regflags.cznv;
54
case 0: return 1; /* T */
55
case 1: return 0; /* F */
56
case 2: return (cznv & 0x41) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
57
case 3: return (cznv & 0x41) != 0; /* GET_CFLG || GET_ZFLG; LS */
58
case 4: return (cznv & 1) == 0; /* !GET_CFLG; CC */
59
case 5: return (cznv & 1) != 0; /* GET_CFLG; CS */
60
case 6: return (cznv & 0x40) == 0; /* !GET_ZFLG; NE */
61
case 7: return (cznv & 0x40) != 0; /* GET_ZFLG; EQ */
62
case 8: return (cznv & 0x800) == 0;/* !GET_VFLG; VC */
63
case 9: return (cznv & 0x800) != 0;/* GET_VFLG; VS */
64
case 10:return (cznv & 0x80) == 0; /* !GET_NFLG; PL */
65
case 11:return (cznv & 0x80) != 0; /* GET_NFLG; MI */
66
case 12:return (((cznv << 4) ^ cznv) & 0x800) == 0; /* GET_NFLG == GET_VFLG; GE */
67
case 13:return (((cznv << 4) ^ cznv) & 0x800) != 0;/* GET_NFLG != GET_VFLG; LT */
70
return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
73
return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
78
#define optflag_testl(v) \
79
__asm__ __volatile__ ("andl %1,%1\n\t" \
82
: "=r" (regflags.cznv) : "r" (v) : "cc")
84
#define optflag_testw(v) \
85
__asm__ __volatile__ ("andw %w1,%w1\n\t" \
88
: "=r" (regflags.cznv) : "r" (v) : "cc")
90
#define optflag_testb(v) \
91
__asm__ __volatile__ ("andb %b1,%b1\n\t" \
94
: "=r" (regflags.cznv) : "q" (v) : "cc")
96
#define optflag_addl(v, s, d) do { \
97
__asm__ __volatile__ ("addl %k2,%k1\n\t" \
100
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
104
#define optflag_addw(v, s, d) do { \
105
__asm__ __volatile__ ("addw %w2,%w1\n\t" \
108
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
112
#define optflag_addb(v, s, d) do { \
113
__asm__ __volatile__ ("addb %b2,%b1\n\t" \
116
: "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
120
#define optflag_subl(v, s, d) do { \
121
__asm__ __volatile__ ("subl %k2,%k1\n\t" \
124
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
128
#define optflag_subw(v, s, d) do { \
129
__asm__ __volatile__ ("subw %w2,%w1\n\t" \
132
: "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
136
#define optflag_subb(v, s, d) do { \
137
__asm__ __volatile__ ("subb %b2,%b1\n\t" \
140
: "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
144
#define optflag_cmpl(s, d) \
145
__asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
148
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
150
#define optflag_cmpw(s, d) \
151
__asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
154
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
156
#define optflag_cmpb(s, d) \
157
__asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
160
: "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
169
#define FLAGVAL_Z 0x4000
170
#define FLAGVAL_N 0x8000
172
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x4000) | (((y) & 1) << 14))
173
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~0x100) | (((y) & 1) << 8))
174
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x1) | (((y) & 1)))
175
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x8000) | (((y) & 1) << 15))
176
#define SET_XFLG(y) (regflags.x = (y))
178
#define GET_ZFLG ((regflags.cznv >> 14) & 1)
179
#define GET_CFLG ((regflags.cznv >> 8) & 1)
180
#define GET_VFLG ((regflags.cznv >> 0) & 1)
181
#define GET_NFLG ((regflags.cznv >> 15) & 1)
182
#define GET_XFLG (regflags.x & 1)
184
#define CLEAR_CZNV (regflags.cznv = 0)
185
#define GET_CZNV (regflags.cznv)
186
#define IOR_CZNV(X) (regflags.cznv |= (X))
187
#define SET_CZNV(X) (regflags.cznv = (X))
189
#define COPY_CARRY (regflags.x = (regflags.cznv)>>8)
191
extern struct flag_struct regflags __asm__ ("regflags");
193
static __inline__ int cctrue(int cc)
195
uae_u32 cznv = regflags.cznv;
197
case 0: return 1; /* T */
198
case 1: return 0; /* F */
199
case 2: return (cznv & 0x4100) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
200
case 3: return (cznv & 0x4100) != 0; /* GET_CFLG || GET_ZFLG; LS */
201
case 4: return (cznv & 0x100) == 0; /* !GET_CFLG; CC */
202
case 5: return (cznv & 0x100) != 0; /* GET_CFLG; CS */
203
case 6: return (cznv & 0x4000) == 0; /* !GET_ZFLG; NE */
204
case 7: return (cznv & 0x4000) != 0; /* GET_ZFLG; EQ */
205
case 8: return (cznv & 0x01) == 0; /* !GET_VFLG; VC */
206
case 9: return (cznv & 0x01) != 0; /* GET_VFLG; VS */
207
case 10:return (cznv & 0x8000) == 0; /* !GET_NFLG; PL */
208
case 11:return (cznv & 0x8000) != 0; /* GET_NFLG; MI */
209
case 12:return (((cznv << 15) ^ cznv) & 0x8000) == 0; /* GET_NFLG == GET_VFLG; GE */
210
case 13:return (((cznv << 15) ^ cznv) & 0x8000) != 0;/* GET_NFLG != GET_VFLG; LT */
213
return (((cznv << 15) ^ cznv) & 0xc000) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
216
return (((cznv << 15) ^ cznv) & 0xc000) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
222
/* Is there any way to do this without declaring *all* memory clobbered?
223
I.e. any way to tell gcc that some byte-sized value is in %al? */
224
#define optflag_testl(v) \
225
__asm__ __volatile__ ("andl %0,%0\n\t" \
228
"movb %%al,regflags\n\t" \
229
"movb %%ah,regflags+1\n\t" \
230
: : "r" (v) : "%eax","cc","memory")
232
#define optflag_testw(v) \
233
__asm__ __volatile__ ("andw %w0,%w0\n\t" \
236
"movb %%al,regflags\n\t" \
237
"movb %%ah,regflags+1\n\t" \
238
: : "r" (v) : "%eax","cc","memory")
240
#define optflag_testb(v) \
241
__asm__ __volatile__ ("andb %b0,%b0\n\t" \
244
"movb %%al,regflags\n\t" \
245
"movb %%ah,regflags+1\n\t" \
246
: : "q" (v) : "%eax","cc","memory")
248
#define optflag_addl(v, s, d) do { \
249
__asm__ __volatile__ ("addl %k1,%k0\n\t" \
252
"movb %%al,regflags\n\t" \
253
"movb %%ah,regflags+1\n\t" \
254
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
258
#define optflag_addw(v, s, d) do { \
259
__asm__ __volatile__ ("addw %w1,%w0\n\t" \
262
"movb %%al,regflags\n\t" \
263
"movb %%ah,regflags+1\n\t" \
264
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
268
#define optflag_addb(v, s, d) do { \
269
__asm__ __volatile__ ("addb %b1,%b0\n\t" \
272
"movb %%al,regflags\n\t" \
273
"movb %%ah,regflags+1\n\t" \
274
: "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
278
#define optflag_subl(v, s, d) do { \
279
__asm__ __volatile__ ("subl %k1,%k0\n\t" \
282
"movb %%al,regflags\n\t" \
283
"movb %%ah,regflags+1\n\t" \
284
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
288
#define optflag_subw(v, s, d) do { \
289
__asm__ __volatile__ ("subw %w1,%w0\n\t" \
292
"movb %%al,regflags\n\t" \
293
"movb %%ah,regflags+1\n\t" \
294
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
298
#define optflag_subb(v, s, d) do { \
299
__asm__ __volatile__ ("subb %b1,%b0\n\t" \
302
"movb %%al,regflags\n\t" \
303
"movb %%ah,regflags+1\n\t" \
304
: "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
308
#define optflag_cmpl(s, d) \
309
__asm__ __volatile__ ("cmpl %k0,%k1\n\t" \
312
"movb %%al,regflags\n\t" \
313
"movb %%ah,regflags+1\n\t" \
314
: : "rmi" (s), "r" (d) : "%eax","cc","memory")
316
#define optflag_cmpw(s, d) \
317
__asm__ __volatile__ ("cmpw %w0,%w1\n\t" \
320
"movb %%al,regflags\n\t" \
321
"movb %%ah,regflags+1\n\t" \
322
: : "rmi" (s), "r" (d) : "%eax","cc","memory");
324
#define optflag_cmpb(s, d) \
325
__asm__ __volatile__ ("cmpb %b0,%b1\n\t" \
328
"movb %%al,regflags\n\t" \
329
"movb %%ah,regflags+1\n\t" \
330
: : "qmi" (s), "q" (d) : "%eax","cc","memory")
334
#elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
341
extern struct flag_struct regflags;
343
#define FLAGVAL_Z 0x04
344
#define FLAGVAL_N 0x08
346
#define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2))
347
#define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1))
348
#define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1))
349
#define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3))
350
#define SET_XFLG(y) (regflags.x = (y))
352
#define GET_ZFLG ((regflags.nzvc >> 2) & 1)
353
#define GET_CFLG (regflags.nzvc & 1)
354
#define GET_VFLG ((regflags.nzvc >> 1) & 1)
355
#define GET_NFLG ((regflags.nzvc >> 3) & 1)
356
#define GET_XFLG (regflags.x & 1)
358
#define CLEAR_CZNV (regflags.nzvc = 0)
359
#define GET_CZNV (reflags.nzvc)
360
#define IOR_CZNV(X) (refglags.nzvc |= (X))
361
#define SET_CZNV(X) (regflags.nzvc = (X))
363
#define COPY_CARRY (regflags.x = regflags.nzvc)
365
static __inline__ int cctrue(int cc)
367
uae_u32 nzvc = regflags.nzvc;
369
case 0: return 1; /* T */
370
case 1: return 0; /* F */
371
case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
372
case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG; LS */
373
case 4: return (nzvc & 1) == 0; /* !GET_CFLG; CC */
374
case 5: return (nzvc & 1) != 0; /* GET_CFLG; CS */
375
case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG; NE */
376
case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG; EQ */
377
case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG; VC */
378
case 9: return (nzvc & 0x02) != 0;/* GET_VFLG; VS */
379
case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG; PL */
380
case 11:return (nzvc & 0x08) != 0; /* GET_NFLG; MI */
381
case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG; GE */
382
case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG; LT */
385
return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
388
return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
393
#ifdef SPARC_V8_ASSEMBLY
395
static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
399
" sll %2, 24, %%o0\n"
400
" sll %3, 24, %%o1\n"
401
" addcc %%o0, %%o1, %%o0\n"
402
" addx %%g0, %%g0, %%o1 ! X,C flags\n"
403
" srl %%o0, 24, %0\n"
404
" stb %%o1, [%1 + 1]\n"
406
" or %%o1, 0x08, %%o1 ! N flag\n"
408
" or %%o1, 0x04, %%o1 ! Z flag\n"
410
" or %%o1, 0x02, %%o1 ! V flag\n"
413
: "r" (flags), "r" (dst), "r" (src)
419
static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
423
" sll %2, 16, %%o0\n"
424
" sll %3, 16, %%o1\n"
425
" addcc %%o0, %%o1, %%o0\n"
426
" addx %%g0, %%g0, %%o1 ! X,C flags\n"
427
" srl %%o0, 16, %0\n"
428
" stb %%o1, [%1 + 1]\n"
430
" or %%o1, 0x08, %%o1 ! N flag\n"
432
" or %%o1, 0x04, %%o1 ! Z flag\n"
434
" or %%o1, 0x02, %%o1 ! V flag\n"
437
: "r" (flags), "r" (dst), "r" (src)
443
static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
447
" addcc %2, %3, %0\n"
448
" addx %%g0, %%g0, %%o0 ! X,C flags\n"
449
" stb %%o0, [%1 + 1]\n"
451
" or %%o0, 0x08, %%o0 ! N flag\n"
453
" or %%o0, 0x04, %%o0 ! Z flag\n"
455
" or %%o0, 0x02, %%o0 ! V flag\n"
458
: "r" (flags), "r" (dst), "r" (src)
464
static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
468
" sll %2, 24, %%o0\n"
469
" sll %3, 24, %%o1\n"
470
" subcc %%o0, %%o1, %%o0\n"
471
" addx %%g0, %%g0, %%o1 ! X,C flags\n"
472
" srl %%o0, 24, %0\n"
473
" stb %%o1, [%1 + 1]\n"
475
" or %%o1, 0x08, %%o1 ! N flag\n"
477
" or %%o1, 0x04, %%o1 ! Z flag\n"
479
" or %%o1, 0x02, %%o1 ! V flag\n"
482
: "r" (flags), "r" (dst), "r" (src)
488
static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
492
" sll %2, 16, %%o0\n"
493
" sll %3, 16, %%o1\n"
494
" subcc %%o0, %%o1, %%o0\n"
495
" addx %%g0, %%g0, %%o1 ! X,C flags\n"
496
" srl %%o0, 16, %0\n"
497
" stb %%o1, [%1 + 1]\n"
499
" or %%o1, 0x08, %%o1 ! N flag\n"
501
" or %%o1, 0x04, %%o1 ! Z flag\n"
503
" or %%o1, 0x02, %%o1 ! V flag\n"
506
: "r" (flags), "r" (dst), "r" (src)
512
static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
516
" subcc %2, %3, %0\n"
517
" addx %%g0, %%g0, %%o0 ! X,C flags\n"
518
" stb %%o0, [%1 + 1]\n"
520
" or %%o0, 0x08, %%o0 ! N flag\n"
522
" or %%o0, 0x04, %%o0 ! Z flag\n"
524
" or %%o0, 0x02, %%o0 ! V flag\n"
527
: "r" (flags), "r" (dst), "r" (src)
533
static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
536
" sll %1, 24, %%o0\n"
537
" sll %2, 24, %%o1\n"
538
" subcc %%o0, %%o1, %%g0\n"
539
" addx %%g0, %%g0, %%o0 ! C flag\n"
541
" or %%o0, 0x08, %%o0 ! N flag\n"
543
" or %%o0, 0x04, %%o0 ! Z flag\n"
545
" or %%o0, 0x02, %%o0 ! V flag\n"
548
: "r" (flags), "r" (dst), "r" (src)
553
static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
556
" sll %1, 16, %%o0\n"
557
" sll %2, 16, %%o1\n"
558
" subcc %%o0, %%o1, %%g0\n"
559
" addx %%g0, %%g0, %%o0 ! C flag\n"
561
" or %%o0, 0x08, %%o0 ! N flag\n"
563
" or %%o0, 0x04, %%o0 ! Z flag\n"
565
" or %%o0, 0x02, %%o0 ! V flag\n"
568
: "r" (flags), "r" (dst), "r" (src)
573
static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
576
" subcc %1, %2, %%o1\n"
577
" srl %%o1, 31, %%o0\n"
578
" sll %%o0, 3, %%o0\n"
579
" addx %%o0, %%g0, %%o0\n"
581
" or %%o0, 0x02, %%o0\n"
582
" subcc %%g0, %%o1, %%g0\n"
583
" addx %%g0, 7, %%o1\n"
584
" and %%o1, 0x04, %%o1\n"
585
" or %%o0, %%o1, %%o0\n"
588
: "r" (flags), "r" (dst), "r" (src)
593
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
597
" ldub [%1 + 1], %%o1 ! Get the X Flag\n"
598
" subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
599
" addxcc %2, %3, %0\n"
601
: "r" (flags), "r" (dst), "r" (src)
609
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
613
" sll %2, 24, %%o0\n"
614
" sll %3, 24, %%o1\n"
615
" addcc %%o0, %%o1, %%o0\n"
616
" addx %%g0, %%g0, %%o1 ! X,C flags\n"
618
" or %%o1, 0x02, %%o1 ! V flag\n"
619
" ldub [%1 + 1], %%o2\n"
620
" subcc %%g0, %%o2, %%g0\n"
621
" addx %%g0, %%g0, %%o2\n"
622
" sll %%o2, 24, %%o2\n"
623
" addcc %%o0, %%o2, %%o0\n"
624
" srl %%o0, 24, %0\n"
625
" addx %%g0, %%g0, %%o2\n"
626
" or %%o1, %%o2, %%o1 ! update X,C flags\n"
628
" or %%o1, 0x08, %%o1 ! N flag\n"
629
" ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n"
631
" or %%o1, 0x02, %%o1 ! update V flag\n"
632
" and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n"
633
" and %%o1, 1, %%o2 ! keep C flag in %%o2\n"
635
" or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n"
636
" stb %%o2, [%1 + 1] ! store the X flag\n"
637
" or %%o1, %%o0, %%o1\n"
640
: "r" (flags), "r" (dst), "r" (src)
641
: "cc", "o0", "o1", "o2"
647
static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
651
" ldub [%1 + 1], %%o0 ! Get the X Flag\n"
652
" subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
653
" addxcc %2, %3, %0\n"
654
" ldub [%1], %%o0 ! retreive the old NZVC flags\n"
655
" and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
656
" addx %%o0, %%g0, %%o0 ! X,C flags\n"
658
" or %%o0, 0x08, %%o0 ! N flag\n"
660
" or %%o0, 0x02, %%o0 ! V flag\n"
662
" and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
664
" stb %%o0, [%1 + 1]\n"
666
: "r" (flags), "r" (dst), "r" (src)
672
#endif /* SPARC_V8_ASSEMBLY */
674
#ifdef SPARC_V9_ASSEMBLY
676
static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
680
" sll %2, 24, %%o0\n"
681
" sll %3, 24, %%o1\n"
682
" addcc %%o0, %%o1, %%o0\n"
684
" srl %%o0, 24, %0\n"
686
" stb %%o1, [%1+1]\n"
688
: "r" (flags), "r" (dst), "r" (src)
694
static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
698
" sll %2, 16, %%o0\n"
699
" sll %3, 16, %%o1\n"
700
" addcc %%o0, %%o1, %%o0\n"
702
" srl %%o0, 16, %0\n"
704
" stb %%o1, [%1+1]\n"
706
: "r" (flags), "r" (dst), "r" (src)
712
static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
716
" addcc %2, %3, %0\n"
719
" stb %%o0, [%1+1]\n"
721
: "r" (flags), "r" (dst), "r" (src)
727
static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
731
" sll %2, 24, %%o0\n"
732
" sll %3, 24, %%o1\n"
733
" subcc %%o0, %%o1, %%o0\n"
735
" srl %%o0, 24, %0\n"
737
" stb %%o1, [%1+1]\n"
739
: "r" (flags), "r" (dst), "r" (src)
745
static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
749
" sll %2, 16, %%o0\n"
750
" sll %3, 16, %%o1\n"
751
" subcc %%o0, %%o1, %%o0\n"
753
" srl %%o0, 16, %0\n"
755
" stb %%o1, [%1+1]\n"
757
: "r" (flags), "r" (dst), "r" (src)
763
static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
767
" subcc %2, %3, %0\n"
770
" stb %%o0, [%1+1]\n"
772
: "r" (flags), "r" (dst), "r" (src)
778
static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
781
" sll %1, 24, %%o0\n"
782
" sll %2, 24, %%o1\n"
783
" subcc %%o0, %%o1, %%g0\n"
787
: "r" (flags), "r" (dst), "r" (src)
792
static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
795
" sll %1, 16, %%o0\n"
796
" sll %2, 16, %%o1\n"
797
" subcc %%o0, %%o1, %%g0\n"
801
: "r" (flags), "r" (dst), "r" (src)
806
static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
809
" subcc %1, %2, %%g0\n"
811
" subcc %1, %2, %%o1\n"
812
" srl %%o1, 31, %%o0\n"
813
" sll %%o0, 3, %%o0\n"
814
" addx %%o0, %%g0, %%o0\n"
816
" or %%o0, 0x02, %%o0\n"
817
" subcc %%g0, %%o1, %%g0\n"
818
" addx %%g0, 7, %%o1\n"
819
" and %%o1, 0x04, %%o1\n"
820
" or %%o0, %%o1, %%o0\n"
823
" subcc %1, %2, %%o1\n"
824
" srl %%o1, 31, %%o0\n"
825
" sll %%o0, 3, %%o0\n"
826
" addx %%o0, %%g0, %%o0\n"
828
" or %%o0, 0x02, %%o0\n"
829
" subcc %%g0, %%o1, %%g0\n"
830
" addx %%g0, 7, %%o1\n"
831
" and %%o1, 0x04, %%o1\n"
832
" or %%o0, %%o1, %%o0\n"
838
: "r" (flags), "r" (dst), "r" (src)
844
static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
847
" sll %1, 24, %%o0\n"
848
" subcc %%o0, %%g0, %%g0\n"
852
: "r" (flags), "r" (val)
857
static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
860
" sll %1, 16, %%o0\n"
861
" subcc %%o0, %%g0, %%g0\n"
865
: "r" (flags), "r" (val)
870
static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
873
" subcc %1, %%g0, %%g0\n"
877
: "r" (flags), "r" (val)
882
static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
885
" sll %1, 24, %%o0\n"
886
" subcc %%o0, %%g0, %%o1\n"
887
" srl %%o1, 31, %%o0\n"
888
" sll %%o0, 3, %%o0\n"
889
" addx %%o0, %%g0, %%o0\n"
891
" or %%o0, 0x02, %%o0\n"
892
" subcc %%g0, %%o1, %%g0\n"
893
" addx %%g0, 7, %%o1\n"
894
" and %%o1, 0x04, %%o1\n"
895
" or %%o0, %%o1, %%o0\n"
898
: "r" (flags), "r" (val)
903
static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
906
" sll %1, 16, %%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"
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"
919
: "r" (flags), "r" (val)
924
static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
927
" subcc %1, %%g0, %%o1\n"
928
" srl %%o1, 31, %%o0\n"
929
" sll %%o0, 3, %%o0\n"
930
" addx %%o0, %%g0, %%o0\n"
932
" or %%o0, 0x02, %%o0\n"
933
" subcc %%g0, %%o1, %%g0\n"
934
" addx %%g0, 7, %%o1\n"
935
" and %%o1, 0x04, %%o1\n"
936
" or %%o0, %%o1, %%o0\n"
939
: "r" (flags), "r" (val)
945
static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
949
" ldub [%1 + 1], %%o1 ! Get the X Flag\n"
950
" subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
951
" addxcc %2, %3, %0\n"
953
: "r" (flags), "r" (dst), "r" (src)
959
static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
963
" ldub [%1 + 1], %%o0 ! Get the X Flag\n"
964
" subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
965
" addxcc %2, %3, %0\n"
966
" ldub [%1], %%o0 ! retreive the old NZVC flags\n"
967
" and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
968
" addx %%o0, %%g0, %%o0 ! X,C flags\n"
970
" or %%o0, 0x08, %%o0 ! N flag\n"
972
" or %%o0, 0x02, %%o0 ! V flag\n"
974
" and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
976
" stb %%o0, [%1 + 1]\n"
978
: "r" (flags), "r" (dst), "r" (src)
984
#endif /* SPARC_V9_ASSEMBLY */
998
extern struct flag_struct regflags;
1000
#define ZFLG (regflags.z)
1001
#define NFLG (regflags.n)
1002
#define CFLG (regflags.c)
1003
#define VFLG (regflags.v)
1004
#define XFLG (regflags.x)
1006
#define SET_CFLG(x) (CFLG = (x))
1007
#define SET_NFLG(x) (NFLG = (x))
1008
#define SET_VFLG(x) (VFLG = (x))
1009
#define SET_ZFLG(x) (ZFLG = (x))
1010
#define SET_XFLG(x) (XFLG = (x))
1012
#define GET_CFLG CFLG
1013
#define GET_NFLG NFLG
1014
#define GET_VFLG VFLG
1015
#define GET_ZFLG ZFLG
1016
#define GET_XFLG XFLG
1018
#define CLEAR_CZNV do { \
1025
#define COPY_CARRY (SET_XFLG (GET_CFLG))
1027
static __inline__ int cctrue(const int cc)
1030
case 0: return 1; /* T */
1031
case 1: return 0; /* F */
1032
case 2: return !CFLG && !ZFLG; /* HI */
1033
case 3: return CFLG || ZFLG; /* LS */
1034
case 4: return !CFLG; /* CC */
1035
case 5: return CFLG; /* CS */
1036
case 6: return !ZFLG; /* NE */
1037
case 7: return ZFLG; /* EQ */
1038
case 8: return !VFLG; /* VC */
1039
case 9: return VFLG; /* VS */
1040
case 10:return !NFLG; /* PL */
1041
case 11:return NFLG; /* MI */
1042
case 12:return NFLG == VFLG; /* GE */
1043
case 13:return NFLG != VFLG; /* LT */
1044
case 14:return !ZFLG && (NFLG == VFLG); /* GT */
1045
case 15:return ZFLG || (NFLG != VFLG); /* LE */
1050
#endif /* OPTIMIZED_FLAGS */
1052
#endif /* M68K_FLAGS_H */