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