Text file
src/runtime/sys_openbsd_arm.s
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 noerr
411 BL libc_errno(SB)
412 MOVW (R0), R0 // errno
413 RSB.CS $0, R0 // caller expects negative errno
414 noerr:
415 MOVW R9, R13
416 RET
417
418 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
419 MOVW R13, R9
420 SUB $8, R13
421 BIC $0x7, R13 // align for ELF ABI
422 MOVW 4(R0), R1 // arg 2 cmd
423 MOVW 8(R0), R2 // arg 3 arg (vararg, on stack)
424 MOVW R2, 0(R13)
425 MOVW 0(R0), R0 // arg 1 fd
426 BL libc_fcntl(SB)
427 MOVW R9, R13
428 RET
429
430 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
431 MOVW R13, R9
432 BIC $0x7, R13 // align for ELF ABI
433 MOVW 4(R0), R1 // arg 2 new
434 MOVW 8(R0), R2 // arg 3 old
435 MOVW 0(R0), R0 // arg 1 sig
436 BL libc_sigaction(SB)
437 CMP $-1, R0
438 BNE 3(PC)
439 MOVW $0, R8 // crash on failure
440 MOVW R8, (R8)
441 MOVW R9, R13
442 RET
443
444 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
445 MOVW R13, R9
446 BIC $0x7, R13 // align for ELF ABI
447 MOVW 4(R0), R1 // arg 2 new
448 MOVW 8(R0), R2 // arg 3 old
449 MOVW 0(R0), R0 // arg 1 how
450 BL libc_pthread_sigmask(SB)
451 CMP $-1, R0
452 BNE 3(PC)
453 MOVW $0, R8 // crash on failure
454 MOVW R8, (R8)
455 MOVW R9, R13
456 RET
457
458 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
459 MOVW R13, R9
460 BIC $0x7, R13 // align for ELF ABI
461 MOVW 4(R0), R1 // arg 2 old
462 MOVW 0(R0), R0 // arg 1 new
463 BL libc_sigaltstack(SB)
464 CMP $-1, R0
465 BNE 3(PC)
466 MOVW $0, R8 // crash on failure
467 MOVW R8, (R8)
468 MOVW R9, R13
469 RET
470
471 // syscall calls a function in libc on behalf of the syscall package.
472 // syscall takes a pointer to a struct like:
473 // struct {
474 // fn uintptr
475 // a1 uintptr
476 // a2 uintptr
477 // a3 uintptr
478 // r1 uintptr
479 // r2 uintptr
480 // err uintptr
481 // }
482 // syscall must be called on the g0 stack with the
483 // C calling convention (use libcCall).
484 //
485 // syscall expects a 32-bit result and tests for 32-bit -1
486 // to decide there was an error.
487 TEXT runtime·syscall(SB),NOSPLIT,$0
488 MOVW R13, R9
489 BIC $0x7, R13 // align for ELF ABI
490
491 MOVW R0, R8
492
493 MOVW (0*4)(R8), R7 // fn
494 MOVW (1*4)(R8), R0 // a1
495 MOVW (2*4)(R8), R1 // a2
496 MOVW (3*4)(R8), R2 // a3
497
498 BL (R7)
499
500 MOVW R0, (4*4)(R8) // r1
501 MOVW R1, (5*4)(R8) // r2
502
503 // Standard libc functions return -1 on error and set errno.
504 CMP $-1, R0
505 BNE ok
506
507 // Get error code from libc.
508 BL libc_errno(SB)
509 MOVW (R0), R1
510 MOVW R1, (6*4)(R8) // err
511
512 ok:
513 MOVW $0, R0 // no error (it's ignored anyway)
514 MOVW R9, R13
515 RET
516
517 // syscallX calls a function in libc on behalf of the syscall package.
518 // syscallX takes a pointer to a struct like:
519 // struct {
520 // fn uintptr
521 // a1 uintptr
522 // a2 uintptr
523 // a3 uintptr
524 // r1 uintptr
525 // r2 uintptr
526 // err uintptr
527 // }
528 // syscallX must be called on the g0 stack with the
529 // C calling convention (use libcCall).
530 //
531 // syscallX is like syscall but expects a 64-bit result
532 // and tests for 64-bit -1 to decide there was an error.
533 TEXT runtime·syscallX(SB),NOSPLIT,$0
534 MOVW R13, R9
535 BIC $0x7, R13 // align for ELF ABI
536
537 MOVW R0, R8
538
539 MOVW (0*4)(R8), R7 // fn
540 MOVW (1*4)(R8), R0 // a1
541 MOVW (2*4)(R8), R1 // a2
542 MOVW (3*4)(R8), R2 // a3
543
544 BL (R7)
545
546 MOVW R0, (4*4)(R8) // r1
547 MOVW R1, (5*4)(R8) // r2
548
549 // Standard libc functions return -1 on error and set errno.
550 CMP $-1, R0
551 BNE ok
552 CMP $-1, R1
553 BNE ok
554
555 // Get error code from libc.
556 BL libc_errno(SB)
557 MOVW (R0), R1
558 MOVW R1, (6*4)(R8) // err
559
560 ok:
561 MOVW $0, R0 // no error (it's ignored anyway)
562 MOVW R9, R13
563 RET
564
565 // syscall6 calls a function in libc on behalf of the syscall package.
566 // syscall6 takes a pointer to a struct like:
567 // struct {
568 // fn uintptr
569 // a1 uintptr
570 // a2 uintptr
571 // a3 uintptr
572 // a4 uintptr
573 // a5 uintptr
574 // a6 uintptr
575 // r1 uintptr
576 // r2 uintptr
577 // err uintptr
578 // }
579 // syscall6 must be called on the g0 stack with the
580 // C calling convention (use libcCall).
581 //
582 // syscall6 expects a 32-bit result and tests for 32-bit -1
583 // to decide there was an error.
584 TEXT runtime·syscall6(SB),NOSPLIT,$0
585 MOVW R13, R9
586 SUB $8, R13
587 BIC $0x7, R13 // align for ELF ABI
588
589 MOVW R0, R8
590
591 MOVW (0*4)(R8), R7 // fn
592 MOVW (1*4)(R8), R0 // a1
593 MOVW (2*4)(R8), R1 // a2
594 MOVW (3*4)(R8), R2 // a3
595 MOVW (4*4)(R8), R3 // a4
596 MOVW (5*4)(R8), R4 // a5
597 MOVW R4, 0(R13)
598 MOVW (6*4)(R8), R5 // a6
599 MOVW R5, 4(R13)
600
601 BL (R7)
602
603 MOVW R0, (7*4)(R8) // r1
604 MOVW R1, (8*4)(R8) // r2
605
606 // Standard libc functions return -1 on error and set errno.
607 CMP $-1, R0
608 BNE ok
609
610 // Get error code from libc.
611 BL libc_errno(SB)
612 MOVW (R0), R1
613 MOVW R1, (9*4)(R8) // err
614
615 ok:
616 MOVW $0, R0 // no error (it's ignored anyway)
617 MOVW R9, R13
618 RET
619
620 // syscall6X calls a function in libc on behalf of the syscall package.
621 // syscall6X takes a pointer to a struct like:
622 // struct {
623 // fn uintptr
624 // a1 uintptr
625 // a2 uintptr
626 // a3 uintptr
627 // a4 uintptr
628 // a5 uintptr
629 // a6 uintptr
630 // r1 uintptr
631 // r2 uintptr
632 // err uintptr
633 // }
634 // syscall6X must be called on the g0 stack with the
635 // C calling convention (use libcCall).
636 //
637 // syscall6X is like syscall6 but expects a 64-bit result
638 // and tests for 64-bit -1 to decide there was an error.
639 TEXT runtime·syscall6X(SB),NOSPLIT,$0
640 MOVW R13, R9
641 SUB $8, R13
642 BIC $0x7, R13 // align for ELF ABI
643
644 MOVW R0, R8
645
646 MOVW (0*4)(R8), R7 // fn
647 MOVW (1*4)(R8), R0 // a1
648 MOVW (2*4)(R8), R1 // a2
649 MOVW (3*4)(R8), R2 // a3
650 MOVW (4*4)(R8), R3 // a4
651 MOVW (5*4)(R8), R4 // a5
652 MOVW R4, 0(R13)
653 MOVW (6*4)(R8), R5 // a6
654 MOVW R5, 4(R13)
655
656 BL (R7)
657
658 MOVW R0, (7*4)(R8) // r1
659 MOVW R1, (8*4)(R8) // r2
660
661 // Standard libc functions return -1 on error and set errno.
662 CMP $-1, R0
663 BNE ok
664 CMP $-1, R1
665 BNE ok
666
667 // Get error code from libc.
668 BL libc_errno(SB)
669 MOVW (R0), R1
670 MOVW R1, (9*4)(R8) // err
671
672 ok:
673 MOVW $0, R0 // no error (it's ignored anyway)
674 MOVW R9, R13
675 RET
676
677 // syscall10 calls a function in libc on behalf of the syscall package.
678 // syscall10 takes a pointer to a struct like:
679 // struct {
680 // fn uintptr
681 // a1 uintptr
682 // a2 uintptr
683 // a3 uintptr
684 // a4 uintptr
685 // a5 uintptr
686 // a6 uintptr
687 // a7 uintptr
688 // a8 uintptr
689 // a9 uintptr
690 // a10 uintptr
691 // r1 uintptr
692 // r2 uintptr
693 // err uintptr
694 // }
695 // syscall10 must be called on the g0 stack with the
696 // C calling convention (use libcCall).
697 TEXT runtime·syscall10(SB),NOSPLIT,$0
698 MOVW R13, R9
699 SUB $24, R13
700 BIC $0x7, R13 // align for ELF ABI
701
702 MOVW R0, R8
703
704 MOVW (0*4)(R8), R7 // fn
705 MOVW (1*4)(R8), R0 // a1
706 MOVW (2*4)(R8), R1 // a2
707 MOVW (3*4)(R8), R2 // a3
708 MOVW (4*4)(R8), R3 // a4
709 MOVW (5*4)(R8), R4 // a5
710 MOVW R4, 0(R13)
711 MOVW (6*4)(R8), R5 // a6
712 MOVW R5, 4(R13)
713 MOVW (7*4)(R8), R6 // a7
714 MOVW R6, 8(R13)
715 MOVW (8*4)(R8), R4 // a8
716 MOVW R4, 12(R13)
717 MOVW (9*4)(R8), R5 // a9
718 MOVW R5, 16(R13)
719 MOVW (10*4)(R8), R6 // a10
720 MOVW R6, 20(R13)
721
722 BL (R7)
723
724 MOVW R0, (11*4)(R8) // r1
725 MOVW R1, (12*4)(R8) // r2
726
727 // Standard libc functions return -1 on error and set errno.
728 CMP $-1, R0
729 BNE ok
730
731 // Get error code from libc.
732 BL libc_errno(SB)
733 MOVW (R0), R1
734 MOVW R1, (13*4)(R8) // err
735
736 ok:
737 MOVW $0, R0 // no error (it's ignored anyway)
738 MOVW R9, R13
739 RET
740
741 // syscall10X calls a function in libc on behalf of the syscall package.
742 // syscall10X takes a pointer to a struct like:
743 // struct {
744 // fn uintptr
745 // a1 uintptr
746 // a2 uintptr
747 // a3 uintptr
748 // a4 uintptr
749 // a5 uintptr
750 // a6 uintptr
751 // a7 uintptr
752 // a8 uintptr
753 // a9 uintptr
754 // a10 uintptr
755 // r1 uintptr
756 // r2 uintptr
757 // err uintptr
758 // }
759 // syscall10X must be called on the g0 stack with the
760 // C calling convention (use libcCall).
761 //
762 // syscall10X is like syscall10 but expects a 64-bit result
763 // and tests for 64-bit -1 to decide there was an error.
764 TEXT runtime·syscall10X(SB),NOSPLIT,$0
765 MOVW R13, R9
766 SUB $24, R13
767 BIC $0x7, R13 // align for ELF ABI
768
769 MOVW R0, R8
770
771 MOVW (0*4)(R8), R7 // fn
772 MOVW (1*4)(R8), R0 // a1
773 MOVW (2*4)(R8), R1 // a2
774 MOVW (3*4)(R8), R2 // a3
775 MOVW (4*4)(R8), R3 // a4
776 MOVW (5*4)(R8), R4 // a5
777 MOVW R4, 0(R13)
778 MOVW (6*4)(R8), R5 // a6
779 MOVW R5, 4(R13)
780 MOVW (7*4)(R8), R6 // a7
781 MOVW R6, 8(R13)
782 MOVW (8*4)(R8), R4 // a8
783 MOVW R4, 12(R13)
784 MOVW (9*4)(R8), R5 // a9
785 MOVW R5, 16(R13)
786 MOVW (10*4)(R8), R6 // a10
787 MOVW R6, 20(R13)
788
789 BL (R7)
790
791 MOVW R0, (11*4)(R8) // r1
792 MOVW R1, (12*4)(R8) // r2
793
794 // Standard libc functions return -1 on error and set errno.
795 CMP $-1, R0
796 BNE ok
797 CMP $-1, R1
798 BNE ok
799
800 // Get error code from libc.
801 BL libc_errno(SB)
802 MOVW (R0), R1
803 MOVW R1, (13*4)(R8) // err
804
805 ok:
806 MOVW $0, R0 // no error (it's ignored anyway)
807 MOVW R9, R13
808 RET
809
View as plain text