Module Name:    src
Committed By:   matt
Date:           Tue Nov 27 23:42:35 UTC 2012

Modified Files:
        src/common/lib/libc/arch/arm/atomic [matt-nb6-plus]: Makefile.inc
            atomic_add_32.S atomic_and_32.S atomic_cas_32.S atomic_cas_8.S
            atomic_dec_32.S atomic_inc_32.S atomic_op_asm.h atomic_or_32.S
            atomic_swap.S membar_ops.S
Added Files:
        src/common/lib/libc/arch/arm/atomic [matt-nb6-plus]: atomic_add_64.S
            atomic_and_64.S atomic_cas_64.S atomic_dec_64.S atomic_inc_64.S
            atomic_or_64.S atomic_swap_64.S

Log Message:
Pull atomic ops from HEAD.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.8.12.1 \
    src/common/lib/libc/arch/arm/atomic/Makefile.inc
cvs rdiff -u -r1.2 -r1.2.24.1 \
    src/common/lib/libc/arch/arm/atomic/atomic_add_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_and_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h \
    src/common/lib/libc/arch/arm/atomic/atomic_or_32.S \
    src/common/lib/libc/arch/arm/atomic/atomic_swap.S \
    src/common/lib/libc/arch/arm/atomic/membar_ops.S
cvs rdiff -u -r0 -r1.3.4.2 \
    src/common/lib/libc/arch/arm/atomic/atomic_add_64.S \
    src/common/lib/libc/arch/arm/atomic/atomic_inc_64.S
cvs rdiff -u -r0 -r1.2.4.2 \
    src/common/lib/libc/arch/arm/atomic/atomic_and_64.S \
    src/common/lib/libc/arch/arm/atomic/atomic_cas_64.S \
    src/common/lib/libc/arch/arm/atomic/atomic_dec_64.S \
    src/common/lib/libc/arch/arm/atomic/atomic_or_64.S \
    src/common/lib/libc/arch/arm/atomic/atomic_swap_64.S
cvs rdiff -u -r1.1 -r1.1.12.1 \
    src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/common/lib/libc/arch/arm/atomic/Makefile.inc
diff -u src/common/lib/libc/arch/arm/atomic/Makefile.inc:1.8 src/common/lib/libc/arch/arm/atomic/Makefile.inc:1.8.12.1
--- src/common/lib/libc/arch/arm/atomic/Makefile.inc:1.8	Sun Jan  4 17:54:29 2009
+++ src/common/lib/libc/arch/arm/atomic/Makefile.inc	Tue Nov 27 23:42:34 2012
@@ -1,19 +1,43 @@
-#	$NetBSD: Makefile.inc,v 1.8 2009/01/04 17:54:29 pooka Exp $
+#	$NetBSD: Makefile.inc,v 1.8.12.1 2012/11/27 23:42:34 matt Exp $
+
+ARMV6= ${CPUFLAGS:M-march=armv7*} ${CPUFLAGS:M-mcpu=cortex*}
+ARMV6+= ${CPUFLAGS:M-march=armv6*} ${CPUFLAGS:M-mcpu=arm11*}
+ARMV6+= ${CFLAGS:M-march=armv7*:} ${CFLAGS:M-mcpu=cortex*}
+ARMV6+= ${CFLAGS:M-march=armv6*:} ${CFLAGS:M-mcpu=arm11*}
+ARMV6+= ${CPPFLAGS:M-march=armv7*:} ${CPPFLAGS:M-mcpu=cortex*}
+ARMV6+= ${CPPFLAGS:M-march=armv6*:} ${CPPFLAGS:M-mcpu=arm11*}
 
 .if defined(LIB) && (${LIB} == "kern" || ${LIB} == "c" || ${LIB} == "pthread" \
 	|| ${LIB} == "rump")
 
