~ubuntu-branches/ubuntu/gutsy/basilisk2/gutsy

« back to all changes in this revision

Viewing changes to src/uae_cpu/m68k.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2003-07-24 00:48:57 UTC
  • Revision ID: james.westby@ubuntu.com-20030724004857-vnv33v6vf7a7u0z6
Tags: upstream-0.9.20030722
ImportĀ upstreamĀ versionĀ 0.9.20030722

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 /* 
 
2
  * UAE - The Un*x Amiga Emulator
 
3
  * 
 
4
  * MC68000 emulation - machine dependent bits
 
5
  *
 
6
  * Copyright 1996 Bernd Schmidt
 
7
  */
 
8
 
 
9
#ifndef M68K_FLAGS_H
 
10
#define M68K_FLAGS_H
 
11
 
 
12
#ifdef OPTIMIZED_FLAGS
 
13
 
 
14
#if (defined(__i386__) && defined(X86_ASSEMBLY)) || (defined(__x86_64__) && defined(X86_64_ASSEMBLY))
 
15
 
 
16
#ifndef SAHF_SETO_PROFITABLE
 
17
 
 
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
 
20
   on the target.  */
 
21
struct flag_struct {
 
22
    unsigned long cznv;
 
23
    unsigned long x;
 
24
};
 
25
 
 
26
#define FLAGVAL_Z       0x40
 
27
#define FLAGVAL_N       0x80
 
28
 
 
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))
 
34
 
 
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)
 
40
 
 
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))
 
45
 
 
46
#define COPY_CARRY      (regflags.x = regflags.cznv)
 
47
 
 
48
extern struct flag_struct regflags __asm__ ("regflags");
 
49
 
 
50
static __inline__ int cctrue(int cc)
 
51
{
 
52
    uae_u32 cznv = regflags.cznv;
 
53
    switch(cc){
 
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 */
 
68
     case 14:
 
69
        cznv &= 0x8c0;
 
70
        return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
 
71
     case 15:
 
72
        cznv &= 0x8c0;
 
73
        return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
 
74
    }
 
75
    return 0;
 
76
}
 
77
 
 
78
#define optflag_testl(v) \
 
79
  __asm__ __volatile__ ("andl %1,%1\n\t" \
 
80
                        "pushf\n\t" \
 
81
                        "pop %0\n\t" \
 
82
                        : "=r" (regflags.cznv) : "r" (v) : "cc")
 
83
 
 
84
#define optflag_testw(v) \
 
85
  __asm__ __volatile__ ("andw %w1,%w1\n\t" \
 
86
                        "pushf\n\t" \
 
87
                        "pop %0\n\t" \
 
88
                        : "=r" (regflags.cznv) : "r" (v) : "cc")
 
89
 
 
90
#define optflag_testb(v) \
 
91
  __asm__ __volatile__ ("andb %b1,%b1\n\t" \
 
92
                        "pushf\n\t" \
 
93
                        "pop %0\n\t" \
 
94
                        : "=r" (regflags.cznv) : "q" (v) : "cc")
 
95
 
 
96
#define optflag_addl(v, s, d) do { \
 
97
  __asm__ __volatile__ ("addl %k2,%k1\n\t" \
 
98
                        "pushf\n\t" \
 
99
                        "pop %0\n\t" \
 
100
                        : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
 
101
    COPY_CARRY; \
 
102
    } while (0)
 
103
 
 
104
#define optflag_addw(v, s, d) do { \
 
105
  __asm__ __volatile__ ("addw %w2,%w1\n\t" \
 
106
                        "pushf\n\t" \
 
107
                        "pop %0\n\t" \
 
108
                        : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
 
109
    COPY_CARRY; \
 
110
    } while (0)
 
111
 
 
112
#define optflag_addb(v, s, d) do { \
 
113
  __asm__ __volatile__ ("addb %b2,%b1\n\t" \
 
114
                        "pushf\n\t" \
 
115
                        "pop %0\n\t" \
 
116
                        : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
 
117
    COPY_CARRY; \
 
118
    } while (0)
 
119
 
 
120
#define optflag_subl(v, s, d) do { \
 
