github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/runtime/sys_nacl_386.s (about)

     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  	MOVL	AX, ret+24(FP)
   231  	RET
   232  
   233  TEXT time·now(SB),NOSPLIT,$20
   234  	MOVL $0, 0(SP) // real time clock
   235  	LEAL 8(SP), AX
   236  	MOVL AX, 4(SP) // timespec
   237  	NACL_SYSCALL(SYS_clock_gettime)
   238  	MOVL 8(SP), AX // low 32 sec
   239  	MOVL 12(SP), CX // high 32 sec
   240  	MOVL 16(SP), BX // nsec
   241  
   242  	// sec is in AX, nsec in BX
   243  	MOVL	AX, sec+0(FP)
   244  	MOVL	CX, sec+4(FP)
   245  	MOVL	BX, nsec+8(FP)
   246  	RET
   247  
   248  TEXT syscall·now(SB),NOSPLIT,$0
   249  	JMP time·now(SB)
   250  
   251  TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$8
   252  	MOVL arg1+0(FP), AX
   253  	MOVL AX, 0(SP)
   254  	MOVL arg2+4(FP), AX
   255  	MOVL AX, 4(SP)
   256  	NACL_SYSCALL(SYS_clock_gettime)
   257  	MOVL AX, ret+8(FP)
   258  	RET
   259  	
   260  TEXT runtime·nanotime(SB),NOSPLIT,$20
   261  	MOVL $0, 0(SP) // real time clock
   262  	LEAL 8(SP), AX
   263  	MOVL AX, 4(SP) // timespec
   264  	NACL_SYSCALL(SYS_clock_gettime)
   265  	MOVL 8(SP), AX // low 32 sec
   266  	MOVL 16(SP), BX // nsec
   267  
   268  	// sec is in AX, nsec in BX
   269  	// convert to DX:AX nsec
   270  	MOVL	$1000000000, CX
   271  	MULL	CX
   272  	ADDL	BX, AX
   273  	ADCL	$0, DX
   274  
   275  	MOVL	AX, ret_lo+0(FP)
   276  	MOVL	DX, ret_hi+4(FP)
   277  	RET
   278  
   279  TEXT runtime·setldt(SB),NOSPLIT,$8
   280  	MOVL	addr+4(FP), BX // aka base
   281  	ADDL	$0x8, BX
   282  	MOVL	BX, 0(SP)
   283  	NACL_SYSCALL(SYS_tls_init)
   284  	RET
   285  
   286  TEXT runtime·sigtramp(SB),NOSPLIT,$0
   287  	get_tls(CX)
   288  
   289  	// check that g exists
   290  	MOVL	g(CX), DI
   291  	CMPL	DI, $0
   292  	JNE	6(PC)
   293  	MOVL	$11, BX
   294  	MOVL	$0, 0(SP)
   295  	MOVL	$runtime·badsignal(SB), AX
   296  	CALL	AX
   297  	JMP 	ret
   298  
   299  	// save g
   300  	MOVL	DI, 20(SP)
   301  	
   302  	// g = m->gsignal
   303  	MOVL	g_m(DI), BX
   304  	MOVL	m_gsignal(BX), BX
   305  	MOVL	BX, g(CX)
   306  	
   307  	// copy arguments for sighandler
   308  	MOVL	$11, 0(SP) // signal
   309  	MOVL	$0, 4(SP) // siginfo
   310  	LEAL	ctxt+4(FP), AX
   311  	MOVL	AX, 8(SP) // context
   312  	MOVL	DI, 12(SP) // g
   313  
   314  	CALL	runtime·sighandler(SB)
   315  
   316  	// restore g
   317  	get_tls(CX)
   318  	MOVL	20(SP), BX
   319  	MOVL	BX, g(CX)
   320  
   321  ret:
   322  	// Enable exceptions again.
   323  	NACL_SYSCALL(SYS_exception_clear_flag)
   324  
   325  	// NaCl has abdicated its traditional operating system responsibility
   326  	// and declined to implement 'sigreturn'. Instead the only way to return
   327  	// to the execution of our program is to restore the registers ourselves.
   328  	// Unfortunately, that is impossible to do with strict fidelity, because
   329  	// there is no way to do the final update of PC that ends the sequence
   330  	// without either (1) jumping to a register, in which case the register ends
   331  	// holding the PC value instead of its intended value or (2) storing the PC
   332  	// on the stack and using RET, which imposes the requirement that SP is
   333  	// valid and that is okay to smash the word below it. The second would
   334  	// normally be the lesser of the two evils, except that on NaCl, the linker
   335  	// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
   336  	// we are going to lose a register as a result of the incoming signal.
   337  	// Similarly, there is no way to restore EFLAGS; the usual way is to use
   338  	// POPFL, but NaCl rejects that instruction. We could inspect the bits and
   339  	// execute a sequence of instructions designed to recreate those flag
   340  	// settings, but that's a lot of work.
   341  	//
   342  	// Thankfully, Go's signal handlers never try to return directly to the
   343  	// executing code, so all the registers and EFLAGS are dead and can be
   344  	// smashed. The only registers that matter are the ones that are setting
   345  	// up for the simulated call that the signal handler has created.
   346  	// Today those registers are just PC and SP, but in case additional registers
   347  	// are relevant in the future (for example DX is the Go func context register)
   348  	// we restore as many registers as possible.
   349  	// 
   350  	// We smash BP, because that's what the linker smashes during RET.
   351  	//
   352  	LEAL	ctxt+4(FP), BP
   353  	ADDL	$64, BP
   354  	MOVL	0(BP), AX
   355  	MOVL	4(BP), CX
   356  	MOVL	8(BP), DX
   357  	MOVL	12(BP), BX
   358  	MOVL	16(BP), SP
   359  	// 20(BP) is saved BP, never to be seen again
   360  	MOVL	24(BP), SI
   361  	MOVL	28(BP), DI
   362  	// 36(BP) is saved EFLAGS, never to be seen again
   363  	MOVL	32(BP), BP // saved PC
   364  	JMP	BP
   365  
   366  // func getRandomData([]byte)
   367  TEXT runtime·getRandomData(SB),NOSPLIT,$8-12
   368  	MOVL buf+0(FP), AX
   369  	MOVL AX, 0(SP)
   370  	MOVL len+4(FP), AX
   371  	MOVL AX, 4(SP)
   372  	NACL_SYSCALL(SYS_get_random_bytes)
   373  	RET