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.3 by cebix, 1999-10-28T16:00:26Z vs.
Revision 1.6 by gbeauche, 2002-11-05T11:59:12Z

# Line 6 | Line 6
6    * Copyright 1996 Bernd Schmidt
7    */
8  
9 < #if defined(__i386__) && defined(X86_ASSEMBLY)
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 int cznv;
23 <    unsigned int x;
22 >    unsigned long cznv;
23 >    unsigned long x;
24   };
25  
26 < #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
27 < #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
28 < #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
29 < #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
30 < #define SET_XFLG(y) (regflags.x = (y))
31 <
32 < #define GET_ZFLG ((regflags.cznv >> 6) & 1)
33 < #define GET_CFLG (regflags.cznv & 1)
34 < #define GET_VFLG ((regflags.cznv >> 11) & 1)
35 < #define GET_NFLG ((regflags.cznv >> 7) & 1)
36 < #define GET_XFLG (regflags.x & 1)
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 CLEAR_CZNV (regflags.cznv = 0)
29 < #define COPY_CARRY (regflags.x = regflags.cznv)
46 > #define COPY_CARRY      (regflags.x = regflags.cznv)
47  
48   extern struct flag_struct regflags __asm__ ("regflags");
49  
# Line 58 | Line 75 | static __inline__ int cctrue(int cc)
75      return 0;
76   }
77  
78 < #define x86_flag_testl(v) \
79 <  __asm__ __volatile__ ("testl %1,%1\n\t" \
80 <                        "pushfl\n\t" \
81 <                        "popl %0\n\t" \
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 x86_flag_testw(v) \
85 <  __asm__ __volatile__ ("testw %w1,%w1\n\t" \
86 <                        "pushfl\n\t" \
87 <                        "popl %0\n\t" \
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 x86_flag_testb(v) \
91 <  __asm__ __volatile__ ("testb %b1,%b1\n\t" \
92 <                        "pushfl\n\t" \
93 <                        "popl %0\n\t" \
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 x86_flag_addl(v, s, d) do { \
96 > #define optflag_addl(v, s, d) do { \
97    __asm__ __volatile__ ("addl %k2,%k1\n\t" \
98 <                        "pushfl\n\t" \
99 <                        "popl %0\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 x86_flag_addw(v, s, d) do { \
104 > #define optflag_addw(v, s, d) do { \
105    __asm__ __volatile__ ("addw %w2,%w1\n\t" \
106 <                        "pushfl\n\t" \
107 <                        "popl %0\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 x86_flag_addb(v, s, d) do { \
112 > #define optflag_addb(v, s, d) do { \
113    __asm__ __volatile__ ("addb %b2,%b1\n\t" \
114 <                        "pushfl\n\t" \
115 <                        "popl %0\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 x86_flag_subl(v, s, d) do { \
120 > #define optflag_subl(v, s, d) do { \
121    __asm__ __volatile__ ("subl %k2,%k1\n\t" \
122 <                        "pushfl\n\t" \
123 <                        "popl %0\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 x86_flag_subw(v, s, d) do { \
128 > #define optflag_subw(v, s, d) do { \
129    __asm__ __volatile__ ("subw %w2,%w1\n\t" \
130 <                        "pushfl\n\t" \
131 <                        "popl %0\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 x86_flag_subb(v, s, d) do { \
136 > #define optflag_subb(v, s, d) do { \
137    __asm__ __volatile__ ("subb %b2,%b1\n\t" \
138 <                        "pushfl\n\t" \
139 <                        "popl %0\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 x86_flag_cmpl(s, d) \
144 > #define optflag_cmpl(s, d) \
145    __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
146 <                        "pushfl\n\t" \
147 <                        "popl %0\n\t" \
146 >                        "pushf\n\t" \
147 >                        "pop %0\n\t" \
148                          : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
149  
150 < #define x86_flag_cmpw(s, d) \
150 > #define optflag_cmpw(s, d) \
151    __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
152 <                        "pushfl\n\t" \
153 <                        "popl %0\n\t" \
152 >                        "pushf\n\t" \
153 >                        "pop %0\n\t" \
154                          : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
155  
156 < #define x86_flag_cmpb(s, d) \
156 > #define optflag_cmpb(s, d) \
157    __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
158 <                        "pushfl\n\t" \
159 <                        "popl %0\n\t" \
158 >                        "pushf\n\t" \
159 >                        "pop %0\n\t" \
160                          : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
161  
162 < #elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
162 > #else
163  
164   struct flag_struct {
165 <        union {
166 <                unsigned short  all;
150 <                unsigned char   bytes[2];
151 <        };
165 >    uae_u32 cznv;
166 >    uae_u32 x;
167   };
168  
169 < typedef unsigned short *        flags_addr;
170 < extern struct flag_struct       regflags;
156 < #define M68K_FLAGS_ADDR         ((flags_addr)(&regflags.all))
157 < #define M68K_FLAGS_NZVC         regflags.bytes[1]
158 < #define M68K_FLAGS_X            regflags.bytes[0]
169 > #define FLAGVAL_Z       0x4000
170 > #define FLAGVAL_N       0x8000
171  
172 < #if 0
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 SET_ZFLG(y)     (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x01) | ((y) & 1))
163 < #define SET_CFLG(y)     (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x02) | (((y) & 1) << 1))
164 < #define SET_XFLG(y)     (M68K_FLAGS_X = ((y) & 1) << 1)
165 < #define SET_VFLG(y)     (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x10) | (((y) & 1) << 4))
166 < #define SET_NFLG(y)     (M68K_FLAGS_NZVC = (M68K_FLAGS_NZVC & ~0x80) | (((y) & 1) << 7))
167 <
168 < #define GET_ZFLG        (M68K_FLAGS_NZVC & 1)
169 < #define GET_CFLG        ((M68K_FLAGS_NZVC >> 1) & 1)
170 < #define GET_XFLG        ((M68K_FLAGS_X >> 1) & 1)
171 < #define GET_VFLG        ((M68K_FLAGS_NZVC >> 4) & 1)
172 < #define GET_NFLG        ((M68K_FLAGS_NZVC >> 7) & 1)
189 > #define COPY_CARRY      (regflags.x = (regflags.cznv)>>8)
190  
191 < #define CLEAR_CZNV      (M68K_FLAGS_NZVC = 0)
175 < #define COPY_CARRY      (M68K_FLAGS_X = M68K_FLAGS_NZVC)
191 > extern struct flag_struct regflags __asm__ ("regflags");
192  
193 < #else
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 M68K_FLAGS_ALL          regflags.all
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 SET_ZFLG(y)     (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x01) | ((y) & 1))
299 < #define SET_CFLG(y)     (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x02) | (((y) & 1) << 1))
300 < #define SET_XFLG(y)     (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x200)| (((y) & 1) << 9))
301 < #define SET_VFLG(y)     (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x10) | (((y) & 1) << 4))
302 < #define SET_NFLG(y)     (M68K_FLAGS_ALL = (M68K_FLAGS_ALL & ~0x80) | (((y) & 1) << 7))
303 <
304 < #define GET_ZFLG        (M68K_FLAGS_ALL & 1)
305 < #define GET_CFLG        ((M68K_FLAGS_ALL >> 1) & 1)
306 < #define GET_XFLG        ((M68K_FLAGS_ALL >> 9) & 1)
190 < #define GET_VFLG        ((M68K_FLAGS_ALL >> 4) & 1)
191 < #define GET_NFLG        ((M68K_FLAGS_ALL >> 7) & 1)
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 CLEAR_CZNV      (M68K_FLAGS_NZVC = 0)
309 < #define COPY_CARRY      (M68K_FLAGS_X = M68K_FLAGS_NZVC)
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 = M68K_FLAGS_NZVC;
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 & 0x03) == 0;         /* !GET_CFLG && !GET_ZFLG;  HI */
372 <     case 3: return (nzvc & 0x03) != 0;         /* GET_CFLG || GET_ZFLG;    LS */
373 <     case 4: return (nzvc & 0x02) == 0;         /* !GET_CFLG;               CC */
374 <     case 5: return (nzvc & 0x02) != 0;         /* GET_CFLG;                CS */
375 <     case 6: return (nzvc & 0x01) == 0;         /* !GET_ZFLG;               NE */
376 <     case 7: return (nzvc & 0x01) != 0;         /* GET_ZFLG;                EQ */
377 <     case 8: return (nzvc & 0x10) == 0;         /* !GET_VFLG;               VC */
378 <     case 9: return (nzvc & 0x10) != 0;         /* GET_VFLG;                VS */
379 <     case 10:return (nzvc & 0x80) == 0;         /* !GET_NFLG;               PL */
380 <     case 11:return (nzvc & 0x80) != 0;         /* GET_NFLG;                MI */
381 <     case 12:return (((nzvc << 3) ^ nzvc) & 0x80) == 0; /* GET_NFLG == GET_VFLG;             GE */
382 <     case 13:return (((nzvc << 3) ^ nzvc) & 0x80) != 0; /* GET_NFLG != GET_VFLG;             LT */
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 < /*      N--V--CZ shifted by 3 leads to V--CZ--- */
385 <        return (((nzvc << 3) ^ nzvc) & 0x88) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
384 >        nzvc &= 0x0e;
385 >        return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
386       case 15:
387 <        return (((nzvc << 3) ^ nzvc) & 0x88) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
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 char *str_flags(void)
228 < {
229 <        static char str[8];
230 <        sprintf(str, "%c%c%c%c%c",
231 <                GET_XFLG ? 'X' : '-',
232 <                GET_NFLG ? 'N' : '-',
233 <                GET_ZFLG ? 'Z' : '-',
234 <                GET_VFLG ? 'V' : '-',
235 <                GET_CFLG ? 'C' : '-'
236 <                );
237 <        return str;
238 < }
239 <
240 < static inline uae_u32 sparc_v8_flag_add_8(flags_addr pflags, uae_u32 src, uae_u32 dst)
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 <                "       subx    %%g0, %%g0, %%o1\n"
403 <                "       srl             %%o0, 24, %0            ! 8-bit result\n"
404 <                "       and             %%o1, 0x202, %%o1       ! X, C flags\n"
405 <                "       and             %0, 0x80, %%o0\n"
406 <                "       or              %%o1, %%o0, %%o1        ! N flag\n"
407 <                "       subcc   %%g0, %0, %%g0\n"
408 <                "       subx    %%o1, -1, %%o1          ! Z flag\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, 0x10, %%o1        ! V flag\n"
411 <                "       sth             %%o1, [%1]\n"
410 >                "       or              %%o1, 0x02, %%o1        ! V flag\n"
411 >                "       stb             %%o1, [%1]\n"
412          :       "=&r" (value)
413 <        :       "r" (pflags), "r" (dst), "r" (src), "0" (value)
413 >        :       "r" (flags), "r" (dst), "r" (src)
414          :       "cc", "o0", "o1"
415          );
261        
262 //      printf("%d + %d = %d (flags = %s)\n", dst, src, value, str_flags());
416          return value;
417   }
418  
419 < static inline uae_u32 sparc_v8_flag_add_16(flags_addr pflags, uae_u32 src, uae_u32 dst)
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 <                "       subx    %%g0, %%g0, %%o1\n"
427 <                "       srl             %%o0, 16, %0            ! 16-bit result\n"
428 <                "       and             %%o1, 0x202, %%o1       ! X, C flags\n"
429 <                "       sra             %%o0, 24, %%o0\n"
430 <                "       and             %%o0, 0x80, %%o0\n"
431 <                "       or              %%o1, %%o0, %%o1        ! N flag\n"
432 <                "       subcc   %%g0, %0, %%g0\n"
280 <                "       subx    %%o1, -1, %%o1          ! Z flag\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, 0x10, %%o1        ! V flag\n"
435 <                "       sth             %%o1, [%1]\n"
434 >                "       or              %%o1, 0x02, %%o1        ! V flag\n"
435 >                "       stb             %%o1, [%1]\n"
436          :       "=&r" (value)
437 <        :       "r" (pflags), "r" (dst), "r" (src), "0" (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(flags_addr pflags, uae_u32 src, uae_u32 dst)
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 <                "       subx    %%g0, %%g0, %%o0\n"
449 <                "       sra             %0, 24, %%o1\n"
450 <                "       and             %%o0, 0x202, %%o0       ! X, C flags\n"
451 <                "       and             %%o1, 0x80, %%o1\n"
452 <                "       or              %%o0, %%o1, %%o0        ! N flag\n"
453 <                "       subcc   %%g0, %0, %%g0\n"
302 <                "       subx    %%o0, -1, %%o0          ! Z flag\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, 0x10, %%o0        ! V flag\n"
456 <                "       sth             %%o0, [%1]\n"
455 >                "       or              %%o0, 0x02, %%o0        ! V flag\n"
456 >                "       stb             %%o0, [%1]\n"
457          :       "=&r" (value)
458 <        :       "r" (pflags), "r" (dst), "r" (src), "0" (value)
459 <        :       "cc", "o0", "o1"
458 >        :       "r" (flags), "r" (dst), "r" (src)
459 >        :       "cc", "o0"
460          );
461          return value;
462   }
# Line 439 | Line 590 | static inline void sparc_v8_flag_cmp_32(
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
# Line 753 | Line 983 | static inline uae_u32 sparc_v9_flag_addx
983  
984   #endif /* SPARC_V9_ASSEMBLY */
985  
986 + #endif
987 +
988   #else
989  
990   struct flag_struct {
# Line 771 | Line 1003 | extern struct flag_struct regflags;
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){
# Line 794 | Line 1047 | static __inline__ int cctrue(const int c
1047      return 0;
1048   }
1049  
1050 < #endif
1050 > #endif /* OPTIMIZED_FLAGS */
1051 >
1052 > #endif /* M68K_FLAGS_H */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines