1*016e43caSmatt/* $NetBSD: atomic_cas_64.S,v 1.3 2013/08/10 19:59:21 matt 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) 39*016e43caSmatt push {r4, r5, r6} /* save temporaries */ 40*016e43caSmatt mov ip, r0 /* we need r0 for return value */ 414e0ad64aSmatt#ifdef __ARM_EABI__ 424e0ad64aSmatt ldrd r4, [sp] /* fetch new value */ 434e0ad64aSmatt#else 444e0ad64aSmatt ldr r4, [sp, #0] /* fetch new value */ 45*016e43caSmatt ldr r5, [sp, #4] /* fetch new value */ 464e0ad64aSmatt mov r3, r2 /* r2 will be overwritten by r1 which ... */ 474e0ad64aSmatt mov r2, r1 /* r1 will be overwritten by ldrexd */ 484e0ad64aSmatt#endif 494e0ad64aSmatt1: 50*016e43caSmatt ldrexd r0, [ip] /* load current value */ 51*016e43caSmatt cmp r0, r2 /* compare to old? 1st half */ 52*016e43caSmatt#ifdef __thumb__ 534e0ad64aSmatt bne 2f /* jump to return if different */ 54*016e43caSmatt cmp r1, r3 /* compare to old? 2nd half */ 55*016e43caSmatt#else 56*016e43caSmatt cmpeq r1, r3 /* compare to old? 2nd half */ 57*016e43caSmatt#endif 58*016e43caSmatt bne 2f /* jump to return if different */ 59*016e43caSmatt strexd r6, r4, [ip] /* store new value */ 60*016e43caSmatt 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: 68*016e43caSmatt pop {r4, r5, r6} /* restore temporaries */ 694e0ad64aSmatt RET /* return. */ 704e0ad64aSmattEND(_atomic_cas_64) 714e0ad64aSmatt 724e0ad64aSmattATOMIC_OP_ALIAS(atomic_cas_64,_atomic_cas_64) 734e0ad64aSmatt 74fe7beba6Schs#endif /* _ARM_ARCH_6 */ 75