-SRCS+=	atomic_add_32_cas.c atomic_add_32_nv_cas.c atomic_and_32_cas.c \
-	atomic_and_32_nv_cas.c atomic_dec_32_cas.c atomic_dec_32_nv_cas.c \
-	atomic_inc_32_cas.c atomic_inc_32_nv_cas.c atomic_or_32_cas.c \
-	atomic_or_32_nv_cas.c atomic_swap_32_cas.c membar_ops_nop.c
+.if empty(ARMV6)
+SRCS.atomic+=	atomic_add_32_cas.c atomic_add_32_nv_cas.c \
+		atomic_and_32_cas.c atomic_and_32_nv_cas.c \
+		atomic_dec_32_cas.c atomic_dec_32_nv_cas.c \
+		atomic_inc_32_cas.c atomic_inc_32_nv_cas.c \
+		atomic_or_32_cas.c atomic_or_32_nv_cas.c \
+		atomic_swap_32_cas.c membar_ops_nop.c
+.else
+SRCS.atomic+=	atomic_add_32.S atomic_and_32.S atomic_cas_32.S
+SRCS.atomic+=	atomic_dec_32.S atomic_inc_32.S atomic_or_32.S
+SRCS.atomic+=	atomic_swap.S membar_ops.S
+SRCS.atomic+=	atomic_add_64.S atomic_and_64.S atomic_cas_64.S
+SRCS.atomic+=	atomic_dec_64.S atomic_inc_64.S atomic_or_64.S
+SRCS.atomic+=	atomic_swap_64.S
+.endif
 
 .endif
 
 .if defined(LIB) && (${LIB} == "c" || ${LIB} == "pthread")
 
-SRCS+=	atomic_init_testset.c
-SRCS+=	atomic_cas_up.S
+.if empty(ARMV6)
+SRCS.atomic+=	atomic_init_testset.c
+SRCS.atomic+=	atomic_cas_up.S
 CPPFLAGS+= -D__HAVE_ASM_ATOMIC_CAS_UP
+.else
+SRCS.atomic+=	atomic_init_cas.c
+.endif
 
 .endif
+
+SRCS+=	${SRCS.atomic}

Index: src/common/lib/libc/arch/arm/atomic/atomic_add_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_add_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_add_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_add_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_add_32.S	Tue Nov 27 23:42:34 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_add_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_add_32.S,v 1.2.24.1 2012/11/27 23:42:34 matt Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -40,6 +40,11 @@ ENTRY_NP(_atomic_add_32)
 	strex	ip, r2, [r3]		/* try to store */
 	cmp	ip, #0			/*   succeed? */
 	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return old value */
 	END(_atomic_add_32)
 ATOMIC_OP_ALIAS(atomic_add_32,_atomic_add_32)
@@ -57,6 +62,11 @@ ENTRY_NP(_atomic_add_32_nv)
 	strex	r2, r0, [r3]		/* try to store */
 	cmp	r2, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_add_32_nv)
 ATOMIC_OP_ALIAS(atomic_add_32_nv,_atomic_add_32_nv)
Index: src/common/lib/libc/arch/arm/atomic/atomic_and_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_and_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_and_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_and_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_and_32.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_and_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_and_32.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -40,6 +40,11 @@ ENTRY_NP(_atomic_and_32)
 	strex	ip, r2, [r3]		/* try to store */
 	cmp	ip, #0			/*   succeed? */
 	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return old value */
 	END(_atomic_and_32)
 ATOMIC_OP_ALIAS(atomic_and_32,_atomic_and_32)
@@ -55,6 +60,11 @@ ENTRY_NP(_atomic_and_32_nv)
 	strex	r2, r0, [r3]		/* try to store */
 	cmp	r2, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_and_32_nv)
 ATOMIC_OP_ALIAS(atomic_and_32_nv,_atomic_and_32_nv)
Index: src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_cas_32.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_cas_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_cas_32.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -44,15 +44,28 @@ ENTRY_NP(_atomic_cas_32)
 	strex	ip, r2, [r3]		/* store new value */
 	cmp	ip, #0			/*   succeed? */
 	bne	1b			/*     nope, try again. */
