github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/runtime/sys_darwin_arm.s (about) 1 // Copyright 2014 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 ARM, Darwin 6 // System calls are implemented in libSystem, this file contains 7 // trampolines that convert from Go to C calling convention. 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 TEXT notok<>(SB),NOSPLIT,$0 14 MOVW $0, R8 15 MOVW R8, (R8) 16 B 0(PC) 17 18 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 19 MOVW 4(R0), R1 // arg 2 mode 20 MOVW 8(R0), R2 // arg 3 perm 21 MOVW 0(R0), R0 // arg 1 name 22 BL libc_open(SB) 23 RET 24 25 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 26 MOVW 0(R0), R0 // arg 1 fd 27 BL libc_close(SB) 28 RET 29 30 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 31 MOVW 4(R0), R1 // arg 2 buf 32 MOVW 8(R0), R2 // arg 3 count 33 MOVW 0(R0), R0 // arg 1 fd 34 BL libc_write(SB) 35 RET 36 37 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 38 MOVW 4(R0), R1 // arg 2 buf 39 MOVW 8(R0), R2 // arg 3 count 40 MOVW 0(R0), R0 // arg 1 fd 41 BL libc_read(SB) 42 RET 43 44 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 45 MOVW 0(R0), R0 // arg 0 code 46 BL libc_exit(SB) 47 MOVW $1234, R0 48 MOVW $1002, R1 49 MOVW R0, (R1) // fail hard 50 51 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 52 MOVW 0(R0), R8 // signal 53 BL libc_getpid(SB) 54 // arg 1 pid already in R0 from getpid 55 MOVW R8, R1 // arg 2 signal 56 BL libc_kill(SB) 57 RET 58 59 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 60 MOVW R0, R8 61 MOVW 0(R8), R0 // arg 1 addr 62 MOVW 4(R8), R1 // arg 2 len 63 MOVW 8(R8), R2 // arg 3 prot 64 MOVW 12(R8), R3 // arg 4 flags 65 MOVW 16(R8), R4 // arg 5 fid 66 MOVW 20(R8), R5 // arg 6 offset 67 MOVW $0, R6 // off_t is uint64_t 68 // Only R0-R3 are used for arguments, the rest 69 // go on the stack. 70 MOVM.DB.W [R4-R6], (R13) 71 BL libc_mmap(SB) 72 ADD $12, R13 73 MOVW $0, R1 74 MOVW $-1, R2 75 CMP R0, R2 76 BNE ok 77 BL libc_error(SB) 78 MOVW (R0), R1 79 MOVW $0, R0 80 ok: 81 MOVW R0, 24(R8) // ret 1 addr 82 MOVW R1, 28(R8) // ret 2 err 83 RET 84 85 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 86 MOVW 4(R0), R1 // arg 2 len 87 MOVW 0(R0), R0 // arg 1 addr 88 BL libc_munmap(SB) 89 MOVW $-1, R2 90 CMP R0, R2 91 BL.EQ notok<>(SB) 92 RET 93 94 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0 95 MOVW 4(R0), R1 // arg 2 len 96 MOVW 8(R0), R2 // arg 3 advice 97 MOVW 0(R0), R0 // arg 1 addr 98 BL libc_madvise(SB) 99 MOVW $-1, R2 100 CMP R0, R2 101 BL.EQ notok<>(SB) 102 RET 103 104 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 105 MOVW 4(R0), R1 // arg 2 new 106 MOVW 8(R0), R2 // arg 3 old 107 MOVW 0(R0), R0 // arg 1 which 108 BL libc_setitimer(SB) 109 RET 110 111 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 112 // R0 already has *timeval 113 MOVW $0, R1 // no timezone needed 114 BL libc_gettimeofday(SB) 115 RET 116 117 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 118 119 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0 120 MOVW R0, R8 121 BL libc_mach_absolute_time(SB) 122 MOVW R0, 0(R8) 123 MOVW R1, 4(R8) 124 MOVW timebase<>+machTimebaseInfo_numer(SB), R6 125 MOVW $timebase<>+machTimebaseInfo_denom(SB), R5 126 MOVW (R5), R7 127 DMB MB_ISH // memory barrier for atomic read 128 CMP $0, R7 129 BNE initialized 130 131 SUB $(machTimebaseInfo__size+7)/8*8, R13 132 MOVW R13, R0 133 BL libc_mach_timebase_info(SB) 134 MOVW machTimebaseInfo_numer(R13), R6 135 MOVW machTimebaseInfo_denom(R13), R7 136 ADD $(machTimebaseInfo__size+7)/8*8, R13 137 138 MOVW R6, timebase<>+machTimebaseInfo_numer(SB) 139 MOVW $timebase<>+machTimebaseInfo_denom(SB), R5 140 DMB MB_ISH // memory barrier for atomic write 141 MOVW R7, (R5) 142 DMB MB_ISH 143 144 initialized: 145 MOVW R6, 8(R8) 146 MOVW R7, 12(R8) 147 RET 148 149 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 150 MOVW sig+4(FP), R0 151 MOVW info+8(FP), R1 152 MOVW ctx+12(FP), R2 153 MOVW fn+0(FP), R11 154 MOVW R13, R4 155 SUB $24, R13 156 BIC $0x7, R13 // alignment for ELF ABI 157 BL (R11) 158 MOVW R4, R13 159 RET 160 161 TEXT runtime·sigtramp(SB),NOSPLIT,$0 162 // Reserve space for callee-save registers and arguments. 163 SUB $36, R13 164 165 MOVW R4, 12(R13) 166 MOVW R5, 16(R13) 167 MOVW R6, 20(R13) 168 MOVW R7, 24(R13) 169 MOVW R8, 28(R13) 170 MOVW R11, 32(R13) 171 172 // Save arguments. 173 MOVW R0, 4(R13) // sig 174 MOVW R1, 8(R13) // info 175 MOVW R2, 12(R13) // ctx 176 177 // this might be called in external code context, 178 // where g is not set. 179 MOVB runtime·iscgo(SB), R0 180 CMP $0, R0 181 BL.NE runtime·load_g(SB) 182 183 MOVW R13, R6 184 CMP $0, g 185 BEQ nog 186 187 // iOS always use the main stack to run the signal handler. 188 // We need to switch to gsignal ourselves. 189 MOVW g_m(g), R11 190 MOVW m_gsignal(R11), R5 191 MOVW (g_stack+stack_hi)(R5), R6 192 193 nog: 194 // Restore arguments. 195 MOVW 4(R13), R0 196 MOVW 8(R13), R1 197 MOVW 12(R13), R2 198 199 // Reserve space for args and the stack pointer on the 200 // gsignal stack. 201 SUB $24, R6 202 // Save stack pointer. 203 MOVW R13, R4 204 MOVW R4, 16(R6) 205 // Switch to gsignal stack. 206 MOVW R6, R13 207 208 // Call sigtrampgo 209 MOVW R0, 4(R13) 210 MOVW R1, 8(R13) 211 MOVW R2, 12(R13) 212 BL runtime·sigtrampgo(SB) 213 214 // Switch to old stack. 215 MOVW 16(R13), R5 216 MOVW R5, R13 217 218 // Restore callee-save registers. 219 MOVW 12(R13), R4 220 MOVW 16(R13), R5 221 MOVW 20(R13), R6 222 MOVW 24(R13), R7 223 MOVW 28(R13), R8 224 MOVW 32(R13), R11 225 226 ADD $36, R13 227 228 RET 229 230 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 231 JMP runtime·sigtramp(SB) 232 233 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 234 MOVW 4(R0), R1 // arg 2 new 235 MOVW 8(R0), R2 // arg 3 old 236 MOVW 0(R0), R0 // arg 1 how 237 BL libc_pthread_sigmask(SB) 238 CMP $0, R0 239 BL.NE notok<>(SB) 240 RET 241 242 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 243 MOVW 4(R0), R1 // arg 2 new 244 MOVW 8(R0), R2 // arg 3 old 245 MOVW 0(R0), R0 // arg 1 how 246 BL libc_sigaction(SB) 247 RET 248 249 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 250 MOVW 0(R0), R0 // arg 1 usec 251 BL libc_usleep(SB) 252 RET 253 254 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 255 B runtime·armPublicationBarrier(SB) 256 257 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 258 MOVW 4(R0), R1 // arg 2 miblen 259 MOVW 8(R0), R2 // arg 3 out 260 MOVW 12(R0), R3 // arg 4 size 261 MOVW 16(R0), R4 // arg 5 dst 262 MOVW 20(R0), R5 // arg 6 ndst 263 MOVW 0(R0), R0 // arg 1 mib 264 // Only R0-R3 are used for arguments, the rest 265 // go on the stack. 266 MOVM.DB.W [R4-R5], (R13) 267 BL libc_sysctl(SB) 268 ADD $(2*4), R13 269 RET 270 271 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 272 BL libc_kqueue(SB) 273 RET 274 275 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int events, Timespec *timeout) 276 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 277 MOVW 4(R0), R1 // arg 2 keventss 278 MOVW 8(R0), R2 // arg 3 nch 279 MOVW 12(R0), R3 // arg 4 ev 280 MOVW 16(R0), R4 // arg 5 nev 281 MOVW 20(R0), R5 // arg 6 ts 282 MOVW 0(R0), R0 // arg 1 kq 283 // Only R0-R3 are used for arguments, the rest 284 // go on the stack. 285 MOVM.DB.W [R4-R5], (R13) 286 BL libc_kevent(SB) 287 ADD $(2*4), R13 288 MOVW $-1, R2 289 CMP R0, R2 290 BNE ok 291 BL libc_error(SB) 292 MOVW (R0), R0 // errno 293 RSB $0, R0, R0 // caller wants it as a negative error code 294 ok: 295 RET 296 297 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 298 MOVW 4(R0), R1 // arg 2 cmd 299 MOVW 8(R0), R2 // arg 3 arg 300 MOVW 0(R0), R0 // arg 1 fd 301 BL libc_fcntl(SB) 302 RET 303 304 // sigaltstack is not supported on iOS, so our sigtramp has 305 // to do the stack switch ourselves. 306 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 307 MOVW $43, R0 308 BL libc_exit(SB) 309 RET 310 311 // Thread related functions 312 // Note: On darwin/arm, the runtime always use runtime/cgo to 313 // create threads, so all thread related functions will just exit with a 314 // unique status. 315 316 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 317 MOVW $44, R0 318 BL libc_exit(SB) 319 RET 320 321 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 322 MOVW $45, R0 323 BL libc_exit(SB) 324 RET 325 326 TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 327 MOVW $46, R0 328 BL libc_exit(SB) 329 RET 330 331 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 332 MOVW $47, R0 333 BL libc_exit(SB) 334 RET 335 336 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 337 MOVW $48, R0 338 BL libc_exit(SB) 339 RET 340 341 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 342 MOVW 0(R0), R0 // arg 1 sig 343 BL libc_raise(SB) 344 RET 345 346 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 347 MOVW 4(R0), R1 // arg 2 attr 348 MOVW 0(R0), R0 // arg 1 mutex 349 BL libc_pthread_mutex_init(SB) 350 RET 351 352 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 353 MOVW 0(R0), R0 // arg 1 mutex 354 BL libc_pthread_mutex_lock(SB) 355 RET 356 357 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 358 MOVW 0(R0), R0 // arg 1 mutex 359 BL libc_pthread_mutex_unlock(SB) 360 RET 361 362 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 363 MOVW 4(R0), R1 // arg 2 attr 364 MOVW 0(R0), R0 // arg 1 cond 365 BL libc_pthread_cond_init(SB) 366 RET 367 368 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 369 MOVW 4(R0), R1 // arg 2 mutex 370 MOVW 0(R0), R0 // arg 1 cond 371 BL libc_pthread_cond_wait(SB) 372 RET 373 374 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 375 MOVW 4(R0), R1 // arg 2 mutex 376 MOVW 8(R0), R2 // arg 3 timeout 377 MOVW 0(R0), R0 // arg 1 cond 378 BL libc_pthread_cond_timedwait_relative_np(SB) 379 RET 380 381 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 382 MOVW 0(R0), R0 // arg 1 cond 383 BL libc_pthread_cond_signal(SB) 384 RET 385 386 // syscall calls a function in libc on behalf of the syscall package. 387 // syscall takes a pointer to a struct like: 388 // struct { 389 // fn uintptr 390 // a1 uintptr 391 // a2 uintptr 392 // a3 uintptr 393 // r1 uintptr 394 // r2 uintptr 395 // err uintptr 396 // } 397 // syscall must be called on the g0 stack with the 398 // C calling convention (use libcCall). 399 TEXT runtime·syscall(SB),NOSPLIT,$0 400 MOVW.W R0, -4(R13) // push structure pointer 401 MOVW 0(R0), R12 // fn 402 MOVW 8(R0), R1 // a2 403 MOVW 12(R0), R2 // a3 404 MOVW 4(R0), R0 // a1 405 BL (R12) 406 MOVW.P 4(R13), R2 // pop structure pointer 407 MOVW R0, 16(R2) // save r1 408 MOVW R1, 20(R2) // save r2 409 MOVW $-1, R3 410 CMP R0, R3 411 BNE ok 412 MOVW.W R2, -4(R13) // push structure pointer 413 BL libc_error(SB) 414 MOVW (R0), R0 415 MOVW.P 4(R13), R2 // pop structure pointer 416 MOVW R0, 24(R2) // save err 417 ok: 418 RET 419 420 // syscallPtr is like syscall except the libc function reports an 421 // error by returning NULL. 422 TEXT runtime·syscallPtr(SB),NOSPLIT,$0 423 MOVW.W R0, -4(R13) // push structure pointer 424 MOVW 0(R0), R12 // fn 425 MOVW 8(R0), R1 // a2 426 MOVW 12(R0), R2 // a3 427 MOVW 4(R0), R0 // a1 428 BL (R12) 429 MOVW.P 4(R13), R2 // pop structure pointer 430 MOVW R0, 16(R2) // save r1 431 MOVW R1, 20(R2) // save r2 432 MOVW $0, R3 433 CMP R0, R3 434 BNE ok 435 MOVW.W R2, -4(R13) // push structure pointer 436 BL libc_error(SB) 437 MOVW (R0), R0 438 MOVW.P 4(R13), R2 // pop structure pointer 439 MOVW R0, 24(R2) // save err 440 ok: 441 RET 442 443 // syscall6 calls a function in libc on behalf of the syscall package. 444 // syscall6 takes a pointer to a struct like: 445 // struct { 446 // fn uintptr 447 // a1 uintptr 448 // a2 uintptr 449 // a3 uintptr 450 // a4 uintptr 451 // a5 uintptr 452 // a6 uintptr 453 // r1 uintptr 454 // r2 uintptr 455 // err uintptr 456 // } 457 // syscall6 must be called on the g0 stack with the 458 // C calling convention (use libcCall). 459 TEXT runtime·syscall6(SB),NOSPLIT,$0 460 MOVW.W R0, -4(R13) // push structure pointer 461 MOVW 0(R0), R12 // fn 462 MOVW 24(R0), R1 // a6 463 MOVW.W R1, -4(R13) 464 MOVW 20(R0), R1 // a5 465 MOVW.W R1, -4(R13) 466 MOVW 8(R0), R1 // a2 467 MOVW 12(R0), R2 // a3 468 MOVW 16(R0), R3 // a4 469 MOVW 4(R0), R0 // a1 470 BL (R12) 471 ADD $8, R13 472 MOVW.P 4(R13), R2 // pop structure pointer 473 MOVW R0, 28(R2) // save r1 474 MOVW R1, 32(R2) // save r2 475 MOVW $-1, R3 476 CMP R0, R3 477 BNE ok 478 MOVW.W R2, -4(R13) // push structure pointer 479 BL libc_error(SB) 480 MOVW (R0), R0 481 MOVW.P 4(R13), R2 // pop structure pointer 482 MOVW R0, 36(R2) // save err 483 ok: 484 RET 485 486 // syscall6X calls a function in libc on behalf of the syscall package. 487 // syscall6X takes a pointer to a struct like: 488 // struct { 489 // fn uintptr 490 // a1 uintptr 491 // a2 uintptr 492 // a3 uintptr 493 // a4 uintptr 494 // a5 uintptr 495 // a6 uintptr 496 // r1 uintptr 497 // r2 uintptr 498 // err uintptr 499 // } 500 // syscall6X must be called on the g0 stack with the 501 // C calling convention (use libcCall). 502 TEXT runtime·syscall6X(SB),NOSPLIT,$0 503 MOVW.W R0, -4(R13) // push structure pointer 504 MOVW 0(R0), R12 // fn 505 MOVW 24(R0), R1 // a6 506 MOVW.W R1, -4(R13) 507 MOVW 20(R0), R1 // a5 508 MOVW.W R1, -4(R13) 509 MOVW 8(R0), R1 // a2 510 MOVW 12(R0), R2 // a3 511 MOVW 16(R0), R3 // a4 512 MOVW 4(R0), R0 // a1 513 BL (R12) 514 ADD $8, R13 515 MOVW.P 4(R13), R2 // pop structure pointer 516 MOVW R0, 28(R2) // save r1 517 MOVW R1, 32(R2) // save r2 518 MOVW $-1, R3 519 CMP R0, R3 520 BNE ok 521 CMP R1, R3 522 BNE ok 523 MOVW.W R2, -4(R13) // push structure pointer 524 BL libc_error(SB) 525 MOVW (R0), R0 526 MOVW.P 4(R13), R2 // pop structure pointer 527 MOVW R0, 36(R2) // save err 528 ok: 529 RET 530 531 // syscall9 calls a function in libc on behalf of the syscall package. 532 // syscall9 takes a pointer to a struct like: 533 // struct { 534 // fn uintptr 535 // a1 uintptr 536 // a2 uintptr 537 // a3 uintptr 538 // a4 uintptr 539 // a5 uintptr 540 // a6 uintptr 541 // a7 uintptr 542 // a8 uintptr 543 // a9 uintptr 544 // r1 uintptr 545 // r2 uintptr 546 // err uintptr 547 // } 548 // syscall9 must be called on the g0 stack with the 549 // C calling convention (use libcCall). 550 TEXT runtime·syscall9(SB),NOSPLIT,$0 551 MOVW.W R0, -4(R13) // push structure pointer 552 MOVW 0(R0), R12 // fn 553 MOVW 36(R0), R1 // a9 554 MOVW.W R1, -4(R13) 555 MOVW 32(R0), R1 // a8 556 MOVW.W R1, -4(R13) 557 MOVW 28(R0), R1 // a7 558 MOVW.W R1, -4(R13) 559 MOVW 24(R0), R1 // a6 560 MOVW.W R1, -4(R13) 561 MOVW 20(R0), R1 // a5 562 MOVW.W R1, -4(R13) 563 MOVW 8(R0), R1 // a2 564 MOVW 12(R0), R2 // a3 565 MOVW 16(R0), R3 // a4 566 MOVW 4(R0), R0 // a1 567 BL (R12) 568 ADD $20, R13 569 MOVW.P 4(R13), R2 // pop structure pointer 570 MOVW R0, 40(R2) // save r1 571 MOVW R1, 44(R2) // save r2 572 MOVW $-1, R3 573 CMP R0, R3 574 BNE ok 575 MOVW.W R2, -4(R13) // push structure pointer 576 BL libc_error(SB) 577 MOVW (R0), R0 578 MOVW.P 4(R13), R2 // pop structure pointer 579 MOVW R0, 48(R2) // save err 580 ok: 581 RET