xref: /openbmc/linux/arch/sh/include/asm/bitops-grb.h (revision 3cf3cdea)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SH_BITOPS_GRB_H
3 #define __ASM_SH_BITOPS_GRB_H
4 
5 static inline void set_bit(int nr, volatile void * addr)
6 {
7 	int	mask;
8 	volatile unsigned int *a = addr;
9 	unsigned long tmp;
10 
11 	a += nr >> 5;
12 	mask = 1 << (nr & 0x1f);
13 
14         __asm__ __volatile__ (
15                 "   .align 2              \n\t"
16                 "   mova    1f,   r0      \n\t" /* r0 = end point */
17                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
18                 "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
19                 "   mov.l  @%1,   %0      \n\t" /* load  old value */
20                 "   or      %2,   %0      \n\t" /* or */
21                 "   mov.l   %0,   @%1     \n\t" /* store new value */
22                 "1: mov     r1,   r15     \n\t" /* LOGOUT */
23                 : "=&r" (tmp),
24                   "+r"  (a)
25                 : "r"   (mask)
26                 : "memory" , "r0", "r1");
27 }
28 
29 static inline void clear_bit(int nr, volatile void * addr)
30 {
31 	int	mask;
32 	volatile unsigned int *a = addr;
33         unsigned long tmp;
34 
35 	a += nr >> 5;
36         mask = ~(1 << (nr & 0x1f));
37         __asm__ __volatile__ (
38                 "   .align 2              \n\t"
39                 "   mova    1f,   r0      \n\t" /* r0 = end point */
40                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
41                 "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
42                 "   mov.l  @%1,   %0      \n\t" /* load  old value */
43                 "   and     %2,   %0      \n\t" /* and */
44                 "   mov.l   %0,   @%1     \n\t" /* store new value */
45                 "1: mov     r1,   r15     \n\t" /* LOGOUT */
46                 : "=&r" (tmp),
47                   "+r"  (a)
48                 : "r"   (mask)
49                 : "memory" , "r0", "r1");
50 }
51 
52 static inline void change_bit(int nr, volatile void * addr)
53 {
54         int     mask;
55         volatile unsigned int *a = addr;
56         unsigned long tmp;
57 
58         a += nr >> 5;
59         mask = 1 << (nr & 0x1f);
60         __asm__ __volatile__ (
61                 "   .align 2              \n\t"
62                 "   mova    1f,   r0      \n\t" /* r0 = end point */
63                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
64                 "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
65                 "   mov.l  @%1,   %0      \n\t" /* load  old value */
66                 "   xor     %2,   %0      \n\t" /* xor */
67                 "   mov.l   %0,   @%1     \n\t" /* store new value */
68                 "1: mov     r1,   r15     \n\t" /* LOGOUT */
69                 : "=&r" (tmp),
70                   "+r"  (a)
71                 : "r"   (mask)
72                 : "memory" , "r0", "r1");
73 }
74 
75 static inline int test_and_set_bit(int nr, volatile void * addr)
76 {
77         int     mask, retval;
78 	volatile unsigned int *a = addr;
79         unsigned long tmp;
80 
81 	a += nr >> 5;
82 	mask = 1 << (nr & 0x1f);
83 
84         __asm__ __volatile__ (
85                 "   .align 2              \n\t"
86                 "   mova    1f,   r0      \n\t" /* r0 = end point */
87                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
88                 "   mov   #-14,   r15     \n\t" /* LOGIN: r15 = size */
89                 "   mov.l  @%2,   %0      \n\t" /* load old value */
90                 "   mov     %0,   %1      \n\t"
91                 "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
92                 "   mov    #-1,   %1      \n\t" /* retvat = -1 */
93                 "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
94                 "   or      %3,   %0      \n\t"
95                 "   mov.l   %0,  @%2      \n\t" /* store new value */
96                 "1: mov     r1,  r15      \n\t" /* LOGOUT */
97                 : "=&r" (tmp),
98                   "=&r" (retval),
99                   "+r"  (a)
100                 : "r"   (mask)
101                 : "memory" , "r0", "r1" ,"t");
102 
103         return retval;
104 }
105 
106 static inline int test_and_clear_bit(int nr, volatile void * addr)
107 {
108         int     mask, retval,not_mask;
109         volatile unsigned int *a = addr;
110         unsigned long tmp;
111 
112         a += nr >> 5;
113         mask = 1 << (nr & 0x1f);
114 
115 	not_mask = ~mask;
116 
117         __asm__ __volatile__ (
118                 "   .align 2              \n\t"
119 		"   mova    1f,   r0      \n\t" /* r0 = end point */
120                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
121 		"   mov   #-14,   r15     \n\t" /* LOGIN */
122 		"   mov.l  @%2,   %0      \n\t" /* load old value */
123                 "   mov     %0,   %1      \n\t" /* %1 = *a */
124                 "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
125 		"   mov    #-1,   %1      \n\t" /* retvat = -1 */
126                 "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
127                 "   and     %4,   %0      \n\t"
128                 "   mov.l   %0,  @%2      \n\t" /* store new value */
129 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
130 		: "=&r" (tmp),
131 		  "=&r" (retval),
132 		  "+r"  (a)
133 		: "r"   (mask),
134 		  "r"   (not_mask)
135 		: "memory" , "r0", "r1", "t");
136 
137         return retval;
138 }
139 
140 static inline int test_and_change_bit(int nr, volatile void * addr)
141 {
142         int     mask, retval;
143         volatile unsigned int *a = addr;
144         unsigned long tmp;
145 
146         a += nr >> 5;
147         mask = 1 << (nr & 0x1f);
148 
149         __asm__ __volatile__ (
150                 "   .align 2              \n\t"
151                 "   mova    1f,   r0      \n\t" /* r0 = end point */
152                 "   mov    r15,   r1      \n\t" /* r1 = saved sp */
153                 "   mov   #-14,   r15     \n\t" /* LOGIN */
154                 "   mov.l  @%2,   %0      \n\t" /* load old value */
155                 "   mov     %0,   %1      \n\t" /* %1 = *a */
156                 "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
157                 "   mov    #-1,   %1      \n\t" /* retvat = -1 */
158                 "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
159                 "   xor     %3,   %0      \n\t"
160                 "   mov.l   %0,  @%2      \n\t" /* store new value */
161                 "1: mov     r1,   r15     \n\t" /* LOGOUT */
162                 : "=&r" (tmp),
163                   "=&r" (retval),
164                   "+r"  (a)
165                 : "r"   (mask)
166                 : "memory" , "r0", "r1", "t");
167 
168         return retval;
169 }
170 
171 #include <asm-generic/bitops/non-atomic.h>
172 
173 #endif /* __ASM_SH_BITOPS_GRB_H */
174