/*
* Copyright ( C ) 2014 Stefan Kristiansson < stefan . kristiansson @ saunalahti . fi >
*
* This file is licensed under the terms of the GNU General Public License
* version 2 . This program is licensed " as is " without any warranty of any
* kind , whether express or implied .
*/
#ifndef __ASM_OPENRISC_ATOMIC_H
#define __ASM_OPENRISC_ATOMIC_H
#include <linux/types.h>
/* Atomically perform op with v->counter and i */
#define ATOMIC_OP(op) \
static inline void arch_atomic_## op(int i, atomic_t *v) \
{ \
int tmp; \
\
__asm__ __volatile__( \
"1: l.lwa %0,0(%1) \n" \
" l." #op " %0,%0,%2 \n" \
" l.swa 0(%1),%0 \n" \
" l.bnf 1b \n" \
" l.nop \n" \
: "=&r" (tmp) \
: "r" (&v->counter), "r" (i) \
: "cc" , "memory" ); \
}
/* Atomically perform op with v->counter and i, return the result */
#define ATOMIC_OP_RETURN(op) \
static inline int arch_atomic_## op## _return (int i, atomic_t *v) \
{ \
int tmp; \
\
__asm__ __volatile__( \
"1: l.lwa %0,0(%1) \n" \
" l." #op " %0,%0,%2 \n" \
" l.swa 0(%1),%0 \n" \
" l.bnf 1b \n" \
" l.nop \n" \
: "=&r" (tmp) \
: "r" (&v->counter), "r" (i) \
: "cc" , "memory" ); \
\
return tmp; \
}
/* Atomically perform op with v->counter and i, return orig v->counter */
#define ATOMIC_FETCH_OP(op) \
static inline int arch_atomic_fetch_## op(int i, atomic_t *v) \
{ \
int tmp, old; \
\
__asm__ __volatile__( \
"1: l.lwa %0,0(%2) \n" \
" l." #op " %1,%0,%3 \n" \
" l.swa 0(%2),%1 \n" \
" l.bnf 1b \n" \
" l.nop \n" \
: "=&r" (old), "=&r" (tmp) \
: "r" (&v->counter), "r" (i) \
: "cc" , "memory" ); \
\
return old; \
}
ATOMIC_OP_RETURN(add)
ATOMIC_OP_RETURN(sub)
ATOMIC_FETCH_OP(add)
ATOMIC_FETCH_OP(sub)
ATOMIC_FETCH_OP(and )
ATOMIC_FETCH_OP(or )
ATOMIC_FETCH_OP(xor )
ATOMIC_OP(add)
ATOMIC_OP(sub)
ATOMIC_OP(and )
ATOMIC_OP(or )
ATOMIC_OP(xor )
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
#define arch_atomic_add_return arch_atomic_add_return
#define arch_atomic_sub_return arch_atomic_sub_return
#define arch_atomic_fetch_add arch_atomic_fetch_add
#define arch_atomic_fetch_sub arch_atomic_fetch_sub
#define arch_atomic_fetch_and arch_atomic_fetch_and
#define arch_atomic_fetch_or arch_atomic_fetch_or
#define arch_atomic_fetch_xor arch_atomic_fetch_xor
#define arch_atomic_add arch_atomic_add
#define arch_atomic_sub arch_atomic_sub
#define arch_atomic_and arch_atomic_and
#define arch_atomic_or arch_atomic_or
#define arch_atomic_xor arch_atomic_xor
/*
* Atomically add a to v - > counter as long as v is not already u .
* Returns the original value at v - > counter .
*
* This is often used through atomic_inc_not_zero ( )
*/
static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
{
int old, tmp;
__asm__ __volatile__(
"1: l.lwa %0, 0(%2) \n"
" l.sfeq %0, %4 \n"
" l.bf 2f \n"
" l.add %1, %0, %3 \n"
" l.swa 0(%2), %1 \n"
" l.bnf 1b \n"
" l.nop \n"
"2: \n"
: "=&r" (old), "=&r" (tmp)
: "r" (&v->counter), "r" (a), "r" (u)
: "cc" , "memory" );
return old;
}
#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless
#define arch_atomic_read(v) READ_ONCE((v)->counter)
#define arch_atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
#include <asm /cmpxchg.h>
#endif /* __ASM_OPENRISC_ATOMIC_H */
Messung V0.5 in Prozent C=96 H=94 G=94
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-10-01)
¤
*© Formatika GbR, Deutschland