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>
