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 #endif /* __ASSEMBLY__ */
72 
73 #endif /* _ASM_TILE_CMPXCHG_H */
74