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