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)