1*77acbbc0Sskrll/*	$NetBSD: atomic_cas_64.S,v 1.12 2021/07/28 07:32:20 skrll 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)
34*77acbbc0Sskrll
354e0ad64aSmatt/*
364e0ad64aSmatt * ARMv6 has load-exclusive/store-exclusive which works for both user
374e0ad64aSmatt * and kernel.
384e0ad64aSmatt */
394e0ad64aSmattENTRY_NP(_atomic_cas_64)
407e8ec618Smatt	push	{r4-r7}			/* save temporaries */
41016e43caSmatt	mov	ip, r0			/* we need r0 for return value */
424e0ad64aSmatt#ifdef __ARM_EABI__
437e8ec618Smatt	ldrd	r4, r5, [sp, #16]	/* fetch new value */
447c6a90ecSmatt#else
45b1e092a5Smatt	ldr	r5, [sp, #16]		/* second word third argument */
46b1e092a5Smatt	mov	r4, r3			/* first word third argument */
474e0ad64aSmatt	mov	r3, r2			/* r2 will be overwritten by r1 which ... */
484e0ad64aSmatt	mov	r2, r1			/* r1 will be overwritten by ldrexd */
494e0ad64aSmatt#endif
504e0ad64aSmatt1:
5135182a90Sjoerg	ldrexd	r0, r1, [ip]		/* load current value */
52016e43caSmatt	cmp	r0, r2			/*   compare to old? 1st half */
53016e43caSmatt#ifdef __thumb__
544e0ad64aSmatt	bne	2f			/*     jump to return if different */
55016e43caSmatt	cmp	r1, r3			/*   compare to old? 2nd half */
56016e43caSmatt#else
57016e43caSmatt	cmpeq	r1, r3			/*   compare to old? 2nd half */
58016e43caSmatt#endif
59016e43caSmatt	bne	2f			/*     jump to return if different */
6035182a90Sjoerg	strexd	r6, r4, r5, [ip]	/* store new value */
61016e43caSmatt	cmp	r6, #0			/*   succeed? */
624e0ad64aSmatt	bne	1b			/*     nope, try again. */
634e0ad64aSmatt2:
647e8ec618Smatt	pop	{r4-r7}			/* restore temporaries */
654e0ad64aSmatt	RET				/* return. */
664e0ad64aSmattEND(_atomic_cas_64)
674e0ad64aSmatt
684e0ad64aSmattATOMIC_OP_ALIAS(atomic_cas_64,_atomic_cas_64)
699d003b57SmartinATOMIC_OP_ALIAS(atomic_cas_64_ni,_atomic_cas_64)
709d003b57SmartinSTRONG_ALIAS(_atomic_cas_64_ni,_atomic_cas_64)
71*77acbbc0Sskrll
72*77acbbc0SskrllENTRY_NP(__sync_val_compare_and_swap_8)
73*77acbbc0Sskrll	push	{r4, lr}
74*77acbbc0Sskrll	DMB
75*77acbbc0Sskrll	bl	_atomic_cas_64
76*77acbbc0Sskrll	DMB
77*77acbbc0Sskrll	pop	{r4, pc}
78*77acbbc0SskrllEND(__sync_val_compare_and_swap_8)
794e0ad64aSmatt
80fe7beba6Schs#endif /* _ARM_ARCH_6 */
81