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