...

Text file src/runtime/sys_nacl_amd64p32.s

     1	// Copyright 2013 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	#include "go_asm.h"
     6	#include "go_tls.h"
     7	#include "textflag.h"
     8	#include "syscall_nacl.h"
     9	
    10	#define NACL_SYSCALL(code) \
    11		MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
    12	
    13	TEXT runtime·settls(SB),NOSPLIT,$0
    14		MOVL	DI, TLS // really BP
    15		RET
    16	
    17	TEXT runtime·exit(SB),NOSPLIT,$0
    18		MOVL code+0(FP), DI
    19		NACL_SYSCALL(SYS_exit)
    20		RET
    21	
    22	// func exitThread(wait *uint32)
    23	TEXT runtime·exitThread(SB),NOSPLIT,$0-4
    24		MOVL wait+0(FP), DI
    25		// SYS_thread_exit will clear *wait when the stack is free.
    26		NACL_SYSCALL(SYS_thread_exit)
    27		JMP 0(PC)
    28	
    29	TEXT runtime·open(SB),NOSPLIT,$0
    30		MOVL name+0(FP), DI
    31		MOVL mode+4(FP), SI
    32		MOVL perm+8(FP), DX
    33		NACL_SYSCALL(SYS_open)
    34		MOVL AX, ret+16(FP)
    35		RET
    36	
    37	TEXT runtime·closefd(SB),NOSPLIT,$0
    38		MOVL fd+0(FP), DI
    39		NACL_SYSCALL(SYS_close)
    40		MOVL AX, ret+8(FP)
    41		RET
    42	
    43	TEXT runtime·read(SB),NOSPLIT,$0
    44		MOVL fd+0(FP), DI
    45		MOVL p+4(FP), SI
    46		MOVL n+8(FP), DX
    47		NACL_SYSCALL(SYS_read)
    48		MOVL AX, ret+16(FP)
    49		RET
    50	
    51	TEXT syscall·naclWrite(SB), NOSPLIT, $24-20
    52		MOVL arg1+0(FP), DI
    53		MOVL arg2+4(FP), SI
    54		MOVL arg3+8(FP), DX
    55		MOVL DI, 0(SP)
    56		MOVL SI, 4(SP)
    57		MOVL DX, 8(SP)
    58		CALL runtime·write(SB)
    59		MOVL 16(SP), AX
    60		MOVL AX, ret+16(FP)
    61		RET
    62	
    63	TEXT runtime·write(SB),NOSPLIT,$16-20
    64		// If using fake time and writing to stdout or stderr,
    65		// emit playback header before actual data.
    66		MOVQ runtime·faketime(SB), AX
    67		CMPQ AX, $0
    68		JEQ write
    69		MOVL fd+0(FP), DI
    70		CMPL DI, $1
    71		JEQ playback
    72		CMPL DI, $2
    73		JEQ playback
    74	
    75	write:
    76		// Ordinary write.
    77		MOVL fd+0(FP), DI
    78		MOVL p+4(FP), SI
    79		MOVL n+8(FP), DX
    80		NACL_SYSCALL(SYS_write)
    81		MOVL	AX, ret+16(FP)
    82		RET
    83	
    84		// Write with playback header.
    85		// First, lock to avoid interleaving writes.
    86	playback:
    87		MOVL $1, BX
    88		XCHGL	runtime·writelock(SB), BX
    89		CMPL BX, $0
    90		JNE playback
    91	
    92		MOVQ runtime·lastfaketime(SB), CX
    93		MOVL runtime·lastfaketimefd(SB), BX
    94		CMPL DI, BX
    95		JE samefd
    96	
    97		// If the current fd doesn't match the fd of the previous write,
    98		// ensure that the timestamp is strictly greater. That way, we can
    99		// recover the original order even if we read the fds separately.
   100		INCQ CX
   101		MOVL DI, runtime·lastfaketimefd(SB)
   102	
   103	samefd:
   104		CMPQ AX, CX
   105		CMOVQLT CX, AX
   106		MOVQ AX, runtime·lastfaketime(SB)
   107	
   108		// Playback header: 0 0 P B <8-byte time> <4-byte data length>
   109		MOVL $(('B'<<24) | ('P'<<16)), 0(SP)
   110		BSWAPQ AX
   111		MOVQ AX, 4(SP)
   112		MOVL n+8(FP), DX
   113		BSWAPL DX
   114		MOVL DX, 12(SP)
   115		MOVL fd+0(FP), DI
   116		MOVL SP, SI
   117		MOVL $16, DX
   118		NACL_SYSCALL(SYS_write)
   119	
   120		// Write actual data.
   121		MOVL fd+0(FP), DI
   122		MOVL p+4(FP), SI
   123		MOVL n+8(FP), DX
   124		NACL_SYSCALL(SYS_write)
   125	
   126		// Unlock.
   127		MOVL	$0, runtime·writelock(SB)
   128	
   129		MOVL	AX, ret+16(FP)
   130		RET
   131	
   132	TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
   133		MOVL p+0(FP), DI
   134		MOVL size+4(FP), SI
   135		NACL_SYSCALL(SYS_exception_stack)
   136		MOVL AX, ret+8(FP)
   137		RET
   138	
   139	TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
   140		MOVL fn+0(FP), DI
   141		MOVL arg+4(FP), SI
   142		NACL_SYSCALL(SYS_exception_handler)
   143		MOVL AX, ret+8(FP)
   144		RET
   145	
   146	TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
   147		MOVL flag+0(FP), DI
   148		NACL_SYSCALL(SYS_sem_create)
   149		MOVL AX, ret+8(FP)
   150		RET
   151	
   152	TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
   153		MOVL sem+0(FP), DI
   154		NACL_SYSCALL(SYS_sem_wait)
   155		MOVL AX, ret+8(FP)
   156		RET
   157	
   158	TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
   159		MOVL sem+0(FP), DI
   160		NACL_SYSCALL(SYS_sem_post)
   161		MOVL AX, ret+8(FP)
   162		RET
   163	
   164	TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
   165		MOVL flag+0(FP), DI
   166		NACL_SYSCALL(SYS_mutex_create)
   167		MOVL AX, ret+8(FP)
   168		RET
   169	
   170	TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
   171		MOVL mutex+0(FP), DI
   172		NACL_SYSCALL(SYS_mutex_lock)
   173		MOVL AX, ret+8(FP)
   174		RET
   175	
   176	TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
   177		MOVL mutex+0(FP), DI
   178		NACL_SYSCALL(SYS_mutex_trylock)
   179		MOVL AX, ret+8(FP)
   180		RET
   181	
   182	TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
   183		MOVL mutex+0(FP), DI
   184		NACL_SYSCALL(SYS_mutex_unlock)
   185		MOVL AX, ret+8(FP)
   186		RET
   187	
   188	TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
   189		MOVL flag+0(FP), DI
   190		NACL_SYSCALL(SYS_cond_create)
   191		MOVL AX, ret+8(FP)
   192		RET
   193	
   194	TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
   195		MOVL cond+0(FP), DI
   196		MOVL n+4(FP), SI
   197		NACL_SYSCALL(SYS_cond_wait)
   198		MOVL AX, ret+8(FP)
   199		RET
   200	
   201	TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
   202		MOVL cond+0(FP), DI
   203		NACL_SYSCALL(SYS_cond_signal)
   204		MOVL AX, ret+8(FP)
   205		RET
   206	
   207	TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
   208		MOVL cond+0(FP), DI
   209		NACL_SYSCALL(SYS_cond_broadcast)
   210		MOVL AX, ret+8(FP)
   211		RET
   212	
   213	TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
   214		MOVL cond+0(FP), DI
   215		MOVL lock+4(FP), SI
   216		MOVL ts+8(FP), DX
   217		NACL_SYSCALL(SYS_cond_timed_wait_abs)
   218		MOVL AX, ret+16(FP)
   219		RET
   220	
   221	TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
   222		MOVL fn+0(FP), DI
   223		MOVL stk+4(FP), SI
   224		MOVL tls+8(FP), DX
   225		MOVL xx+12(FP), CX
   226		NACL_SYSCALL(SYS_thread_create)
   227		MOVL AX, ret+16(FP)
   228		RET
   229	
   230	TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
   231		NACL_SYSCALL(SYS_tls_get)
   232		SUBL	$8, AX
   233		MOVL	AX, TLS
   234		JMP runtime·mstart(SB)
   235	
   236	TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
   237		MOVL ts+0(FP), DI
   238		MOVL extra+4(FP), SI
   239		NACL_SYSCALL(SYS_nanosleep)
   240		MOVL AX, ret+8(FP)
   241		RET
   242	
   243	TEXT runtime·osyield(SB),NOSPLIT,$0
   244		NACL_SYSCALL(SYS_sched_yield)
   245		RET
   246	
   247	TEXT runtime·mmap(SB),NOSPLIT,$8
   248		MOVL addr+0(FP), DI
   249		MOVL n+4(FP), SI
   250		MOVL prot+8(FP), DX
   251		MOVL flags+12(FP), CX
   252		MOVL fd+16(FP), R8
   253		MOVL off+20(FP), AX
   254		MOVQ AX, 0(SP)
   255		MOVL SP, R9
   256		NACL_SYSCALL(SYS_mmap)
   257		CMPL AX, $-4095
   258		JNA ok
   259		NEGL AX
   260		MOVL	$0, p+24(FP)
   261		MOVL	AX, err+28(FP)
   262		RET
   263	ok:
   264		MOVL	AX, p+24(FP)
   265		MOVL	$0, err+28(FP)
   266		RET
   267	
   268	TEXT runtime·walltime(SB),NOSPLIT,$16
   269		MOVQ runtime·faketime(SB), AX
   270		CMPQ AX, $0
   271		JEQ realtime
   272		MOVQ $0, DX
   273		MOVQ $1000000000, CX
   274		DIVQ CX
   275		MOVQ AX, sec+0(FP)
   276		MOVL DX, nsec+8(FP)
   277		RET
   278	realtime:
   279		MOVL $0, DI // real time clock
   280		LEAL 0(SP), AX
   281		MOVL AX, SI // timespec
   282		NACL_SYSCALL(SYS_clock_gettime)
   283		MOVL 0(SP), AX // low 32 sec
   284		MOVL 4(SP), CX // high 32 sec
   285		MOVL 8(SP), BX // nsec
   286	
   287		// sec is in AX, nsec in BX
   288		MOVL	AX, sec_lo+0(FP)
   289		MOVL	CX, sec_hi+4(FP)
   290		MOVL	BX, nsec+8(FP)
   291		RET
   292	
   293	TEXT syscall·now(SB),NOSPLIT,$0
   294		JMP runtime·walltime(SB)
   295	
   296	TEXT runtime·nanotime(SB),NOSPLIT,$16
   297		MOVQ runtime·faketime(SB), AX
   298		CMPQ AX, $0
   299		JEQ 3(PC)
   300		MOVQ	AX, ret+0(FP)
   301		RET
   302		MOVL $0, DI // real time clock
   303		LEAL 0(SP), AX
   304		MOVL AX, SI // timespec
   305		NACL_SYSCALL(SYS_clock_gettime)
   306		MOVQ 0(SP), AX // sec
   307		MOVL 8(SP), DX // nsec
   308	
   309		// sec is in AX, nsec in DX
   310		// return nsec in AX
   311		IMULQ	$1000000000, AX
   312		ADDQ	DX, AX
   313		MOVQ	AX, ret+0(FP)
   314		RET
   315	
   316	TEXT runtime·sigtramp(SB),NOSPLIT,$80
   317		// restore TLS register at time of execution,
   318		// in case it's been smashed.
   319		// the TLS register is really BP, but for consistency
   320		// with non-NaCl systems it is referred to here as TLS.
   321		// NOTE: Cannot use SYS_tls_get here (like we do in mstart_nacl),
   322		// because the main thread never calls tls_set.
   323		LEAL ctxt+0(FP), AX
   324		MOVL	(16*4+5*8)(AX), AX
   325		MOVL	AX, TLS
   326	
   327		// check that g exists
   328		get_tls(CX)
   329		MOVL	g(CX), DI
   330	
   331		CMPL	DI, $0
   332		JEQ	nog
   333	
   334		// save g
   335		MOVL	DI, 20(SP)
   336	
   337		// g = m->gsignal
   338		MOVL	g_m(DI), BX
   339		MOVL	m_gsignal(BX), BX
   340		MOVL	BX, g(CX)
   341	
   342	//JMP debughandler
   343	
   344		// copy arguments for sighandler
   345		MOVL	$11, 0(SP) // signal
   346		MOVL	$0, 4(SP) // siginfo
   347		LEAL	ctxt+0(FP), AX
   348		MOVL	AX, 8(SP) // context
   349		MOVL	DI, 12(SP) // g
   350	
   351		CALL	runtime·sighandler(SB)
   352	
   353		// restore g
   354		get_tls(CX)
   355		MOVL	20(SP), BX
   356		MOVL	BX, g(CX)
   357	
   358		// Enable exceptions again.
   359		NACL_SYSCALL(SYS_exception_clear_flag)
   360	
   361		// Restore registers as best we can. Impossible to do perfectly.
   362		// See comment in sys_nacl_386.s for extended rationale.
   363		LEAL	ctxt+0(FP), SI
   364		ADDL	$64, SI
   365		MOVQ	0(SI), AX
   366		MOVQ	8(SI), CX
   367		MOVQ	16(SI), DX
   368		MOVQ	24(SI), BX
   369		MOVL	32(SI), SP	// MOVL for SP sandboxing
   370		// 40(SI) is saved BP aka TLS, already restored above
   371		// 48(SI) is saved SI, never to be seen again
   372		MOVQ	56(SI), DI
   373		MOVQ	64(SI), R8
   374		MOVQ	72(SI), R9
   375		MOVQ	80(SI), R10
   376		MOVQ	88(SI), R11
   377		MOVQ	96(SI), R12
   378		MOVQ	104(SI), R13
   379		MOVQ	112(SI), R14
   380		// 120(SI) is R15, which is owned by Native Client and must not be modified
   381		MOVQ	128(SI), SI // saved PC
   382		// 136(SI) is saved EFLAGS, never to be seen again
   383		JMP	SI
   384	
   385	//debughandler:
   386		//// print basic information
   387		//LEAL	ctxt+0(FP), DI
   388		//MOVL	$runtime·sigtrampf(SB), AX
   389		//MOVL	AX, 0(SP)
   390		//MOVQ	(16*4+16*8)(DI), BX // rip
   391		//MOVQ	BX, 8(SP)
   392		//MOVQ	(16*4+0*8)(DI), BX // rax
   393		//MOVQ	BX, 16(SP)
   394		//MOVQ	(16*4+1*8)(DI), BX // rcx
   395		//MOVQ	BX, 24(SP)
   396		//MOVQ	(16*4+2*8)(DI), BX // rdx
   397		//MOVQ	BX, 32(SP)
   398		//MOVQ	(16*4+3*8)(DI), BX // rbx
   399		//MOVQ	BX, 40(SP)
   400		//MOVQ	(16*4+7*8)(DI), BX // rdi
   401		//MOVQ	BX, 48(SP)
   402		//MOVQ	(16*4+15*8)(DI), BX // r15
   403		//MOVQ	BX, 56(SP)
   404		//MOVQ	(16*4+4*8)(DI), BX // rsp
   405		//MOVQ	0(BX), BX
   406		//MOVQ	BX, 64(SP)
   407		//CALL	runtime·printf(SB)
   408		//
   409		//LEAL	ctxt+0(FP), DI
   410		//MOVQ	(16*4+16*8)(DI), BX // rip
   411		//MOVL	BX, 0(SP)
   412		//MOVQ	(16*4+4*8)(DI), BX // rsp
   413		//MOVL	BX, 4(SP)
   414		//MOVL	$0, 8(SP)	// lr
   415		//get_tls(CX)
   416		//MOVL	g(CX), BX
   417		//MOVL	BX, 12(SP)	// gp
   418		//CALL	runtime·traceback(SB)
   419	
   420	notls:
   421		MOVL	0, AX
   422		RET
   423	
   424	nog:
   425		MOVL	0, AX
   426		RET
   427	
   428	// cannot do real signal handling yet, because gsignal has not been allocated.
   429	MOVL $1, DI; NACL_SYSCALL(SYS_exit)
   430	
   431	// func getRandomData([]byte)
   432	TEXT runtime·getRandomData(SB),NOSPLIT,$0-12
   433		MOVL arg_base+0(FP), DI
   434		MOVL arg_len+4(FP), SI
   435		NACL_SYSCALL(SYS_get_random_bytes)
   436		RET
   437	
   438	TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
   439	/*
   440		MOVL	di+0(FP), DI
   441		LEAL	12(DI), BX
   442		MOVL	8(DI), AX
   443		ADDL	4(DI), AX
   444		ADDL	$2, AX
   445		LEAL	(BX)(AX*4), BX
   446		MOVL	BX, runtime·nacl_irt_query(SB)
   447	auxloop:
   448		MOVL	0(BX), DX
   449		CMPL	DX, $0
   450		JNE	2(PC)
   451		RET
   452		CMPL	DX, $32
   453		JEQ	auxfound
   454		ADDL	$8, BX
   455		JMP	auxloop
   456	auxfound:
   457		MOVL	4(BX), BX
   458		MOVL	BX, runtime·nacl_irt_query(SB)
   459	
   460		LEAL	runtime·nacl_irt_basic_v0_1_str(SB), DI
   461		LEAL	runtime·nacl_irt_basic_v0_1(SB), SI
   462		MOVL	runtime·nacl_irt_basic_v0_1_size(SB), DX
   463		MOVL	runtime·nacl_irt_query(SB), BX
   464		CALL	BX
   465	
   466		LEAL	runtime·nacl_irt_memory_v0_3_str(SB), DI
   467		LEAL	runtime·nacl_irt_memory_v0_3(SB), SI
   468		MOVL	runtime·nacl_irt_memory_v0_3_size(SB), DX
   469		MOVL	runtime·nacl_irt_query(SB), BX
   470		CALL	BX
   471	
   472		LEAL	runtime·nacl_irt_thread_v0_1_str(SB), DI
   473		LEAL	runtime·nacl_irt_thread_v0_1(SB), SI
   474		MOVL	runtime·nacl_irt_thread_v0_1_size(SB), DX
   475		MOVL	runtime·nacl_irt_query(SB), BX
   476		CALL	BX
   477	
   478		// TODO: Once we have a NaCl SDK with futex syscall support,
   479		// try switching to futex syscalls and here load the
   480		// nacl-irt-futex-0.1 table.
   481	*/
   482		RET

View as plain text