github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/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 "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