github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/sys_linux_s390x.s (about) 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_mmap 90 21 #define SYS_munmap 91 22 #define SYS_setitimer 104 23 #define SYS_clone 120 24 #define SYS_sched_yield 158 25 #define SYS_nanosleep 162 26 #define SYS_rt_sigreturn 173 27 #define SYS_rt_sigaction 174 28 #define SYS_rt_sigprocmask 175 29 #define SYS_sigaltstack 186 30 #define SYS_madvise 219 31 #define SYS_mincore 218 32 #define SYS_gettid 236 33 #define SYS_futex 238 34 #define SYS_sched_getaffinity 240 35 #define SYS_tgkill 241 36 #define SYS_exit_group 248 37 #define SYS_timer_create 254 38 #define SYS_timer_settime 255 39 #define SYS_timer_delete 258 40 #define SYS_clock_gettime 260 41 #define SYS_pipe2 325 42 43 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4 44 MOVW code+0(FP), R2 45 MOVW $SYS_exit_group, R1 46 SYSCALL 47 RET 48 49 // func exitThread(wait *atomic.Uint32) 50 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 51 MOVD wait+0(FP), R1 52 // We're done using the stack. 53 MOVW $0, R2 54 MOVW R2, (R1) 55 MOVW $0, R2 // exit code 56 MOVW $SYS_exit, R1 57 SYSCALL 58 JMP 0(PC) 59 60 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20 61 MOVD name+0(FP), R2 62 MOVW mode+8(FP), R3 63 MOVW perm+12(FP), R4 64 MOVW $SYS_open, R1 65 SYSCALL 66 MOVD $-4095, R3 67 CMPUBLT R2, R3, 2(PC) 68 MOVW $-1, R2 69 MOVW R2, ret+16(FP) 70 RET 71 72 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12 73 MOVW fd+0(FP), R2 74 MOVW $SYS_close, R1 75 SYSCALL 76 MOVD $-4095, R3 77 CMPUBLT R2, R3, 2(PC) 78 MOVW $-1, R2 79 MOVW R2, ret+8(FP) 80 RET 81 82 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28 83 MOVD fd+0(FP), R2 84 MOVD p+8(FP), R3 85 MOVW n+16(FP), R4 86 MOVW $SYS_write, R1 87 SYSCALL 88 MOVW R2, ret+24(FP) 89 RET 90 91 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28 92 MOVW fd+0(FP), R2 93 MOVD p+8(FP), R3 94 MOVW n+16(FP), R4 95 MOVW $SYS_read, R1 96 SYSCALL 97 MOVW R2, ret+24(FP) 98 RET 99 100 // func pipe2() (r, w int32, errno int32) 101 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 102 MOVD $r+8(FP), R2 103 MOVW flags+0(FP), R3 104 MOVW $SYS_pipe2, R1 105 SYSCALL 106 MOVW R2, errno+16(FP) 107 RET 108 109 TEXT runtime·usleep(SB),NOSPLIT,$16-4 110 MOVW usec+0(FP), R2 111 MOVD R2, R4 112 MOVW $1000000, R3 113 DIVD R3, R2 114 MOVD R2, 8(R15) 115 MOVW $1000, R3 116 MULLD R2, R3 117 SUB R3, R4 118 MOVD R4, 16(R15) 119 120 // nanosleep(&ts, 0) 121 ADD $8, R15, R2 122 MOVW $0, R3 123 MOVW $SYS_nanosleep, R1 124 SYSCALL 125 RET 126 127 TEXT runtime·gettid(SB),NOSPLIT,$0-4 128 MOVW $SYS_gettid, R1 129 SYSCALL 130 MOVW R2, ret+0(FP) 131 RET 132 133 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 134 MOVW $SYS_getpid, R1 135 SYSCALL 136 MOVW R2, R10 137 MOVW $SYS_gettid, R1 138 SYSCALL 139 MOVW R2, R3 // arg 2 tid 140 MOVW R10, R2 // arg 1 pid 141 MOVW sig+0(FP), R4 // arg 2 142 MOVW $SYS_tgkill, R1 143 SYSCALL 144 RET 145 146 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 147 MOVW $SYS_getpid, R1 148 SYSCALL 149 MOVW R2, R2 // arg 1 pid 150 MOVW sig+0(FP), R3 // arg 2 151 MOVW $SYS_kill, R1 152 SYSCALL 153 RET 154 155 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8 156 MOVW $SYS_getpid, R1 157 SYSCALL 158 MOVD R2, ret+0(FP) 159 RET 160 161 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24 162 MOVD tgid+0(FP), R2 163 MOVD tid+8(FP), R3 164 MOVD sig+16(FP), R4 165 MOVW $SYS_tgkill, R1 166 SYSCALL 167 RET 168 169 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24 170 MOVW mode+0(FP), R2 171 MOVD new+8(FP), R3 172 MOVD old+16(FP), R4 173 MOVW $SYS_setitimer, R1 174 SYSCALL 175 RET 176 177 TEXT runtime·timer_create(SB),NOSPLIT|NOFRAME,$0-28 178 MOVW clockid+0(FP), R2 179 MOVD sevp+8(FP), R3 180 MOVD timerid+16(FP), R4 181 MOVW $SYS_timer_create, R1 182 SYSCALL 183 MOVW R2, ret+24(FP) 184 RET 185 186 TEXT runtime·timer_settime(SB),NOSPLIT|NOFRAME,$0-28 187 MOVW timerid+0(FP), R2 188 MOVW flags+4(FP), R3 189 MOVD new+8(FP), R4 190 MOVD old+16(FP), R5 191 MOVW $SYS_timer_settime, R1 192 SYSCALL 193 MOVW R2, ret+24(FP) 194 RET 195 196 TEXT runtime·timer_delete(SB),NOSPLIT|NOFRAME,$0-12 197 MOVW timerid+0(FP), R2 198 MOVW $SYS_timer_delete, R1 199 SYSCALL 200 MOVW R2, ret+8(FP) 201 RET 202 203 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 204 MOVD addr+0(FP), R2 205 MOVD n+8(FP), R3 206 MOVD dst+16(FP), R4 207 MOVW $SYS_mincore, R1 208 SYSCALL 209 MOVW R2, ret+24(FP) 210 RET 211 212 // func walltime() (sec int64, nsec int32) 213 TEXT runtime·walltime(SB),NOSPLIT,$32-12 214 MOVW $0, R2 // CLOCK_REALTIME 215 MOVD R15, R7 // Backup stack pointer 216 217 MOVD g_m(g), R6 //m 218 219 MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability 220 CMPBEQ R9, $0, fallback 221 222 MOVD m_vdsoPC(R6), R4 223 MOVD R4, 16(R15) 224 MOVD m_vdsoSP(R6), R4 225 MOVD R4, 24(R15) 226 227 MOVD R14, R8 // Backup return address 228 MOVD $sec+0(FP), R4 // return parameter caller 229 230 MOVD R8, m_vdsoPC(R6) 231 MOVD R4, m_vdsoSP(R6) 232 233 MOVD m_curg(R6), R5 234 CMP g, R5 235 BNE noswitch 236 237 MOVD m_g0(R6), R4 238 MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack 239 240 noswitch: 241 SUB $16, R15 // reserve 2x 8 bytes for parameters 242 MOVD $~7, R4 // align to 8 bytes because of gcc ABI 243 AND R4, R15 244 MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime 245 246 MOVB runtime·iscgo(SB),R12 247 CMPBNE R12, $0, nosaveg 248 249 MOVD m_gsignal(R6), R12 // g.m.gsignal 250 CMPBEQ R12, $0, nosaveg 251 252 CMPBEQ g, R12, nosaveg 253 MOVD (g_stack+stack_lo)(R12), R12 // g.m.gsignal.stack.lo 254 MOVD g, (R12) 255 256 BL R9 // to vdso lookup 257 258 MOVD $0, (R12) 259 260 JMP finish 261 262 nosaveg: 263 BL R9 // to vdso lookup 264 265 finish: 266 MOVD 0(R15), R3 // sec 267 MOVD 8(R15), R5 // nsec 268 MOVD R7, R15 // Restore SP 269 270 // Restore vdsoPC, vdsoSP 271 // We don't worry about being signaled between the two stores. 272 // If we are not in a signal handler, we'll restore vdsoSP to 0, 273 // and no one will care about vdsoPC. If we are in a signal handler, 274 // we cannot receive another signal. 275 MOVD 24(R15), R12 276 MOVD R12, m_vdsoSP(R6) 277 MOVD 16(R15), R12 278 MOVD R12, m_vdsoPC(R6) 279 280 return: 281 // sec is in R3, nsec in R5 282 // return nsec in R3 283 MOVD R3, sec+0(FP) 284 MOVW R5, nsec+8(FP) 285 RET 286 287 // Syscall fallback 288 fallback: 289 MOVD $tp-16(SP), R3 290 MOVW $SYS_clock_gettime, R1 291 SYSCALL 292 LMG tp-16(SP), R2, R3 293 // sec is in R2, nsec in R3 294 MOVD R2, sec+0(FP) 295 MOVW R3, nsec+8(FP) 296 RET 297 298 TEXT runtime·nanotime1(SB),NOSPLIT,$32-8 299 MOVW $1, R2 // CLOCK_MONOTONIC 300 301 MOVD R15, R7 // Backup stack pointer 302 303 MOVD g_m(g), R6 //m 304 305 MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability 306 CMPBEQ R9, $0, fallback 307 308 MOVD m_vdsoPC(R6), R4 309 MOVD R4, 16(R15) 310 MOVD m_vdsoSP(R6), R4 311 MOVD R4, 24(R15) 312 313 MOVD R14, R8 // Backup return address 314 MOVD $ret+0(FP), R4 // caller's SP 315 316 MOVD R8, m_vdsoPC(R6) 317 MOVD R4, m_vdsoSP(R6) 318 319 MOVD m_curg(R6), R5 320 CMP g, R5 321 BNE noswitch 322 323 MOVD m_g0(R6), R4 324 MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack 325 326 noswitch: 327 SUB $16, R15 // reserve 2x 8 bytes for parameters 328 MOVD $~7, R4 // align to 8 bytes because of gcc ABI 329 AND R4, R15 330 MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime 331 332 MOVB runtime·iscgo(SB),R12 333 CMPBNE R12, $0, nosaveg 334 335 MOVD m_gsignal(R6), R12 // g.m.gsignal 336 CMPBEQ R12, $0, nosaveg 337 338 CMPBEQ g, R12, nosaveg 339 MOVD (g_stack+stack_lo)(R12), R12 // g.m.gsignal.stack.lo 340 MOVD g, (R12) 341 342 BL R9 // to vdso lookup 343 344 MOVD $0, (R12) 345 346 JMP finish 347 348 nosaveg: 349 BL R9 // to vdso lookup 350 351 finish: 352 MOVD 0(R15), R3 // sec 353 MOVD 8(R15), R5 // nsec 354 MOVD R7, R15 // Restore SP 355 356 // Restore vdsoPC, vdsoSP 357 // We don't worry about being signaled between the two stores. 358 // If we are not in a signal handler, we'll restore vdsoSP to 0, 359 // and no one will care about vdsoPC. If we are in a signal handler, 360 // we cannot receive another signal. 361 362 MOVD 24(R15), R12 363 MOVD R12, m_vdsoSP(R6) 364 MOVD 16(R15), R12 365 MOVD R12, m_vdsoPC(R6) 366 367 return: 368 // sec is in R3, nsec in R5 369 // return nsec in R3 370 MULLD $1000000000, R3 371 ADD R5, R3 372 MOVD R3, ret+0(FP) 373 RET 374 375 // Syscall fallback 376 fallback: 377 MOVD $tp-16(SP), R3 378 MOVD $SYS_clock_gettime, R1 379 SYSCALL 380 LMG tp-16(SP), R2, R3 381 MOVD R3, R5 382 MOVD R2, R3 383 JMP return 384 385 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 386 MOVW how+0(FP), R2 387 MOVD new+8(FP), R3 388 MOVD old+16(FP), R4 389 MOVW size+24(FP), R5 390 MOVW $SYS_rt_sigprocmask, R1 391 SYSCALL 392 MOVD $-4095, R3 393 CMPUBLT R2, R3, 2(PC) 394 MOVD R0, 0(R0) // crash 395 RET 396 397 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36 398 MOVD sig+0(FP), R2 399 MOVD new+8(FP), R3 400 MOVD old+16(FP), R4 401 MOVD size+24(FP), R5 402 MOVW $SYS_rt_sigaction, R1 403 SYSCALL 404 MOVW R2, ret+32(FP) 405 RET 406 407 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 408 MOVW sig+8(FP), R2 409 MOVD info+16(FP), R3 410 MOVD ctx+24(FP), R4 411 MOVD fn+0(FP), R5 412 BL R5 413 RET 414 415 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$64 416 // initialize essential registers (just in case) 417 XOR R0, R0 418 419 // this might be called in external code context, 420 // where g is not set. 421 MOVB runtime·iscgo(SB), R6 422 CMPBEQ R6, $0, 2(PC) 423 BL runtime·load_g(SB) 424 425 MOVW R2, 8(R15) 426 MOVD R3, 16(R15) 427 MOVD R4, 24(R15) 428 MOVD $runtime·sigtrampgo(SB), R5 429 BL R5 430 RET 431 432 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 433 BR runtime·sigtramp(SB) 434 435 // func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer 436 TEXT runtime·mmap(SB),NOSPLIT,$48-48 437 MOVD addr+0(FP), R2 438 MOVD n+8(FP), R3 439 MOVW prot+16(FP), R4 440 MOVW flags+20(FP), R5 441 MOVW fd+24(FP), R6 442 MOVWZ off+28(FP), R7 443 444 // s390x uses old_mmap, so the arguments need to be placed into 445 // a struct and a pointer to the struct passed to mmap. 446 MOVD R2, addr-48(SP) 447 MOVD R3, n-40(SP) 448 MOVD R4, prot-32(SP) 449 MOVD R5, flags-24(SP) 450 MOVD R6, fd-16(SP) 451 MOVD R7, off-8(SP) 452 453 MOVD $addr-48(SP), R2 454 MOVW $SYS_mmap, R1 455 SYSCALL 456 MOVD $-4095, R3 457 CMPUBLT R2, R3, ok 458 NEG R2 459 MOVD $0, p+32(FP) 460 MOVD R2, err+40(FP) 461 RET 462 ok: 463 MOVD R2, p+32(FP) 464 MOVD $0, err+40(FP) 465 RET 466 467 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 468 MOVD addr+0(FP), R2 469 MOVD n+8(FP), R3 470 MOVW $SYS_munmap, R1 471 SYSCALL 472 MOVD $-4095, R3 473 CMPUBLT R2, R3, 2(PC) 474 MOVD R0, 0(R0) // crash 475 RET 476 477 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 478 MOVD addr+0(FP), R2 479 MOVD n+8(FP), R3 480 MOVW flags+16(FP), R4 481 MOVW $SYS_madvise, R1 482 SYSCALL 483 MOVW R2, ret+24(FP) 484 RET 485 486 // int64 futex(int32 *uaddr, int32 op, int32 val, 487 // struct timespec *timeout, int32 *uaddr2, int32 val2); 488 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0 489 MOVD addr+0(FP), R2 490 MOVW op+8(FP), R3 491 MOVW val+12(FP), R4 492 MOVD ts+16(FP), R5 493 MOVD addr2+24(FP), R6 494 MOVW val3+32(FP), R7 495 MOVW $SYS_futex, R1 496 SYSCALL 497 MOVW R2, ret+40(FP) 498 RET 499 500 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 501 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 502 MOVW flags+0(FP), R3 503 MOVD stk+8(FP), R2 504 505 // Copy mp, gp, fn off parent stack for use by child. 506 // Careful: Linux system call clobbers ???. 507 MOVD mp+16(FP), R7 508 MOVD gp+24(FP), R8 509 MOVD fn+32(FP), R9 510 511 MOVD R7, -8(R2) 512 MOVD R8, -16(R2) 513 MOVD R9, -24(R2) 514 MOVD $1234, R7 515 MOVD R7, -32(R2) 516 517 SYSCALL $SYS_clone 518 519 // In parent, return. 520 CMPBEQ R2, $0, 3(PC) 521 MOVW R2, ret+40(FP) 522 RET 523 524 // In child, on new stack. 525 // initialize essential registers 526 XOR R0, R0 527 MOVD -32(R15), R7 528 CMP R7, $1234 529 BEQ 2(PC) 530 MOVD R0, 0(R0) 531 532 // Initialize m->procid to Linux tid 533 SYSCALL $SYS_gettid 534 535 MOVD -24(R15), R9 // fn 536 MOVD -16(R15), R8 // g 537 MOVD -8(R15), R7 // m 538 539 CMPBEQ R7, $0, nog 540 CMP R8, $0 541 BEQ nog 542 543 MOVD R2, m_procid(R7) 544 545 // In child, set up new stack 546 MOVD R7, g_m(R8) 547 MOVD R8, g 548 //CALL runtime·stackcheck(SB) 549 550 nog: 551 // Call fn 552 BL R9 553 554 // It shouldn't return. If it does, exit that thread. 555 MOVW $111, R2 556 MOVW $SYS_exit, R1 557 SYSCALL 558 BR -2(PC) // keep exiting 559 560 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 561 MOVD new+0(FP), R2 562 MOVD old+8(FP), R3 563 MOVW $SYS_sigaltstack, R1 564 SYSCALL 565 MOVD $-4095, R3 566 CMPUBLT R2, R3, 2(PC) 567 MOVD R0, 0(R0) // crash 568 RET 569 570 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 571 MOVW $SYS_sched_yield, R1 572 SYSCALL 573 RET 574 575 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0 576 MOVD pid+0(FP), R2 577 MOVD len+8(FP), R3 578 MOVD buf+16(FP), R4 579 MOVW $SYS_sched_getaffinity, R1 580 SYSCALL 581 MOVW R2, ret+24(FP) 582 RET 583 584 // func sbrk0() uintptr 585 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8 586 // Implemented as brk(NULL). 587 MOVD $0, R2 588 MOVW $SYS_brk, R1 589 SYSCALL 590 MOVD R2, ret+0(FP) 591 RET 592 593 TEXT runtime·access(SB),$0-20 594 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 595 MOVW R0, ret+16(FP) 596 RET 597 598 TEXT runtime·connect(SB),$0-28 599 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 600 MOVW R0, ret+24(FP) 601 RET 602 603 TEXT runtime·socket(SB),$0-20 604 MOVD $0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 605 MOVW R0, ret+16(FP) 606 RET