...
Run Format

Text file src/runtime/sys_nacl_386.s

Documentation: runtime

     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·exit(SB),NOSPLIT,$4
    14		MOVL code+0(FP), AX
    15		MOVL AX, 0(SP)
    16		NACL_SYSCALL(SYS_exit)
    17		JMP 0(PC)
    18	
    19	TEXT runtime·exit1(SB),NOSPLIT,$4
    20		MOVL code+0(FP), AX
    21		MOVL AX, 0(SP)
    22		NACL_SYSCALL(SYS_thread_exit)
    23		RET
    24	
    25	TEXT runtime·open(SB),NOSPLIT,$12
    26		MOVL name+0(FP), AX
    27		MOVL AX, 0(SP)
    28		MOVL mode+4(FP), AX
    29		MOVL AX, 4(SP)
    30		MOVL perm+8(FP), AX
    31		MOVL AX, 8(SP)
    32		NACL_SYSCALL(SYS_open)
    33		MOVL AX, ret+12(FP)
    34		RET
    35	
    36	TEXT runtime·closefd(SB),NOSPLIT,$4
    37		MOVL fd+0(FP), AX
    38		MOVL AX, 0(SP)
    39		NACL_SYSCALL(SYS_close)
    40		MOVL AX, ret+4(FP)
    41		RET
    42	
    43	TEXT runtime·read(SB),NOSPLIT,$12
    44		MOVL fd+0(FP), AX
    45		MOVL AX, 0(SP)
    46		MOVL p+4(FP), AX
    47		MOVL AX, 4(SP)
    48		MOVL n+8(FP), AX
    49		MOVL AX, 8(SP)
    50		NACL_SYSCALL(SYS_read)
    51		MOVL AX, ret+12(FP)
    52		RET
    53	
    54	TEXT syscall·naclWrite(SB), NOSPLIT, $16-16
    55		MOVL arg1+0(FP), DI
    56		MOVL arg2+4(FP), SI
    57		MOVL arg3+8(FP), DX
    58		MOVL DI, 0(SP)
    59		MOVL SI, 4(SP)
    60		MOVL DX, 8(SP)
    61		CALL runtime·write(SB)
    62		MOVL AX, ret+16(FP)
    63		RET
    64	
    65	TEXT runtime·write(SB),NOSPLIT,$12
    66		MOVL fd+0(FP), AX
    67		MOVL AX, 0(SP)
    68		MOVL p+4(FP), AX
    69		MOVL AX, 4(SP)
    70		MOVL n+8(FP), AX
    71		MOVL AX, 8(SP)
    72		NACL_SYSCALL(SYS_write)
    73		MOVL AX, ret+12(FP)
    74		RET
    75	
    76	TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$8
    77		MOVL p+0(FP), AX
    78		MOVL AX, 0(SP)
    79		MOVL size+4(FP), AX
    80		MOVL AX, 4(SP)
    81		NACL_SYSCALL(SYS_exception_stack)
    82		MOVL AX, ret+8(FP)
    83		RET
    84	
    85	TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$8
    86		MOVL fn+0(FP), AX
    87		MOVL AX, 0(SP)
    88		MOVL arg+4(FP), AX
    89		MOVL AX, 4(SP)
    90		NACL_SYSCALL(SYS_exception_handler)
    91		MOVL AX, ret+8(FP)
    92		RET
    93	
    94	TEXT runtime·nacl_sem_create(SB),NOSPLIT,$4
    95		MOVL flag+0(FP), AX
    96		MOVL AX, 0(SP)
    97		NACL_SYSCALL(SYS_sem_create)
    98		MOVL AX, ret+4(FP)
    99		RET
   100	
   101	TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$4
   102		MOVL sem+0(FP), AX
   103		MOVL AX, 0(SP)
   104		NACL_SYSCALL(SYS_sem_wait)
   105		MOVL AX, ret+4(FP)
   106		RET
   107	
   108	TEXT runtime·nacl_sem_post(SB),NOSPLIT,$4
   109		MOVL sem+0(FP), AX
   110		MOVL AX, 0(SP)
   111		NACL_SYSCALL(SYS_sem_post)
   112		MOVL AX, ret+4(FP)
   113		RET
   114	
   115	TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$4
   116		MOVL flag+0(FP), AX
   117		MOVL AX, 0(SP)
   118		NACL_SYSCALL(SYS_mutex_create)
   119		MOVL AX, ret+4(FP)
   120		RET
   121	
   122	TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$4
   123		MOVL mutex+0(FP), AX
   124		MOVL AX, 0(SP)
   125		NACL_SYSCALL(SYS_mutex_lock)
   126		MOVL AX, ret+4(FP)
   127		RET
   128	
   129	TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$4
   130		MOVL mutex+0(FP), AX
   131		MOVL AX, 0(SP)
   132		NACL_SYSCALL(SYS_mutex_trylock)
   133		MOVL AX, ret+4(FP)
   134		RET
   135	
   136	TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$4
   137		MOVL mutex+0(FP), AX
   138		MOVL AX, 0(SP)
   139		NACL_SYSCALL(SYS_mutex_unlock)
   140		MOVL AX, ret+4(FP)
   141		RET
   142	
   143	TEXT runtime·nacl_cond_create(SB),NOSPLIT,$4
   144		MOVL flag+0(FP), AX
   145		MOVL AX, 0(SP)
   146		NACL_SYSCALL(SYS_cond_create)
   147		MOVL AX, ret+4(FP)
   148		RET
   149	
   150	TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$8
   151		MOVL cond+0(FP), AX
   152		MOVL AX, 0(SP)
   153		MOVL n+4(FP), AX
   154		MOVL AX, 4(SP)
   155		NACL_SYSCALL(SYS_cond_wait)
   156		MOVL AX, ret+8(FP)
   157		RET
   158	
   159	TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$4
   160		MOVL cond+0(FP), AX
   161		MOVL AX, 0(SP)
   162		NACL_SYSCALL(SYS_cond_signal)
   163		MOVL AX, ret+4(FP)
   164		RET
   165	
   166	TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$4
   167		MOVL cond+0(FP), AX
   168		MOVL AX, 0(SP)
   169		NACL_SYSCALL(SYS_cond_broadcast)
   170		MOVL AX, ret+4(FP)
   171		RET
   172	
   173	TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$12
   174		MOVL cond+0(FP), AX
   175		MOVL AX, 0(SP)
   176		MOVL lock+4(FP), AX
   177		MOVL AX, 4(SP)
   178		MOVL ts+8(FP), AX
   179		MOVL AX, 8(SP)
   180		NACL_SYSCALL(SYS_cond_timed_wait_abs)
   181		MOVL AX, ret+12(FP)
   182		RET
   183	
   184	TEXT runtime·nacl_thread_create(SB),NOSPLIT,$16
   185		MOVL fn+0(FP), AX
   186		MOVL AX, 0(SP)
   187		MOVL stk+4(FP), AX
   188		MOVL AX, 4(SP)
   189		MOVL tls+8(FP), AX
   190		MOVL AX, 8(SP)
   191		MOVL xx+12(FP), AX
   192		MOVL AX, 12(SP)
   193		NACL_SYSCALL(SYS_thread_create)
   194		MOVL AX, ret+16(FP)
   195		RET
   196	
   197	TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
   198		JMP runtime·mstart(SB)
   199	
   200	TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$8
   201		MOVL ts+0(FP), AX
   202		MOVL AX, 0(SP)
   203		MOVL extra+4(FP), AX
   204		MOVL AX, 4(SP)
   205		NACL_SYSCALL(SYS_nanosleep)
   206		MOVL AX, ret+8(FP)
   207		RET
   208	
   209	TEXT runtime·osyield(SB),NOSPLIT,$0
   210		NACL_SYSCALL(SYS_sched_yield)
   211		RET
   212	
   213	TEXT runtime·mmap(SB),NOSPLIT,$32
   214		MOVL	addr+0(FP), AX
   215		MOVL	AX, 0(SP)
   216		MOVL	n+4(FP), AX
   217		MOVL	AX, 4(SP)
   218		MOVL	prot+8(FP), AX
   219		MOVL	AX, 8(SP)
   220		MOVL	flags+12(FP), AX
   221		MOVL	AX, 12(SP)
   222		MOVL	fd+16(FP), AX
   223		MOVL	AX, 16(SP)
   224		MOVL	off+20(FP), AX
   225		MOVL	AX, 24(SP)
   226		MOVL	$0, 28(SP)
   227		LEAL	24(SP), AX
   228		MOVL	AX, 20(SP)
   229		NACL_SYSCALL(SYS_mmap)
   230		CMPL	AX, $-4095
   231		JNA	2(PC)
   232		NEGL	AX
   233		MOVL	AX, ret+24(FP)
   234		RET
   235	
   236	TEXT runtime·walltime(SB),NOSPLIT,$20
   237		MOVL $0, 0(SP) // real time clock
   238		LEAL 8(SP), AX
   239		MOVL AX, 4(SP) // timespec
   240		NACL_SYSCALL(SYS_clock_gettime)
   241		MOVL 8(SP), AX // low 32 sec
   242		MOVL 12(SP), CX // high 32 sec
   243		MOVL 16(SP), BX // nsec
   244	
   245		// sec is in AX, nsec in BX
   246		MOVL	AX, sec_lo+0(FP)
   247		MOVL	CX, sec_hi+4(FP)
   248		MOVL	BX, nsec+8(FP)
   249		RET
   250	
   251	TEXT syscall·now(SB),NOSPLIT,$0
   252		JMP runtime·walltime(SB)
   253	
   254	TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$8
   255		MOVL arg1+0(FP), AX
   256		MOVL AX, 0(SP)
   257		MOVL arg2+4(FP), AX
   258		MOVL AX, 4(SP)
   259		NACL_SYSCALL(SYS_clock_gettime)
   260		MOVL AX, ret+8(FP)
   261		RET
   262		
   263	TEXT runtime·nanotime(SB),NOSPLIT,$20
   264		MOVL $0, 0(SP) // real time clock
   265		LEAL 8(SP), AX
   266		MOVL AX, 4(SP) // timespec
   267		NACL_SYSCALL(SYS_clock_gettime)
   268		MOVL 8(SP), AX // low 32 sec
   269		MOVL 16(SP), BX // nsec
   270	
   271		// sec is in AX, nsec in BX
   272		// convert to DX:AX nsec
   273		MOVL	$1000000000, CX
   274		MULL	CX
   275		ADDL	BX, AX
   276		ADCL	$0, DX
   277	
   278		MOVL	AX, ret_lo+0(FP)
   279		MOVL	DX, ret_hi+4(FP)
   280		RET
   281	
   282	TEXT runtime·setldt(SB),NOSPLIT,$8
   283		MOVL	addr+4(FP), BX // aka base
   284		ADDL	$0x8, BX
   285		MOVL	BX, 0(SP)
   286		NACL_SYSCALL(SYS_tls_init)
   287		RET
   288	
   289	TEXT runtime·sigtramp(SB),NOSPLIT,$0
   290		get_tls(CX)
   291	
   292		// check that g exists
   293		MOVL	g(CX), DI
   294		CMPL	DI, $0
   295		JNE	6(PC)
   296		MOVL	$11, BX
   297		MOVL	$0, 0(SP)
   298		MOVL	$runtime·badsignal(SB), AX
   299		CALL	AX
   300		JMP 	ret
   301	
   302		// save g
   303		MOVL	DI, 20(SP)
   304		
   305		// g = m->gsignal
   306		MOVL	g_m(DI), BX
   307		MOVL	m_gsignal(BX), BX
   308		MOVL	BX, g(CX)
   309		
   310		// copy arguments for sighandler
   311		MOVL	$11, 0(SP) // signal
   312		MOVL	$0, 4(SP) // siginfo
   313		LEAL	ctxt+4(FP), AX
   314		MOVL	AX, 8(SP) // context
   315		MOVL	DI, 12(SP) // g
   316	
   317		CALL	runtime·sighandler(SB)
   318	
   319		// restore g
   320		get_tls(CX)
   321		MOVL	20(SP), BX
   322		MOVL	BX, g(CX)
   323	
   324	ret:
   325		// Enable exceptions again.
   326		NACL_SYSCALL(SYS_exception_clear_flag)
   327	
   328		// NaCl has abdicated its traditional operating system responsibility
   329		// and declined to implement 'sigreturn'. Instead the only way to return
   330		// to the execution of our program is to restore the registers ourselves.
   331		// Unfortunately, that is impossible to do with strict fidelity, because
   332		// there is no way to do the final update of PC that ends the sequence
   333		// without either (1) jumping to a register, in which case the register ends
   334		// holding the PC value instead of its intended value or (2) storing the PC
   335		// on the stack and using RET, which imposes the requirement that SP is
   336		// valid and that is okay to smash the word below it. The second would
   337		// normally be the lesser of the two evils, except that on NaCl, the linker
   338		// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
   339		// we are going to lose a register as a result of the incoming signal.
   340		// Similarly, there is no way to restore EFLAGS; the usual way is to use
   341		// POPFL, but NaCl rejects that instruction. We could inspect the bits and
   342		// execute a sequence of instructions designed to recreate those flag
   343		// settings, but that's a lot of work.
   344		//
   345		// Thankfully, Go's signal handlers never try to return directly to the
   346		// executing code, so all the registers and EFLAGS are dead and can be
   347		// smashed. The only registers that matter are the ones that are setting
   348		// up for the simulated call that the signal handler has created.
   349		// Today those registers are just PC and SP, but in case additional registers
   350		// are relevant in the future (for example DX is the Go func context register)
   351		// we restore as many registers as possible.
   352		// 
   353		// We smash BP, because that's what the linker smashes during RET.
   354		//
   355		LEAL	ctxt+4(FP), BP
   356		ADDL	$64, BP
   357		MOVL	0(BP), AX
   358		MOVL	4(BP), CX
   359		MOVL	8(BP), DX
   360		MOVL	12(BP), BX
   361		MOVL	16(BP), SP
   362		// 20(BP) is saved BP, never to be seen again
   363		MOVL	24(BP), SI
   364		MOVL	28(BP), DI
   365		// 36(BP) is saved EFLAGS, never to be seen again
   366		MOVL	32(BP), BP // saved PC
   367		JMP	BP
   368	
   369	// func getRandomData([]byte)
   370	TEXT runtime·getRandomData(SB),NOSPLIT,$8-12
   371		MOVL arg_base+0(FP), AX
   372		MOVL AX, 0(SP)
   373		MOVL arg_len+4(FP), AX
   374		MOVL AX, 4(SP)
   375		NACL_SYSCALL(SYS_get_random_bytes)
   376		RET

View as plain text