]>
Commit | Line | Data |
---|---|---|
7adcbafe | 1 | /* Copyright (C) 2012-2022 Free Software Foundation, Inc. |
a32e5e93 RH |
2 | Contributed by Richard Henderson <rth@redhat.com>. |
3 | ||
4 | This file is part of the GNU Transactional Memory Library (libitm). | |
5 | ||
6 | Libitm is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | Libitm is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
13 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
14 | more details. | |
15 | ||
16 | Under Section 7 of GPL version 3, you are granted additional | |
17 | permissions described in the GCC Runtime Library Exception, version | |
18 | 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | You should have received a copy of the GNU General Public License and | |
21 | a copy of the GCC Runtime Library Exception along with this program; | |
22 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | <http://www.gnu.org/licenses/>. */ | |
24 | ||
25 | .text | |
26 | ||
27 | #include "asmcfi.h" | |
28 | ||
2dd7b937 AM |
29 | #if defined(__powerpc64__) && _CALL_ELF == 2 && defined(__PCREL__) |
30 | .macro FUNC name | |
31 | .globl \name | |
32 | .type \name, @function | |
33 | \name: | |
34 | .localentry \name, 1 | |
35 | .endm | |
36 | .macro END name | |
37 | .size \name, . - \name | |
38 | .endm | |
39 | .macro HIDDEN name | |
40 | .hidden \name | |
41 | .endm | |
42 | .macro CALL name | |
43 | bl \name @notoc | |
44 | .endm | |
45 | #elif defined(__powerpc64__) && _CALL_ELF == 2 | |
b54214fe UW |
46 | .macro FUNC name |
47 | .globl \name | |
48 | .type \name, @function | |
49 | \name: | |
50 | 0: addis 2,12,(.TOC.-0b)@ha | |
51 | addi 2,2,(.TOC.-0b)@l | |
52 | .localentry \name, . - \name | |
53 | .endm | |
54 | .macro END name | |
55 | .size \name, . - \name | |
56 | .endm | |
57 | .macro HIDDEN name | |
58 | .hidden \name | |
59 | .endm | |
60 | .macro CALL name | |
61 | bl \name | |
62 | nop | |
63 | .endm | |
64 | #elif defined(__powerpc64__) && defined(__ELF__) | |
a32e5e93 RH |
65 | .macro FUNC name |
66 | .globl \name, .\name | |
67 | .section ".opd","aw" | |
68 | .align 3 | |
69 | \name: | |
70 | .quad .\name, .TOC.@tocbase, 0 | |
71 | .size \name, 24 | |
72 | .type .\name, @function | |
73 | .text | |
74 | .\name: | |
75 | .endm | |
76 | .macro END name | |
77 | .size .\name, . - .\name | |
78 | .endm | |
79 | .macro HIDDEN name | |
80 | .hidden \name, .\name | |
81 | .endm | |
82 | .macro CALL name | |
83 | bl \name | |
84 | nop | |
85 | .endm | |
86 | #elif defined(__ELF__) | |
87 | .macro FUNC name | |
88 | .globl \name | |
89 | .type \name, @function | |
90 | \name: | |
91 | .endm | |
92 | .macro END name | |
93 | .size \name, . - \name | |
94 | .endm | |
95 | .macro HIDDEN name | |
96 | .hidden \name | |
97 | .endm | |
98 | .macro CALL name | |
99 | bl \name | |
100 | .endm | |
101 | #elif defined(_CALL_DARWIN) | |
cd5a9a74 | 102 | .macro FUNC |
a32e5e93 RH |
103 | .globl _$0 |
104 | _$0: | |
105 | .endmacro | |
cd5a9a74 | 106 | .macro END |
a32e5e93 | 107 | .endmacro |
cd5a9a74 | 108 | .macro HIDDEN |
a32e5e93 RH |
109 | .private_extern _$0 |
110 | .endmacro | |
cd5a9a74 | 111 | .macro CALL |
a32e5e93 RH |
112 | bl _$0 |
113 | .endmacro | |
114 | # ifdef __ppc64__ | |
115 | .machine ppc64 | |
116 | # else | |
117 | .machine ppc7400 | |
118 | # endif | |
119 | #else | |
120 | #error "unsupported system" | |
121 | #endif | |
122 | ||
123 | /* Parameterize the naming of registers. */ | |
124 | #if defined(__ELF__) | |
125 | # define r(N) %r##N | |
126 | # define f(N) %f##N | |
127 | # define v(N) %v##N | |
128 | #elif defined(__MACH__) | |
129 | # define r(N) r##N | |
130 | # define f(N) f##N | |
131 | # define v(N) v##N | |
132 | #else | |
133 | # define r(N) N | |
134 | # define f(N) N | |
135 | # define v(N) N | |
136 | #endif | |
137 | ||
138 | /* Parameterize the code for 32-bit vs 64-bit. */ | |
139 | #if defined(__powerpc64__) || defined(__ppc64__) | |
140 | #define ldreg ld | |
141 | #define streg std | |
142 | #define stregu stdu | |
143 | #define WS 8 | |
144 | #else | |
145 | #define ldreg lwz | |
146 | #define streg stw | |
147 | #define stregu stwu | |
148 | #define WS 4 | |
149 | #endif | |
150 | ||
151 | /* Parameterize the code for call frame constants. */ | |
152 | #if defined(_CALL_AIXDESC) | |
153 | # define BASE 6*WS | |
154 | # define LR_SAVE 2*WS | |
b54214fe UW |
155 | #elif _CALL_ELF == 2 |
156 | # define BASE 6*WS | |
157 | # define LR_SAVE 2*WS | |
a32e5e93 RH |
158 | #elif defined(_CALL_SYSV) |
159 | # define BASE 2*WS | |
160 | # define LR_SAVE 1*WS | |
161 | #elif defined(_CALL_DARWIN) | |
162 | # define BASE (6*WS + 2*WS) | |
163 | # define LR_SAVE 2*WS | |
164 | #else | |
165 | # error "unsupported system" | |
166 | #endif | |
167 | ||
168 | #if defined(__ALTIVEC__) || defined(__VSX__) | |
169 | # define OFS_VR 0 | |
170 | # define OFS_VSCR 12*16 | |
171 | # define OFS_VR_END OFS_VSCR + 8 | |
172 | #else | |
173 | # define OFS_VR_END 0 | |
174 | #endif | |
175 | #ifndef _SOFT_FLOAT | |
176 | # define OFS_FR OFS_VR_END | |
177 | # define OFS_FPSCR OFS_FR + 18*8 | |
178 | # define OFS_FR_END OFS_FPSCR + 8 | |
179 | #else | |
180 | # define OFS_FR_END OFS_VR_END | |
181 | #endif | |
182 | #define OFS_GR OFS_FR_END | |
183 | #define OFS_CFA OFS_GR + 18*WS | |
184 | #define OFS_LR OFS_CFA + WS | |
185 | #define OFS_TOC OFS_LR + WS | |
186 | #define OFS_CR OFS_TOC + WS | |
187 | #define OFS_END (((OFS_CR + WS + 15) / 16) * 16) | |
188 | ||
189 | #define FRAME (((BASE + OFS_END + 15) / 16) * 16) | |
190 | #define VRSAVE 256 | |
191 | ||
192 | .align 4 | |
193 | FUNC _ITM_beginTransaction | |
194 | cfi_startproc | |
195 | mflr r(0) | |
196 | mfcr r(5) | |
197 | addi r(4), r(1), -OFS_END | |
198 | mr r(6), r(1) | |
199 | streg r(0), LR_SAVE(r(1)) | |
200 | stregu r(1), -FRAME(r(1)) | |
201 | cfi_def_cfa_offset(FRAME) | |
202 | cfi_offset(65, LR_SAVE) | |
203 | streg r(6), OFS_CFA(r(4)) | |
204 | streg r(0), OFS_LR(r(4)) | |
205 | #ifdef _CALL_DARWIN | |
206 | streg r(13), OFS_TOC(r(4)) | |
207 | #else | |
208 | streg r(2), OFS_TOC(r(4)) | |
209 | #endif | |
210 | streg r(5), OFS_CR(r(4)) | |
211 | streg r(14), 0*WS+OFS_GR(r(4)) | |
212 | streg r(15), 1*WS+OFS_GR(r(4)) | |
213 | streg r(16), 2*WS+OFS_GR(r(4)) | |
214 | streg r(17), 3*WS+OFS_GR(r(4)) | |
215 | streg r(18), 4*WS+OFS_GR(r(4)) | |
216 | streg r(19), 5*WS+OFS_GR(r(4)) | |
217 | streg r(20), 6*WS+OFS_GR(r(4)) | |
218 | streg r(21), 7*WS+OFS_GR(r(4)) | |
219 | streg r(22), 8*WS+OFS_GR(r(4)) | |
220 | streg r(23), 9*WS+OFS_GR(r(4)) | |
221 | streg r(24), 10*WS+OFS_GR(r(4)) | |
222 | streg r(25), 11*WS+OFS_GR(r(4)) | |
223 | streg r(26), 12*WS+OFS_GR(r(4)) | |
224 | streg r(27), 13*WS+OFS_GR(r(4)) | |
225 | streg r(28), 14*WS+OFS_GR(r(4)) | |
226 | streg r(29), 15*WS+OFS_GR(r(4)) | |
227 | streg r(30), 16*WS+OFS_GR(r(4)) | |
228 | streg r(31), 17*WS+OFS_GR(r(4)) | |
229 | ||
230 | #ifndef _SOFT_FLOAT | |
231 | /* ??? Determine when FPRs not present. */ | |
232 | /* ??? Test r(3) for pr_hasNoFloatUpdate and skip the fp save. | |
233 | This is not yet set by the compiler. */ | |
234 | mffs f(0) | |
235 | stfd f(14), 0+OFS_FR(r(4)) | |
236 | stfd f(15), 8+OFS_FR(r(4)) | |
237 | stfd f(16), 16+OFS_FR(r(4)) | |
238 | stfd f(17), 24+OFS_FR(r(4)) | |
239 | stfd f(18), 32+OFS_FR(r(4)) | |
240 | stfd f(19), 40+OFS_FR(r(4)) | |
241 | stfd f(20), 48+OFS_FR(r(4)) | |
242 | stfd f(21), 56+OFS_FR(r(4)) | |
243 | stfd f(22), 64+OFS_FR(r(4)) | |
244 | stfd f(23), 72+OFS_FR(r(4)) | |
245 | stfd f(24), 80+OFS_FR(r(4)) | |
246 | stfd f(25), 88+OFS_FR(r(4)) | |
247 | stfd f(26), 96+OFS_FR(r(4)) | |
248 | stfd f(27),104+OFS_FR(r(4)) | |
249 | stfd f(28),112+OFS_FR(r(4)) | |
250 | stfd f(29),120+OFS_FR(r(4)) | |
251 | stfd f(30),128+OFS_FR(r(4)) | |
252 | stfd f(31),136+OFS_FR(r(4)) | |
253 | stfd f(0), OFS_FPSCR(r(4)) | |
254 | #endif | |
255 | ||
256 | #if defined(__ALTIVEC__) | |
257 | /* ??? Determine when VRs not present. */ | |
258 | /* ??? Test r(3) for pr_hasNoVectorUpdate and skip the vr save. | |
259 | This is not yet set by the compiler. */ | |
260 | addi r(5), r(4), OFS_VR | |
261 | addi r(6), r(4), OFS_VR+16 | |
262 | mfspr r(0), VRSAVE | |
263 | stvx v(20), 0, r(5) | |
264 | addi r(5), r(5), 32 | |
265 | stvx v(21), 0, r(6) | |
266 | addi r(6), r(6), 32 | |
267 | stvx v(22), 0, r(5) | |
268 | addi r(5), r(5), 32 | |
269 | stvx v(23), 0, r(6) | |
270 | addi r(6), r(6), 32 | |
271 | stvx v(25), 0, r(5) | |
272 | addi r(5), r(5), 32 | |
273 | stvx v(26), 0, r(6) | |
274 | addi r(6), r(6), 32 | |
275 | stvx v(26), 0, r(5) | |
276 | addi r(5), r(5), 32 | |
277 | stvx v(27), 0, r(6) | |
278 | addi r(6), r(6), 32 | |
279 | stvx v(28), 0, r(5) | |
280 | addi r(5), r(5), 32 | |
281 | stvx v(29), 0, r(6) | |
282 | addi r(6), r(6), 32 | |
283 | stvx v(30), 0, r(5) | |
284 | stvx v(31), 0, r(6) | |
285 | streg r(0), OFS_VSCR(r(4)) | |
286 | #endif | |
287 | ||
288 | CALL GTM_begin_transaction | |
289 | ||
290 | ldreg r(0), LR_SAVE+FRAME(r(1)) | |
291 | mtlr r(0) | |
292 | addi r(1), r(1), FRAME | |
293 | cfi_def_cfa_offset(0) | |
294 | cfi_restore(65) | |
295 | blr | |
296 | cfi_endproc | |
297 | END _ITM_beginTransaction | |
298 | ||
299 | .align 4 | |
300 | HIDDEN GTM_longjmp | |
301 | FUNC GTM_longjmp | |
302 | cfi_startproc | |
303 | #if defined(__ALTIVEC__) || defined(__VSX__) | |
304 | /* ??? Determine when VRs not present. */ | |
305 | /* ??? Test r(5) for pr_hasNoVectorUpdate and skip the vr restore. | |
306 | This is not yet set by the compiler. */ | |
307 | addi r(6), r(4), OFS_VR | |
308 | addi r(7), r(4), OFS_VR+16 | |
309 | ldreg r(0), OFS_VSCR(r(4)) | |
310 | cfi_undefined(v(20)) | |
311 | cfi_undefined(v(21)) | |
312 | cfi_undefined(v(22)) | |
313 | cfi_undefined(v(23)) | |
314 | cfi_undefined(v(24)) | |
315 | cfi_undefined(v(25)) | |
316 | cfi_undefined(v(26)) | |
317 | cfi_undefined(v(27)) | |
318 | cfi_undefined(v(28)) | |
319 | cfi_undefined(v(29)) | |
320 | cfi_undefined(v(30)) | |
321 | cfi_undefined(v(31)) | |
322 | lvx v(20), 0, r(6) | |
323 | addi r(6), r(6), 32 | |
324 | lvx v(21), 0, r(7) | |
325 | addi r(7), r(7), 32 | |
326 | lvx v(22), 0, r(6) | |
327 | addi r(6), r(6), 32 | |
328 | lvx v(23), 0, r(7) | |
329 | addi r(7), r(7), 32 | |
330 | lvx v(24), 0, r(6) | |
331 | addi r(6), r(6), 32 | |
332 | lvx v(25), 0, r(7) | |
333 | addi r(7), r(7), 32 | |
334 | lvx v(26), 0, r(6) | |
335 | addi r(6), r(6), 32 | |
336 | lvx v(27), 0, r(7) | |
337 | addi r(7), r(7), 32 | |
338 | lvx v(28), 0, r(6) | |
339 | addi r(6), r(6), 32 | |
340 | lvx v(29), 0, r(7) | |
341 | addi r(7), r(7), 32 | |
342 | lvx v(30), 0, r(6) | |
343 | lvx v(31), 0, r(7) | |
344 | mtspr VRSAVE, r(0) | |
345 | #endif | |
346 | ||
347 | #ifndef _SOFT_FLOAT | |
348 | /* ??? Determine when FPRs not present. */ | |
349 | /* ??? Test r(5) for pr_hasNoFloatUpdate and skip the fp load. | |
350 | This is not yet set by the compiler. */ | |
351 | lfd f(0), OFS_FPSCR(r(4)) | |
352 | cfi_undefined(f(14)) | |
353 | cfi_undefined(f(15)) | |
354 | cfi_undefined(f(16)) | |
355 | cfi_undefined(f(17)) | |
356 | cfi_undefined(f(18)) | |
357 | cfi_undefined(f(19)) | |
358 | cfi_undefined(f(20)) | |
359 | cfi_undefined(f(21)) | |
360 | cfi_undefined(f(22)) | |
361 | cfi_undefined(f(23)) | |
362 | cfi_undefined(f(24)) | |
363 | cfi_undefined(f(25)) | |
364 | cfi_undefined(f(26)) | |
365 | cfi_undefined(f(27)) | |
366 | cfi_undefined(f(28)) | |
367 | cfi_undefined(f(29)) | |
368 | cfi_undefined(f(30)) | |
369 | cfi_undefined(f(31)) | |
370 | lfd f(14), 0+OFS_FR(r(4)) | |
371 | lfd f(15), 8+OFS_FR(r(4)) | |
372 | lfd f(16), 16+OFS_FR(r(4)) | |
373 | lfd f(17), 24+OFS_FR(r(4)) | |
374 | lfd f(18), 32+OFS_FR(r(4)) | |
375 | lfd f(19), 40+OFS_FR(r(4)) | |
376 | lfd f(20), 48+OFS_FR(r(4)) | |
377 | lfd f(21), 56+OFS_FR(r(4)) | |
378 | lfd f(22), 64+OFS_FR(r(4)) | |
379 | lfd f(23), 72+OFS_FR(r(4)) | |
380 | lfd f(24), 80+OFS_FR(r(4)) | |
381 | lfd f(25), 88+OFS_FR(r(4)) | |
382 | lfd f(26), 96+OFS_FR(r(4)) | |
383 | lfd f(27),104+OFS_FR(r(4)) | |
384 | lfd f(28),112+OFS_FR(r(4)) | |
385 | lfd f(29),120+OFS_FR(r(4)) | |
386 | lfd f(30),128+OFS_FR(r(4)) | |
387 | lfd f(31),136+OFS_FR(r(4)) | |
388 | mtfsf 0xff, f(0) | |
389 | #endif | |
390 | ||
391 | ldreg r(6), OFS_CFA(r(4)) | |
392 | ldreg r(0), OFS_LR(r(4)) | |
393 | #ifdef _CALL_DARWIN | |
394 | ldreg r(13), OFS_TOC(r(4)) | |
395 | #else | |
396 | ldreg r(2), OFS_TOC(r(4)) | |
397 | #endif | |
398 | ldreg r(7), OFS_CR(r(4)) | |
399 | /* At the instant we restore the LR, the only coherent view of | |
400 | the world we have is into the new stack frame. Define the | |
401 | CFA in terms of the not-yet-restored stack pointer. This will | |
402 | last until the end of the function. */ | |
403 | mtlr r(0) | |
404 | cfi_def_cfa(r(6), 0) | |
405 | cfi_undefined(r(14)) | |
406 | cfi_undefined(r(15)) | |
407 | cfi_undefined(r(16)) | |
408 | cfi_undefined(r(17)) | |
409 | cfi_undefined(r(18)) | |
410 | cfi_undefined(r(19)) | |
411 | cfi_undefined(r(20)) | |
412 | cfi_undefined(r(21)) | |
413 | cfi_undefined(r(22)) | |
414 | cfi_undefined(r(23)) | |
415 | cfi_undefined(r(24)) | |
416 | cfi_undefined(r(25)) | |
417 | cfi_undefined(r(26)) | |
418 | cfi_undefined(r(27)) | |
419 | cfi_undefined(r(28)) | |
420 | cfi_undefined(r(29)) | |
421 | cfi_undefined(r(30)) | |
422 | cfi_undefined(r(31)) | |
423 | mtcr r(7) | |
424 | ldreg r(14), 0*WS+OFS_GR(r(4)) | |
425 | ldreg r(15), 1*WS+OFS_GR(r(4)) | |
426 | ldreg r(16), 2*WS+OFS_GR(r(4)) | |
427 | ldreg r(17), 3*WS+OFS_GR(r(4)) | |
428 | ldreg r(18), 4*WS+OFS_GR(r(4)) | |
429 | ldreg r(19), 5*WS+OFS_GR(r(4)) | |
430 | ldreg r(20), 6*WS+OFS_GR(r(4)) | |
431 | ldreg r(21), 7*WS+OFS_GR(r(4)) | |
432 | ldreg r(22), 8*WS+OFS_GR(r(4)) | |
433 | ldreg r(23), 9*WS+OFS_GR(r(4)) | |
434 | ldreg r(24), 10*WS+OFS_GR(r(4)) | |
435 | ldreg r(25), 11*WS+OFS_GR(r(4)) | |
436 | ldreg r(26), 12*WS+OFS_GR(r(4)) | |
437 | ldreg r(27), 13*WS+OFS_GR(r(4)) | |
438 | ldreg r(28), 14*WS+OFS_GR(r(4)) | |
439 | ldreg r(29), 15*WS+OFS_GR(r(4)) | |
440 | ldreg r(30), 16*WS+OFS_GR(r(4)) | |
441 | ldreg r(31), 17*WS+OFS_GR(r(4)) | |
442 | mr r(1), r(6) | |
443 | blr | |
444 | cfi_endproc | |
445 | END GTM_longjmp | |
446 | ||
447 | #ifdef __linux__ | |
448 | .section .note.GNU-stack, "", @progbits | |
449 | #endif |