121
  __asm__ __volatile__ ("subl %k2,%k1\n\t" \
 
122
                        "pushf\n\t" \
 
123
                        "pop %0\n\t" \
 
124
                        : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
 
125
    COPY_CARRY; \
 
126
    } while (0)
 
127
 
 
128
#define optflag_subw(v, s, d) do { \
 
129
  __asm__ __volatile__ ("subw %w2,%w1\n\t" \
 
130
                        "pushf\n\t" \
 
131
                        "pop %0\n\t" \
 
132
                        : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
 
133
    COPY_CARRY; \
 
134
    } while (0)
 
135
 
 
136
#define optflag_subb(v, s, d) do { \
 
137
  __asm__ __volatile__ ("subb %b2,%b1\n\t" \
 
138
                        "pushf\n\t" \
 
139
                        "pop %0\n\t" \
 
140
                        : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
 
141
    COPY_CARRY; \
 
142
    } while (0)
 
143
 
 
144
#define optflag_cmpl(s, d) \
 
145
  __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
 
146
                        "pushf\n\t" \
 
147
                        "pop %0\n\t" \
 
148
                        : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
 
149
 
 
150
#define optflag_cmpw(s, d) \
 
151
  __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
 
152
                        "pushf\n\t" \
 
153
                        "pop %0\n\t" \
 
154
                        : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
 
155
 
 
156
#define optflag_cmpb(s, d) \
 
157
  __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
 
158
                        "pushf\n\t" \
 
159
                        "pop %0\n\t" \
 
160
                        : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
 
161
 
 
162
#else
 
163
 
 
164
struct flag_struct {
 
165
    uae_u32 cznv;
 
166
    uae_u32 x;
 
167
};
 
168
 
 
169
#define FLAGVAL_Z       0x4000
 
170
#define FLAGVAL_N       0x8000
 
171
 
 
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))
 
177
 
 
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)
 
183
 
 
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))
 
188
 
 
189
#define COPY_CARRY      (regflags.x = (regflags.cznv)>>8)
 
190
 
 
191
extern struct flag_struct regflags __asm__ ("regflags");
 
192
 
 
193
static __inline__ int cctrue(int cc)
 
194
{
 
195
    uae_u32 cznv = regflags.cznv;
 
196
    switch(cc){
 
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 */
 
211
     case 14:
 
212
        cznv &= 0xc001;
 
213
        return (((cznv << 15) ^ cznv) & 0xc000) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
 
214
     case 15:
 
215
        cznv &= 0xc001;
 
216
        return (((cznv << 15) ^ cznv) & 0xc000) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
 
217
    }
 
218
    abort();
 
219
    return 0;
 
220
}
 
221
 
 
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" \
 
226
                        "lahf\n\t" \
 
227
                        "seto %%al\n\t" \
 
228
                        "movb %%al,regflags\n\t" \
 
229
                        "movb %%ah,regflags+1\n\t" \
 
230
                        : : "r" (v) : "%eax","cc","memory")
 
231
 
 
232
#define optflag_testw(v) \
 
233
  __asm__ __volatile__ ("andw %w0,%w0\n\t" \
 
234
                        "lahf\n\t" \
 
235
                        "seto %%al\n\t" \
 
236
                        "movb %%al,regflags\n\t" \
 
237
                        "movb %%ah,regflags+1\n\t" \
 
238
                        : : "r" (v) : "%eax","cc","memory")
 
239
 
 
240
#define optflag_testb(v) \
 
241
  __asm__ __volatile__ ("andb %b0,%b0\n\t" \
 
242
                        "lahf\n\t" \
 
243
                        "seto %%al\n\t" \
 
244
                        "movb %%al,regflags\n\t" \
 
245
                        "movb %%ah,regflags+1\n\t" \
 
246
                        : : "q" (v) : "%eax","cc","memory")
 
247
 
 
248
#define optflag_addl(v, s, d) do { \
 
249
  __asm__ __volatile__ ("addl %k1,%k0\n\t" \
 
250
                        "lahf\n\t" \
 
251
                        "seto %%al\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"); \
 
255
                        COPY_CARRY; \
 
256
        } while (0)
 
257
 
 
258
#define optflag_addw(v, s, d) do { \
 
