Text file
src/runtime/sys_openbsd_arm.s
Documentation: runtime
1 // Copyright 2009 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 // System calls and other sys.stuff for ARM, OpenBSD
6 // /usr/src/sys/kern/syscalls.master for syscall numbers.
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define CLOCK_REALTIME $0
14 #define CLOCK_MONOTONIC $3
15
16 // With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions
17 // after the SWI instruction, to allow for a speculative execution
18 // barrier to be placed after the SWI without impacting performance.
19 // For now use hardware no-ops as this works with both older and newer
20 // kernels. After OpenBSD 6.8 is released this should be changed to
21 // speculation barriers.
22 #define NOOP MOVW R0, R0
23 #define INVOKE_SYSCALL \
24 SWI $0; \
25 NOOP; \
26 NOOP
27
28 // mstart_stub is the first function executed on a new thread started by pthread_create.
29 // It just does some low-level setup and then calls mstart.
30 // Note: called with the C calling convention.
31 TEXT runtime·mstart_stub(SB),NOSPLIT,$0
32 // R0 points to the m.
33 // We are already on m's g0 stack.
34
35 // Save callee-save registers.
36 MOVM.DB.W [R4-R11], (R13)
37
38 MOVW m_g0(R0), g
39 BL runtime·save_g(SB)
40
41 BL runtime·mstart(SB)
42
43 // Restore callee-save registers.
44 MOVM.IA.W (R13), [R4-R11]
45
46 // Go is all done with this OS thread.
47 // Tell pthread everything is ok (we never join with this thread, so
48 // the value here doesn't really matter).
49 MOVW $0, R0
50 RET
51
52 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
53 MOVW sig+4(FP), R0
54 MOVW info+8(FP), R1
55 MOVW ctx+12(FP), R2
56 MOVW fn+0(FP), R3
57 MOVW R13, R9
58 SUB $24, R13
59 BIC $0x7, R13 // alignment for ELF ABI
60 BL (R3)
61 MOVW R9, R13
62 RET
63
64 TEXT runtime·sigtramp(SB),NOSPLIT,$0
65 // Reserve space for callee-save registers and arguments.
66 MOVM.DB.W [R4-R11], (R13)
67 SUB $16, R13
68
69 // If called from an external code context, g will not be set.
70 // Save R0, since runtime·load_g will clobber it.
71 MOVW R0, 4(R13) // signum
72 BL runtime·load_g(SB)
73
74 MOVW R1, 8(R13)
75 MOVW R2, 12(R13)
76 BL runtime·sigtrampgo(SB)
77
78 // Restore callee-save registers.
79 ADD $16, R13
80 MOVM.IA.W (R13), [R4-R11]
81
82 RET
83
84 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
85 B runtime·armPublicationBarrier(SB)
86
87 // TODO(jsing): OpenBSD only supports GOARM=7 machines... this
88 // should not be needed, however the linker still allows GOARM=5
89 // on this platform.
90 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
91 MOVM.WP [R1, R2, R3, R12], (R13)
92 MOVW $330, R12 // sys___get_tcb
93 INVOKE_SYSCALL
94 MOVM.IAW (R13), [R1, R2, R3, R12]
95 RET
96
97 // These trampolines help convert from Go calling convention to C calling convention.
98 // They should be called with asmcgocall - note that while asmcgocall does
99 // stack alignment, creation of a frame undoes it again.
100 // A pointer to the arguments is passed in R0.
101 // A single int32 result is returned in R0.
102 // (For more results, make an args/results structure.)
103 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
104 MOVW R13, R9
105 BIC $0x7, R13 // align for ELF ABI
106 MOVW 0(R0), R0 // arg 1 attr
107 CALL libc_pthread_attr_init(SB)
108 MOVW R9, R13
109 RET
110
111 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
112 MOVW R13, R9
113 BIC $0x7, R13 // align for ELF ABI
114 MOVW 0(R0), R0 // arg 1 attr
115 CALL libc_pthread_attr_destroy(SB)
116 MOVW R9, R13
117 RET
118
119 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
120 MOVW R13, R9
121 BIC $0x7, R13 // align for ELF ABI
122 MOVW 4(R0), R1 // arg 2 size
123 MOVW 0(R0), R0 // arg 1 attr
124 CALL libc_pthread_attr_getstacksize(SB)
125 MOVW R9, R13
126 RET
127
128 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
129 MOVW R13, R9
130 BIC $0x7, R13 // align for ELF ABI
131 MOVW 4(R0), R1 // arg 2 state
132 MOVW 0(R0), R0 // arg 1 attr
133 CALL libc_pthread_attr_setdetachstate(SB)
134 MOVW R9, R13
135 RET
136
137 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
138 MOVW R13, R9
139 SUB $16, R13
140 BIC $0x7, R13 // align for ELF ABI
141 MOVW 0(R0), R1 // arg 2 attr
142 MOVW 4(R0), R2 // arg 3 start
143 MOVW 8(R0), R3 // arg 4 arg
144 MOVW R13, R0 // arg 1 &threadid (discarded)
145 CALL libc_pthread_create(SB)
146 MOVW R9, R13
147 RET
148
149 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
150 MOVW R13, R9
151 BIC $0x7, R13 // align for ELF ABI
152 MOVW 4(R0), R1 // arg 2 - signal
153 MOVW $0, R2 // arg 3 - tcb
154 MOVW 0(R0), R0 // arg 1 - tid
155 CALL libc_thrkill(SB)
156 MOVW R9, R13
157 RET
158
159 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
160 MOVW R13, R9
161 SUB $16, R13
162 BIC $0x7, R13 // align for ELF ABI
163 MOVW 4(R0), R1 // arg 2 - clock_id
164 MOVW 8(R0), R2 // arg 3 - abstime
165 MOVW 12(R0), R3 // arg 4 - lock
166 MOVW 16(R0), R4 // arg 5 - abort (on stack)
167 MOVW R4, 0(R13)
168 MOVW 0(R0), R0 // arg 1 - id
169 CALL libc_thrsleep(SB)
170 MOVW R9, R13
171 RET
172
173 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
174 MOVW R13, R9
175 BIC $0x7, R13 // align for ELF ABI
176 MOVW 4(R0), R1 // arg 2 - count
177 MOVW 0(R0), R0 // arg 1 - id
178 CALL libc_thrwakeup(SB)
179 MOVW R9, R13
180 RET
181
182 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
183 MOVW R13, R9
184 BIC $0x7, R13 // align for ELF ABI
185 MOVW 0(R0), R0 // arg 1 exit status
186 BL libc_exit(SB)
187 MOVW $0, R8 // crash on failure
188 MOVW R8, (R8)
189 MOVW R9, R13
190 RET
191
192 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
193 MOVW R13, R9
194 MOVW R0, R8
195 BIC $0x7, R13 // align for ELF ABI
196 BL libc_getthrid(SB)
197 MOVW R0, 0(R8)
198 MOVW R9, R13
199 RET
200
201 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
202 MOVW R13, R9
203 BIC $0x7, R13 // align for ELF ABI
204 MOVW R0, R4
205 BL libc_getpid(SB) // arg 1 pid
206 MOVW R4, R1 // arg 2 signal
207 BL libc_kill(SB)
208 MOVW R9, R13
209 RET
210
211 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
212 MOVW R13, R9
213 BIC $0x7, R13 // align for ELF ABI
214 BL libc_sched_yield(SB)
215 MOVW R9, R13
216 RET
217
218 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
219 MOVW R13, R9
220 SUB $16, R13
221 BIC $0x7, R13 // align for ELF ABI
222 MOVW R0, R8
223 MOVW 4(R0), R1 // arg 2 len
224 MOVW 8(R0), R2 // arg 3 prot
225 MOVW 12(R0), R3 // arg 4 flags
226 MOVW 16(R0), R4 // arg 5 fid (on stack)
227 MOVW R4, 0(R13)
228 MOVW $0, R5 // pad (on stack)
229 MOVW R5, 4(R13)
230 MOVW 20(R0), R6 // arg 6 offset (on stack)
231 MOVW R6, 8(R13) // low 32 bits
232 MOVW $0, R7
233 MOVW R7, 12(R13) // high 32 bits
234 MOVW 0(R0), R0 // arg 1 addr
235 BL libc_mmap(SB)
236 MOVW $0, R1
237 CMP $-1, R0
238 BNE ok
239 BL libc_errno(SB)
240 MOVW (R0), R1 // errno
241 MOVW $0, R0
242 ok:
243 MOVW R0, 24(R8)
244 MOVW R1, 28(R8)
245 MOVW R9, R13
246 RET
247
248 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
249 MOVW R13, R9
250 BIC $0x7, R13 // align for ELF ABI
251 MOVW 4(R0), R1 // arg 2 len
252 MOVW 0(R0), R0 // arg 1 addr
253 BL libc_munmap(SB)
254 CMP $-1, R0
255 BNE 3(PC)
256 MOVW $0, R8 // crash on failure
257 MOVW R8, (R8)
258 MOVW R9, R13
259 RET
260
261 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
262 MOVW R13, R9
263 BIC $0x7, R13 // align for ELF ABI
264 MOVW 4(R0), R1 // arg 2 len
265 MOVW 8(R0), R2 // arg 3 advice
266 MOVW 0(R0), R0 // arg 1 addr
267 BL libc_madvise(SB)
268 // ignore failure - maybe pages are locked
269 MOVW R9, R13
270 RET
271
272 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
273 MOVW R13, R9
274 SUB $8, R13
275 BIC $0x7, R13 // align for ELF ABI
276 MOVW 4(R0), R1 // arg 2 - flags
277 MOVW 8(R0), R2 // arg 3 - mode (vararg, on stack)
278 MOVW R2, 0(R13)
279 MOVW 0(R0), R0 // arg 1 - path
280 MOVW R13, R4
281 BIC $0x7, R13 // align for ELF ABI
282 BL libc_open(SB)
283 MOVW R9, R13
284 RET
285
286 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
287 MOVW R13, R9
288 BIC $0x7, R13 // align for ELF ABI
289 MOVW 0(R0), R0 // arg 1 - fd
290 BL libc_close(SB)
291 MOVW R9, R13
292 RET
293
294 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
295 MOVW R13, R9
296 BIC $0x7, R13 // align for ELF ABI
297 MOVW 4(R0), R1 // arg 2 - buf
298 MOVW 8(R0), R2 // arg 3 - count
299 MOVW 0(R0), R0 // arg 1 - fd
300 BL libc_read(SB)
301 CMP $-1, R0
302 BNE noerr
303 BL libc_errno(SB)
304 MOVW (R0), R0 // errno
305 RSB.CS $0, R0 // caller expects negative errno
306 noerr:
307 MOVW R9, R13
308 RET
309
310 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
311 MOVW R13, R9
312 BIC $0x7, R13 // align for ELF ABI
313 MOVW 4(R0), R1 // arg 2 buf
314 MOVW 8(R0), R2 // arg 3 count
315 MOVW 0(R0), R0 // arg 1 fd
316 BL libc_write(SB)
317 CMP $-1, R0
318 BNE noerr
319 BL libc_errno(SB)
320 MOVW (R0), R0 // errno
321 RSB.CS $0, R0 // caller expects negative errno
322 noerr:
323 MOVW R9, R13
324 RET
325
326 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
327 MOVW R13, R9
328 BIC $0x7, R13 // align for ELF ABI
329 MOVW 4(R0), R1 // arg 2 flags
330 MOVW 0(R0), R0 // arg 1 filedes
331 BL libc_pipe2(SB)
332 CMP $-1, R0
333 BNE 3(PC)
334 BL libc_errno(SB)
335 MOVW (R0), R0 // errno
336 RSB.CS $0, R0 // caller expects negative errno
337 MOVW R9, R13
338 RET
339
340 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
341 MOVW R13, R9
342 BIC $0x7, R13 // align for ELF ABI
343 MOVW 4(R0), R1 // arg 2 new
344 MOVW 8(R0), R2 // arg 3 old
345 MOVW 0(R0), R0 // arg 1 which
346 BL libc_setitimer(SB)
347 MOVW R9, R13
348 RET
349
350 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
351 MOVW R13, R9
352 BIC $0x7, R13 // align for ELF ABI
353 MOVW 0(R0), R0 // arg 1 usec
354 BL libc_usleep(SB)
355 MOVW R9, R13
356 RET
357
358 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
359 MOVW R13, R9
360 SUB $8, R13
361 BIC $0x7, R13 // align for ELF ABI
362 MOVW 4(R0), R1 // arg 2 miblen
363 MOVW 8(R0), R2 // arg 3 out
364 MOVW 12(R0), R3 // arg 4 size
365 MOVW 16(R0), R4 // arg 5 dst (on stack)
366 MOVW R4, 0(R13)
367 MOVW 20(R0), R5 // arg 6 ndst (on stack)
368 MOVW R5, 4(R13)
369 MOVW 0(R0), R0 // arg 1 mib
370 BL libc_sysctl(SB)
371 MOVW R9, R13
372 RET
373
374 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
375 MOVW R13, R9
376 BIC $0x7, R13 // align for ELF ABI
377 BL libc_kqueue(SB)
378 MOVW R9, R13
379 RET
380
381 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
382 MOVW R13, R9
383 SUB $8, R13
384 BIC $0x7, R13 // align for ELF ABI
385 MOVW 4(R0), R1 // arg 2 keventt
386 MOVW 8(R0), R2 // arg 3 nch
387 MOVW 12(R0), R3 // arg 4 ev
388 MOVW 16(R0), R4 // arg 5 nev (on stack)
389 MOVW R4, 0(R13)
390 MOVW 20(R0), R5 // arg 6 ts (on stack)
391 MOVW R5, 4(R13)
392 MOVW 0(R0), R0 // arg 1 kq
393 BL libc_kevent(SB)
394 CMP $-1, R0
395 BNE ok
396 BL libc_errno(SB)
397 MOVW (R0), R0 // errno
398 RSB.CS $0, R0 // caller expects negative errno
399 ok:
400 MOVW R9, R13
401 RET
402
403 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
404 MOVW R13, R9
405 BIC $0x7, R13 // align for ELF ABI
406 MOVW 4(R0), R1 // arg 2 tp
407 MOVW 0(R0), R0 // arg 1 clock_id
408 BL libc_clock_gettime(SB)
409 CMP $-1, R0
410 BNE 3(PC)
411 MOVW $0, R8 // crash on failure
412 MOVW R8, (R8)
413 MOVW R9, R13
414 RET
415
416 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
417 MOVW R13, R9
418 SUB $8, R13
419 BIC $0x7, R13 // align for ELF ABI
420 MOVW 4(R0), R1 // arg 2 cmd
421 MOVW 8(R0), R2 // arg 3 arg (vararg, on stack)
422 MOVW R2, 0(R13)
423 MOVW 0(R0), R0 // arg 1 fd
424 BL libc_fcntl(SB)
425 MOVW R9, R13
426 RET
427
428 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
429 MOVW R13, R9
430 BIC $0x7, R13 // align for ELF ABI
431 MOVW 4(R0), R1 // arg 2 new
432 MOVW 8(R0), R2 // arg 3 old
433 MOVW 0(R0), R0 // arg 1 sig
434 BL libc_sigaction(SB)
435 CMP $-1, R0
436 BNE 3(PC)
437 MOVW $0, R8 // crash on failure
438 MOVW R8, (R8)
439 MOVW R9, R13
440 RET
441
442 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
443 MOVW R13, R9
444 BIC $0x7, R13 // align for ELF ABI
445 MOVW 4(R0), R1 // arg 2 new
446 MOVW 8(R0), R2 // arg 3 old
447 MOVW 0(R0), R0 // arg 1 how
448 BL libc_pthread_sigmask(SB)
449 CMP $-1, R0
450 BNE 3(PC)
451 MOVW $0, R8 // crash on failure
452 MOVW R8, (R8)
453 MOVW R9, R13
454 RET
455
456 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
457 MOVW R13, R9
458 BIC $0x7, R13 // align for ELF ABI
459 MOVW 4(R0), R1 // arg 2 old
460 MOVW 0(R0), R0 // arg 1 new
461 BL libc_sigaltstack(SB)
462 CMP $-1, R0
463 BNE 3(PC)
464 MOVW $0, R8 // crash on failure
465 MOVW R8, (R8)
466 MOVW R9, R13
467 RET
468
469 // syscall calls a function in libc on behalf of the syscall package.
470 // syscall takes a pointer to a struct like:
471 // struct {
472 // fn uintptr
473 // a1 uintptr
474 // a2 uintptr
475 // a3 uintptr
476 // r1 uintptr
477 // r2 uintptr
478 // err uintptr
479 // }
480 // syscall must be called on the g0 stack with the
481 // C calling convention (use libcCall).
482 //
483 // syscall expects a 32-bit result and tests for 32-bit -1
484 // to decide there was an error.
485 TEXT runtime·syscall(SB),NOSPLIT,$0
486 MOVW R13, R9
487 BIC $0x7, R13 // align for ELF ABI
488
489 MOVW R0, R8
490
491 MOVW (0*4)(R8), R7 // fn
492 MOVW (1*4)(R8), R0 // a1
493 MOVW (2*4)(R8), R1 // a2
494 MOVW (3*4)(R8), R2 // a3
495
496 BL (R7)
497
498 MOVW R0, (4*4)(R8) // r1
499 MOVW R1, (5*4)(R8) // r2
500
501 // Standard libc functions return -1 on error and set errno.
502 CMP $-1, R0
503 BNE ok
504
505 // Get error code from libc.
506 BL libc_errno(SB)
507 MOVW (R0), R1
508 MOVW R1, (6*4)(R8) // err
509
510 ok:
511 MOVW $0, R0 // no error (it's ignored anyway)
512 MOVW R9, R13
513 RET
514
515 // syscallX calls a function in libc on behalf of the syscall package.
516 // syscallX takes a pointer to a struct like:
517 // struct {
518 // fn uintptr
519 // a1 uintptr
520 // a2 uintptr
521 // a3 uintptr
522 // r1 uintptr
523 // r2 uintptr
524 // err uintptr
525 // }
526 // syscallX must be called on the g0 stack with the
527 // C calling convention (use libcCall).
528 //
529 // syscallX is like syscall but expects a 64-bit result
530 // and tests for 64-bit -1 to decide there was an error.
531 TEXT runtime·syscallX(SB),NOSPLIT,$0
532 MOVW R13, R9
533 BIC $0x7, R13 // align for ELF ABI
534
535 MOVW R0, R8
536
537 MOVW (0*4)(R8), R7 // fn
538 MOVW (1*4)(R8), R0 // a1
539 MOVW (2*4)(R8), R1 // a2
540 MOVW (3*4)(R8), R2 // a3
541
542 BL (R7)
543
544 MOVW R0, (4*4)(R8) // r1
545 MOVW R1, (5*4)(R8) // r2
546
547 // Standard libc functions return -1 on error and set errno.
548 CMP $-1, R0
549 BNE ok
550 CMP $-1, R1
551 BNE ok
552
553 // Get error code from libc.
554 BL libc_errno(SB)
555 MOVW (R0), R1
556 MOVW R1, (6*4)(R8) // err
557
558 ok:
559 MOVW $0, R0 // no error (it's ignored anyway)
560 MOVW R9, R13
561 RET
562
563 // syscall6 calls a function in libc on behalf of the syscall package.
564 // syscall6 takes a pointer to a struct like:
565 // struct {
566 // fn uintptr
567 // a1 uintptr
568 // a2 uintptr
569 // a3 uintptr
570 // a4 uintptr
571 // a5 uintptr
572 // a6 uintptr
573 // r1 uintptr
574 // r2 uintptr
575 // err uintptr
576 // }
577 // syscall6 must be called on the g0 stack with the
578 // C calling convention (use libcCall).
579 //
580 // syscall6 expects a 32-bit result and tests for 32-bit -1
581 // to decide there was an error.
582 TEXT runtime·syscall6(SB),NOSPLIT,$0
583 MOVW R13, R9
584 SUB $8, R13
585 BIC $0x7, R13 // align for ELF ABI
586
587 MOVW R0, R8
588
589 MOVW (0*4)(R8), R7 // fn
590 MOVW (1*4)(R8), R0 // a1
591 MOVW (2*4)(R8), R1 // a2
592 MOVW (3*4)(R8), R2 // a3
593 MOVW (4*4)(R8), R3 // a4
594 MOVW (5*4)(R8), R4 // a5
595 MOVW R4, 0(R13)
596 MOVW (6*4)(R8), R5 // a6
597 MOVW R5, 4(R13)
598
599 BL (R7)
600
601 MOVW R0, (7*4)(R8) // r1
602 MOVW R1, (8*4)(R8) // r2
603
604 // Standard libc functions return -1 on error and set errno.
605 CMP $-1, R0
606 BNE ok
607
608 // Get error code from libc.
609 BL libc_errno(SB)
610 MOVW (R0), R1
611 MOVW R1, (9*4)(R8) // err
612
613 ok:
614 MOVW $0, R0 // no error (it's ignored anyway)
615 MOVW R9, R13
616 RET
617
618 // syscall6X calls a function in libc on behalf of the syscall package.
619 // syscall6X takes a pointer to a struct like:
620 // struct {
621 // fn uintptr
622 // a1 uintptr
623 // a2 uintptr
624 // a3 uintptr
625 // a4 uintptr
626 // a5 uintptr
627 // a6 uintptr
628 // r1 uintptr
629 // r2 uintptr
630 // err uintptr
631 // }
632 // syscall6X must be called on the g0 stack with the
633 // C calling convention (use libcCall).
634 //
635 // syscall6X is like syscall6 but expects a 64-bit result
636 // and tests for 64-bit -1 to decide there was an error.
637 TEXT runtime·syscall6X(SB),NOSPLIT,$0
638 MOVW R13, R9
639 SUB $8, R13
640 BIC $0x7, R13 // align for ELF ABI
641
642 MOVW R0, R8
643
644 MOVW (0*4)(R8), R7 // fn
645 MOVW (1*4)(R8), R0 // a1
646 MOVW (2*4)(R8), R1 // a2
647 MOVW (3*4)(R8), R2 // a3
648 MOVW (4*4)(R8), R3 // a4
649 MOVW (5*4)(R8), R4 // a5
650 MOVW R4, 0(R13)
651 MOVW (6*4)(R8), R5 // a6
652 MOVW R5, 4(R13)
653
654 BL (R7)
655
656 MOVW R0, (7*4)(R8) // r1
657 MOVW R1, (8*4)(R8) // r2
658
659 // Standard libc functions return -1 on error and set errno.
660 CMP $-1, R0
661 BNE ok
662 CMP $-1, R1
663 BNE ok
664
665 // Get error code from libc.
666 BL libc_errno(SB)
667 MOVW (R0), R1
668 MOVW R1, (9*4)(R8) // err
669
670 ok:
671 MOVW $0, R0 // no error (it's ignored anyway)
672 MOVW R9, R13
673 RET
674
675 // syscall10 calls a function in libc on behalf of the syscall package.
676 // syscall10 takes a pointer to a struct like:
677 // struct {
678 // fn uintptr
679 // a1 uintptr
680 // a2 uintptr
681 // a3 uintptr
682 // a4 uintptr
683 // a5 uintptr
684 // a6 uintptr
685 // a7 uintptr
686 // a8 uintptr
687 // a9 uintptr
688 // a10 uintptr
689 // r1 uintptr
690 // r2 uintptr
691 // err uintptr
692 // }
693 // syscall10 must be called on the g0 stack with the
694 // C calling convention (use libcCall).
695 TEXT runtime·syscall10(SB),NOSPLIT,$0
696 MOVW R13, R9
697 SUB $24, R13
698 BIC $0x7, R13 // align for ELF ABI
699
700 MOVW R0, R8
701
702 MOVW (0*4)(R8), R7 // fn
703 MOVW (1*4)(R8), R0 // a1
704 MOVW (2*4)(R8), R1 // a2
705 MOVW (3*4)(R8), R2 // a3
706 MOVW (4*4)(R8), R3 // a4
707 MOVW (5*4)(R8), R4 // a5
708 MOVW R4, 0(R13)
709 MOVW (6*4)(R8), R5 // a6
710 MOVW R5, 4(R13)
711 MOVW (7*4)(R8), R6 // a7
712 MOVW R6, 8(R13)
713 MOVW (8*4)(R8), R4 // a8
714 MOVW R4, 12(R13)
715 MOVW (9*4)(R8), R5 // a9
716 MOVW R5, 16(R13)
717 MOVW (10*4)(R8), R6 // a10
718 MOVW R6, 20(R13)
719
720 BL (R7)
721
722 MOVW R0, (11*4)(R8) // r1
723 MOVW R1, (12*4)(R8) // r2
724
725 // Standard libc functions return -1 on error and set errno.
726 CMP $-1, R0
727 BNE ok
728
729 // Get error code from libc.
730 BL libc_errno(SB)
731 MOVW (R0), R1
732 MOVW R1, (13*4)(R8) // err
733
734 ok:
735 MOVW $0, R0 // no error (it's ignored anyway)
736 MOVW R9, R13
737 RET
738
739 // syscall10X calls a function in libc on behalf of the syscall package.
740 // syscall10X takes a pointer to a struct like:
741 // struct {
742 // fn uintptr
743 // a1 uintptr
744 // a2 uintptr
745 // a3 uintptr
746 // a4 uintptr
747 // a5 uintptr
748 // a6 uintptr
749 // a7 uintptr
750 // a8 uintptr
751 // a9 uintptr
752 // a10 uintptr
753 // r1 uintptr
754 // r2 uintptr
755 // err uintptr
756 // }
757 // syscall10X must be called on the g0 stack with the
758 // C calling convention (use libcCall).
759 //
760 // syscall10X is like syscall10 but expects a 64-bit result
761 // and tests for 64-bit -1 to decide there was an error.
762 TEXT runtime·syscall10X(SB),NOSPLIT,$0
763 MOVW R13, R9
764 SUB $24, R13
765 BIC $0x7, R13 // align for ELF ABI
766
767 MOVW R0, R8
768
769 MOVW (0*4)(R8), R7 // fn
770 MOVW (1*4)(R8), R0 // a1
771 MOVW (2*4)(R8), R1 // a2
772 MOVW (3*4)(R8), R2 // a3
773 MOVW (4*4)(R8), R3 // a4
774 MOVW (5*4)(R8), R4 // a5
775 MOVW R4, 0(R13)
776 MOVW (6*4)(R8), R5 // a6
777 MOVW R5, 4(R13)
778 MOVW (7*4)(R8), R6 // a7
779 MOVW R6, 8(R13)
780 MOVW (8*4)(R8), R4 // a8
781 MOVW R4, 12(R13)
782 MOVW (9*4)(R8), R5 // a9
783 MOVW R5, 16(R13)
784 MOVW (10*4)(R8), R6 // a10
785 MOVW R6, 20(R13)
786
787 BL (R7)
788
789 MOVW R0, (11*4)(R8) // r1
790 MOVW R1, (12*4)(R8) // r2
791
792 // Standard libc functions return -1 on error and set errno.
793 CMP $-1, R0
794 BNE ok
795 CMP $-1, R1
796 BNE ok
797
798 // Get error code from libc.
799 BL libc_errno(SB)
800 MOVW (R0), R1
801 MOVW R1, (13*4)(R8) // err
802
803 ok:
804 MOVW $0, R0 // no error (it's ignored anyway)
805 MOVW R9, R13
806 RET
807
View as plain text