1 | /* Copyright (C) 1999-2022 Free Software Foundation, Inc. |
2 | |
3 | The GNU C Library is free software; you can redistribute it and/or |
4 | modify it under the terms of the GNU Lesser General Public |
5 | License as published by the Free Software Foundation; either |
6 | version 2.1 of the License, or (at your option) any later version. |
7 | |
8 | The GNU C Library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Lesser General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Lesser General Public |
14 | License along with the GNU C Library; if not, see |
15 | <https://www.gnu.org/licenses/>. |
16 | |
17 | The layout of the jmp_buf is as follows. This is subject to change |
18 | and user-code should never depend on the particular layout of |
19 | jmp_buf! |
20 | |
21 | |
22 | offset: description: |
23 | ------- ------------ |
24 | 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS) |
25 | 0x008 r1 (gp) |
26 | 0x010 caller's unat |
27 | 0x018 fpsr ; disabled per the C standard; BZ 16379 |
28 | 0x020 r4 |
29 | 0x028 r5 |
30 | 0x030 r6 |
31 | 0x038 r7 |
32 | 0x040 rp (b0) |
33 | 0x048 b1 |
34 | 0x050 b2 |
35 | 0x058 b3 |
36 | 0x060 b4 |
37 | 0x068 b5 |
38 | 0x070 ar.pfs |
39 | 0x078 ar.lc |
40 | 0x080 pr |
41 | 0x088 ar.bsp ; unchangeable (see __longjmp.S) |
42 | 0x090 ar.unat |
43 | 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat) |
44 | 0x0a0 f2 |
45 | 0x0b0 f3 |
46 | 0x0c0 f4 |
47 | 0x0d0 f5 |
48 | 0x0e0 f16 |
49 | 0x0f0 f17 |
50 | 0x100 f18 |
51 | 0x110 f19 |
52 | 0x120 f20 |
53 | 0x130 f21 |
54 | 0x130 f22 |
55 | 0x140 f23 |
56 | 0x150 f24 |
57 | 0x160 f25 |
58 | 0x170 f26 |
59 | 0x180 f27 |
60 | 0x190 f28 |
61 | 0x1a0 f29 |
62 | 0x1b0 f30 |
63 | 0x1c0 f31 */ |
64 | |
65 | #include <sysdep.h> |
66 | #include <features.h> |
67 | |
68 | /* The following two entry points are the traditional entry points: */ |
69 | |
70 | LEAF(setjmp) |
71 | alloc r8=ar.pfs,2,0,0,0 |
72 | mov in1=1 |
73 | br.cond.sptk.many HIDDEN_JUMPTARGET(__sigsetjmp) |
74 | END(setjmp) |
75 | |
76 | LEAF(_setjmp) |
77 | alloc r8=ar.pfs,2,0,0,0 |
78 | mov in1=0 |
79 | br.cond.sptk.many HIDDEN_JUMPTARGET(__sigsetjmp) |
80 | END(_setjmp) |
81 | libc_hidden_def (_setjmp) |
82 | |
83 | /* __sigsetjmp(__jmp_buf buf, int savemask) */ |
84 | |
85 | ENTRY(__sigsetjmp) |
86 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) |
87 | alloc loc1=ar.pfs,2,5,2,0 |
88 | .save ar.unat, loc2 |
89 | mov loc2=ar.unat |
90 | ;; |
91 | // mov r17=ar.fpsr |
92 | mov r2=in0 |
93 | add r3=8,in0 |
94 | ;; |
95 | .mem.offset 8,0; st8.spill.nta [r2]=sp,16 // r12 (sp) |
96 | .mem.offset 0,0; st8.spill.nta [r3]=gp,32 // r1 (gp) |
97 | ;; |
98 | st8.nta [r2]=loc2,16 // save caller's unat |
99 | // st8.nta [r3]=r17,16 // save fpsr |
100 | add r8=0xa0,in0 |
101 | ;; |
102 | .mem.offset 8,0; st8.spill.nta [r2]=r4,16 // r4 |
103 | .mem.offset 0,0; st8.spill.nta [r3]=r5,16 // r5 |
104 | add r9=0xb0,in0 |
105 | ;; |
106 | stf.spill.nta [r8]=f2,32 |
107 | stf.spill.nta [r9]=f3,32 |
108 | mov loc0=rp |
109 | .body |
110 | ;; |
111 | stf.spill.nta [r8]=f4,32 |
112 | stf.spill.nta [r9]=f5,32 |
113 | mov r17=b1 |
114 | ;; |
115 | stf.spill.nta [r8]=f16,32 |
116 | stf.spill.nta [r9]=f17,32 |
117 | mov r18=b2 |
118 | ;; |
119 | stf.spill.nta [r8]=f18,32 |
120 | stf.spill.nta [r9]=f19,32 |
121 | mov r19=b3 |
122 | ;; |
123 | stf.spill.nta [r8]=f20,32 |
124 | stf.spill.nta [r9]=f21,32 |
125 | mov r20=b4 |
126 | ;; |
127 | stf.spill.nta [r8]=f22,32 |
128 | stf.spill.nta [r9]=f23,32 |
129 | mov r21=b5 |
130 | ;; |
131 | stf.spill.nta [r8]=f24,32 |
132 | stf.spill.nta [r9]=f25,32 |
133 | mov r22=ar.lc |
134 | ;; |
135 | stf.spill.nta [r8]=f26,32 |
136 | stf.spill.nta [r9]=f27,32 |
137 | mov r24=pr |
138 | ;; |
139 | stf.spill.nta [r8]=f28,32 |
140 | stf.spill.nta [r9]=f29,32 |
141 | #ifdef PTR_MANGLE |
142 | mov loc3=loc0 |
143 | ;; |
144 | PTR_MANGLE (loc3, loc4) |
145 | #else |
146 | ;; |
147 | #endif |
148 | stf.spill.nta [r8]=f30 |
149 | stf.spill.nta [r9]=f31 |
150 | |
151 | .mem.offset 8,0; st8.spill.nta [r2]=r6,16 // r6 |
152 | .mem.offset 0,0; st8.spill.nta [r3]=r7,16 // r7 |
153 | ;; |
154 | mov r23=ar.bsp |
155 | mov r25=ar.unat |
156 | mov out0=in0 |
157 | |
158 | #ifdef PTR_MANGLE |
159 | st8.nta [r2]=loc3,16 // b0 |
160 | #else |
161 | st8.nta [r2]=loc0,16 // b0 |
162 | #endif |
163 | st8.nta [r3]=r17,16 // b1 |
164 | mov out1=in1 |
165 | ;; |
166 | st8.nta [r2]=r18,16 // b2 |
167 | st8.nta [r3]=r19,16 // b3 |
168 | ;; |
169 | st8.nta [r2]=r20,16 // b4 |
170 | st8.nta [r3]=r21,16 // b5 |
171 | ;; |
172 | st8.nta [r2]=loc1,16 // ar.pfs |
173 | st8.nta [r3]=r22,16 // ar.lc |
174 | ;; |
175 | st8.nta [r2]=r24,16 // pr |
176 | st8.nta [r3]=r23,16 // ar.bsp |
177 | ;; |
178 | st8.nta [r2]=r25 // ar.unat |
179 | st8.nta [r3]=in0 // &__jmp_buf |
180 | #if IS_IN (rtld) |
181 | /* In ld.so we never save the signal mask. */ |
182 | ;; |
183 | #else |
184 | br.call.dpnt.few rp=__sigjmp_save |
185 | #endif |
186 | .ret0: // force a new bundle ::q |
187 | mov.m ar.unat=loc2 // restore caller's unat |
188 | mov rp=loc0 |
189 | mov ar.pfs=loc1 |
190 | mov r8=0 |
191 | ret |
192 | END(__sigsetjmp) |
193 | libc_hidden_def (__sigsetjmp) |
194 | rtld_hidden_def (__sigsetjmp) |
195 | |
196 | weak_extern(_setjmp) |
197 | weak_extern(setjmp) |
198 | |