xref: /haiku/src/system/libroot/os/arch/x86/atomic.S (revision b6f76ebe7153b94820cf35f8db4facc158841abb)
15af32e75SAxel Dörfler/*
2077c84ebSPawel Dziepak * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org.
3077c84ebSPawel Dziepak * Distributed under the terms of the MIT License.
4077c84ebSPawel Dziepak *
55af32e75SAxel Dörfler** Copyright 2003, Marcus Overhagen. All rights reserved.
6*b6f76ebeSAugustin Cavalier** Distributed under the terms of the MIT License.
75af32e75SAxel Dörfler**
85af32e75SAxel Dörfler** Copyright 2001, Travis Geiselbrecht. All rights reserved.
95af32e75SAxel Dörfler** Distributed under the terms of the NewOS License.
105af32e75SAxel Dörfler*/
115af32e75SAxel Dörfler
12077c84ebSPawel Dziepak
138cc14638SIngo Weinhold#include <asm_defs.h>
148cc14638SIngo Weinhold
155af32e75SAxel Dörfler
165af32e75SAxel Dörfler.text
175af32e75SAxel Dörfler
18077c84ebSPawel Dziepak
19077c84ebSPawel Dziepak/* void		atomic_set(int32* value, int32 newValue) */
205af32e75SAxel DörflerFUNCTION(atomic_set):
215af32e75SAxel Dörfler	movl		4(%esp), %edx
225af32e75SAxel Dörfler	movl		8(%esp), %eax
235af32e75SAxel Dörfler	lock
24077c84ebSPawel Dziepak	addl		$0, (%esp)
25077c84ebSPawel Dziepak	movl		%eax, (%edx)
265af32e75SAxel Dörfler	ret
278cc14638SIngo WeinholdFUNCTION_END(atomic_set)
285af32e75SAxel Dörfler
29077c84ebSPawel Dziepak
30077c84ebSPawel Dziepak/* int32	atomic_get_and_set(int32* value, int32 newValue) */
31077c84ebSPawel DziepakFUNCTION(atomic_get_and_set):
32077c84ebSPawel Dziepak	movl		4(%esp), %edx
33077c84ebSPawel Dziepak	movl		8(%esp), %eax
34077c84ebSPawel Dziepak	xchg		%eax, (%edx)
35077c84ebSPawel Dziepak	ret
36077c84ebSPawel DziepakFUNCTION_END(atomic_get_and_set)
37077c84ebSPawel Dziepak
38077c84ebSPawel Dziepak
39077c84ebSPawel Dziepak/* int32	atomic_test_and_set(int32* value, int32 newValue,
40077c84ebSPawel Dziepak	int32 testAgainst) */
415af32e75SAxel DörflerFUNCTION(atomic_test_and_set):
425af32e75SAxel Dörfler	movl		4(%esp), %edx
435af32e75SAxel Dörfler	movl		8(%esp), %ecx
445af32e75SAxel Dörfler	movl		12(%esp), %eax
455af32e75SAxel Dörfler	lock
465af32e75SAxel Dörfler	cmpxchgl	%ecx, (%edx)
475af32e75SAxel Dörfler	ret
488cc14638SIngo WeinholdFUNCTION_END(atomic_test_and_set)
495af32e75SAxel Dörfler
50077c84ebSPawel Dziepak
51077c84ebSPawel Dziepak/* int32	atomic_add(int32* value, int32 addValue) */
525af32e75SAxel DörflerFUNCTION(atomic_add):
535af32e75SAxel Dörfler	movl		4(%esp), %edx
545af32e75SAxel Dörfler	movl		8(%esp), %eax
555af32e75SAxel Dörfler	lock
565af32e75SAxel Dörfler	xaddl		%eax, (%edx)
575af32e75SAxel Dörfler	ret
588cc14638SIngo WeinholdFUNCTION_END(atomic_add)
595af32e75SAxel Dörfler
60077c84ebSPawel Dziepak
61077c84ebSPawel Dziepak/* int32	atomic_and(int32* value, int32 andValue) */
625af32e75SAxel DörflerFUNCTION(atomic_and):
635af32e75SAxel Dörfler	movl		4(%esp), %edx
64077c84ebSPawel Dziepak1:
655af32e75SAxel Dörfler	movl		8(%esp), %ecx
665af32e75SAxel Dörfler	movl		(%edx), %eax
675af32e75SAxel Dörfler	andl		%eax, %ecx
685af32e75SAxel Dörfler	lock
695af32e75SAxel Dörfler	cmpxchgl	%ecx, (%edx)
70077c84ebSPawel Dziepak	jnz			1b
715af32e75SAxel Dörfler	ret
728cc14638SIngo WeinholdFUNCTION_END(atomic_and)
735af32e75SAxel Dörfler
74077c84ebSPawel Dziepak
75077c84ebSPawel Dziepak/* int32	atomic_or(int32* value, int32 orValue) */
765af32e75SAxel DörflerFUNCTION(atomic_or):
775af32e75SAxel Dörfler	movl		4(%esp), %edx
78077c84ebSPawel Dziepak1:
795af32e75SAxel Dörfler	movl		8(%esp), %ecx
805af32e75SAxel Dörfler	movl		(%edx), %eax
815af32e75SAxel Dörfler	orl			%eax, %ecx
825af32e75SAxel Dörfler	lock
835af32e75SAxel Dörfler	cmpxchgl	%ecx, (%edx)
84077c84ebSPawel Dziepak	jnz			1b
855af32e75SAxel Dörfler	ret
868cc14638SIngo WeinholdFUNCTION_END(atomic_or)
875af32e75SAxel Dörfler
88077c84ebSPawel Dziepak
89077c84ebSPawel Dziepak/* int32	atomic_get(int32* value) */
905af32e75SAxel DörflerFUNCTION(atomic_get):
915af32e75SAxel Dörfler	movl		4(%esp), %edx
925af32e75SAxel Dörfler	movl		(%edx), %eax
935af32e75SAxel Dörfler	lock
94077c84ebSPawel Dziepak	addl		$0, (%esp)
955af32e75SAxel Dörfler	ret
968cc14638SIngo WeinholdFUNCTION_END(atomic_get)
975af32e75SAxel Dörfler
98077c84ebSPawel Dziepak
99077c84ebSPawel Dziepak/* void		atomic_set64(int64* value, int64 newValue) */
1005af32e75SAxel DörflerFUNCTION(atomic_set64):
101f711e9dcSIngo Weinhold	push		%esi
1025af32e75SAxel Dörfler	push		%ebx
103f711e9dcSIngo Weinhold	movl		12(%esp), %esi	/* value */
1045af32e75SAxel Dörfler	movl		16(%esp), %ebx	/* newValue low */
1055af32e75SAxel Dörfler	movl		20(%esp), %ecx	/* newValue high */
106077c84ebSPawel Dziepak1:
107f711e9dcSIngo Weinhold	movl		(%esi), %eax	/* testAgainst low */
108f711e9dcSIngo Weinhold	movl		4(%esi), %edx	/* testAgainst high */
1095af32e75SAxel Dörfler	lock
110f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
111077c84ebSPawel Dziepak	jnz			1b
1125af32e75SAxel Dörfler	pop			%ebx
113f711e9dcSIngo Weinhold	pop			%esi
1145af32e75SAxel Dörfler	ret
1158cc14638SIngo WeinholdFUNCTION_END(atomic_set64)
1165af32e75SAxel Dörfler
117077c84ebSPawel Dziepak
118077c84ebSPawel Dziepak/* void		atomic_get_and_set64(int64* value, int64 newValue) */
119077c84ebSPawel DziepakFUNCTION(atomic_get_and_set64):
120077c84ebSPawel Dziepak	push		%esi
121077c84ebSPawel Dziepak	push		%ebx
122077c84ebSPawel Dziepak	movl		12(%esp), %esi	/* value */
123077c84ebSPawel Dziepak	movl		16(%esp), %ebx	/* newValue low */
124077c84ebSPawel Dziepak	movl		20(%esp), %ecx	/* newValue high */
125077c84ebSPawel Dziepak1:
126077c84ebSPawel Dziepak	movl		(%esi), %eax	/* testAgainst low */
127077c84ebSPawel Dziepak	movl		4(%esi), %edx	/* testAgainst high */
128077c84ebSPawel Dziepak	lock
129077c84ebSPawel Dziepak	cmpxchg8b	(%esi)
130077c84ebSPawel Dziepak	jnz			1b
131077c84ebSPawel Dziepak	pop			%ebx
132077c84ebSPawel Dziepak	pop			%esi
133077c84ebSPawel Dziepak	ret
134077c84ebSPawel DziepakFUNCTION_END(atomic_get_and_set64)
135077c84ebSPawel Dziepak
136077c84ebSPawel Dziepak
137077c84ebSPawel Dziepak/* int64	atomic_test_and_set64(int64* value, int64 newValue,
138077c84ebSPawel Dziepak	int64 testAgainst) */
1395af32e75SAxel DörflerFUNCTION(atomic_test_and_set64):
140f711e9dcSIngo Weinhold	push		%esi
1415af32e75SAxel Dörfler	push		%ebx
142f711e9dcSIngo Weinhold	movl		12(%esp), %esi	/* value */
1435af32e75SAxel Dörfler	movl		16(%esp), %ebx	/* newValue low */
1445af32e75SAxel Dörfler	movl		20(%esp), %ecx	/* newValue high */
1455af32e75SAxel Dörfler	movl		24(%esp), %eax	/* testAgainst low */
1465af32e75SAxel Dörfler	movl		28(%esp), %edx	/* testAgainst high */
1475af32e75SAxel Dörfler	lock
148f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
1495af32e75SAxel Dörfler	pop			%ebx
150f711e9dcSIngo Weinhold	pop			%esi
1515af32e75SAxel Dörfler	ret
1528cc14638SIngo WeinholdFUNCTION_END(atomic_test_and_set64)
1535af32e75SAxel Dörfler
154077c84ebSPawel Dziepak
155077c84ebSPawel Dziepak/* int64	atomic_add64(int64* value, int64 addValue) */
1565af32e75SAxel DörflerFUNCTION(atomic_add64):
157f711e9dcSIngo Weinhold	push		%esi
1585af32e75SAxel Dörfler	push		%ebx
159f711e9dcSIngo Weinhold	movl		12(%esp), %esi
160077c84ebSPawel Dziepak1:
161f711e9dcSIngo Weinhold	movl		(%esi), %eax
162f711e9dcSIngo Weinhold	movl		4(%esi), %edx
1635af32e75SAxel Dörfler	movl		%eax, %ebx
1645af32e75SAxel Dörfler	movl		%edx, %ecx
1655af32e75SAxel Dörfler	addl		16(%esp), %ebx
1665af32e75SAxel Dörfler	adcl		20(%esp), %ecx
1675af32e75SAxel Dörfler	lock
168f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
169077c84ebSPawel Dziepak	jnz			1b
1705af32e75SAxel Dörfler	pop			%ebx
171f711e9dcSIngo Weinhold	pop			%esi
1725af32e75SAxel Dörfler	ret
1738cc14638SIngo WeinholdFUNCTION_END(atomic_add64)
1745af32e75SAxel Dörfler
175077c84ebSPawel Dziepak/* int64	atomic_and64(int64* value, int64 andValue) */
1765af32e75SAxel DörflerFUNCTION(atomic_and64):
177f711e9dcSIngo Weinhold	push		%esi
1785af32e75SAxel Dörfler	push		%ebx
179f711e9dcSIngo Weinhold	movl		12(%esp), %esi
180077c84ebSPawel Dziepak1:
181f711e9dcSIngo Weinhold	movl		(%esi), %eax
182f711e9dcSIngo Weinhold	movl		4(%esi), %edx
1835af32e75SAxel Dörfler	movl		%eax, %ebx
1845af32e75SAxel Dörfler	movl		%edx, %ecx
1855af32e75SAxel Dörfler	andl		16(%esp), %ebx
1865af32e75SAxel Dörfler	andl		20(%esp), %ecx
1875af32e75SAxel Dörfler	lock
188f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
189077c84ebSPawel Dziepak	jnz			1b
1905af32e75SAxel Dörfler	pop			%ebx
191f711e9dcSIngo Weinhold	pop			%esi
1925af32e75SAxel Dörfler	ret
1938cc14638SIngo WeinholdFUNCTION_END(atomic_and64)
1945af32e75SAxel Dörfler
195077c84ebSPawel Dziepak
196077c84ebSPawel Dziepak/* int64	atomic_or64(int64* value, int64 orValue) */
1975af32e75SAxel DörflerFUNCTION(atomic_or64):
198f711e9dcSIngo Weinhold	push		%esi
1995af32e75SAxel Dörfler	push		%ebx
200f711e9dcSIngo Weinhold	movl		12(%esp), %esi
201077c84ebSPawel Dziepak1:
202f711e9dcSIngo Weinhold	movl		(%esi), %eax
203f711e9dcSIngo Weinhold	movl		4(%esi), %edx
2045af32e75SAxel Dörfler	movl		%eax, %ebx
2055af32e75SAxel Dörfler	movl		%edx, %ecx
2065af32e75SAxel Dörfler	orl			16(%esp), %ebx
2075af32e75SAxel Dörfler	orl			20(%esp), %ecx
2085af32e75SAxel Dörfler	lock
209f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
210077c84ebSPawel Dziepak	jnz			1b
2115af32e75SAxel Dörfler	pop			%ebx
212f711e9dcSIngo Weinhold	pop			%esi
2135af32e75SAxel Dörfler	ret
2148cc14638SIngo WeinholdFUNCTION_END(atomic_or64)
2155af32e75SAxel Dörfler
216077c84ebSPawel Dziepak
217077c84ebSPawel Dziepak/* int64	atomic_get64(int64* value) */
2185af32e75SAxel DörflerFUNCTION(atomic_get64):
219f711e9dcSIngo Weinhold	push		%esi
2205af32e75SAxel Dörfler	push		%ebx
221f711e9dcSIngo Weinhold	movl		12(%esp), %esi
222077c84ebSPawel Dziepak1:
223f711e9dcSIngo Weinhold	movl		(%esi), %eax
224f711e9dcSIngo Weinhold	movl		4(%esi), %edx
2255af32e75SAxel Dörfler	movl		%eax, %ebx
2265af32e75SAxel Dörfler	movl		%edx, %ecx
2275af32e75SAxel Dörfler	lock
228f711e9dcSIngo Weinhold	cmpxchg8b	(%esi)
229077c84ebSPawel Dziepak	jnz			1b
2305af32e75SAxel Dörfler	pop			%ebx
231f711e9dcSIngo Weinhold	pop			%esi
2325af32e75SAxel Dörfler	ret
2338cc14638SIngo WeinholdFUNCTION_END(atomic_get64)
234077c84ebSPawel Dziepak
235