Text file
src/runtime/sys_aix_ppc64.s
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //
6 // System calls and other sys.stuff for ppc64, Aix
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12 #include "asm_ppc64x.h"
13
14 // This function calls a C function with the function descriptor in R12
15 TEXT callCfunction<>(SB), NOSPLIT|NOFRAME,$0
16 MOVD 0(R12), R12
17 MOVD R2, 40(R1)
18 MOVD 0(R12), R0
19 MOVD 8(R12), R2
20 MOVD R0, CTR
21 BR (CTR)
22
23
24 // asmsyscall6 calls a library function with a function descriptor
25 // stored in libcall_fn and store the results in libcall structure
26 // Up to 6 arguments can be passed to this C function
27 // Called by runtime.asmcgocall
28 // It reserves a stack of 288 bytes for the C function. It must
29 // follow AIX convention, thus the first local variable must
30 // be stored at the offset 112, after the linker area (48 bytes)
31 // and the argument area (64).
32 // The AIX convention is described here:
33 // https://www.ibm.com/docs/en/aix/7.2?topic=overview-runtime-process-stack
34 // NOT USING GO CALLING CONVENTION
35 // runtime.asmsyscall6 is a function descriptor to the real asmsyscall6.
36 DATA runtime·asmsyscall6+0(SB)/8, $asmsyscall6<>(SB)
37 DATA runtime·asmsyscall6+8(SB)/8, $TOC(SB)
38 DATA runtime·asmsyscall6+16(SB)/8, $0
39 GLOBL runtime·asmsyscall6(SB), NOPTR, $24
40
41 TEXT asmsyscall6<>(SB),NOSPLIT,$256
42 // Save libcall for later
43 MOVD R3, 112(R1)
44 MOVD libcall_fn(R3), R12
45 MOVD libcall_args(R3), R9
46 MOVD 0(R9), R3
47 MOVD 8(R9), R4
48 MOVD 16(R9), R5
49 MOVD 24(R9), R6
50 MOVD 32(R9), R7
51 MOVD 40(R9), R8
52 BL callCfunction<>(SB)
53
54 // Restore R0 and TOC
55 XOR R0, R0
56 MOVD 40(R1), R2
57
58 // Store result in libcall
59 MOVD 112(R1), R5
60 MOVD R3, (libcall_r1)(R5)
61 MOVD $-1, R6
62 CMP R6, R3
63 BNE skiperrno
64
65 // Save errno in libcall
66 BL runtime·load_g(SB)
67 MOVD g_m(g), R4
68 MOVD (m_mOS + mOS_perrno)(R4), R9
69 MOVW 0(R9), R9
70 MOVD R9, (libcall_err)(R5)
71 RET
72 skiperrno:
73 // Reset errno if no error has been returned
74 MOVD R0, (libcall_err)(R5)
75 RET
76
77
78 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
79 MOVW sig+8(FP), R3
80 MOVD info+16(FP), R4
81 MOVD ctx+24(FP), R5
82 MOVD fn+0(FP), R12
83 // fn is a function descriptor
84 // R2 must be saved on restore
85 MOVD 0(R12), R0
86 MOVD R2, 40(R1)
87 MOVD 8(R12), R2
88 MOVD R0, CTR
89 BL (CTR)
90 MOVD 40(R1), R2
91 BL runtime·reginit(SB)
92 RET
93
94
95 // runtime.sigtramp is a function descriptor to the real sigtramp.
96 DATA runtime·sigtramp+0(SB)/8, $sigtramp<>(SB)
97 DATA runtime·sigtramp+8(SB)/8, $TOC(SB)
98 DATA runtime·sigtramp+16(SB)/8, $0
99 GLOBL runtime·sigtramp(SB), NOPTR, $24
100
101 // This function must not have any frame as we want to control how
102 // every registers are used.
103 // TODO(aix): Implement SetCgoTraceback handler.
104 TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
105 MOVD LR, R0
106 MOVD R0, 16(R1)
107 // initialize essential registers (just in case)
108 BL runtime·reginit(SB)
109
110 // Note that we are executing on altsigstack here, so we have
111 // more stack available than NOSPLIT would have us believe.
112 // To defeat the linker, we make our own stack frame with
113 // more space.
114 SUB $144+FIXED_FRAME, R1
115
116 // Save registers
117 MOVD R31, 56(R1)
118 MOVD g, 64(R1)
119 MOVD R29, 72(R1)
120 MOVD R14, 80(R1)
121 MOVD R15, 88(R1)
122
123 BL runtime·load_g(SB)
124
125 CMP $0, g
126 BEQ sigtramp // g == nil
127 MOVD g_m(g), R6
128 CMP $0, R6
129 BEQ sigtramp // g.m == nil
130
131 // Save m->libcall. We need to do this because we
132 // might get interrupted by a signal in runtime·asmcgocall.
133 MOVD (m_libcall+libcall_fn)(R6), R7
134 MOVD R7, 96(R1)
135 MOVD (m_libcall+libcall_args)(R6), R7
136 MOVD R7, 104(R1)
137 MOVD (m_libcall+libcall_n)(R6), R7
138 MOVD R7, 112(R1)
139 MOVD (m_libcall+libcall_r1)(R6), R7
140 MOVD R7, 120(R1)
141 MOVD (m_libcall+libcall_r2)(R6), R7
142 MOVD R7, 128(R1)
143
144 // save errno, it might be EINTR; stuff we do here might reset it.
145 MOVD (m_mOS+mOS_perrno)(R6), R8
146 MOVD 0(R8), R8
147 MOVD R8, 136(R1)
148
149 sigtramp:
150 MOVW R3, FIXED_FRAME+0(R1)
151 MOVD R4, FIXED_FRAME+8(R1)
152 MOVD R5, FIXED_FRAME+16(R1)
153 MOVD $runtime·sigtrampgo(SB), R12
154 MOVD R12, CTR
155 BL (CTR)
156
157 CMP $0, g
158 BEQ exit // g == nil
159 MOVD g_m(g), R6
160 CMP $0, R6
161 BEQ exit // g.m == nil
162
163 // restore libcall
164 MOVD 96(R1), R7
165 MOVD R7, (m_libcall+libcall_fn)(R6)
166 MOVD 104(R1), R7
167 MOVD R7, (m_libcall+libcall_args)(R6)
168 MOVD 112(R1), R7
169 MOVD R7, (m_libcall+libcall_n)(R6)
170 MOVD 120(R1), R7
171 MOVD R7, (m_libcall+libcall_r1)(R6)
172 MOVD 128(R1), R7
173 MOVD R7, (m_libcall+libcall_r2)(R6)
174
175 // restore errno
176 MOVD (m_mOS+mOS_perrno)(R6), R7
177 MOVD 136(R1), R8
178 MOVD R8, 0(R7)
179
180 exit:
181 // restore registers
182 MOVD 56(R1),R31
183 MOVD 64(R1),g
184 MOVD 72(R1),R29
185 MOVD 80(R1), R14
186 MOVD 88(R1), R15
187
188 // Don't use RET because we need to restore R31 !
189 ADD $144+FIXED_FRAME, R1
190 MOVD 16(R1), R0
191 MOVD R0, LR
192 BR (LR)
193
194 // runtime.tstart is a function descriptor to the real tstart.
195 DATA runtime·tstart+0(SB)/8, $tstart<>(SB)
196 DATA runtime·tstart+8(SB)/8, $TOC(SB)
197 DATA runtime·tstart+16(SB)/8, $0
198 GLOBL runtime·tstart(SB), NOPTR, $24
199
200 TEXT tstart<>(SB),NOSPLIT,$0
201 XOR R0, R0 // reset R0
202
203 // set g
204 MOVD m_g0(R3), g
205 BL runtime·save_g(SB)
206 MOVD R3, g_m(g)
207
208 // Layout new m scheduler stack on os stack.
209 MOVD R1, R3
210 MOVD R3, (g_stack+stack_hi)(g)
211 SUB $(const_threadStackSize), R3 // stack size
212 MOVD R3, (g_stack+stack_lo)(g)
213 ADD $const_stackGuard, R3
214 MOVD R3, g_stackguard0(g)
215 MOVD R3, g_stackguard1(g)
216
217 BL runtime·mstart(SB)
218
219 MOVD R0, R3
220 RET
221
222
223 #define CSYSCALL() \
224 MOVD 0(R12), R12 \
225 MOVD R2, 40(R1) \
226 MOVD 0(R12), R0 \
227 MOVD 8(R12), R2 \
228 MOVD R0, CTR \
229 BL (CTR) \
230 MOVD 40(R1), R2 \
231 BL runtime·reginit(SB)
232
233
234 // Runs on OS stack, called from runtime·osyield.
235 TEXT runtime·osyield1(SB),NOSPLIT,$0
236 MOVD $libc_sched_yield(SB), R12
237 CSYSCALL()
238 RET
239
240
241 // Runs on OS stack, called from runtime·sigprocmask.
242 TEXT runtime·sigprocmask1(SB),NOSPLIT,$0-24
243 MOVD how+0(FP), R3
244 MOVD new+8(FP), R4
245 MOVD old+16(FP), R5
246 MOVD $libpthread_sigthreadmask(SB), R12
247 CSYSCALL()
248 RET
249
250 // Runs on OS stack, called from runtime·usleep.
251 TEXT runtime·usleep1(SB),NOSPLIT,$0-4
252 MOVW us+0(FP), R3
253 MOVD $libc_usleep(SB), R12
254 CSYSCALL()
255 RET
256
257 // Runs on OS stack, called from runtime·exit.
258 TEXT runtime·exit1(SB),NOSPLIT,$0-4
259 MOVW code+0(FP), R3
260 MOVD $libc_exit(SB), R12
261 CSYSCALL()
262 RET
263
264 // Runs on OS stack, called from runtime·write1.
265 TEXT runtime·write2(SB),NOSPLIT,$0-28
266 MOVD fd+0(FP), R3
267 MOVD p+8(FP), R4
268 MOVW n+16(FP), R5
269 MOVD $libc_write(SB), R12
270 CSYSCALL()
271 MOVW R3, ret+24(FP)
272 RET
273
274 // Runs on OS stack, called from runtime·pthread_attr_init.
275 TEXT runtime·pthread_attr_init1(SB),NOSPLIT,$0-12
276 MOVD attr+0(FP), R3
277 MOVD $libpthread_attr_init(SB), R12
278 CSYSCALL()
279 MOVW R3, ret+8(FP)
280 RET
281
282 // Runs on OS stack, called from runtime·pthread_attr_setstacksize.
283 TEXT runtime·pthread_attr_setstacksize1(SB),NOSPLIT,$0-20
284 MOVD attr+0(FP), R3
285 MOVD size+8(FP), R4
286 MOVD $libpthread_attr_setstacksize(SB), R12
287 CSYSCALL()
288 MOVW R3, ret+16(FP)
289 RET
290
291 // Runs on OS stack, called from runtime·pthread_setdetachstate.
292 TEXT runtime·pthread_attr_setdetachstate1(SB),NOSPLIT,$0-20
293 MOVD attr+0(FP), R3
294 MOVW state+8(FP), R4
295 MOVD $libpthread_attr_setdetachstate(SB), R12
296 CSYSCALL()
297 MOVW R3, ret+16(FP)
298 RET
299
300 // Runs on OS stack, called from runtime·pthread_create.
301 TEXT runtime·pthread_create1(SB),NOSPLIT,$0-36
302 MOVD tid+0(FP), R3
303 MOVD attr+8(FP), R4
304 MOVD fn+16(FP), R5
305 MOVD arg+24(FP), R6
306 MOVD $libpthread_create(SB), R12
307 CSYSCALL()
308 MOVW R3, ret+32(FP)
309 RET
310
311 // Runs on OS stack, called from runtime·sigaction.
312 TEXT runtime·sigaction1(SB),NOSPLIT,$0-24
313 MOVD sig+0(FP), R3
314 MOVD new+8(FP), R4
315 MOVD old+16(FP), R5
316 MOVD $libc_sigaction(SB), R12
317 CSYSCALL()
318 RET
319
View as plain text