Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Jan 2002 23:56:54 +0100 (CET)
From:      Michal Mertl <mime@traveller.cz>
To:        Peter Jeremy <peter.jeremy@alcatel.com.au>
Subject:   i386 atomic quad implementation (was: 64 bit counters again)
Message-ID:  <Pine.BSF.4.41.0201162353001.78763-200000@prg.traveller.cz>
In-Reply-To: <20020117090710.I72285@gsmx07.alcatel.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
--0-1934547448-1011221814=:78763
Content-Type: TEXT/PLAIN; charset=US-ASCII

On Thu, 17 Jan 2002, Peter Jeremy wrote:

> On 2002-Jan-16 22:15:13 +0100, Michal Mertl <mime@traveller.cz> wrote:
> >In my patch there's also support for 64 bit atomic ops on >=i586. That's
> >one thing which shouldn't hurt anyone. That needs review - I wasn't able
> >to find good documentation examples for gcc inline asm constraints
>
> I agree that this makes inline asm difficult to use for non-trivial
> functions.  Another problem is that the allowable constraint
> combinations change between gcc revisions and even with different
> optimization levels.  Have a look at old versions of i386 atomic.h
> and the regular "it doesn't work at -O0" threads for details.
>

I don't think we need to bother with older than 2.95 gcc. From comments in
atomic.h it seems the change you're talking about was at 2.8, which is
veru old.