259
  __asm__ __volatile__ ("addw %w1,%w0\n\t" \
 
260
                        "lahf\n\t" \
 
261
                        "seto %%al\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"); \
 
265
                        COPY_CARRY; \
 
266
    } while (0)
 
267
 
 
268
#define optflag_addb(v, s, d) do { \
 
269
  __asm__ __volatile__ ("addb %b1,%b0\n\t" \
 
270
                        "lahf\n\t" \
 
271
                        "seto %%al\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"); \
 
275
                        COPY_CARRY; \
 
276
    } while (0)
 
277
 
 
278
#define optflag_subl(v, s, d) do { \
 
279
  __asm__ __volatile__ ("subl %k1,%k0\n\t" \
 
280
                        "lahf\n\t" \
 
281
                        "seto %%al\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"); \
 
285
                        COPY_CARRY; \
 
286
    } while (0)
 
287
 
 
288
#define optflag_subw(v, s, d) do { \
 
289
  __asm__ __volatile__ ("subw %w1,%w0\n\t" \
 
290
                        "lahf\n\t" \
 
291
                        "seto %%al\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"); \
 
295
                        COPY_CARRY; \
 
296
    } while (0)
 
297
 
 
298
#define optflag_subb(v, s, d) do { \
 
299
   __asm__ __volatile__ ("subb %b1,%b0\n\t" \
 
300
                        "lahf\n\t" \
 
301
                        "seto %%al\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"); \
 
305
                        COPY_CARRY; \
 
306
    } while (0)
 
307
 
 
308
#define optflag_cmpl(s, d) \
 
309
  __asm__ __volatile__ ("cmpl %k0,%k1\n\t" \
 
310
                        "lahf\n\t" \
 
311
                        "seto %%al\n\t" \
 
312
                        "movb %%al,regflags\n\t" \
 
313
                        "movb %%ah,regflags+1\n\t" \
 
314
                        : : "rmi" (s), "r" (d) : "%eax","cc","memory")
 
315
 
 
316
#define optflag_cmpw(s, d) \
 
317
  __asm__ __volatile__ ("cmpw %w0,%w1\n\t" \
 
318
                        "lahf\n\t" \
 
319
                        "seto %%al\n\t" \
 
320
                        "movb %%al,regflags\n\t" \
 
321
                        "movb %%ah,regflags+1\n\t" \
 
322
                        : : "rmi" (s), "r" (d) : "%eax","cc","memory");
 
323
 
 
324
#define optflag_cmpb(s, d) \
 
325
  __asm__ __volatile__ ("cmpb %b0,%b1\n\t" \
 
326
                        "lahf\n\t" \
 
327
                        "seto %%al\n\t" \
 
328
                        "movb %%al,regflags\n\t" \
 
329
                        "movb %%ah,regflags+1\n\t" \
 
330
                        : : "qmi" (s), "q" (d) : "%eax","cc","memory")
 
331
 
 
332
#endif
 
333
 
 
334
#elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
 
335
 
 
336
struct flag_struct {
 
337
    unsigned char nzvc;
 
338
    unsigned char x;
 
339
};
 
340
 
 
341
extern struct flag_struct regflags;
 
342
 
 
343
#define FLAGVAL_Z       0x04
 
344
#define FLAGVAL_N       0x08
 
345
 
 
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))
 
351
 
 
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)
 
357
 
 
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))
 
362
 
 
363
#define COPY_CARRY (regflags.x = regflags.nzvc)
 
364
 
 
365
static __inline__ int cctrue(int cc)
 
366
{
 
367
    uae_u32 nzvc = regflags.nzvc;
 
368
    switch(cc){
 
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 */
 
383
     case 14:
 
384
        nzvc &= 0x0e;
 
385
        return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
 
386
     case 15:
 
387
        nzvc &= 0x0e;
 
388
        return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
 
389
    }
 
390
    return 0;
 
391
}
 
392
 
 
393
#ifdef SPARC_V8_ASSEMBLY
 