-	RET				/*    yes, return. */
+#ifdef _ARM_ARCH_7
+	dsb
+#else
+	mcr	p15, 0, ip, c7, c10, 4	/* data synchronization barrier */
+#endif
+	RET				/* return. */
 	END(_atomic_cas_32)
 
 ATOMIC_OP_ALIAS(atomic_cas_32,_atomic_cas_32)
 ATOMIC_OP_ALIAS(atomic_cas_uint,_atomic_cas_32)
 ATOMIC_OP_ALIAS(atomic_cas_ulong,_atomic_cas_32)
 ATOMIC_OP_ALIAS(atomic_cas_ptr,_atomic_cas_32)
+ATOMIC_OP_ALIAS(atomic_cas_32_ni,_atomic_cas_32)
+ATOMIC_OP_ALIAS(atomic_cas_uint_ni,_atomic_cas_32)
+ATOMIC_OP_ALIAS(atomic_cas_ulong_ni,_atomic_cas_32)
+ATOMIC_OP_ALIAS(atomic_cas_ptr_ni,_atomic_cas_32)
 STRONG_ALIAS(_atomic_cas_uint,_atomic_cas_32)
 STRONG_ALIAS(_atomic_cas_ulong,_atomic_cas_32)
+STRONG_ALIAS(_atomic_cas_32_ni,_atomic_cas_32)
+STRONG_ALIAS(_atomic_cas_ptr_ni,_atomic_cas_32)
+STRONG_ALIAS(_atomic_cas_uint_ni,_atomic_cas_32)
+STRONG_ALIAS(_atomic_cas_ulong_ni,_atomic_cas_32)
 STRONG_ALIAS(_atomic_cas_ptr,_atomic_cas_32)
 
-#endif /* _ARCH_ARM_6 */
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_dec_32.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_dec_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_dec_32.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,6 +39,11 @@ ENTRY_NP(_atomic_dec_32)
 	strex	r3, r1, [r2]		/* try to store */
 	cmp	r3, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_dec_32)
 ATOMIC_OP_ALIAS(atomic_dec_32,_atomic_dec_32)
@@ -56,6 +61,11 @@ ENTRY_NP(_atomic_dec_32_nv)
 	strex	r1, r0, [r2]		/* try to store */
 	cmp	r1, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_dec_32_nv)
 ATOMIC_OP_ALIAS(atomic_dec_32_nv,_atomic_dec_32_nv)
Index: src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_inc_32.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_inc_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_inc_32.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,6 +39,11 @@ ENTRY_NP(_atomic_inc_32)
 	strex	r3, r1, [r2]		/* try to store */
 	cmp	r3, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_inc_32)
 ATOMIC_OP_ALIAS(atomic_inc_32,_atomic_inc_32)
@@ -56,6 +61,11 @@ ENTRY_NP(_atomic_inc_32_nv)
 	strex	r1, r0, [r2]		/* try to store */
 	cmp	r1, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_inc_32_nv)
 ATOMIC_OP_ALIAS(atomic_inc_32_nv,_atomic_inc_32_nv)
