xref: /openbsd/sys/arch/mips64/include/atomic.h (revision 8932bfb7)
1 /*	$OpenBSD: atomic.h,v 1.7 2011/03/23 16:54:36 pirofti Exp $	*/
2 
3 /* Public Domain */
4 
5 #ifndef _MIPS64_ATOMIC_H_
6 #define _MIPS64_ATOMIC_H_
7 
8 #if defined(_KERNEL)
9 
10 /* wait until the bits to set are clear, and set them */
11 static __inline void
12 atomic_wait_and_setbits_int(__volatile unsigned int *uip, unsigned int v)
13 {
14 	unsigned int tmp0, tmp1;
15 
16 	__asm__ __volatile__ (
17 	"1:	ll	%0,	0(%2)\n"
18 	"	and	%1,	%0,	%3\n"
19 	"	bnez	%1,	1b\n"
20 	"	or	%0,	%3,	%0\n"
21 	"	sc	%0,	0(%2)\n"
22 	"	beqz	%0,	1b\n"
23 	"	 nop\n" :
24 		"=&r"(tmp0), "=&r"(tmp1) :
25 		"r"(uip), "r"(v) : "memory");
26 }
27 
28 static __inline void
29 atomic_setbits_int(__volatile unsigned int *uip, unsigned int v)
30 {
31 	unsigned int tmp;
32 
33 	__asm__ __volatile__ (
34 	"1:	ll	%0,	0(%1)\n"
35 	"	or	%0,	%2,	%0\n"
36 	"	sc	%0,	0(%1)\n"
37 	"	beqz	%0,	1b\n"
38 	"	 nop\n" :
39 		"=&r"(tmp) :
40 		"r"(uip), "r"(v) : "memory");
41 }
42 
43 static __inline void
44 atomic_clearbits_int(__volatile unsigned int *uip, unsigned int v)
45 {
46 	unsigned int tmp;
47 
48 	__asm__ __volatile__ (
49 	"1:	ll	%0,	0(%1)\n"
50 	"	and	%0,	%2,	%0\n"
51 	"	sc	%0,	0(%1)\n"
52 	"	beqz	%0,	1b\n"
53 	"	 nop\n" :
54 		"=&r"(tmp) :
55 		"r"(uip), "r"(~v) : "memory");
56 }
57 
58 static __inline void
59 atomic_add_int(__volatile unsigned int *uip, unsigned int v)
60 {
61 	unsigned int tmp;
62 
63 	__asm__ __volatile__ (
64 	"1:	ll	%0,	0(%1)\n"
65 	"	addu	%0,	%2,	%0\n"
66 	"	sc	%0,	0(%1)\n"
67 	"	beqz	%0,	1b\n"
68 	"	 nop\n" :
69 		"=&r"(tmp) :
70 		"r"(uip), "r"(v) : "memory");
71 }
72 static __inline void
73 atomic_add_uint64(__volatile uint64_t *uip, uint64_t v)
74 {
75 	uint64_t tmp;
76 
77 	__asm__ __volatile__ (
78 	"1:	lld	%0,	0(%1)\n"
79 	"	daddu	%0,	%2,	%0\n"
80 	"	scd	%0,	0(%1)\n"
81 	"	beqz	%0,	1b\n"
82 	"	 nop\n" :
83 		"=&r"(tmp) :
84 		"r"(uip), "r"(v) : "memory");
85 }
86 #endif /* defined(_KERNEL) */
87 #endif /* _MIPS64_ATOMIC_H_ */
88