394
 
 
395
static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
396
{
 
397
        uae_u32 value;
 
398
        __asm__ ("\n"
 
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"
 
405
                "       bl,a    .+8\n"
 
406
                "       or              %%o1, 0x08, %%o1        ! N flag\n"
 
407
                "       bz,a    .+8\n"
 
408
                "       or              %%o1, 0x04, %%o1        ! Z flag\n"
 
409
                "       bvs,a   .+8\n"
 
410
                "       or              %%o1, 0x02, %%o1        ! V flag\n"
 
411
                "       stb             %%o1, [%1]\n"
 
412
        :       "=&r" (value)
 
413
        :       "r" (flags), "r" (dst), "r" (src)
 
414
        :       "cc", "o0", "o1"
 
415
        );
 
416
        return value;
 
417
}
 
418
 
 
419
static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
420
{
 
421
        uae_u32 value;
 
422
        __asm__ ("\n"
 
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"
 
429
                "       bl,a    .+8\n"
 
430
                "       or              %%o1, 0x08, %%o1        ! N flag\n"
 
431
                "       bz,a    .+8\n"
 
432
                "       or              %%o1, 0x04, %%o1        ! Z flag\n"
 
433
                "       bvs,a   .+8\n"
 
434
                "       or              %%o1, 0x02, %%o1        ! V flag\n"
 
435
                "       stb             %%o1, [%1]\n"
 
436
        :       "=&r" (value)
 
437
        :       "r" (flags), "r" (dst), "r" (src)
 
438
        :       "cc", "o0", "o1"
 
439
        );
 
440
        return value;
 
441
}
 
442
 
 
443
static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
444
{
 
445
        uae_u32 value;
 
446
        __asm__ ("\n"
 
447
                "       addcc   %2, %3, %0\n"
 
448
                "       addx    %%g0, %%g0, %%o0        ! X,C flags\n"
 
449
                "       stb             %%o0, [%1 + 1]\n"
 
450
                "       bl,a    .+8\n"
 
451
                "       or              %%o0, 0x08, %%o0        ! N flag\n"
 
452
                "       bz,a    .+8\n"
 
453
                "       or              %%o0, 0x04, %%o0        ! Z flag\n"
 
454
                "       bvs,a   .+8\n"
 
455
                "       or              %%o0, 0x02, %%o0        ! V flag\n"
 
456
                "       stb             %%o0, [%1]\n"
 
457
        :       "=&r" (value)
 
458
        :       "r" (flags), "r" (dst), "r" (src)
 
459
        :       "cc", "o0"
 
460
        );
 
461
        return value;
 
462
}
 
463
 
 
464
static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
465
{
 
466
        uae_u32 value;
 
467
        __asm__ ("\n"
 
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"
 
474
                "       bl,a    .+8\n"
 
475
                "       or              %%o1, 0x08, %%o1        ! N flag\n"
 
476
                "       bz,a    .+8\n"
 
477
                "       or              %%o1, 0x04, %%o1        ! Z flag\n"
 
478
                "       bvs,a   .+8\n"
 
479
                "       or              %%o1, 0x02, %%o1        ! V flag\n"
 
480
                "       stb             %%o1, [%1]\n"
 
481
        :       "=&r" (value)
 
482
        :       "r" (flags), "r" (dst), "r" (src)
 
483
        :       "cc", "o0", "o1"
 
484
        );
 
485
        return value;
 
486
}
 
487
 
 
488
static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
489
{
 
490
        uae_u32 value;
 
491
        __asm__ ("\n"
 
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"
 
498
                "       bl,a    .+8\n"
 
499
                "       or              %%o1, 0x08, %%o1        ! N flag\n"
 
500
                "       bz,a    .+8\n"
 
501
                "       or              %%o1, 0x04, %%o1        ! Z flag\n"
 
502
                "       bvs,a   .+8\n"
 
503
                "       or              %%o1, 0x02, %%o1        ! V flag\n"
 
504
                "       stb             %%o1, [%1]\n"
 
505
        :       "=&r" (value)
 
506
        :       "r" (flags), "r" (dst), "r" (src)
 
507
        :       "cc", "o0", "o1"
 
508
        );
 
509
        return value;
 
510
}
 