> > so I
> >ended up mostly telling gcc exactly which register to use.
>
> As long as you did this within the constraints this should be OK.
> You shouldn't need to specify register names in the actual assembler.
>
> I suggest you post your patch (or a pointer if it's big) to -arch or
> -audit with a request for review.  Before this can be committed, you'll
> need MD backends for each architecture supported.
>

Here it is.

--- atomic.h	Fri Jul  7 02:38:47 2000
+++ atomic.h.new	Wed Jan 16 23:54:56 2002
@@ -148,4 +148,165 @@

 #endif

+#if 1
+#define _ATOMIC_HAVE_QUAD
+#endif
+
+#ifdef _ATOMIC_HAVE_QUAD
+#define	atomic_set_acq_quad	atomic_set_quad
+#define	atomic_set_rel_quad	atomic_set_quad
+#define	atomic_clear_acq_quad	atomic_clear_quad
+#define	atomic_clear_rel_quad	atomic_clear_quad
+#define	atomic_add_acq_quad	atomic_add_quad
+#define	atomic_add_rel_quad	atomic_add_quad
+#define	atomic_subtract_acq_quad	atomic_subtract_quad
+#define	atomic_subtract_rel_quad	atomic_subtract_quad
+#define	atomic_cmpset_acq_quad	atomic_cmpset_quad
+#define	atomic_cmpset_rel_quad	atomic_cmpset_quad
+#define	atomic_readandclear_quad	atomic_readandclear_quad
+
+#if !defined(KLD_MODULE)
+static __inline void atomic_store_rel_quad(volatile u_int64_t *p,u_int64_t v){
+	__asm __volatile ("#atomic_store_rel_quad
+	movl (%%esi),%%eax
+	movl 4(%%esi),%%edx
+	1:"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1b"
+	:
+	: "S" (p), "b" ((u_long)v), "c" ((u_long)((u_long *)&v)[1])
+	: "eax", "edx");
+}
+
+static __inline void atomic_add_quad(volatile u_int64_t *p, u_int64_t v)
+{
+	__asm __volatile ("#atomic_add_quad
+	movl (%%esi),%%eax
+	movl 4(%%esi),%%edx
+	1:movl (%%edi),%%ebx
+	movl 4(%%edi),%%ecx
+	addl %%eax,%%ebx
+	adcl %%edx,%%ecx
+	"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1b"
+	:
+	: "S" (p), "D" (&v)
+	: "eax", "ebx", "ecx", "edx");
+}
+
+static __inline void atomic_subtract_quad(volatile u_int64_t *p, u_int64_t v)
+{
+	atomic_add_quad(p,-v);
+}
+
+static __inline void atomic_clear_quad(volatile u_int64_t *p, u_int64_t v)
+{
+	__asm __volatile ("#atomic_clear_quad
+	movl (%%esi),%%eax
+	movl 4(%%esi),%%edx
+	1: movl (%%edi),%%ebx
+	movl 4(%%edi),%%ecx
+	notl %%eax
+	notl %%edx
+	andl %%eax,%%ebx
+	andl %%edx,%%ecx
+	movl (%%edi),%%eax
+	movl 4(%%edi),%%edx
+	"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1b"
+	:
+	: "S" (p), "D" (&v)
+	: "eax", "ebx", "ecx", "edx");
+}
+
+static __inline void atomic_set_quad(volatile u_int64_t *p, u_int64_t v)
+{
+	__asm __volatile ("#atomic_set_quad
+	movl (%%esi),%%eax
+	movl 4(%%esi),%%edx
+	1: movl (%%edi),%%ebx
+	movl 4(%%edi),%%ecx
+	orl %%eax,%%ebx
+	orl %%edx,%%ecx
+	"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1b"
+	:
+	: "S" (p), "D" (&v)
+	: "eax", "ebx", "ecx", "edx");
+}
+
+static __inline u_int64_t atomic_load_acq_quad(volatile u_int64_t *p)
+{
+	u_int64_t tmp;
+
+	__asm __volatile ("#atomic_load_acq_quad
+	xorl %%eax,%%eax
+	xorl %%ebx,%%ebx
+	xorl %%ecx,%%ecx
+	xorl %%edx,%%edx
+	"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1f
+	movl $0,(%%edi)
+	movl $0,4(%%edi)
+	jmp 2f
+1:	movl %%eax,(%%edi)
+	movl %%edx,4(%%edi)
+2:"
+	:
+	: "D" (&tmp), "S" (p)
+	: "eax", "ebx", "ecx", "edx");
+	return tmp;
+}
+
+static __inline int atomic_cmpset_quad(volatile u_int64_t *dst,u_int64_t exp,u_int64_t src)
+{
+	int res=exp;
+
+	__asm __volatile (MPLOCKED "#atomic_cmpset_quad
+	cmpxchg8b (%%esi)
+	setz %%al
+	movzbl	%%al,%0"
+	: "=a" (res) /* 0 */
+	: "S" (dst) /* 1 */, "eax" ((u_long)exp), "edx" ((u_long)((u_long *)&exp)[1]),
+						"ebx" ((u_long)src), "ecx" ((u_long)((u_long *)&src)[1])
+	);
+	return res;
+}
+
+static __inline u_int64_t atomic_readandclear_quad(volatile u_int64_t *p)
+{
+	u_int64_t tmp;
+
+	__asm __volatile ("#atomic_readandclear_quad
+	xorl %%eax,%%eax
+	xorl %%ebx,%%ebx
+	xorl %%ecx,%%ecx
+	xorl %%edx,%%edx
+	"MPLOCKED "cmpxchg8b (%%esi)
+	jnz 1f
+	movl $0,(%%edi)
+	movl $0,4(%%edi)
+	jmp 2f
+1:	movl %%eax,(%%edi)
+	movl %%edx,4(%%edi)
+2:  "MPLOCKED "cmpxchg8b (%%esi)"
+	:
+	: "D" (&tmp), "S" (p)
+	: "eax", "ebx", "ecx", "edx");
+	return tmp;
+}
+
+#else /* define(KLD_MODULE) */
+
+void atomic_set_quad(volatile u_int64_t *, u_int64_t);
+void atomic_store_rel_quad(volatile u_int64_t *, u_int64_t);
+void atomic_clear_quad(volatile u_int64_t *, u_int64_t);
+void atomic_add_quad(volatile u_int64_t *, u_int64_t);
+void atomic_subtract_quad(volatile u_int64_t *, u_int64_t);
+u_int64_t atomic_load_acq_quad(volatile u_int64_t *);
+int atomic_cmpset_quad(volatile u_int64_t *,u_int64_t,u_int64_t);
+u_int64_t atomic_readandclear_quad(volatile u_int64_t *);
+#endif
+
+#endif  /*defined(ATOMIC_HAVE_QUAD)*/
+
 #endif /* ! _MACHINE_ATOMIC_H_ */
--------------------------- 8< cut here ------


-- 
Michal Mertl
mime@traveller.cz


--0-1934547448-1011221814=:78763
X-Content-Type: TEXT/PLAIN; charset=US-ASCII; name="atomic.h.diff"
X-Content-Transfer-Encoding: BASE64
Content-ID: <Pine.BSF.4.41.0201162356540.78763@prg.traveller.cz>
Content-Description: 
X-Content-Disposition: attachment; filename="atomic.h.diff"
Content-Type: TEXT/PLAIN

The following attachment was sent,
but NOT saved in the Fcc copy:
    A Text/PLAIN segment of about 4,186 bytes.

--0-1934547448-1011221814=:78763--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.41.0201162353001.78763-200000>