]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / cddl / contrib / opensolaris / common / atomic / i386 / 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 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27         .file   "atomic.s"
28
29 #define _ASM
30 #include <sys/asm_linkage.h>
31
32         /*
33          * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever
34          * separated, it is important to edit the libc i386 platform
35          * specific mapfile and remove the NODYNSORT attribute
36          * from atomic_dec_64_nv.
37          */
38         ENTRY(atomic_dec_64)
39         ALTENTRY(atomic_dec_64_nv)
40         pushl   %edi
41         pushl   %ebx
42         movl    12(%esp), %edi  // %edi = target address
43         movl    (%edi), %eax
44         movl    4(%edi), %edx   // %edx:%eax = old value
45 1:
46         xorl    %ebx, %ebx
47         xorl    %ecx, %ecx
48         not     %ecx
49         not     %ebx            // %ecx:%ebx = -1
50         addl    %eax, %ebx
51         adcl    %edx, %ecx      // add in the carry from inc
52         lock
53         cmpxchg8b (%edi)        // try to stick it in
54         jne     1b
55         movl    %ebx, %eax
56         movl    %ecx, %edx      // return new value
57         popl    %ebx
58         popl    %edi
59         ret
60         SET_SIZE(atomic_dec_64_nv)
61         SET_SIZE(atomic_dec_64)
62
63         /*
64          * NOTE: If atomic_add_64 and atomic_add_64_nv are ever
65          * separated, it is important to edit the libc i386 platform
66          * specific mapfile and remove the NODYNSORT attribute
67          * from atomic_add_64_nv.
68          */
69         ENTRY(atomic_add_64)
70         ALTENTRY(atomic_add_64_nv)
71         pushl   %edi
72         pushl   %ebx
73         movl    12(%esp), %edi  // %edi = target address
74         movl    (%edi), %eax
75         movl    4(%edi), %edx   // %edx:%eax = old value
76 1:
77         movl    16(%esp), %ebx
78         movl    20(%esp), %ecx  // %ecx:%ebx = delta
79         addl    %eax, %ebx
80         adcl    %edx, %ecx      // %ecx:%ebx = new value
81         lock
82         cmpxchg8b (%edi)        // try to stick it in
83         jne     1b
84         movl    %ebx, %eax
85         movl    %ecx, %edx      // return new value
86         popl    %ebx
87         popl    %edi
88         ret
89         SET_SIZE(atomic_add_64_nv)
90         SET_SIZE(atomic_add_64)
91
92         ENTRY(atomic_or_8_nv)
93         movl    4(%esp), %edx   // %edx = target address
94         movb    (%edx), %al     // %al = old value
95 1:
96         movl    8(%esp), %ecx   // %ecx = delta
97         orb     %al, %cl        // %cl = new value
98         lock
99         cmpxchgb %cl, (%edx)    // try to stick it in
100         jne     1b
101         movzbl  %cl, %eax       // return new value
102         ret
103         SET_SIZE(atomic_or_8_nv)
104
105         ENTRY(atomic_cas_32)
106         movl    4(%esp), %edx
107         movl    8(%esp), %eax
108         movl    12(%esp), %ecx
109         lock
110         cmpxchgl %ecx, (%edx)
111         ret
112         SET_SIZE(atomic_cas_32)
113
114         ENTRY(atomic_cas_64)
115         pushl   %ebx
116         pushl   %esi
117         movl    12(%esp), %esi
118         movl    16(%esp), %eax
119         movl    20(%esp), %edx
120         movl    24(%esp), %ebx
121         movl    28(%esp), %ecx
122         lock
123         cmpxchg8b (%esi)
124         popl    %esi
125         popl    %ebx
126         ret
127         SET_SIZE(atomic_cas_64)
128
129         ENTRY(membar_producer)
130         lock
131         xorl    $0, (%esp)
132         ret
133         SET_SIZE(membar_producer)