511
 
 
512
static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
513
{
 
514
        uae_u32 value;
 
515
        __asm__ ("\n"
 
516
                "       subcc   %2, %3, %0\n"
 
517
                "       addx    %%g0, %%g0, %%o0        ! X,C flags\n"
 
518
                "       stb             %%o0, [%1 + 1]\n"
 
519
                "       bl,a    .+8\n"
 
520
                "       or              %%o0, 0x08, %%o0        ! N flag\n"
 
521
                "       bz,a    .+8\n"
 
522
                "       or              %%o0, 0x04, %%o0        ! Z flag\n"
 
523
                "       bvs,a   .+8\n"
 
524
                "       or              %%o0, 0x02, %%o0        ! V flag\n"
 
525
                "       stb             %%o0, [%1]\n"
 
526
        :       "=&r" (value)
 
527
        :       "r" (flags), "r" (dst), "r" (src)
 
528
        :       "cc", "o0"
 
529
        );
 
530
        return value;
 
531
}
 
532
 
 
533
static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
534
{
 
535
        __asm__ ("\n"
 
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"
 
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, [%0]\n"
 
547
        :       /* no outputs */
 
548
        :       "r" (flags), "r" (dst), "r" (src)
 
549
        :       "cc", "o0", "o1"
 
550
        );
 
551
}
 
552
 
 
553
static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
554
{
 
555
        __asm__ ("\n"
 
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"
 
560
                "       bl,a    .+8\n"
 
561
                "       or              %%o0, 0x08, %%o0        ! N flag\n"
 
562
                "       bz,a    .+8\n"
 
563
                "       or              %%o0, 0x04, %%o0        ! Z flag\n"
 
564
                "       bvs,a   .+8\n"
 
565
                "       or              %%o0, 0x02, %%o0        ! V flag\n"
 
566
                "       stb             %%o0, [%0]\n"
 
567
        :       /* no outputs */
 
568
        :       "r" (flags), "r" (dst), "r" (src)
 
569
        :       "cc", "o0", "o1"
 
570
        );
 
571
}
 
572
 
 
573
static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
574
{
 
575
        __asm__ ("\n"
 
576
                "       subcc   %1, %2, %%o1\n"
 
577
                "       srl             %%o1, 31, %%o0\n"
 
578
                "       sll             %%o0, 3, %%o0\n"
 
579
                "       addx    %%o0, %%g0, %%o0\n"
 
580
                "       bvs,a   .+8\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"
 
586
                "       stb             %%o0, [%0]\n"
 
587
        :       /* no outputs */
 
588
        :       "r" (flags), "r" (dst), "r" (src)
 
589
        :       "cc", "o0", "o1"
 
590
        );
 
591
}
 
592
 
 
593
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
594
{
 
595
        uae_u32 value;
 
596
        __asm__ ("\n"
 
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"
 
600
        :       "=&r" (value)
 
601
        :       "r" (flags), "r" (dst), "r" (src)
 
602
        :       "cc", "o0", "o1"
 
603
        );
 
604
        return value;
 
605
}
 
606
 
 
607
#if 0
 
608
VERY SLOW...
 
609
static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
610
{
 
611
        uae_u32 value;
 
612
        __asm__ ("\n"
 
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"
 
617
                "       bvs,a   .+8\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"
 
627
                "       bl,a    .+8\n"
 
628
                "       or              %%o1, 0x08, %%o1        ! N flag\n"
 
629
                "       ldub    [%1], %%o0                      ! retreive the old NZVC flags (XXX)\n"
 
630
                "       bvs,a   .+8\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"
 
634
                "       bnz,a   .+8\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"
 
638
                "       stb             %%o1, [%1]\n"
 
639
        :       "=&r" (value)
 
640
        :       "r" (flags), "r" (dst), "r" (src)
 
641
        :       "cc", "o0", "o1", "o2"
 
642
        );
 
643
        return value;
 
644
}
 
645
#endif
 
