ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/m68k.h
Revision: 1.2
Committed: 1999-10-21T15:27:11Z (25 years, 1 month ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: snapshot-21101999
Changes since 1.1: +646 -1 lines
Log Message:
- integrated SPARC assembly optimizations

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * UAE - The Un*x Amiga Emulator
3     *
4     * MC68000 emulation - machine dependent bits
5     *
6     * Copyright 1996 Bernd Schmidt
7     */
8    
9 cebix 1.2 #if defined(__i386__) && defined(X86_ASSEMBLY)
10 cebix 1.1
11     struct flag_struct {
12     unsigned int cznv;
13     unsigned int x;
14     };
15    
16     #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
17     #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
18     #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
19     #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
20     #define SET_XFLG(y) (regflags.x = (y))
21    
22     #define GET_ZFLG ((regflags.cznv >> 6) & 1)
23     #define GET_CFLG (regflags.cznv & 1)
24     #define GET_VFLG ((regflags.cznv >> 11) & 1)
25     #define GET_NFLG ((regflags.cznv >> 7) & 1)
26     #define GET_XFLG (regflags.x & 1)
27    
28     #define CLEAR_CZNV (regflags.cznv = 0)
29     #define COPY_CARRY (regflags.x = regflags.cznv)
30    
31     extern struct flag_struct regflags __asm__ ("regflags");
32    
33     static __inline__ int cctrue(int cc)
34     {
35     uae_u32 cznv = regflags.cznv;
36     switch(cc){
37     case 0: return 1; /* T */
38     case 1: return 0; /* F */
39     case 2: return (cznv & 0x41) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
40     case 3: return (cznv & 0x41) != 0; /* GET_CFLG || GET_ZFLG; LS */
41     case 4: return (cznv & 1) == 0; /* !GET_CFLG; CC */
42     case 5: return (cznv & 1) != 0; /* GET_CFLG; CS */
43     case 6: return (cznv & 0x40) == 0; /* !GET_ZFLG; NE */
44     case 7: return (cznv & 0x40) != 0; /* GET_ZFLG; EQ */
45     case 8: return (cznv & 0x800) == 0;/* !GET_VFLG; VC */
46     case 9: return (cznv & 0x800) != 0;/* GET_VFLG; VS */
47     case 10:return (cznv & 0x80) == 0; /* !GET_NFLG; PL */
48     case 11:return (cznv & 0x80) != 0; /* GET_NFLG; MI */
49     case 12:return (((cznv << 4) ^ cznv) & 0x800) == 0; /* GET_NFLG == GET_VFLG; GE */
50     case 13:return (((cznv << 4) ^ cznv) & 0x800) != 0;/* GET_NFLG != GET_VFLG; LT */
51     case 14:
52     cznv &= 0x8c0;
53     return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
54     case 15:
55     cznv &= 0x8c0;
56     return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
57     }
58     return 0;
59     }
60    
61     #define x86_flag_testl(v) \
62     __asm__ __volatile__ ("testl %1,%1\n\t" \
63     "pushfl\n\t" \
64     "popl %0\n\t" \
65     : "=r" (regflags.cznv) : "r" (v) : "cc")
66    
67     #define x86_flag_testw(v) \
68     __asm__ __volatile__ ("testw %w1,%w1\n\t" \
69     "pushfl\n\t" \
70     "popl %0\n\t" \
71     : "=r" (regflags.cznv) : "r" (v) : "cc")
72    
73     #define x86_flag_testb(v) \
74     __asm__ __volatile__ ("testb %b1,%b1\n\t" \
75     "pushfl\n\t" \
76     "popl %0\n\t" \
77     : "=r" (regflags.cznv) : "q" (v) : "cc")
78    
79     #define x86_flag_addl(v, s, d) do { \
80     __asm__ __volatile__ ("addl %k2,%k1\n\t" \
81     "pushfl\n\t" \
82     "popl %0\n\t" \
83     : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
84     COPY_CARRY; \
85     } while (0)
86    
87     #define x86_flag_addw(v, s, d) do { \
88     __asm__ __volatile__ ("addw %w2,%w1\n\t" \
89     "pushfl\n\t" \
90     "popl %0\n\t" \
91     : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
92     COPY_CARRY; \
93     } while (0)
94    
95     #define x86_flag_addb(v, s, d) do { \
96     __asm__ __volatile__ ("addb %b2,%b1\n\t" \
97     "pushfl\n\t" \
98     "popl %0\n\t" \
99     : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
100     COPY_CARRY; \
101     } while (0)
102    
103     #define x86_flag_subl(v, s, d) do { \
104     __asm__ __volatile__ ("subl %k2,%k1\n\t" \
105     "pushfl\n\t" \
106     "popl %0\n\t" \
107     : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
108     COPY_CARRY; \
109     } while (0)
110    
111     #define x86_flag_subw(v, s, d) do { \
112     __asm__ __volatile__ ("subw %w2,%w1\n\t" \
113     "pushfl\n\t" \
114     "popl %0\n\t" \
115     : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
116     COPY_CARRY; \
117     } while (0)
118    
119     #define x86_flag_subb(v, s, d) do { \
120     __asm__ __volatile__ ("subb %b2,%b1\n\t" \
121     "pushfl\n\t" \
122     "popl %0\n\t" \
123     : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
124     COPY_CARRY; \
125     } while (0)
126    
127     #define x86_flag_cmpl(s, d) \
128     __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
129     "pushfl\n\t" \
130     "popl %0\n\t" \
131     : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
132    
133     #define x86_flag_cmpw(s, d) \
134     __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
135     "pushfl\n\t" \
136     "popl %0\n\t" \
137     : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
138    
139     #define x86_flag_cmpb(s, d) \
140     __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
141     "pushfl\n\t" \
142     "popl %0\n\t" \
143     : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
144 cebix 1.2
145     #elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
146    
147     struct flag_struct {
148     unsigned char nzvc;
149     unsigned char x;
150     };
151    
152     extern struct flag_struct regflags;
153    
154     #define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2))
155     #define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1))
156     #define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1))
157     #define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3))
158     #define SET_XFLG(y) (regflags.x = (y))
159    
160     #define GET_ZFLG ((regflags.nzvc >> 2) & 1)
161     #define GET_CFLG (regflags.nzvc & 1)
162     #define GET_VFLG ((regflags.nzvc >> 1) & 1)
163     #define GET_NFLG ((regflags.nzvc >> 3) & 1)
164     #define GET_XFLG (regflags.x & 1)
165    
166     #define CLEAR_CZNV (regflags.nzvc = 0)
167     #define COPY_CARRY (regflags.x = regflags.nzvc)
168    
169     static __inline__ int cctrue(int cc)
170     {
171     uae_u32 nzvc = regflags.nzvc;
172     switch(cc){
173     case 0: return 1; /* T */
174     case 1: return 0; /* F */
175     case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
176     case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG; LS */
177     case 4: return (nzvc & 1) == 0; /* !GET_CFLG; CC */
178     case 5: return (nzvc & 1) != 0; /* GET_CFLG; CS */
179     case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG; NE */
180     case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG; EQ */
181     case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG; VC */
182     case 9: return (nzvc & 0x02) != 0;/* GET_VFLG; VS */
183     case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG; PL */
184     case 11:return (nzvc & 0x08) != 0; /* GET_NFLG; MI */
185     case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG; GE */
186     case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG; LT */
187     case 14:
188     nzvc &= 0x0e;
189     return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
190     case 15:
191     nzvc &= 0x0e;
192     return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
193     }
194     return 0;
195     }
196    
197     #ifdef SPARC_V8_ASSEMBLY
198    
199     static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
200     {
201     uae_u32 value;
202     __asm__ ("\n"
203     " sll %2, 24, %%o0\n"
204     " sll %3, 24, %%o1\n"
205     " addcc %%o0, %%o1, %%o0\n"
206     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
207     " srl %%o0, 24, %0\n"
208     " stb %%o1, [%1 + 1]\n"
209     " bl,a .+8\n"
210     " or %%o1, 0x08, %%o1 ! N flag\n"
211     " bz,a .+8\n"
212     " or %%o1, 0x04, %%o1 ! Z flag\n"
213     " bvs,a .+8\n"
214     " or %%o1, 0x02, %%o1 ! V flag\n"
215     " stb %%o1, [%1]\n"
216     : "=&r" (value)
217     : "r" (flags), "r" (dst), "r" (src)
218     : "cc", "o0", "o1"
219     );
220     return value;
221     }
222    
223     static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
224     {
225     uae_u32 value;
226     __asm__ ("\n"
227     " sll %2, 16, %%o0\n"
228     " sll %3, 16, %%o1\n"
229     " addcc %%o0, %%o1, %%o0\n"
230     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
231     " srl %%o0, 16, %0\n"
232     " stb %%o1, [%1 + 1]\n"
233     " bl,a .+8\n"
234     " or %%o1, 0x08, %%o1 ! N flag\n"
235     " bz,a .+8\n"
236     " or %%o1, 0x04, %%o1 ! Z flag\n"
237     " bvs,a .+8\n"
238     " or %%o1, 0x02, %%o1 ! V flag\n"
239     " stb %%o1, [%1]\n"
240     : "=&r" (value)
241     : "r" (flags), "r" (dst), "r" (src)
242     : "cc", "o0", "o1"
243     );
244     return value;
245     }
246    
247     static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
248     {
249     uae_u32 value;
250     __asm__ ("\n"
251     " addcc %2, %3, %0\n"
252     " addx %%g0, %%g0, %%o0 ! X,C flags\n"
253     " stb %%o0, [%1 + 1]\n"
254     " bl,a .+8\n"
255     " or %%o0, 0x08, %%o0 ! N flag\n"
256     " bz,a .+8\n"
257     " or %%o0, 0x04, %%o0 ! Z flag\n"
258     " bvs,a .+8\n"
259     " or %%o0, 0x02, %%o0 ! V flag\n"
260     " stb %%o0, [%1]\n"
261     : "=&r" (value)
262     : "r" (flags), "r" (dst), "r" (src)
263     : "cc", "o0"
264     );
265     return value;
266     }
267    
268     static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
269     {
270     uae_u32 value;
271     __asm__ ("\n"
272     " sll %2, 24, %%o0\n"
273     " sll %3, 24, %%o1\n"
274     " subcc %%o0, %%o1, %%o0\n"
275     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
276     " srl %%o0, 24, %0\n"
277     " stb %%o1, [%1 + 1]\n"
278     " bl,a .+8\n"
279     " or %%o1, 0x08, %%o1 ! N flag\n"
280     " bz,a .+8\n"
281     " or %%o1, 0x04, %%o1 ! Z flag\n"
282     " bvs,a .+8\n"
283     " or %%o1, 0x02, %%o1 ! V flag\n"
284     " stb %%o1, [%1]\n"
285     : "=&r" (value)
286     : "r" (flags), "r" (dst), "r" (src)
287     : "cc", "o0", "o1"
288     );
289     return value;
290     }
291    
292     static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
293     {
294     uae_u32 value;
295     __asm__ ("\n"
296     " sll %2, 16, %%o0\n"
297     " sll %3, 16, %%o1\n"
298     " subcc %%o0, %%o1, %%o0\n"
299     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
300     " srl %%o0, 16, %0\n"
301     " stb %%o1, [%1 + 1]\n"
302     " bl,a .+8\n"
303     " or %%o1, 0x08, %%o1 ! N flag\n"
304     " bz,a .+8\n"
305     " or %%o1, 0x04, %%o1 ! Z flag\n"
306     " bvs,a .+8\n"
307     " or %%o1, 0x02, %%o1 ! V flag\n"
308     " stb %%o1, [%1]\n"
309     : "=&r" (value)
310     : "r" (flags), "r" (dst), "r" (src)
311     : "cc", "o0", "o1"
312     );
313     return value;
314     }
315    
316     static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
317     {
318     uae_u32 value;
319     __asm__ ("\n"
320     " subcc %2, %3, %0\n"
321     " addx %%g0, %%g0, %%o0 ! X,C flags\n"
322     " stb %%o0, [%1 + 1]\n"
323     " bl,a .+8\n"
324     " or %%o0, 0x08, %%o0 ! N flag\n"
325     " bz,a .+8\n"
326     " or %%o0, 0x04, %%o0 ! Z flag\n"
327     " bvs,a .+8\n"
328     " or %%o0, 0x02, %%o0 ! V flag\n"
329     " stb %%o0, [%1]\n"
330     : "=&r" (value)
331     : "r" (flags), "r" (dst), "r" (src)
332     : "cc", "o0"
333     );
334     return value;
335     }
336    
337     static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
338     {
339     __asm__ ("\n"
340     " sll %1, 24, %%o0\n"
341     " sll %2, 24, %%o1\n"
342     " subcc %%o0, %%o1, %%g0\n"
343     " addx %%g0, %%g0, %%o0 ! C flag\n"
344     " bl,a .+8\n"
345     " or %%o0, 0x08, %%o0 ! N flag\n"
346     " bz,a .+8\n"
347     " or %%o0, 0x04, %%o0 ! Z flag\n"
348     " bvs,a .+8\n"
349     " or %%o0, 0x02, %%o0 ! V flag\n"
350     " stb %%o0, [%0]\n"
351     : /* no outputs */
352     : "r" (flags), "r" (dst), "r" (src)
353     : "cc", "o0", "o1"
354     );
355     }
356    
357     static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
358     {
359     __asm__ ("\n"
360     " sll %1, 16, %%o0\n"
361     " sll %2, 16, %%o1\n"
362     " subcc %%o0, %%o1, %%g0\n"
363     " addx %%g0, %%g0, %%o0 ! C flag\n"
364     " bl,a .+8\n"
365     " or %%o0, 0x08, %%o0 ! N flag\n"
366     " bz,a .+8\n"
367     " or %%o0, 0x04, %%o0 ! Z flag\n"
368     " bvs,a .+8\n"
369     " or %%o0, 0x02, %%o0 ! V flag\n"
370     " stb %%o0, [%0]\n"
371     : /* no outputs */
372     : "r" (flags), "r" (dst), "r" (src)
373     : "cc", "o0", "o1"
374     );
375     }
376    
377     static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
378     {
379     __asm__ ("\n"
380     " subcc %1, %2, %%o1\n"
381     " srl %%o1, 31, %%o0\n"
382     " sll %%o0, 3, %%o0\n"
383     " addx %%o0, %%g0, %%o0\n"
384     " bvs,a .+8\n"
385     " or %%o0, 0x02, %%o0\n"
386     " subcc %%g0, %%o1, %%g0\n"
387     " addx %%g0, 7, %%o1\n"
388     " and %%o1, 0x04, %%o1\n"
389     " or %%o0, %%o1, %%o0\n"
390     " stb %%o0, [%0]\n"
391     : /* no outputs */
392     : "r" (flags), "r" (dst), "r" (src)
393     : "cc", "o0", "o1"
394     );
395     }
396    
397     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
398     {
399     uae_u32 value;
400     __asm__ ("\n"
401     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
402     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
403     " addxcc %2, %3, %0\n"
404     : "=&r" (value)
405     : "r" (flags), "r" (dst), "r" (src)
406     : "cc", "o0", "o1"
407     );
408     return value;
409     }
410    
411     #if 0
412     VERY SLOW...
413     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
414     {
415     uae_u32 value;
416     __asm__ ("\n"
417     " sll %2, 24, %%o0\n"
418     " sll %3, 24, %%o1\n"
419     " addcc %%o0, %%o1, %%o0\n"
420     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
421     " bvs,a .+8\n"
422     " or %%o1, 0x02, %%o1 ! V flag\n"
423     " ldub [%1 + 1], %%o2\n"
424     " subcc %%g0, %%o2, %%g0\n"
425     " addx %%g0, %%g0, %%o2\n"
426     " sll %%o2, 24, %%o2\n"
427     " addcc %%o0, %%o2, %%o0\n"
428     " srl %%o0, 24, %0\n"
429     " addx %%g0, %%g0, %%o2\n"
430     " or %%o1, %%o2, %%o1 ! update X,C flags\n"
431     " bl,a .+8\n"
432     " or %%o1, 0x08, %%o1 ! N flag\n"
433     " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n"
434     " bvs,a .+8\n"
435     " or %%o1, 0x02, %%o1 ! update V flag\n"
436     " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n"
437     " and %%o1, 1, %%o2 ! keep C flag in %%o2\n"
438     " bnz,a .+8\n"
439     " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n"
440     " stb %%o2, [%1 + 1] ! store the X flag\n"
441     " or %%o1, %%o0, %%o1\n"
442     " stb %%o1, [%1]\n"
443     : "=&r" (value)
444     : "r" (flags), "r" (dst), "r" (src)
445     : "cc", "o0", "o1", "o2"
446     );
447     return value;
448     }
449     #endif
450    
451     static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
452     {
453     uae_u32 value;
454     __asm__ ("\n"
455     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
456     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
457     " addxcc %2, %3, %0\n"
458     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
459     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
460     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
461     " bl,a .+8\n"
462     " or %%o0, 0x08, %%o0 ! N flag\n"
463     " bvs,a .+8\n"
464     " or %%o0, 0x02, %%o0 ! V flag\n"
465     " bnz,a .+8\n"
466     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
467     " stb %%o0, [%1]\n"
468     " stb %%o0, [%1 + 1]\n"
469     : "=&r" (value)
470     : "r" (flags), "r" (dst), "r" (src)
471     : "cc", "o0"
472     );
473     return value;
474     }
475    
476     #endif /* SPARC_V8_ASSEMBLY */
477    
478     #ifdef SPARC_V9_ASSEMBLY
479    
480     static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
481     {
482     uae_u32 value;
483     __asm__ ("\n"
484     " sll %2, 24, %%o0\n"
485     " sll %3, 24, %%o1\n"
486     " addcc %%o0, %%o1, %%o0\n"
487     " rd %%ccr, %%o1\n"
488     " srl %%o0, 24, %0\n"
489     " stb %%o1, [%1]\n"
490     " stb %%o1, [%1+1]\n"
491     : "=&r" (value)
492     : "r" (flags), "r" (dst), "r" (src)
493     : "cc", "o0", "o1"
494     );
495     return value;
496     }
497    
498     static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
499     {
500     uae_u32 value;
501     __asm__ ("\n"
502     " sll %2, 16, %%o0\n"
503     " sll %3, 16, %%o1\n"
504     " addcc %%o0, %%o1, %%o0\n"
505     " rd %%ccr, %%o1\n"
506     " srl %%o0, 16, %0\n"
507     " stb %%o1, [%1]\n"
508     " stb %%o1, [%1+1]\n"
509     : "=&r" (value)
510     : "r" (flags), "r" (dst), "r" (src)
511     : "cc", "o0", "o1"
512     );
513     return value;
514     }
515    
516     static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
517     {
518     uae_u32 value;
519     __asm__ ("\n"
520     " addcc %2, %3, %0\n"
521     " rd %%ccr, %%o0\n"
522     " stb %%o0, [%1]\n"
523     " stb %%o0, [%1+1]\n"
524     : "=&r" (value)
525     : "r" (flags), "r" (dst), "r" (src)
526     : "cc", "o0"
527     );
528     return value;
529     }
530    
531     static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
532     {
533     uae_u32 value;
534     __asm__ ("\n"
535     " sll %2, 24, %%o0\n"
536     " sll %3, 24, %%o1\n"
537     " subcc %%o0, %%o1, %%o0\n"
538     " rd %%ccr, %%o1\n"
539     " srl %%o0, 24, %0\n"
540     " stb %%o1, [%1]\n"
541     " stb %%o1, [%1+1]\n"
542     : "=&r" (value)
543     : "r" (flags), "r" (dst), "r" (src)
544     : "cc", "o0", "o1"
545     );
546     return value;
547     }
548    
549     static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
550     {
551     uae_u32 value;
552     __asm__ ("\n"
553     " sll %2, 16, %%o0\n"
554     " sll %3, 16, %%o1\n"
555     " subcc %%o0, %%o1, %%o0\n"
556     " rd %%ccr, %%o1\n"
557     " srl %%o0, 16, %0\n"
558     " stb %%o1, [%1]\n"
559     " stb %%o1, [%1+1]\n"
560     : "=&r" (value)
561     : "r" (flags), "r" (dst), "r" (src)
562     : "cc", "o0", "o1"
563     );
564     return value;
565     }
566    
567     static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
568     {
569     uae_u32 value;
570     __asm__ ("\n"
571     " subcc %2, %3, %0\n"
572     " rd %%ccr, %%o0\n"
573     " stb %%o0, [%1]\n"
574     " stb %%o0, [%1+1]\n"
575     : "=&r" (value)
576     : "r" (flags), "r" (dst), "r" (src)
577     : "cc", "o0"
578     );
579     return value;
580     }
581    
582     static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
583     {
584     __asm__ ("\n"
585     " sll %1, 24, %%o0\n"
586     " sll %2, 24, %%o1\n"
587     " subcc %%o0, %%o1, %%g0\n"
588     " rd %%ccr, %%o0\n"
589     " stb %%o0, [%0]\n"
590     : /* no outputs */
591     : "r" (flags), "r" (dst), "r" (src)
592     : "cc", "o0", "o1"
593     );
594     }
595    
596     static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
597     {
598     __asm__ ("\n"
599     " sll %1, 16, %%o0\n"
600     " sll %2, 16, %%o1\n"
601     " subcc %%o0, %%o1, %%g0\n"
602     " rd %%ccr, %%o0\n"
603     " stb %%o0, [%0]\n"
604     : /* no outputs */
605     : "r" (flags), "r" (dst), "r" (src)
606     : "cc", "o0", "o1"
607     );
608     }
609    
610     static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
611     {
612     __asm__ ("\n"
613     " subcc %1, %2, %%g0\n"
614     #if 0
615     " subcc %1, %2, %%o1\n"
616     " srl %%o1, 31, %%o0\n"
617     " sll %%o0, 3, %%o0\n"
618     " addx %%o0, %%g0, %%o0\n"
619     " bvs,a .+8\n"
620     " or %%o0, 0x02, %%o0\n"
621     " subcc %%g0, %%o1, %%g0\n"
622     " addx %%g0, 7, %%o1\n"
623     " and %%o1, 0x04, %%o1\n"
624     " or %%o0, %%o1, %%o0\n"
625     #endif
626     #if 0
627     " subcc %1, %2, %%o1\n"
628     " srl %%o1, 31, %%o0\n"
629     " sll %%o0, 3, %%o0\n"
630     " addx %%o0, %%g0, %%o0\n"
631     " bvs,pt,a .+8\n"
632     " or %%o0, 0x02, %%o0\n"
633     " subcc %%g0, %%o1, %%g0\n"
634     " addx %%g0, 7, %%o1\n"
635     " and %%o1, 0x04, %%o1\n"
636     " or %%o0, %%o1, %%o0\n"
637     " stb %%o0, [%0]\n"
638     #endif
639     " rd %%ccr, %%o0\n"
640     " stb %%o0, [%0]\n"
641     : /* no outputs */
642     : "r" (flags), "r" (dst), "r" (src)
643     : "cc", "o0", "o1"
644     );
645     }
646    
647     #if 1
648     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
649     {
650     __asm__ ("\n"
651     " sll %1, 24, %%o0\n"
652     " subcc %%o0, %%g0, %%g0\n"
653     " rd %%ccr, %%o0\n"
654     " stb %%o0, [%0]\n"
655     : /* no outputs */
656     : "r" (flags), "r" (val)
657     : "cc", "o0"
658     );
659     }
660    
661     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
662     {
663     __asm__ ("\n"
664     " sll %1, 16, %%o0\n"
665     " subcc %%o0, %%g0, %%g0\n"
666     " rd %%ccr, %%o0\n"
667     " stb %%o0, [%0]\n"
668     : /* no outputs */
669     : "r" (flags), "r" (val)
670     : "cc", "o0"
671     );
672     }
673    
674     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
675     {
676     __asm__ ("\n"
677     " subcc %1, %%g0, %%g0\n"
678     " rd %%ccr, %%o0\n"
679     " stb %%o0, [%0]\n"
680     : /* no outputs */
681     : "r" (flags), "r" (val)
682     : "cc", "o0"
683     );
684     }
685     #else
686     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
687     {
688     __asm__ ("\n"
689     " sll %1, 24, %%o0\n"
690     " subcc %%o0, %%g0, %%o1\n"
691     " srl %%o1, 31, %%o0\n"
692     " sll %%o0, 3, %%o0\n"
693     " addx %%o0, %%g0, %%o0\n"
694     " bvs,a .+8\n"
695     " or %%o0, 0x02, %%o0\n"
696     " subcc %%g0, %%o1, %%g0\n"
697     " addx %%g0, 7, %%o1\n"
698     " and %%o1, 0x04, %%o1\n"
699     " or %%o0, %%o1, %%o0\n"
700     " stb %%o0, [%0]\n"
701     : /* no outputs */
702     : "r" (flags), "r" (val)
703     : "cc", "o0", "o1"
704     );
705     }
706    
707     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
708     {
709     __asm__ ("\n"
710     " sll %1, 16, %%o0\n"
711     " subcc %%o0, %%g0, %%o1\n"
712     " srl %%o1, 31, %%o0\n"
713     " sll %%o0, 3, %%o0\n"
714     " addx %%o0, %%g0, %%o0\n"
715     " bvs,a .+8\n"
716     " or %%o0, 0x02, %%o0\n"
717     " subcc %%g0, %%o1, %%g0\n"
718     " addx %%g0, 7, %%o1\n"
719     " and %%o1, 0x04, %%o1\n"
720     " or %%o0, %%o1, %%o0\n"
721     " stb %%o0, [%0]\n"
722     : /* no outputs */
723     : "r" (flags), "r" (val)
724     : "cc", "o0", "o1"
725     );
726     }
727    
728     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
729     {
730     __asm__ ("\n"
731     " subcc %1, %%g0, %%o1\n"
732     " srl %%o1, 31, %%o0\n"
733     " sll %%o0, 3, %%o0\n"
734     " addx %%o0, %%g0, %%o0\n"
735     " bvs,a .+8\n"
736     " or %%o0, 0x02, %%o0\n"
737     " subcc %%g0, %%o1, %%g0\n"
738     " addx %%g0, 7, %%o1\n"
739     " and %%o1, 0x04, %%o1\n"
740     " or %%o0, %%o1, %%o0\n"
741     " stb %%o0, [%0]\n"
742     : /* no outputs */
743     : "r" (flags), "r" (val)
744     : "cc", "o0", "o1"
745     );
746     }
747     #endif
748    
749     static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
750     {
751     uae_u32 value;
752     __asm__ ("\n"
753     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
754     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
755     " addxcc %2, %3, %0\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_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
764     {
765     uae_u32 value;
766     __asm__ ("\n"
767     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
768     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
769     " addxcc %2, %3, %0\n"
770     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
771     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
772     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
773     " bl,a .+8\n"
774     " or %%o0, 0x08, %%o0 ! N flag\n"
775     " bvs,a .+8\n"
776     " or %%o0, 0x02, %%o0 ! V flag\n"
777     " bnz,a .+8\n"
778     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
779     " stb %%o0, [%1]\n"
780     " stb %%o0, [%1 + 1]\n"
781     : "=&r" (value)
782     : "r" (flags), "r" (dst), "r" (src)
783     : "cc", "o0"
784     );
785     return value;
786     }
787    
788     #endif /* SPARC_V9_ASSEMBLY */
789 cebix 1.1
790     #else
791    
792     struct flag_struct {
793     unsigned int c;
794     unsigned int z;
795     unsigned int n;
796     unsigned int v;
797     unsigned int x;
798     };
799    
800     extern struct flag_struct regflags;
801    
802     #define ZFLG (regflags.z)
803     #define NFLG (regflags.n)
804     #define CFLG (regflags.c)
805     #define VFLG (regflags.v)
806     #define XFLG (regflags.x)
807    
808     static __inline__ int cctrue(const int cc)
809     {
810     switch(cc){
811     case 0: return 1; /* T */
812     case 1: return 0; /* F */
813     case 2: return !CFLG && !ZFLG; /* HI */
814     case 3: return CFLG || ZFLG; /* LS */
815     case 4: return !CFLG; /* CC */
816     case 5: return CFLG; /* CS */
817     case 6: return !ZFLG; /* NE */
818     case 7: return ZFLG; /* EQ */
819     case 8: return !VFLG; /* VC */
820     case 9: return VFLG; /* VS */
821     case 10:return !NFLG; /* PL */
822     case 11:return NFLG; /* MI */
823     case 12:return NFLG == VFLG; /* GE */
824     case 13:return NFLG != VFLG; /* LT */
825     case 14:return !ZFLG && (NFLG == VFLG); /* GT */
826     case 15:return ZFLG || (NFLG != VFLG); /* LE */
827     }
828     return 0;
829     }
830    
831     #endif