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