rl78.md: New define_expand "smindi3".
[gcc.git] / libgcc / config / s390 / morestack.S
1 # s390 support for -fsplit-stack.
2 # Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 # Contributed by Marcin Koƛcielnicki <koriakin@0x04.net>.
4
5 # This file is part of GCC.
6
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.
11
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.
16
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.
20
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/>.
25
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
30
31 # The __morestack function.
32
33 .global __morestack
34 .hidden __morestack
35
36 .type __morestack,@function
37
38 __morestack:
39 .LFB1:
40 .cfi_startproc
41
42
43 #ifndef __s390x__
44
45
46 # The 31-bit __morestack function.
47
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
57
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).
75
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
83
84 brasl %r14, __morestack_block_signals
85
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
95
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.
99
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.
105
106 brasl %r14, __morestack_unblock_signals
107
108 lr %r0, %r8 # Static chain.
109 lm %r2, %r6, 0x8(%r11) # Paremeter registers.
110
111 # Third parameter is address of function meat - address of parameter
112 # block.
113 a %r10, 0x8(%r10)
114
115 # Leave vararg pointer in %r1, in case function uses it
116 la %r1, 0x60(%r11)
117
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.
128
129 stm %r2, %r3, 0x8(%r11) # Save return registers.
130
131 brasl %r14, __morestack_block_signals
132
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
139
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.
145
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
152
153 brasl %r14, __morestack_unblock_signals
154
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.
169
170 # Executed if no new stack allocation is needed.
171
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
185
186 .Lnostackparm:
187 # Third parameter is address of function meat - address of parameter
188 # block.
189 a %r10, 0x8(%r10)
190
191 # Leave vararg pointer in %r1, in case function uses it
192 la %r1, 0x60(%r11)
193
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.
198
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.
213
214 # This is the cleanup code called by the stack unwinder when unwinding
215 # through the code between .LEHB0 and .LEHE0 above.
216
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.
226
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
235
236 #else /* defined(__s390x__) */
237
238
239 # The 64-bit __morestack function.
240
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
250
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).
268
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
278
279 brasl %r14, __morestack_block_signals
280
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
290
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.
294
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.
302
303 brasl %r14, __morestack_unblock_signals
304
305 lgr %r0, %r8 # Static chain.
306 lmg %r2, %r6, 0x10(%r11) # Paremeter registers.
307
308 # Third parameter is address of function meat - address of parameter
309 # block.
310 ag %r10, 0x10(%r10)
311
312 # Leave vararg pointer in %r1, in case function uses it
313 la %r1, 0xa0(%r11)
314
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.
325
326 stg %r2, 0x10(%r11) # Save return register.
327
328 brasl %r14, __morestack_block_signals
329
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
336
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.
344
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
351
352 brasl %r14, __morestack_unblock_signals
353
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.
368
369 # Executed if no new stack allocation is needed.
370
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
384
385 .Lnostackparm:
386 # Third parameter is address of function meat - address of parameter
387 # block.
388 ag %r10, 0x10(%r10)
389
390 # Leave vararg pointer in %r1, in case function uses it
391 la %r1, 0xa0(%r11)
392
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.
397
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.
412
413 # This is the cleanup code called by the stack unwinder when unwinding
414 # through the code between .LEHB0 and .LEHE0 above.
415
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.
427
428 lgr %r2, %r6 # Exception header.
429 #ifdef __PIC__
430 brasl %r14, _Unwind_Resume@PLT
431 #else
432 brasl %r14, _Unwind_Resume
433 #endif
434
435 #endif /* defined(__s390x__) */
436
437 .cfi_endproc
438 .size __morestack, . - __morestack
439
440
441 # The exception table. This tells the personality routine to execute
442 # the exception handler.
443
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:
457
458
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
478
479
480
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.
484
485 .text
486 .global __stack_split_initialize
487 .hidden __stack_split_initialize
488
489 .type __stack_split_initialize, @function
490
491 __stack_split_initialize:
492
493 #ifndef __s390x__
494
495 ear %r1, %a0
496 lr %r0, %r15
497 ahi %r0, -0x4000 # We should have at least 16K.
498 st %r0, 0x20(%r1)
499
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
507
508 #else /* defined(__s390x__) */
509
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)
516
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
524
525 #endif /* defined(__s390x__) */
526
527 .size __stack_split_initialize, . - __stack_split_initialize
528
529 # Routines to get and set the guard, for __splitstack_getcontext,
530 # __splitstack_setcontext, and __splitstack_makecontext.
531
532 # void *__morestack_get_guard (void) returns the current stack guard.
533 .text
534 .global __morestack_get_guard
535 .hidden __morestack_get_guard
536
537 .type __morestack_get_guard,@function
538
539 __morestack_get_guard:
540
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
551
552 .size __morestack_get_guard, . - __morestack_get_guard
553
554 # void __morestack_set_guard (void *) sets the stack guard.
555 .global __morestack_set_guard
556 .hidden __morestack_set_guard
557
558 .type __morestack_set_guard,@function
559
560 __morestack_set_guard:
561
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
572
573 .size __morestack_set_guard, . - __morestack_set_guard
574
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
579
580 .type __morestack_make_guard,@function
581
582 __morestack_make_guard:
583
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
592
593 .size __morestack_make_guard, . - __morestack_make_guard
594
595 # Make __stack_split_initialize a high priority constructor.
596
597 .section .ctors.65535,"aw",@progbits
598
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
608
609 .section .note.GNU-stack,"",@progbits
610 .section .note.GNU-split-stack,"",@progbits
611 .section .note.GNU-no-split-stack,"",@progbits