1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _ASM_ATOMIC_H
  28 #define _ASM_ATOMIC_H
  29 
  30 #include <sys/ccompile.h>
  31 #include <sys/types.h>
  32 
  33 #ifdef  __cplusplus
  34 extern "C" {
  35 #endif
  36 
  37 #if !defined(__lint) && defined(__GNUC__)
  38 
  39 #if defined(__amd64)
  40 
  41 extern __GNU_INLINE void
  42 atomic_or_long(ulong_t *target, ulong_t bits)
  43 {
  44         __asm__ __volatile__(
  45             "lock; orq %1, (%0)"
  46             : /* no output */
  47             : "r" (target), "r" (bits));
  48 }
  49 
  50 extern __GNU_INLINE void
  51 atomic_and_long(ulong_t *target, ulong_t bits)
  52 {
  53         __asm__ __volatile__(
  54             "lock; andq %1, (%0)"
  55             : /* no output */
  56             : "r" (target), "r" (bits));
  57 }
  58 
  59 #ifdef notdef
  60 extern __GNU_INLINE uint64_t
  61 cas64(uint64_t *target, uint64_t cmp,
  62         uint64_t newval)
  63 {
  64         uint64_t retval;
  65 
  66         __asm__ __volatile__(
  67             "movq %2, %%rax; lock; cmpxchgq %3, (%1)"
  68             : "=a" (retval)
  69             : "r" (target), "r" (cmp), "r" (newval));
  70         return (retval);
  71 }
  72 #endif
  73 
  74 #elif defined(__i386)
  75 
  76 extern __GNU_INLINE void
  77 atomic_or_long(ulong_t *target, ulong_t bits)
  78 {
  79         __asm__ __volatile__(
  80             "lock; orl %1, (%0)"
  81             : /* no output */
  82             : "r" (target), "r" (bits));
  83 }
  84 
  85 extern __GNU_INLINE void
  86 atomic_and_long(ulong_t *target, ulong_t bits)
  87 {
  88         __asm__ __volatile__(
  89             "lock; andl %1, (%0)"
  90             : /* no output */
  91             : "r" (target), "r" (bits));
  92 }
  93 
  94 #else
  95 #error  "port me"
  96 #endif
  97 
  98 #endif /* !__lint && __GNUC__ */
  99 
 100 #ifdef __cplusplus
 101 }
 102 #endif
 103 
 104 #endif  /* _ASM_ATOMIC_H */