646
 
 
647
static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
648
{
 
649
        uae_u32 value;
 
650
        __asm__ ("\n"
 
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"
 
657
                "       bl,a    .+8\n"
 
658
                "       or              %%o0, 0x08, %%o0        ! N flag\n"
 
659
                "       bvs,a   .+8\n"
 
660
                "       or              %%o0, 0x02, %%o0        ! V flag\n"
 
661
                "       bnz,a   .+8\n"
 
662
                "       and             %%o0, 0x0B, %%o0        ! Z flag cleared if result is non-zero\n"
 
663
                "       stb             %%o0, [%1]\n"
 
664
                "       stb             %%o0, [%1 + 1]\n"
 
665
        :       "=&r" (value)
 
666
        :       "r" (flags), "r" (dst), "r" (src)
 
667
        :       "cc", "o0"
 
668
        );
 
669
        return value;
 
670
}
 
671
 
 
672
#endif /* SPARC_V8_ASSEMBLY */
 
673
 
 
674
#ifdef SPARC_V9_ASSEMBLY
 
675
 
 
676
static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
677
{
 
678
        uae_u32 value;
 
679
        __asm__ ("\n"
 
680
                "       sll             %2, 24, %%o0\n"
 
681
                "       sll             %3, 24, %%o1\n"
 
682
                "       addcc   %%o0, %%o1, %%o0\n"
 
683
                "       rd              %%ccr, %%o1\n"
 
684
                "       srl             %%o0, 24, %0\n"
 
685
                "       stb             %%o1, [%1]\n"
 
686
                "       stb             %%o1, [%1+1]\n"
 
687
        :       "=&r" (value)
 
688
        :       "r" (flags), "r" (dst), "r" (src)
 
689
        :       "cc", "o0", "o1"
 
690
        );
 
691
        return value;
 
692
}
 
693
 
 
694
static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
695
{
 
696
        uae_u32 value;
 
697
        __asm__ ("\n"
 
698
                "       sll             %2, 16, %%o0\n"
 
699
                "       sll             %3, 16, %%o1\n"
 
700
                "       addcc   %%o0, %%o1, %%o0\n"
 
701
                "       rd              %%ccr, %%o1\n"
 
702
                "       srl             %%o0, 16, %0\n"
 
703
                "       stb             %%o1, [%1]\n"
 
704
                "       stb             %%o1, [%1+1]\n"
 
705
        :       "=&r" (value)
 
706
        :       "r" (flags), "r" (dst), "r" (src)
 
707
        :       "cc", "o0", "o1"
 
708
        );
 
709
        return value;
 
710
}
 
711
 
 
712
static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
713
{
 
714
        uae_u32 value;
 
715
        __asm__ ("\n"
 
716
                "       addcc   %2, %3, %0\n"
 
717
                "       rd              %%ccr, %%o0\n"
 
718
                "       stb             %%o0, [%1]\n"
 
719
                "       stb             %%o0, [%1+1]\n"
 
720
        :       "=&r" (value)
 
721
        :       "r" (flags), "r" (dst), "r" (src)
 
722
        :       "cc", "o0"
 
723
        );
 
724
        return value;
 
725
}
 
726
 
 
727
static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
728
{
 
729
        uae_u32 value;
 
730
        __asm__ ("\n"
 
731
                "       sll             %2, 24, %%o0\n"
 
732
                "       sll             %3, 24, %%o1\n"
 
733
                "       subcc   %%o0, %%o1, %%o0\n"
 
734
                "       rd              %%ccr, %%o1\n"
 
735
                "       srl             %%o0, 24, %0\n"
 
736
                "       stb             %%o1, [%1]\n"
 
737
                "       stb             %%o1, [%1+1]\n"
 
738
        :       "=&r" (value)
 
739
        :       "r" (flags), "r" (dst), "r" (src)
 
740
        :       "cc", "o0", "o1"
 
741
        );
 
742
        return value;
 
743
}
 
744
 
 
745
static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
746
{
 
747
        uae_u32 value;
 
748
        __asm__ ("\n"
 
749
                "       sll             %2, 16, %%o0\n"
 
750
                "       sll             %3, 16, %%o1\n"
 
751
                "       subcc   %%o0, %%o1, %%o0\n"
 
752
                "       rd              %%ccr, %%o1\n"
 
753
                "       srl             %%o0, 16, %0\n"
 
754
                "       stb             %%o1, [%1]\n"
 
755
                "       stb             %%o1, [%1+1]\n"
 
756
        :       "=&r" (value)
 
757
        :       "r" (flags), "r" (dst), "r" (src)
 
758
        :       "cc", "o0", "o1"
 
759
        );
 
760
        return value;
 
761
}
 
