Logo Search packages:      
Sourcecode: linux version File versions

atomic-grb.h

#ifndef __ASM_SH_ATOMIC_GRB_H
#define __ASM_SH_ATOMIC_GRB_H

static inline void atomic_add(int i, atomic_t *v)
{
      int tmp;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov    r15,   r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   add     %2,   %0      \n\t" /* add */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (i)
            : "memory" , "r0", "r1");
}

static inline void atomic_sub(int i, atomic_t *v)
{
      int tmp;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov     r15,  r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   sub     %2,   %0      \n\t" /* sub */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (i)
            : "memory" , "r0", "r1");
}

static inline int atomic_add_return(int i, atomic_t *v)
{
      int tmp;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov    r15,   r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   add     %2,   %0      \n\t" /* add */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (i)
            : "memory" , "r0", "r1");

      return tmp;
}

static inline int atomic_sub_return(int i, atomic_t *v)
{
      int tmp;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov    r15,   r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   sub     %2,   %0      \n\t" /* sub */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (i)
            : "memory", "r0", "r1");

      return tmp;
}

static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
{
      int tmp;
      unsigned int _mask = ~mask;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov    r15,   r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   and     %2,   %0      \n\t" /* add */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (_mask)
            : "memory" , "r0", "r1");
}

static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
{
      int tmp;

      __asm__ __volatile__ (
            "   .align 2              \n\t"
            "   mova    1f,   r0      \n\t" /* r0 = end point */
            "   mov    r15,   r1      \n\t" /* r1 = saved sp */
            "   mov    #-6,   r15     \n\t" /* LOGIN: r15 = size */
            "   mov.l  @%1,   %0      \n\t" /* load  old value */
            "   or      %2,   %0      \n\t" /* or */
            "   mov.l   %0,   @%1     \n\t" /* store new value */
            "1: mov     r1,   r15     \n\t" /* LOGOUT */
            : "=&r" (tmp),
              "+r"  (v)
            : "r"   (mask)
            : "memory" , "r0", "r1");
}

static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
      int ret;

      __asm__ __volatile__ (
            "   .align 2            \n\t"
            "   mova     1f,  r0    \n\t"
            "   nop                 \n\t"
            "   mov     r15,  r1    \n\t"
            "   mov    #-8,  r15    \n\t"
            "   mov.l   @%1,  %0    \n\t"
            "   cmp/eq   %2,  %0    \n\t"
            "   bf           1f           \n\t"
            "   mov.l    %3, @%1    \n\t"
            "1: mov      r1,  r15   \n\t"
            : "=&r" (ret)
            : "r" (v), "r" (old), "r" (new)
            : "memory" , "r0", "r1" , "t");

      return ret;
}

static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
      int ret;
      unsigned long tmp;

      __asm__ __volatile__ (
            "   .align 2            \n\t"
            "   mova    1f,   r0    \n\t"
            "   nop                 \n\t"
            "   mov    r15,   r1    \n\t"
            "   mov    #-12,  r15   \n\t"
            "   mov.l  @%2,   %1    \n\t"
            "   mov         %1,   %0    \n\t"
            "   cmp/eq  %4,   %0    \n\t"
            "   bt/s    1f          \n\t"
            "    add    %3,   %1    \n\t"
            "   mov.l   %1,  @%2    \n\t"
            "1: mov     r1,   r15   \n\t"
            : "=&r" (ret), "=&r" (tmp)
            : "r" (v), "r" (a), "r" (u)
            : "memory" , "r0", "r1" , "t");

      return ret != u;
}
#endif /* __ASM_SH_ATOMIC_GRB_H */

Generated by  Doxygen 1.6.0   Back to index