1*053f45beSAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2*053f45beSAndroid Build Coastguard Worker /*
3*053f45beSAndroid Build Coastguard Worker * rseq-ppc.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 2016-2018 - Boqun Feng <[email protected]>
7*053f45beSAndroid Build Coastguard Worker */
8*053f45beSAndroid Build Coastguard Worker
9*053f45beSAndroid Build Coastguard Worker /*
10*053f45beSAndroid Build Coastguard Worker * RSEQ_SIG is used with the following trap instruction:
11*053f45beSAndroid Build Coastguard Worker *
12*053f45beSAndroid Build Coastguard Worker * powerpc-be: 0f e5 00 0b twui r5,11
13*053f45beSAndroid Build Coastguard Worker * powerpc64-le: 0b 00 e5 0f twui r5,11
14*053f45beSAndroid Build Coastguard Worker * powerpc64-be: 0f e5 00 0b twui r5,11
15*053f45beSAndroid Build Coastguard Worker */
16*053f45beSAndroid Build Coastguard Worker
17*053f45beSAndroid Build Coastguard Worker #define RSEQ_SIG 0x0fe5000b
18*053f45beSAndroid Build Coastguard Worker
19*053f45beSAndroid Build Coastguard Worker #define rseq_smp_mb() __asm__ __volatile__ ("sync" ::: "memory", "cc")
20*053f45beSAndroid Build Coastguard Worker #define rseq_smp_lwsync() __asm__ __volatile__ ("lwsync" ::: "memory", "cc")
21*053f45beSAndroid Build Coastguard Worker #define rseq_smp_rmb() rseq_smp_lwsync()
22*053f45beSAndroid Build Coastguard Worker #define rseq_smp_wmb() rseq_smp_lwsync()
23*053f45beSAndroid Build Coastguard Worker
24*053f45beSAndroid Build Coastguard Worker #define rseq_smp_load_acquire(p) \
25*053f45beSAndroid Build Coastguard Worker __extension__ ({ \
26*053f45beSAndroid Build Coastguard Worker __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \
27*053f45beSAndroid Build Coastguard Worker rseq_smp_lwsync(); \
28*053f45beSAndroid Build Coastguard Worker ____p1; \
29*053f45beSAndroid Build Coastguard Worker })
30*053f45beSAndroid Build Coastguard Worker
31*053f45beSAndroid Build Coastguard Worker #define rseq_smp_acquire__after_ctrl_dep() rseq_smp_lwsync()
32*053f45beSAndroid Build Coastguard Worker
33*053f45beSAndroid Build Coastguard Worker #define rseq_smp_store_release(p, v) \
34*053f45beSAndroid Build Coastguard Worker do { \
35*053f45beSAndroid Build Coastguard Worker rseq_smp_lwsync(); \
36*053f45beSAndroid Build Coastguard Worker RSEQ_WRITE_ONCE(*p, v); \
37*053f45beSAndroid Build Coastguard Worker } while (0)
38*053f45beSAndroid Build Coastguard Worker
39*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_SKIP_FASTPATH
40*053f45beSAndroid Build Coastguard Worker #include "rseq-skip.h"
41*053f45beSAndroid Build Coastguard Worker #else /* !RSEQ_SKIP_FASTPATH */
42*053f45beSAndroid Build Coastguard Worker
43*053f45beSAndroid Build Coastguard Worker /*
44*053f45beSAndroid Build Coastguard Worker * The __rseq_cs_ptr_array and __rseq_cs sections can be used by debuggers to
45*053f45beSAndroid Build Coastguard Worker * better handle single-stepping through the restartable critical sections.
46*053f45beSAndroid Build Coastguard Worker */
47*053f45beSAndroid Build Coastguard Worker
48*053f45beSAndroid Build Coastguard Worker #ifdef __PPC64__
49*053f45beSAndroid Build Coastguard Worker
50*053f45beSAndroid Build Coastguard Worker #define RSEQ_STORE_LONG(arg) "std%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
51*053f45beSAndroid Build Coastguard Worker #define RSEQ_STORE_INT(arg) "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
52*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOAD_LONG(arg) "ld%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
53*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOAD_INT(arg) "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
54*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOADX_LONG "ldx " /* From base register ("b" constraint) */
55*053f45beSAndroid Build Coastguard Worker #define RSEQ_CMP_LONG "cmpd "
56*053f45beSAndroid Build Coastguard Worker #define RSEQ_CMP_LONG_INT "cmpdi "
57*053f45beSAndroid Build Coastguard Worker
58*053f45beSAndroid Build Coastguard Worker #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
59*053f45beSAndroid Build Coastguard Worker start_ip, post_commit_offset, abort_ip) \
60*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_cs, \"aw\"\n\t" \
61*053f45beSAndroid Build Coastguard Worker ".balign 32\n\t" \
62*053f45beSAndroid Build Coastguard Worker __rseq_str(label) ":\n\t" \
63*053f45beSAndroid Build Coastguard Worker ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
64*053f45beSAndroid Build Coastguard Worker ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \
65*053f45beSAndroid Build Coastguard Worker ".popsection\n\t" \
66*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \
67*053f45beSAndroid Build Coastguard Worker ".quad " __rseq_str(label) "b\n\t" \
68*053f45beSAndroid Build Coastguard Worker ".popsection\n\t"
69*053f45beSAndroid Build Coastguard Worker
70*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
71*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(1) \
72*053f45beSAndroid Build Coastguard Worker "lis %%r17, (" __rseq_str(cs_label) ")@highest\n\t" \
73*053f45beSAndroid Build Coastguard Worker "ori %%r17, %%r17, (" __rseq_str(cs_label) ")@higher\n\t" \
74*053f45beSAndroid Build Coastguard Worker "rldicr %%r17, %%r17, 32, 31\n\t" \
75*053f45beSAndroid Build Coastguard Worker "oris %%r17, %%r17, (" __rseq_str(cs_label) ")@high\n\t" \
76*053f45beSAndroid Build Coastguard Worker "ori %%r17, %%r17, (" __rseq_str(cs_label) ")@l\n\t" \
77*053f45beSAndroid Build Coastguard Worker "std %%r17, %[" __rseq_str(rseq_cs) "]\n\t" \
78*053f45beSAndroid Build Coastguard Worker __rseq_str(label) ":\n\t"
79*053f45beSAndroid Build Coastguard Worker
80*053f45beSAndroid Build Coastguard Worker /*
81*053f45beSAndroid Build Coastguard Worker * Exit points of a rseq critical section consist of all instructions outside
82*053f45beSAndroid Build Coastguard Worker * of the critical section where a critical section can either branch to or
83*053f45beSAndroid Build Coastguard Worker * reach through the normal course of its execution. The abort IP and the
84*053f45beSAndroid Build Coastguard Worker * post-commit IP are already part of the __rseq_cs section and should not be
85*053f45beSAndroid Build Coastguard Worker * explicitly defined as additional exit points. Knowing all exit points is
86*053f45beSAndroid Build Coastguard Worker * useful to assist debuggers stepping over the critical section.
87*053f45beSAndroid Build Coastguard Worker */
88*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \
89*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \
90*053f45beSAndroid Build Coastguard Worker ".quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n\t" \
91*053f45beSAndroid Build Coastguard Worker ".popsection\n\t"
92*053f45beSAndroid Build Coastguard Worker
93*053f45beSAndroid Build Coastguard Worker #else /* #ifdef __PPC64__ */
94*053f45beSAndroid Build Coastguard Worker
95*053f45beSAndroid Build Coastguard Worker #define RSEQ_STORE_LONG(arg) "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* To memory ("m" constraint) */
96*053f45beSAndroid Build Coastguard Worker #define RSEQ_STORE_INT(arg) RSEQ_STORE_LONG(arg) /* To memory ("m" constraint) */
97*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOAD_LONG(arg) "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] " /* From memory ("m" constraint) */
98*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOAD_INT(arg) RSEQ_LOAD_LONG(arg) /* From memory ("m" constraint) */
99*053f45beSAndroid Build Coastguard Worker #define RSEQ_LOADX_LONG "lwzx " /* From base register ("b" constraint) */
100*053f45beSAndroid Build Coastguard Worker #define RSEQ_CMP_LONG "cmpw "
101*053f45beSAndroid Build Coastguard Worker #define RSEQ_CMP_LONG_INT "cmpwi "
102*053f45beSAndroid Build Coastguard Worker
103*053f45beSAndroid Build Coastguard Worker #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
104*053f45beSAndroid Build Coastguard Worker start_ip, post_commit_offset, abort_ip) \
105*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_cs, \"aw\"\n\t" \
106*053f45beSAndroid Build Coastguard Worker ".balign 32\n\t" \
107*053f45beSAndroid Build Coastguard Worker __rseq_str(label) ":\n\t" \
108*053f45beSAndroid Build Coastguard Worker ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
109*053f45beSAndroid Build Coastguard Worker /* 32-bit only supported on BE */ \
110*053f45beSAndroid Build Coastguard Worker ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \
111*053f45beSAndroid Build Coastguard Worker ".popsection\n\t" \
112*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \
113*053f45beSAndroid Build Coastguard Worker ".long 0x0, " __rseq_str(label) "b\n\t" \
114*053f45beSAndroid Build Coastguard Worker ".popsection\n\t"
115*053f45beSAndroid Build Coastguard Worker
116*053f45beSAndroid Build Coastguard Worker /*
117*053f45beSAndroid Build Coastguard Worker * Exit points of a rseq critical section consist of all instructions outside
118*053f45beSAndroid Build Coastguard Worker * of the critical section where a critical section can either branch to or
119*053f45beSAndroid Build Coastguard Worker * reach through the normal course of its execution. The abort IP and the
120*053f45beSAndroid Build Coastguard Worker * post-commit IP are already part of the __rseq_cs section and should not be
121*053f45beSAndroid Build Coastguard Worker * explicitly defined as additional exit points. Knowing all exit points is
122*053f45beSAndroid Build Coastguard Worker * useful to assist debuggers stepping over the critical section.
123*053f45beSAndroid Build Coastguard Worker */
124*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \
125*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \
126*053f45beSAndroid Build Coastguard Worker /* 32-bit only supported on BE */ \
127*053f45beSAndroid Build Coastguard Worker ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(exit_ip) "\n\t" \
128*053f45beSAndroid Build Coastguard Worker ".popsection\n\t"
129*053f45beSAndroid Build Coastguard Worker
130*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
131*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(1) \
132*053f45beSAndroid Build Coastguard Worker "lis %%r17, (" __rseq_str(cs_label) ")@ha\n\t" \
133*053f45beSAndroid Build Coastguard Worker "addi %%r17, %%r17, (" __rseq_str(cs_label) ")@l\n\t" \
134*053f45beSAndroid Build Coastguard Worker RSEQ_STORE_INT(rseq_cs) "%%r17, %[" __rseq_str(rseq_cs) "]\n\t" \
135*053f45beSAndroid Build Coastguard Worker __rseq_str(label) ":\n\t"
136*053f45beSAndroid Build Coastguard Worker
137*053f45beSAndroid Build Coastguard Worker #endif /* #ifdef __PPC64__ */
138*053f45beSAndroid Build Coastguard Worker
139*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
140*053f45beSAndroid Build Coastguard Worker __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
141*053f45beSAndroid Build Coastguard Worker (post_commit_ip - start_ip), abort_ip)
142*053f45beSAndroid Build Coastguard Worker
143*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
144*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(2) \
145*053f45beSAndroid Build Coastguard Worker RSEQ_LOAD_INT(current_cpu_id) "%%r17, %[" __rseq_str(current_cpu_id) "]\n\t" \
146*053f45beSAndroid Build Coastguard Worker "cmpw cr7, %[" __rseq_str(cpu_id) "], %%r17\n\t" \
147*053f45beSAndroid Build Coastguard Worker "bne- cr7, " __rseq_str(label) "\n\t"
148*053f45beSAndroid Build Coastguard Worker
149*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_DEFINE_ABORT(label, abort_label) \
150*053f45beSAndroid Build Coastguard Worker ".pushsection __rseq_failure, \"ax\"\n\t" \
151*053f45beSAndroid Build Coastguard Worker ".long " __rseq_str(RSEQ_SIG) "\n\t" \
152*053f45beSAndroid Build Coastguard Worker __rseq_str(label) ":\n\t" \
153*053f45beSAndroid Build Coastguard Worker "b %l[" __rseq_str(abort_label) "]\n\t" \
154*053f45beSAndroid Build Coastguard Worker ".popsection\n\t"
155*053f45beSAndroid Build Coastguard Worker
156*053f45beSAndroid Build Coastguard Worker /*
157*053f45beSAndroid Build Coastguard Worker * RSEQ_ASM_OPs: asm operations for rseq
158*053f45beSAndroid Build Coastguard Worker * RSEQ_ASM_OP_R_*: has hard-code registers in it
159*053f45beSAndroid Build Coastguard Worker * RSEQ_ASM_OP_* (else): doesn't have hard-code registers(unless cr7)
160*053f45beSAndroid Build Coastguard Worker */
161*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_CMPEQ(var, expect, label) \
162*053f45beSAndroid Build Coastguard Worker RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
163*053f45beSAndroid Build Coastguard Worker RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expect) "]\n\t" \
164*053f45beSAndroid Build Coastguard Worker "bne- cr7, " __rseq_str(label) "\n\t"
165*053f45beSAndroid Build Coastguard Worker
166*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_CMPNE(var, expectnot, label) \
167*053f45beSAndroid Build Coastguard Worker RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
168*053f45beSAndroid Build Coastguard Worker RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expectnot) "]\n\t" \
169*053f45beSAndroid Build Coastguard Worker "beq- cr7, " __rseq_str(label) "\n\t"
170*053f45beSAndroid Build Coastguard Worker
171*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_STORE(value, var) \
172*053f45beSAndroid Build Coastguard Worker RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t"
173*053f45beSAndroid Build Coastguard Worker
174*053f45beSAndroid Build Coastguard Worker /* Load @var to r17 */
175*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_LOAD(var) \
176*053f45beSAndroid Build Coastguard Worker RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
177*053f45beSAndroid Build Coastguard Worker
178*053f45beSAndroid Build Coastguard Worker /* Store r17 to @var */
179*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_STORE(var) \
180*053f45beSAndroid Build Coastguard Worker RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
181*053f45beSAndroid Build Coastguard Worker
182*053f45beSAndroid Build Coastguard Worker /* Add @count to r17 */
183*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_ADD(count) \
184*053f45beSAndroid Build Coastguard Worker "add %%r17, %[" __rseq_str(count) "], %%r17\n\t"
185*053f45beSAndroid Build Coastguard Worker
186*053f45beSAndroid Build Coastguard Worker /* Load (r17 + voffp) to r17 */
187*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_LOADX(voffp) \
188*053f45beSAndroid Build Coastguard Worker RSEQ_LOADX_LONG "%%r17, %[" __rseq_str(voffp) "], %%r17\n\t"
189*053f45beSAndroid Build Coastguard Worker
190*053f45beSAndroid Build Coastguard Worker /* TODO: implement a faster memcpy. */
191*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_MEMCPY() \
192*053f45beSAndroid Build Coastguard Worker RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
193*053f45beSAndroid Build Coastguard Worker "beq 333f\n\t" \
194*053f45beSAndroid Build Coastguard Worker "addi %%r20, %%r20, -1\n\t" \
195*053f45beSAndroid Build Coastguard Worker "addi %%r21, %%r21, -1\n\t" \
196*053f45beSAndroid Build Coastguard Worker "222:\n\t" \
197*053f45beSAndroid Build Coastguard Worker "lbzu %%r18, 1(%%r20)\n\t" \
198*053f45beSAndroid Build Coastguard Worker "stbu %%r18, 1(%%r21)\n\t" \
199*053f45beSAndroid Build Coastguard Worker "addi %%r19, %%r19, -1\n\t" \
200*053f45beSAndroid Build Coastguard Worker RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
201*053f45beSAndroid Build Coastguard Worker "bne 222b\n\t" \
202*053f45beSAndroid Build Coastguard Worker "333:\n\t" \
203*053f45beSAndroid Build Coastguard Worker
204*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label) \
205*053f45beSAndroid Build Coastguard Worker RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t" \
206*053f45beSAndroid Build Coastguard Worker __rseq_str(post_commit_label) ":\n\t"
207*053f45beSAndroid Build Coastguard Worker
208*053f45beSAndroid Build Coastguard Worker #define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label) \
209*053f45beSAndroid Build Coastguard Worker RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t" \
210*053f45beSAndroid Build Coastguard Worker __rseq_str(post_commit_label) ":\n\t"
211*053f45beSAndroid Build Coastguard Worker
212*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_cmpeqv_storev(intptr_t * v,intptr_t expect,intptr_t newv,int cpu)213*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
214*053f45beSAndroid Build Coastguard Worker {
215*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
216*053f45beSAndroid Build Coastguard Worker
217*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
218*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
219*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
220*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
221*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
222*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
223*053f45beSAndroid Build Coastguard Worker #endif
224*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
225*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
226*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
227*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
228*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
229*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
230*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
231*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
232*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
233*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
234*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
235*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
236*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
237*053f45beSAndroid Build Coastguard Worker #endif
238*053f45beSAndroid Build Coastguard Worker /* final store */
239*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
240*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
241*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
242*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
243*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
244*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
245*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
246*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
247*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
248*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv)
249*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
250*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
251*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
252*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
253*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
254*053f45beSAndroid Build Coastguard Worker , error1, error2
255*053f45beSAndroid Build Coastguard Worker #endif
256*053f45beSAndroid Build Coastguard Worker );
257*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
258*053f45beSAndroid Build Coastguard Worker return 0;
259*053f45beSAndroid Build Coastguard Worker abort:
260*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
261*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
262*053f45beSAndroid Build Coastguard Worker return -1;
263*053f45beSAndroid Build Coastguard Worker cmpfail:
264*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
265*053f45beSAndroid Build Coastguard Worker return 1;
266*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
267*053f45beSAndroid Build Coastguard Worker error1:
268*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
269*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
270*053f45beSAndroid Build Coastguard Worker error2:
271*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
272*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
273*053f45beSAndroid Build Coastguard Worker #endif
274*053f45beSAndroid Build Coastguard Worker }
275*053f45beSAndroid Build Coastguard Worker
276*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)277*053f45beSAndroid Build Coastguard Worker int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
278*053f45beSAndroid Build Coastguard Worker long voffp, intptr_t *load, int cpu)
279*053f45beSAndroid Build Coastguard Worker {
280*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
281*053f45beSAndroid Build Coastguard Worker
282*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
283*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
284*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
285*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
286*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
287*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
288*053f45beSAndroid Build Coastguard Worker #endif
289*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
290*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
291*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
292*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
293*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
294*053f45beSAndroid Build Coastguard Worker /* cmp @v not equal to @expectnot */
295*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPNE(v, expectnot, %l[cmpfail])
296*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
297*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
298*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
299*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
300*053f45beSAndroid Build Coastguard Worker /* cmp @v not equal to @expectnot */
301*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPNE(v, expectnot, %l[error2])
302*053f45beSAndroid Build Coastguard Worker #endif
303*053f45beSAndroid Build Coastguard Worker /* load the value of @v */
304*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_LOAD(v)
305*053f45beSAndroid Build Coastguard Worker /* store it in @load */
306*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_STORE(load)
307*053f45beSAndroid Build Coastguard Worker /* dereference voffp(v) */
308*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_LOADX(voffp)
309*053f45beSAndroid Build Coastguard Worker /* final store the value at voffp(v) */
310*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_FINAL_STORE(v, 2)
311*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
312*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
313*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
314*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
315*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
316*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
317*053f45beSAndroid Build Coastguard Worker /* final store input */
318*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
319*053f45beSAndroid Build Coastguard Worker [expectnot] "r" (expectnot),
320*053f45beSAndroid Build Coastguard Worker [voffp] "b" (voffp),
321*053f45beSAndroid Build Coastguard Worker [load] "m" (*load)
322*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
323*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
324*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
325*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
326*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
327*053f45beSAndroid Build Coastguard Worker , error1, error2
328*053f45beSAndroid Build Coastguard Worker #endif
329*053f45beSAndroid Build Coastguard Worker );
330*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
331*053f45beSAndroid Build Coastguard Worker return 0;
332*053f45beSAndroid Build Coastguard Worker abort:
333*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
334*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
335*053f45beSAndroid Build Coastguard Worker return -1;
336*053f45beSAndroid Build Coastguard Worker cmpfail:
337*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
338*053f45beSAndroid Build Coastguard Worker return 1;
339*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
340*053f45beSAndroid Build Coastguard Worker error1:
341*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
342*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
343*053f45beSAndroid Build Coastguard Worker error2:
344*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
345*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
346*053f45beSAndroid Build Coastguard Worker #endif
347*053f45beSAndroid Build Coastguard Worker }
348*053f45beSAndroid Build Coastguard Worker
349*053f45beSAndroid Build Coastguard Worker static inline __attribute__((always_inline))
rseq_addv(intptr_t * v,intptr_t count,int cpu)350*053f45beSAndroid Build Coastguard Worker int rseq_addv(intptr_t *v, intptr_t count, int cpu)
351*053f45beSAndroid Build Coastguard Worker {
352*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
353*053f45beSAndroid Build Coastguard Worker
354*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
355*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
356*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
357*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
358*053f45beSAndroid Build Coastguard Worker #endif
359*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
360*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
361*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
362*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
363*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
364*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
365*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
366*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
367*053f45beSAndroid Build Coastguard Worker #endif
368*053f45beSAndroid Build Coastguard Worker /* load the value of @v */
369*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_LOAD(v)
370*053f45beSAndroid Build Coastguard Worker /* add @count to it */
371*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_ADD(count)
372*053f45beSAndroid Build Coastguard Worker /* final store */
373*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_FINAL_STORE(v, 2)
374*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
375*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
376*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
377*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
378*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
379*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
380*053f45beSAndroid Build Coastguard Worker /* final store input */
381*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
382*053f45beSAndroid Build Coastguard Worker [count] "r" (count)
383*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
384*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
385*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
386*053f45beSAndroid Build Coastguard Worker : abort
387*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
388*053f45beSAndroid Build Coastguard Worker , error1
389*053f45beSAndroid Build Coastguard Worker #endif
390*053f45beSAndroid Build Coastguard Worker );
391*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
392*053f45beSAndroid Build Coastguard Worker return 0;
393*053f45beSAndroid Build Coastguard Worker abort:
394*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
395*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
396*053f45beSAndroid Build Coastguard Worker return -1;
397*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
398*053f45beSAndroid Build Coastguard Worker error1:
399*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
400*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
401*053f45beSAndroid Build Coastguard Worker #endif
402*053f45beSAndroid Build Coastguard Worker }
403*053f45beSAndroid Build Coastguard Worker
404*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)405*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
406*053f45beSAndroid Build Coastguard Worker intptr_t *v2, intptr_t newv2,
407*053f45beSAndroid Build Coastguard Worker intptr_t newv, int cpu)
408*053f45beSAndroid Build Coastguard Worker {
409*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
410*053f45beSAndroid Build Coastguard Worker
411*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
412*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
413*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
414*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
415*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
416*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
417*053f45beSAndroid Build Coastguard Worker #endif
418*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
419*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
420*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
421*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
422*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
423*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
424*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
425*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
426*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
427*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
428*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
429*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
430*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
431*053f45beSAndroid Build Coastguard Worker #endif
432*053f45beSAndroid Build Coastguard Worker /* try store */
433*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_STORE(newv2, v2)
434*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
435*053f45beSAndroid Build Coastguard Worker /* final store */
436*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
437*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(6)
438*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
439*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
440*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
441*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
442*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
443*053f45beSAndroid Build Coastguard Worker /* try store input */
444*053f45beSAndroid Build Coastguard Worker [v2] "m" (*v2),
445*053f45beSAndroid Build Coastguard Worker [newv2] "r" (newv2),
446*053f45beSAndroid Build Coastguard Worker /* final store input */
447*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
448*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
449*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv)
450*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
451*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
452*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
453*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
454*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
455*053f45beSAndroid Build Coastguard Worker , error1, error2
456*053f45beSAndroid Build Coastguard Worker #endif
457*053f45beSAndroid Build Coastguard Worker );
458*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
459*053f45beSAndroid Build Coastguard Worker return 0;
460*053f45beSAndroid Build Coastguard Worker abort:
461*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
462*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
463*053f45beSAndroid Build Coastguard Worker return -1;
464*053f45beSAndroid Build Coastguard Worker cmpfail:
465*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
466*053f45beSAndroid Build Coastguard Worker return 1;
467*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
468*053f45beSAndroid Build Coastguard Worker error1:
469*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
470*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
471*053f45beSAndroid Build Coastguard Worker error2:
472*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
473*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
474*053f45beSAndroid Build Coastguard Worker #endif
475*053f45beSAndroid Build Coastguard Worker }
476*053f45beSAndroid Build Coastguard Worker
477*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)478*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
479*053f45beSAndroid Build Coastguard Worker intptr_t *v2, intptr_t newv2,
480*053f45beSAndroid Build Coastguard Worker intptr_t newv, int cpu)
481*053f45beSAndroid Build Coastguard Worker {
482*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
483*053f45beSAndroid Build Coastguard Worker
484*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
485*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
486*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
487*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
488*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
489*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
490*053f45beSAndroid Build Coastguard Worker #endif
491*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
492*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
493*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
494*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
495*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
496*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
497*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
498*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
499*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
500*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
501*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
502*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
503*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
504*053f45beSAndroid Build Coastguard Worker #endif
505*053f45beSAndroid Build Coastguard Worker /* try store */
506*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_STORE(newv2, v2)
507*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
508*053f45beSAndroid Build Coastguard Worker /* for 'release' */
509*053f45beSAndroid Build Coastguard Worker "lwsync\n\t"
510*053f45beSAndroid Build Coastguard Worker /* final store */
511*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
512*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(6)
513*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
514*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
515*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
516*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
517*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
518*053f45beSAndroid Build Coastguard Worker /* try store input */
519*053f45beSAndroid Build Coastguard Worker [v2] "m" (*v2),
520*053f45beSAndroid Build Coastguard Worker [newv2] "r" (newv2),
521*053f45beSAndroid Build Coastguard Worker /* final store input */
522*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
523*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
524*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv)
525*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
526*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
527*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
528*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
529*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
530*053f45beSAndroid Build Coastguard Worker , error1, error2
531*053f45beSAndroid Build Coastguard Worker #endif
532*053f45beSAndroid Build Coastguard Worker );
533*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
534*053f45beSAndroid Build Coastguard Worker return 0;
535*053f45beSAndroid Build Coastguard Worker abort:
536*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
537*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
538*053f45beSAndroid Build Coastguard Worker return -1;
539*053f45beSAndroid Build Coastguard Worker cmpfail:
540*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
541*053f45beSAndroid Build Coastguard Worker return 1;
542*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
543*053f45beSAndroid Build Coastguard Worker error1:
544*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
545*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
546*053f45beSAndroid Build Coastguard Worker error2:
547*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
548*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
549*053f45beSAndroid Build Coastguard Worker #endif
550*053f45beSAndroid Build Coastguard Worker }
551*053f45beSAndroid Build Coastguard Worker
552*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)553*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
554*053f45beSAndroid Build Coastguard Worker intptr_t *v2, intptr_t expect2,
555*053f45beSAndroid Build Coastguard Worker intptr_t newv, int cpu)
556*053f45beSAndroid Build Coastguard Worker {
557*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
558*053f45beSAndroid Build Coastguard Worker
559*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
560*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
561*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
562*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
563*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
564*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
565*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
566*053f45beSAndroid Build Coastguard Worker #endif
567*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
568*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
569*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
570*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
571*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
572*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
573*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
574*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
575*053f45beSAndroid Build Coastguard Worker /* cmp @v2 equal to @expct2 */
576*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[cmpfail])
577*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
578*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
579*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
580*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
581*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
582*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
583*053f45beSAndroid Build Coastguard Worker /* cmp @v2 equal to @expct2 */
584*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[error3])
585*053f45beSAndroid Build Coastguard Worker #endif
586*053f45beSAndroid Build Coastguard Worker /* final store */
587*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
588*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(6)
589*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
590*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
591*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
592*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
593*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
594*053f45beSAndroid Build Coastguard Worker /* cmp2 input */
595*053f45beSAndroid Build Coastguard Worker [v2] "m" (*v2),
596*053f45beSAndroid Build Coastguard Worker [expect2] "r" (expect2),
597*053f45beSAndroid Build Coastguard Worker /* final store input */
598*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
599*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
600*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv)
601*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
602*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17"
603*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
604*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
605*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
606*053f45beSAndroid Build Coastguard Worker , error1, error2, error3
607*053f45beSAndroid Build Coastguard Worker #endif
608*053f45beSAndroid Build Coastguard Worker );
609*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
610*053f45beSAndroid Build Coastguard Worker return 0;
611*053f45beSAndroid Build Coastguard Worker abort:
612*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
613*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
614*053f45beSAndroid Build Coastguard Worker return -1;
615*053f45beSAndroid Build Coastguard Worker cmpfail:
616*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
617*053f45beSAndroid Build Coastguard Worker return 1;
618*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
619*053f45beSAndroid Build Coastguard Worker error1:
620*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
621*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
622*053f45beSAndroid Build Coastguard Worker error2:
623*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
624*053f45beSAndroid Build Coastguard Worker rseq_bug("1st expected value comparison failed");
625*053f45beSAndroid Build Coastguard Worker error3:
626*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
627*053f45beSAndroid Build Coastguard Worker rseq_bug("2nd 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(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(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(3, 1f, 2f, 4f) /* start, commit, abort */
640*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
641*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
642*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
643*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
644*053f45beSAndroid Build Coastguard Worker #endif
645*053f45beSAndroid Build Coastguard Worker /* setup for mempcy */
646*053f45beSAndroid Build Coastguard Worker "mr %%r19, %[len]\n\t"
647*053f45beSAndroid Build Coastguard Worker "mr %%r20, %[src]\n\t"
648*053f45beSAndroid Build Coastguard Worker "mr %%r21, %[dst]\n\t"
649*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
650*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
651*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
652*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
653*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
654*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
655*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
656*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
657*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
658*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
659*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
660*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
661*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
662*053f45beSAndroid Build Coastguard Worker #endif
663*053f45beSAndroid Build Coastguard Worker /* try memcpy */
664*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_MEMCPY()
665*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
666*053f45beSAndroid Build Coastguard Worker /* final store */
667*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
668*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(6)
669*053f45beSAndroid Build Coastguard Worker /* teardown */
670*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
671*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
672*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
673*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
674*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
675*053f45beSAndroid Build Coastguard Worker /* final store input */
676*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
677*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
678*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv),
679*053f45beSAndroid Build Coastguard Worker /* try memcpy input */
680*053f45beSAndroid Build Coastguard Worker [dst] "r" (dst),
681*053f45beSAndroid Build Coastguard Worker [src] "r" (src),
682*053f45beSAndroid Build Coastguard Worker [len] "r" (len)
683*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
684*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17", "r18", "r19", "r20", "r21"
685*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
686*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
687*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
688*053f45beSAndroid Build Coastguard Worker , error1, error2
689*053f45beSAndroid Build Coastguard Worker #endif
690*053f45beSAndroid Build Coastguard Worker );
691*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
692*053f45beSAndroid Build Coastguard Worker return 0;
693*053f45beSAndroid Build Coastguard Worker abort:
694*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
695*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
696*053f45beSAndroid Build Coastguard Worker return -1;
697*053f45beSAndroid Build Coastguard Worker cmpfail:
698*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
699*053f45beSAndroid Build Coastguard Worker return 1;
700*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
701*053f45beSAndroid Build Coastguard Worker error1:
702*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
703*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
704*053f45beSAndroid Build Coastguard Worker error2:
705*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
706*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
707*053f45beSAndroid Build Coastguard Worker #endif
708*053f45beSAndroid Build Coastguard Worker }
709*053f45beSAndroid Build Coastguard Worker
710*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)711*053f45beSAndroid Build Coastguard Worker int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
712*053f45beSAndroid Build Coastguard Worker void *dst, void *src, size_t len,
713*053f45beSAndroid Build Coastguard Worker intptr_t newv, int cpu)
714*053f45beSAndroid Build Coastguard Worker {
715*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_C(9)
716*053f45beSAndroid Build Coastguard Worker
717*053f45beSAndroid Build Coastguard Worker __asm__ __volatile__ goto (
718*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
719*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
720*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
721*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
722*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
723*053f45beSAndroid Build Coastguard Worker #endif
724*053f45beSAndroid Build Coastguard Worker /* setup for mempcy */
725*053f45beSAndroid Build Coastguard Worker "mr %%r19, %[len]\n\t"
726*053f45beSAndroid Build Coastguard Worker "mr %%r20, %[src]\n\t"
727*053f45beSAndroid Build Coastguard Worker "mr %%r21, %[dst]\n\t"
728*053f45beSAndroid Build Coastguard Worker /* Start rseq by storing table entry pointer into rseq_cs. */
729*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
730*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
731*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
732*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(3)
733*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
734*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
735*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(4)
736*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
737*053f45beSAndroid Build Coastguard Worker /* cmp cpuid */
738*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
739*053f45beSAndroid Build Coastguard Worker /* cmp @v equal to @expect */
740*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
741*053f45beSAndroid Build Coastguard Worker #endif
742*053f45beSAndroid Build Coastguard Worker /* try memcpy */
743*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_R_MEMCPY()
744*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(5)
745*053f45beSAndroid Build Coastguard Worker /* for 'release' */
746*053f45beSAndroid Build Coastguard Worker "lwsync\n\t"
747*053f45beSAndroid Build Coastguard Worker /* final store */
748*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
749*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_ASM(6)
750*053f45beSAndroid Build Coastguard Worker /* teardown */
751*053f45beSAndroid Build Coastguard Worker RSEQ_ASM_DEFINE_ABORT(4, abort)
752*053f45beSAndroid Build Coastguard Worker : /* gcc asm goto does not allow outputs */
753*053f45beSAndroid Build Coastguard Worker : [cpu_id] "r" (cpu),
754*053f45beSAndroid Build Coastguard Worker [current_cpu_id] "m" (rseq_get_abi()->cpu_id),
755*053f45beSAndroid Build Coastguard Worker [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
756*053f45beSAndroid Build Coastguard Worker /* final store input */
757*053f45beSAndroid Build Coastguard Worker [v] "m" (*v),
758*053f45beSAndroid Build Coastguard Worker [expect] "r" (expect),
759*053f45beSAndroid Build Coastguard Worker [newv] "r" (newv),
760*053f45beSAndroid Build Coastguard Worker /* try memcpy input */
761*053f45beSAndroid Build Coastguard Worker [dst] "r" (dst),
762*053f45beSAndroid Build Coastguard Worker [src] "r" (src),
763*053f45beSAndroid Build Coastguard Worker [len] "r" (len)
764*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_INPUT
765*053f45beSAndroid Build Coastguard Worker : "memory", "cc", "r17", "r18", "r19", "r20", "r21"
766*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_CLOBBER
767*053f45beSAndroid Build Coastguard Worker : abort, cmpfail
768*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
769*053f45beSAndroid Build Coastguard Worker , error1, error2
770*053f45beSAndroid Build Coastguard Worker #endif
771*053f45beSAndroid Build Coastguard Worker );
772*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
773*053f45beSAndroid Build Coastguard Worker return 0;
774*053f45beSAndroid Build Coastguard Worker abort:
775*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
776*053f45beSAndroid Build Coastguard Worker RSEQ_INJECT_FAILED
777*053f45beSAndroid Build Coastguard Worker return -1;
778*053f45beSAndroid Build Coastguard Worker cmpfail:
779*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
780*053f45beSAndroid Build Coastguard Worker return 1;
781*053f45beSAndroid Build Coastguard Worker #ifdef RSEQ_COMPARE_TWICE
782*053f45beSAndroid Build Coastguard Worker error1:
783*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
784*053f45beSAndroid Build Coastguard Worker rseq_bug("cpu_id comparison failed");
785*053f45beSAndroid Build Coastguard Worker error2:
786*053f45beSAndroid Build Coastguard Worker rseq_after_asm_goto();
787*053f45beSAndroid Build Coastguard Worker rseq_bug("expected value comparison failed");
788*053f45beSAndroid Build Coastguard Worker #endif
789*053f45beSAndroid Build Coastguard Worker }
790*053f45beSAndroid Build Coastguard Worker
791*053f45beSAndroid Build Coastguard Worker #endif /* !RSEQ_SKIP_FASTPATH */
792