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>