]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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         and     %o0, 0x3, %o4           ! %o4 = byte offset, left-to-right
81         xor     %o4, 0x3, %g1           ! %g1 = byte offset, right-to-left
82         sll     %g1, 3, %g1             ! %g1 = bit offset, right-to-left
83         set     0xff, %o3               ! %o3 = mask
84         sll     %o3, %g1, %o3           ! %o3 = shifted to bit offset
85         sll     %o1, %g1, %o1           ! %o1 = shifted to bit offset
86         and     %o1, %o3, %o1           ! %o1 = single byte value
87         andn    %o0, 0x3, %o0           ! %o0 = word address
88         ld      [%o0], %o2              ! read old value
89 1:
90         or      %o2, %o1, %o5           ! or in the new value
91         casa    [%o0] __ASI_ATOMIC, %o2, %o5
92         cmp     %o2, %o5
93         bne,a,pn %icc, 1b
94           mov   %o5, %o2                ! %o2 = old value
95         or      %o2, %o1, %o5
96         and     %o5, %o3, %o5
97         retl
98         srl     %o5, %g1, %o0           ! %o0 = new value
99         SET_SIZE(atomic_or_uchar)
100         SET_SIZE(atomic_or_8_nv)
101         SET_SIZE(atomic_or_8)
102
103         /*
104          * Spitfires and Blackbirds have a problem with membars in the
105          * delay slot (SF_ERRATA_51).  For safety's sake, we assume
106          * that the whole world needs the workaround.
107          */
108
109         ENTRY(membar_producer)
110         membar  #StoreStore
111         retl
112         nop
113         SET_SIZE(membar_producer)