#include <linux/kernel.h>
-static __inline__ int atomic_add_return(int i, atomic_t *v)
+static inline int atomic_add_return(int i, atomic_t *v)
{
- unsigned long flags;
+ unsigned short ccr;
int ret;
- local_irq_save(flags);
- ret = v->counter += i;
- local_irq_restore(flags);
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "add.l %3,%0\n\t"
+ "mov.l %0,%1\n\t"
+ "ldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr)
+ : "ri"(i));
return ret;
}
#define atomic_add(i, v) atomic_add_return(i, v)
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-static __inline__ int atomic_sub_return(int i, atomic_t *v)
+static inline int atomic_sub_return(int i, atomic_t *v)
{
- unsigned long flags;
+ unsigned short ccr;
int ret;
- local_irq_save(flags);
- ret = v->counter -= i;
- local_irq_restore(flags);
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "sub.l %3,%0\n\t"
+ "mov.l %0,%1\n\t"
+ "ldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr)
+ : "ri"(i));
return ret;
}
#define atomic_sub(i, v) atomic_sub_return(i, v)
-#define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0)
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
-static __inline__ int atomic_inc_return(atomic_t *v)
+static inline int atomic_inc_return(atomic_t *v)
{
- unsigned long flags;
+ unsigned short ccr;
int ret;
- local_irq_save(flags);
- v->counter++;
- ret = v->counter;
- local_irq_restore(flags);
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "inc.l #1,%0\n\t"
+ "mov.l %0,%1\n\t"
+ "ldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr));
return ret;
}
*/
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-static __inline__ int atomic_dec_return(atomic_t *v)
+static inline int atomic_dec_return(atomic_t *v)
{
- unsigned long flags;
+ unsigned short ccr;
int ret;
- local_irq_save(flags);
- --v->counter;
- ret = v->counter;
- local_irq_restore(flags);
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "dec.l #1,%0\n\t"
+ "mov.l %0,%1\n\t"
+ "ldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr));
return ret;
}
#define atomic_dec(v) atomic_dec_return(v)
-static __inline__ int atomic_dec_and_test(atomic_t *v)
+static inline int atomic_dec_and_test(atomic_t *v)
{
- unsigned long flags;
+ unsigned short ccr;
int ret;
- local_irq_save(flags);
- --v->counter;
- ret = v->counter;
- local_irq_restore(flags);
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "dec.l #1,%0\n\t"
+ "mov.l %0,%1\n\t"
+ "ldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr));
return ret == 0;
}
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (likely(ret == old))
- v->counter = new;
- local_irq_restore(flags);
+ unsigned short ccr;
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "cmp.l %3,%0\n\t"
+ "bne 1f\n\t"
+ "mov.l %4,%1\n"
+ "1:\tldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr)
+ : "g"(old), "r"(new));
return ret;
}
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (ret != u)
- v->counter += a;
- local_irq_restore(flags);
+ unsigned char ccr;
+
+ __asm__ __volatile__ (
+ "stc ccr,%w2\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %1,%0\n\t"
+ "cmp.l %4,%0\n\t"
+ "beq 1f\n\t"
+ "add.l %0,%3\n\t"
+ "mov.l %3,%1\n"
+ "1:\tldc %w2,ccr"
+ : "=r"(ret), "+m"(v->counter), "=r"(ccr), "+r"(a)
+ : "ri"(u));
return ret;
}
-static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *v)
{
- __asm__ __volatile__("stc ccr,r1l\n\t"
- "orc #0x80,ccr\n\t"
- "mov.l %0,er0\n\t"
- "and.l %1,er0\n\t"
- "mov.l er0,%0\n\t"
- "ldc r1l,ccr"
- : "=m" (*v) : "g" (~(mask)) :"er0","er1");
+ unsigned char ccr;
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+ "stc ccr,%w3\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %0,%1\n\t"
+ "and.l %2,%1\n\t"
+ "mov.l %1,%0\n\t"
+ "ldc %w3,ccr"
+ : "=m"(*v), "=r"(tmp)
+ : "g"(~(mask)), "r"(ccr));
}
-static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
+static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
{
- __asm__ __volatile__("stc ccr,r1l\n\t"
- "orc #0x80,ccr\n\t"
- "mov.l %0,er0\n\t"
- "or.l %1,er0\n\t"
- "mov.l er0,%0\n\t"
- "ldc r1l,ccr"
- : "=m" (*v) : "g" (mask) :"er0","er1");
+ unsigned char ccr;
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+ "stc ccr,%w3\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %0,%1\n\t"
+ "or.l %2,%1\n\t"
+ "mov.l %1,%0\n\t"
+ "ldc %w3,ccr"
+ : "=m"(*v), "=r"(tmp)
+ : "g"(~(mask)), "r"(ccr));
}
/* Atomic operations are already serializing */