xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/rseq/rseq-arm64.h (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2*053f45beSAndroid Build Coastguard Worker /*
3*053f45beSAndroid Build Coastguard Worker  * rseq-arm64.h
4*053f45beSAndroid Build Coastguard Worker  *
5*053f45beSAndroid Build Coastguard Worker  * (C) Copyright 2016-2018 - Mathieu Desnoyers <[email protected]>
6*053f45beSAndroid Build Coastguard Worker  * (C) Copyright 2018 - Will Deacon <[email protected]>
7*053f45beSAndroid Build Coastguard Worker  */
8*053f45beSAndroid Build Coastguard Worker 
9*053f45beSAndroid Build Coastguard Worker /*
10*053f45beSAndroid Build Coastguard Worker  * aarch64 -mbig-endian generates mixed endianness code vs data:
11*053f45beSAndroid Build Coastguard Worker  * little-endian code and big-endian data. Ensure the RSEQ_SIG signature
12*053f45beSAndroid Build Coastguard Worker  * matches code endianness.
13*053f45beSAndroid Build Coastguard Worker  */
14*053f45beSAndroid Build Coastguard Worker #define RSEQ_SIG_CODE	0xd428bc00	/* BRK #0x45E0.  */
15*053f45beSAndroid Build Coastguard Worker 
16*053f45beSAndroid Build Coastguard Worker #ifdef __AARCH64EB__
17*053f45beSAndroid Build Coastguard Worker #define RSEQ_SIG_DATA	0x00bc28d4	/* BRK #0x45E0.  */
18*053f45beSAndroid Build Coastguard Worker #else
19*053f45beSAndroid Build Coastguard Worker #define RSEQ_SIG_DATA	RSEQ_SIG_CODE
20*053f45beSAndroid Build Coastguard Worker #endif
21*053f45beSAndroid Build Coastguard Worker 
22*053f45beSAndroid Build Coastguard Worker #define RSEQ_SIG	RSEQ_SIG_DATA
23*053f45beSAndroid Build Coastguard Worker 
24*053f45beSAndroid Build Coastguard Worker #define rseq_smp_mb()	__asm__ __volatile__ ("dmb ish" ::: "memory")
25*053f45beSAndroid Build Coastguard Worker #define rseq_smp_rmb()	__asm__ __volatile__ ("dmb ishld" ::: "memory")
26*053f45beSAndroid Build Coastguard Worker #define rseq_smp_wmb()	__asm__ __volatile__ ("dmb ishst" ::: "memory")
27*053f45beSAndroid Build Coastguard Worker 
28*053f45beSAndroid Build Coastguard Worker #define rseq_smp_load_acquire(p)						\
29*053f45beSAndroid Build Coastguard Worker __extension__ ({								\
30*053f45beSAndroid Build Coastguard Worker 	__typeof(*p) ____p1;							\
31*053f45beSAndroid Build Coastguard Worker 	switch (sizeof(*p)) {							\
32*053f45beSAndroid Build Coastguard Worker 	case 1:									\
33*053f45beSAndroid Build Coastguard Worker 		asm volatile ("ldarb %w0, %1"					\
34*053f45beSAndroid Build Coastguard Worker 			: "=r" (*(__u8 *)p)					\
35*053f45beSAndroid Build Coastguard Worker 			: "Q" (*p) : "memory");					\
36*053f45beSAndroid Build Coastguard Worker 		break;								\
37*053f45beSAndroid Build Coastguard Worker 	case 2:									\
38*053f45beSAndroid Build Coastguard Worker 		asm volatile ("ldarh %w0, %1"					\
39*053f45beSAndroid Build Coastguard Worker 			: "=r" (*(__u16 *)p)					\
40*053f45beSAndroid Build Coastguard Worker 			: "Q" (*p) : "memory");					\
41*053f45beSAndroid Build Coastguard Worker 		break;								\
42*053f45beSAndroid Build Coastguard Worker 	case 4:									\
43*053f45beSAndroid Build Coastguard Worker 		asm volatile ("ldar %w0, %1"					\
44*053f45beSAndroid Build Coastguard Worker 			: "=r" (*(__u32 *)p)					\
45*053f45beSAndroid Build Coastguard Worker 			: "Q" (*p) : "memory");					\
46*053f45beSAndroid Build Coastguard Worker 		break;								\
47*053f45beSAndroid Build Coastguard Worker 	case 8:									\
48*053f45beSAndroid Build Coastguard Worker 		asm volatile ("ldar %0, %1"					\
49*053f45beSAndroid Build Coastguard Worker 			: "=r" (*(__u64 *)p)					\
50*053f45beSAndroid Build Coastguard Worker 			: "Q" (*p) : "memory");					\
51*053f45beSAndroid Build Coastguard Worker 		break;								\
52*053f45beSAndroid Build Coastguard Worker 	}									\
53*053f45beSAndroid Build Coastguard Worker 	____p1;									\
54*053f45beSAndroid Build Coastguard Worker })
55*053f45beSAndroid Build Coastguard Worker 
56*053f45beSAndroid Build Coastguard Worker #define rseq_smp_acquire__after_ctrl_dep()	rseq_smp_rmb()
57*053f45beSAndroid Build Coastguard Worker 
58*053f45beSAndroid Build Coastguard Worker #define rseq_smp_store_release(p, v)						\
59*053f45beSAndroid Build Coastguard Worker do {										\
60*053f45beSAndroid Build Coastguard Worker 	switch (sizeof(*p)) {							\
61*053f45beSAndroid Build Coastguard Worker 	case 1:									\
62*053f45beSAndroid Build Coastguard Worker 		asm volatile ("stlrb %w1, %0"					\
63*053f45beSAndroid Build Coastguard Worker 				: "=Q" (*p)					\
64*053f45beSAndroid Build Coastguard Worker 				: "r" ((__u8)v)					\
65*053f45beSAndroid Build Coastguard Worker 				: "memory");					\
66*053f45beSAndroid Build Coastguard Worker 		break;								\
67*053f45beSAndroid Build Coastguard Worker 	case 2:									\
68*053f45beSAndroid Build Coastguard Worker 		asm volatile ("stlrh %w1, %0"					\
69*053f45beSAndroid Build Coastguard Worker 				: "=Q" (*p)					\
70*053f45beSAndroid Build Coastguard Worker 				: "r" ((__u16)v)				\
71*053f45beSAndroid Build Coastguard Worker 				: "memory");					\
72*053f45beSAndroid Build Coastguard Worker 		break;								\
73*053f45beSAndroid Build Coastguard Worker 	case 4:									\
74*053f45beSAndroid Build Coastguard Worker 		asm volatile ("stlr %w1, %0"					\
75*053f45beSAndroid Build Coastguard Worker 				: "=Q" (*p)					\
76*053f45beSAndroid Build Coastguard Worker 				: "r" ((__u32)v)				\
77*053f45beSAndroid Build Coastguard Worker 				: "memory");					\
78*053f45beSAndroid Build Coastguard Worker 		break;								\
79*053f45beSAndroid Build Coastguard Worker 	case 8:									\
80*053f45beSAndroid Build Coastguard Worker 		asm volatile ("stlr %1, %0"					\
81*053f45beSAndroid Build Coastguard Worker 				: "=Q" (*p)					\
82*053f45beSAndroid Build Coastguard Worker 				: "r" ((__u64)v)				\
83*053f45beSAndroid Build Coastguard Worker 				: "memory");					\
84*053f45beSAndroid Build Coastguard Worker 		break;								\
85*053f45beSAndroid Build Coastguard Worker 	}									\
86*053f45beSAndroid Build Coastguard Worker } while (0)
87*053f45beSAndroid Build Coastguard Worker 
88*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_SKIP_FASTPATH
89*053f45beSAndroid Build Coastguard Worker #include "rseq-skip.h"
90*053f45beSAndroid Build Coastguard Worker #else /* !RSEQ_SKIP_FASTPATH */
91*053f45beSAndroid Build Coastguard Worker 
92*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_TMP_REG32	"w15"
93*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_TMP_REG	"x15"
94*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_TMP_REG_2	"x14"
95*053f45beSAndroid Build Coastguard Worker 
96*053f45beSAndroid Build Coastguard Worker #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip,		\
97*053f45beSAndroid Build Coastguard Worker 				post_commit_offset, abort_ip)			\
98*053f45beSAndroid Build Coastguard Worker 	"	.pushsection	__rseq_cs, \"aw\"\n"				\
99*053f45beSAndroid Build Coastguard Worker 	"	.balign	32\n"							\
100*053f45beSAndroid Build Coastguard Worker 	__rseq_str(label) ":\n"							\
101*053f45beSAndroid Build Coastguard Worker 	"	.long	" __rseq_str(version) ", " __rseq_str(flags) "\n"	\
102*053f45beSAndroid Build Coastguard Worker 	"	.quad	" __rseq_str(start_ip) ", "				\
103*053f45beSAndroid Build Coastguard Worker 			  __rseq_str(post_commit_offset) ", "			\
104*053f45beSAndroid Build Coastguard Worker 			  __rseq_str(abort_ip) "\n"				\
105*053f45beSAndroid Build Coastguard Worker 	"	.popsection\n\t"						\
106*053f45beSAndroid Build Coastguard Worker 	"	.pushsection __rseq_cs_ptr_array, \"aw\"\n"				\
107*053f45beSAndroid Build Coastguard Worker 	"	.quad " __rseq_str(label) "b\n"					\
108*053f45beSAndroid Build Coastguard Worker 	"	.popsection\n"
109*053f45beSAndroid Build Coastguard Worker 
110*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip)	\
111*053f45beSAndroid Build Coastguard Worker 	__RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip,			\
112*053f45beSAndroid Build Coastguard Worker 				(post_commit_ip - start_ip), abort_ip)
113*053f45beSAndroid Build Coastguard Worker 
114*053f45beSAndroid Build Coastguard Worker /*
115*053f45beSAndroid Build Coastguard Worker  * Exit points of a rseq critical section consist of all instructions outside
116*053f45beSAndroid Build Coastguard Worker  * of the critical section where a critical section can either branch to or
117*053f45beSAndroid Build Coastguard Worker  * reach through the normal course of its execution. The abort IP and the
118*053f45beSAndroid Build Coastguard Worker  * post-commit IP are already part of the __rseq_cs section and should not be
119*053f45beSAndroid Build Coastguard Worker  * explicitly defined as additional exit points. Knowing all exit points is
120*053f45beSAndroid Build Coastguard Worker  * useful to assist debuggers stepping over the critical section.
121*053f45beSAndroid Build Coastguard Worker  */
122*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip)				\
123*053f45beSAndroid Build Coastguard Worker 	"	.pushsection __rseq_exit_point_array, \"aw\"\n"			\
124*053f45beSAndroid Build Coastguard Worker 	"	.quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n"	\
125*053f45beSAndroid Build Coastguard Worker 	"	.popsection\n"
126*053f45beSAndroid Build Coastguard Worker 
127*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs)			\
128*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_ASM(1)							\
129*053f45beSAndroid Build Coastguard Worker 	"	adrp	" RSEQ_ASM_TMP_REG ", " __rseq_str(cs_label) "\n"	\
130*053f45beSAndroid Build Coastguard Worker 	"	add	" RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG		\
131*053f45beSAndroid Build Coastguard Worker 			", :lo12:" __rseq_str(cs_label) "\n"			\
132*053f45beSAndroid Build Coastguard Worker 	"	str	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(rseq_cs) "]\n"	\
133*053f45beSAndroid Build Coastguard Worker 	__rseq_str(label) ":\n"
134*053f45beSAndroid Build Coastguard Worker 
135*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_ABORT(label, abort_label)				\
136*053f45beSAndroid Build Coastguard Worker 	"	b	222f\n"							\
137*053f45beSAndroid Build Coastguard Worker 	"	.inst 	"	__rseq_str(RSEQ_SIG_CODE) "\n"			\
138*053f45beSAndroid Build Coastguard Worker 	__rseq_str(label) ":\n"							\
139*053f45beSAndroid Build Coastguard Worker 	"	b	%l[" __rseq_str(abort_label) "]\n"			\
140*053f45beSAndroid Build Coastguard Worker 	"222:\n"
141*053f45beSAndroid Build Coastguard Worker 
142*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_STORE(value, var)						\
143*053f45beSAndroid Build Coastguard Worker 	"	str	%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n"
144*053f45beSAndroid Build Coastguard Worker 
145*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_STORE_RELEASE(value, var)					\
146*053f45beSAndroid Build Coastguard Worker 	"	stlr	%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n"
147*053f45beSAndroid Build Coastguard Worker 
148*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label)			\
149*053f45beSAndroid Build Coastguard Worker 	RSEQ_ASM_OP_STORE(value, var)						\
150*053f45beSAndroid Build Coastguard Worker 	__rseq_str(post_commit_label) ":\n"
151*053f45beSAndroid Build Coastguard Worker 
152*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_FINAL_STORE_RELEASE(value, var, post_commit_label)		\
153*053f45beSAndroid Build Coastguard Worker 	RSEQ_ASM_OP_STORE_RELEASE(value, var)					\
154*053f45beSAndroid Build Coastguard Worker 	__rseq_str(post_commit_label) ":\n"
155*053f45beSAndroid Build Coastguard Worker 
156*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_CMPEQ(var, expect, label)					\
157*053f45beSAndroid Build Coastguard Worker 	"	ldr	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"		\
158*053f45beSAndroid Build Coastguard Worker 	"	sub	" RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG		\
159*053f45beSAndroid Build Coastguard Worker 			", %[" __rseq_str(expect) "]\n"				\
160*053f45beSAndroid Build Coastguard Worker 	"	cbnz	" RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n"
161*053f45beSAndroid Build Coastguard Worker 
162*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_CMPEQ32(var, expect, label)					\
163*053f45beSAndroid Build Coastguard Worker 	"	ldr	" RSEQ_ASM_TMP_REG32 ", %[" __rseq_str(var) "]\n"	\
164*053f45beSAndroid Build Coastguard Worker 	"	sub	" RSEQ_ASM_TMP_REG32 ", " RSEQ_ASM_TMP_REG32		\
165*053f45beSAndroid Build Coastguard Worker 			", %w[" __rseq_str(expect) "]\n"			\
166*053f45beSAndroid Build Coastguard Worker 	"	cbnz	" RSEQ_ASM_TMP_REG32 ", " __rseq_str(label) "\n"
167*053f45beSAndroid Build Coastguard Worker 
168*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_CMPNE(var, expect, label)					\
169*053f45beSAndroid Build Coastguard Worker 	"	ldr	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"		\
170*053f45beSAndroid Build Coastguard Worker 	"	sub	" RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG		\
171*053f45beSAndroid Build Coastguard Worker 			", %[" __rseq_str(expect) "]\n"				\
172*053f45beSAndroid Build Coastguard Worker 	"	cbz	" RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n"
173*053f45beSAndroid Build Coastguard Worker 
174*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label)			\
175*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_ASM(2)							\
176*053f45beSAndroid Build Coastguard Worker 	RSEQ_ASM_OP_CMPEQ32(current_cpu_id, cpu_id, label)
177*053f45beSAndroid Build Coastguard Worker 
178*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_LOAD(var)							\
179*053f45beSAndroid Build Coastguard Worker 	"	ldr	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"
180*053f45beSAndroid Build Coastguard Worker 
181*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_STORE(var)						\
182*053f45beSAndroid Build Coastguard Worker 	"	str	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"
183*053f45beSAndroid Build Coastguard Worker 
184*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_LOAD_OFF(offset)						\
185*053f45beSAndroid Build Coastguard Worker 	"	ldr	" RSEQ_ASM_TMP_REG ", [" RSEQ_ASM_TMP_REG		\
186*053f45beSAndroid Build Coastguard Worker 			", %[" __rseq_str(offset) "]]\n"
187*053f45beSAndroid Build Coastguard Worker 
188*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_ADD(count)						\
189*053f45beSAndroid Build Coastguard Worker 	"	add	" RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG		\
190*053f45beSAndroid Build Coastguard Worker 			", %[" __rseq_str(count) "]\n"
191*053f45beSAndroid Build Coastguard Worker 
192*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label)			\
193*053f45beSAndroid Build Coastguard Worker 	"	str	" RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"		\
194*053f45beSAndroid Build Coastguard Worker 	__rseq_str(post_commit_label) ":\n"
195*053f45beSAndroid Build Coastguard Worker 
196*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)					\
197*053f45beSAndroid Build Coastguard Worker 	"	cbz	%[" __rseq_str(len) "], 333f\n"				\
198*053f45beSAndroid Build Coastguard Worker 	"	mov	" RSEQ_ASM_TMP_REG_2 ", %[" __rseq_str(len) "]\n"	\
199*053f45beSAndroid Build Coastguard Worker 	"222:	sub	" RSEQ_ASM_TMP_REG_2 ", " RSEQ_ASM_TMP_REG_2 ", #1\n"	\
200*053f45beSAndroid Build Coastguard Worker 	"	ldrb	" RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(src) "]"	\
201*053f45beSAndroid Build Coastguard Worker 			", " RSEQ_ASM_TMP_REG_2 "]\n"				\
202*053f45beSAndroid Build Coastguard Worker 	"	strb	" RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(dst) "]"	\
203*053f45beSAndroid Build Coastguard Worker 			", " RSEQ_ASM_TMP_REG_2 "]\n"				\
204*053f45beSAndroid Build Coastguard Worker 	"	cbnz	" RSEQ_ASM_TMP_REG_2 ", 222b\n"				\
205*053f45beSAndroid Build Coastguard Worker 	"333:\n"
206*053f45beSAndroid Build Coastguard Worker 
207*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_storev(intptr_t * v,intptr_t expect,intptr_t newv,int cpu)208*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
209*053f45beSAndroid Build Coastguard Worker {
210*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
211*053f45beSAndroid Build Coastguard Worker 
212*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
213*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
214*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
215*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
216*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
217*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
218*053f45beSAndroid Build Coastguard Worker #endif
219*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
220*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
221*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
222*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
223*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
224*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
225*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
226*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
227*053f45beSAndroid Build Coastguard Worker #endif
228*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
229*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
230*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
231*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
232*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
233*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
234*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
235*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
236*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
237*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv)
238*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
239*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
240*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
241*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
242*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
243*053f45beSAndroid Build Coastguard Worker #endif
244*053f45beSAndroid Build Coastguard Worker 	);
245*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
246*053f45beSAndroid Build Coastguard Worker 	return 0;
247*053f45beSAndroid Build Coastguard Worker abort:
248*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
249*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
250*053f45beSAndroid Build Coastguard Worker 	return -1;
251*053f45beSAndroid Build Coastguard Worker cmpfail:
252*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
253*053f45beSAndroid Build Coastguard Worker 	return 1;
254*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
255*053f45beSAndroid Build Coastguard Worker error1:
256*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
257*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
258*053f45beSAndroid Build Coastguard Worker error2:
259*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
260*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
261*053f45beSAndroid Build Coastguard Worker #endif
262*053f45beSAndroid Build Coastguard Worker }
263*053f45beSAndroid Build Coastguard Worker 
264*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpnev_storeoffp_load(intptr_t * v,intptr_t expectnot,long voffp,intptr_t * load,int cpu)265*053f45beSAndroid Build Coastguard Worker int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
266*053f45beSAndroid Build Coastguard Worker 			       long voffp, intptr_t *load, int cpu)
267*053f45beSAndroid Build Coastguard Worker {
268*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
269*053f45beSAndroid Build Coastguard Worker 
270*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
271*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
272*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
273*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
274*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
275*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
276*053f45beSAndroid Build Coastguard Worker #endif
277*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
278*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
279*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
280*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPNE(v, expectnot, %l[cmpfail])
281*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
282*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
283*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
284*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPNE(v, expectnot, %l[error2])
285*053f45beSAndroid Build Coastguard Worker #endif
286*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_LOAD(v)
287*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_STORE(load)
288*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_LOAD_OFF(voffp)
289*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
290*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
291*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
292*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
293*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
294*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
295*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
296*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
297*053f45beSAndroid Build Coastguard Worker 		  [expectnot]		"r" (expectnot),
298*053f45beSAndroid Build Coastguard Worker 		  [load]		"Qo" (*load),
299*053f45beSAndroid Build Coastguard Worker 		  [voffp]		"r" (voffp)
300*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
301*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
302*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
303*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
304*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
305*053f45beSAndroid Build Coastguard Worker #endif
306*053f45beSAndroid Build Coastguard Worker 	);
307*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
308*053f45beSAndroid Build Coastguard Worker 	return 0;
309*053f45beSAndroid Build Coastguard Worker abort:
310*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
311*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
312*053f45beSAndroid Build Coastguard Worker 	return -1;
313*053f45beSAndroid Build Coastguard Worker cmpfail:
314*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
315*053f45beSAndroid Build Coastguard Worker 	return 1;
316*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
317*053f45beSAndroid Build Coastguard Worker error1:
318*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
319*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
320*053f45beSAndroid Build Coastguard Worker error2:
321*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
322*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
323*053f45beSAndroid Build Coastguard Worker #endif
324*053f45beSAndroid Build Coastguard Worker }
325*053f45beSAndroid Build Coastguard Worker 
326*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_addv(intptr_t * v,intptr_t count,int cpu)327*053f45beSAndroid Build Coastguard Worker int rseq_addv(intptr_t *v, intptr_t count, int cpu)
328*053f45beSAndroid Build Coastguard Worker {
329*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
330*053f45beSAndroid Build Coastguard Worker 
331*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
332*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
333*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
334*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
335*053f45beSAndroid Build Coastguard Worker #endif
336*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
337*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
338*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
339*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
340*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
341*053f45beSAndroid Build Coastguard Worker #endif
342*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_LOAD(v)
343*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_ADD(count)
344*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
345*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
346*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
347*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
348*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
349*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
350*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
351*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
352*053f45beSAndroid Build Coastguard Worker 		  [count]		"r" (count)
353*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
354*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
355*053f45beSAndroid Build Coastguard Worker 		: abort
356*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
357*053f45beSAndroid Build Coastguard Worker 		  , error1
358*053f45beSAndroid Build Coastguard Worker #endif
359*053f45beSAndroid Build Coastguard Worker 	);
360*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
361*053f45beSAndroid Build Coastguard Worker 	return 0;
362*053f45beSAndroid Build Coastguard Worker abort:
363*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
364*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
365*053f45beSAndroid Build Coastguard Worker 	return -1;
366*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
367*053f45beSAndroid Build Coastguard Worker error1:
368*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
369*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
370*053f45beSAndroid Build Coastguard Worker #endif
371*053f45beSAndroid Build Coastguard Worker }
372*053f45beSAndroid Build Coastguard Worker 
373*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_trystorev_storev(intptr_t * v,intptr_t expect,intptr_t * v2,intptr_t newv2,intptr_t newv,int cpu)374*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
375*053f45beSAndroid Build Coastguard Worker 				 intptr_t *v2, intptr_t newv2,
376*053f45beSAndroid Build Coastguard Worker 				 intptr_t newv, int cpu)
377*053f45beSAndroid Build Coastguard Worker {
378*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
379*053f45beSAndroid Build Coastguard Worker 
380*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
381*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
382*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
383*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
384*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
385*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
386*053f45beSAndroid Build Coastguard Worker #endif
387*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
388*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
389*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
390*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
391*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
392*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
393*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
394*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
395*053f45beSAndroid Build Coastguard Worker #endif
396*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_STORE(newv2, v2)
397*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
398*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
399*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(6)
400*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
401*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
402*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
403*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
404*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
405*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
406*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
407*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv),
408*053f45beSAndroid Build Coastguard Worker 		  [v2]			"Qo" (*v2),
409*053f45beSAndroid Build Coastguard Worker 		  [newv2]		"r" (newv2)
410*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
411*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
412*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
413*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
414*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
415*053f45beSAndroid Build Coastguard Worker #endif
416*053f45beSAndroid Build Coastguard Worker 	);
417*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
418*053f45beSAndroid Build Coastguard Worker 	return 0;
419*053f45beSAndroid Build Coastguard Worker abort:
420*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
421*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
422*053f45beSAndroid Build Coastguard Worker 	return -1;
423*053f45beSAndroid Build Coastguard Worker cmpfail:
424*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
425*053f45beSAndroid Build Coastguard Worker 	return 1;
426*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
427*053f45beSAndroid Build Coastguard Worker error1:
428*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
429*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
430*053f45beSAndroid Build Coastguard Worker error2:
431*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
432*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
433*053f45beSAndroid Build Coastguard Worker #endif
434*053f45beSAndroid Build Coastguard Worker }
435*053f45beSAndroid Build Coastguard Worker 
436*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_trystorev_storev_release(intptr_t * v,intptr_t expect,intptr_t * v2,intptr_t newv2,intptr_t newv,int cpu)437*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
438*053f45beSAndroid Build Coastguard Worker 					 intptr_t *v2, intptr_t newv2,
439*053f45beSAndroid Build Coastguard Worker 					 intptr_t newv, int cpu)
440*053f45beSAndroid Build Coastguard Worker {
441*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
442*053f45beSAndroid Build Coastguard Worker 
443*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
444*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
445*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
446*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
447*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
448*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
449*053f45beSAndroid Build Coastguard Worker #endif
450*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
451*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
452*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
453*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
454*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
455*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
456*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
457*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
458*053f45beSAndroid Build Coastguard Worker #endif
459*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_STORE(newv2, v2)
460*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
461*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3)
462*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(6)
463*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
464*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
465*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
466*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
467*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
468*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
469*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
470*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv),
471*053f45beSAndroid Build Coastguard Worker 		  [v2]			"Qo" (*v2),
472*053f45beSAndroid Build Coastguard Worker 		  [newv2]		"r" (newv2)
473*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
474*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
475*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
476*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
477*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
478*053f45beSAndroid Build Coastguard Worker #endif
479*053f45beSAndroid Build Coastguard Worker 	);
480*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
481*053f45beSAndroid Build Coastguard Worker 	return 0;
482*053f45beSAndroid Build Coastguard Worker abort:
483*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
484*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
485*053f45beSAndroid Build Coastguard Worker 	return -1;
486*053f45beSAndroid Build Coastguard Worker cmpfail:
487*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
488*053f45beSAndroid Build Coastguard Worker 	return 1;
489*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
490*053f45beSAndroid Build Coastguard Worker error1:
491*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
492*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
493*053f45beSAndroid Build Coastguard Worker error2:
494*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
495*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
496*053f45beSAndroid Build Coastguard Worker #endif
497*053f45beSAndroid Build Coastguard Worker }
498*053f45beSAndroid Build Coastguard Worker 
499*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_cmpeqv_storev(intptr_t * v,intptr_t expect,intptr_t * v2,intptr_t expect2,intptr_t newv,int cpu)500*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
501*053f45beSAndroid Build Coastguard Worker 			      intptr_t *v2, intptr_t expect2,
502*053f45beSAndroid Build Coastguard Worker 			      intptr_t newv, int cpu)
503*053f45beSAndroid Build Coastguard Worker {
504*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
505*053f45beSAndroid Build Coastguard Worker 
506*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
507*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
508*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
509*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
510*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
511*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
512*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error3])
513*053f45beSAndroid Build Coastguard Worker #endif
514*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
515*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
516*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
517*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
518*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
519*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[cmpfail])
520*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
521*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
522*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
523*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
524*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[error3])
525*053f45beSAndroid Build Coastguard Worker #endif
526*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
527*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(6)
528*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
529*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
530*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
531*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
532*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
533*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
534*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
535*053f45beSAndroid Build Coastguard Worker 		  [v2]			"Qo" (*v2),
536*053f45beSAndroid Build Coastguard Worker 		  [expect2]		"r" (expect2),
537*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv)
538*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
539*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG
540*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
541*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
542*053f45beSAndroid Build Coastguard Worker 		  , error1, error2, error3
543*053f45beSAndroid Build Coastguard Worker #endif
544*053f45beSAndroid Build Coastguard Worker 	);
545*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
546*053f45beSAndroid Build Coastguard Worker 	return 0;
547*053f45beSAndroid Build Coastguard Worker abort:
548*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
549*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
550*053f45beSAndroid Build Coastguard Worker 	return -1;
551*053f45beSAndroid Build Coastguard Worker cmpfail:
552*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
553*053f45beSAndroid Build Coastguard Worker 	return 1;
554*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
555*053f45beSAndroid Build Coastguard Worker error1:
556*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
557*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
558*053f45beSAndroid Build Coastguard Worker error2:
559*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
560*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
561*053f45beSAndroid Build Coastguard Worker error3:
562*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
563*053f45beSAndroid Build Coastguard Worker 	rseq_bug("2nd expected value comparison failed");
564*053f45beSAndroid Build Coastguard Worker #endif
565*053f45beSAndroid Build Coastguard Worker }
566*053f45beSAndroid Build Coastguard Worker 
567*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_trymemcpy_storev(intptr_t * v,intptr_t expect,void * dst,void * src,size_t len,intptr_t newv,int cpu)568*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
569*053f45beSAndroid Build Coastguard Worker 				 void *dst, void *src, size_t len,
570*053f45beSAndroid Build Coastguard Worker 				 intptr_t newv, int cpu)
571*053f45beSAndroid Build Coastguard Worker {
572*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
573*053f45beSAndroid Build Coastguard Worker 
574*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
575*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
576*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
577*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
578*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
579*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
580*053f45beSAndroid Build Coastguard Worker #endif
581*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
582*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
583*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
584*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
585*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
586*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
587*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
588*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
589*053f45beSAndroid Build Coastguard Worker #endif
590*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)
591*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
592*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
593*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(6)
594*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
595*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
596*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
597*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
598*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
599*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
600*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
601*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv),
602*053f45beSAndroid Build Coastguard Worker 		  [dst]			"r" (dst),
603*053f45beSAndroid Build Coastguard Worker 		  [src]			"r" (src),
604*053f45beSAndroid Build Coastguard Worker 		  [len]			"r" (len)
605*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
606*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2
607*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
608*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
609*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
610*053f45beSAndroid Build Coastguard Worker #endif
611*053f45beSAndroid Build Coastguard Worker 	);
612*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
613*053f45beSAndroid Build Coastguard Worker 	return 0;
614*053f45beSAndroid Build Coastguard Worker abort:
615*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
616*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
617*053f45beSAndroid Build Coastguard Worker 	return -1;
618*053f45beSAndroid Build Coastguard Worker cmpfail:
619*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
620*053f45beSAndroid Build Coastguard Worker 	return 1;
621*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
622*053f45beSAndroid Build Coastguard Worker error1:
623*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
624*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
625*053f45beSAndroid Build Coastguard Worker error2:
626*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
627*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
628*053f45beSAndroid Build Coastguard Worker #endif
629*053f45beSAndroid Build Coastguard Worker }
630*053f45beSAndroid Build Coastguard Worker 
631*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_trymemcpy_storev_release(intptr_t * v,intptr_t expect,void * dst,void * src,size_t len,intptr_t newv,int cpu)632*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
633*053f45beSAndroid Build Coastguard Worker 					 void *dst, void *src, size_t len,
634*053f45beSAndroid Build Coastguard Worker 					 intptr_t newv, int cpu)
635*053f45beSAndroid Build Coastguard Worker {
636*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_C(9)
637*053f45beSAndroid Build Coastguard Worker 
638*053f45beSAndroid Build Coastguard Worker 	__asm__ __volatile__ goto (
639*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
640*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[cmpfail])
641*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
642*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error1])
643*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_EXIT_POINT(2f, %l[error2])
644*053f45beSAndroid Build Coastguard Worker #endif
645*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
646*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
647*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(3)
648*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
649*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(4)
650*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
651*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
652*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
653*053f45beSAndroid Build Coastguard Worker #endif
654*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)
655*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(5)
656*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3)
657*053f45beSAndroid Build Coastguard Worker 		RSEQ_INJECT_ASM(6)
658*053f45beSAndroid Build Coastguard Worker 		RSEQ_ASM_DEFINE_ABORT(4, abort)
659*053f45beSAndroid Build Coastguard Worker 		: /* gcc asm goto does not allow outputs */
660*053f45beSAndroid Build Coastguard Worker 		: [cpu_id]		"r" (cpu),
661*053f45beSAndroid Build Coastguard Worker 		  [current_cpu_id]	"Qo" (rseq_get_abi()->cpu_id),
662*053f45beSAndroid Build Coastguard Worker 		  [rseq_cs]		"m" (rseq_get_abi()->rseq_cs.arch.ptr),
663*053f45beSAndroid Build Coastguard Worker 		  [expect]		"r" (expect),
664*053f45beSAndroid Build Coastguard Worker 		  [v]			"Qo" (*v),
665*053f45beSAndroid Build Coastguard Worker 		  [newv]		"r" (newv),
666*053f45beSAndroid Build Coastguard Worker 		  [dst]			"r" (dst),
667*053f45beSAndroid Build Coastguard Worker 		  [src]			"r" (src),
668*053f45beSAndroid Build Coastguard Worker 		  [len]			"r" (len)
669*053f45beSAndroid Build Coastguard Worker 		  RSEQ_INJECT_INPUT
670*053f45beSAndroid Build Coastguard Worker 		: "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2
671*053f45beSAndroid Build Coastguard Worker 		: abort, cmpfail
672*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
673*053f45beSAndroid Build Coastguard Worker 		  , error1, error2
674*053f45beSAndroid Build Coastguard Worker #endif
675*053f45beSAndroid Build Coastguard Worker 	);
676*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
677*053f45beSAndroid Build Coastguard Worker 	return 0;
678*053f45beSAndroid Build Coastguard Worker abort:
679*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
680*053f45beSAndroid Build Coastguard Worker 	RSEQ_INJECT_FAILED
681*053f45beSAndroid Build Coastguard Worker 	return -1;
682*053f45beSAndroid Build Coastguard Worker cmpfail:
683*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
684*053f45beSAndroid Build Coastguard Worker 	return 1;
685*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
686*053f45beSAndroid Build Coastguard Worker error1:
687*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
688*053f45beSAndroid Build Coastguard Worker 	rseq_bug("cpu_id comparison failed");
689*053f45beSAndroid Build Coastguard Worker error2:
690*053f45beSAndroid Build Coastguard Worker 	rseq_after_asm_goto();
691*053f45beSAndroid Build Coastguard Worker 	rseq_bug("expected value comparison failed");
692*053f45beSAndroid Build Coastguard Worker #endif
693*053f45beSAndroid Build Coastguard Worker }
694*053f45beSAndroid Build Coastguard Worker 
695*053f45beSAndroid Build Coastguard Worker #endif /* !RSEQ_SKIP_FASTPATH */
696