Text file src/runtime/sys_nacl_arm.s
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 runtime·exit(SB),NOSPLIT,$0
14 MOVW code+0(FP), R0
15 NACL_SYSCALL(SYS_exit)
16 RET
17
18 // func exitThread(wait *uint32)
19 TEXT runtime·exitThread(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 runtime·open(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 runtime·closefd(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 runtime·read(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 syscall·naclWrite(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 runtime·write(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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·nacl_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 runtime·mstart_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 runtime·mstart(SB)
169
170 TEXT runtime·nacl_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 runtime·osyield(SB),NOSPLIT,$0
178 NACL_SYSCALL(SYS_sched_yield)
179 RET
180
181 TEXT runtime·mmap(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 runtime·walltime(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 syscall·now(SB),NOSPLIT,$0
218 B runtime·walltime(SB)
219
220 // int64 nanotime(void) so really
221 // void nanotime(int64 *nsec)
222 TEXT runtime·nanotime(SB),NOSPLIT,$16
223 MOVW $0, R0 // real time clock
224 MOVW $4(R13), R1
225 NACL_SYSCALL(SYS_clock_gettime)
226 MOVW 4(R13), R0 // low 32-bit sec
227 MOVW 8(R13), R1 // high 32-bit sec (ignored for now)
228 MOVW 12(R13), R2 // nsec
229 MOVW $1000000000, R3
230 MULLU R0, R3, (R1, R0)
231 MOVW $0, R4
232 ADD.S R2, R0
233 ADC R4, R1
234 MOVW R0, ret_lo+0(FP)
235 MOVW R1, ret_hi+4(FP)
236 RET
237
238 TEXT runtime·sigtramp(SB),NOSPLIT,$80
239 // load g from thread context
240 MOVW $ctxt+-4(FP), R0
241 MOVW (16*4+10*4)(R0), g
242
243 // check that g exists
244 CMP $0, g
245 BNE 4(PC)
246 MOVW $runtime·badsignal2(SB), R11
247 BL (R11)
248 RET
249
250 // save g
251 MOVW g, R3
252 MOVW g, 20(R13)
253
254 // g = m->gsignal
255 MOVW g_m(g), R8
256 MOVW m_gsignal(R8), g
257
258 // copy arguments for call to sighandler
259 MOVW $11, R0
260 MOVW R0, 4(R13) // signal
261 MOVW $0, R0
262 MOVW R0, 8(R13) // siginfo
263 MOVW $ctxt+-4(FP), R0
264 MOVW R0, 12(R13) // context
265 MOVW R3, 16(R13) // g
266
267 BL runtime·sighandler(SB)
268
269 // restore g
270 MOVW 20(R13), g
271
272 // Enable exceptions again.
273 NACL_SYSCALL(SYS_exception_clear_flag)
274
275 // Restore registers as best we can. Impossible to do perfectly.
276 // See comment in sys_nacl_386.s for extended rationale.
277 MOVW $ctxt+-4(FP), R1
278 ADD $64, R1
279 MOVW (0*4)(R1), R0
280 MOVW (2*4)(R1), R2
281 MOVW (3*4)(R1), R3
282 MOVW (4*4)(R1), R4
283 MOVW (5*4)(R1), R5
284 MOVW (6*4)(R1), R6
285 MOVW (7*4)(R1), R7
286 MOVW (8*4)(R1), R8
287 // cannot write to R9
288 MOVW (10*4)(R1), g
289 MOVW (11*4)(R1), R11
290 MOVW (12*4)(R1), R12
291 MOVW (13*4)(R1), R13
292 MOVW (14*4)(R1), R14
293 MOVW (15*4)(R1), R1
294 B (R1)
295
296 nog:
297 MOVW $0, R0
298 RET
299
300 // func getRandomData([]byte)
301 TEXT runtime·getRandomData(SB),NOSPLIT,$0-12
302 MOVW arg_base+0(FP), R0
303 MOVW arg_len+4(FP), R1
304 NACL_SYSCALL(SYS_get_random_bytes)
305 RET
306
307 // Likewise, this is only valid for ARMv7+, but that's okay.
308 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
309 B runtime·armPublicationBarrier(SB)
310
311 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
312 WORD $0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0)
View as plain text