1#include "tsan_ppc_regs.h"
2
3 .section .text
4 .hidden __tsan_setjmp
5 .globl _setjmp
6 .type _setjmp, @function
7 .align 4
8#if _CALL_ELF == 2
9_setjmp:
10#else
11 .section ".opd","aw"
12 .align 3
13_setjmp:
14 .quad .L._setjmp,.TOC.@tocbase,0
15 .previous
16#endif
17.L._setjmp:
18 mflr r0
19 stdu r1,-48(r1)
20 std r2,24(r1)
21 std r3,32(r1)
22 std r0,40(r1)
23 // r3 is the original stack pointer.
24 addi r3,r1,48
25 // r4 is the mangled stack pointer (see glibc)
26 ld r4,-28696(r13)
27 xor r4,r3,r4
28 // Materialize a TOC in case we were called from libc.
29 // For big-endian, we load the TOC from the OPD. For little-
30 // endian, we use the .TOC. symbol to find it.
31 nop
32 bcl 20,31,0f
330:
34 mflr r2
35#if _CALL_ELF == 2
36 addis r2,r2,.TOC.-0b@ha
37 addi r2,r2,.TOC.-0b@l
38#else
39 addis r2,r2,_setjmp-0b@ha
40 addi r2,r2,_setjmp-0b@l
41 ld r2,8(r2)
42#endif
43 // Call the interceptor.
44 bl __tsan_setjmp
45 nop
46 // Restore regs needed for setjmp.
47 ld r3,32(r1)
48 ld r0,40(r1)
49 // Emulate the real setjmp function. We do this because we can't
50 // perform a sibcall: The real setjmp function trashes the TOC
51 // pointer, and with a sibcall we have no way to restore it.
52 // This way we can make sure our caller's stack pointer and
53 // link register are saved correctly in the jmpbuf.
54 ld r6,-28696(r13)
55 addi r5,r1,48 // original stack ptr of caller
56 xor r5,r6,r5
57 std r5,0(r3) // mangled stack ptr of caller
58 ld r5,24(r1)
59 std r5,8(r3) // caller's saved TOC pointer
60 xor r0,r6,r0
61 std r0,16(r3) // caller's mangled return address
62 mfcr r0
63 // Nonvolatiles.
64 std r14,24(r3)
65 stfd f14,176(r3)
66 stw r0,172(r3) // CR
67 std r15,32(r3)
68 stfd f15,184(r3)
69 std r16,40(r3)
70 stfd f16,192(r3)
71 std r17,48(r3)
72 stfd f17,200(r3)
73 std r18,56(r3)
74 stfd f18,208(r3)
75 std r19,64(r3)
76 stfd f19,216(r3)
77 std r20,72(r3)
78 stfd f20,224(r3)
79 std r21,80(r3)
80 stfd f21,232(r3)
81 std r22,88(r3)
82 stfd f22,240(r3)
83 std r23,96(r3)
84 stfd f23,248(r3)
85 std r24,104(r3)
86 stfd f24,256(r3)
87 std r25,112(r3)
88 stfd f25,264(r3)
89 std r26,120(r3)
90 stfd f26,272(r3)
91 std r27,128(r3)
92 stfd f27,280(r3)
93 std r28,136(r3)
94 stfd f28,288(r3)
95 std r29,144(r3)
96 stfd f29,296(r3)
97 std r30,152(r3)
98 stfd f30,304(r3)
99 std r31,160(r3)
100 stfd f31,312(r3)
101 addi r5,r3,320
102 mfspr r0,256
103 stw r0,168(r3) // VRSAVE
104 addi r6,r5,16
105 stvx v20,0,r5
106 addi r5,r5,32
107 stvx v21,0,r6
108 addi r6,r6,32
109 stvx v22,0,r5
110 addi r5,r5,32
111 stvx v23,0,r6
112 addi r6,r6,32
113 stvx v24,0,r5
114 addi r5,r5,32
115 stvx v25,0,r6
116 addi r6,r6,32
117 stvx v26,0,r5
118 addi r5,r5,32
119 stvx v27,0,r6
120 addi r6,r6,32
121 stvx v28,0,r5
122 addi r5,r5,32
123 stvx v29,0,r6
124 addi r6,r6,32
125 stvx v30,0,r5
126 stvx v31,0,r6
127 // Clear the "mask-saved" slot.
128 li r4,0
129 stw r4,512(r3)
130 // Restore TOC, LR, and stack and return to caller.
131 ld r2,24(r1)
132 ld r0,40(r1)
133 addi r1,r1,48
134 li r3,0 // This is the setjmp return path
135 mtlr r0
136 blr
137 .size _setjmp, .-.L._setjmp
138
139 .globl setjmp
140 .type setjmp, @function
141 .align 4
142setjmp:
143 b _setjmp
144 .size setjmp, .-setjmp
145
146 // sigsetjmp is like setjmp, except that the mask in r4 needs
147 // to be saved at offset 512 of the jump buffer.
148 .globl __sigsetjmp
149 .type __sigsetjmp, @function
150 .align 4
151#if _CALL_ELF == 2
152__sigsetjmp:
153#else
154 .section ".opd","aw"
155 .align 3
156__sigsetjmp:
157 .quad .L.__sigsetjmp,.TOC.@tocbase,0
158 .previous
159#endif
160.L.__sigsetjmp:
161 mflr r0
162 stdu r1,-64(r1)
163 std r2,24(r1)
164 std r3,32(r1)
165 std r4,40(r1)
166 std r0,48(r1)
167 // r3 is the original stack pointer.
168 addi r3,r1,64
169 // r4 is the mangled stack pointer (see glibc)
170 ld r4,-28696(r13)
171 xor r4,r3,r4
172 // Materialize a TOC in case we were called from libc.
173 // For big-endian, we load the TOC from the OPD. For little-
174 // endian, we use the .TOC. symbol to find it.
175 nop
176 bcl 20,31,1f
1771:
178 mflr r2
179#if _CALL_ELF == 2
180 addis r2,r2,.TOC.-1b@ha
181 addi r2,r2,.TOC.-1b@l
182#else
183 addis r2,r2,_setjmp-1b@ha
184 addi r2,r2,_setjmp-1b@l
185 ld r2,8(r2)
186#endif
187 // Call the interceptor.
188 bl __tsan_setjmp
189 nop
190 // Restore regs needed for __sigsetjmp.
191 ld r3,32(r1)
192 ld r4,40(r1)
193 ld r0,48(r1)
194 // Emulate the real sigsetjmp function. We do this because we can't
195 // perform a sibcall: The real sigsetjmp function trashes the TOC
196 // pointer, and with a sibcall we have no way to restore it.
197 // This way we can make sure our caller's stack pointer and
198 // link register are saved correctly in the jmpbuf.
199 ld r6,-28696(r13)
200 addi r5,r1,64 // original stack ptr of caller
201 xor r5,r6,r5
202 std r5,0(r3) // mangled stack ptr of caller
203 ld r5,24(r1)
204 std r5,8(r3) // caller's saved TOC pointer
205 xor r0,r6,r0
206 std r0,16(r3) // caller's mangled return address
207 mfcr r0
208 // Nonvolatiles.
209 std r14,24(r3)
210 stfd f14,176(r3)
211 stw r0,172(r3) // CR
212 std r15,32(r3)
213 stfd f15,184(r3)
214 std r16,40(r3)
215 stfd f16,192(r3)
216 std r17,48(r3)
217 stfd f17,200(r3)
218 std r18,56(r3)
219 stfd f18,208(r3)
220 std r19,64(r3)
221 stfd f19,216(r3)
222 std r20,72(r3)
223 stfd f20,224(r3)
224 std r21,80(r3)
225 stfd f21,232(r3)
226 std r22,88(r3)
227 stfd f22,240(r3)
228 std r23,96(r3)
229 stfd f23,248(r3)
230 std r24,104(r3)
231 stfd f24,256(r3)
232 std r25,112(r3)
233 stfd f25,264(r3)
234 std r26,120(r3)
235 stfd f26,272(r3)
236 std r27,128(r3)
237 stfd f27,280(r3)
238 std r28,136(r3)
239 stfd f28,288(r3)
240 std r29,144(r3)
241 stfd f29,296(r3)
242 std r30,152(r3)
243 stfd f30,304(r3)
244 std r31,160(r3)
245 stfd f31,312(r3)
246 addi r5,r3,320
247 mfspr r0,256
248 stw r0,168(r3) // VRSAVE
249 addi r6,r5,16
250 stvx v20,0,r5
251 addi r5,r5,32
252 stvx v21,0,r6
253 addi r6,r6,32
254 stvx v22,0,r5
255 addi r5,r5,32
256 stvx v23,0,r6
257 addi r6,r6,32
258 stvx v24,0,r5
259 addi r5,r5,32
260 stvx v25,0,r6
261 addi r6,r6,32
262 stvx v26,0,r5
263 addi r5,r5,32
264 stvx v27,0,r6
265 addi r6,r6,32
266 stvx v28,0,r5
267 addi r5,r5,32
268 stvx v29,0,r6
269 addi r6,r6,32
270 stvx v30,0,r5
271 stvx v31,0,r6
272 // Save into the "mask-saved" slot.
273 stw r4,512(r3)
274 // Restore TOC, LR, and stack and return to caller.
275 ld r2,24(r1)
276 ld r0,48(r1)
277 addi r1,r1,64
278 li r3,0 // This is the sigsetjmp return path
279 mtlr r0
280 blr
281 .size __sigsetjmp, .-.L.__sigsetjmp
282
283 .globl sigsetjmp
284 .type sigsetjmp, @function
285 .align 4
286sigsetjmp:
287 b __sigsetjmp
288 .size sigsetjmp, .-sigsetjmp
289

source code of compiler-rt/lib/tsan/rtl/tsan_rtl_ppc64.S