Home | History | Annotate | Download | only in runtime
      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 "go_asm.h"
     15 #include "go_tls.h"
     16 #include "textflag.h"
     17 
     18 // Exit the entire program (like C exit)
     19 TEXT runtimeexit(SB),NOSPLIT,$0
     20 	MOVL	code+0(FP), DI		// arg 1 exit status
     21 	MOVL	$(0x2000000+1), AX	// syscall entry
     22 	SYSCALL
     23 	MOVL	$0xf1, 0xf1  // crash
     24 	RET
     25 
     26 // Exit this OS thread (like pthread_exit, which eventually
     27 // calls __bsdthread_terminate).
     28 TEXT exit1<>(SB),NOSPLIT,$0
     29 	// Because of exitThread below, this must not use the stack.
     30 	// __bsdthread_terminate takes 4 word-size arguments.
     31 	// Set them all to 0. (None are an exit status.)
     32 	MOVL	$0, DI
     33 	MOVL	$0, SI
     34 	MOVL	$0, DX
     35 	MOVL	$0, R10
     36 	MOVL	$(0x2000000+361), AX	// syscall entry
     37 	SYSCALL
     38 	MOVL	$0xf1, 0xf1  // crash
     39 	RET
     40 
     41 // func exitThread(wait *uint32)
     42 TEXT runtimeexitThread(SB),NOSPLIT,$0-8
     43 	MOVQ	wait+0(FP), AX
     44 	// We're done using the stack.
     45 	MOVL	$0, (AX)
     46 	JMP	exit1<>(SB)
     47 
     48 TEXT runtimeopen(SB),NOSPLIT,$0
     49 	MOVQ	name+0(FP), DI		// arg 1 pathname
     50 	MOVL	mode+8(FP), SI		// arg 2 flags
     51 	MOVL	perm+12(FP), DX		// arg 3 mode
     52 	MOVL	$(0x2000000+5), AX	// syscall entry
     53 	SYSCALL
     54 	JCC	2(PC)
     55 	MOVL	$-1, AX
     56 	MOVL	AX, ret+16(FP)
     57 	RET
     58 
     59 TEXT runtimeclosefd(SB),NOSPLIT,$0
     60 	MOVL	fd+0(FP), DI		// arg 1 fd
     61 	MOVL	$(0x2000000+6), AX	// syscall entry
     62 	SYSCALL
     63 	JCC	2(PC)
     64 	MOVL	$-1, AX
     65 	MOVL	AX, ret+8(FP)
     66 	RET
     67 
     68 TEXT runtimeread(SB),NOSPLIT,$0
     69 	MOVL	fd+0(FP), DI		// arg 1 fd
     70 	MOVQ	p+8(FP), SI		// arg 2 buf
     71 	MOVL	n+16(FP), DX		// arg 3 count
     72 	MOVL	$(0x2000000+3), AX	// syscall entry
     73 	SYSCALL
     74 	JCC	2(PC)
     75 	MOVL	$-1, AX
     76 	MOVL	AX, ret+24(FP)
     77 	RET
     78 
     79 TEXT runtimewrite(SB),NOSPLIT,$0
     80 	MOVQ	fd+0(FP), DI		// arg 1 fd
     81 	MOVQ	p+8(FP), SI		// arg 2 buf
     82 	MOVL	n+16(FP), DX		// arg 3 count
     83 	MOVL	$(0x2000000+4), AX	// syscall entry
     84 	SYSCALL
     85 	JCC	2(PC)
     86 	MOVL	$-1, AX
     87 	MOVL	AX, ret+24(FP)
     88 	RET
     89 
     90 TEXT runtimeraise(SB),NOSPLIT,$0
     91 	// Ideally we'd send the signal to the current thread,
     92 	// not the whole process, but that's too hard on OS X.
     93 	JMP	runtimeraiseproc(SB)
     94 
     95 TEXT runtimeraiseproc(SB),NOSPLIT,$24
     96 	MOVL	$(0x2000000+20), AX // getpid
     97 	SYSCALL
     98 	MOVQ	AX, DI	// arg 1 - pid
     99 	MOVL	sig+0(FP), SI	// arg 2 - signal
    100 	MOVL	$1, DX	// arg 3 - posix
    101 	MOVL	$(0x2000000+37), AX // kill
    102 	SYSCALL
    103 	RET
    104 
    105 TEXT runtimesetitimer(SB), NOSPLIT, $0
    106 	MOVL	mode+0(FP), DI
    107 	MOVQ	new+8(FP), SI
    108 	MOVQ	old+16(FP), DX
    109 	MOVL	$(0x2000000+83), AX	// syscall entry
    110 	SYSCALL
    111 	RET
    112 
    113 TEXT runtimemadvise(SB), NOSPLIT, $0
    114 	MOVQ	addr+0(FP), DI		// arg 1 addr
    115 	MOVQ	n+8(FP), SI		// arg 2 len
    116 	MOVL	flags+16(FP), DX		// arg 3 advice
    117 	MOVL	$(0x2000000+75), AX	// syscall entry madvise
    118 	SYSCALL
    119 	// ignore failure - maybe pages are locked
    120 	RET
    121 
    122 // OS X comm page time offsets
    123 // https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
    124 
    125 #define	nt_tsc_base	0x50
    126 #define	nt_scale	0x58
    127 #define	nt_shift	0x5c
    128 #define	nt_ns_base	0x60
    129 #define	nt_generation	0x68
    130 #define	gtod_generation	0x6c  // obsolete since Darwin v17 (High Sierra)
    131 #define	gtod_ns_base	0x70  // obsolete since Darwin v17 (High Sierra)
    132 #define	gtod_sec_base	0x78  // obsolete since Darwin v17 (High Sierra)
    133 
    134 #define	v17_gtod_ns_base	0xd0
    135 #define	v17_gtod_sec_ofs	0xd8
    136 #define	v17_gtod_frac_ofs	0xe0
    137 #define	v17_gtod_scale		0xe8
    138 #define	v17_gtod_tkspersec	0xf0
    139 
    140 TEXT runtimenanotime(SB),NOSPLIT,$0-8
    141 	MOVQ	$0x7fffffe00000, BP	/* comm page base */
    142 	// Loop trying to take a consistent snapshot
    143 	// of the time parameters.
    144 timeloop:
    145 	MOVL	nt_generation(BP), R9
    146 	TESTL	R9, R9
    147 	JZ	timeloop
    148 	RDTSC
    149 	MOVQ	nt_tsc_base(BP), R10
    150 	MOVL	nt_scale(BP), R11
    151 	MOVQ	nt_ns_base(BP), R12
    152 	CMPL	nt_generation(BP), R9
    153 	JNE	timeloop
    154 
    155 	// Gathered all the data we need. Compute monotonic time:
    156 	//	((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
    157 	// The multiply and shift extracts the top 64 bits of the 96-bit product.
    158 	SHLQ	$32, DX
    159 	ADDQ	DX, AX
    160 	SUBQ	R10, AX
    161 	MULQ	R11
    162 	SHRQ	$32, AX:DX
    163 	ADDQ	R12, AX
    164 	MOVQ	runtimestartNano(SB), CX
    165 	SUBQ	CX, AX
    166 	MOVQ	AX, ret+0(FP)
    167 	RET
    168 
    169 TEXT timenow(SB), NOSPLIT, $32-24
    170 	// Note: The 32 bytes of stack frame requested on the TEXT line
    171 	// are used in the systime fallback, as the timeval address
    172 	// filled in by the system call.
    173 	MOVQ	$0x7fffffe00000, BP	/* comm page base */
    174 	CMPQ	runtimedarwinVersion(SB), $17
    175 	JB		legacy /* sierra and older */
    176 
    177 	// This is the new code, for macOS High Sierra (Darwin v17) and newer.
    178 v17:
    179 	// Loop trying to take a consistent snapshot
    180 	// of the time parameters.
    181 timeloop17:
    182 	MOVQ 	v17_gtod_ns_base(BP), R12
    183 
    184 	MOVL	nt_generation(BP), CX
    185 	TESTL	CX, CX
    186 	JZ		timeloop17
    187 	RDTSC
    188 	MOVQ	nt_tsc_base(BP), SI
    189 	MOVL	nt_scale(BP), DI
    190 	MOVQ	nt_ns_base(BP), BX
    191 	CMPL	nt_generation(BP), CX
    192 	JNE		timeloop17
    193 
    194 	MOVQ 	v17_gtod_sec_ofs(BP), R8
    195 	MOVQ 	v17_gtod_frac_ofs(BP), R9
    196 	MOVQ 	v17_gtod_scale(BP), R10
    197 	MOVQ 	v17_gtod_tkspersec(BP), R11
    198 	CMPQ 	v17_gtod_ns_base(BP), R12
    199 	JNE 	timeloop17
    200 
    201 	// Compute monotonic time
    202 	//	mono = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
    203 	// The multiply and shift extracts the top 64 bits of the 96-bit product.
    204 	SHLQ	$32, DX
    205 	ADDQ	DX, AX
    206 	SUBQ	SI, AX
    207 	MULQ	DI
    208 	SHRQ	$32, AX:DX
    209 	ADDQ	BX, AX
    210 
    211 	// Subtract startNano base to return the monotonic runtime timer
    212 	// which is an offset from process boot.
    213 	MOVQ	AX, BX
    214 	MOVQ	runtimestartNano(SB), CX
    215 	SUBQ	CX, BX
    216 	MOVQ	BX, monotonic+16(FP)
    217 
    218 	// Now compute the 128-bit wall time:
    219 	//  wall = ((mono - gtod_ns_base) * gtod_scale) + gtod_offs
    220 	// The parameters are updated every second, so if we found them
    221 	// outdated (that is, more than one second is passed from the ns base),
    222 	// fallback to the syscall.
    223 	TESTQ	R12, R12
    224 	JZ		systime
    225 	SUBQ	R12, AX
    226 	CMPQ	R11, AX
    227 	JB		systime
    228 	MULQ 	R10
    229 	ADDQ	R9, AX
    230 	ADCQ	R8, DX
    231 
    232 	// Convert the 128-bit wall time into (sec,nsec).
    233 	// High part (seconds) is already good to go, while low part
    234 	// (fraction of seconds) must be converted to nanoseconds.
    235 	MOVQ	DX, sec+0(FP)
    236 	MOVQ 	$1000000000, CX
    237 	MULQ	CX
    238 	MOVQ	DX, nsec+8(FP)
    239 	RET
    240 
    241 	// This is the legacy code needed for macOS Sierra (Darwin v16) and older.
    242 legacy:
    243 	// Loop trying to take a consistent snapshot
    244 	// of the time parameters.
    245 timeloop:
    246 	MOVL	gtod_generation(BP), R8
    247 	MOVL	nt_generation(BP), R9
    248 	TESTL	R9, R9
    249 	JZ	timeloop
    250 	RDTSC
    251 	MOVQ	nt_tsc_base(BP), R10
    252 	MOVL	nt_scale(BP), R11
    253 	MOVQ	nt_ns_base(BP), R12
    254 	CMPL	nt_generation(BP), R9
    255 	JNE	timeloop
    256 	MOVQ	gtod_ns_base(BP), R13
    257 	MOVQ	gtod_sec_base(BP), R14
    258 	CMPL	gtod_generation(BP), R8
    259 	JNE	timeloop
    260 
    261 	// Gathered all the data we need. Compute:
    262 	//	monotonic_time = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
    263 	// The multiply and shift extracts the top 64 bits of the 96-bit product.
    264 	SHLQ	$32, DX
    265 	ADDQ	DX, AX
    266 	SUBQ	R10, AX
    267 	MULQ	R11
    268 	SHRQ	$32, AX:DX
    269 	ADDQ	R12, AX
    270 	MOVQ	AX, BX
    271 	MOVQ	runtimestartNano(SB), CX
    272 	SUBQ	CX, BX
    273 	MOVQ	BX, monotonic+16(FP)
    274 
    275 	// Compute:
    276 	//	wall_time = monotonic time - gtod_ns_base + gtod_sec_base*1e9
    277 	// or, if gtod_generation==0, invoke the system call.
    278 	TESTL	R8, R8
    279 	JZ	systime
    280 	SUBQ	R13, AX
    281 	IMULQ	$1000000000, R14
    282 	ADDQ	R14, AX
    283 
    284 	// Split wall time into sec, nsec.
    285 	// generated code for
    286 	//	func f(x uint64) (uint64, uint64) { return x/1e9, x%1e9 }
    287 	// adapted to reduce duplication
    288 	MOVQ	AX, CX
    289 	SHRQ	$9, AX
    290 	MOVQ	$19342813113834067, DX
    291 	MULQ	DX
    292 	SHRQ	$11, DX
    293 	MOVQ	DX, sec+0(FP)
    294 	IMULQ	$1000000000, DX
    295 	SUBQ	DX, CX
    296 	MOVL	CX, nsec+8(FP)
    297 	RET
    298 
    299 systime:
    300 	// Fall back to system call (usually first call in this thread).
    301 	MOVQ	SP, DI
    302 	MOVQ	$0, SI
    303 	MOVQ	$0, DX  // required as of Sierra; Issue 16570
    304 	MOVL	$(0x2000000+116), AX // gettimeofday
    305 	SYSCALL
    306 	CMPQ	AX, $0
    307 	JNE	inreg
    308 	MOVQ	0(SP), AX
    309 	MOVL	8(SP), DX
    310 inreg:
    311 	// sec is in AX, usec in DX
    312 	IMULQ	$1000, DX
    313 	MOVQ	AX, sec+0(FP)
    314 	MOVL	DX, nsec+8(FP)
    315 	RET
    316 
    317 TEXT runtimesigprocmask(SB),NOSPLIT,$0
    318 	MOVL	how+0(FP), DI
    319 	MOVQ	new+8(FP), SI
    320 	MOVQ	old+16(FP), DX
    321 	MOVL	$(0x2000000+329), AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
    322 	SYSCALL
    323 	JCC	2(PC)
    324 	MOVL	$0xf1, 0xf1  // crash
    325 	RET
    326 
    327 TEXT runtimesigaction(SB),NOSPLIT,$0-24
    328 	MOVL	mode+0(FP), DI		// arg 1 sig
    329 	MOVQ	new+8(FP), SI		// arg 2 act
    330 	MOVQ	old+16(FP), DX		// arg 3 oact
    331 	MOVQ	old+16(FP), CX		// arg 3 oact
    332 	MOVQ	old+16(FP), R10		// arg 3 oact
    333 	MOVL	$(0x2000000+46), AX	// syscall entry
    334 	SYSCALL
    335 	JCC	2(PC)
    336 	MOVL	$0xf1, 0xf1  // crash
    337 	RET
    338 
    339 TEXT runtimesigfwd(SB),NOSPLIT,$0-32
    340 	MOVQ	fn+0(FP),    AX
    341 	MOVL	sig+8(FP),   DI
    342 	MOVQ	info+16(FP), SI
    343 	MOVQ	ctx+24(FP),  DX
    344 	PUSHQ	BP
    345 	MOVQ	SP, BP
    346 	ANDQ	$~15, SP     // alignment for x86_64 ABI
    347 	CALL	AX
    348 	MOVQ	BP, SP
    349 	POPQ	BP
    350 	RET
    351 
    352 TEXT runtimesigtramp(SB),NOSPLIT,$40
    353 	MOVL SI, 24(SP) // save infostyle for sigreturn below
    354 	MOVQ R8, 32(SP) // save ctx
    355 	MOVL DX, 0(SP)  // sig
    356 	MOVQ CX, 8(SP)  // info
    357 	MOVQ R8, 16(SP) // ctx
    358 	MOVQ $runtimesigtrampgo(SB), AX
    359 	CALL AX
    360 	MOVQ 32(SP), DI // ctx
    361 	MOVL 24(SP), SI // infostyle
    362 	MOVL $(0x2000000+184), AX
    363 	SYSCALL
    364 	INT $3 // not reached
    365 
    366 TEXT runtimemmap(SB),NOSPLIT,$0
    367 	MOVQ	addr+0(FP), DI		// arg 1 addr
    368 	MOVQ	n+8(FP), SI		// arg 2 len
    369 	MOVL	prot+16(FP), DX		// arg 3 prot
    370 	MOVL	flags+20(FP), R10		// arg 4 flags
    371 	MOVL	fd+24(FP), R8		// arg 5 fid
    372 	MOVL	off+28(FP), R9		// arg 6 offset
    373 	MOVL	$(0x2000000+197), AX	// syscall entry
    374 	SYSCALL
    375 	JCC	ok
    376 	MOVQ	$0, p+32(FP)
    377 	MOVQ	AX, err+40(FP)
    378 	RET
    379 ok:
    380 	MOVQ	AX, p+32(FP)
    381 	MOVQ	$0, err+40(FP)
    382 	RET
    383 
    384 TEXT runtimemunmap(SB),NOSPLIT,$0
    385 	MOVQ	addr+0(FP), DI		// arg 1 addr
    386 	MOVQ	n+8(FP), SI		// arg 2 len
    387 	MOVL	$(0x2000000+73), AX	// syscall entry
    388 	SYSCALL
    389 	JCC	2(PC)
    390 	MOVL	$0xf1, 0xf1  // crash
    391 	RET
    392 
    393 TEXT runtimesigaltstack(SB),NOSPLIT,$0
    394 	MOVQ	new+0(FP), DI
    395 	MOVQ	old+8(FP), SI
    396 	MOVQ	$(0x2000000+53), AX
    397 	SYSCALL
    398 	JCC	2(PC)
    399 	MOVL	$0xf1, 0xf1  // crash
    400 	RET
    401 
    402 TEXT runtimeusleep(SB),NOSPLIT,$16
    403 	MOVL	$0, DX
    404 	MOVL	usec+0(FP), AX
    405 	MOVL	$1000000, CX
    406 	DIVL	CX
    407 	MOVQ	AX, 0(SP)  // sec
    408 	MOVL	DX, 8(SP)  // usec
    409 
    410 	// select(0, 0, 0, 0, &tv)
    411 	MOVL	$0, DI
    412 	MOVL	$0, SI
    413 	MOVL	$0, DX
    414 	MOVL	$0, R10
    415 	MOVQ	SP, R8
    416 	MOVL	$(0x2000000+93), AX
    417 	SYSCALL
    418 	RET
    419 
    420 // func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
    421 TEXT runtimebsdthread_create(SB),NOSPLIT,$0
    422 	// Set up arguments to bsdthread_create system call.
    423 	// The ones in quotes pass through to the thread callback
    424 	// uninterpreted, so we can put whatever we want there.
    425 	MOVQ	fn+16(FP),   DI
    426 	MOVQ	arg+8(FP),  SI
    427 	MOVQ	stk+0(FP),   DX
    428 	MOVQ	$0x01000000, R8  // flags = PTHREAD_START_CUSTOM
    429 	MOVQ	$0,          R9  // paranoia
    430 	MOVQ	$0,          R10 // paranoia, "pthread"
    431 	MOVQ	$(0x2000000+360), AX	// bsdthread_create
    432 	SYSCALL
    433 	JCC 4(PC)
    434 	NEGQ	AX
    435 	MOVL	AX, ret+24(FP)
    436 	RET
    437 	MOVL	$0, AX
    438 	MOVL	AX, ret+24(FP)
    439 	RET
    440 
    441 // The thread that bsdthread_create creates starts executing here,
    442 // because we registered this function using bsdthread_register
    443 // at startup.
    444 //	DI = "pthread"
    445 //	SI = mach thread port
    446 //	DX = "func" (= fn)
    447 //	CX = "arg" (= m)
    448 //	R8 = stack
    449 //	R9 = flags (= 0)
    450 //	SP = stack - C_64_REDZONE_LEN (= stack - 128)
    451 TEXT runtimebsdthread_start(SB),NOSPLIT,$0
    452 	MOVQ	R8, SP		// empirically, SP is very wrong but R8 is right
    453 
    454 	PUSHQ	DX
    455 	PUSHQ	CX
    456 	PUSHQ	SI
    457 
    458 	// set up thread local storage pointing at m->tls.
    459 	LEAQ	m_tls(CX), DI
    460 	CALL	runtimesettls(SB)
    461 
    462 	POPQ	SI
    463 	POPQ	CX
    464 	POPQ	DX
    465 
    466 	get_tls(BX)
    467 	MOVQ	SI, m_procid(CX)	// thread port is m->procid
    468 	MOVQ	m_g0(CX), AX
    469 	MOVQ	AX, g(BX)
    470 	MOVQ	CX, g_m(AX)
    471 	CALL	runtimestackcheck(SB)	// smashes AX, CX
    472 	CALL	DX	// fn
    473 	CALL	exit1<>(SB)
    474 	RET
    475 
    476 // func bsdthread_register() int32
    477 // registers callbacks for threadstart (see bsdthread_create above
    478 // and wqthread and pthsize (not used).  returns 0 on success.
    479 TEXT runtimebsdthread_register(SB),NOSPLIT,$0
    480 	MOVQ	$runtimebsdthread_start(SB), DI	// threadstart
    481 	MOVQ	$0, SI	// wqthread, not used by us
    482 	MOVQ	$0, DX	// pthsize, not used by us
    483 	MOVQ	$0, R10	// dummy_value [sic]
    484 	MOVQ	$0, R8	// targetconc_ptr
    485 	MOVQ	$0, R9	// dispatchqueue_offset
    486 	MOVQ	$(0x2000000+366), AX	// bsdthread_register
    487 	SYSCALL
    488 	JCC 4(PC)
    489 	NEGQ	AX
    490 	MOVL	AX, ret+0(FP)
    491 	RET
    492 	MOVL	$0, AX
    493 	MOVL	AX, ret+0(FP)
    494 	RET
    495 
    496 // Mach system calls use 0x1000000 instead of the BSD's 0x2000000.
    497 
    498 // func mach_msg_trap(h unsafe.Pointer, op int32, send_size, rcv_size, rcv_name, timeout, notify uint32) int32
    499 TEXT runtimemach_msg_trap(SB),NOSPLIT,$0
    500 	MOVQ	h+0(FP), DI
    501 	MOVL	op+8(FP), SI
    502 	MOVL	send_size+12(FP), DX
    503 	MOVL	rcv_size+16(FP), R10
    504 	MOVL	rcv_name+20(FP), R8
    505 	MOVL	timeout+24(FP), R9
    506 	MOVL	notify+28(FP), R11
    507 	PUSHQ	R11	// seventh arg, on stack
    508 	MOVL	$(0x1000000+31), AX	// mach_msg_trap
    509 	SYSCALL
    510 	POPQ	R11
    511 	MOVL	AX, ret+32(FP)
    512 	RET
    513 
    514 TEXT runtimemach_task_self(SB),NOSPLIT,$0
    515 	MOVL	$(0x1000000+28), AX	// task_self_trap
    516 	SYSCALL
    517 	MOVL	AX, ret+0(FP)
    518 	RET
    519 
    520 TEXT runtimemach_thread_self(SB),NOSPLIT,$0
    521 	MOVL	$(0x1000000+27), AX	// thread_self_trap
    522 	SYSCALL
    523 	MOVL	AX, ret+0(FP)
    524 	RET
    525 
    526 TEXT runtimemach_reply_port(SB),NOSPLIT,$0
    527 	MOVL	$(0x1000000+26), AX	// mach_reply_port
    528 	SYSCALL
    529 	MOVL	AX, ret+0(FP)
    530 	RET
    531 
    532 // Mach provides trap versions of the semaphore ops,
    533 // instead of requiring the use of RPC.
    534 
    535 // func mach_semaphore_wait(sema uint32) int32
    536 TEXT runtimemach_semaphore_wait(SB),NOSPLIT,$0
    537 	MOVL	sema+0(FP), DI
    538 	MOVL	$(0x1000000+36), AX	// semaphore_wait_trap
    539 	SYSCALL
    540 	MOVL	AX, ret+8(FP)
    541 	RET
    542 
    543 // func mach_semaphore_timedwait(sema, sec, nsec uint32) int32
    544 TEXT runtimemach_semaphore_timedwait(SB),NOSPLIT,$0
    545 	MOVL	sema+0(FP), DI
    546 	MOVL	sec+4(FP), SI
    547 	MOVL	nsec+8(FP), DX
    548 	MOVL	$(0x1000000+38), AX	// semaphore_timedwait_trap
    549 	SYSCALL
    550 	MOVL	AX, ret+16(FP)
    551 	RET
    552 
    553 // func mach_semaphore_signal(sema uint32) int32
    554 TEXT runtimemach_semaphore_signal(SB),NOSPLIT,$0
    555 	MOVL	sema+0(FP), DI
    556 	MOVL	$(0x1000000+33), AX	// semaphore_signal_trap
    557 	SYSCALL
    558 	MOVL	AX, ret+8(FP)
    559 	RET
    560 
    561 // func mach_semaphore_signal_all(sema uint32) int32
    562 TEXT runtimemach_semaphore_signal_all(SB),NOSPLIT,$0
    563 	MOVL	sema+0(FP), DI
    564 	MOVL	$(0x1000000+34), AX	// semaphore_signal_all_trap
    565 	SYSCALL
    566 	MOVL	AX, ret+8(FP)
    567 	RET
    568 
    569 // set tls base to DI
    570 TEXT runtimesettls(SB),NOSPLIT,$32
    571 	/*
    572 	* Same as in sys_darwin_386.s:/ugliness, different constant.
    573 	* See cgo/gcc_darwin_amd64.c for the derivation
    574 	* of the constant.
    575 	*/
    576 	SUBQ $0x8a0, DI
    577 
    578 	MOVL	$(0x3000000+3), AX	// thread_fast_set_cthread_self - machdep call #3
    579 	SYSCALL
    580 	RET
    581 
    582 TEXT runtimesysctl(SB),NOSPLIT,$0
    583 	MOVQ	mib+0(FP), DI
    584 	MOVL	miblen+8(FP), SI
    585 	MOVQ	out+16(FP), DX
    586 	MOVQ	size+24(FP), R10
    587 	MOVQ	dst+32(FP), R8
    588 	MOVQ	ndst+40(FP), R9
    589 	MOVL	$(0x2000000+202), AX	// syscall entry
    590 	SYSCALL
    591 	JCC 4(PC)
    592 	NEGQ	AX
    593 	MOVL	AX, ret+48(FP)
    594 	RET
    595 	MOVL	$0, AX
    596 	MOVL	AX, ret+48(FP)
    597 	RET
    598 
    599 // func kqueue() int32
    600 TEXT runtimekqueue(SB),NOSPLIT,$0
    601 	MOVQ    $0, DI
    602 	MOVQ    $0, SI
    603 	MOVQ    $0, DX
    604 	MOVL	$(0x2000000+362), AX
    605 	SYSCALL
    606 	JCC	2(PC)
    607 	NEGQ	AX
    608 	MOVL	AX, ret+0(FP)
    609 	RET
    610 
    611 // func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
    612 TEXT runtimekevent(SB),NOSPLIT,$0
    613 	MOVL    kq+0(FP), DI
    614 	MOVQ    ch+8(FP), SI
    615 	MOVL    nch+16(FP), DX
    616 	MOVQ    ev+24(FP), R10
    617 	MOVL    nev+32(FP), R8
    618 	MOVQ    ts+40(FP), R9
    619 	MOVL	$(0x2000000+363), AX
    620 	SYSCALL
    621 	JCC	2(PC)
    622 	NEGQ	AX
    623 	MOVL	AX, ret+48(FP)
    624 	RET
    625 
    626 // func closeonexec(fd int32)
    627 TEXT runtimecloseonexec(SB),NOSPLIT,$0
    628 	MOVL    fd+0(FP), DI  // fd
    629 	MOVQ    $2, SI  // F_SETFD
    630 	MOVQ    $1, DX  // FD_CLOEXEC
    631 	MOVL	$(0x2000000+92), AX  // fcntl
    632 	SYSCALL
    633 	RET
    634