@@ -66,4 +76,4 @@ STRONG_ALIAS(_atomic_inc_uint_nv,_atomic
 STRONG_ALIAS(_atomic_inc_ulong_nv,_atomic_inc_32_nv)
 STRONG_ALIAS(_atomic_inc_ptr_nv,_atomic_inc_32_nv)
 
-#endif /* _ARCH_ARM_6 */
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h
diff -u src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h:1.2 src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_op_asm.h	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_op_asm.h,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_op_asm.h,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -51,4 +51,16 @@
 
 #endif /* _KERNEL */
 
+#ifdef __ARMEB__
+#define	HI	r0
+#define	LO	r1
+#define	NHI	r2
+#define	NLO	r3
+#else
+#define	LO	r0
+#define	HI	r1
+#define	NLO	r2
+#define	NHI	r3
+#endif
+
 #endif /* _ATOMIC_OP_ASM_H_ */
Index: src/common/lib/libc/arch/arm/atomic/atomic_or_32.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_or_32.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_or_32.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_or_32.S:1.2	Sat Aug 16 07:12:39 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_or_32.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic_or_32.S,v 1.2 2008/08/16 07:12:39 matt Exp $	*/
+/*	$NetBSD: atomic_or_32.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,6 +39,11 @@ ENTRY_NP(_atomic_or_32)
 	strex	ip, r2, [r3]		/* try to store */
 	cmp	ip, #0			/*   succeed? */
 	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return old value */
 	END(_atomic_or_32)
 ATOMIC_OP_ALIAS(atomic_or_32,_atomic_or_32)
@@ -54,6 +59,11 @@ ENTRY_NP(_atomic_or_32_nv)
 	strex	r2, r0, [r3]		/* try to store */
 	cmp	r2, #0			/*   succeed? */
 	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET				/* return new value */
 	END(_atomic_or_32_nv)
 ATOMIC_OP_ALIAS(atomic_or_32_nv,_atomic_or_32_nv)
Index: src/common/lib/libc/arch/arm/atomic/atomic_swap.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_swap.S:1.2 src/common/lib/libc/arch/arm/atomic/atomic_swap.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/atomic_swap.S:1.2	Sat Aug 16 07:12:40 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_swap.S	Tue Nov 27 23:42:35 2012
@@ -1,7 +1,7 @@
-/*	$NetBSD: atomic_swap.S,v 1.2 2008/08/16 07:12:40 matt Exp $	*/
+/*	$NetBSD: atomic_swap.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 
 /*-
- * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * Copyright (c) 2007,2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -15,13 +15,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the NetBSD
- *	Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *      
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -38,8 +31,38 @@
 
 #include "atomic_op_asm.h"
 
+/*
+ * While SWP{B} is sufficient on its own for pre-ARMv7 CPUs, on MP ARMv7 cores
+ * SWP{B} is disabled since it's no longer atomic among multiple CPUs.  They
+ * will actually raise an UNDEFINED exception.
+ *
+ * So if we use the LDREX/STREX template, but use a SWP instruction followed
+ * by a MOV instruction (using a temporary register), that gives a handler
+ * for the SWP UNDEFINED exception enough information to "patch" this instance
+ * SWP with correct forms of LDREX/STREX.  (note that this would happen even
+ * "read-only" pages.  If the page gets tossed, we will get another exception
+ * and fix yet again).
+ */
+
 ENTRY_NP(_atomic_swap_32)
-	swp	r0, r1, [r0]
+	mov	r2, r0
+1:
+#ifdef _ARM_ARCH_6
+	ldrex	r0, [r2]
+	cmp	r0, r1
+	strexne	ip, r1, [r2]
+#else
+	swp	r0, r1, [r2]
+	cmp	r0, r1
+	movsne	ip, #0
+#endif
+	cmpne	ip, #0
+	bne	1b
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET
 	END(_atomic_swap_32)
 ATOMIC_OP_ALIAS(atomic_swap_32,_atomic_swap_32)
@@ -51,11 +74,26 @@ STRONG_ALIAS(_atomic_swap_ulong,_atomic_
 STRONG_ALIAS(_atomic_swap_ptr,_atomic_swap_32)
 
 ENTRY_NP(_atomic_swap_8)
-	swpb	r0, r1, [r0]
+	mov	r2, r0
+1:
+#ifdef _ARM_ARCH_6
+	ldrexb	r0, [r2]
+	strexb	r3, r1, [r2]
+#else
+	swpb	r0, r1, [r2]
+	mov	r3, #0
+#endif
+	cmp	r3, #0
+	bne	1b
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
 	RET
 	END(_atomic_swap_8)
 ATOMIC_OP_ALIAS(atomic_swap_8,_atomic_swap_8)
 ATOMIC_OP_ALIAS(atomic_swap_char,_atomic_swap_8)
 ATOMIC_OP_ALIAS(atomic_swap_uchar,_atomic_swap_8)
-STRONG_ALIAS(_atomic_swap_char,_atomic_swap_32)
-STRONG_ALIAS(_atomic_swap_uchar,_atomic_swap_32)
+STRONG_ALIAS(_atomic_swap_char,_atomic_swap_8)
+STRONG_ALIAS(_atomic_swap_uchar,_atomic_swap_8)
Index: src/common/lib/libc/arch/arm/atomic/membar_ops.S
diff -u src/common/lib/libc/arch/arm/atomic/membar_ops.S:1.2 src/common/lib/libc/arch/arm/atomic/membar_ops.S:1.2.24.1
--- src/common/lib/libc/arch/arm/atomic/membar_ops.S:1.2	Sat Aug 16 07:12:40 2008
+++ src/common/lib/libc/arch/arm/atomic/membar_ops.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: membar_ops.S,v 1.2 2008/08/16 07:12:40 matt Exp $	*/
+/*	$NetBSD: membar_ops.S,v 1.2.24.1 2012/11/27 23:42:35 matt Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -33,7 +33,11 @@
 #ifdef _ARM_ARCH_6
 
 ENTRY_NP(_membar_producer)
+#ifdef _ARM_ARCH_7
+	dsb
+#else
 	mcr	p15, 0, r0, c7, c10, 4	 /* Data Synchronization Barrier */
+#endif
 	RET
 	END(_membar_producer)
 ATOMIC_OP_ALIAS(membar_producer,_membar_producer)
@@ -41,7 +45,11 @@ ATOMIC_OP_ALIAS(membar_write,_membar_pro
 STRONG_ALIAS(_membar_write,_membar_producer)
 
 ENTRY_NP(_membar_sync)
+#ifdef _ARM_ARCH_7
+	dmb
+#else
 	mcr	p15, 0, r0, c7, c10, 5	/* Data Memory Barrier */
+#endif
 	RET
 	END(_membar_sync)
 ATOMIC_OP_ALIAS(membar_sync,_membar_sync)

Index: src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S
diff -u src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S:1.1 src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S:1.1.12.1
--- src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S:1.1	Tue Nov 18 15:22:56 2008
+++ src/common/lib/libc/arch/arm/atomic/atomic_cas_8.S	Tue Nov 27 23:42:35 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: atomic_cas_8.S,v 1.1 2008/11/18 15:22:56 matt Exp $ */
+/* $NetBSD: atomic_cas_8.S,v 1.1.12.1 2012/11/27 23:42:35 matt Exp $ */
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -27,37 +27,33 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-#include <machine/asm.h>
 
-RCSID("$NetBSD: atomic_cas_8.S,v 1.1 2008/11/18 15:22:56 matt Exp $")
+#include "atomic_op_asm.h"
 
-ENTRY(atomic_cas_8)
-	XPUSH	{r4,r5}			/* we need some more registers */
-	and	r3, r0, #3		/* which byte do we replace? */
-#if __ARMEB__
-	eor	r3, r3, #3		/* bytes are reversed on BE */
+#if defined(_ARM_ARCH_6)
+/*
+ * ARMv6 has load-exclusive/store-exclusive which works for both user
+ * and kernel.
+ */
+ENTRY_NP(_atomic_cas_8)
+	mov	r3, r0			/* we need r0 for return value */
+1:
+	ldrexb	r0, [r3]		/* load old value */
+	teq	r0, r1			/*   compare? */
+	RETc(ne)			/*     return if different */
+	strexb	ip, r2, [r3]		/* store new value */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     nope, try again. */
+#ifdef _ARM_ARCH_7
+	dsb				/* data synchronization barrier */
+#else
+	mcr	p15, 0, ip, c7, c10, 4	/* data synchronization barrier */
 #endif
-	mov	r3, r3, lsl #3		/* multiply by 8 */
-	mov	r1, r1, lsl r3		/* mov old value to correct byte */
-	eor	r2, r1, r2, lsl r3	/* move new value to correct byte */
-/*	eor	r2, r2, r1 */		/* new value is now (old ^ new) */
-	mov	r5, #0xff		/* load mask */
-	mov	r5, r5, lsl r3		/* and move to correct byte */
-	mov	r3, r0			/* move pointer */
+	RET				/* return. */
+	END(_atomic_cas_8)
 
-1:	ldrex	r4, [r3]		/* load 32bit value */
-	and	r0, r4, r5		/* clear other bytes */
-	teq	r0, r1			/* equal old value? */
-	bne	2f			/*   nope, bail. */
-	eor	r4, r4, r2		/* new == old ^ (old ^ new) */
-	strex	ip, r4, [r3]		/* attempt to store it */
-	cmp	ip, #0			/*   succeed? */
-	bne	1b			/* nope, try again. */
+ATOMIC_OP_ALIAS(atomic_cas_8,_atomic_cas_8)
+STRONG_ALIAS(_atomic_cas_char,_atomic_cas_8)
+STRONG_ALIAS(_atomic_cas_uchar,_atomic_cas_8)
 
-2:	XPOP	{r4,r5}			/* don't need these anymore */
-	and	r1, r3, #3
-#if __ARMEB__
-	eor	r1, r1, #3
-#endif
-	mov	r0, r0, lsr r1		/* shift it back to lsb byte */
-	RET
+#endif /* _ARM_ARCH_6 */

Added files:

Index: src/common/lib/libc/arch/arm/atomic/atomic_add_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_add_64.S:1.3.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_add_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,81 @@
+/*	$NetBSD: atomic_add_64.S,v 1.3.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#ifdef _ARM_ARCH_6
+
+ENTRY_NP(_atomic_add_64)
+	str	r4, [sp, #-4]!		/* save temporary */
+	mov	r4, r0			/* need r0 for return value */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+1:	ldrexd	r0, [r4]		/* load old value (to be returned) */
+	adds	NLO, LO, NLO		/* calculate new value */
+	adc	NHI, HI, NHI		/* calculate new value */
+	strexd	ip, r2, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return old value */
+	END(_atomic_add_64)
+ATOMIC_OP_ALIAS(atomic_add_64,_atomic_add_64)
+
+ENTRY_NP(_atomic_add_64_nv)
+	str	r4, [sp, #-4]!		/* save temporary */
+	mov	r4, r0			/* need r0 for return value */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+1:	ldrexd	r0, [r4]		/* load old value */
+	adds	LO, LO, NLO		/* calculate new value lo */
+	adc	HI, HI, NHI		/* calculate new value hi */
+	strexd	ip, r0, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return new value */
+	END(_atomic_add_64_nv)
+ATOMIC_OP_ALIAS(atomic_add_64_nv,_atomic_add_64_nv)
+
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_inc_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_inc_64.S:1.3.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_inc_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,72 @@
+/*	$NetBSD: atomic_inc_64.S,v 1.3.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#ifdef _ARM_ARCH_6
+
+ENTRY_NP(_atomic_inc_64)
+	mov	r3, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r3]		/* load old value (return value) */
+	adds	LO, LO, #1		/* calculate new value */
+	adc	HI, HI, #0		/* zero means we carried */
+	strexd	ip, r0, [r3]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	mvn	r2, #0			/* r2 = -1 */
+	adds	LO, LO, r2		/* add it */
+	adc	HI, HI, r2		/* add with carry */
+	RET				/* return orig value */
+	END(_atomic_inc_64)
+ATOMIC_OP_ALIAS(atomic_inc_64,_atomic_inc_64)
+
+ENTRY_NP(_atomic_inc_64_nv)
+	mov	r3, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r3]		/* load old value */
+	add	LO, LO, #1		/* calculate new value (return value) */
+	adc	HI, HI, #0		/* fold carry into high */
+	strexd	ip, r0, [r3]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	RET				/* return new value */
+	END(_atomic_inc_64_nv)
+ATOMIC_OP_ALIAS(atomic_inc_64_nv,_atomic_inc_64_nv)
+
+#endif /* _ARM_ARCH_6 */

Index: src/common/lib/libc/arch/arm/atomic/atomic_and_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_and_64.S:1.2.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_and_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,81 @@
+/*	$NetBSD: atomic_and_64.S,v 1.2.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#ifdef _ARM_ARCH_6
+
+ENTRY_NP(_atomic_and_64)
+	str	r4, [sp, #-4]!		/* save temporary */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+	mov	r4, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r4]		/* load old value (to be returned) */
+	and	r2, r0, r2		/* calculate new value */
+	and	r3, r1, r3		/* calculate new value */
+	strexd	ip, r2, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return old value */
+	END(_atomic_and_64)
+ATOMIC_OP_ALIAS(atomic_and_64,_atomic_and_64)
+
+ENTRY_NP(_atomic_and_64_nv)
+	str	r4, [sp, #-4]!		/* save temporary */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+	mov	r4, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r4]		/* load old value */
+	and	r0, r0, r2		/* calculate new value */
+	and	r1, r1, r3		/* calculate new value */
+	strexd	ip, r0, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return new value */
+	END(_atomic_and_64_nv)
+ATOMIC_OP_ALIAS(atomic_and_64_nv,_atomic_and_64_nv)
+
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_cas_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_cas_64.S:1.2.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_cas_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,69 @@
+/*	$NetBSD: atomic_cas_64.S,v 1.2.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#if defined(_ARM_ARCH_6)
+/*
+ * ARMv6 has load-exclusive/store-exclusive which works for both user
+ * and kernel.
+ */
+ENTRY_NP(_atomic_cas_64)
+	stmfd	sp!, {r4, r5, r6}	/* save temporaries */
+	mov	r6, r0			/* we need r0 for return value */
+#ifdef __ARM_EABI__
+	ldrd	r4, [sp]		/* fetch new value */
+#else
+	ldr	r5, [sp, #4]		/* fetch new value */
+	ldr	r4, [sp, #0]		/* fetch new value */
+	mov	r3, r2			/* r2 will be overwritten by r1 which ... */
+	mov	r2, r1			/* r1 will be overwritten by ldrexd */
+#endif
+1:
+	ldrexd	r0, [r6]		/* load current value */
+	teq	r0, r2			/*   compare to old? 1st half */
+	teqeq	r1, r3			/*   compare to old? 2nd half */
+	bne	2f			/*     jump to return if different */
+	strexd	ip, r4, [r6]		/* store new value */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     nope, try again. */
+#ifdef _ARM_ARCH_7
+	dsb
+#else
+	mcr	p15, 0, ip, c7, c10, 4	/* data synchronization barrier */
+#endif
+2:
+	ldmfd	sp!, {r4, r5, r6}	/* restore temporaries */
+	RET				/* return. */
+	END(_atomic_cas_64)
+
+ATOMIC_OP_ALIAS(atomic_cas_64,_atomic_cas_64)
+
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_dec_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_dec_64.S:1.2.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_dec_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,73 @@
+/*	$NetBSD: atomic_dec_64.S,v 1.2.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#ifdef _ARM_ARCH_6
+
+ENTRY_NP(_atomic_dec_64)
+	mvn	r2, #0
+	mov	r3, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r3]		/* load old value (return value) */
+	adds	LO, LO, r2		/* calculate new value */
+	adc	HI, HI, r2		/* calculate new value */
+	strexd	ip, r0, [r3]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	adds	LO, LO, #1
+	adc	HI, HI, #0
+	RET				/* return old value */
+	END(_atomic_dec_64)
+ATOMIC_OP_ALIAS(atomic_dec_64,_atomic_dec_64)
+
+ENTRY_NP(_atomic_dec_64_nv)
+	mvn	r2, #0
+	mov	r3, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r3]		/* load old value */
+	adds	LO, LO, r2		/* calculate new value */
+	adc	HI, HI, r2		/* calculate new value */
+	strexd	ip, r0, [r3]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	RET				/* return new value */
+	END(_atomic_dec_64_nv)
+ATOMIC_OP_ALIAS(atomic_dec_64_nv,_atomic_dec_64_nv)
+
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_or_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_or_64.S:1.2.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_or_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,81 @@
+/*	$NetBSD: atomic_or_64.S,v 1.2.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <m...@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+#ifdef _ARM_ARCH_6
+
+ENTRY_NP(_atomic_or_64)
+	str	r4, [sp, #-4]!		/* save temporary */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+	mov	r4, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r4]		/* load old value (to be returned) */
+	orr	r2, r0, r2		/* calculate new value */
+	orr	r3, r1, r3		/* calculate new value */
+	strexd	ip, r2, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return old value */
+	END(_atomic_or_64)
+ATOMIC_OP_ALIAS(atomic_or_64,_atomic_or_64)
+
+ENTRY_NP(_atomic_or_64_nv)
+	str	r4, [sp, #-4]!		/* save temporary */
+#ifndef __ARM_EABI__
+	mov	r3, r2
+	mov	r2, r1
+#endif
+	mov	r4, r0			/* need r0 for return value */
+1:	ldrexd	r0, [r4]		/* load old value */
+	orr	r0, r0, r2		/* calculate new value (return value) */
+	orr	r1, r1, r3		/* calculate new value (return value) */
+	strexd	ip, r0, [r4]		/* try to store */
+	cmp	ip, #0			/*   succeed? */
+	bne	1b			/*     no, try again? */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET				/* return new value */
+	END(_atomic_or_64_nv)
+ATOMIC_OP_ALIAS(atomic_or_64_nv,_atomic_or_64_nv)
+
+#endif /* _ARM_ARCH_6 */
Index: src/common/lib/libc/arch/arm/atomic/atomic_swap_64.S
diff -u /dev/null src/common/lib/libc/arch/arm/atomic/atomic_swap_64.S:1.2.4.2
--- /dev/null	Tue Nov 27 23:42:35 2012
+++ src/common/lib/libc/arch/arm/atomic/atomic_swap_64.S	Tue Nov 27 23:42:35 2012
@@ -0,0 +1,53 @@
+/*	$NetBSD: atomic_swap_64.S,v 1.2.4.2 2012/11/27 23:42:35 matt Exp $	*/
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *      
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_asm.h"
+
+ENTRY_NP(_atomic_swap_64)
+	str	r4, [sp, #-4]!		/* save temporary */
+	mov	r4, r0			/* return value will be in r0 */
+#ifndef __ARM_EABI__
+	mov	r3, r2			/* r2 will be overwriten by r1 */
+	mov	r2, r1			/* and r1 will be overwritten by ldrexd */
+#endif
+1:
+	ldrexd	r0, [r4]		/* load old value */
+	strexd	ip, r2, [r4]		/* store new value */
+	cmpne	ip, #0			/*    succeed? */
+	bne	1b			/*    no, try again */
+#ifdef _ARM_ARCH_7
+	dmb
+#else
+	mcr	p15, 0, ip, c7, c10, 5	/* data memory barrier */
+#endif
+	ldr	r4, [sp], #4		/* restore temporary */
+	RET
+	END(_atomic_swap_64)
+ATOMIC_OP_ALIAS(atomic_swap_64,_atomic_swap_64)

Reply via email to