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