xref: /openbmc/linux/arch/sh/include/asm/cmpxchg-grb.h (revision 92a76f6d)
1 #ifndef __ASM_SH_CMPXCHG_GRB_H
2 #define __ASM_SH_CMPXCHG_GRB_H
3 
4 static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
5 {
6 	unsigned long retval;
7 
8 	__asm__ __volatile__ (
9 		"   .align 2              \n\t"
10 		"   mova    1f,   r0      \n\t" /* r0 = end point */
11 		"   nop                   \n\t"
12 		"   mov    r15,   r1      \n\t" /* r1 = saved sp */
13 		"   mov    #-4,   r15     \n\t" /* LOGIN */
14 		"   mov.l  @%1,   %0      \n\t" /* load  old value */
15 		"   mov.l   %2,   @%1     \n\t" /* store new value */
16 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
17 		: "=&r" (retval),
18 		  "+r"  (m),
19 		  "+r"  (val)		/* inhibit r15 overloading */
20 		:
21 		: "memory", "r0", "r1");
22 
23 	return retval;
24 }
25 
26 static inline unsigned long xchg_u16(volatile u16 *m, unsigned long val)
27 {
28 	unsigned long retval;
29 
30 	__asm__ __volatile__ (
31 		"   .align  2             \n\t"
32 		"   mova    1f,   r0      \n\t" /* r0 = end point */
33 		"   mov    r15,   r1      \n\t" /* r1 = saved sp */
34 		"   mov    #-6,   r15     \n\t" /* LOGIN */
35 		"   mov.w  @%1,   %0      \n\t" /* load  old value */
36 		"   extu.w  %0,   %0      \n\t" /* extend as unsigned */
37 		"   mov.w   %2,   @%1     \n\t" /* store new value */
38 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
39 		: "=&r" (retval),
40 		  "+r"  (m),
41 		  "+r"  (val)		/* inhibit r15 overloading */
42 		:
43 		: "memory" , "r0", "r1");
44 
45 	return retval;
46 }
47 
48 static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
49 {
50 	unsigned long retval;
51 
52 	__asm__ __volatile__ (
53 		"   .align  2             \n\t"
54 		"   mova    1f,   r0      \n\t" /* r0 = end point */
55 		"   mov    r15,   r1      \n\t" /* r1 = saved sp */
56 		"   mov    #-6,   r15     \n\t" /* LOGIN */
57 		"   mov.b  @%1,   %0      \n\t" /* load  old value */
58 		"   extu.b  %0,   %0      \n\t" /* extend as unsigned */
59 		"   mov.b   %2,   @%1     \n\t" /* store new value */
60 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
61 		: "=&r" (retval),
62 		  "+r"  (m),
63 		  "+r"  (val)		/* inhibit r15 overloading */
64 		:
65 		: "memory" , "r0", "r1");
66 
67 	return retval;
68 }
69 
70 static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
71 					  unsigned long new)
72 {
73 	unsigned long retval;
74 
75 	__asm__ __volatile__ (
76 		"   .align  2             \n\t"
77 		"   mova    1f,   r0      \n\t" /* r0 = end point */
78 		"   nop                   \n\t"
79 		"   mov    r15,   r1      \n\t" /* r1 = saved sp */
80 		"   mov    #-8,   r15     \n\t" /* LOGIN */
81 		"   mov.l  @%3,   %0      \n\t" /* load  old value */
82 		"   cmp/eq  %0,   %1      \n\t"
83 		"   bf            1f      \n\t" /* if not equal */
84 		"   mov.l   %2,   @%3     \n\t" /* store new value */
85 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
86 		: "=&r" (retval),
87 		  "+r"  (old), "+r"  (new) /* old or new can be r15 */
88 		:  "r"  (m)
89 		: "memory" , "r0", "r1", "t");
90 
91 	return retval;
92 }
93 
94 #endif /* __ASM_SH_CMPXCHG_GRB_H */
95