rseq: output whether configure finds rseq syscall
[lttng-ust.git] / libringbuffer / rseq-arm.h
CommitLineData
b76e5200
MD
1/*
2 * rseq-arm.h
3 *
4 * (C) Copyright 2016 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
b76e5200
MD
25#define has_fast_acquire_release() 0
26#define has_single_copy_load_64() 1
27
28/*
29 * The __rseq_table section can be used by debuggers to better handle
30 * single-stepping through the restartable critical sections.
b76e5200
MD
31 */
32
33#define RSEQ_FINISH_ASM(_target_final, _to_write_final, _start_value, \
34 _failure, _spec_store, _spec_input, \
35 _final_store, _final_input, _extra_clobber, \
36 _setup, _teardown, _scratch) \
37do { \
38 _scratch \
39 __asm__ __volatile__ goto ( \
40 ".pushsection __rseq_table, \"aw\"\n\t" \
41 ".balign 32\n\t" \
42 ".word 1f, 0x0, 2f, 0x0, 5f, 0x0, 0x0, 0x0\n\t" \
43 ".popsection\n\t" \
44 "1:\n\t" \
45 _setup \
46 RSEQ_INJECT_ASM(1) \
47 "adr r0, 3f\n\t" \
48 "str r0, [%[rseq_cs]]\n\t" \
49 RSEQ_INJECT_ASM(2) \
50 "ldr r0, %[current_event_counter]\n\t" \
b76e5200
MD
51 "cmp %[start_event_counter], r0\n\t" \
52 "bne 5f\n\t" \
53 RSEQ_INJECT_ASM(3) \
54 _spec_store \
55 _final_store \
56 "2:\n\t" \
57 RSEQ_INJECT_ASM(5) \
b76e5200
MD
58 _teardown \
59 "b 4f\n\t" \
60 ".balign 32\n\t" \
61 "3:\n\t" \
62 ".word 1b, 0x0, 2b, 0x0, 5f, 0x0, 0x0, 0x0\n\t" \
63 "5:\n\t" \
b76e5200
MD
64 _teardown \
65 "b %l[failure]\n\t" \
66 "4:\n\t" \
26cc635c 67 : /* gcc asm goto does not allow outputs */ \
b76e5200
MD
68 : [start_event_counter]"r"((_start_value).event_counter), \
69 [current_event_counter]"m"((_start_value).rseqp->u.e.event_counter), \
70 [rseq_cs]"r"(&(_start_value).rseqp->rseq_cs) \
71 _spec_input \
72 _final_input \
73 RSEQ_INJECT_INPUT \
6b31d669 74 : "r0", "memory", "cc" \
b76e5200
MD
75 _extra_clobber \
76 RSEQ_INJECT_CLOBBER \
77 : _failure \
78 ); \
79} while (0)
80
81#define RSEQ_FINISH_FINAL_STORE_ASM() \
82 "str %[to_write_final], [%[target_final]]\n\t"
83
84#define RSEQ_FINISH_FINAL_STORE_RELEASE_ASM() \
85 "dmb\n\t" \
86 RSEQ_FINISH_FINAL_STORE_ASM()
87
88#define RSEQ_FINISH_FINAL_STORE_INPUT(_target_final, _to_write_final) \
89 , [to_write_final]"r"(_to_write_final), \
90 [target_final]"r"(_target_final)
91
92#define RSEQ_FINISH_SPECULATIVE_STORE_ASM() \
93 "str %[to_write_spec], [%[target_spec]]\n\t" \
94 RSEQ_INJECT_ASM(4)
95
96#define RSEQ_FINISH_SPECULATIVE_STORE_INPUT(_target_spec, _to_write_spec) \
97 , [to_write_spec]"r"(_to_write_spec), \
98 [target_spec]"r"(_target_spec)
99
100/* TODO: implement a faster memcpy. */
101#define RSEQ_FINISH_MEMCPY_STORE_ASM() \
102 "cmp %[len_memcpy], #0\n\t" \
103 "beq 333f\n\t" \
104 "222:\n\t" \
105 "ldrb %%r0, [%[to_write_memcpy]]\n\t" \
106 "strb %%r0, [%[target_memcpy]]\n\t" \
107 "adds %[to_write_memcpy], #1\n\t" \
108 "adds %[target_memcpy], #1\n\t" \
109 "subs %[len_memcpy], #1\n\t" \
110 "bne 222b\n\t" \
111 "333:\n\t" \
112 RSEQ_INJECT_ASM(4)
113
114#define RSEQ_FINISH_MEMCPY_STORE_INPUT(_target_memcpy, _to_write_memcpy, _len_memcpy) \
115 , [to_write_memcpy]"r"(_to_write_memcpy), \
116 [target_memcpy]"r"(_target_memcpy), \
117 [len_memcpy]"r"(_len_memcpy), \
118 [rseq_scratch0]"m"(rseq_scratch[0]), \
119 [rseq_scratch1]"m"(rseq_scratch[1]), \
120 [rseq_scratch2]"m"(rseq_scratch[2])
121
122/* We can use r0. */
123#define RSEQ_FINISH_MEMCPY_CLOBBER()
124
125#define RSEQ_FINISH_MEMCPY_SCRATCH() \
126 uint32_t rseq_scratch[3];
127
128/*
129 * We need to save and restore those input registers so they can be
130 * modified within the assembly.
131 */
132#define RSEQ_FINISH_MEMCPY_SETUP() \
133 "str %[to_write_memcpy], %[rseq_scratch0]\n\t" \
134 "str %[target_memcpy], %[rseq_scratch1]\n\t" \
135 "str %[len_memcpy], %[rseq_scratch2]\n\t"
136
137#define RSEQ_FINISH_MEMCPY_TEARDOWN() \
138 "ldr %[len_memcpy], %[rseq_scratch2]\n\t" \
139 "ldr %[target_memcpy], %[rseq_scratch1]\n\t" \
140 "ldr %[to_write_memcpy], %[rseq_scratch0]\n\t"
This page took 0.031763 seconds and 5 git commands to generate.