github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/sys_darwin_amd64.s (about) 1 // Copyright 2009 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 AMD64, Darwin 7 // See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228 8 // or /usr/include/sys/syscall.h (on a Mac) for system call numbers. 9 // 10 // The low 24 bits are the system call number. 11 // The high 8 bits specify the kind of system call: 1=Mach, 2=BSD, 3=Machine-Dependent. 12 // 13 14 #include "zasm_GOOS_GOARCH.h" 15 #include "../../cmd/ld/textflag.h" 16 17 // Exit the entire program (like C exit) 18 TEXT runtime·exit(SB),NOSPLIT,$0 19 MOVL 8(SP), DI // arg 1 exit status 20 MOVL $(0x2000000+1), AX // syscall entry 21 SYSCALL 22 MOVL $0xf1, 0xf1 // crash 23 RET 24 25 // Exit this OS thread (like pthread_exit, which eventually 26 // calls __bsdthread_terminate). 27 TEXT runtime·exit1(SB),NOSPLIT,$0 28 MOVL 8(SP), DI // arg 1 exit status 29 MOVL $(0x2000000+361), AX // syscall entry 30 SYSCALL 31 MOVL $0xf1, 0xf1 // crash 32 RET 33 34 TEXT runtime·open(SB),NOSPLIT,$0 35 MOVQ 8(SP), DI // arg 1 pathname 36 MOVL 16(SP), SI // arg 2 flags 37 MOVL 20(SP), DX // arg 3 mode 38 MOVL $(0x2000000+5), AX // syscall entry 39 SYSCALL 40 RET 41 42 TEXT runtime·close(SB),NOSPLIT,$0 43 MOVL 8(SP), DI // arg 1 fd 44 MOVL $(0x2000000+6), AX // syscall entry 45 SYSCALL 46 RET 47 48 TEXT runtime·read(SB),NOSPLIT,$0 49 MOVL 8(SP), DI // arg 1 fd 50 MOVQ 16(SP), SI // arg 2 buf 51 MOVL 24(SP), DX // arg 3 count 52 MOVL $(0x2000000+3), AX // syscall entry 53 SYSCALL 54 RET 55 56 TEXT runtime·write(SB),NOSPLIT,$0 57 MOVL 8(SP), DI // arg 1 fd 58 MOVQ 16(SP), SI // arg 2 buf 59 MOVL 24(SP), DX // arg 3 count 60 MOVL $(0x2000000+4), AX // syscall entry 61 SYSCALL 62 RET 63 64 TEXT runtime·raise(SB),NOSPLIT,$24 65 MOVL $(0x2000000+20), AX // getpid 66 SYSCALL 67 MOVQ AX, DI // arg 1 - pid 68 MOVL sig+0(FP), SI // arg 2 - signal 69 MOVL $1, DX // arg 3 - posix 70 MOVL $(0x2000000+37), AX // kill 71 SYSCALL 72 RET 73 74 TEXT runtime·setitimer(SB), NOSPLIT, $0 75 MOVL 8(SP), DI 76 MOVQ 16(SP), SI 77 MOVQ 24(SP), DX 78 MOVL $(0x2000000+83), AX // syscall entry 79 SYSCALL 80 RET 81 82 TEXT runtime·madvise(SB), NOSPLIT, $0 83 MOVQ 8(SP), DI // arg 1 addr 84 MOVQ 16(SP), SI // arg 2 len 85 MOVL 24(SP), DX // arg 3 advice 86 MOVL $(0x2000000+75), AX // syscall entry madvise 87 SYSCALL 88 // ignore failure - maybe pages are locked 89 RET 90 91 // OS X comm page time offsets 92 // http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h 93 #define nt_tsc_base 0x50 94 #define nt_scale 0x58 95 #define nt_shift 0x5c 96 #define nt_ns_base 0x60 97 #define nt_generation 0x68 98 #define gtod_generation 0x6c 99 #define gtod_ns_base 0x70 100 #define gtod_sec_base 0x78 101 102 // int64 nanotime(void) 103 TEXT runtime·nanotime(SB), NOSPLIT, $32 104 MOVQ $0x7fffffe00000, BP /* comm page base */ 105 // Loop trying to take a consistent snapshot 106 // of the time parameters. 107 timeloop: 108 MOVL gtod_generation(BP), R8 109 TESTL R8, R8 110 JZ systime 111 MOVL nt_generation(BP), R9 112 TESTL R9, R9 113 JZ timeloop 114 RDTSC 115 MOVQ nt_tsc_base(BP), R10 116 MOVL nt_scale(BP), R11 117 MOVQ nt_ns_base(BP), R12 118 CMPL nt_generation(BP), R9 119 JNE timeloop 120 MOVQ gtod_ns_base(BP), R13 121 MOVQ gtod_sec_base(BP), R14 122 CMPL gtod_generation(BP), R8 123 JNE timeloop 124 125 // Gathered all the data we need. Compute time. 126 // ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9 127 // The multiply and shift extracts the top 64 bits of the 96-bit product. 128 SHLQ $32, DX 129 ADDQ DX, AX 130 SUBQ R10, AX 131 MULQ R11 132 SHRQ $32, AX:DX 133 ADDQ R12, AX 134 SUBQ R13, AX 135 IMULQ $1000000000, R14 136 ADDQ R14, AX 137 RET 138 139 systime: 140 // Fall back to system call (usually first call in this thread). 141 MOVQ SP, DI // must be non-nil, unused 142 MOVQ $0, SI 143 MOVL $(0x2000000+116), AX 144 SYSCALL 145 // sec is in AX, usec in DX 146 // return nsec in AX 147 IMULQ $1000000000, AX 148 IMULQ $1000, DX 149 ADDQ DX, AX 150 RET 151 152 // func now() (sec int64, nsec int32) 153 TEXT time·now(SB),NOSPLIT,$0 154 CALL runtime·nanotime(SB) 155 156 // generated code for 157 // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 } 158 // adapted to reduce duplication 159 MOVQ AX, CX 160 MOVQ $1360296554856532783, AX 161 MULQ CX 162 ADDQ CX, DX 163 RCRQ $1, DX 164 SHRQ $29, DX 165 MOVQ DX, sec+0(FP) 166 IMULQ $1000000000, DX 167 SUBQ DX, CX 168 MOVL CX, nsec+8(FP) 169 RET 170 171 TEXT runtime·sigprocmask(SB),NOSPLIT,$0 172 MOVL 8(SP), DI 173 MOVQ 16(SP), SI 174 MOVQ 24(SP), DX 175 MOVL $(0x2000000+329), AX // pthread_sigmask (on OS X, sigprocmask==entire process) 176 SYSCALL 177 JCC 2(PC) 178 MOVL $0xf1, 0xf1 // crash 179 RET 180 181 TEXT runtime·sigaction(SB),NOSPLIT,$0 182 MOVL 8(SP), DI // arg 1 sig 183 MOVQ 16(SP), SI // arg 2 act 184 MOVQ 24(SP), DX // arg 3 oact 185 MOVQ 24(SP), CX // arg 3 oact 186 MOVQ 24(SP), R10 // arg 3 oact 187 MOVL $(0x2000000+46), AX // syscall entry 188 SYSCALL 189 JCC 2(PC) 190 MOVL $0xf1, 0xf1 // crash 191 RET 192 193 TEXT runtime·sigtramp(SB),NOSPLIT,$64 194 get_tls(BX) 195 196 MOVQ R8, 32(SP) // save ucontext 197 MOVQ SI, 40(SP) // save infostyle 198 199 // check that m exists 200 MOVQ m(BX), BP 201 CMPQ BP, $0 202 JNE 5(PC) 203 MOVL DX, 0(SP) 204 MOVQ $runtime·badsignal(SB), AX 205 CALL AX 206 JMP sigtramp_ret 207 208 // save g 209 MOVQ g(BX), R10 210 MOVQ R10, 48(SP) 211 212 // g = m->gsignal 213 MOVQ m_gsignal(BP), BP 214 MOVQ BP, g(BX) 215 216 MOVL DX, 0(SP) 217 MOVQ CX, 8(SP) 218 MOVQ R8, 16(SP) 219 MOVQ R10, 24(SP) 220 221 CALL DI 222 223 // restore g 224 get_tls(BX) 225 MOVQ 48(SP), R10 226 MOVQ R10, g(BX) 227 228 sigtramp_ret: 229 // call sigreturn 230 MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle) 231 MOVQ 32(SP), DI // saved ucontext 232 MOVQ 40(SP), SI // saved infostyle 233 SYSCALL 234 INT $3 // not reached 235 236 TEXT runtime·mmap(SB),NOSPLIT,$0 237 MOVQ 8(SP), DI // arg 1 addr 238 MOVQ 16(SP), SI // arg 2 len 239 MOVL 24(SP), DX // arg 3 prot 240 MOVL 28(SP), R10 // arg 4 flags 241 MOVL 32(SP), R8 // arg 5 fid 242 MOVL 36(SP), R9 // arg 6 offset 243 MOVL $(0x2000000+197), AX // syscall entry 244 SYSCALL 245 RET 246 247 TEXT runtime·munmap(SB),NOSPLIT,$0 248 MOVQ 8(SP), DI // arg 1 addr 249 MOVQ 16(SP), SI // arg 2 len 250 MOVL $(0x2000000+73), AX // syscall entry 251 SYSCALL 252 JCC 2(PC) 253 MOVL $0xf1, 0xf1 // crash 254 RET 255 256 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 257 MOVQ new+8(SP), DI 258 MOVQ old+16(SP), SI 259 MOVQ $(0x2000000+53), AX 260 SYSCALL 261 JCC 2(PC) 262 MOVL $0xf1, 0xf1 // crash 263 RET 264 265 TEXT runtime·usleep(SB),NOSPLIT,$16 266 MOVL $0, DX 267 MOVL usec+0(FP), AX 268 MOVL $1000000, CX 269 DIVL CX 270 MOVQ AX, 0(SP) // sec 271 MOVL DX, 8(SP) // usec 272 273 // select(0, 0, 0, 0, &tv) 274 MOVL $0, DI 275 MOVL $0, SI 276 MOVL $0, DX 277 MOVL $0, R10 278 MOVQ SP, R8 279 MOVL $(0x2000000+93), AX 280 SYSCALL 281 RET 282 283 // void bsdthread_create(void *stk, M *mp, G *gp, void (*fn)(void)) 284 TEXT runtime·bsdthread_create(SB),NOSPLIT,$0 285 // Set up arguments to bsdthread_create system call. 286 // The ones in quotes pass through to the thread callback 287 // uninterpreted, so we can put whatever we want there. 288 MOVQ fn+32(SP), DI // "func" 289 MOVQ mm+16(SP), SI // "arg" 290 MOVQ stk+8(SP), DX // stack 291 MOVQ gg+24(SP), R10 // "pthread" 292 MOVQ $0x01000000, R8 // flags = PTHREAD_START_CUSTOM 293 MOVQ $0, R9 // paranoia 294 MOVQ $(0x2000000+360), AX // bsdthread_create 295 SYSCALL 296 JCC 3(PC) 297 NEGQ AX 298 RET 299 MOVL $0, AX 300 RET 301 302 // The thread that bsdthread_create creates starts executing here, 303 // because we registered this function using bsdthread_register 304 // at startup. 305 // DI = "pthread" 306 // SI = mach thread port 307 // DX = "func" (= fn) 308 // CX = "arg" (= m) 309 // R8 = stack 310 // R9 = flags (= 0) 311 // SP = stack - C_64_REDZONE_LEN (= stack - 128) 312 TEXT runtime·bsdthread_start(SB),NOSPLIT,$0 313 MOVQ R8, SP // empirically, SP is very wrong but R8 is right 314 315 PUSHQ DX 316 PUSHQ CX 317 PUSHQ SI 318 319 // set up thread local storage pointing at m->tls. 320 LEAQ m_tls(CX), DI 321 CALL runtime·settls(SB) 322 323 POPQ SI 324 POPQ CX 325 POPQ DX 326 327 get_tls(BX) 328 MOVQ CX, m(BX) 329 MOVQ SI, m_procid(CX) // thread port is m->procid 330 MOVQ m_g0(CX), AX 331 MOVQ AX, g(BX) 332 CALL runtime·stackcheck(SB) // smashes AX, CX 333 CALL DX // fn 334 CALL runtime·exit1(SB) 335 RET 336 337 // void bsdthread_register(void) 338 // registers callbacks for threadstart (see bsdthread_create above 339 // and wqthread and pthsize (not used). returns 0 on success. 340 TEXT runtime·bsdthread_register(SB),NOSPLIT,$0 341 MOVQ $runtime·bsdthread_start(SB), DI // threadstart 342 MOVQ $0, SI // wqthread, not used by us 343 MOVQ $0, DX // pthsize, not used by us 344 MOVQ $0, R10 // dummy_value [sic] 345 MOVQ $0, R8 // targetconc_ptr 346 MOVQ $0, R9 // dispatchqueue_offset 347 MOVQ $(0x2000000+366), AX // bsdthread_register 348 SYSCALL 349 JCC 3(PC) 350 NEGQ AX 351 RET 352 MOVL $0, AX 353 RET 354 355 // Mach system calls use 0x1000000 instead of the BSD's 0x2000000. 356 357 // uint32 mach_msg_trap(void*, uint32, uint32, uint32, uint32, uint32, uint32) 358 TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0 359 MOVQ 8(SP), DI 360 MOVL 16(SP), SI 361 MOVL 20(SP), DX 362 MOVL 24(SP), R10 363 MOVL 28(SP), R8 364 MOVL 32(SP), R9 365 MOVL 36(SP), R11 366 PUSHQ R11 // seventh arg, on stack 367 MOVL $(0x1000000+31), AX // mach_msg_trap 368 SYSCALL 369 POPQ R11 370 RET 371 372 TEXT runtime·mach_task_self(SB),NOSPLIT,$0 373 MOVL $(0x1000000+28), AX // task_self_trap 374 SYSCALL 375 RET 376 377 TEXT runtime·mach_thread_self(SB),NOSPLIT,$0 378 MOVL $(0x1000000+27), AX // thread_self_trap 379 SYSCALL 380 RET 381 382 TEXT runtime·mach_reply_port(SB),NOSPLIT,$0 383 MOVL $(0x1000000+26), AX // mach_reply_port 384 SYSCALL 385 RET 386 387 // Mach provides trap versions of the semaphore ops, 388 // instead of requiring the use of RPC. 389 390 // uint32 mach_semaphore_wait(uint32) 391 TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0 392 MOVL 8(SP), DI 393 MOVL $(0x1000000+36), AX // semaphore_wait_trap 394 SYSCALL 395 RET 396 397 // uint32 mach_semaphore_timedwait(uint32, uint32, uint32) 398 TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0 399 MOVL 8(SP), DI 400 MOVL 12(SP), SI 401 MOVL 16(SP), DX 402 MOVL $(0x1000000+38), AX // semaphore_timedwait_trap 403 SYSCALL 404 RET 405 406 // uint32 mach_semaphore_signal(uint32) 407 TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0 408 MOVL 8(SP), DI 409 MOVL $(0x1000000+33), AX // semaphore_signal_trap 410 SYSCALL 411 RET 412 413 // uint32 mach_semaphore_signal_all(uint32) 414 TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0 415 MOVL 8(SP), DI 416 MOVL $(0x1000000+34), AX // semaphore_signal_all_trap 417 SYSCALL 418 RET 419 420 // set tls base to DI 421 TEXT runtime·settls(SB),NOSPLIT,$32 422 /* 423 * Same as in sys_darwin_386.s:/ugliness, different constant. 424 * See cgo/gcc_darwin_amd64.c for the derivation 425 * of the constant. 426 */ 427 SUBQ $0x8a0, DI 428 429 MOVL $(0x3000000+3), AX // thread_fast_set_cthread_self - machdep call #3 430 SYSCALL 431 RET 432 433 TEXT runtime·sysctl(SB),NOSPLIT,$0 434 MOVQ 8(SP), DI 435 MOVL 16(SP), SI 436 MOVQ 24(SP), DX 437 MOVQ 32(SP), R10 438 MOVQ 40(SP), R8 439 MOVQ 48(SP), R9 440 MOVL $(0x2000000+202), AX // syscall entry 441 SYSCALL 442 JCC 3(PC) 443 NEGQ AX 444 RET 445 MOVL $0, AX 446 RET 447 448 // int32 runtime·kqueue(void); 449 TEXT runtime·kqueue(SB),NOSPLIT,$0 450 MOVQ $0, DI 451 MOVQ $0, SI 452 MOVQ $0, DX 453 MOVL $(0x2000000+362), AX 454 SYSCALL 455 JCC 2(PC) 456 NEGQ AX 457 RET 458 459 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 460 TEXT runtime·kevent(SB),NOSPLIT,$0 461 MOVL 8(SP), DI 462 MOVQ 16(SP), SI 463 MOVL 24(SP), DX 464 MOVQ 32(SP), R10 465 MOVL 40(SP), R8 466 MOVQ 48(SP), R9 467 MOVL $(0x2000000+363), AX 468 SYSCALL 469 JCC 2(PC) 470 NEGQ AX 471 RET 472 473 // void runtime·closeonexec(int32 fd); 474 TEXT runtime·closeonexec(SB),NOSPLIT,$0 475 MOVL 8(SP), DI // fd 476 MOVQ $2, SI // F_SETFD 477 MOVQ $1, DX // FD_CLOEXEC 478 MOVL $(0x2000000+92), AX // fcntl 479 SYSCALL 480 RET