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