162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_SH_BITOPS_GRB_H
362306a36Sopenharmony_ci#define __ASM_SH_BITOPS_GRB_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_cistatic inline void set_bit(int nr, volatile void * addr)
662306a36Sopenharmony_ci{
762306a36Sopenharmony_ci	int	mask;
862306a36Sopenharmony_ci	volatile unsigned int *a = addr;
962306a36Sopenharmony_ci	unsigned long tmp;
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci	a += nr >> 5;
1262306a36Sopenharmony_ci	mask = 1 << (nr & 0x1f);
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci        __asm__ __volatile__ (
1562306a36Sopenharmony_ci                "   .align 2              \n\t"
1662306a36Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
1762306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
1862306a36Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
1962306a36Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
2062306a36Sopenharmony_ci                "   or      %2,   %0      \n\t" /* or */
2162306a36Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
2262306a36Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
2362306a36Sopenharmony_ci                : "=&r" (tmp),
2462306a36Sopenharmony_ci                  "+r"  (a)
2562306a36Sopenharmony_ci                : "r"   (mask)
2662306a36Sopenharmony_ci                : "memory" , "r0", "r1");
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline void clear_bit(int nr, volatile void * addr)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	int	mask;
3262306a36Sopenharmony_ci	volatile unsigned int *a = addr;
3362306a36Sopenharmony_ci        unsigned long tmp;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	a += nr >> 5;
3662306a36Sopenharmony_ci        mask = ~(1 << (nr & 0x1f));
3762306a36Sopenharmony_ci        __asm__ __volatile__ (
3862306a36Sopenharmony_ci                "   .align 2              \n\t"
3962306a36Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
4062306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
4162306a36Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
4262306a36Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
4362306a36Sopenharmony_ci                "   and     %2,   %0      \n\t" /* and */
4462306a36Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
4562306a36Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
4662306a36Sopenharmony_ci                : "=&r" (tmp),
4762306a36Sopenharmony_ci                  "+r"  (a)
4862306a36Sopenharmony_ci                : "r"   (mask)
4962306a36Sopenharmony_ci                : "memory" , "r0", "r1");
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic inline void change_bit(int nr, volatile void * addr)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci        int     mask;
5562306a36Sopenharmony_ci        volatile unsigned int *a = addr;
5662306a36Sopenharmony_ci        unsigned long tmp;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci        a += nr >> 5;
5962306a36Sopenharmony_ci        mask = 1 << (nr & 0x1f);
6062306a36Sopenharmony_ci        __asm__ __volatile__ (
6162306a36Sopenharmony_ci                "   .align 2              \n\t"
6262306a36Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
6362306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
6462306a36Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
6562306a36Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
6662306a36Sopenharmony_ci                "   xor     %2,   %0      \n\t" /* xor */
6762306a36Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
6862306a36Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
6962306a36Sopenharmony_ci                : "=&r" (tmp),
7062306a36Sopenharmony_ci                  "+r"  (a)
7162306a36Sopenharmony_ci                : "r"   (mask)
7262306a36Sopenharmony_ci                : "memory" , "r0", "r1");
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic inline int test_and_set_bit(int nr, volatile void * addr)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci        int     mask, retval;
7862306a36Sopenharmony_ci	volatile unsigned int *a = addr;
7962306a36Sopenharmony_ci        unsigned long tmp;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	a += nr >> 5;
8262306a36Sopenharmony_ci	mask = 1 << (nr & 0x1f);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci        __asm__ __volatile__ (
8562306a36Sopenharmony_ci                "   .align 2              \n\t"
8662306a36Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
8762306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
8862306a36Sopenharmony_ci                "   mov   #-14,   r15     \n\t" /* LOGIN: r15 = size */
8962306a36Sopenharmony_ci                "   mov.l  @%2,   %0      \n\t" /* load old value */
9062306a36Sopenharmony_ci                "   mov     %0,   %1      \n\t"
9162306a36Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
9262306a36Sopenharmony_ci                "   mov    #-1,   %1      \n\t" /* retvat = -1 */
9362306a36Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
9462306a36Sopenharmony_ci                "   or      %3,   %0      \n\t"
9562306a36Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
9662306a36Sopenharmony_ci                "1: mov     r1,  r15      \n\t" /* LOGOUT */
9762306a36Sopenharmony_ci                : "=&r" (tmp),
9862306a36Sopenharmony_ci                  "=&r" (retval),
9962306a36Sopenharmony_ci                  "+r"  (a)
10062306a36Sopenharmony_ci                : "r"   (mask)
10162306a36Sopenharmony_ci                : "memory" , "r0", "r1" ,"t");
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci        return retval;
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic inline int test_and_clear_bit(int nr, volatile void * addr)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci        int     mask, retval,not_mask;
10962306a36Sopenharmony_ci        volatile unsigned int *a = addr;
11062306a36Sopenharmony_ci        unsigned long tmp;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci        a += nr >> 5;
11362306a36Sopenharmony_ci        mask = 1 << (nr & 0x1f);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	not_mask = ~mask;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci        __asm__ __volatile__ (
11862306a36Sopenharmony_ci                "   .align 2              \n\t"
11962306a36Sopenharmony_ci		"   mova    1f,   r0      \n\t" /* r0 = end point */
12062306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
12162306a36Sopenharmony_ci		"   mov   #-14,   r15     \n\t" /* LOGIN */
12262306a36Sopenharmony_ci		"   mov.l  @%2,   %0      \n\t" /* load old value */
12362306a36Sopenharmony_ci                "   mov     %0,   %1      \n\t" /* %1 = *a */
12462306a36Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
12562306a36Sopenharmony_ci		"   mov    #-1,   %1      \n\t" /* retvat = -1 */
12662306a36Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
12762306a36Sopenharmony_ci                "   and     %4,   %0      \n\t"
12862306a36Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
12962306a36Sopenharmony_ci		"1: mov     r1,   r15     \n\t" /* LOGOUT */
13062306a36Sopenharmony_ci		: "=&r" (tmp),
13162306a36Sopenharmony_ci		  "=&r" (retval),
13262306a36Sopenharmony_ci		  "+r"  (a)
13362306a36Sopenharmony_ci		: "r"   (mask),
13462306a36Sopenharmony_ci		  "r"   (not_mask)
13562306a36Sopenharmony_ci		: "memory" , "r0", "r1", "t");
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci        return retval;
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic inline int test_and_change_bit(int nr, volatile void * addr)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci        int     mask, retval;
14362306a36Sopenharmony_ci        volatile unsigned int *a = addr;
14462306a36Sopenharmony_ci        unsigned long tmp;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci        a += nr >> 5;
14762306a36Sopenharmony_ci        mask = 1 << (nr & 0x1f);
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci        __asm__ __volatile__ (
15062306a36Sopenharmony_ci                "   .align 2              \n\t"
15162306a36Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
15262306a36Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
15362306a36Sopenharmony_ci                "   mov   #-14,   r15     \n\t" /* LOGIN */
15462306a36Sopenharmony_ci                "   mov.l  @%2,   %0      \n\t" /* load old value */
15562306a36Sopenharmony_ci                "   mov     %0,   %1      \n\t" /* %1 = *a */
15662306a36Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
15762306a36Sopenharmony_ci                "   mov    #-1,   %1      \n\t" /* retvat = -1 */
15862306a36Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
15962306a36Sopenharmony_ci                "   xor     %3,   %0      \n\t"
16062306a36Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
16162306a36Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
16262306a36Sopenharmony_ci                : "=&r" (tmp),
16362306a36Sopenharmony_ci                  "=&r" (retval),
16462306a36Sopenharmony_ci                  "+r"  (a)
16562306a36Sopenharmony_ci                : "r"   (mask)
16662306a36Sopenharmony_ci                : "memory" , "r0", "r1", "t");
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci        return retval;
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#include <asm-generic/bitops/non-atomic.h>
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci#endif /* __ASM_SH_BITOPS_GRB_H */
174