]> git.ipfire.org Git - thirdparty/gcc.git/blame - libphobos/libdruntime/config/aarch64/switchcontext.S
Update copyright years.
[thirdparty/gcc.git] / libphobos / libdruntime / config / aarch64 / switchcontext.S
CommitLineData
2493e718 1/* AArch64 support code for fibers and multithreading.
99dee823 2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
2493e718
IB
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
24
25#include "../common/threadasm.S"
26
27/**
28 * preserve/restore AAPCS64 registers
29 * x19-x28 5.1.1 64-bit callee saved
30 * x29 fp, or possibly callee saved reg - depends on platform choice 5.2.3)
31 * x30 lr
32 * d8-d15 5.1.2 says callee only must save bottom 64-bits (the "d" regs)
33 *
34 * saved regs on stack will look like:
35 * 19: x19
36 * 18: x20
37 * ...
38 * 10: x28
39 * 9: x29 (fp) <-- oldp / *newp save stack top
40 * 8: x30 (lr)
41 * 7: d8
42 * ...
43 * 0: d15 <-- sp
44 */
45 .text
46 .global CSYM(fiber_switchContext)
47 .type CSYM(fiber_switchContext), %function
48 .align 4
49CSYM(fiber_switchContext):
50 .cfi_startproc
51 stp d15, d14, [sp, #-20*8]!
52 stp d13, d12, [sp, #2*8]
53 stp d11, d10, [sp, #4*8]
54 stp d9, d8, [sp, #6*8]
55 stp x30, x29, [sp, #8*8] // lr, fp
56 stp x28, x27, [sp, #10*8]
57 stp x26, x25, [sp, #12*8]
58 stp x24, x23, [sp, #14*8]
59 stp x22, x21, [sp, #16*8]
60 stp x20, x19, [sp, #18*8]
61
62 // oldp is set above saved lr (x30) to hide it and float regs
63 // from GC
64 add x19, sp, #9*8
65 str x19, [x0] // *oldp tstack
66 sub sp, x1, #9*8 // switch to newp sp
67
68 ldp x20, x19, [sp, #18*8]
69 ldp x22, x21, [sp, #16*8]
70 ldp x24, x23, [sp, #14*8]
71 ldp x26, x25, [sp, #12*8]
72 ldp x28, x27, [sp, #10*8]
73 ldp x30, x29, [sp, #8*8] // lr, fp
74 ldp d9, d8, [sp, #6*8]
75 ldp d11, d10, [sp, #4*8]
76 ldp d13, d12, [sp, #2*8]
77 ldp d15, d14, [sp], #20*8
78 ret
79 .cfi_endproc
80 .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
81
82/**
83 * When generating any kind of backtrace (gdb, exception handling) for
84 * a function called in a Fiber, we need to tell the unwinder to stop
85 * at our Fiber main entry point, i.e. we need to mark the bottom of
86 * the call stack. This can be done by clearing the link register lr
87 * prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or
88 * using a .cfi_undefined directive for the link register in the
89 * Fiber entry point. cfi_undefined seems to yield better results in gdb.
90 * Unfortunately we can't place it into fiber_entryPoint using inline
91 * asm, so we use this trampoline instead.
92 */
93 .text
94 .global CSYM(fiber_trampoline)
95 .p2align 2
96 .type CSYM(fiber_trampoline), %function
97CSYM(fiber_trampoline):
98 .cfi_startproc
99 .cfi_undefined x30
100 // fiber_entryPoint never returns
101 bl CSYM(fiber_entryPoint)
102 .cfi_endproc
103 .size CSYM(fiber_trampoline),.-CSYM(fiber_trampoline)