...
Run Format

Text file src/runtime/sys_darwin_amd64.s

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

View as plain text