2018-11-11 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgcc / config / s390 / morestack.S
blob510d7a0c88cf0f0e5695d76d9961bf25eac9c04b
1 # s390 support for -fsplit-stack.
2 # Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 # Contributed by Marcin Koƛcielnicki <koriakin@0x04.net>.
5 # This file is part of GCC.
7 # GCC is free software; you can redistribute it and/or modify it under
8 # the terms of the GNU General Public License as published by the Free
9 # Software Foundation; either version 3, or (at your option) any later
10 # version.
12 # GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 # for more details.
17 # Under Section 7 of GPL version 3, you are granted additional
18 # permissions described in the GCC Runtime Library Exception, version
19 # 3.1, as published by the Free Software Foundation.
21 # You should have received a copy of the GNU General Public License and
22 # a copy of the GCC Runtime Library Exception along with this program;
23 # see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 # <http://www.gnu.org/licenses/>.
26 # Excess space needed to call ld.so resolver for lazy plt
27 # resolution.  Go uses sigaltstack so this doesn't need to
28 # also cover signal frame size.
29 #define BACKOFF 0x1000
31 # The __morestack function.
33         .global __morestack
34         .hidden __morestack
36         .type   __morestack,@function
38 __morestack:
39 .LFB1:
40         .cfi_startproc
43 #ifndef __s390x__
46 # The 31-bit __morestack function.
48         # We use a cleanup to restore the stack guard if an exception
49         # is thrown through this code.
50 #ifndef __PIC__
51         .cfi_personality 0,__gcc_personality_v0
52         .cfi_lsda 0,.LLSDA1
53 #else
54         .cfi_personality 0x9b,DW.ref.__gcc_personality_v0
55         .cfi_lsda 0x1b,.LLSDA1
56 #endif
58         stm     %r2, %r15, 0x8(%r15)    # Save %r2-%r15.
59         .cfi_offset %r6, -0x48
60         .cfi_offset %r7, -0x44
61         .cfi_offset %r8, -0x40
62         .cfi_offset %r9, -0x3c
63         .cfi_offset %r10, -0x38
64         .cfi_offset %r11, -0x34
65         .cfi_offset %r12, -0x30
66         .cfi_offset %r13, -0x2c
67         .cfi_offset %r14, -0x28
68         .cfi_offset %r15, -0x24
69         lr      %r11, %r15              # Make frame pointer for vararg.
70         .cfi_def_cfa_register %r11
71         ahi     %r15, -0x60             # 0x60 for standard frame.
72         st      %r11, 0(%r15)           # Save back chain.
73         lr      %r8, %r0                # Save %r0 (static chain).
74         lr      %r10, %r1               # Save %r1 (address of parameter block).
76         l       %r7, 0(%r10)            # Required frame size to %r7
77         ear     %r1, %a0                # Extract thread pointer.
78         l       %r1, 0x20(%r1)          # Get stack bounduary
79         ar      %r1, %r7                # Stack bounduary + frame size
80         a       %r1, 4(%r10)            # + stack param size
81         clr     %r1, %r15               # Compare with current stack pointer
82         jle     .Lnoalloc               # guard > sp - frame-size: need alloc
84         brasl   %r14, __morestack_block_signals
86         # We abuse one of caller's fpr save slots (which we don't use for fprs)
87         # as a local variable.  Not needed here, but done to be consistent with
88         # the below use.
89         ahi     %r7, BACKOFF            # Bump requested size a bit.
90         st      %r7, 0x40(%r11)         # Stuff frame size on stack.
91         la      %r2, 0x40(%r11)         # Pass its address as parameter.
92         la      %r3, 0x60(%r11)         # Caller's stack parameters.
93         l       %r4, 4(%r10)            # Size of stack parameters.
94         brasl   %r14, __generic_morestack
96         lr      %r15, %r2               # Switch to the new stack.
97         ahi     %r15, -0x60             # Make a stack frame on it.
98         st      %r11, 0(%r15)           # Save back chain.
100         s       %r2, 0x40(%r11)         # The end of stack space.
101         ahi     %r2, BACKOFF            # Back off a bit.
102         ear     %r1, %a0                # Extract thread pointer.
103 .LEHB0:
104         st      %r2, 0x20(%r1)  # Save the new stack boundary.
106         brasl   %r14, __morestack_unblock_signals
108         lr      %r0, %r8                # Static chain.
109         lm      %r2, %r6, 0x8(%r11)     # Paremeter registers.
111         # Third parameter is address of function meat - address of parameter
112         # block.
113         a       %r10, 0x8(%r10)
115         # Leave vararg pointer in %r1, in case function uses it
116         la      %r1, 0x60(%r11)
118         # State of registers:
119         # %r0: Static chain from entry.
120         # %r1: Vararg pointer.
121         # %r2-%r6: Parameters from entry.
122         # %r7-%r10: Indeterminate.
123         # %r11: Frame pointer (%r15 from entry).
124         # %r12-%r13: Indeterminate.
125         # %r14: Return address.
126         # %r15: Stack pointer.
127         basr    %r14, %r10              # Call our caller.
129         stm     %r2, %r3, 0x8(%r11)     # Save return registers.
131         brasl   %r14, __morestack_block_signals
133         # We need a stack slot now, but have no good way to get it - the frame
134         # on new stack had to be exactly 0x60 bytes, or stack parameters would
135         # be passed wrong.  Abuse fpr save area in caller's frame (we don't
136         # save actual fprs).
137         la      %r2, 0x40(%r11)
138         brasl   %r14, __generic_releasestack
140         s       %r2, 0x40(%r11)         # Subtract available space.
141         ahi     %r2, BACKOFF            # Back off a bit.
142         ear     %r1, %a0                # Extract thread pointer.
143 .LEHE0:
144         st      %r2, 0x20(%r1)  # Save the new stack boundary.
146         # We need to restore the old stack pointer before unblocking signals.
147         # We also need 0x60 bytes for a stack frame.  Since we had a stack
148         # frame at this place before the stack switch, there's no need to
149         # write the back chain again.
150         lr      %r15, %r11
151         ahi     %r15, -0x60
153         brasl   %r14, __morestack_unblock_signals
155         lm      %r2, %r15, 0x8(%r11)    # Restore all registers.
156         .cfi_remember_state
157         .cfi_restore %r15
158         .cfi_restore %r14
159         .cfi_restore %r13
160         .cfi_restore %r12
161         .cfi_restore %r11
162         .cfi_restore %r10
163         .cfi_restore %r9
164         .cfi_restore %r8
165         .cfi_restore %r7
166         .cfi_restore %r6
167         .cfi_def_cfa_register %r15
168         br      %r14                    # Return to caller's caller.
170 # Executed if no new stack allocation is needed.
172 .Lnoalloc:
173         .cfi_restore_state
174         # We may need to copy stack parameters.
175         l       %r9, 0x4(%r10)          # Load stack parameter size.
176         ltr     %r9, %r9                # And check if it's 0.
177         je      .Lnostackparm           # Skip the copy if not needed.
178         sr      %r15, %r9               # Make space on the stack.
179         la      %r8, 0x60(%r15)         # Destination.
180         la      %r12, 0x60(%r11)        # Source.
181         lr      %r13, %r9               # Source size.
182 .Lcopy:
183         mvcle   %r8, %r12, 0            # Copy.
184         jo      .Lcopy
186 .Lnostackparm:
187         # Third parameter is address of function meat - address of parameter
188         # block.
189         a       %r10, 0x8(%r10)
191         # Leave vararg pointer in %r1, in case function uses it
192         la      %r1, 0x60(%r11)
194         # OK, no stack allocation needed.  We still follow the protocol and
195         # call our caller - it doesn't cost much and makes sure vararg works.
196         # No need to set any registers here - %r0 and %r2-%r6 weren't modified.
197         basr    %r14, %r10              # Call our caller.
199         lm      %r6, %r15, 0x18(%r11)   # Restore all callee-saved registers.
200         .cfi_remember_state
201         .cfi_restore %r15
202         .cfi_restore %r14
203         .cfi_restore %r13
204         .cfi_restore %r12
205         .cfi_restore %r11
206         .cfi_restore %r10
207         .cfi_restore %r9
208         .cfi_restore %r8
209         .cfi_restore %r7
210         .cfi_restore %r6
211         .cfi_def_cfa_register %r15
212         br      %r14                    # Return to caller's caller.
214 # This is the cleanup code called by the stack unwinder when unwinding
215 # through the code between .LEHB0 and .LEHE0 above.
217 .L1:
218         .cfi_restore_state
219         lr      %r2, %r11               # Stack pointer after resume.
220         brasl   %r14, __generic_findstack
221         lr      %r3, %r11               # Get the stack pointer.
222         sr      %r3, %r2                # Subtract available space.
223         ahi     %r3, BACKOFF            # Back off a bit.
224         ear     %r1, %a0                # Extract thread pointer.
225         st      %r3, 0x20(%r1)  # Save the new stack boundary.
227         # We need GOT pointer in %r12 for PLT entry.
228         larl    %r12,_GLOBAL_OFFSET_TABLE_
229         lr      %r2, %r6                # Exception header.
230 #ifdef __PIC__
231         brasl   %r14, _Unwind_Resume@PLT
232 #else
233         brasl   %r14, _Unwind_Resume
234 #endif
236 #else /* defined(__s390x__) */
239 # The 64-bit __morestack function.
241         # We use a cleanup to restore the stack guard if an exception
242         # is thrown through this code.
243 #ifndef __PIC__
244         .cfi_personality 0x3,__gcc_personality_v0
245         .cfi_lsda 0x3,.LLSDA1
246 #else
247         .cfi_personality 0x9b,DW.ref.__gcc_personality_v0
248         .cfi_lsda 0x1b,.LLSDA1
249 #endif
251         stmg    %r2, %r15, 0x10(%r15)   # Save %r2-%r15.
252         .cfi_offset %r6, -0x70
253         .cfi_offset %r7, -0x68
254         .cfi_offset %r8, -0x60
255         .cfi_offset %r9, -0x58
256         .cfi_offset %r10, -0x50
257         .cfi_offset %r11, -0x48
258         .cfi_offset %r12, -0x40
259         .cfi_offset %r13, -0x38
260         .cfi_offset %r14, -0x30
261         .cfi_offset %r15, -0x28
262         lgr     %r11, %r15              # Make frame pointer for vararg.
263         .cfi_def_cfa_register %r11
264         aghi    %r15, -0xa0             # 0xa0 for standard frame.
265         stg     %r11, 0(%r15)           # Save back chain.
266         lgr     %r8, %r0                # Save %r0 (static chain).
267         lgr     %r10, %r1               # Save %r1 (address of parameter block).
269         lg      %r7, 0(%r10)            # Required frame size to %r7
270         ear     %r1, %a0
271         sllg    %r1, %r1, 32
272         ear     %r1, %a1                # Extract thread pointer.
273         lg      %r1, 0x38(%r1)          # Get stack bounduary
274         agr     %r1, %r7                # Stack bounduary + frame size
275         ag      %r1, 8(%r10)            # + stack param size
276         clgr    %r1, %r15               # Compare with current stack pointer
277         jle     .Lnoalloc               # guard > sp - frame-size: need alloc
279         brasl   %r14, __morestack_block_signals
281         # We abuse one of caller's fpr save slots (which we don't use for fprs)
282         # as a local variable.  Not needed here, but done to be consistent with
283         # the below use.
284         aghi    %r7, BACKOFF            # Bump requested size a bit.
285         stg     %r7, 0x80(%r11)         # Stuff frame size on stack.
286         la      %r2, 0x80(%r11)         # Pass its address as parameter.
287         la      %r3, 0xa0(%r11)         # Caller's stack parameters.
288         lg      %r4, 8(%r10)            # Size of stack parameters.
289         brasl   %r14, __generic_morestack
291         lgr     %r15, %r2               # Switch to the new stack.
292         aghi    %r15, -0xa0             # Make a stack frame on it.
293         stg     %r11, 0(%r15)           # Save back chain.
295         sg      %r2, 0x80(%r11)         # The end of stack space.
296         aghi    %r2, BACKOFF            # Back off a bit.
297         ear     %r1, %a0
298         sllg    %r1, %r1, 32
299         ear     %r1, %a1                # Extract thread pointer.
300 .LEHB0:
301         stg     %r2, 0x38(%r1)  # Save the new stack boundary.
303         brasl   %r14, __morestack_unblock_signals
305         lgr     %r0, %r8                # Static chain.
306         lmg     %r2, %r6, 0x10(%r11)    # Paremeter registers.
308         # Third parameter is address of function meat - address of parameter
309         # block.
310         ag      %r10, 0x10(%r10)
312         # Leave vararg pointer in %r1, in case function uses it
313         la      %r1, 0xa0(%r11)
315         # State of registers:
316         # %r0: Static chain from entry.
317         # %r1: Vararg pointer.
318         # %r2-%r6: Parameters from entry.
319         # %r7-%r10: Indeterminate.
320         # %r11: Frame pointer (%r15 from entry).
321         # %r12-%r13: Indeterminate.
322         # %r14: Return address.
323         # %r15: Stack pointer.
324         basr    %r14, %r10              # Call our caller.
326         stg     %r2, 0x10(%r11)         # Save return register.
328         brasl   %r14, __morestack_block_signals
330         # We need a stack slot now, but have no good way to get it - the frame
331         # on new stack had to be exactly 0xa0 bytes, or stack parameters would
332         # be passed wrong.  Abuse fpr save area in caller's frame (we don't
333         # save actual fprs).
334         la      %r2, 0x80(%r11)
335         brasl   %r14, __generic_releasestack
337         sg      %r2, 0x80(%r11)         # Subtract available space.
338         aghi    %r2, BACKOFF            # Back off a bit.
339         ear     %r1, %a0
340         sllg    %r1, %r1, 32
341         ear     %r1, %a1                # Extract thread pointer.
342 .LEHE0:
343         stg     %r2, 0x38(%r1)  # Save the new stack boundary.
345         # We need to restore the old stack pointer before unblocking signals.
346         # We also need 0xa0 bytes for a stack frame.  Since we had a stack
347         # frame at this place before the stack switch, there's no need to
348         # write the back chain again.
349         lgr     %r15, %r11
350         aghi    %r15, -0xa0
352         brasl   %r14, __morestack_unblock_signals
354         lmg     %r2, %r15, 0x10(%r11)   # Restore all registers.
355         .cfi_remember_state
356         .cfi_restore %r15
357         .cfi_restore %r14
358         .cfi_restore %r13
359         .cfi_restore %r12
360         .cfi_restore %r11
361         .cfi_restore %r10
362         .cfi_restore %r9
363         .cfi_restore %r8
364         .cfi_restore %r7
365         .cfi_restore %r6
366         .cfi_def_cfa_register %r15
367         br      %r14                    # Return to caller's caller.
369 # Executed if no new stack allocation is needed.
371 .Lnoalloc:
372         .cfi_restore_state
373         # We may need to copy stack parameters.
374         lg      %r9, 0x8(%r10)          # Load stack parameter size.
375         ltgr    %r9, %r9                # Check if it's 0.
376         je      .Lnostackparm           # Skip the copy if not needed.
377         sgr     %r15, %r9               # Make space on the stack.
378         la      %r8, 0xa0(%r15)         # Destination.
379         la      %r12, 0xa0(%r11)        # Source.
380         lgr     %r13, %r9               # Source size.
381 .Lcopy:
382         mvcle   %r8, %r12, 0            # Copy.
383         jo      .Lcopy
385 .Lnostackparm:
386         # Third parameter is address of function meat - address of parameter
387         # block.
388         ag      %r10, 0x10(%r10)
390         # Leave vararg pointer in %r1, in case function uses it
391         la      %r1, 0xa0(%r11)
393         # OK, no stack allocation needed.  We still follow the protocol and
394         # call our caller - it doesn't cost much and makes sure vararg works.
395         # No need to set any registers here - %r0 and %r2-%r6 weren't modified.
396         basr    %r14, %r10              # Call our caller.
398         lmg     %r6, %r15, 0x30(%r11)   # Restore all callee-saved registers.
399         .cfi_remember_state
400         .cfi_restore %r15
401         .cfi_restore %r14
402         .cfi_restore %r13
403         .cfi_restore %r12
404         .cfi_restore %r11
405         .cfi_restore %r10
406         .cfi_restore %r9
407         .cfi_restore %r8
408         .cfi_restore %r7
409         .cfi_restore %r6
410         .cfi_def_cfa_register %r15
411         br      %r14                    # Return to caller's caller.
413 # This is the cleanup code called by the stack unwinder when unwinding
414 # through the code between .LEHB0 and .LEHE0 above.
416 .L1:
417         .cfi_restore_state
418         lgr     %r2, %r11               # Stack pointer after resume.
419         brasl   %r14, __generic_findstack
420         lgr     %r3, %r11               # Get the stack pointer.
421         sgr     %r3, %r2                # Subtract available space.
422         aghi    %r3, BACKOFF            # Back off a bit.
423         ear     %r1, %a0
424         sllg    %r1, %r1, 32
425         ear     %r1, %a1                # Extract thread pointer.
426         stg     %r3, 0x38(%r1)  # Save the new stack boundary.
428         lgr     %r2, %r6                # Exception header.
429 #ifdef __PIC__
430         brasl   %r14, _Unwind_Resume@PLT
431 #else
432         brasl   %r14, _Unwind_Resume
433 #endif
435 #endif /* defined(__s390x__) */
437         .cfi_endproc
438         .size   __morestack, . - __morestack
441 # The exception table.  This tells the personality routine to execute
442 # the exception handler.
444         .section        .gcc_except_table,"a",@progbits
445         .align  4
446 .LLSDA1:
447         .byte   0xff    # @LPStart format (omit)
448         .byte   0xff    # @TType format (omit)
449         .byte   0x1     # call-site format (uleb128)
450         .uleb128 .LLSDACSE1-.LLSDACSB1  # Call-site table length
451 .LLSDACSB1:
452         .uleb128 .LEHB0-.LFB1   # region 0 start
453         .uleb128 .LEHE0-.LEHB0  # length
454         .uleb128 .L1-.LFB1      # landing pad
455         .uleb128 0              # action
456 .LLSDACSE1:
459         .global __gcc_personality_v0
460 #ifdef __PIC__
461         # Build a position independent reference to the basic
462         # personality function.
463         .hidden DW.ref.__gcc_personality_v0
464         .weak   DW.ref.__gcc_personality_v0
465         .section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat
466         .type   DW.ref.__gcc_personality_v0, @object
467 DW.ref.__gcc_personality_v0:
468 #ifndef __LP64__
469         .align 4
470         .size   DW.ref.__gcc_personality_v0, 4
471         .long   __gcc_personality_v0
472 #else
473         .align 8
474         .size   DW.ref.__gcc_personality_v0, 8
475         .quad   __gcc_personality_v0
476 #endif
477 #endif
481 # Initialize the stack test value when the program starts or when a
482 # new thread starts.  We don't know how large the main stack is, so we
483 # guess conservatively.  We might be able to use getrlimit here.
485         .text
486         .global __stack_split_initialize
487         .hidden __stack_split_initialize
489         .type   __stack_split_initialize, @function
491 __stack_split_initialize:
493 #ifndef __s390x__
495         ear     %r1, %a0
496         lr      %r0, %r15
497         ahi     %r0, -0x4000    # We should have at least 16K.
498         st      %r0, 0x20(%r1)
500         lr      %r2, %r15
501         lhi     %r3, 0x4000
502 #ifdef __PIC__
503         jg      __generic_morestack_set_initial_sp@PLT  # Tail call
504 #else
505         jg      __generic_morestack_set_initial_sp      # Tail call
506 #endif
508 #else /* defined(__s390x__) */
510         ear     %r1, %a0
511         sllg    %r1, %r1, 32
512         ear     %r1, %a1
513         lgr     %r0, %r15
514         aghi    %r0, -0x4000    # We should have at least 16K.
515         stg     %r0, 0x38(%r1)
517         lgr     %r2, %r15
518         lghi    %r3, 0x4000
519 #ifdef __PIC__
520         jg      __generic_morestack_set_initial_sp@PLT  # Tail call
521 #else
522         jg      __generic_morestack_set_initial_sp      # Tail call
523 #endif
525 #endif /* defined(__s390x__) */
527         .size   __stack_split_initialize, . - __stack_split_initialize
529 # Routines to get and set the guard, for __splitstack_getcontext,
530 # __splitstack_setcontext, and __splitstack_makecontext.
532 # void *__morestack_get_guard (void) returns the current stack guard.
533         .text
534         .global __morestack_get_guard
535         .hidden __morestack_get_guard
537         .type   __morestack_get_guard,@function
539 __morestack_get_guard:
541 #ifndef __s390x__
542         ear     %r1, %a0
543         l       %r2, 0x20(%r1)
544 #else
545         ear     %r1, %a0
546         sllg    %r1, %r1, 32
547         ear     %r1, %a1
548         lg      %r2, 0x38(%r1)
549 #endif
550         br %r14
552         .size   __morestack_get_guard, . - __morestack_get_guard
554 # void __morestack_set_guard (void *) sets the stack guard.
555         .global __morestack_set_guard
556         .hidden __morestack_set_guard
558         .type   __morestack_set_guard,@function
560 __morestack_set_guard:
562 #ifndef __s390x__
563         ear     %r1, %a0
564         st      %r2, 0x20(%r1)
565 #else
566         ear     %r1, %a0
567         sllg    %r1, %r1, 32
568         ear     %r1, %a1
569         stg     %r2, 0x38(%r1)
570 #endif
571         br      %r14
573         .size   __morestack_set_guard, . - __morestack_set_guard
575 # void *__morestack_make_guard (void *, size_t) returns the stack
576 # guard value for a stack.
577         .global __morestack_make_guard
578         .hidden __morestack_make_guard
580         .type   __morestack_make_guard,@function
582 __morestack_make_guard:
584 #ifndef __s390x__
585         sr      %r2, %r3
586         ahi     %r2, BACKOFF
587 #else
588         sgr     %r2, %r3
589         aghi    %r2, BACKOFF
590 #endif
591         br      %r14
593         .size   __morestack_make_guard, . - __morestack_make_guard
595 # Make __stack_split_initialize a high priority constructor.
597         .section .ctors.65535,"aw",@progbits
599 #ifndef __LP64__
600         .align  4
601         .long   __stack_split_initialize
602         .long   __morestack_load_mmap
603 #else
604         .align  8
605         .quad   __stack_split_initialize
606         .quad   __morestack_load_mmap
607 #endif
609         .section        .note.GNU-stack,"",@progbits
610         .section        .note.GNU-split-stack,"",@progbits
611         .section        .note.GNU-no-split-stack,"",@progbits