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_mOS+mOS_libcall+libcall_fn)(R6), R7
134 MOVD R7, 96(R1)
135 MOVD (m_mOS+mOS_libcall+libcall_args)(R6), R7
136 MOVD R7, 104(R1)
137 MOVD (m_mOS+mOS_libcall+libcall_n)(R6), R7
138 MOVD R7, 112(R1)
139 MOVD (m_mOS+mOS_libcall+libcall_r1)(R6), R7
140 MOVD R7, 120(R1)
141 MOVD (m_mOS+mOS_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_mOS+mOS_libcall+libcall_fn)(R6)
166 MOVD 104(R1), R7
167 MOVD R7, (m_mOS+mOS_libcall+libcall_args)(R6)
168 MOVD 112(R1), R7
169 MOVD R7, (m_mOS+mOS_libcall+libcall_n)(R6)
170 MOVD 120(R1), R7
171 MOVD R7, (m_mOS+mOS_libcall+libcall_r1)(R6)
172 MOVD 128(R1), R7
173 MOVD R7, (m_mOS+mOS_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 // runtime.rt0LibGoDesc is a function descriptor to rt0_lib_go,
201 // used by libInit to create a new thread on AIX where
202 // pthread_create expects a function descriptor, not a raw
203 // code address.
204 DATA runtime·rt0LibGoDesc+0(SB)/8, $runtime·rt0_lib_go(SB)
205 DATA runtime·rt0LibGoDesc+8(SB)/8, $TOC(SB)
206 DATA runtime·rt0LibGoDesc+16(SB)/8, $0
207 GLOBL runtime·rt0LibGoDesc(SB), NOPTR, $24
208
209 TEXT tstart<>(SB),NOSPLIT,$0
210 XOR R0, R0 // reset R0
211
212 // set g
213 MOVD m_g0(R3), g
214 BL runtime·save_g(SB)
215 MOVD R3, g_m(g)
216
217 // Layout new m scheduler stack on os stack.
218 MOVD R1, R3
219 MOVD R3, (g_stack+stack_hi)(g)
220 SUB $(const_threadStackSize), R3 // stack size
221 MOVD R3, (g_stack+stack_lo)(g)
222 ADD $const_stackGuard, R3
223 MOVD R3, g_stackguard0(g)
224 MOVD R3, g_stackguard1(g)
225
226 BL runtime·mstart(SB)
227
228 MOVD R0, R3
229 RET
230
231
232 #define CSYSCALL() \
233 MOVD 0(R12), R12 \
234 MOVD R2, 40(R1) \
235 MOVD 0(R12), R0 \
236 MOVD 8(R12), R2 \
237 MOVD R0, CTR \
238 BL (CTR) \
239 MOVD 40(R1), R2 \
240 BL runtime·reginit(SB)
241
242
243 // Runs on OS stack, called from runtime·osyield.
244 TEXT runtime·osyield1(SB),NOSPLIT,$0
245 MOVD $libc_sched_yield(SB), R12
246 CSYSCALL()
247 RET
248
249
250 // Runs on OS stack, called from runtime·sigprocmask.
251 TEXT runtime·sigprocmask1(SB),NOSPLIT,$0-24
252 MOVD how+0(FP), R3
253 MOVD new+8(FP), R4
254 MOVD old+16(FP), R5
255 MOVD $libpthread_sigthreadmask(SB), R12
256 CSYSCALL()
257 RET
258
259 // Runs on OS stack, called from runtime·usleep.
260 TEXT runtime·usleep1(SB),NOSPLIT,$0-4
261 MOVW us+0(FP), R3
262 MOVD $libc_usleep(SB), R12
263 CSYSCALL()
264 RET
265
266 // Runs on OS stack, called from runtime·exit.
267 TEXT runtime·exit1(SB),NOSPLIT,$0-4
268 MOVW code+0(FP), R3
269 MOVD $libc_exit(SB), R12
270 CSYSCALL()
271 RET
272
273 // Runs on OS stack, called from runtime·write1.
274 TEXT runtime·write2(SB),NOSPLIT,$0-28
275 MOVD fd+0(FP), R3
276 MOVD p+8(FP), R4
277 MOVW n+16(FP), R5
278 MOVD $libc_write(SB), R12
279 CSYSCALL()
280 MOVW R3, ret+24(FP)
281 RET
282
283 // Runs on OS stack, called from runtime·pthread_attr_init.
284 TEXT runtime·pthread_attr_init1(SB),NOSPLIT,$0-12
285 MOVD attr+0(FP), R3
286 MOVD $libpthread_attr_init(SB), R12
287 CSYSCALL()
288 MOVW R3, ret+8(FP)
289 RET
290
291 // Runs on OS stack, called from runtime·pthread_attr_setstacksize.
292 TEXT runtime·pthread_attr_setstacksize1(SB),NOSPLIT,$0-20
293 MOVD attr+0(FP), R3
294 MOVD size+8(FP), R4
295 MOVD $libpthread_attr_setstacksize(SB), R12
296 CSYSCALL()
297 MOVW R3, ret+16(FP)
298 RET
299
300 // Runs on OS stack, called from runtime·pthread_setdetachstate.
301 TEXT runtime·pthread_attr_setdetachstate1(SB),NOSPLIT,$0-20
302 MOVD attr+0(FP), R3
303 MOVW state+8(FP), R4
304 MOVD $libpthread_attr_setdetachstate(SB), R12
305 CSYSCALL()
306 MOVW R3, ret+16(FP)
307 RET
308
309 // Runs on OS stack, called from runtime·pthread_create.
310 TEXT runtime·pthread_create1(SB),NOSPLIT,$0-36
311 MOVD tid+0(FP), R3
312 MOVD attr+8(FP), R4
313 MOVD fn+16(FP), R5
314 MOVD arg+24(FP), R6
315 MOVD $libpthread_create(SB), R12
316 CSYSCALL()
317 MOVW R3, ret+32(FP)
318 RET
319
320 // Runs on OS stack, called from runtime·sigaction.
321 TEXT runtime·sigaction1(SB),NOSPLIT,$0-24
322 MOVD sig+0(FP), R3
323 MOVD new+8(FP), R4
324 MOVD old+16(FP), R5
325 MOVD $libc_sigaction(SB), R12
326 CSYSCALL()
327 RET
328
View as plain text