762
 
 
763
static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
764
{
 
765
        uae_u32 value;
 
766
        __asm__ ("\n"
 
767
                "       subcc   %2, %3, %0\n"
 
768
                "       rd              %%ccr, %%o0\n"
 
769
                "       stb             %%o0, [%1]\n"
 
770
                "       stb             %%o0, [%1+1]\n"
 
771
        :       "=&r" (value)
 
772
        :       "r" (flags), "r" (dst), "r" (src)
 
773
        :       "cc", "o0"
 
774
        );
 
775
        return value;
 
776
}
 
777
 
 
778
static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
779
{
 
780
        __asm__ ("\n"
 
781
                "       sll             %1, 24, %%o0\n"
 
782
                "       sll             %2, 24, %%o1\n"
 
783
                "       subcc   %%o0, %%o1, %%g0\n"
 
784
                "       rd              %%ccr, %%o0\n"
 
785
                "       stb             %%o0, [%0]\n"
 
786
        :       /* no outputs */
 
787
        :       "r" (flags), "r" (dst), "r" (src)
 
788
        :       "cc", "o0", "o1"
 
789
        );
 
790
}
 
791
 
 
792
static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
793
{
 
794
        __asm__ ("\n"
 
795
                "       sll             %1, 16, %%o0\n"
 
796
                "       sll             %2, 16, %%o1\n"
 
797
                "       subcc   %%o0, %%o1, %%g0\n"
 
798
                "       rd              %%ccr, %%o0\n"
 
799
                "       stb             %%o0, [%0]\n"
 
800
        :       /* no outputs */
 
801
        :       "r" (flags), "r" (dst), "r" (src)
 
802
        :       "cc", "o0", "o1"
 
803
        );
 
804
}
 
805
 
 
806
static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
807
{
 
808
        __asm__ ("\n"
 
809
                "       subcc   %1, %2, %%g0\n"
 
810
#if 0
 
811
                "       subcc   %1, %2, %%o1\n"
 
812
                "       srl             %%o1, 31, %%o0\n"
 
813
                "       sll             %%o0, 3, %%o0\n"
 
814
                "       addx    %%o0, %%g0, %%o0\n"
 
815
                "       bvs,a   .+8\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"
 
821
#endif
 
822
#if 0
 
823
                "       subcc   %1, %2, %%o1\n"
 
824
                "       srl             %%o1, 31, %%o0\n"
 
825
                "       sll             %%o0, 3, %%o0\n"
 
826
                "       addx    %%o0, %%g0, %%o0\n"
 
827
                "       bvs,pt,a        .+8\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"
 
833
                "       stb             %%o0, [%0]\n"
 
834
#endif
 
835
                "       rd              %%ccr, %%o0\n"
 
836
                "       stb             %%o0, [%0]\n"
 
837
        :       /* no outputs */
 
838
        :       "r" (flags), "r" (dst), "r" (src)
 
839
        :       "cc", "o0", "o1"
 
840
        );
 
841
}
 
842
 
 
843
#if 1
 
844
static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
 
845
{
 
846
        __asm__ ("\n"
 
847
                "       sll             %1, 24, %%o0\n"
 
848
                "       subcc   %%o0, %%g0, %%g0\n"
 
849
                "       rd              %%ccr, %%o0\n"
 
850
                "       stb             %%o0, [%0]\n"
 
851
        :       /* no outputs */
 
852
        :       "r" (flags), "r" (val)
 
853
        :       "cc", "o0"
 
854
        );
 
855
}
 
856
 
 
857
static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
 
858
{
 
859
        __asm__ ("\n"
 
860
                "       sll             %1, 16, %%o0\n"
 
861
                "       subcc   %%o0, %%g0, %%g0\n"
 
862
                "       rd              %%ccr, %%o0\n"
 
863
                "       stb             %%o0, [%0]\n"
 
864
        :       /* no outputs */
 
865
        :       "r" (flags), "r" (val)
 
866
        :       "cc", "o0"
 
867
        );
 
868
}
 
