1*9d003b57Smartin/*	$NetBSD: atomic_cas_64.S,v 1.11 2019/02/18 11:22:56 martin Exp $	*/
24e0ad64aSmatt/*-
34e0ad64aSmatt * Copyright (c) 2012 The NetBSD Foundation, Inc.
44e0ad64aSmatt * All rights reserved.
54e0ad64aSmatt *
64e0ad64aSmatt * This code is derived from software contributed to The NetBSD Foundation
74e0ad64aSmatt * by Matt Thomas <matt@3am-software.com>
84e0ad64aSmatt *
94e0ad64aSmatt * Redistribution and use in source and binary forms, with or without
104e0ad64aSmatt * modification, are permitted provided that the following conditions
114e0ad64aSmatt * are met:
124e0ad64aSmatt * 1. Redistributions of source code must retain the above copyright
134e0ad64aSmatt *    notice, this list of conditions and the following disclaimer.
144e0ad64aSmatt * 2. Redistributions in binary form must reproduce the above copyright
154e0ad64aSmatt *    notice, this list of conditions and the following disclaimer in the
164e0ad64aSmatt *    documentation and/or other materials provided with the distribution.
174e0ad64aSmatt *
184e0ad64aSmatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
194e0ad64aSmatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
204e0ad64aSmatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
214e0ad64aSmatt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
224e0ad64aSmatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
234e0ad64aSmatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
244e0ad64aSmatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
254e0ad64aSmatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
264e0ad64aSmatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
274e0ad64aSmatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
284e0ad64aSmatt * POSSIBILITY OF SUCH DAMAGE.
294e0ad64aSmatt */
304e0ad64aSmatt
314e0ad64aSmatt#include "atomic_op_asm.h"
324e0ad64aSmatt
334e0ad64aSmatt#if defined(_ARM_ARCH_6)
344e0ad64aSmatt/*
354e0ad64aSmatt * ARMv6 has load-exclusive/store-exclusive which works for both user
364e0ad64aSmatt * and kernel.
374e0ad64aSmatt */
384e0ad64aSmattENTRY_NP(_atomic_cas_64)
397e8ec618Smatt	push	{r4-r7}			/* save temporaries */
40016e43caSmatt	mov	ip, r0			/* we need r0 for return value */
414e0ad64aSmatt#ifdef __ARM_EABI__
427e8ec618Smatt	ldrd	r4, r5, [sp, #16]	/* fetch new value */
437c6a90ecSmatt#else
44b1e092a5Smatt	ldr	r5, [sp, #16]		/* second word third argument */
45b1e092a5Smatt	mov	r4, r3			/* first word third argument */
464e0ad64aSmatt	mov	r3, r2			/* r2 will be overwritten by r1 which ... */
474e0ad64aSmatt	mov	r2, r1			/* r1 will be overwritten by ldrexd */
484e0ad64aSmatt#endif
494e0ad64aSmatt1:
5035182a90Sjoerg	ldrexd	r0, r1, [ip]		/* load current value */
51016e43caSmatt	cmp	r0, r2			/*   compare to old? 1st half */
52016e43caSmatt#ifdef __thumb__
534e0ad64aSmatt	bne	2f			/*     jump to return if different */
54016e43caSmatt	cmp	r1, r3			/*   compare to old? 2nd half */
55016e43caSmatt#else
56016e43caSmatt	cmpeq	r1, r3			/*   compare to old? 2nd half */
57016e43caSmatt#endif
58016e43caSmatt	bne	2f			/*     jump to return if different */
5935182a90Sjoerg	strexd	r6, r4, r5, [ip]	/* store new value */
60016e43caSmatt	cmp	r6, #0			/*   succeed? */
614e0ad64aSmatt	bne	1b			/*     nope, try again. */
624e0ad64aSmatt#ifdef _ARM_ARCH_7
634e0ad64aSmatt	dsb
644e0ad64aSmatt#else
654e0ad64aSmatt	mcr	p15, 0, ip, c7, c10, 4	/* data synchronization barrier */
664e0ad64aSmatt#endif
674e0ad64aSmatt2:
687e8ec618Smatt	pop	{r4-r7}			/* restore temporaries */
694e0ad64aSmatt	RET				/* return. */
704e0ad64aSmattEND(_atomic_cas_64)
714e0ad64aSmatt
724e0ad64aSmattATOMIC_OP_ALIAS(atomic_cas_64,_atomic_cas_64)
73*9d003b57SmartinATOMIC_OP_ALIAS(atomic_cas_64_ni,_atomic_cas_64)
74*9d003b57SmartinSTRONG_ALIAS(_atomic_cas_64_ni,_atomic_cas_64)
750c8f69fbSmattCRT_ALIAS(__sync_val_compare_and_swap_8,_atomic_cas_64)
764e0ad64aSmatt
77fe7beba6Schs#endif /* _ARM_ARCH_6 */
78