]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / cddl / contrib / opensolaris / common / atomic / sparc64 / opensolaris_atomic.S
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25
26         .ident  "%Z%%M% %I%     %E% SMI"
27
28         .file   "%M%"
29
30 #define _ASM
31 #include <sys/asm_linkage.h>
32
33 #include <machine/asi.h>
34
35 /* Userland needs different ASIs. */
36 #ifdef _KERNEL
37 #define __ASI_ATOMIC    ASI_N
38 #else
39 #define __ASI_ATOMIC    ASI_P
40 #endif
41
42         /*
43          * NOTE: If atomic_add_64 and atomic_add_64_nv are ever
44          * separated, you need to also edit the libc sparcv9 platform
45          * specific mapfile and remove the NODYNSORT attribute
46          * from atomic_add_64_nv.
47          */
48         ENTRY(atomic_add_64)
49         ALTENTRY(atomic_add_64_nv)
50         ALTENTRY(atomic_add_ptr)
51         ALTENTRY(atomic_add_ptr_nv)
52         ALTENTRY(atomic_add_long)
53         ALTENTRY(atomic_add_long_nv)
54 add_64:
55         ldx     [%o0], %o2
56 1:
57         add     %o2, %o1, %o3
58         casxa   [%o0] __ASI_ATOMIC, %o2, %o3
59         cmp     %o2, %o3
60         bne,a,pn %xcc, 1b
61           mov   %o3, %o2
62         retl
63         add     %o2, %o1, %o0           ! return new value
64         SET_SIZE(atomic_add_long_nv)
65         SET_SIZE(atomic_add_long)
66         SET_SIZE(atomic_add_ptr_nv)
67         SET_SIZE(atomic_add_ptr)
68         SET_SIZE(atomic_add_64_nv)
69         SET_SIZE(atomic_add_64)
70
71         /*
72          * NOTE: If atomic_or_8 and atomic_or_8_nv are ever
73          * separated, you need to also edit the libc sparcv9 platform
74          * specific mapfile and remove the NODYNSORT attribute
75          * from atomic_or_8_nv.
76          */
77         ENTRY(atomic_or_8)
78         ALTENTRY(atomic_or_8_nv)
79         ALTENTRY(atomic_or_uchar)
80         ALTENTRY(atomic_or_uchar_nv)
81         and     %o0, 0x3, %o4           ! %o4 = byte offset, left-to-right
82         xor     %o4, 0x3, %g1           ! %g1 = byte offset, right-to-left
83         sll     %g1, 3, %g1             ! %g1 = bit offset, right-to-left
84         set     0xff, %o3               ! %o3 = mask
85         sll     %o3, %g1, %o3           ! %o3 = shifted to bit offset
86         sll     %o1, %g1, %o1           ! %o1 = shifted to bit offset
87         and     %o1, %o3, %o1           ! %o1 = single byte value
88         andn    %o0, 0x3, %o0           ! %o0 = word address
89         ld      [%o0], %o2              ! read old value
90 1:
91         or      %o2, %o1, %o5           ! or in the new value
92         casa    [%o0] __ASI_ATOMIC, %o2, %o5
93         cmp     %o2, %o5
94         bne,a,pn %icc, 1b
95           mov   %o5, %o2                ! %o2 = old value
96         or      %o2, %o1, %o5
97         and     %o5, %o3, %o5
98         retl
99         srl     %o5, %g1, %o0           ! %o0 = new value
100         SET_SIZE(atomic_or_uchar_nv)
101         SET_SIZE(atomic_or_uchar)
102         SET_SIZE(atomic_or_8_nv)
103         SET_SIZE(atomic_or_8)
104
105         /*
106          * Spitfires and Blackbirds have a problem with membars in the
107          * delay slot (SF_ERRATA_51).  For safety's sake, we assume
108          * that the whole world needs the workaround.
109          */
110
111         ENTRY(membar_producer)
112         membar  #StoreStore
113         retl
114         nop
115         SET_SIZE(membar_producer)