opensolaris_atomic.S revision 170431
1168482Spjd/*
2168482Spjd * CDDL HEADER START
3168482Spjd *
4168482Spjd * The contents of this file are subject to the terms of the
5168482Spjd * Common Development and Distribution License, Version 1.0 only
6168482Spjd * (the "License").  You may not use this file except in compliance
7168482Spjd * with the License.
8168482Spjd *
9168482Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10168482Spjd * or http://www.opensolaris.org/os/licensing.
11168482Spjd * See the License for the specific language governing permissions
12168482Spjd * and limitations under the License.
13168482Spjd *
14168482Spjd * When distributing Covered Code, include this CDDL HEADER in each
15168482Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16168482Spjd * If applicable, add the following below this CDDL HEADER, with the
17168482Spjd * fields enclosed by brackets "[]" replaced with your own identifying
18168482Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
19168482Spjd *
20168482Spjd * CDDL HEADER END
21168482Spjd */
22168482Spjd/*
23168482Spjd * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24168482Spjd * Use is subject to license terms.
25168482Spjd */
26168482Spjd
27168482Spjd	.ident	"%Z%%M%	%I%	%E% SMI"
28168482Spjd
29168482Spjd	.file	"%M%"
30168482Spjd
31168482Spjd#define	_ASM
32168482Spjd#include <sys/asm_linkage.h>
33168482Spjd
34168482Spjd	ENTRY(atomic_add_64)
35168482Spjd	ALTENTRY(atomic_add_64_nv)
36168482Spjd	pushl	%edi
37168482Spjd	pushl	%ebx
38168675Spjd	movl	12(%esp), %edi	// %edi = target address
39168482Spjd	movl	(%edi), %eax
40168675Spjd	movl	4(%edi), %edx	// %edx:%eax = old value
41168482Spjd1:
42168482Spjd	movl	16(%esp), %ebx
43168675Spjd	movl	20(%esp), %ecx	// %ecx:%ebx = delta
44168482Spjd	addl	%eax, %ebx
45168675Spjd	adcl	%edx, %ecx	// %ecx:%ebx = new value
46168482Spjd	lock
47168675Spjd	cmpxchg8b (%edi)	// try to stick it in
48168482Spjd	jne	1b
49168482Spjd	movl	%ebx, %eax
50168675Spjd	movl	%ecx, %edx	// return new value
51168482Spjd	popl	%ebx
52168482Spjd	popl	%edi
53168482Spjd	ret
54168482Spjd	SET_SIZE(atomic_add_64_nv)
55168482Spjd	SET_SIZE(atomic_add_64)
56168482Spjd
57168482Spjd	ENTRY(atomic_or_8_nv)
58168675Spjd	movl	4(%esp), %edx	// %edx = target address
59168675Spjd	movb	(%edx), %al	// %al = old value
60168482Spjd1:
61168675Spjd	movl	8(%esp), %ecx	// %ecx = delta
62168675Spjd	orb	%al, %cl	// %cl = new value
63168482Spjd	lock
64168675Spjd	cmpxchgb %cl, (%edx)	// try to stick it in
65168482Spjd	jne	1b
66168675Spjd	movzbl	%cl, %eax	// return new value
67168482Spjd	ret
68168482Spjd	SET_SIZE(atomic_or_8_nv)
69168482Spjd
70170431Spjd	ENTRY(atomic_cas_ptr)
71168482Spjd	movl	4(%esp), %edx
72168482Spjd	movl	8(%esp), %eax
73168482Spjd	movl	12(%esp), %ecx
74168482Spjd	lock
75168482Spjd	cmpxchgl %ecx, (%edx)
76168482Spjd	ret
77168482Spjd	SET_SIZE(atomic_cas_ptr)
78168482Spjd
79168482Spjd	ENTRY(atomic_cas_64)
80168482Spjd	pushl	%ebx
81168482Spjd	pushl	%esi
82168482Spjd	movl	12(%esp), %esi
83168482Spjd	movl	16(%esp), %eax
84168482Spjd	movl	20(%esp), %edx
85168482Spjd	movl	24(%esp), %ebx
86168482Spjd	movl	28(%esp), %ecx
87168482Spjd	lock
88168482Spjd	cmpxchg8b (%esi)
89168482Spjd	popl	%esi
90168482Spjd	popl	%ebx
91168482Spjd	ret
92168482Spjd	SET_SIZE(atomic_cas_64)
93168482Spjd
94170431Spjd	ENTRY(membar_producer)
95168482Spjd	lock
96168482Spjd	xorl	$0, (%esp)
97168482Spjd	ret
98168482Spjd	SET_SIZE(membar_producer)
99