Home | History | Annotate | Download | only in runtime
      1 // Copyright 2014 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 	MOVW	$(0x10000 + ((code)<<5)), R8; BL (R8)
     12 
     13 TEXT runtimeexit(SB),NOSPLIT,$0
     14 	MOVW	code+0(FP), R0
     15 	NACL_SYSCALL(SYS_exit)
     16 	RET
     17 
     18 // func exitThread(wait *uint32)
     19 TEXT runtimeexitThread(SB),NOSPLIT,$4-4
     20 	MOVW wait+0(FP), R0
     21 	// SYS_thread_exit will clear *wait when the stack is free.
     22 	NACL_SYSCALL(SYS_thread_exit)
     23 	JMP 0(PC)
     24 
     25 TEXT runtimeopen(SB),NOSPLIT,$0
     26 	MOVW	name+0(FP), R0
     27 	MOVW	name+0(FP), R1
     28 	MOVW	name+0(FP), R2
     29 	NACL_SYSCALL(SYS_open)
     30 	MOVW	R0, ret+12(FP)
     31 	RET
     32 
     33 TEXT runtimeclosefd(SB),NOSPLIT,$0
     34 	MOVW	fd+0(FP), R0
     35 	NACL_SYSCALL(SYS_close)
     36 	MOVW	R0, ret+4(FP)
     37 	RET
     38 
     39 TEXT runtimeread(SB),NOSPLIT,$0
     40 	MOVW	fd+0(FP), R0
     41 	MOVW	p+4(FP), R1
     42 	MOVW	n+8(FP), R2
     43 	NACL_SYSCALL(SYS_read)
     44 	MOVW	R0, ret+12(FP)
     45 	RET
     46 
     47 // func naclWrite(fd int, b []byte) int
     48 TEXT syscallnaclWrite(SB),NOSPLIT,$0
     49 	MOVW	arg1+0(FP), R0
     50 	MOVW	arg2+4(FP), R1
     51 	MOVW	arg3+8(FP), R2
     52 	NACL_SYSCALL(SYS_write)
     53 	MOVW	R0, ret+16(FP)
     54 	RET
     55 
     56 TEXT runtimewrite(SB),NOSPLIT,$0
     57 	MOVW	fd+0(FP), R0
     58 	MOVW	p+4(FP), R1
     59 	MOVW	n+8(FP), R2
     60 	NACL_SYSCALL(SYS_write)
     61 	MOVW	R0, ret+12(FP)
     62 	RET
     63 
     64 TEXT runtimenacl_exception_stack(SB),NOSPLIT,$0
     65 	MOVW	p+0(FP), R0
     66 	MOVW	size+4(FP), R1
     67 	NACL_SYSCALL(SYS_exception_stack)
     68 	MOVW	R0, ret+8(FP)
     69 	RET
     70 
     71 TEXT runtimenacl_exception_handler(SB),NOSPLIT,$0
     72 	MOVW	fn+0(FP), R0
     73 	MOVW	arg+4(FP), R1
     74 	NACL_SYSCALL(SYS_exception_handler)
     75 	MOVW	R0, ret+8(FP)
     76 	RET
     77 
     78 TEXT runtimenacl_sem_create(SB),NOSPLIT,$0
     79 	MOVW	flag+0(FP), R0
     80 	NACL_SYSCALL(SYS_sem_create)
     81 	MOVW	R0, ret+4(FP)
     82 	RET
     83 
     84 TEXT runtimenacl_sem_wait(SB),NOSPLIT,$0
     85 	MOVW	sem+0(FP), R0
     86 	NACL_SYSCALL(SYS_sem_wait)
     87 	MOVW	R0, ret+4(FP)
     88 	RET
     89 
     90 TEXT runtimenacl_sem_post(SB),NOSPLIT,$0
     91 	MOVW	sem+0(FP), R0
     92 	NACL_SYSCALL(SYS_sem_post)
     93 	MOVW	R0, ret+4(FP)
     94 	RET
     95 
     96 TEXT runtimenacl_mutex_create(SB),NOSPLIT,$0
     97 	MOVW	flag+0(FP), R0
     98 	NACL_SYSCALL(SYS_mutex_create)
     99 	MOVW	R0, ret+4(FP)
    100 	RET
    101 
    102 TEXT runtimenacl_mutex_lock(SB),NOSPLIT,$0
    103 	MOVW	mutex+0(FP), R0
    104 	NACL_SYSCALL(SYS_mutex_lock)
    105 	MOVW	R0, ret+4(FP)
    106 	RET
    107 
    108 TEXT runtimenacl_mutex_trylock(SB),NOSPLIT,$0
    109 	MOVW	mutex+0(FP), R0
    110 	NACL_SYSCALL(SYS_mutex_trylock)
    111 	MOVW	R0, ret+4(FP)
    112 	RET
    113 
    114 TEXT runtimenacl_mutex_unlock(SB),NOSPLIT,$0
    115 	MOVW	mutex+0(FP), R0
    116 	NACL_SYSCALL(SYS_mutex_unlock)
    117 	MOVW	R0, ret+4(FP)
    118 	RET
    119 
    120 TEXT runtimenacl_cond_create(SB),NOSPLIT,$0
    121 	MOVW	flag+0(FP), R0
    122 	NACL_SYSCALL(SYS_cond_create)
    123 	MOVW	R0, ret+4(FP)
    124 	RET
    125 
    126 TEXT runtimenacl_cond_wait(SB),NOSPLIT,$0
    127 	MOVW	cond+0(FP), R0
    128 	MOVW	n+4(FP), R1
    129 	NACL_SYSCALL(SYS_cond_wait)
    130 	MOVW	R0, ret+8(FP)
    131 	RET
    132 
    133 TEXT runtimenacl_cond_signal(SB),NOSPLIT,$0
    134 	MOVW	cond+0(FP), R0
    135 	NACL_SYSCALL(SYS_cond_signal)
    136 	MOVW	R0, ret+4(FP)
    137 	RET
    138 
    139 TEXT runtimenacl_cond_broadcast(SB),NOSPLIT,$0
    140 	MOVW	cond+0(FP), R0
    141 	NACL_SYSCALL(SYS_cond_broadcast)
    142 	MOVW	R0, ret+4(FP)
    143 	RET
    144 
    145 TEXT runtimenacl_cond_timed_wait_abs(SB),NOSPLIT,$0
    146 	MOVW	cond+0(FP), R0
    147 	MOVW	lock+4(FP), R1
    148 	MOVW	ts+8(FP), R2
    149 	NACL_SYSCALL(SYS_cond_timed_wait_abs)
    150 	MOVW	R0, ret+12(FP)
    151 	RET
    152 
    153 TEXT runtimenacl_thread_create(SB),NOSPLIT,$0
    154 	MOVW	fn+0(FP), R0
    155 	MOVW	stk+4(FP), R1
    156 	MOVW	tls+8(FP), R2
    157 	MOVW	xx+12(FP), R3
    158 	NACL_SYSCALL(SYS_thread_create)
    159 	MOVW	R0, ret+16(FP)
    160 	RET
    161 
    162 TEXT runtimemstart_nacl(SB),NOSPLIT,$0
    163 	MOVW	0(R9), R0 // TLS
    164 	MOVW	-8(R0), R1 // g
    165 	MOVW	-4(R0), R2 // m
    166 	MOVW	R2, g_m(R1)
    167 	MOVW	R1, g
    168 	B runtimemstart(SB)
    169 
    170 TEXT runtimenacl_nanosleep(SB),NOSPLIT,$0
    171 	MOVW	ts+0(FP), R0
    172 	MOVW	extra+4(FP), R1
    173 	NACL_SYSCALL(SYS_nanosleep)
    174 	MOVW	R0, ret+8(FP)
    175 	RET
    176 
    177 TEXT runtimeosyield(SB),NOSPLIT,$0
    178 	NACL_SYSCALL(SYS_sched_yield)
    179 	RET
    180 
    181 TEXT runtimemmap(SB),NOSPLIT,$8
    182 	MOVW	addr+0(FP), R0
    183 	MOVW	n+4(FP), R1
    184 	MOVW	prot+8(FP), R2
    185 	MOVW	flags+12(FP), R3
    186 	MOVW	fd+16(FP), R4
    187 	// arg6:offset should be passed as a pointer (to int64)
    188 	MOVW	off+20(FP), R5
    189 	MOVW	R5, 4(R13)
    190 	MOVW	$0, R6
    191 	MOVW	R6, 8(R13)
    192 	MOVW	$4(R13), R5
    193 	MOVM.DB.W [R4,R5], (R13) // arg5 and arg6 are passed on stack
    194 	NACL_SYSCALL(SYS_mmap)
    195 	MOVM.IA.W (R13), [R4, R5]
    196 	CMP	$-4095, R0
    197 	MOVW	$0, R1
    198 	RSB.HI	$0, R0
    199 	MOVW.HI	R0, R1		// if error, put in R1
    200 	MOVW.HI	$0, R0
    201 	MOVW	R0, p+24(FP)
    202 	MOVW	R1, err+28(FP)
    203 	RET
    204 
    205 TEXT runtimewalltime(SB),NOSPLIT,$16
    206 	MOVW	$0, R0 // real time clock
    207 	MOVW	$4(R13), R1
    208 	NACL_SYSCALL(SYS_clock_gettime)
    209 	MOVW	4(R13), R0 // low 32-bit sec
    210 	MOVW	8(R13), R1 // high 32-bit sec
    211 	MOVW	12(R13), R2 // nsec
    212 	MOVW	R0, sec_lo+0(FP)
    213 	MOVW	R1, sec_hi+4(FP)
    214 	MOVW	R2, nsec+8(FP)
    215 	RET
    216 
    217 TEXT syscallnow(SB),NOSPLIT,$0
    218 	B runtimewalltime(SB)
    219 
    220 TEXT runtimenacl_clock_gettime(SB),NOSPLIT,$0
    221 	MOVW	arg1+0(FP), R0
    222 	MOVW	arg2+4(FP), R1
    223 	NACL_SYSCALL(SYS_clock_gettime)
    224 	MOVW	R0, ret+8(FP)
    225 	RET
    226 
    227 // int64 nanotime(void) so really
    228 // void nanotime(int64 *nsec)
    229 TEXT runtimenanotime(SB),NOSPLIT,$16
    230 	MOVW	$0, R0 // real time clock
    231 	MOVW	$4(R13), R1
    232 	NACL_SYSCALL(SYS_clock_gettime)
    233 	MOVW	4(R13), R0 // low 32-bit sec
    234 	MOVW	8(R13), R1 // high 32-bit sec (ignored for now)
    235 	MOVW	12(R13), R2 // nsec
    236 	MOVW	$1000000000, R3
    237 	MULLU	R0, R3, (R1, R0)
    238 	MOVW	$0, R4
    239 	ADD.S	R2, R0
    240 	ADC	R4, R1
    241 	MOVW	R0, ret_lo+0(FP)
    242 	MOVW	R1, ret_hi+4(FP)
    243 	RET
    244 
    245 TEXT runtimesigtramp(SB),NOSPLIT,$80
    246 	// load g from thread context
    247 	MOVW	$ctxt+-4(FP), R0
    248 	MOVW	(16*4+10*4)(R0), g
    249 
    250 	// check that g exists
    251 	CMP	$0, g
    252 	BNE 	4(PC)
    253 	MOVW  	$runtimebadsignal2(SB), R11
    254 	BL	(R11)
    255 	RET
    256 
    257 	// save g
    258 	MOVW	g, R3
    259 	MOVW	g, 20(R13)
    260 
    261 	// g = m->gsignal
    262 	MOVW	g_m(g), R8
    263 	MOVW	m_gsignal(R8), g
    264 
    265 	// copy arguments for call to sighandler
    266 	MOVW	$11, R0
    267 	MOVW	R0, 4(R13) // signal
    268 	MOVW	$0, R0
    269 	MOVW	R0, 8(R13) // siginfo
    270 	MOVW	$ctxt+-4(FP), R0
    271 	MOVW	R0, 12(R13) // context
    272 	MOVW	R3, 16(R13) // g
    273 
    274 	BL	runtimesighandler(SB)
    275 
    276 	// restore g
    277 	MOVW	20(R13), g
    278 
    279 	// Enable exceptions again.
    280 	NACL_SYSCALL(SYS_exception_clear_flag)
    281 
    282 	// Restore registers as best we can. Impossible to do perfectly.
    283 	// See comment in sys_nacl_386.s for extended rationale.
    284 	MOVW	$ctxt+-4(FP), R1
    285 	ADD	$64, R1
    286 	MOVW	(0*4)(R1), R0
    287 	MOVW	(2*4)(R1), R2
    288 	MOVW	(3*4)(R1), R3
    289 	MOVW	(4*4)(R1), R4
    290 	MOVW	(5*4)(R1), R5
    291 	MOVW	(6*4)(R1), R6
    292 	MOVW	(7*4)(R1), R7
    293 	MOVW	(8*4)(R1), R8
    294 	// cannot write to R9
    295 	MOVW	(10*4)(R1), g
    296 	MOVW	(11*4)(R1), R11
    297 	MOVW	(12*4)(R1), R12
    298 	MOVW	(13*4)(R1), R13
    299 	MOVW	(14*4)(R1), R14
    300 	MOVW	(15*4)(R1), R1
    301 	B	(R1)
    302 
    303 nog:
    304 	MOVW	$0, R0
    305 	RET
    306 
    307 TEXT runtimenacl_sysinfo(SB),NOSPLIT,$16
    308 	RET
    309 
    310 // func getRandomData([]byte)
    311 TEXT runtimegetRandomData(SB),NOSPLIT,$0-12
    312 	MOVW arg_base+0(FP), R0
    313 	MOVW arg_len+4(FP), R1
    314 	NACL_SYSCALL(SYS_get_random_bytes)
    315 	RET
    316 
    317 // Likewise, this is only valid for ARMv7+, but that's okay.
    318 TEXT publicationBarrier(SB),NOSPLIT,$-4-0
    319 	B	runtimearmPublicationBarrier(SB)
    320 
    321 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4
    322 	WORD $0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0)
    323