github.com/aloncn/graphics-go@v0.0.1/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  	CMPL	AX, $-4095
   231  	JNA	2(PC)
   232  	NEGL	AX
   233  	MOVL	AX, ret+24(FP)
   234  	RET
   235  
   236  TEXT time·now(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+0(FP)
   247  	MOVL	CX, sec+4(FP)
   248  	MOVL	BX, nsec+8(FP)
   249  	RET
   250  
   251  TEXT syscall·now(SB),NOSPLIT,$0
   252  	JMP time·now(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 buf+0(FP), AX
   372  	MOVL AX, 0(SP)
   373  	MOVL len+4(FP), AX
   374  	MOVL AX, 4(SP)
   375  	NACL_SYSCALL(SYS_get_random_bytes)
   376  	RET