xref: /onnv-gate/usr/src/common/atomic/amd64/atomic.s (revision 12541:cf209463f3e9)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
54292Sab196087 * Common Development and Distribution License (the "License").
64292Sab196087 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
216812Sraf
220Sstevel@tonic-gate/*
23*12541SSurya.Prakki@Sun.COM * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
267298SMark.J.Nelson@Sun.COM	.file	"atomic.s"
270Sstevel@tonic-gate
280Sstevel@tonic-gate#include <sys/asm_linkage.h>
290Sstevel@tonic-gate
300Sstevel@tonic-gate#if defined(_KERNEL)
310Sstevel@tonic-gate	/*
320Sstevel@tonic-gate	 * Legacy kernel interfaces; they will go away (eventually).
330Sstevel@tonic-gate	 */
340Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function)
350Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function)
360Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function)
370Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function)
380Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function)
390Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function)
400Sstevel@tonic-gate	ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function)
410Sstevel@tonic-gate#endif
420Sstevel@tonic-gate
430Sstevel@tonic-gate	ENTRY(atomic_inc_8)
440Sstevel@tonic-gate	ALTENTRY(atomic_inc_uchar)
450Sstevel@tonic-gate	lock
460Sstevel@tonic-gate	incb	(%rdi)
470Sstevel@tonic-gate	ret
480Sstevel@tonic-gate	SET_SIZE(atomic_inc_uchar)
490Sstevel@tonic-gate	SET_SIZE(atomic_inc_8)
500Sstevel@tonic-gate
510Sstevel@tonic-gate	ENTRY(atomic_inc_16)
520Sstevel@tonic-gate	ALTENTRY(atomic_inc_ushort)
530Sstevel@tonic-gate	lock
540Sstevel@tonic-gate	incw	(%rdi)
550Sstevel@tonic-gate	ret
560Sstevel@tonic-gate	SET_SIZE(atomic_inc_ushort)
570Sstevel@tonic-gate	SET_SIZE(atomic_inc_16)
580Sstevel@tonic-gate
590Sstevel@tonic-gate	ENTRY(atomic_inc_32)
600Sstevel@tonic-gate	ALTENTRY(atomic_inc_uint)
610Sstevel@tonic-gate	lock
620Sstevel@tonic-gate	incl	(%rdi)
630Sstevel@tonic-gate	ret
640Sstevel@tonic-gate	SET_SIZE(atomic_inc_uint)
650Sstevel@tonic-gate	SET_SIZE(atomic_inc_32)
660Sstevel@tonic-gate
670Sstevel@tonic-gate	ENTRY(atomic_inc_64)
680Sstevel@tonic-gate	ALTENTRY(atomic_inc_ulong)
690Sstevel@tonic-gate	lock
700Sstevel@tonic-gate	incq	(%rdi)
710Sstevel@tonic-gate	ret
720Sstevel@tonic-gate	SET_SIZE(atomic_inc_ulong)
730Sstevel@tonic-gate	SET_SIZE(atomic_inc_64)
740Sstevel@tonic-gate
750Sstevel@tonic-gate	ENTRY(atomic_inc_8_nv)
760Sstevel@tonic-gate	ALTENTRY(atomic_inc_uchar_nv)
7711599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ clear upper bits of %eax return register
7811599SBill.Holler@Sun.COM	incb	%al		/ %al = 1
790Sstevel@tonic-gate	lock
8011599SBill.Holler@Sun.COM	  xaddb	%al, (%rdi)	/ %al = old value, (%rdi) = new value
8111599SBill.Holler@Sun.COM	incb	%al		/ return new value
820Sstevel@tonic-gate	ret
830Sstevel@tonic-gate	SET_SIZE(atomic_inc_uchar_nv)
840Sstevel@tonic-gate	SET_SIZE(atomic_inc_8_nv)
850Sstevel@tonic-gate
860Sstevel@tonic-gate	ENTRY(atomic_inc_16_nv)
870Sstevel@tonic-gate	ALTENTRY(atomic_inc_ushort_nv)
8811599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ clear upper bits of %eax return register
8911599SBill.Holler@Sun.COM	incw	%ax		/ %ax = 1
900Sstevel@tonic-gate	lock
9111599SBill.Holler@Sun.COM	  xaddw	%ax, (%rdi)	/ %ax = old value, (%rdi) = new value
9211599SBill.Holler@Sun.COM	incw	%ax		/ return new value
930Sstevel@tonic-gate	ret
940Sstevel@tonic-gate	SET_SIZE(atomic_inc_ushort_nv)
950Sstevel@tonic-gate	SET_SIZE(atomic_inc_16_nv)
960Sstevel@tonic-gate
970Sstevel@tonic-gate	ENTRY(atomic_inc_32_nv)
980Sstevel@tonic-gate	ALTENTRY(atomic_inc_uint_nv)
9911599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ %eax = 0
10011599SBill.Holler@Sun.COM	incl	%eax		/ %eax = 1
1010Sstevel@tonic-gate	lock
10211599SBill.Holler@Sun.COM	  xaddl	%eax, (%rdi)	/ %eax = old value, (%rdi) = new value
10311599SBill.Holler@Sun.COM	incl	%eax		/ return new value
1040Sstevel@tonic-gate	ret
1050Sstevel@tonic-gate	SET_SIZE(atomic_inc_uint_nv)
1060Sstevel@tonic-gate	SET_SIZE(atomic_inc_32_nv)
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate	ENTRY(atomic_inc_64_nv)
1090Sstevel@tonic-gate	ALTENTRY(atomic_inc_ulong_nv)
11011599SBill.Holler@Sun.COM	xorq	%rax, %rax	/ %rax = 0
11111599SBill.Holler@Sun.COM	incq	%rax		/ %rax = 1
1120Sstevel@tonic-gate	lock
11311599SBill.Holler@Sun.COM	  xaddq	%rax, (%rdi)	/ %rax = old value, (%rdi) = new value
11411599SBill.Holler@Sun.COM	incq	%rax		/ return new value
1150Sstevel@tonic-gate	ret
1160Sstevel@tonic-gate	SET_SIZE(atomic_inc_ulong_nv)
1170Sstevel@tonic-gate	SET_SIZE(atomic_inc_64_nv)
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate	ENTRY(atomic_dec_8)
1200Sstevel@tonic-gate	ALTENTRY(atomic_dec_uchar)
1210Sstevel@tonic-gate	lock
1220Sstevel@tonic-gate	decb	(%rdi)
1230Sstevel@tonic-gate	ret
1240Sstevel@tonic-gate	SET_SIZE(atomic_dec_uchar)
1250Sstevel@tonic-gate	SET_SIZE(atomic_dec_8)
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate	ENTRY(atomic_dec_16)
1280Sstevel@tonic-gate	ALTENTRY(atomic_dec_ushort)
1290Sstevel@tonic-gate	lock
1300Sstevel@tonic-gate	decw	(%rdi)
1310Sstevel@tonic-gate	ret
1320Sstevel@tonic-gate	SET_SIZE(atomic_dec_ushort)
1330Sstevel@tonic-gate	SET_SIZE(atomic_dec_16)
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate	ENTRY(atomic_dec_32)
1360Sstevel@tonic-gate	ALTENTRY(atomic_dec_uint)
1370Sstevel@tonic-gate	lock
1380Sstevel@tonic-gate	decl	(%rdi)
1390Sstevel@tonic-gate	ret
1400Sstevel@tonic-gate	SET_SIZE(atomic_dec_uint)
1410Sstevel@tonic-gate	SET_SIZE(atomic_dec_32)
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate	ENTRY(atomic_dec_64)
1440Sstevel@tonic-gate	ALTENTRY(atomic_dec_ulong)
1450Sstevel@tonic-gate	lock
1460Sstevel@tonic-gate	decq	(%rdi)
1470Sstevel@tonic-gate	ret
1480Sstevel@tonic-gate	SET_SIZE(atomic_dec_ulong)
1490Sstevel@tonic-gate	SET_SIZE(atomic_dec_64)
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate	ENTRY(atomic_dec_8_nv)
1520Sstevel@tonic-gate	ALTENTRY(atomic_dec_uchar_nv)
15311599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ clear upper bits of %eax return register
15411599SBill.Holler@Sun.COM	decb	%al		/ %al = -1
1550Sstevel@tonic-gate	lock
15611599SBill.Holler@Sun.COM	  xaddb	%al, (%rdi)	/ %al = old value, (%rdi) = new value
15711599SBill.Holler@Sun.COM	decb	%al		/ return new value
1580Sstevel@tonic-gate	ret
1590Sstevel@tonic-gate	SET_SIZE(atomic_dec_uchar_nv)
1600Sstevel@tonic-gate	SET_SIZE(atomic_dec_8_nv)
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate	ENTRY(atomic_dec_16_nv)
1630Sstevel@tonic-gate	ALTENTRY(atomic_dec_ushort_nv)
16411599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ clear upper bits of %eax return register
16511599SBill.Holler@Sun.COM	decw	%ax		/ %ax = -1
1660Sstevel@tonic-gate	lock
16711599SBill.Holler@Sun.COM	  xaddw	%ax, (%rdi)	/ %ax = old value, (%rdi) = new value
16811599SBill.Holler@Sun.COM	decw	%ax		/ return new value
1690Sstevel@tonic-gate	ret
1700Sstevel@tonic-gate	SET_SIZE(atomic_dec_ushort_nv)
1710Sstevel@tonic-gate	SET_SIZE(atomic_dec_16_nv)
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate	ENTRY(atomic_dec_32_nv)
1740Sstevel@tonic-gate	ALTENTRY(atomic_dec_uint_nv)
17511599SBill.Holler@Sun.COM	xorl	%eax, %eax	/ %eax = 0
17611599SBill.Holler@Sun.COM	decl	%eax		/ %eax = -1
1770Sstevel@tonic-gate	lock
17811599SBill.Holler@Sun.COM	  xaddl	%eax, (%rdi)	/ %eax = old value, (%rdi) = new value
17911599SBill.Holler@Sun.COM	decl	%eax		/ return new value
1800Sstevel@tonic-gate	ret
1810Sstevel@tonic-gate	SET_SIZE(atomic_dec_uint_nv)
1820Sstevel@tonic-gate	SET_SIZE(atomic_dec_32_nv)
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate	ENTRY(atomic_dec_64_nv)
1850Sstevel@tonic-gate	ALTENTRY(atomic_dec_ulong_nv)
18611599SBill.Holler@Sun.COM	xorq	%rax, %rax	/ %rax = 0
18711599SBill.Holler@Sun.COM	decq	%rax		/ %rax = -1
1880Sstevel@tonic-gate	lock
18911599SBill.Holler@Sun.COM	  xaddq	%rax, (%rdi)	/ %rax = old value, (%rdi) = new value
19011599SBill.Holler@Sun.COM	decq	%rax		/ return new value
1910Sstevel@tonic-gate	ret
1920Sstevel@tonic-gate	SET_SIZE(atomic_dec_ulong_nv)
1930Sstevel@tonic-gate	SET_SIZE(atomic_dec_64_nv)
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate	ENTRY(atomic_add_8)
1960Sstevel@tonic-gate	ALTENTRY(atomic_add_char)
1970Sstevel@tonic-gate	lock
1980Sstevel@tonic-gate	addb	%sil, (%rdi)
1990Sstevel@tonic-gate	ret
2000Sstevel@tonic-gate	SET_SIZE(atomic_add_char)
2010Sstevel@tonic-gate	SET_SIZE(atomic_add_8)
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate	ENTRY(atomic_add_16)
2040Sstevel@tonic-gate	ALTENTRY(atomic_add_short)
2050Sstevel@tonic-gate	lock
2060Sstevel@tonic-gate	addw	%si, (%rdi)
2070Sstevel@tonic-gate	ret
2080Sstevel@tonic-gate	SET_SIZE(atomic_add_short)
2090Sstevel@tonic-gate	SET_SIZE(atomic_add_16)
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate	ENTRY(atomic_add_32)
2120Sstevel@tonic-gate	ALTENTRY(atomic_add_int)
2130Sstevel@tonic-gate	lock
2140Sstevel@tonic-gate	addl	%esi, (%rdi)
2150Sstevel@tonic-gate	ret
2160Sstevel@tonic-gate	SET_SIZE(atomic_add_int)
2170Sstevel@tonic-gate	SET_SIZE(atomic_add_32)
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate	ENTRY(atomic_add_64)
2200Sstevel@tonic-gate	ALTENTRY(atomic_add_ptr)
2210Sstevel@tonic-gate	ALTENTRY(atomic_add_long)
2220Sstevel@tonic-gate	lock
2230Sstevel@tonic-gate	addq	%rsi, (%rdi)
2240Sstevel@tonic-gate	ret
2250Sstevel@tonic-gate	SET_SIZE(atomic_add_long)
2260Sstevel@tonic-gate	SET_SIZE(atomic_add_ptr)
2270Sstevel@tonic-gate	SET_SIZE(atomic_add_64)
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate	ENTRY(atomic_or_8)
2300Sstevel@tonic-gate	ALTENTRY(atomic_or_uchar)
2310Sstevel@tonic-gate	lock
2320Sstevel@tonic-gate	orb	%sil, (%rdi)
2330Sstevel@tonic-gate	ret
2340Sstevel@tonic-gate	SET_SIZE(atomic_or_uchar)
2350Sstevel@tonic-gate	SET_SIZE(atomic_or_8)
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate	ENTRY(atomic_or_16)
2380Sstevel@tonic-gate	ALTENTRY(atomic_or_ushort)
2390Sstevel@tonic-gate	lock
2400Sstevel@tonic-gate	orw	%si, (%rdi)
2410Sstevel@tonic-gate	ret
2420Sstevel@tonic-gate	SET_SIZE(atomic_or_ushort)
2430Sstevel@tonic-gate	SET_SIZE(atomic_or_16)
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate	ENTRY(atomic_or_32)
2460Sstevel@tonic-gate	ALTENTRY(atomic_or_uint)
2470Sstevel@tonic-gate	lock
2480Sstevel@tonic-gate	orl	%esi, (%rdi)
2490Sstevel@tonic-gate	ret
2500Sstevel@tonic-gate	SET_SIZE(atomic_or_uint)
2510Sstevel@tonic-gate	SET_SIZE(atomic_or_32)
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate	ENTRY(atomic_or_64)
2540Sstevel@tonic-gate	ALTENTRY(atomic_or_ulong)
2550Sstevel@tonic-gate	lock
2560Sstevel@tonic-gate	orq	%rsi, (%rdi)
2570Sstevel@tonic-gate	ret
2580Sstevel@tonic-gate	SET_SIZE(atomic_or_ulong)
2590Sstevel@tonic-gate	SET_SIZE(atomic_or_64)
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate	ENTRY(atomic_and_8)
2620Sstevel@tonic-gate	ALTENTRY(atomic_and_uchar)
2630Sstevel@tonic-gate	lock
2640Sstevel@tonic-gate	andb	%sil, (%rdi)
2650Sstevel@tonic-gate	ret
2660Sstevel@tonic-gate	SET_SIZE(atomic_and_uchar)
2670Sstevel@tonic-gate	SET_SIZE(atomic_and_8)
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate	ENTRY(atomic_and_16)
2700Sstevel@tonic-gate	ALTENTRY(atomic_and_ushort)
2710Sstevel@tonic-gate	lock
2720Sstevel@tonic-gate	andw	%si, (%rdi)
2730Sstevel@tonic-gate	ret
2740Sstevel@tonic-gate	SET_SIZE(atomic_and_ushort)
2750Sstevel@tonic-gate	SET_SIZE(atomic_and_16)
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate	ENTRY(atomic_and_32)
2780Sstevel@tonic-gate	ALTENTRY(atomic_and_uint)
2790Sstevel@tonic-gate	lock
2800Sstevel@tonic-gate	andl	%esi, (%rdi)
2810Sstevel@tonic-gate	ret
2820Sstevel@tonic-gate	SET_SIZE(atomic_and_uint)
2830Sstevel@tonic-gate	SET_SIZE(atomic_and_32)
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate	ENTRY(atomic_and_64)
2860Sstevel@tonic-gate	ALTENTRY(atomic_and_ulong)
2870Sstevel@tonic-gate	lock
2880Sstevel@tonic-gate	andq	%rsi, (%rdi)
2890Sstevel@tonic-gate	ret
2900Sstevel@tonic-gate	SET_SIZE(atomic_and_ulong)
2910Sstevel@tonic-gate	SET_SIZE(atomic_and_64)
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate	ENTRY(atomic_add_8_nv)
2940Sstevel@tonic-gate	ALTENTRY(atomic_add_char_nv)
29511599SBill.Holler@Sun.COM	movzbl	%sil, %eax		/ %al = delta addend, clear upper bits
2960Sstevel@tonic-gate	lock
29711599SBill.Holler@Sun.COM	  xaddb	%sil, (%rdi)		/ %sil = old value, (%rdi) = sum
29811599SBill.Holler@Sun.COM	addb	%sil, %al		/ new value = original value + delta
2990Sstevel@tonic-gate	ret
3000Sstevel@tonic-gate	SET_SIZE(atomic_add_char_nv)
3010Sstevel@tonic-gate	SET_SIZE(atomic_add_8_nv)
3020Sstevel@tonic-gate
3030Sstevel@tonic-gate	ENTRY(atomic_add_16_nv)
3040Sstevel@tonic-gate	ALTENTRY(atomic_add_short_nv)
30511599SBill.Holler@Sun.COM	movzwl	%si, %eax		/ %ax = delta addend, clean upper bits
3060Sstevel@tonic-gate	lock
30711599SBill.Holler@Sun.COM	  xaddw	%si, (%rdi)		/ %si = old value, (%rdi) = sum
30811599SBill.Holler@Sun.COM	addw	%si, %ax		/ new value = original value + delta
3090Sstevel@tonic-gate	ret
3100Sstevel@tonic-gate	SET_SIZE(atomic_add_short_nv)
3110Sstevel@tonic-gate	SET_SIZE(atomic_add_16_nv)
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate	ENTRY(atomic_add_32_nv)
3140Sstevel@tonic-gate	ALTENTRY(atomic_add_int_nv)
31511599SBill.Holler@Sun.COM	mov	%esi, %eax		/ %eax = delta addend
3160Sstevel@tonic-gate	lock
31711599SBill.Holler@Sun.COM	  xaddl	%esi, (%rdi)		/ %esi = old value, (%rdi) = sum
31811599SBill.Holler@Sun.COM	add	%esi, %eax		/ new value = original value + delta
3190Sstevel@tonic-gate	ret
3200Sstevel@tonic-gate	SET_SIZE(atomic_add_int_nv)
3210Sstevel@tonic-gate	SET_SIZE(atomic_add_32_nv)
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate	ENTRY(atomic_add_64_nv)
3240Sstevel@tonic-gate	ALTENTRY(atomic_add_ptr_nv)
3250Sstevel@tonic-gate	ALTENTRY(atomic_add_long_nv)
32611599SBill.Holler@Sun.COM	mov	%rsi, %rax		/ %rax = delta addend
3270Sstevel@tonic-gate	lock
32811599SBill.Holler@Sun.COM	  xaddq	%rsi, (%rdi)		/ %rsi = old value, (%rdi) = sum
32911599SBill.Holler@Sun.COM	addq	%rsi, %rax		/ new value = original value + delta
3300Sstevel@tonic-gate	ret
3310Sstevel@tonic-gate	SET_SIZE(atomic_add_long_nv)
3320Sstevel@tonic-gate	SET_SIZE(atomic_add_ptr_nv)
3330Sstevel@tonic-gate	SET_SIZE(atomic_add_64_nv)
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate	ENTRY(atomic_and_8_nv)
3360Sstevel@tonic-gate	ALTENTRY(atomic_and_uchar_nv)
3370Sstevel@tonic-gate	movb	(%rdi), %al	/ %al = old value
3380Sstevel@tonic-gate1:
3390Sstevel@tonic-gate	movb	%sil, %cl
3400Sstevel@tonic-gate	andb	%al, %cl	/ %cl = new value
3410Sstevel@tonic-gate	lock
3420Sstevel@tonic-gate	cmpxchgb %cl, (%rdi)	/ try to stick it in
3430Sstevel@tonic-gate	jne	1b
3440Sstevel@tonic-gate	movzbl	%cl, %eax	/ return new value
3450Sstevel@tonic-gate	ret
3460Sstevel@tonic-gate	SET_SIZE(atomic_and_uchar_nv)
3470Sstevel@tonic-gate	SET_SIZE(atomic_and_8_nv)
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate	ENTRY(atomic_and_16_nv)
3500Sstevel@tonic-gate	ALTENTRY(atomic_and_ushort_nv)
3510Sstevel@tonic-gate	movw	(%rdi), %ax	/ %ax = old value
3520Sstevel@tonic-gate1:
3530Sstevel@tonic-gate	movw	%si, %cx
3540Sstevel@tonic-gate	andw	%ax, %cx	/ %cx = new value
3550Sstevel@tonic-gate	lock
3560Sstevel@tonic-gate	cmpxchgw %cx, (%rdi)	/ try to stick it in
3570Sstevel@tonic-gate	jne	1b
3580Sstevel@tonic-gate	movzwl	%cx, %eax	/ return new value
3590Sstevel@tonic-gate	ret
3600Sstevel@tonic-gate	SET_SIZE(atomic_and_ushort_nv)
3610Sstevel@tonic-gate	SET_SIZE(atomic_and_16_nv)
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate	ENTRY(atomic_and_32_nv)
3640Sstevel@tonic-gate	ALTENTRY(atomic_and_uint_nv)
3650Sstevel@tonic-gate	movl	(%rdi), %eax
3660Sstevel@tonic-gate1:
3670Sstevel@tonic-gate	movl	%esi, %ecx
3680Sstevel@tonic-gate	andl	%eax, %ecx
3690Sstevel@tonic-gate	lock
3700Sstevel@tonic-gate	cmpxchgl %ecx, (%rdi)
3710Sstevel@tonic-gate	jne	1b
3720Sstevel@tonic-gate	movl	%ecx, %eax
3730Sstevel@tonic-gate	ret
3740Sstevel@tonic-gate	SET_SIZE(atomic_and_uint_nv)
3750Sstevel@tonic-gate	SET_SIZE(atomic_and_32_nv)
3760Sstevel@tonic-gate
3770Sstevel@tonic-gate	ENTRY(atomic_and_64_nv)
3780Sstevel@tonic-gate	ALTENTRY(atomic_and_ulong_nv)
3790Sstevel@tonic-gate	movq	(%rdi), %rax
3800Sstevel@tonic-gate1:
3810Sstevel@tonic-gate	movq	%rsi, %rcx
3820Sstevel@tonic-gate	andq	%rax, %rcx
3830Sstevel@tonic-gate	lock
3840Sstevel@tonic-gate	cmpxchgq %rcx, (%rdi)
3850Sstevel@tonic-gate	jne	1b
3860Sstevel@tonic-gate	movq	%rcx, %rax
3870Sstevel@tonic-gate	ret
3880Sstevel@tonic-gate	SET_SIZE(atomic_and_ulong_nv)
3890Sstevel@tonic-gate	SET_SIZE(atomic_and_64_nv)
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate	ENTRY(atomic_or_8_nv)
3920Sstevel@tonic-gate	ALTENTRY(atomic_or_uchar_nv)
3930Sstevel@tonic-gate	movb	(%rdi), %al	/ %al = old value
3940Sstevel@tonic-gate1:
3950Sstevel@tonic-gate	movb	%sil, %cl
3960Sstevel@tonic-gate	orb	%al, %cl	/ %cl = new value
3970Sstevel@tonic-gate	lock
3980Sstevel@tonic-gate	cmpxchgb %cl, (%rdi)	/ try to stick it in
3990Sstevel@tonic-gate	jne	1b
4000Sstevel@tonic-gate	movzbl	%cl, %eax	/ return new value
4010Sstevel@tonic-gate	ret
402*12541SSurya.Prakki@Sun.COM	SET_SIZE(atomic_or_uchar_nv)
403*12541SSurya.Prakki@Sun.COM	SET_SIZE(atomic_or_8_nv)
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate	ENTRY(atomic_or_16_nv)
4060Sstevel@tonic-gate	ALTENTRY(atomic_or_ushort_nv)
4070Sstevel@tonic-gate	movw	(%rdi), %ax	/ %ax = old value
4080Sstevel@tonic-gate1:
4090Sstevel@tonic-gate	movw	%si, %cx
4100Sstevel@tonic-gate	orw	%ax, %cx	/ %cx = new value
4110Sstevel@tonic-gate	lock
4120Sstevel@tonic-gate	cmpxchgw %cx, (%rdi)	/ try to stick it in
4130Sstevel@tonic-gate	jne	1b
4140Sstevel@tonic-gate	movzwl	%cx, %eax	/ return new value
4150Sstevel@tonic-gate	ret
4160Sstevel@tonic-gate	SET_SIZE(atomic_or_ushort_nv)
4170Sstevel@tonic-gate	SET_SIZE(atomic_or_16_nv)
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate	ENTRY(atomic_or_32_nv)
4200Sstevel@tonic-gate	ALTENTRY(atomic_or_uint_nv)
4210Sstevel@tonic-gate	movl	(%rdi), %eax
4220Sstevel@tonic-gate1:
4230Sstevel@tonic-gate	movl	%esi, %ecx
4240Sstevel@tonic-gate	orl	%eax, %ecx
4250Sstevel@tonic-gate	lock
4260Sstevel@tonic-gate	cmpxchgl %ecx, (%rdi)
4270Sstevel@tonic-gate	jne	1b
4280Sstevel@tonic-gate	movl	%ecx, %eax
4290Sstevel@tonic-gate	ret
4300Sstevel@tonic-gate	SET_SIZE(atomic_or_uint_nv)
4310Sstevel@tonic-gate	SET_SIZE(atomic_or_32_nv)
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate	ENTRY(atomic_or_64_nv)
4340Sstevel@tonic-gate	ALTENTRY(atomic_or_ulong_nv)
4350Sstevel@tonic-gate	movq	(%rdi), %rax
4360Sstevel@tonic-gate1:
4370Sstevel@tonic-gate	movq	%rsi, %rcx
4380Sstevel@tonic-gate	orq	%rax, %rcx
4390Sstevel@tonic-gate	lock
4400Sstevel@tonic-gate	cmpxchgq %rcx, (%rdi)
4410Sstevel@tonic-gate	jne	1b
4420Sstevel@tonic-gate	movq	%rcx, %rax
4430Sstevel@tonic-gate	ret
4440Sstevel@tonic-gate	SET_SIZE(atomic_or_ulong_nv)
4450Sstevel@tonic-gate	SET_SIZE(atomic_or_64_nv)
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate	ENTRY(atomic_cas_8)
4480Sstevel@tonic-gate	ALTENTRY(atomic_cas_uchar)
4490Sstevel@tonic-gate	movzbl	%sil, %eax
4500Sstevel@tonic-gate	lock
4510Sstevel@tonic-gate	cmpxchgb %dl, (%rdi)
4520Sstevel@tonic-gate	ret
4530Sstevel@tonic-gate	SET_SIZE(atomic_cas_uchar)
4540Sstevel@tonic-gate	SET_SIZE(atomic_cas_8)
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate	ENTRY(atomic_cas_16)
4570Sstevel@tonic-gate	ALTENTRY(atomic_cas_ushort)
4580Sstevel@tonic-gate	movzwl	%si, %eax
4590Sstevel@tonic-gate	lock
4600Sstevel@tonic-gate	cmpxchgw %dx, (%rdi)
4610Sstevel@tonic-gate	ret
4620Sstevel@tonic-gate	SET_SIZE(atomic_cas_ushort)
4630Sstevel@tonic-gate	SET_SIZE(atomic_cas_16)
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate	ENTRY(atomic_cas_32)
4660Sstevel@tonic-gate	ALTENTRY(atomic_cas_uint)
4670Sstevel@tonic-gate	movl	%esi, %eax
4680Sstevel@tonic-gate	lock
4690Sstevel@tonic-gate	cmpxchgl %edx, (%rdi)
4700Sstevel@tonic-gate	ret
4710Sstevel@tonic-gate	SET_SIZE(atomic_cas_uint)
4720Sstevel@tonic-gate	SET_SIZE(atomic_cas_32)
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate	ENTRY(atomic_cas_64)
4750Sstevel@tonic-gate	ALTENTRY(atomic_cas_ulong)
4760Sstevel@tonic-gate	ALTENTRY(atomic_cas_ptr)
4770Sstevel@tonic-gate	movq	%rsi, %rax
4780Sstevel@tonic-gate	lock
4790Sstevel@tonic-gate	cmpxchgq %rdx, (%rdi)
4800Sstevel@tonic-gate	ret
4810Sstevel@tonic-gate	SET_SIZE(atomic_cas_ptr)
4820Sstevel@tonic-gate	SET_SIZE(atomic_cas_ulong)
4830Sstevel@tonic-gate	SET_SIZE(atomic_cas_64)
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate	ENTRY(atomic_swap_8)
4860Sstevel@tonic-gate	ALTENTRY(atomic_swap_uchar)
4870Sstevel@tonic-gate	movzbl	%sil, %eax
4880Sstevel@tonic-gate	lock
4890Sstevel@tonic-gate	xchgb %al, (%rdi)
4900Sstevel@tonic-gate	ret
4910Sstevel@tonic-gate	SET_SIZE(atomic_swap_uchar)
4920Sstevel@tonic-gate	SET_SIZE(atomic_swap_8)
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate	ENTRY(atomic_swap_16)
4950Sstevel@tonic-gate	ALTENTRY(atomic_swap_ushort)
4960Sstevel@tonic-gate	movzwl	%si, %eax
4970Sstevel@tonic-gate	lock
4980Sstevel@tonic-gate	xchgw %ax, (%rdi)
4990Sstevel@tonic-gate	ret
5000Sstevel@tonic-gate	SET_SIZE(atomic_swap_ushort)
5010Sstevel@tonic-gate	SET_SIZE(atomic_swap_16)
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate	ENTRY(atomic_swap_32)
5040Sstevel@tonic-gate	ALTENTRY(atomic_swap_uint)
5050Sstevel@tonic-gate	movl	%esi, %eax
5060Sstevel@tonic-gate	lock
5070Sstevel@tonic-gate	xchgl %eax, (%rdi)
5080Sstevel@tonic-gate	ret
5090Sstevel@tonic-gate	SET_SIZE(atomic_swap_uint)
5100Sstevel@tonic-gate	SET_SIZE(atomic_swap_32)
5110Sstevel@tonic-gate
5120Sstevel@tonic-gate	ENTRY(atomic_swap_64)
5130Sstevel@tonic-gate	ALTENTRY(atomic_swap_ulong)
5140Sstevel@tonic-gate	ALTENTRY(atomic_swap_ptr)
5150Sstevel@tonic-gate	movq	%rsi, %rax
5160Sstevel@tonic-gate	lock
5170Sstevel@tonic-gate	xchgq %rax, (%rdi)
5180Sstevel@tonic-gate	ret
5190Sstevel@tonic-gate	SET_SIZE(atomic_swap_ptr)
5200Sstevel@tonic-gate	SET_SIZE(atomic_swap_ulong)
5210Sstevel@tonic-gate	SET_SIZE(atomic_swap_64)
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate	ENTRY(atomic_set_long_excl)
5240Sstevel@tonic-gate	xorl	%eax, %eax
5250Sstevel@tonic-gate	lock
5260Sstevel@tonic-gate	btsq	%rsi, (%rdi)
5270Sstevel@tonic-gate	jnc	1f
5280Sstevel@tonic-gate	decl	%eax			/ return -1
5290Sstevel@tonic-gate1:
5300Sstevel@tonic-gate	ret
5310Sstevel@tonic-gate	SET_SIZE(atomic_set_long_excl)
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate	ENTRY(atomic_clear_long_excl)
5340Sstevel@tonic-gate	xorl	%eax, %eax
5350Sstevel@tonic-gate	lock
5360Sstevel@tonic-gate	btrq	%rsi, (%rdi)
5370Sstevel@tonic-gate	jc	1f
5380Sstevel@tonic-gate	decl	%eax			/ return -1
5390Sstevel@tonic-gate1:
5400Sstevel@tonic-gate	ret
5410Sstevel@tonic-gate	SET_SIZE(atomic_clear_long_excl)
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate#if !defined(_KERNEL)
5440Sstevel@tonic-gate
5454292Sab196087	/*
5464292Sab196087	 * NOTE: membar_enter, and membar_exit are identical routines.
5474292Sab196087	 * We define them separately, instead of using an ALTENTRY
5484292Sab196087	 * definitions to alias them together, so that DTrace and
5494292Sab196087	 * debuggers will see a unique address for them, allowing
5504292Sab196087	 * more accurate tracing.
5514292Sab196087	*/
5524292Sab196087
5530Sstevel@tonic-gate	ENTRY(membar_enter)
5544292Sab196087	mfence
5554292Sab196087	ret
5564292Sab196087	SET_SIZE(membar_enter)
5574292Sab196087
5584292Sab196087	ENTRY(membar_exit)
5590Sstevel@tonic-gate	mfence
5600Sstevel@tonic-gate	ret
5610Sstevel@tonic-gate	SET_SIZE(membar_exit)
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate	ENTRY(membar_producer)
5640Sstevel@tonic-gate	sfence
5650Sstevel@tonic-gate	ret
5660Sstevel@tonic-gate	SET_SIZE(membar_producer)
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate	ENTRY(membar_consumer)
5690Sstevel@tonic-gate	lfence
5700Sstevel@tonic-gate	ret
5710Sstevel@tonic-gate	SET_SIZE(membar_consumer)
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate#endif	/* !_KERNEL */
574