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