Subject: Re: atomic.h for MIPS
To: None <port-mips@netbsd.org>
From: Toru Nishimura <locore32@gaea.ocn.ne.jp>
List: port-mips
Date: 06/01/2004 00:38:15
> It was a bogus Q.  Linux does have them.

Here it is.

- not tested, copied from alpha, consulting with ppc.
- LP64 model requires 64bit insns.
- requires -mips2 flag to use.

Toru Nishimura/ALKYL Technology

#ifndef _MIPS_ATOMIC_H_
#define	_MIPS_ATOMIC_H_

static __inline void
atomic_setbits_ulong(__volatile unsigned long *ulp, unsigned long v)
{
	unsigned long tmp;

	__asm __volatile(
"# BEGIN atomic_setbits_ulong	\n"
"1:	ll	%0,%3		\n"
"	or	%0,%2,%0	\n"
"	sc	%0,%1		\n"
"	beqz	%0,1b		\n"
"# END atomic_setbits_ulong	\n"
	: "=&r" (tmp), "=m"(*ulp)
	: "r"(v), "m"(*ulp)
	: "memory"
	);
}

static __inline void
atomic_clearbits_ulong(__volatile unsigned long *ulp, unsigned long v)
{
	unsigned long tmp;

	__asm __volatile(
"# BEGIN atomic_clearbits_ulong	\n"
"1:	ll	%0,%3		\n"
"	xor	%0,%2,%0	\n"
"	sc	%0,%1		\n"
"	beqz	%0,1b		\n"
"# END atomic_clearbits_ulong	\n"
	: "=&r" (tmp), "=m"(*ulp)
	: "r"(v), "m"(*ulp)
	: "memory"
	);
}

static __inline void
atomic_add_ulong(__volatile unsigned long *ulp, unsigned long v)
{
	unsigned long tmp;

	__asm __volatile(
"# BEGIN atomic_add_ulong	\n"
"1:	ll	%0,%3		\n"
"	addu	%0,%2,%0	\n"
"	sc	%0,%1		\n"
"	beqz	%0,1b		\n"
"# END atomic_add_ulong	\n"
	: "=&r" (tmp), "=m"(*ulp)
	: "r"(v), "m"(*ulp)
	: "memory"
	);
}

static __inline void
atomic_sub_ulong(__volatile unsigned long *ulp, unsigned long v)
{
	unsigned long tmp;

	__asm __volatile(
"# BEGIN atomic_sub_ulong	\n"
"1:	ll	%0,%3		\n"
"	subu	%0,%2,%0	\n"
"	sc	%0,%1		\n"
"	beqz	%0,1b		\n"
"# END atomic_sub_ulong	\n"
	: "=&r" (tmp), "=m"(*ulp)
	: "r"(v), "m"(*ulp)
	: "memory"
	);
}

static __inline unsigned long
atomic_loadlatch_ulong(__volatile unsigned long *ulp, unsigned long v)
{
	unsigned long tmp, v0;

	__asm __volatile(
"# BEGIN atomic_loadlatch_ulong	\n"
"1:	move	%0,%3		\n"
"	ll	%1,%4		\n"
"	sc	%0,%2		\n"
"	beqz	%0,1b		\n"
"# END atomic_loadlatch_ulong	\n"
	: "=&r" (tmp), "=r" (v0), "=m"(*ulp)
	: "r"(v), "m"(*ulp)
	: "memory"
	);
	return (v0);
}

#endif /* _MIPS_ATOMIC_H_ */