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