github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/sys_openbsd_riscv64.s (about) 1 // Copyright 2023 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 sys.stuff for riscv64, OpenBSD 6 // System calls are implemented in libc/libpthread, this file 7 // contains trampolines that convert from Go to C calling convention. 8 // 9 10 #include "go_asm.h" 11 #include "go_tls.h" 12 #include "textflag.h" 13 14 #define CLOCK_REALTIME $0 15 #define CLOCK_MONOTONIC $3 16 17 // mstart_stub is the first function executed on a new thread started by pthread_create. 18 // It just does some low-level setup and then calls mstart. 19 // Note: called with the C calling convention. 20 TEXT runtime·mstart_stub(SB),NOSPLIT,$200 21 // X10 points to the m. 22 // We are already on m's g0 stack. 23 24 // Save callee-save registers (X8, X9, X18..X27, F8, F9, F18..F27) 25 MOV X8, (1*8)(X2) 26 MOV X9, (2*8)(X2) 27 MOV X18, (3*8)(X2) 28 MOV X19, (4*8)(X2) 29 MOV X20, (5*8)(X2) 30 MOV X21, (6*8)(X2) 31 MOV X22, (7*8)(X2) 32 MOV X23, (8*8)(X2) 33 MOV X24, (9*8)(X2) 34 MOV X25, (10*8)(X2) 35 MOV X26, (11*8)(X2) 36 MOV g, (12*8)(X2) 37 MOVF F8, (13*8)(X2) 38 MOVF F9, (14*8)(X2) 39 MOVF F18, (15*8)(X2) 40 MOVF F19, (16*8)(X2) 41 MOVF F20, (17*8)(X2) 42 MOVF F21, (18*8)(X2) 43 MOVF F22, (19*8)(X2) 44 MOVF F23, (20*8)(X2) 45 MOVF F24, (21*8)(X2) 46 MOVF F25, (22*8)(X2) 47 MOVF F26, (23*8)(X2) 48 MOVF F27, (24*8)(X2) 49 50 MOV m_g0(X10), g 51 CALL runtime·save_g(SB) 52 53 CALL runtime·mstart(SB) 54 55 // Restore callee-save registers. 56 MOV (1*8)(X2), X8 57 MOV (2*8)(X2), X9 58 MOV (3*8)(X2), X18 59 MOV (4*8)(X2), X19 60 MOV (5*8)(X2), X20 61 MOV (6*8)(X2), X21 62 MOV (7*8)(X2), X22 63 MOV (8*8)(X2), X23 64 MOV (9*8)(X2), X24 65 MOV (10*8)(X2), X25 66 MOV (11*8)(X2), X26 67 MOV (12*8)(X2), g 68 MOVF (13*8)(X2), F8 69 MOVF (14*8)(X2), F9 70 MOVF (15*8)(X2), F18 71 MOVF (16*8)(X2), F19 72 MOVF (17*8)(X2), F20 73 MOVF (18*8)(X2), F21 74 MOVF (19*8)(X2), F22 75 MOVF (20*8)(X2), F23 76 MOVF (21*8)(X2), F24 77 MOVF (22*8)(X2), F25 78 MOVF (23*8)(X2), F26 79 MOVF (24*8)(X2), F27 80 81 // Go is all done with this OS thread. 82 // Tell pthread everything is ok (we never join with this thread, so 83 // the value here doesn't really matter). 84 MOV $0, X10 85 86 RET 87 88 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 89 MOVW sig+8(FP), X10 90 MOV info+16(FP), X11 91 MOV ctx+24(FP), X12 92 MOV fn+0(FP), X5 93 JALR X1, X5 94 RET 95 96 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$224 97 // Save callee-save registers (X8, X9, X18..X27, F8, F9, F18..F27) 98 MOV X8, (4*8)(X2) 99 MOV X9, (5*8)(X2) 100 MOV X18, (6*8)(X2) 101 MOV X19, (7*8)(X2) 102 MOV X20, (8*8)(X2) 103 MOV X21, (9*8)(X2) 104 MOV X22, (10*8)(X2) 105 MOV X23, (11*8)(X2) 106 MOV X24, (12*8)(X2) 107 MOV X25, (13*8)(X2) 108 MOV X26, (14*8)(X2) 109 MOV g, (15*8)(X2) 110 MOVF F8, (16*8)(X2) 111 MOVF F9, (17*8)(X2) 112 MOVF F18, (18*8)(X2) 113 MOVF F19, (19*8)(X2) 114 MOVF F20, (20*8)(X2) 115 MOVF F21, (21*8)(X2) 116 MOVF F22, (22*8)(X2) 117 MOVF F23, (23*8)(X2) 118 MOVF F24, (24*8)(X2) 119 MOVF F25, (25*8)(X2) 120 MOVF F26, (26*8)(X2) 121 MOVF F27, (27*8)(X2) 122 123 // this might be called in external code context, 124 // where g is not set. 125 CALL runtime·load_g(SB) 126 127 MOVW X10, 8(X2) 128 MOV X11, 16(X2) 129 MOV X12, 24(X2) 130 MOV $runtime·sigtrampgo(SB), X5 131 JALR X1, X5 132 133 // Restore callee-save registers. 134 MOV (4*8)(X2), X8 135 MOV (5*8)(X2), X9 136 MOV (6*8)(X2), X18 137 MOV (7*8)(X2), X19 138 MOV (8*8)(X2), X20 139 MOV (9*8)(X2), X21 140 MOV (10*8)(X2), X22 141 MOV (11*8)(X2), X23 142 MOV (12*8)(X2), X24 143 MOV (13*8)(X2), X25 144 MOV (14*8)(X2), X26 145 MOV (15*8)(X2), g 146 MOVF (16*8)(X2), F8 147 MOVF (17*8)(X2), F9 148 MOVF (18*8)(X2), F18 149 MOVF (19*8)(X2), F19 150 MOVF (20*8)(X2), F20 151 MOVF (21*8)(X2), F21 152 MOVF (22*8)(X2), F22 153 MOVF (23*8)(X2), F23 154 MOVF (24*8)(X2), F24 155 MOVF (25*8)(X2), F25 156 MOVF (26*8)(X2), F26 157 MOVF (27*8)(X2), F27 158 159 RET 160 161 // 162 // These trampolines help convert from Go calling convention to C calling convention. 163 // They should be called with asmcgocall. 164 // A pointer to the arguments is passed in R0. 165 // A single int32 result is returned in R0. 166 // (For more results, make an args/results structure.) 167 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$8 168 MOV 0(X10), X10 // arg 1 - attr 169 CALL libc_pthread_attr_init(SB) 170 RET 171 172 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$8 173 MOV 0(X10), X10 // arg 1 - attr 174 CALL libc_pthread_attr_destroy(SB) 175 RET 176 177 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$8 178 MOV 8(X10), X11 // arg 2 - size 179 MOV 0(X10), X10 // arg 1 - attr 180 CALL libc_pthread_attr_getstacksize(SB) 181 RET 182 183 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$8 184 MOV 8(X10), X11 // arg 2 - state 185 MOV 0(X10), X10 // arg 1 - attr 186 CALL libc_pthread_attr_setdetachstate(SB) 187 RET 188 189 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$8 190 MOV 0(X10), X11 // arg 2 - attr 191 MOV 8(X10), X12 // arg 3 - start 192 MOV 16(X10), X13 // arg 4 - arg 193 ADD $-16, X2 194 MOV X2, X10 // arg 1 - &threadid (discard) 195 CALL libc_pthread_create(SB) 196 ADD $16, X2 197 RET 198 199 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$8 200 MOV 8(X10), X11 // arg 2 - signal 201 MOV $0, X12 // arg 3 - tcb 202 MOVW 0(X10), X10 // arg 1 - tid 203 CALL libc_thrkill(SB) 204 RET 205 206 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$8 207 MOVW 8(X10), X11 // arg 2 - clock_id 208 MOV 16(X10), X12 // arg 3 - abstime 209 MOV 24(X10), X13 // arg 4 - lock 210 MOV 32(X10), X14 // arg 5 - abort 211 MOV 0(X10), X10 // arg 1 - id 212 CALL libc_thrsleep(SB) 213 RET 214 215 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$8 216 MOVW 8(X10), X11 // arg 2 - count 217 MOV 0(X10), X10 // arg 1 - id 218 CALL libc_thrwakeup(SB) 219 RET 220 221 TEXT runtime·exit_trampoline(SB),NOSPLIT,$8 222 MOVW 0(X10), X10 // arg 1 - status 223 CALL libc_exit(SB) 224 MOV $0, X5 // crash on failure 225 MOV X5, (X5) 226 RET 227 228 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$8 229 MOV X10, X9 // pointer to args 230 CALL libc_getthrid(SB) 231 MOVW X10, 0(X9) // return value 232 RET 233 234 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$8 235 MOV X10, X9 // pointer to args 236 CALL libc_getpid(SB) // arg 1 - pid (result in X10) 237 MOVW 0(X9), X11 // arg 2 - signal 238 CALL libc_kill(SB) 239 RET 240 241 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$8 242 CALL libc_sched_yield(SB) 243 RET 244 245 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$8 246 MOV X10, X9 // pointer to args 247 MOV 0(X9), X10 // arg 1 - addr 248 MOV 8(X9), X11 // arg 2 - len 249 MOVW 16(X9), X12 // arg 3 - prot 250 MOVW 20(X9), X13 // arg 4 - flags 251 MOVW 24(X9), X14 // arg 5 - fid 252 MOVW 28(X9), X15 // arg 6 - offset 253 CALL libc_mmap(SB) 254 MOV $0, X5 255 MOV $-1, X6 256 BNE X6, X10, noerr 257 CALL libc_errno(SB) 258 MOVW (X10), X5 // errno 259 MOV $0, X10 260 noerr: 261 MOV X10, 32(X9) 262 MOV X5, 40(X9) 263 RET 264 265 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$8 266 MOV 8(X10), X11 // arg 2 - len 267 MOV 0(X10), X10 // arg 1 - addr 268 CALL libc_munmap(SB) 269 MOV $-1, X5 270 BNE X5, X10, 3(PC) 271 MOV $0, X5 // crash on failure 272 MOV X5, (X5) 273 RET 274 275 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$8 276 MOV 8(X10), X11 // arg 2 - len 277 MOVW 16(X10), X12 // arg 3 - advice 278 MOV 0(X10), X10 // arg 1 - addr 279 CALL libc_madvise(SB) 280 // ignore failure - maybe pages are locked 281 RET 282 283 TEXT runtime·open_trampoline(SB),NOSPLIT,$8 284 MOVW 8(X10), X11 // arg 2 - flags 285 MOVW 12(X10), X12 // arg 3 - mode 286 MOV 0(X10), X10 // arg 1 - path 287 MOV $0, X13 // varargs 288 CALL libc_open(SB) 289 RET 290 291 TEXT runtime·close_trampoline(SB),NOSPLIT,$8 292 MOVW 0(X10), X10 // arg 1 - fd 293 CALL libc_close(SB) 294 RET 295 296 TEXT runtime·read_trampoline(SB),NOSPLIT,$8 297 MOV 8(X10), X11 // arg 2 - buf 298 MOVW 16(X10), X12 // arg 3 - count 299 MOVW 0(X10), X10 // arg 1 - fd (int32 from read) 300 CALL libc_read(SB) 301 MOV $-1, X5 302 BNE X5, X10, noerr 303 CALL libc_errno(SB) 304 MOVW (X10), X10 // errno 305 NEG X10 // caller expects negative errno 306 noerr: 307 RET 308 309 TEXT runtime·write_trampoline(SB),NOSPLIT,$8 310 MOV 8(X10), X11 // arg 2 - buf 311 MOVW 16(X10), X12 // arg 3 - count 312 MOV 0(X10), X10 // arg 1 - fd (uintptr from write1) 313 CALL libc_write(SB) 314 MOV $-1, X5 315 BNE X5, X10, noerr 316 CALL libc_errno(SB) 317 MOVW (X10), X10 // errno 318 NEG X10 // caller expects negative errno 319 noerr: 320 RET 321 322 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$8 323 MOVW 8(X10), X11 // arg 2 - flags 324 MOV 0(X10), X10 // arg 1 - filedes 325 CALL libc_pipe2(SB) 326 MOV $-1, X5 327 BNE X5, X10, noerr 328 CALL libc_errno(SB) 329 MOVW (X10), X10 // errno 330 NEG X10 // caller expects negative errno 331 noerr: 332 RET 333 334 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$8 335 MOV 8(X10), X11 // arg 2 - new 336 MOV 16(X10), X12 // arg 3 - old 337 MOVW 0(X10), X10 // arg 1 - which 338 CALL libc_setitimer(SB) 339 RET 340 341 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$8 342 MOVW 0(X10), X10 // arg 1 - usec 343 CALL libc_usleep(SB) 344 RET 345 346 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$8 347 MOVW 8(X10), X11 // arg 2 - miblen 348 MOV 16(X10), X12 // arg 3 - out 349 MOV 24(X10), X13 // arg 4 - size 350 MOV 32(X10), X14 // arg 5 - dst 351 MOV 40(X10), X15 // arg 6 - ndst 352 MOV 0(X10), X10 // arg 1 - mib 353 CALL libc_sysctl(SB) 354 RET 355 356 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$8 357 CALL libc_kqueue(SB) 358 RET 359 360 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$8 361 MOV 8(X10), X11 // arg 2 - keventt 362 MOVW 16(X10), X12 // arg 3 - nch 363 MOV 24(X10), X13 // arg 4 - ev 364 MOVW 32(X10), X14 // arg 5 - nev 365 MOV 40(X10), X15 // arg 6 - ts 366 MOVW 0(X10), X10 // arg 1 - kq 367 CALL libc_kevent(SB) 368 MOV $-1, X5 369 BNE X5, X10, noerr 370 CALL libc_errno(SB) 371 MOVW (X10), X10 // errno 372 NEG X10 // caller expects negative errno 373 noerr: 374 RET 375 376 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$8 377 MOV 8(X10), X11 // arg 2 - tp 378 MOVW 0(X10), X10 // arg 1 - clock_id 379 CALL libc_clock_gettime(SB) 380 MOV $-1, X5 381 BNE X5, X10, 3(PC) 382 MOV $0, X5 // crash on failure 383 MOV X5, (X5) 384 RET 385 386 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$8 387 MOV X10, X9 // pointer to args 388 MOVW 0(X9), X10 // arg 1 - fd 389 MOVW 4(X9), X11 // arg 2 - cmd 390 MOVW 8(X9), X12 // arg 3 - arg 391 MOV $0, X13 // vararg 392 CALL libc_fcntl(SB) 393 MOV $-1, X5 394 MOV $0, X11 395 BNE X5, X10, noerr 396 CALL libc_errno(SB) 397 MOVW (X10), X11 // errno 398 MOV $-1, X10 399 noerr: 400 MOVW X10, 12(X9) 401 MOVW X11, 16(X9) 402 RET 403 404 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$8 405 MOV 8(X10), X11 // arg 2 - new 406 MOV 16(X10), X12 // arg 3 - old 407 MOVW 0(X10), X10 // arg 1 - sig 408 CALL libc_sigaction(SB) 409 MOV $-1, X5 410 BNE X5, X10, 3(PC) 411 MOV $0, X5 // crash on failure 412 MOV X5, (X5) 413 RET 414 415 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$8 416 MOV 8(X10), X11 // arg 2 - new 417 MOV 16(X10), X12 // arg 3 - old 418 MOVW 0(X10), X10 // arg 1 - how 419 CALL libc_pthread_sigmask(SB) 420 MOV $-1, X5 421 BNE X5, X10, 3(PC) 422 MOV $0, X5 // crash on failure 423 MOV X5, (X5) 424 RET 425 426 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$8 427 MOV 8(X10), X11 // arg 2 - old 428 MOV 0(X10), X10 // arg 1 - new 429 CALL libc_sigaltstack(SB) 430 MOV $-1, X5 431 BNE X5, X10, 3(PC) 432 MOV $0, X5 // crash on failure 433 MOV X5, (X5) 434 RET 435 436 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0 437 MOV X10, X9 // pointer to args 438 CALL libc_issetugid(SB) 439 MOVW X10, 0(X9) // return value 440 RET 441 442 // syscall calls a function in libc on behalf of the syscall package. 443 // syscall takes a pointer to a struct like: 444 // struct { 445 // fn uintptr 446 // a1 uintptr 447 // a2 uintptr 448 // a3 uintptr 449 // r1 uintptr 450 // r2 uintptr 451 // err uintptr 452 // } 453 // syscall must be called on the g0 stack with the 454 // C calling convention (use libcCall). 455 // 456 // syscall expects a 32-bit result and tests for 32-bit -1 457 // to decide there was an error. 458 TEXT runtime·syscall(SB),NOSPLIT,$8 459 MOV X10, X9 // pointer to args 460 461 MOV (0*8)(X9), X5 // fn 462 MOV (1*8)(X9), X10 // a1 463 MOV (2*8)(X9), X11 // a2 464 MOV (3*8)(X9), X12 // a3 465 MOV $0, X13 // vararg 466 467 JALR X1, X5 468 469 MOV X10, (4*8)(X9) // r1 470 MOV X11, (5*8)(X9) // r2 471 472 // Standard libc functions return -1 on error 473 // and set errno. 474 MOV $-1, X5 475 MOVW X10, X11 476 BNE X5, X11, ok 477 478 // Get error code from libc. 479 CALL libc_errno(SB) 480 MOVW (X10), X10 481 MOV X10, (6*8)(X9) // err 482 483 ok: 484 RET 485 486 // syscallX calls a function in libc on behalf of the syscall package. 487 // syscallX takes a pointer to a struct like: 488 // struct { 489 // fn uintptr 490 // a1 uintptr 491 // a2 uintptr 492 // a3 uintptr 493 // r1 uintptr 494 // r2 uintptr 495 // err uintptr 496 // } 497 // syscallX must be called on the g0 stack with the 498 // C calling convention (use libcCall). 499 // 500 // syscallX is like syscall but expects a 64-bit result 501 // and tests for 64-bit -1 to decide there was an error. 502 TEXT runtime·syscallX(SB),NOSPLIT,$8 503 MOV X10, X9 // pointer to args 504 505 MOV (0*8)(X9), X5 // fn 506 MOV (1*8)(X9), X10 // a1 507 MOV (2*8)(X9), X11 // a2 508 MOV (3*8)(X9), X12 // a3 509 MOV $0, X13 // vararg 510 511 JALR X1, X5 512 513 MOV X10, (4*8)(X9) // r1 514 MOV X11, (5*8)(X9) // r2 515 516 // Standard libc functions return -1 on error 517 // and set errno. 518 MOV $-1, X5 519 BNE X5, X10, ok 520 521 // Get error code from libc. 522 CALL libc_errno(SB) 523 MOVW (X10), X10 524 MOV X10, (6*8)(X9) // err 525 526 ok: 527 RET 528 529 // syscall6 calls a function in libc on behalf of the syscall package. 530 // syscall6 takes a pointer to a struct like: 531 // struct { 532 // fn uintptr 533 // a1 uintptr 534 // a2 uintptr 535 // a3 uintptr 536 // a4 uintptr 537 // a5 uintptr 538 // a6 uintptr 539 // r1 uintptr 540 // r2 uintptr 541 // err uintptr 542 // } 543 // syscall6 must be called on the g0 stack with the 544 // C calling convention (use libcCall). 545 // 546 // syscall6 expects a 32-bit result and tests for 32-bit -1 547 // to decide there was an error. 548 TEXT runtime·syscall6(SB),NOSPLIT,$8 549 MOV X10, X9 // pointer to args 550 551 MOV (0*8)(X9), X5 // fn 552 MOV (1*8)(X9), X10 // a1 553 MOV (2*8)(X9), X11 // a2 554 MOV (3*8)(X9), X12 // a3 555 MOV (4*8)(X9), X13 // a4 556 MOV (5*8)(X9), X14 // a5 557 MOV (6*8)(X9), X15 // a6 558 MOV $0, X16 // vararg 559 560 JALR X1, X5 561 562 MOV X10, (7*8)(X9) // r1 563 MOV X11, (8*8)(X9) // r2 564 565 // Standard libc functions return -1 on error 566 // and set errno. 567 MOV $-1, X5 568 MOVW X10, X11 569 BNE X5, X11, ok 570 571 // Get error code from libc. 572 CALL libc_errno(SB) 573 MOVW (X10), X10 574 MOV X10, (9*8)(X9) // err 575 576 ok: 577 RET 578 579 // syscall6X calls a function in libc on behalf of the syscall package. 580 // syscall6X takes a pointer to a struct like: 581 // struct { 582 // fn uintptr 583 // a1 uintptr 584 // a2 uintptr 585 // a3 uintptr 586 // a4 uintptr 587 // a5 uintptr 588 // a6 uintptr 589 // r1 uintptr 590 // r2 uintptr 591 // err uintptr 592 // } 593 // syscall6X must be called on the g0 stack with the 594 // C calling convention (use libcCall). 595 // 596 // syscall6X is like syscall6 but expects a 64-bit result 597 // and tests for 64-bit -1 to decide there was an error. 598 TEXT runtime·syscall6X(SB),NOSPLIT,$8 599 MOV X10, X9 // pointer to args 600 601 MOV (0*8)(X9), X5 // fn 602 MOV (1*8)(X9), X10 // a1 603 MOV (2*8)(X9), X11 // a2 604 MOV (3*8)(X9), X12 // a3 605 MOV (4*8)(X9), X13 // a4 606 MOV (5*8)(X9), X14 // a5 607 MOV (6*8)(X9), X15 // a6 608 MOV $0, X16 // vararg 609 610 JALR X1, X5 611 612 MOV X10, (7*8)(X9) // r1 613 MOV X11, (8*8)(X9) // r2 614 615 // Standard libc functions return -1 on error 616 // and set errno. 617 MOV $-1, X5 618 BNE X5, X10, ok 619 620 // Get error code from libc. 621 CALL libc_errno(SB) 622 MOVW (X10), X10 623 MOV X10, (9*8)(X9) // err 624 625 ok: 626 RET 627 628 // syscall10 calls a function in libc on behalf of the syscall package. 629 // syscall10 takes a pointer to a struct like: 630 // struct { 631 // fn uintptr 632 // a1 uintptr 633 // a2 uintptr 634 // a3 uintptr 635 // a4 uintptr 636 // a5 uintptr 637 // a6 uintptr 638 // a7 uintptr 639 // a8 uintptr 640 // a9 uintptr 641 // a10 uintptr 642 // r1 uintptr 643 // r2 uintptr 644 // err uintptr 645 // } 646 // syscall10 must be called on the g0 stack with the 647 // C calling convention (use libcCall). 648 // 649 // The openbsd/riscv64 kernel only accepts eight syscall arguments. 650 TEXT runtime·syscall10(SB),NOSPLIT,$0 651 MOV X10, X9 // pointer to args 652 653 ADD $-16, X2 654 655 MOV (0*8)(X9), X5 // fn 656 MOV (1*8)(X9), X10 // a1 657 MOV (2*8)(X9), X11 // a2 658 MOV (3*8)(X9), X12 // a3 659 MOV (4*8)(X9), X13 // a4 660 MOV (5*8)(X9), X14 // a5 661 MOV (6*8)(X9), X15 // a6 662 MOV (7*8)(X9), X16 // a7 663 MOV (8*8)(X9), X17 // a8 664 665 JALR X1, X5 666 667 MOV X10, (11*8)(X9) // r1 668 MOV X11, (12*8)(X9) // r2 669 670 // Standard libc functions return -1 on error 671 // and set errno. 672 MOV $-1, X5 673 MOVW X10, X11 674 BNE X5, X11, ok 675 676 // Get error code from libc. 677 CALL libc_errno(SB) 678 MOVW (X10), X10 679 MOV X10, (13*8)(X9) // err 680 681 ok: 682 ADD $16, X2 683 RET 684 685 // syscall10X calls a function in libc on behalf of the syscall package. 686 // syscall10X takes a pointer to a struct like: 687 // struct { 688 // fn uintptr 689 // a1 uintptr 690 // a2 uintptr 691 // a3 uintptr 692 // a4 uintptr 693 // a5 uintptr 694 // a6 uintptr 695 // a7 uintptr 696 // a8 uintptr 697 // a9 uintptr 698 // a10 uintptr 699 // r1 uintptr 700 // r2 uintptr 701 // err uintptr 702 // } 703 // syscall10X must be called on the g0 stack with the 704 // C calling convention (use libcCall). 705 // 706 // syscall10X is like syscall10 but expects a 64-bit result 707 // and tests for 64-bit -1 to decide there was an error. 708 // 709 // The openbsd/riscv64 kernel only accepts eight syscall arguments. 710 TEXT runtime·syscall10X(SB),NOSPLIT,$0 711 MOV X10, X9 // pointer to args 712 713 ADD $-16, X2 714 715 MOV (0*8)(X9), X5 // fn 716 MOV (1*8)(X9), X10 // a1 717 MOV (2*8)(X9), X11 // a2 718 MOV (3*8)(X9), X12 // a3 719 MOV (4*8)(X9), X13 // a4 720 MOV (5*8)(X9), X14 // a5 721 MOV (6*8)(X9), X15 // a6 722 MOV (7*8)(X9), X16 // a7 723 MOV (8*8)(X9), X17 // a8 724 725 JALR X1, X5 726 727 MOV X10, (11*8)(X9) // r1 728 MOV X11, (12*8)(X9) // r2 729 730 // Standard libc functions return -1 on error 731 // and set errno. 732 MOV $-1, X5 733 BNE X5, X10, ok 734 735 // Get error code from libc. 736 CALL libc_errno(SB) 737 MOVW (X10), X10 738 MOV X10, (13*8)(X9) // err 739 740 ok: 741 ADD $16, X2 742 RET