1219019Sgabor/*	$NetBSD: atomic_xor_16.S,v 1.5 2021/07/28 07:32:20 skrll Exp $	*/
2219019Sgabor
3219019Sgabor/*-
4219019Sgabor * Copyright (c) 2013 The NetBSD Foundation, Inc.
5219019Sgabor * All rights reserved.
6219019Sgabor *
7219019Sgabor * This code is derived from software contributed to The NetBSD Foundation
8219019Sgabor * by Matt Thomas <matt@3am-software.com>
9219019Sgabor *
10219019Sgabor * Redistribution and use in source and binary forms, with or without
11219019Sgabor * modification, are permitted provided that the following conditions
12219019Sgabor * are met:
13219019Sgabor * 1. Redistributions of source code must retain the above copyright
14219019Sgabor *    notice, this list of conditions and the following disclaimer.
15219019Sgabor * 2. Redistributions in binary form must reproduce the above copyright
16219019Sgabor *    notice, this list of conditions and the following disclaimer in the
17219019Sgabor *    documentation and/or other materials provided with the distribution.
18219019Sgabor *
19219019Sgabor * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20219019Sgabor * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21219019Sgabor * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22219019Sgabor * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23219019Sgabor * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24219019Sgabor * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25219019Sgabor * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26219019Sgabor * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27219019Sgabor * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28219019Sgabor * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29219019Sgabor * POSSIBILITY OF SUCH DAMAGE.
30219019Sgabor */
31219019Sgabor
32219019Sgabor#include "atomic_op_asm.h"
33219019Sgabor
34219019Sgabor#if defined(_ARM_ARCH_6)
35219019Sgabor
36219019SgaborENTRY_NP(_atomic_xor_16)
37219019Sgabor	mov	ip, r0
38219019Sgabor1:	ldrexh	r0, [ip]		/* load old value (to be returned) */
39219019Sgabor	eors	r3, r0, r1		/* calculate new value */
40219019Sgabor	strexh	r2, r3, [ip]		/* try to store */
41219019Sgabor	cmp	r2, #0			/*   succeed? */
42219019Sgabor	bne	1b			/*     no, try again */
43219019Sgabor	RET				/* return old value */
44219019SgaborEND(_atomic_xor_16)
45219019Sgabor
46219019SgaborATOMIC_OP_ALIAS(atomic_xor_16,_atomic_xor_16)
47219019SgaborATOMIC_OP_ALIAS(atomic_xor_ushort,_atomic_xor_16)
48219019SgaborCRT_ALIAS(__atomic_fetch_xor_2,_atomic_xor_16)
49219019SgaborSTRONG_ALIAS(_atomic_xor_ushort,_atomic_xor_16)
50219019Sgabor
51219019SgaborENTRY_NP(__sync_fetch_and_xor_2)
52219019Sgabor	push	{r4, lr}
53219019Sgabor	DMB
54219019Sgabor	bl	_atomic_xor_16
55219019Sgabor	DMB
56219019Sgabor	pop	{r4, pc}
57219019SgaborEND(__sync_fetch_and_xor_2)
58219019Sgabor
59219019Sgabor
60219019SgaborENTRY_NP(_atomic_xor_16_nv)
61219019Sgabor	mov	ip, r0			/* need r0 for return value */
62219019Sgabor1:	ldrexh	r0, [ip]		/* load old value */
63219019Sgabor	eors	r0, r0, r1		/* calculate new value (return value) */
64219019Sgabor	strexh	r2, r0, [ip]		/* try to store */
65219019Sgabor	cmp	r2, #0			/*   succeed? */
66219019Sgabor	bne	1b			/*     no, try again? */
67219019Sgabor	RET				/* return new value */
68219019SgaborEND(_atomic_xor_16_nv)
69219019Sgabor
70219019SgaborATOMIC_OP_ALIAS(atomic_xor_16_nv,_atomic_xor_16_nv)
71219019SgaborATOMIC_OP_ALIAS(atomic_xor_ushort_nv,_atomic_xor_16_nv)
72219019SgaborSTRONG_ALIAS(_atomic_xor_ushort_nv,_atomic_xor_16_nv)
73219019Sgabor
74219019SgaborENTRY_NP(__sync_xor_and_fetch_2)
75219019Sgabor	push	{r4, lr}
76219019Sgabor	DMB
77219019Sgabor	bl	_atomic_xor_16_nv
78219019Sgabor	DMB
79219019Sgabor	pop	{r4, pc}
80219019SgaborEND(__sync_xor_and_fetch_2)
81219019Sgabor
82219019Sgabor#endif /* _ARM_ARCH_6 */
83219019Sgabor