1da5bfbd8c61d135edda020c17724de4ab315ebe
[cascardo/linux.git] / arch / tile / include / asm / cmpxchg.h
1 /*
2  * cmpxchg.h -- forked from asm/atomic.h with this copyright:
3  *
4  * Copyright 2010 Tilera Corporation. All Rights Reserved.
5  *
6  *   This program is free software; you can redistribute it and/or
7  *   modify it under the terms of the GNU General Public License
8  *   as published by the Free Software Foundation, version 2.
9  *
10  *   This program is distributed in the hope that it will be useful, but
11  *   WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13  *   NON INFRINGEMENT.  See the GNU General Public License for
14  *   more details.
15  *
16  */
17
18 #ifndef _ASM_TILE_CMPXCHG_H
19 #define _ASM_TILE_CMPXCHG_H
20
21 #ifndef __ASSEMBLY__
22
23 /* Nonexistent functions intended to cause link errors. */
24 extern unsigned long __xchg_called_with_bad_pointer(void);
25 extern unsigned long __cmpxchg_called_with_bad_pointer(void);
26
27 #define xchg(ptr, x)                                                    \
28         ({                                                              \
29                 typeof(*(ptr)) __x;                                     \
30                 switch (sizeof(*(ptr))) {                               \
31                 case 4:                                                 \
32                         __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
33                                 (atomic_t *)(ptr),                      \
34                                 (u32)(typeof((x)-(x)))(x));             \
35                         break;                                          \
36                 case 8:                                                 \
37                         __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
38                                 (atomic64_t *)(ptr),                    \
39                                 (u64)(typeof((x)-(x)))(x));             \
40                         break;                                          \
41                 default:                                                \
42                         __xchg_called_with_bad_pointer();               \
43                 }                                                       \
44                 __x;                                                    \
45         })
46
47 #define cmpxchg(ptr, o, n)                                              \
48         ({                                                              \
49                 typeof(*(ptr)) __x;                                     \
50                 switch (sizeof(*(ptr))) {                               \
51                 case 4:                                                 \
52                         __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
53                                 (atomic_t *)(ptr),                      \
54                                 (u32)(typeof((o)-(o)))(o),              \
55                                 (u32)(typeof((n)-(n)))(n));             \
56                         break;                                          \
57                 case 8:                                                 \
58                         __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
59                                 (atomic64_t *)(ptr),                    \
60                                 (u64)(typeof((o)-(o)))(o),              \
61                                 (u64)(typeof((n)-(n)))(n));             \
62                         break;                                          \
63                 default:                                                \
64                         __cmpxchg_called_with_bad_pointer();            \
65                 }                                                       \
66                 __x;                                                    \
67         })
68
69 #define tas(ptr) (xchg((ptr), 1))
70
71 #define cmpxchg64(ptr, o, n)                                            \
72 ({                                                                      \
73         BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
74         cmpxchg((ptr), (o), (n));                                       \
75 })
76
77 #endif /* __ASSEMBLY__ */
78
79 #endif /* _ASM_TILE_CMPXCHG_H */