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