Text file
src/runtime/sys_linux_s390x.s
Documentation: runtime
1 // Copyright 2016 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 // System calls and other system stuff for Linux s390x; see
6 // /usr/include/asm/unistd.h for the syscall number definitions.
7
8 #include "go_asm.h"
9 #include "go_tls.h"
10 #include "textflag.h"
11
12 #define SYS_exit 1
13 #define SYS_read 3
14 #define SYS_write 4
15 #define SYS_open 5
16 #define SYS_close 6
17 #define SYS_getpid 20
18 #define SYS_kill 37
19 #define SYS_pipe 42
20 #define SYS_brk 45
21 #define SYS_fcntl 55
22 #define SYS_mmap 90
23 #define SYS_munmap 91
24 #define SYS_setitimer 104
25 #define SYS_clone 120
26 #define SYS_sched_yield 158
27 #define SYS_nanosleep 162
28 #define SYS_rt_sigreturn 173
29 #define SYS_rt_sigaction 174
30 #define SYS_rt_sigprocmask 175
31 #define SYS_sigaltstack 186
32 #define SYS_madvise 219
33 #define SYS_mincore 218
34 #define SYS_gettid 236
35 #define SYS_futex 238
36 #define SYS_sched_getaffinity 240
37 #define SYS_tgkill 241
38 #define SYS_exit_group 248
39 #define SYS_epoll_create 249
40 #define SYS_epoll_ctl 250
41 #define SYS_epoll_wait 251
42 #define SYS_clock_gettime 260
43 #define SYS_pipe2 325
44 #define SYS_epoll_create1 327
45
46 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
47 MOVW code+0(FP), R2
48 MOVW $SYS_exit_group, R1
49 SYSCALL
50 RET
51
52 // func exitThread(wait *uint32)
53 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
54 MOVD wait+0(FP), R1
55 // We're done using the stack.
56 MOVW $0, R2
57 MOVW R2, (R1)
58 MOVW $0, R2 // exit code
59 MOVW $SYS_exit, R1
60 SYSCALL
61 JMP 0(PC)
62
63 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
64 MOVD name+0(FP), R2
65 MOVW mode+8(FP), R3
66 MOVW perm+12(FP), R4
67 MOVW $SYS_open, R1
68 SYSCALL
69 MOVD $-4095, R3
70 CMPUBLT R2, R3, 2(PC)
71 MOVW $-1, R2
72 MOVW R2, ret+16(FP)
73 RET
74
75 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
76 MOVW fd+0(FP), R2
77 MOVW $SYS_close, R1
78 SYSCALL
79 MOVD $-4095, R3
80 CMPUBLT R2, R3, 2(PC)
81 MOVW $-1, R2
82 MOVW R2, ret+8(FP)
83 RET
84
85 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
86 MOVD fd+0(FP), R2
87 MOVD p+8(FP), R3
88 MOVW n+16(FP), R4
89 MOVW $SYS_write, R1
90 SYSCALL
91 MOVW R2, ret+24(FP)
92 RET
93
94 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
95 MOVW fd+0(FP), R2
96 MOVD p+8(FP), R3
97 MOVW n+16(FP), R4
98 MOVW $SYS_read, R1
99 SYSCALL
100 MOVW R2, ret+24(FP)
101 RET
102
103 // func pipe() (r, w int32, errno int32)
104 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
105 MOVD $r+0(FP), R2
106 MOVW $SYS_pipe, R1
107 SYSCALL
108 MOVW R2, errno+8(FP)
109 RET
110
111 // func pipe2() (r, w int32, errno int32)
112 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
113 MOVD $r+8(FP), R2
114 MOVW flags+0(FP), R3
115 MOVW $SYS_pipe2, R1
116 SYSCALL
117 MOVW R2, errno+16(FP)
118 RET
119
120 TEXT runtime·usleep(SB),NOSPLIT,$16-4
121 MOVW usec+0(FP), R2
122 MOVD R2, R4
123 MOVW $1000000, R3
124 DIVD R3, R2
125 MOVD R2, 8(R15)
126 MOVW $1000, R3
127 MULLD R2, R3
128 SUB R3, R4
129 MOVD R4, 16(R15)
130
131 // nanosleep(&ts, 0)
132 ADD $8, R15, R2
133 MOVW $0, R3
134 MOVW $SYS_nanosleep, R1
135 SYSCALL
136 RET
137
138 TEXT runtime·gettid(SB),NOSPLIT,$0-4
139 MOVW $SYS_gettid, R1
140 SYSCALL
141 MOVW R2, ret+0(FP)
142 RET
143
144 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
145 MOVW $SYS_getpid, R1
146 SYSCALL
147 MOVW R2, R10
148 MOVW $SYS_gettid, R1
149 SYSCALL
150 MOVW R2, R3 // arg 2 tid
151 MOVW R10, R2 // arg 1 pid
152 MOVW sig+0(FP), R4 // arg 2
153 MOVW $SYS_tgkill, R1
154 SYSCALL
155 RET
156
157 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
158 MOVW $SYS_getpid, R1
159 SYSCALL
160 MOVW R2, R2 // arg 1 pid
161 MOVW sig+0(FP), R3 // arg 2
162 MOVW $SYS_kill, R1
163 SYSCALL
164 RET
165
166 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
167 MOVW $SYS_getpid, R1
168 SYSCALL
169 MOVD R2, ret+0(FP)
170 RET
171
172 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
173 MOVD tgid+0(FP), R2
174 MOVD tid+8(FP), R3
175 MOVD sig+16(FP), R4
176 MOVW $SYS_tgkill, R1
177 SYSCALL
178 RET
179
180 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
181 MOVW mode+0(FP), R2
182 MOVD new+8(FP), R3
183 MOVD old+16(FP), R4
184 MOVW $SYS_setitimer, R1
185 SYSCALL
186 RET
187
188 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
189 MOVD addr+0(FP), R2
190 MOVD n+8(FP), R3
191 MOVD dst+16(FP), R4
192 MOVW $SYS_mincore, R1
193 SYSCALL
194 MOVW R2, ret+24(FP)
195 RET
196
197 // func walltime() (sec int64, nsec int32)
198 TEXT runtime·walltime(SB),NOSPLIT,$16
199 MOVW $0, R2 // CLOCK_REALTIME
200 MOVD $tp-16(SP), R3
201 MOVW $SYS_clock_gettime, R1
202 SYSCALL
203 LMG tp-16(SP), R2, R3
204 // sec is in R2, nsec in R3
205 MOVD R2, sec+0(FP)
206 MOVW R3, nsec+8(FP)
207 RET
208
209 TEXT runtime·nanotime1(SB),NOSPLIT,$16
210 MOVW $1, R2 // CLOCK_MONOTONIC
211 MOVD $tp-16(SP), R3
212 MOVW $SYS_clock_gettime, R1
213 SYSCALL
214 LMG tp-16(SP), R2, R3
215 // sec is in R2, nsec in R3
216 // return nsec in R2
217 MULLD $1000000000, R2
218 ADD R3, R2
219 MOVD R2, ret+0(FP)
220 RET
221
222 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
223 MOVW how+0(FP), R2
224 MOVD new+8(FP), R3
225 MOVD old+16(FP), R4
226 MOVW size+24(FP), R5
227 MOVW $SYS_rt_sigprocmask, R1
228 SYSCALL
229 MOVD $-4095, R3
230 CMPUBLT R2, R3, 2(PC)
231 MOVD R0, 0(R0) // crash
232 RET
233
234 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
235 MOVD sig+0(FP), R2
236 MOVD new+8(FP), R3
237 MOVD old+16(FP), R4
238 MOVD size+24(FP), R5
239 MOVW $SYS_rt_sigaction, R1
240 SYSCALL
241 MOVW R2, ret+32(FP)
242 RET
243
244 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
245 MOVW sig+8(FP), R2
246 MOVD info+16(FP), R3
247 MOVD ctx+24(FP), R4
248 MOVD fn+0(FP), R5
249 BL R5
250 RET
251
252 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
253 RET
254
255 TEXT runtime·sigtramp(SB),NOSPLIT,$64
256 // initialize essential registers (just in case)
257 XOR R0, R0
258
259 // this might be called in external code context,
260 // where g is not set.
261 MOVB runtime·iscgo(SB), R6
262 CMPBEQ R6, $0, 2(PC)
263 BL runtime·load_g(SB)
264
265 MOVW R2, 8(R15)
266 MOVD R3, 16(R15)
267 MOVD R4, 24(R15)
268 MOVD $runtime·sigtrampgo(SB), R5
269 BL R5
270 RET
271
272 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
273 BR runtime·sigtramp(SB)
274
275 // func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
276 TEXT runtime·mmap(SB),NOSPLIT,$48-48
277 MOVD addr+0(FP), R2
278 MOVD n+8(FP), R3
279 MOVW prot+16(FP), R4
280 MOVW flags+20(FP), R5
281 MOVW fd+24(FP), R6
282 MOVWZ off+28(FP), R7
283
284 // s390x uses old_mmap, so the arguments need to be placed into
285 // a struct and a pointer to the struct passed to mmap.
286 MOVD R2, addr-48(SP)
287 MOVD R3, n-40(SP)
288 MOVD R4, prot-32(SP)
289 MOVD R5, flags-24(SP)
290 MOVD R6, fd-16(SP)
291 MOVD R7, off-8(SP)
292
293 MOVD $addr-48(SP), R2
294 MOVW $SYS_mmap, R1
295 SYSCALL
296 MOVD $-4095, R3
297 CMPUBLT R2, R3, ok
298 NEG R2
299 MOVD $0, p+32(FP)
300 MOVD R2, err+40(FP)
301 RET
302 ok:
303 MOVD R2, p+32(FP)
304 MOVD $0, err+40(FP)
305 RET
306
307 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
308 MOVD addr+0(FP), R2
309 MOVD n+8(FP), R3
310 MOVW $SYS_munmap, R1
311 SYSCALL
312 MOVD $-4095, R3
313 CMPUBLT R2, R3, 2(PC)
314 MOVD R0, 0(R0) // crash
315 RET
316
317 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
318 MOVD addr+0(FP), R2
319 MOVD n+8(FP), R3
320 MOVW flags+16(FP), R4
321 MOVW $SYS_madvise, R1
322 SYSCALL
323 MOVW R2, ret+24(FP)
324 RET
325
326 // int64 futex(int32 *uaddr, int32 op, int32 val,
327 // struct timespec *timeout, int32 *uaddr2, int32 val2);
328 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
329 MOVD addr+0(FP), R2
330 MOVW op+8(FP), R3
331 MOVW val+12(FP), R4
332 MOVD ts+16(FP), R5
333 MOVD addr2+24(FP), R6
334 MOVW val3+32(FP), R7
335 MOVW $SYS_futex, R1
336 SYSCALL
337 MOVW R2, ret+40(FP)
338 RET
339
340 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
341 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
342 MOVW flags+0(FP), R3
343 MOVD stk+8(FP), R2
344
345 // Copy mp, gp, fn off parent stack for use by child.
346 // Careful: Linux system call clobbers ???.
347 MOVD mp+16(FP), R7
348 MOVD gp+24(FP), R8
349 MOVD fn+32(FP), R9
350
351 MOVD R7, -8(R2)
352 MOVD R8, -16(R2)
353 MOVD R9, -24(R2)
354 MOVD $1234, R7
355 MOVD R7, -32(R2)
356
357 SYSCALL $SYS_clone
358
359 // In parent, return.
360 CMPBEQ R2, $0, 3(PC)
361 MOVW R2, ret+40(FP)
362 RET
363
364 // In child, on new stack.
365 // initialize essential registers
366 XOR R0, R0
367 MOVD -32(R15), R7
368 CMP R7, $1234
369 BEQ 2(PC)
370 MOVD R0, 0(R0)
371
372 // Initialize m->procid to Linux tid
373 SYSCALL $SYS_gettid
374
375 MOVD -24(R15), R9 // fn
376 MOVD -16(R15), R8 // g
377 MOVD -8(R15), R7 // m
378
379 CMPBEQ R7, $0, nog
380 CMP R8, $0
381 BEQ nog
382
383 MOVD R2, m_procid(R7)
384
385 // In child, set up new stack
386 MOVD R7, g_m(R8)
387 MOVD R8, g
388 //CALL runtime·stackcheck(SB)
389
390 nog:
391 // Call fn
392 BL R9
393
394 // It shouldn't return. If it does, exit that thread.
395 MOVW $111, R2
396 MOVW $SYS_exit, R1
397 SYSCALL
398 BR -2(PC) // keep exiting
399
400 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
401 MOVD new+0(FP), R2
402 MOVD old+8(FP), R3
403 MOVW $SYS_sigaltstack, R1
404 SYSCALL
405 MOVD $-4095, R3
406 CMPUBLT R2, R3, 2(PC)
407 MOVD R0, 0(R0) // crash
408 RET
409
410 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
411 MOVW $SYS_sched_yield, R1
412 SYSCALL
413 RET
414
415 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
416 MOVD pid+0(FP), R2
417 MOVD len+8(FP), R3
418 MOVD buf+16(FP), R4
419 MOVW $SYS_sched_getaffinity, R1
420 SYSCALL
421 MOVW R2, ret+24(FP)
422 RET
423
424 // int32 runtime·epollcreate(int32 size);
425 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
426 MOVW size+0(FP), R2
427 MOVW $SYS_epoll_create, R1
428 SYSCALL
429 MOVW R2, ret+8(FP)
430 RET
431
432 // int32 runtime·epollcreate1(int32 flags);
433 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
434 MOVW flags+0(FP), R2
435 MOVW $SYS_epoll_create1, R1
436 SYSCALL
437 MOVW R2, ret+8(FP)
438 RET
439
440 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
441 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
442 MOVW epfd+0(FP), R2
443 MOVW op+4(FP), R3
444 MOVW fd+8(FP), R4
445 MOVD ev+16(FP), R5
446 MOVW $SYS_epoll_ctl, R1
447 SYSCALL
448 MOVW R2, ret+24(FP)
449 RET
450
451 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
452 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
453 MOVW epfd+0(FP), R2
454 MOVD ev+8(FP), R3
455 MOVW nev+16(FP), R4
456 MOVW timeout+20(FP), R5
457 MOVW $SYS_epoll_wait, R1
458 SYSCALL
459 MOVW R2, ret+24(FP)
460 RET
461
462 // void runtime·closeonexec(int32 fd);
463 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
464 MOVW fd+0(FP), R2 // fd
465 MOVD $2, R3 // F_SETFD
466 MOVD $1, R4 // FD_CLOEXEC
467 MOVW $SYS_fcntl, R1
468 SYSCALL
469 RET
470
471 // func runtime·setNonblock(int32 fd)
472 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
473 MOVW fd+0(FP), R2 // fd
474 MOVD $3, R3 // F_GETFL
475 XOR R4, R4
476 MOVW $SYS_fcntl, R1
477 SYSCALL
478 MOVD $0x800, R4 // O_NONBLOCK
479 OR R2, R4
480 MOVW fd+0(FP), R2 // fd
481 MOVD $4, R3 // F_SETFL
482 MOVW $SYS_fcntl, R1
483 SYSCALL
484 RET
485
486 // func sbrk0() uintptr
487 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
488 // Implemented as brk(NULL).
489 MOVD $0, R2
490 MOVW $SYS_brk, R1
491 SYSCALL
492 MOVD R2, ret+0(FP)
493 RET
494
495 TEXT runtime·access(SB),$0-20
496 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
497 MOVW R0, ret+16(FP)
498 RET
499
500 TEXT runtime·connect(SB),$0-28
501 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
502 MOVW R0, ret+24(FP)
503 RET
504
505 TEXT runtime·socket(SB),$0-20
506 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
507 MOVW R0, ret+16(FP)
508 RET
509
View as plain text