xref: /netbsd-src/common/lib/libc/arch/powerpc/atomic/membar_ops.S (revision 4f8ce3b31dd3bccb2f78a8118c558aacc733ac7d)
1*4f8ce3b3Sriastradh/*	$NetBSD: membar_ops.S,v 1.6 2022/04/09 23:32:52 riastradh Exp $	*/
2bc7bf35cSad
3bc7bf35cSad/*-
4bc7bf35cSad * Copyright (c) 2007 The NetBSD Foundation, Inc.
5bc7bf35cSad * All rights reserved.
6bc7bf35cSad *
7bc7bf35cSad * This code is derived from software contributed to The NetBSD Foundation
8bc7bf35cSad * by Jason R. Thorpe, and by Andrew Doran.
9bc7bf35cSad *
10bc7bf35cSad * Redistribution and use in source and binary forms, with or without
11bc7bf35cSad * modification, are permitted provided that the following conditions
12bc7bf35cSad * are met:
13bc7bf35cSad * 1. Redistributions of source code must retain the above copyright
14bc7bf35cSad *    notice, this list of conditions and the following disclaimer.
15bc7bf35cSad * 2. Redistributions in binary form must reproduce the above copyright
16bc7bf35cSad *    notice, this list of conditions and the following disclaimer in the
17bc7bf35cSad *    documentation and/or other materials provided with the distribution.
18bc7bf35cSad *
19bc7bf35cSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20bc7bf35cSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21bc7bf35cSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22bc7bf35cSad * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23bc7bf35cSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24bc7bf35cSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25bc7bf35cSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26bc7bf35cSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27bc7bf35cSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28bc7bf35cSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29bc7bf35cSad * POSSIBILITY OF SUCH DAMAGE.
30bc7bf35cSad */
31bc7bf35cSad
32bc7bf35cSad#include "atomic_op_asm.h"
33bc7bf35cSad
34*4f8ce3b3Sriastradh__RCSID("$NetBSD: membar_ops.S,v 1.6 2022/04/09 23:32:52 riastradh Exp $")
35bc7bf35cSad
36cf88c389Smatt	.text
37bc7bf35cSad
38*4f8ce3b3SriastradhENTRY(_membar_acquire)
39*4f8ce3b3Sriastradh	/*
40*4f8ce3b3Sriastradh	 * It is tempting to use isync to order load-before-load/store.
41*4f8ce3b3Sriastradh	 * However, isync orders prior loads only if their value flows
42*4f8ce3b3Sriastradh	 * into a control-flow dependency prior to the isync:
43*4f8ce3b3Sriastradh	 *
44*4f8ce3b3Sriastradh	 *	`[I]f an isync follows a conditional Branch instruction
45*4f8ce3b3Sriastradh	 *	 that depends on the value returned by a preceding Load
46*4f8ce3b3Sriastradh	 *	 instruction, the load on which the Branch depends is
47*4f8ce3b3Sriastradh	 *	 performed before any loads caused by instructions
48*4f8ce3b3Sriastradh	 *	 following the isync. This applies even if the effects
49*4f8ce3b3Sriastradh	 *	 of the ``dependency'' are independent of the value
50*4f8ce3b3Sriastradh	 *	 loaded (e.g., the value is compared to itself and the
51*4f8ce3b3Sriastradh	 *	 Branch tests the EQ bit in the selected CR field), and
52*4f8ce3b3Sriastradh	 *	 even if the branch target is the sequentially next
53*4f8ce3b3Sriastradh	 *	 instruction.'
54*4f8ce3b3Sriastradh	 *
55*4f8ce3b3Sriastradh	 *	--PowerPC Virtual Environment Architecture, Book II,
56*4f8ce3b3Sriastradh	 *	  Version 2.01, December 2003, 1.7.1 `Storage Access
57*4f8ce3b3Sriastradh	 *	  Ordering', p. 7.
58*4f8ce3b3Sriastradh	 *
59*4f8ce3b3Sriastradh	 * We are required here, however, to order _all_ prior loads,
60*4f8ce3b3Sriastradh	 * even if they do not flow into any control flow dependency.
61*4f8ce3b3Sriastradh	 * For example:
62*4f8ce3b3Sriastradh	 *
63*4f8ce3b3Sriastradh	 *	x = *p;
64*4f8ce3b3Sriastradh	 *	membar_acquire();
65*4f8ce3b3Sriastradh	 *	if (x) goto foo;
66*4f8ce3b3Sriastradh	 *
67*4f8ce3b3Sriastradh	 * This can't be implemented by:
68*4f8ce3b3Sriastradh	 *
69*4f8ce3b3Sriastradh	 *	lwz	x, p
70*4f8ce3b3Sriastradh	 *	isync
71*4f8ce3b3Sriastradh	 *	cmpwi	x, 0
72*4f8ce3b3Sriastradh	 *	bne	foo
73*4f8ce3b3Sriastradh	 *
74*4f8ce3b3Sriastradh	 * isync doesn't work here because there's no conditional
75*4f8ce3b3Sriastradh	 * dependency on x between the lwz x, p and the isync.
76*4f8ce3b3Sriastradh	 *
77*4f8ce3b3Sriastradh	 * isync would only work if it followed the branch:
78*4f8ce3b3Sriastradh	 *
79*4f8ce3b3Sriastradh	 *	lwz	x, p
80*4f8ce3b3Sriastradh	 *	isync
81*4f8ce3b3Sriastradh	 *	cmpwi	x, 0
82*4f8ce3b3Sriastradh	 *	bne	foo
83*4f8ce3b3Sriastradh	 *	...
84*4f8ce3b3Sriastradh	 * foo:	isync
85*4f8ce3b3Sriastradh	 *	...
86*4f8ce3b3Sriastradh	 *
87*4f8ce3b3Sriastradh	 * lwsync orders everything except store-before-load, so it
88*4f8ce3b3Sriastradh	 * serves here -- see below in membar_release in lwsync.
89*4f8ce3b3Sriastradh	 * Except we can't use it on booke, so use sync for now.
90*4f8ce3b3Sriastradh	 */
91bc7bf35cSad	sync
92bc7bf35cSad	blr
93*4f8ce3b3SriastradhEND(_membar_acquire)
94*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_acquire,_membar_acquire)
95bc7bf35cSad
96*4f8ce3b3SriastradhENTRY(_membar_release)
97*4f8ce3b3Sriastradh	/*
98*4f8ce3b3Sriastradh	 *	`The memory barrier provides an ordering function for
99*4f8ce3b3Sriastradh	 *	 the storage accesses caused by Load, Store, and dcbz
100*4f8ce3b3Sriastradh	 *	 instructions that are executed by the processor
101*4f8ce3b3Sriastradh	 *	 executing the [lwsync] instruction and for which the
102*4f8ce3b3Sriastradh	 *	 specified storage location is in storage that is
103*4f8ce3b3Sriastradh	 *	 Memory Coherence Required and is neither Write Through
104*4f8ce3b3Sriastradh	 *	 Required nor Caching Inhibited.  The applicable pairs
105*4f8ce3b3Sriastradh	 *	 are all pairs a_i, b_j of such accesses except those
106*4f8ce3b3Sriastradh	 *	 in which a_i is an access caused by a Store or dcbz
107*4f8ce3b3Sriastradh	 *	 instruction and b_j is an access caused by a Load
108*4f8ce3b3Sriastradh	 *	 instruction.'
109*4f8ce3b3Sriastradh	 *
110*4f8ce3b3Sriastradh	 *	--PowerPC Virtual Environment Architecture, Book II,
111*4f8ce3b3Sriastradh	 *	  Version 2.01, December 2003, 3.3.3 `Memory Barrier
112*4f8ce3b3Sriastradh	 *	  Instructions', p. 25.
113*4f8ce3b3Sriastradh	 *
114*4f8ce3b3Sriastradh	 * In brief, lwsync is an acquire-release barrier -- it orders
115*4f8ce3b3Sriastradh	 * load-before-load/store and load/store-before-store, but not
116*4f8ce3b3Sriastradh	 * store-before-load.  Except we can't use it on booke, so use
117*4f8ce3b3Sriastradh	 * sync for now.
118*4f8ce3b3Sriastradh	 */
119*4f8ce3b3Sriastradh	sync
120*4f8ce3b3Sriastradh	blr
121*4f8ce3b3SriastradhEND(_membar_release)
122*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_release,_membar_release)
123*4f8ce3b3Sriastradh
124*4f8ce3b3SriastradhENTRY(_membar_sync)
125*4f8ce3b3Sriastradh	/*
126*4f8ce3b3Sriastradh	 * sync, or `heavyweight sync', is a full sequential
127*4f8ce3b3Sriastradh	 * consistency barrier.
128*4f8ce3b3Sriastradh	 */
129*4f8ce3b3Sriastradh	sync
130*4f8ce3b3Sriastradh	blr
131*4f8ce3b3SriastradhEND(_membar_sync)
132*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_sync,_membar_sync)
133*4f8ce3b3Sriastradh
134*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_producer,_membar_release)
135*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_producer,_membar_release)
136*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_consumer,_membar_acquire)
137*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_consumer,_membar_acquire)
138*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_enter,_membar_sync)
139*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_enter,_membar_sync)
140*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_exit,_membar_release)
141*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_exit,_membar_release)
142