869
 
 
870
static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
 
871
{
 
872
        __asm__ ("\n"
 
873
                "       subcc   %1, %%g0, %%g0\n"
 
874
                "       rd              %%ccr, %%o0\n"
 
875
                "       stb             %%o0, [%0]\n"
 
876
        :       /* no outputs */
 
877
        :       "r" (flags), "r" (val)
 
878
        :       "cc", "o0"
 
879
        );
 
880
}
 
881
#else
 
882
static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
 
883
{
 
884
        __asm__ ("\n"
 
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"
 
890
                "       bvs,a   .+8\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"
 
896
                "       stb             %%o0, [%0]\n"
 
897
        :       /* no outputs */
 
898
        :       "r" (flags), "r" (val)
 
899
        :       "cc", "o0", "o1"
 
900
        );
 
901
}
 
902
 
 
903
static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
 
904
{
 
905
        __asm__ ("\n"
 
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"
 
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_32(flag_struct *flags, uae_u32 val)
 
925
{
 
926
        __asm__ ("\n"
 
927
                "       subcc   %1, %%g0, %%o1\n"
 
928
                "       srl             %%o1, 31, %%o0\n"
 
929
                "       sll             %%o0, 3, %%o0\n"
 
930
                "       addx    %%o0, %%g0, %%o0\n"
 
931
                "       bvs,a   .+8\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"
 
937
                "       stb             %%o0, [%0]\n"
 
938
        :       /* no outputs */
 
939
        :       "r" (flags), "r" (val)
 
940
        :       "cc", "o0", "o1"
 
941
        );
 
942
}
 
943
#endif
 
944
 
 
945
static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
946
{
 
947
        uae_u32 value;
 
948
        __asm__ ("\n"
 
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"
 
952
        :       "=&r" (value)
 
953
        :       "r" (flags), "r" (dst), "r" (src)
 
954
        :       "cc", "o0", "o1"
 
955
        );
 
956
        return value;
 
957
}
 
958
 
 
959
static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
 
960
{
 
961
        uae_u32 value;
 
962
        __asm__ ("\n"
 
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"
 
969
                "       bl,a    .+8\n"
 
970
                "       or              %%o0, 0x08, %%o0        ! N flag\n"
 
971
                "       bvs,a   .+8\n"
 
972
                "       or              %%o0, 0x02, %%o0        ! V flag\n"
 
973
                "       bnz,a   .+8\n"
 
974
                "       and             %%o0, 0x0B, %%o0        ! Z flag cleared if result is non-zero\n"
 
975
                "       stb             %%o0, [%1]\n"
 
976
                "       stb             %%o0, [%1 + 1]\n"
 
977
        :       "=&r" (value)
 
978
        :       "r" (flags), "r" (dst), "r" (src)
 
979
        :       "cc", "o0"
 
980
        );
 
981
        return value;
 
982
}
 
983
 
 
984
#endif /* SPARC_V9_ASSEMBLY */
 
985
 
 
986
#endif
 
987
 
 
988
#else
 
989
 
 
990
struct flag_struct {
 
991
    unsigned int c;
 
992
    unsigned int z;
 
993
    unsigned int n;
 
994
    unsigned int v; 
 
995
    unsigned int x;
 
996
};
 
997
 
 
998
extern struct flag_struct regflags;
 
999
 
 
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)
 
1005
 
 
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))
 
1011
 
 
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
 
1017
 
 
1018
#define CLEAR_CZNV do { \
 
1019
 SET_CFLG (0); \
 
1020
 SET_ZFLG (0); \
 
1021
 SET_NFLG (0); \
 
1022
 SET_VFLG (0); \
 
1023
} while (0)
 
1024
 
 
1025
#define COPY_CARRY (SET_XFLG (GET_CFLG))
 
1026
 
 
1027
static __inline__ int cctrue(const int cc)
 
1028
{
 
1029
    switch(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 */
 
1046
    }
 
1047
    return 0;
 
1048
}
 
1049
 
 
1050
#endif /* OPTIMIZED_FLAGS */
 
1051
 
 
1052
#endif /* M68K_FLAGS_H */