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