diff options
Diffstat (limited to 'arch/ia64/include/asm/intrinsics.h')
| -rw-r--r-- | arch/ia64/include/asm/intrinsics.h | 114 |
1 files changed, 1 insertions, 113 deletions
diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h index e4076b511829..d129e367e764 100644 --- a/arch/ia64/include/asm/intrinsics.h +++ b/arch/ia64/include/asm/intrinsics.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #else | 18 | #else |
| 19 | # include <asm/gcc_intrin.h> | 19 | # include <asm/gcc_intrin.h> |
| 20 | #endif | 20 | #endif |
| 21 | #include <asm/cmpxchg.h> | ||
| 21 | 22 | ||
| 22 | #define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I) | 23 | #define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I) |
| 23 | 24 | ||
| @@ -81,119 +82,6 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); | |||
| 81 | 82 | ||
| 82 | #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ | 83 | #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ |
| 83 | 84 | ||
| 84 | /* | ||
| 85 | * This function doesn't exist, so you'll get a linker error if | ||
| 86 | * something tries to do an invalid xchg(). | ||
| 87 | */ | ||
| 88 | extern void ia64_xchg_called_with_bad_pointer (void); | ||
| 89 | |||
| 90 | #define __xchg(x,ptr,size) \ | ||
| 91 | ({ \ | ||
| 92 | unsigned long __xchg_result; \ | ||
| 93 | \ | ||
| 94 | switch (size) { \ | ||
| 95 | case 1: \ | ||
| 96 | __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ | ||
| 97 | break; \ | ||
| 98 | \ | ||
| 99 | case 2: \ | ||
| 100 | __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ | ||
| 101 | break; \ | ||
| 102 | \ | ||
| 103 | case 4: \ | ||
| 104 | __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ | ||
| 105 | break; \ | ||
| 106 | \ | ||
| 107 | case 8: \ | ||
| 108 | __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ | ||
| 109 | break; \ | ||
| 110 | default: \ | ||
| 111 | ia64_xchg_called_with_bad_pointer(); \ | ||
| 112 | } \ | ||
| 113 | __xchg_result; \ | ||
| 114 | }) | ||
| 115 | |||
| 116 | #define xchg(ptr,x) \ | ||
| 117 | ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr)))) | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
| 121 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
| 122 | * indicated by comparing RETURN with OLD. | ||
| 123 | */ | ||
| 124 | |||
| 125 | #define __HAVE_ARCH_CMPXCHG 1 | ||
| 126 | |||
| 127 | /* | ||
| 128 | * This function doesn't exist, so you'll get a linker error | ||
| 129 | * if something tries to do an invalid cmpxchg(). | ||
| 130 | */ | ||
| 131 | extern long ia64_cmpxchg_called_with_bad_pointer (void); | ||
| 132 | |||
| 133 | #define ia64_cmpxchg(sem,ptr,old,new,size) \ | ||
| 134 | ({ \ | ||
| 135 | __u64 _o_, _r_; \ | ||
| 136 | \ | ||
| 137 | switch (size) { \ | ||
| 138 | case 1: _o_ = (__u8 ) (long) (old); break; \ | ||
| 139 | case 2: _o_ = (__u16) (long) (old); break; \ | ||
| 140 | case 4: _o_ = (__u32) (long) (old); break; \ | ||
| 141 | case 8: _o_ = (__u64) (long) (old); break; \ | ||
| 142 | default: break; \ | ||
| 143 | } \ | ||
| 144 | switch (size) { \ | ||
| 145 | case 1: \ | ||
| 146 | _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ | ||
| 147 | break; \ | ||
| 148 | \ | ||
| 149 | case 2: \ | ||
| 150 | _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ | ||
| 151 | break; \ | ||
| 152 | \ | ||
| 153 | case 4: \ | ||
| 154 | _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ | ||
| 155 | break; \ | ||
| 156 | \ | ||
| 157 | case 8: \ | ||
| 158 | _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ | ||
| 159 | break; \ | ||
| 160 | \ | ||
| 161 | default: \ | ||
| 162 | _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ | ||
| 163 | break; \ | ||
| 164 | } \ | ||
| 165 | (__typeof__(old)) _r_; \ | ||
| 166 | }) | ||
| 167 | |||
| 168 | #define cmpxchg_acq(ptr, o, n) \ | ||
| 169 | ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) | ||
| 170 | #define cmpxchg_rel(ptr, o, n) \ | ||
| 171 | ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) | ||
| 172 | |||
| 173 | /* for compatibility with other platforms: */ | ||
| 174 | #define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) | ||
| 175 | #define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) | ||
| 176 | |||
| 177 | #define cmpxchg_local cmpxchg | ||
| 178 | #define cmpxchg64_local cmpxchg64 | ||
| 179 | |||
| 180 | #ifdef CONFIG_IA64_DEBUG_CMPXCHG | ||
| 181 | # define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; | ||
| 182 | # define CMPXCHG_BUGCHECK(v) \ | ||
| 183 | do { \ | ||
| 184 | if (_cmpxchg_bugcheck_count-- <= 0) { \ | ||
| 185 | void *ip; \ | ||
| 186 | extern int printk(const char *fmt, ...); \ | ||
| 187 | ip = (void *) ia64_getreg(_IA64_REG_IP); \ | ||
| 188 | printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \ | ||
| 189 | break; \ | ||
| 190 | } \ | ||
| 191 | } while (0) | ||
| 192 | #else /* !CONFIG_IA64_DEBUG_CMPXCHG */ | ||
| 193 | # define CMPXCHG_BUGCHECK_DECL | ||
| 194 | # define CMPXCHG_BUGCHECK(v) | ||
| 195 | #endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ | ||
| 196 | |||
| 197 | #endif | 85 | #endif |
| 198 | 86 | ||
| 199 | #ifdef __KERNEL__ | 87 | #ifdef __KERNEL__ |
