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