ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Solaris/sparcasm.h
Revision: 1.1
Committed: 1999-10-21T13:19:26Z (25 years ago) by cebix
Content type: text/plain
Branch: MAIN
Log Message:
- added fbdev video code and SPARC assembly optimizations

File Contents

# User Rev Content
1 cebix 1.1 #ifndef SPARC_ASSEMBLY__HEADER
2     #define SPARC_ASSEMBLY__HEADER
3    
4     #ifdef SPARC_V8_ASSEMBLY
5    
6     static inline char *str_flags(void)
7     {
8     static char str[8];
9     sprintf(str, "%c%c%c%c%c",
10     GET_XFLG ? 'X' : '-',
11     GET_NFLG ? 'N' : '-',
12     GET_ZFLG ? 'Z' : '-',
13     GET_VFLG ? 'V' : '-',
14     GET_CFLG ? 'C' : '-'
15     );
16     return str;
17     }
18    
19     static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
20     {
21     uae_u32 value;
22     __asm__ ("\n"
23     " sll %2, 24, %%o0\n"
24     " sll %3, 24, %%o1\n"
25     " addcc %%o0, %%o1, %%o0\n"
26     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
27     " srl %%o0, 24, %0\n"
28     " stb %%o1, [%1 + 1]\n"
29     " bl,a .+8\n"
30     " or %%o1, 0x08, %%o1 ! N flag\n"
31     " bz,a .+8\n"
32     " or %%o1, 0x04, %%o1 ! Z flag\n"
33     " bvs,a .+8\n"
34     " or %%o1, 0x02, %%o1 ! V flag\n"
35     " stb %%o1, [%1]\n"
36     : "=&r" (value)
37     : "r" (flags), "r" (dst), "r" (src)
38     : "cc", "o0", "o1"
39     );
40     return value;
41     }
42    
43     static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
44     {
45     uae_u32 value;
46     __asm__ ("\n"
47     " sll %2, 16, %%o0\n"
48     " sll %3, 16, %%o1\n"
49     " addcc %%o0, %%o1, %%o0\n"
50     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
51     " srl %%o0, 16, %0\n"
52     " stb %%o1, [%1 + 1]\n"
53     " bl,a .+8\n"
54     " or %%o1, 0x08, %%o1 ! N flag\n"
55     " bz,a .+8\n"
56     " or %%o1, 0x04, %%o1 ! Z flag\n"
57     " bvs,a .+8\n"
58     " or %%o1, 0x02, %%o1 ! V flag\n"
59     " stb %%o1, [%1]\n"
60     : "=&r" (value)
61     : "r" (flags), "r" (dst), "r" (src)
62     : "cc", "o0", "o1"
63     );
64     return value;
65     }
66    
67     static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
68     {
69     uae_u32 value;
70     __asm__ ("\n"
71     " addcc %2, %3, %0\n"
72     " addx %%g0, %%g0, %%o0 ! X,C flags\n"
73     " stb %%o0, [%1 + 1]\n"
74     " bl,a .+8\n"
75     " or %%o0, 0x08, %%o0 ! N flag\n"
76     " bz,a .+8\n"
77     " or %%o0, 0x04, %%o0 ! Z flag\n"
78     " bvs,a .+8\n"
79     " or %%o0, 0x02, %%o0 ! V flag\n"
80     " stb %%o0, [%1]\n"
81     : "=&r" (value)
82     : "r" (flags), "r" (dst), "r" (src)
83     : "cc", "o0"
84     );
85     return value;
86     }
87    
88     static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
89     {
90     uae_u32 value;
91     __asm__ ("\n"
92     " sll %2, 24, %%o0\n"
93     " sll %3, 24, %%o1\n"
94     " subcc %%o0, %%o1, %%o0\n"
95     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
96     " srl %%o0, 24, %0\n"
97     " stb %%o1, [%1 + 1]\n"
98     " bl,a .+8\n"
99     " or %%o1, 0x08, %%o1 ! N flag\n"
100     " bz,a .+8\n"
101     " or %%o1, 0x04, %%o1 ! Z flag\n"
102     " bvs,a .+8\n"
103     " or %%o1, 0x02, %%o1 ! V flag\n"
104     " stb %%o1, [%1]\n"
105     : "=&r" (value)
106     : "r" (flags), "r" (dst), "r" (src)
107     : "cc", "o0", "o1"
108     );
109     return value;
110     }
111    
112     static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
113     {
114     uae_u32 value;
115     __asm__ ("\n"
116     " sll %2, 16, %%o0\n"
117     " sll %3, 16, %%o1\n"
118     " subcc %%o0, %%o1, %%o0\n"
119     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
120     " srl %%o0, 16, %0\n"
121     " stb %%o1, [%1 + 1]\n"
122     " bl,a .+8\n"
123     " or %%o1, 0x08, %%o1 ! N flag\n"
124     " bz,a .+8\n"
125     " or %%o1, 0x04, %%o1 ! Z flag\n"
126     " bvs,a .+8\n"
127     " or %%o1, 0x02, %%o1 ! V flag\n"
128     " stb %%o1, [%1]\n"
129     : "=&r" (value)
130     : "r" (flags), "r" (dst), "r" (src)
131     : "cc", "o0", "o1"
132     );
133     return value;
134     }
135    
136     static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
137     {
138     uae_u32 value;
139     __asm__ ("\n"
140     " subcc %2, %3, %0\n"
141     " addx %%g0, %%g0, %%o0 ! X,C flags\n"
142     " stb %%o0, [%1 + 1]\n"
143     " bl,a .+8\n"
144     " or %%o0, 0x08, %%o0 ! N flag\n"
145     " bz,a .+8\n"
146     " or %%o0, 0x04, %%o0 ! Z flag\n"
147     " bvs,a .+8\n"
148     " or %%o0, 0x02, %%o0 ! V flag\n"
149     " stb %%o0, [%1]\n"
150     : "=&r" (value)
151     : "r" (flags), "r" (dst), "r" (src)
152     : "cc", "o0"
153     );
154     return value;
155     }
156    
157     static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
158     {
159     __asm__ ("\n"
160     " sll %1, 24, %%o0\n"
161     " sll %2, 24, %%o1\n"
162     " subcc %%o0, %%o1, %%g0\n"
163     " addx %%g0, %%g0, %%o0 ! C flag\n"
164     " bl,a .+8\n"
165     " or %%o0, 0x08, %%o0 ! N flag\n"
166     " bz,a .+8\n"
167     " or %%o0, 0x04, %%o0 ! Z flag\n"
168     " bvs,a .+8\n"
169     " or %%o0, 0x02, %%o0 ! V flag\n"
170     " stb %%o0, [%0]\n"
171     : /* no outputs */
172     : "r" (flags), "r" (dst), "r" (src)
173     : "cc", "o0", "o1"
174     );
175     }
176    
177     static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
178     {
179     __asm__ ("\n"
180     " sll %1, 16, %%o0\n"
181     " sll %2, 16, %%o1\n"
182     " subcc %%o0, %%o1, %%g0\n"
183     " addx %%g0, %%g0, %%o0 ! C flag\n"
184     " bl,a .+8\n"
185     " or %%o0, 0x08, %%o0 ! N flag\n"
186     " bz,a .+8\n"
187     " or %%o0, 0x04, %%o0 ! Z flag\n"
188     " bvs,a .+8\n"
189     " or %%o0, 0x02, %%o0 ! V flag\n"
190     " stb %%o0, [%0]\n"
191     : /* no outputs */
192     : "r" (flags), "r" (dst), "r" (src)
193     : "cc", "o0", "o1"
194     );
195     }
196    
197     static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
198     {
199     __asm__ ("\n"
200     " subcc %1, %2, %%o1\n"
201     " srl %%o1, 31, %%o0\n"
202     " sll %%o0, 3, %%o0\n"
203     " addx %%o0, %%g0, %%o0\n"
204     " bvs,a .+8\n"
205     " or %%o0, 0x02, %%o0\n"
206     " subcc %%g0, %%o1, %%g0\n"
207     " addx %%g0, 7, %%o1\n"
208     " and %%o1, 0x04, %%o1\n"
209     " or %%o0, %%o1, %%o0\n"
210     " stb %%o0, [%0]\n"
211     : /* no outputs */
212     : "r" (flags), "r" (dst), "r" (src)
213     : "cc", "o0", "o1"
214     );
215     }
216    
217     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
218     {
219     uae_u32 value;
220     __asm__ ("\n"
221     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
222     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
223     " addxcc %2, %3, %0\n"
224     : "=&r" (value)
225     : "r" (flags), "r" (dst), "r" (src)
226     : "cc", "o0", "o1"
227     );
228     return value;
229     }
230    
231     #if 0
232     VERY SLOW...
233     static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
234     {
235     uae_u32 value;
236     __asm__ ("\n"
237     " sll %2, 24, %%o0\n"
238     " sll %3, 24, %%o1\n"
239     " addcc %%o0, %%o1, %%o0\n"
240     " addx %%g0, %%g0, %%o1 ! X,C flags\n"
241     " bvs,a .+8\n"
242     " or %%o1, 0x02, %%o1 ! V flag\n"
243     " ldub [%1 + 1], %%o2\n"
244     " subcc %%g0, %%o2, %%g0\n"
245     " addx %%g0, %%g0, %%o2\n"
246     " sll %%o2, 24, %%o2\n"
247     " addcc %%o0, %%o2, %%o0\n"
248     " srl %%o0, 24, %0\n"
249     " addx %%g0, %%g0, %%o2\n"
250     " or %%o1, %%o2, %%o1 ! update X,C flags\n"
251     " bl,a .+8\n"
252     " or %%o1, 0x08, %%o1 ! N flag\n"
253     " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n"
254     " bvs,a .+8\n"
255     " or %%o1, 0x02, %%o1 ! update V flag\n"
256     " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n"
257     " and %%o1, 1, %%o2 ! keep C flag in %%o2\n"
258     " bnz,a .+8\n"
259     " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n"
260     " stb %%o2, [%1 + 1] ! store the X flag\n"
261     " or %%o1, %%o0, %%o1\n"
262     " stb %%o1, [%1]\n"
263     : "=&r" (value)
264     : "r" (flags), "r" (dst), "r" (src)
265     : "cc", "o0", "o1", "o2"
266     );
267     return value;
268     }
269     #endif
270    
271     static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
272     {
273     uae_u32 value;
274     __asm__ ("\n"
275     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
276     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
277     " addxcc %2, %3, %0\n"
278     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
279     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
280     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
281     " bl,a .+8\n"
282     " or %%o0, 0x08, %%o0 ! N flag\n"
283     " bvs,a .+8\n"
284     " or %%o0, 0x02, %%o0 ! V flag\n"
285     " bnz,a .+8\n"
286     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
287     " stb %%o0, [%1]\n"
288     " stb %%o0, [%1 + 1]\n"
289     : "=&r" (value)
290     : "r" (flags), "r" (dst), "r" (src)
291     : "cc", "o0"
292     );
293     return value;
294     }
295    
296     #endif /* SPARC_V8_ASSEMBLY */
297    
298     #ifdef SPARC_V9_ASSEMBLY
299    
300     static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
301     {
302     uae_u32 value;
303     __asm__ ("\n"
304     " sll %2, 24, %%o0\n"
305     " sll %3, 24, %%o1\n"
306     " addcc %%o0, %%o1, %%o0\n"
307     " rd %%ccr, %%o1\n"
308     " srl %%o0, 24, %0\n"
309     " stb %%o1, [%1]\n"
310     " stb %%o1, [%1+1]\n"
311     : "=&r" (value)
312     : "r" (flags), "r" (dst), "r" (src)
313     : "cc", "o0", "o1"
314     );
315     return value;
316     }
317    
318     static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
319     {
320     uae_u32 value;
321     __asm__ ("\n"
322     " sll %2, 16, %%o0\n"
323     " sll %3, 16, %%o1\n"
324     " addcc %%o0, %%o1, %%o0\n"
325     " rd %%ccr, %%o1\n"
326     " srl %%o0, 16, %0\n"
327     " stb %%o1, [%1]\n"
328     " stb %%o1, [%1+1]\n"
329     : "=&r" (value)
330     : "r" (flags), "r" (dst), "r" (src)
331     : "cc", "o0", "o1"
332     );
333     return value;
334     }
335    
336     static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
337     {
338     uae_u32 value;
339     __asm__ ("\n"
340     " addcc %2, %3, %0\n"
341     " rd %%ccr, %%o0\n"
342     " stb %%o0, [%1]\n"
343     " stb %%o0, [%1+1]\n"
344     : "=&r" (value)
345     : "r" (flags), "r" (dst), "r" (src)
346     : "cc", "o0"
347     );
348     return value;
349     }
350    
351     static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
352     {
353     uae_u32 value;
354     __asm__ ("\n"
355     " sll %2, 24, %%o0\n"
356     " sll %3, 24, %%o1\n"
357     " subcc %%o0, %%o1, %%o0\n"
358     " rd %%ccr, %%o1\n"
359     " srl %%o0, 24, %0\n"
360     " stb %%o1, [%1]\n"
361     " stb %%o1, [%1+1]\n"
362     : "=&r" (value)
363     : "r" (flags), "r" (dst), "r" (src)
364     : "cc", "o0", "o1"
365     );
366     return value;
367     }
368    
369     static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
370     {
371     uae_u32 value;
372     __asm__ ("\n"
373     " sll %2, 16, %%o0\n"
374     " sll %3, 16, %%o1\n"
375     " subcc %%o0, %%o1, %%o0\n"
376     " rd %%ccr, %%o1\n"
377     " srl %%o0, 16, %0\n"
378     " stb %%o1, [%1]\n"
379     " stb %%o1, [%1+1]\n"
380     : "=&r" (value)
381     : "r" (flags), "r" (dst), "r" (src)
382     : "cc", "o0", "o1"
383     );
384     return value;
385     }
386    
387     static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
388     {
389     uae_u32 value;
390     __asm__ ("\n"
391     " subcc %2, %3, %0\n"
392     " rd %%ccr, %%o0\n"
393     " stb %%o0, [%1]\n"
394     " stb %%o0, [%1+1]\n"
395     : "=&r" (value)
396     : "r" (flags), "r" (dst), "r" (src)
397     : "cc", "o0"
398     );
399     return value;
400     }
401    
402     static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
403     {
404     __asm__ ("\n"
405     " sll %1, 24, %%o0\n"
406     " sll %2, 24, %%o1\n"
407     " subcc %%o0, %%o1, %%g0\n"
408     " rd %%ccr, %%o0\n"
409     " stb %%o0, [%0]\n"
410     : /* no outputs */
411     : "r" (flags), "r" (dst), "r" (src)
412     : "cc", "o0", "o1"
413     );
414     }
415    
416     static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
417     {
418     __asm__ ("\n"
419     " sll %1, 16, %%o0\n"
420     " sll %2, 16, %%o1\n"
421     " subcc %%o0, %%o1, %%g0\n"
422     " rd %%ccr, %%o0\n"
423     " stb %%o0, [%0]\n"
424     : /* no outputs */
425     : "r" (flags), "r" (dst), "r" (src)
426     : "cc", "o0", "o1"
427     );
428     }
429    
430     static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
431     {
432     __asm__ ("\n"
433     " subcc %1, %2, %%g0\n"
434     #if 0
435     " subcc %1, %2, %%o1\n"
436     " srl %%o1, 31, %%o0\n"
437     " sll %%o0, 3, %%o0\n"
438     " addx %%o0, %%g0, %%o0\n"
439     " bvs,a .+8\n"
440     " or %%o0, 0x02, %%o0\n"
441     " subcc %%g0, %%o1, %%g0\n"
442     " addx %%g0, 7, %%o1\n"
443     " and %%o1, 0x04, %%o1\n"
444     " or %%o0, %%o1, %%o0\n"
445     #endif
446     #if 0
447     " subcc %1, %2, %%o1\n"
448     " srl %%o1, 31, %%o0\n"
449     " sll %%o0, 3, %%o0\n"
450     " addx %%o0, %%g0, %%o0\n"
451     " bvs,pt,a .+8\n"
452     " or %%o0, 0x02, %%o0\n"
453     " subcc %%g0, %%o1, %%g0\n"
454     " addx %%g0, 7, %%o1\n"
455     " and %%o1, 0x04, %%o1\n"
456     " or %%o0, %%o1, %%o0\n"
457     " stb %%o0, [%0]\n"
458     #endif
459     " rd %%ccr, %%o0\n"
460     " stb %%o0, [%0]\n"
461     : /* no outputs */
462     : "r" (flags), "r" (dst), "r" (src)
463     : "cc", "o0", "o1"
464     );
465     }
466    
467     #if 1
468     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
469     {
470     __asm__ ("\n"
471     " sll %1, 24, %%o0\n"
472     " subcc %%o0, %%g0, %%g0\n"
473     " rd %%ccr, %%o0\n"
474     " stb %%o0, [%0]\n"
475     : /* no outputs */
476     : "r" (flags), "r" (val)
477     : "cc", "o0"
478     );
479     }
480    
481     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
482     {
483     __asm__ ("\n"
484     " sll %1, 16, %%o0\n"
485     " subcc %%o0, %%g0, %%g0\n"
486     " rd %%ccr, %%o0\n"
487     " stb %%o0, [%0]\n"
488     : /* no outputs */
489     : "r" (flags), "r" (val)
490     : "cc", "o0"
491     );
492     }
493    
494     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
495     {
496     __asm__ ("\n"
497     " subcc %1, %%g0, %%g0\n"
498     " rd %%ccr, %%o0\n"
499     " stb %%o0, [%0]\n"
500     : /* no outputs */
501     : "r" (flags), "r" (val)
502     : "cc", "o0"
503     );
504     }
505     #else
506     static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
507     {
508     __asm__ ("\n"
509     " sll %1, 24, %%o0\n"
510     " subcc %%o0, %%g0, %%o1\n"
511     " srl %%o1, 31, %%o0\n"
512     " sll %%o0, 3, %%o0\n"
513     " addx %%o0, %%g0, %%o0\n"
514     " bvs,a .+8\n"
515     " or %%o0, 0x02, %%o0\n"
516     " subcc %%g0, %%o1, %%g0\n"
517     " addx %%g0, 7, %%o1\n"
518     " and %%o1, 0x04, %%o1\n"
519     " or %%o0, %%o1, %%o0\n"
520     " stb %%o0, [%0]\n"
521     : /* no outputs */
522     : "r" (flags), "r" (val)
523     : "cc", "o0", "o1"
524     );
525     }
526    
527     static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
528     {
529     __asm__ ("\n"
530     " sll %1, 16, %%o0\n"
531     " subcc %%o0, %%g0, %%o1\n"
532     " srl %%o1, 31, %%o0\n"
533     " sll %%o0, 3, %%o0\n"
534     " addx %%o0, %%g0, %%o0\n"
535     " bvs,a .+8\n"
536     " or %%o0, 0x02, %%o0\n"
537     " subcc %%g0, %%o1, %%g0\n"
538     " addx %%g0, 7, %%o1\n"
539     " and %%o1, 0x04, %%o1\n"
540     " or %%o0, %%o1, %%o0\n"
541     " stb %%o0, [%0]\n"
542     : /* no outputs */
543     : "r" (flags), "r" (val)
544     : "cc", "o0", "o1"
545     );
546     }
547    
548     static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
549     {
550     __asm__ ("\n"
551     " subcc %1, %%g0, %%o1\n"
552     " srl %%o1, 31, %%o0\n"
553     " sll %%o0, 3, %%o0\n"
554     " addx %%o0, %%g0, %%o0\n"
555     " bvs,a .+8\n"
556     " or %%o0, 0x02, %%o0\n"
557     " subcc %%g0, %%o1, %%g0\n"
558     " addx %%g0, 7, %%o1\n"
559     " and %%o1, 0x04, %%o1\n"
560     " or %%o0, %%o1, %%o0\n"
561     " stb %%o0, [%0]\n"
562     : /* no outputs */
563     : "r" (flags), "r" (val)
564     : "cc", "o0", "o1"
565     );
566     }
567     #endif
568    
569     static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
570     {
571     uae_u32 value;
572     __asm__ ("\n"
573     " ldub [%1 + 1], %%o1 ! Get the X Flag\n"
574     " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n"
575     " addxcc %2, %3, %0\n"
576     : "=&r" (value)
577     : "r" (flags), "r" (dst), "r" (src)
578     : "cc", "o0", "o1"
579     );
580     return value;
581     }
582    
583     static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
584     {
585     uae_u32 value;
586     __asm__ ("\n"
587     " ldub [%1 + 1], %%o0 ! Get the X Flag\n"
588     " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n"
589     " addxcc %2, %3, %0\n"
590     " ldub [%1], %%o0 ! retreive the old NZVC flags\n"
591     " and %%o0, 0x04, %%o0 ! but keep only Z flag\n"
592     " addx %%o0, %%g0, %%o0 ! X,C flags\n"
593     " bl,a .+8\n"
594     " or %%o0, 0x08, %%o0 ! N flag\n"
595     " bvs,a .+8\n"
596     " or %%o0, 0x02, %%o0 ! V flag\n"
597     " bnz,a .+8\n"
598     " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n"
599     " stb %%o0, [%1]\n"
600     " stb %%o0, [%1 + 1]\n"
601     : "=&r" (value)
602     : "r" (flags), "r" (dst), "r" (src)
603     : "cc", "o0"
604     );
605     return value;
606     }
607    
608     #endif /* SPARC_V9_ASSEMBLY */
609    
610     #endif /* SPARC_ASSEMBLY__HEADER */