18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __ASM_SH_BITOPS_GRB_H
38c2ecf20Sopenharmony_ci#define __ASM_SH_BITOPS_GRB_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_cistatic inline void set_bit(int nr, volatile void * addr)
68c2ecf20Sopenharmony_ci{
78c2ecf20Sopenharmony_ci	int	mask;
88c2ecf20Sopenharmony_ci	volatile unsigned int *a = addr;
98c2ecf20Sopenharmony_ci	unsigned long tmp;
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci	a += nr >> 5;
128c2ecf20Sopenharmony_ci	mask = 1 << (nr & 0x1f);
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
158c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
168c2ecf20Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
178c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
188c2ecf20Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
198c2ecf20Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
208c2ecf20Sopenharmony_ci                "   or      %2,   %0      \n\t" /* or */
218c2ecf20Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
228c2ecf20Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
238c2ecf20Sopenharmony_ci                : "=&r" (tmp),
248c2ecf20Sopenharmony_ci                  "+r"  (a)
258c2ecf20Sopenharmony_ci                : "r"   (mask)
268c2ecf20Sopenharmony_ci                : "memory" , "r0", "r1");
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic inline void clear_bit(int nr, volatile void * addr)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	int	mask;
328c2ecf20Sopenharmony_ci	volatile unsigned int *a = addr;
338c2ecf20Sopenharmony_ci        unsigned long tmp;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	a += nr >> 5;
368c2ecf20Sopenharmony_ci        mask = ~(1 << (nr & 0x1f));
378c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
388c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
398c2ecf20Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
408c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
418c2ecf20Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
428c2ecf20Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
438c2ecf20Sopenharmony_ci                "   and     %2,   %0      \n\t" /* and */
448c2ecf20Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
458c2ecf20Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
468c2ecf20Sopenharmony_ci                : "=&r" (tmp),
478c2ecf20Sopenharmony_ci                  "+r"  (a)
488c2ecf20Sopenharmony_ci                : "r"   (mask)
498c2ecf20Sopenharmony_ci                : "memory" , "r0", "r1");
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic inline void change_bit(int nr, volatile void * addr)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci        int     mask;
558c2ecf20Sopenharmony_ci        volatile unsigned int *a = addr;
568c2ecf20Sopenharmony_ci        unsigned long tmp;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci        a += nr >> 5;
598c2ecf20Sopenharmony_ci        mask = 1 << (nr & 0x1f);
608c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
618c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
628c2ecf20Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
638c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
648c2ecf20Sopenharmony_ci                "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
658c2ecf20Sopenharmony_ci                "   mov.l  @%1,   %0      \n\t" /* load  old value */
668c2ecf20Sopenharmony_ci                "   xor     %2,   %0      \n\t" /* xor */
678c2ecf20Sopenharmony_ci                "   mov.l   %0,   @%1     \n\t" /* store new value */
688c2ecf20Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
698c2ecf20Sopenharmony_ci                : "=&r" (tmp),
708c2ecf20Sopenharmony_ci                  "+r"  (a)
718c2ecf20Sopenharmony_ci                : "r"   (mask)
728c2ecf20Sopenharmony_ci                : "memory" , "r0", "r1");
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic inline int test_and_set_bit(int nr, volatile void * addr)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci        int     mask, retval;
788c2ecf20Sopenharmony_ci	volatile unsigned int *a = addr;
798c2ecf20Sopenharmony_ci        unsigned long tmp;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	a += nr >> 5;
828c2ecf20Sopenharmony_ci	mask = 1 << (nr & 0x1f);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
858c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
868c2ecf20Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
878c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
888c2ecf20Sopenharmony_ci                "   mov   #-14,   r15     \n\t" /* LOGIN: r15 = size */
898c2ecf20Sopenharmony_ci                "   mov.l  @%2,   %0      \n\t" /* load old value */
908c2ecf20Sopenharmony_ci                "   mov     %0,   %1      \n\t"
918c2ecf20Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
928c2ecf20Sopenharmony_ci                "   mov    #-1,   %1      \n\t" /* retvat = -1 */
938c2ecf20Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
948c2ecf20Sopenharmony_ci                "   or      %3,   %0      \n\t"
958c2ecf20Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
968c2ecf20Sopenharmony_ci                "1: mov     r1,  r15      \n\t" /* LOGOUT */
978c2ecf20Sopenharmony_ci                : "=&r" (tmp),
988c2ecf20Sopenharmony_ci                  "=&r" (retval),
998c2ecf20Sopenharmony_ci                  "+r"  (a)
1008c2ecf20Sopenharmony_ci                : "r"   (mask)
1018c2ecf20Sopenharmony_ci                : "memory" , "r0", "r1" ,"t");
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci        return retval;
1048c2ecf20Sopenharmony_ci}
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic inline int test_and_clear_bit(int nr, volatile void * addr)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci        int     mask, retval,not_mask;
1098c2ecf20Sopenharmony_ci        volatile unsigned int *a = addr;
1108c2ecf20Sopenharmony_ci        unsigned long tmp;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci        a += nr >> 5;
1138c2ecf20Sopenharmony_ci        mask = 1 << (nr & 0x1f);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	not_mask = ~mask;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
1188c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
1198c2ecf20Sopenharmony_ci		"   mova    1f,   r0      \n\t" /* r0 = end point */
1208c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
1218c2ecf20Sopenharmony_ci		"   mov   #-14,   r15     \n\t" /* LOGIN */
1228c2ecf20Sopenharmony_ci		"   mov.l  @%2,   %0      \n\t" /* load old value */
1238c2ecf20Sopenharmony_ci                "   mov     %0,   %1      \n\t" /* %1 = *a */
1248c2ecf20Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
1258c2ecf20Sopenharmony_ci		"   mov    #-1,   %1      \n\t" /* retvat = -1 */
1268c2ecf20Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
1278c2ecf20Sopenharmony_ci                "   and     %4,   %0      \n\t"
1288c2ecf20Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
1298c2ecf20Sopenharmony_ci		"1: mov     r1,   r15     \n\t" /* LOGOUT */
1308c2ecf20Sopenharmony_ci		: "=&r" (tmp),
1318c2ecf20Sopenharmony_ci		  "=&r" (retval),
1328c2ecf20Sopenharmony_ci		  "+r"  (a)
1338c2ecf20Sopenharmony_ci		: "r"   (mask),
1348c2ecf20Sopenharmony_ci		  "r"   (not_mask)
1358c2ecf20Sopenharmony_ci		: "memory" , "r0", "r1", "t");
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci        return retval;
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic inline int test_and_change_bit(int nr, volatile void * addr)
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci        int     mask, retval;
1438c2ecf20Sopenharmony_ci        volatile unsigned int *a = addr;
1448c2ecf20Sopenharmony_ci        unsigned long tmp;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci        a += nr >> 5;
1478c2ecf20Sopenharmony_ci        mask = 1 << (nr & 0x1f);
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci        __asm__ __volatile__ (
1508c2ecf20Sopenharmony_ci                "   .align 2              \n\t"
1518c2ecf20Sopenharmony_ci                "   mova    1f,   r0      \n\t" /* r0 = end point */
1528c2ecf20Sopenharmony_ci                "   mov    r15,   r1      \n\t" /* r1 = saved sp */
1538c2ecf20Sopenharmony_ci                "   mov   #-14,   r15     \n\t" /* LOGIN */
1548c2ecf20Sopenharmony_ci                "   mov.l  @%2,   %0      \n\t" /* load old value */
1558c2ecf20Sopenharmony_ci                "   mov     %0,   %1      \n\t" /* %1 = *a */
1568c2ecf20Sopenharmony_ci                "   tst     %1,   %3      \n\t" /* T = ((*a & mask) == 0) */
1578c2ecf20Sopenharmony_ci                "   mov    #-1,   %1      \n\t" /* retvat = -1 */
1588c2ecf20Sopenharmony_ci                "   negc    %1,   %1      \n\t" /* retval = (mask & *a) != 0 */
1598c2ecf20Sopenharmony_ci                "   xor     %3,   %0      \n\t"
1608c2ecf20Sopenharmony_ci                "   mov.l   %0,  @%2      \n\t" /* store new value */
1618c2ecf20Sopenharmony_ci                "1: mov     r1,   r15     \n\t" /* LOGOUT */
1628c2ecf20Sopenharmony_ci                : "=&r" (tmp),
1638c2ecf20Sopenharmony_ci                  "=&r" (retval),
1648c2ecf20Sopenharmony_ci                  "+r"  (a)
1658c2ecf20Sopenharmony_ci                : "r"   (mask)
1668c2ecf20Sopenharmony_ci                : "memory" , "r0", "r1", "t");
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci        return retval;
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci#include <asm-generic/bitops/non-atomic.h>
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci#endif /* __ASM_SH_BITOPS_GRB_H */
174