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