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//
6// System calls and other sys.stuff for arm64, Linux
7//
8
9#include "go_asm.h"
10#include "go_tls.h"
11#include "textflag.h"
12
13#define AT_FDCWD -100
14
15#define CLOCK_REALTIME 0
16#define CLOCK_MONOTONIC 1
17
18#define SYS_exit		93
19#define SYS_read		63
20#define SYS_write		64
21#define SYS_openat		56
22#define SYS_close		57
23#define SYS_pipe2		59
24#define SYS_fcntl		25
25#define SYS_nanosleep		101
26#define SYS_mmap		222
27#define SYS_munmap		215
28#define SYS_setitimer		103
29#define SYS_clone		220
30#define SYS_sched_yield		124
31#define SYS_rt_sigreturn	139
32#define SYS_rt_sigaction	134
33#define SYS_rt_sigprocmask	135
34#define SYS_sigaltstack		132
35#define SYS_madvise		233
36#define SYS_mincore		232
37#define SYS_getpid		172
38#define SYS_gettid		178
39#define SYS_kill		129
40#define SYS_tgkill		131
41#define SYS_futex		98
42#define SYS_sched_getaffinity	123
43#define SYS_exit_group		94
44#define SYS_epoll_create1	20
45#define SYS_epoll_ctl		21
46#define SYS_epoll_pwait		22
47#define SYS_clock_gettime	113
48#define SYS_faccessat		48
49#define SYS_socket		198
50#define SYS_connect		203
51#define SYS_brk			214
52
53TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
54	MOVW	code+0(FP), R0
55	MOVD	$SYS_exit_group, R8
56	SVC
57	RET
58
59// func exitThread(wait *uint32)
60TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
61	MOVD	wait+0(FP), R0
62	// We're done using the stack.
63	MOVW	$0, R1
64	STLRW	R1, (R0)
65	MOVW	$0, R0	// exit code
66	MOVD	$SYS_exit, R8
67	SVC
68	JMP	0(PC)
69
70TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
71	MOVD	$AT_FDCWD, R0
72	MOVD	name+0(FP), R1
73	MOVW	mode+8(FP), R2
74	MOVW	perm+12(FP), R3
75	MOVD	$SYS_openat, R8
76	SVC
77	CMN	$4095, R0
78	BCC	done
79	MOVW	$-1, R0
80done:
81	MOVW	R0, ret+16(FP)
82	RET
83
84TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
85	MOVW	fd+0(FP), R0
86	MOVD	$SYS_close, R8
87	SVC
88	CMN	$4095, R0
89	BCC	done
90	MOVW	$-1, R0
91done:
92	MOVW	R0, ret+8(FP)
93	RET
94
95TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
96	MOVD	fd+0(FP), R0
97	MOVD	p+8(FP), R1
98	MOVW	n+16(FP), R2
99	MOVD	$SYS_write, R8
100	SVC
101	MOVW	R0, ret+24(FP)
102	RET
103
104TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
105	MOVW	fd+0(FP), R0
106	MOVD	p+8(FP), R1
107	MOVW	n+16(FP), R2
108	MOVD	$SYS_read, R8
109	SVC
110	MOVW	R0, ret+24(FP)
111	RET
112
113// func pipe() (r, w int32, errno int32)
114TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
115	MOVD	$r+0(FP), R0
116	MOVW	$0, R1
117	MOVW	$SYS_pipe2, R8
118	SVC
119	MOVW	R0, errno+8(FP)
120	RET
121
122// func pipe2(flags int32) (r, w int32, errno int32)
123TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
124	MOVD	$r+8(FP), R0
125	MOVW	flags+0(FP), R1
126	MOVW	$SYS_pipe2, R8
127	SVC
128	MOVW	R0, errno+16(FP)
129	RET
130
131TEXT runtime·usleep(SB),NOSPLIT,$24-4
132	MOVWU	usec+0(FP), R3
133	MOVD	R3, R5
134	MOVW	$1000000, R4
135	UDIV	R4, R3
136	MOVD	R3, 8(RSP)
137	MUL	R3, R4
138	SUB	R4, R5
139	MOVW	$1000, R4
140	MUL	R4, R5
141	MOVD	R5, 16(RSP)
142
143	// nanosleep(&ts, 0)
144	ADD	$8, RSP, R0
145	MOVD	$0, R1
146	MOVD	$SYS_nanosleep, R8
147	SVC
148	RET
149
150TEXT runtime·gettid(SB),NOSPLIT,$0-4
151	MOVD	$SYS_gettid, R8
152	SVC
153	MOVW	R0, ret+0(FP)
154	RET
155
156TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
157	MOVD	$SYS_getpid, R8
158	SVC
159	MOVW	R0, R19
160	MOVD	$SYS_gettid, R8
161	SVC
162	MOVW	R0, R1	// arg 2 tid
163	MOVW	R19, R0	// arg 1 pid
164	MOVW	sig+0(FP), R2	// arg 3
165	MOVD	$SYS_tgkill, R8
166	SVC
167	RET
168
169TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
170	MOVD	$SYS_getpid, R8
171	SVC
172	MOVW	R0, R0		// arg 1 pid
173	MOVW	sig+0(FP), R1	// arg 2
174	MOVD	$SYS_kill, R8
175	SVC
176	RET
177
178TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
179	MOVD	$SYS_getpid, R8
180	SVC
181	MOVD	R0, ret+0(FP)
182	RET
183
184TEXT ·tgkill(SB),NOSPLIT,$0-24
185	MOVD	tgid+0(FP), R0
186	MOVD	tid+8(FP), R1
187	MOVD	sig+16(FP), R2
188	MOVD	$SYS_tgkill, R8
189	SVC
190	RET
191
192TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
193	MOVW	mode+0(FP), R0
194	MOVD	new+8(FP), R1
195	MOVD	old+16(FP), R2
196	MOVD	$SYS_setitimer, R8
197	SVC
198	RET
199
200TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
201	MOVD	addr+0(FP), R0
202	MOVD	n+8(FP), R1
203	MOVD	dst+16(FP), R2
204	MOVD	$SYS_mincore, R8
205	SVC
206	MOVW	R0, ret+24(FP)
207	RET
208
209// func walltime1() (sec int64, nsec int32)
210TEXT runtime·walltime1(SB),NOSPLIT,$24-12
211	MOVD	RSP, R20	// R20 is unchanged by C code
212	MOVD	RSP, R1
213
214	MOVD	g_m(g), R21	// R21 = m
215
216	// Set vdsoPC and vdsoSP for SIGPROF traceback.
217	MOVD	LR, m_vdsoPC(R21)
218	MOVD	R20, m_vdsoSP(R21)
219
220	MOVD	m_curg(R21), R0
221	CMP	g, R0
222	BNE	noswitch
223
224	MOVD	m_g0(R21), R3
225	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
226
227noswitch:
228	SUB	$16, R1
229	BIC	$15, R1	// Align for C code
230	MOVD	R1, RSP
231
232	MOVW	$CLOCK_REALTIME, R0
233	MOVD	runtime·vdsoClockgettimeSym(SB), R2
234	CBZ	R2, fallback
235
236	// Store g on gsignal's stack, so if we receive a signal
237	// during VDSO code we can find the g.
238	// If we don't have a signal stack, we won't receive signal,
239	// so don't bother saving g.
240	// When using cgo, we already saved g on TLS, also don't save
241	// g here.
242	// Also don't save g if we are already on the signal stack.
243	// We won't get a nested signal.
244	MOVBU	runtime·iscgo(SB), R22
245	CBNZ	R22, nosaveg
246	MOVD	m_gsignal(R21), R22          // g.m.gsignal
247	CBZ	R22, nosaveg
248	CMP	g, R22
249	BEQ	nosaveg
250	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
251	MOVD	g, (R22)
252
253	BL	(R2)
254
255	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
256
257	B	finish
258
259nosaveg:
260	BL	(R2)
261	B	finish
262
263fallback:
264	MOVD	$SYS_clock_gettime, R8
265	SVC
266
267finish:
268	MOVD	0(RSP), R3	// sec
269	MOVD	8(RSP), R5	// nsec
270
271	MOVD	R20, RSP	// restore SP
272	MOVD	$0, m_vdsoSP(R21)	// clear vdsoSP
273
274	MOVD	R3, sec+0(FP)
275	MOVW	R5, nsec+8(FP)
276	RET
277
278TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
279	MOVD	RSP, R20	// R20 is unchanged by C code
280	MOVD	RSP, R1
281
282	MOVD	g_m(g), R21	// R21 = m
283
284	// Set vdsoPC and vdsoSP for SIGPROF traceback.
285	MOVD	LR, m_vdsoPC(R21)
286	MOVD	R20, m_vdsoSP(R21)
287
288	MOVD	m_curg(R21), R0
289	CMP	g, R0
290	BNE	noswitch
291
292	MOVD	m_g0(R21), R3
293	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
294
295noswitch:
296	SUB	$32, R1
297	BIC	$15, R1
298	MOVD	R1, RSP
299
300	MOVW	$CLOCK_MONOTONIC, R0
301	MOVD	runtime·vdsoClockgettimeSym(SB), R2
302	CBZ	R2, fallback
303
304	// Store g on gsignal's stack, so if we receive a signal
305	// during VDSO code we can find the g.
306	// If we don't have a signal stack, we won't receive signal,
307	// so don't bother saving g.
308	// When using cgo, we already saved g on TLS, also don't save
309	// g here.
310	// Also don't save g if we are already on the signal stack.
311	// We won't get a nested signal.
312	MOVBU	runtime·iscgo(SB), R22
313	CBNZ	R22, nosaveg
314	MOVD	m_gsignal(R21), R22          // g.m.gsignal
315	CBZ	R22, nosaveg
316	CMP	g, R22
317	BEQ	nosaveg
318	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
319	MOVD	g, (R22)
320
321	BL	(R2)
322
323	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
324
325	B	finish
326
327nosaveg:
328	BL	(R2)
329	B	finish
330
331fallback:
332	MOVD	$SYS_clock_gettime, R8
333	SVC
334
335finish:
336	MOVD	0(RSP), R3	// sec
337	MOVD	8(RSP), R5	// nsec
338
339	MOVD	R20, RSP	// restore SP
340	MOVD	$0, m_vdsoSP(R21)	// clear vdsoSP
341
342	// sec is in R3, nsec in R5
343	// return nsec in R3
344	MOVD	$1000000000, R4
345	MUL	R4, R3
346	ADD	R5, R3
347	MOVD	R3, ret+0(FP)
348	RET
349
350TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
351	MOVW	how+0(FP), R0
352	MOVD	new+8(FP), R1
353	MOVD	old+16(FP), R2
354	MOVW	size+24(FP), R3
355	MOVD	$SYS_rt_sigprocmask, R8
356	SVC
357	CMN	$4095, R0
358	BCC	done
359	MOVD	$0, R0
360	MOVD	R0, (R0)	// crash
361done:
362	RET
363
364TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
365	MOVD	sig+0(FP), R0
366	MOVD	new+8(FP), R1
367	MOVD	old+16(FP), R2
368	MOVD	size+24(FP), R3
369	MOVD	$SYS_rt_sigaction, R8
370	SVC
371	MOVW	R0, ret+32(FP)
372	RET
373
374// Call the function stored in _cgo_sigaction using the GCC calling convention.
375TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
376	MOVD	sig+0(FP), R0
377	MOVD	new+8(FP), R1
378	MOVD	old+16(FP), R2
379	MOVD	 _cgo_sigaction(SB), R3
380	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
381	BL	R3
382	ADD	$16, RSP
383	MOVW	R0, ret+24(FP)
384	RET
385
386TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
387	MOVW	sig+8(FP), R0
388	MOVD	info+16(FP), R1
389	MOVD	ctx+24(FP), R2
390	MOVD	fn+0(FP), R11
391	BL	(R11)
392	RET
393
394TEXT runtime·sigtramp(SB),NOSPLIT,$192
395	// Save callee-save registers in the case of signal forwarding.
396	// Please refer to https://golang.org/issue/31827 .
397	MOVD	R19, 8*4(RSP)
398	MOVD	R20, 8*5(RSP)
399	MOVD	R21, 8*6(RSP)
400	MOVD	R22, 8*7(RSP)
401	MOVD	R23, 8*8(RSP)
402	MOVD	R24, 8*9(RSP)
403	MOVD	R25, 8*10(RSP)
404	MOVD	R26, 8*11(RSP)
405	MOVD	R27, 8*12(RSP)
406	MOVD	g, 8*13(RSP)
407	MOVD	R29, 8*14(RSP)
408	FMOVD	F8, 8*15(RSP)
409	FMOVD	F9, 8*16(RSP)
410	FMOVD	F10, 8*17(RSP)
411	FMOVD	F11, 8*18(RSP)
412	FMOVD	F12, 8*19(RSP)
413	FMOVD	F13, 8*20(RSP)
414	FMOVD	F14, 8*21(RSP)
415	FMOVD	F15, 8*22(RSP)
416
417	// this might be called in external code context,
418	// where g is not set.
419	// first save R0, because runtime·load_g will clobber it
420	MOVW	R0, 8(RSP)
421	MOVBU	runtime·iscgo(SB), R0
422	CMP	$0, R0
423	BEQ	2(PC)
424	BL	runtime·load_g(SB)
425
426	MOVD	R1, 16(RSP)
427	MOVD	R2, 24(RSP)
428	MOVD	$runtime·sigtrampgo(SB), R0
429	BL	(R0)
430
431	// Restore callee-save registers.
432	MOVD	8*4(RSP), R19
433	MOVD	8*5(RSP), R20
434	MOVD	8*6(RSP), R21
435	MOVD	8*7(RSP), R22
436	MOVD	8*8(RSP), R23
437	MOVD	8*9(RSP), R24
438	MOVD	8*10(RSP), R25
439	MOVD	8*11(RSP), R26
440	MOVD	8*12(RSP), R27
441	MOVD	8*13(RSP), g
442	MOVD	8*14(RSP), R29
443	FMOVD	8*15(RSP), F8
444	FMOVD	8*16(RSP), F9
445	FMOVD	8*17(RSP), F10
446	FMOVD	8*18(RSP), F11
447	FMOVD	8*19(RSP), F12
448	FMOVD	8*20(RSP), F13
449	FMOVD	8*21(RSP), F14
450	FMOVD	8*22(RSP), F15
451
452	RET
453
454TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
455	MOVD	$runtime·sigtramp(SB), R3
456	B	(R3)
457
458TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
459	MOVD	addr+0(FP), R0
460	MOVD	n+8(FP), R1
461	MOVW	prot+16(FP), R2
462	MOVW	flags+20(FP), R3
463	MOVW	fd+24(FP), R4
464	MOVW	off+28(FP), R5
465
466	MOVD	$SYS_mmap, R8
467	SVC
468	CMN	$4095, R0
469	BCC	ok
470	NEG	R0,R0
471	MOVD	$0, p+32(FP)
472	MOVD	R0, err+40(FP)
473	RET
474ok:
475	MOVD	R0, p+32(FP)
476	MOVD	$0, err+40(FP)
477	RET
478
479// Call the function stored in _cgo_mmap using the GCC calling convention.
480// This must be called on the system stack.
481TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
482	MOVD	addr+0(FP), R0
483	MOVD	n+8(FP), R1
484	MOVW	prot+16(FP), R2
485	MOVW	flags+20(FP), R3
486	MOVW	fd+24(FP), R4
487	MOVW	off+28(FP), R5
488	MOVD	_cgo_mmap(SB), R9
489	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
490	BL	R9
491	ADD	$16, RSP
492	MOVD	R0, ret+32(FP)
493	RET
494
495TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
496	MOVD	addr+0(FP), R0
497	MOVD	n+8(FP), R1
498	MOVD	$SYS_munmap, R8
499	SVC
500	CMN	$4095, R0
501	BCC	cool
502	MOVD	R0, 0xf0(R0)
503cool:
504	RET
505
506// Call the function stored in _cgo_munmap using the GCC calling convention.
507// This must be called on the system stack.
508TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
509	MOVD	addr+0(FP), R0
510	MOVD	n+8(FP), R1
511	MOVD	_cgo_munmap(SB), R9
512	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
513	BL	R9
514	ADD	$16, RSP
515	RET
516
517TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
518	MOVD	addr+0(FP), R0
519	MOVD	n+8(FP), R1
520	MOVW	flags+16(FP), R2
521	MOVD	$SYS_madvise, R8
522	SVC
523	MOVW	R0, ret+24(FP)
524	RET
525
526// int64 futex(int32 *uaddr, int32 op, int32 val,
527//	struct timespec *timeout, int32 *uaddr2, int32 val2);
528TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
529	MOVD	addr+0(FP), R0
530	MOVW	op+8(FP), R1
531	MOVW	val+12(FP), R2
532	MOVD	ts+16(FP), R3
533	MOVD	addr2+24(FP), R4
534	MOVW	val3+32(FP), R5
535	MOVD	$SYS_futex, R8
536	SVC
537	MOVW	R0, ret+40(FP)
538	RET
539
540// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
541TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
542	MOVW	flags+0(FP), R0
543	MOVD	stk+8(FP), R1
544
545	// Copy mp, gp, fn off parent stack for use by child.
546	MOVD	mp+16(FP), R10
547	MOVD	gp+24(FP), R11
548	MOVD	fn+32(FP), R12
549
550	MOVD	R10, -8(R1)
551	MOVD	R11, -16(R1)
552	MOVD	R12, -24(R1)
553	MOVD	$1234, R10
554	MOVD	R10, -32(R1)
555
556	MOVD	$SYS_clone, R8
557	SVC
558
559	// In parent, return.
560	CMP	ZR, R0
561	BEQ	child
562	MOVW	R0, ret+40(FP)
563	RET
564child:
565
566	// In child, on new stack.
567	MOVD	-32(RSP), R10
568	MOVD	$1234, R0
569	CMP	R0, R10
570	BEQ	good
571	MOVD	$0, R0
572	MOVD	R0, (R0)	// crash
573
574good:
575	// Initialize m->procid to Linux tid
576	MOVD	$SYS_gettid, R8
577	SVC
578
579	MOVD	-24(RSP), R12     // fn
580	MOVD	-16(RSP), R11     // g
581	MOVD	-8(RSP), R10      // m
582
583	CMP	$0, R10
584	BEQ	nog
585	CMP	$0, R11
586	BEQ	nog
587
588	MOVD	R0, m_procid(R10)
589
590	// TODO: setup TLS.
591
592	// In child, set up new stack
593	MOVD	R10, g_m(R11)
594	MOVD	R11, g
595	//CALL	runtime·stackcheck(SB)
596
597nog:
598	// Call fn
599	MOVD	R12, R0
600	BL	(R0)
601
602	// It shouldn't return.	 If it does, exit that thread.
603	MOVW	$111, R0
604again:
605	MOVD	$SYS_exit, R8
606	SVC
607	B	again	// keep exiting
608
609TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
610	MOVD	new+0(FP), R0
611	MOVD	old+8(FP), R1
612	MOVD	$SYS_sigaltstack, R8
613	SVC
614	CMN	$4095, R0
615	BCC	ok
616	MOVD	$0, R0
617	MOVD	R0, (R0)	// crash
618ok:
619	RET
620
621TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
622	MOVD	$SYS_sched_yield, R8
623	SVC
624	RET
625
626TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
627	MOVD	pid+0(FP), R0
628	MOVD	len+8(FP), R1
629	MOVD	buf+16(FP), R2
630	MOVD	$SYS_sched_getaffinity, R8
631	SVC
632	MOVW	R0, ret+24(FP)
633	RET
634
635// int32 runtime·epollcreate(int32 size);
636TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
637	MOVW	$0, R0
638	MOVD	$SYS_epoll_create1, R8
639	SVC
640	MOVW	R0, ret+8(FP)
641	RET
642
643// int32 runtime·epollcreate1(int32 flags);
644TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
645	MOVW	flags+0(FP), R0
646	MOVD	$SYS_epoll_create1, R8
647	SVC
648	MOVW	R0, ret+8(FP)
649	RET
650
651// func epollctl(epfd, op, fd int32, ev *epollEvent) int
652TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
653	MOVW	epfd+0(FP), R0
654	MOVW	op+4(FP), R1
655	MOVW	fd+8(FP), R2
656	MOVD	ev+16(FP), R3
657	MOVD	$SYS_epoll_ctl, R8
658	SVC
659	MOVW	R0, ret+24(FP)
660	RET
661
662// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
663TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
664	MOVW	epfd+0(FP), R0
665	MOVD	ev+8(FP), R1
666	MOVW	nev+16(FP), R2
667	MOVW	timeout+20(FP), R3
668	MOVD	$0, R4
669	MOVD	$SYS_epoll_pwait, R8
670	SVC
671	MOVW	R0, ret+24(FP)
672	RET
673
674// void runtime·closeonexec(int32 fd);
675TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
676	MOVW	fd+0(FP), R0  // fd
677	MOVD	$2, R1	// F_SETFD
678	MOVD	$1, R2	// FD_CLOEXEC
679	MOVD	$SYS_fcntl, R8
680	SVC
681	RET
682
683// func runtime·setNonblock(int32 fd)
684TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
685	MOVW	fd+0(FP), R0 // fd
686	MOVD	$3, R1	// F_GETFL
687	MOVD	$0, R2
688	MOVD	$SYS_fcntl, R8
689	SVC
690	MOVD	$0x800, R2 // O_NONBLOCK
691	ORR	R0, R2
692	MOVW	fd+0(FP), R0 // fd
693	MOVD	$4, R1	// F_SETFL
694	MOVD	$SYS_fcntl, R8
695	SVC
696	RET
697
698// int access(const char *name, int mode)
699TEXT runtime·access(SB),NOSPLIT,$0-20
700	MOVD	$AT_FDCWD, R0
701	MOVD	name+0(FP), R1
702	MOVW	mode+8(FP), R2
703	MOVD	$SYS_faccessat, R8
704	SVC
705	MOVW	R0, ret+16(FP)
706	RET
707
708// int connect(int fd, const struct sockaddr *addr, socklen_t len)
709TEXT runtime·connect(SB),NOSPLIT,$0-28
710	MOVW	fd+0(FP), R0
711	MOVD	addr+8(FP), R1
712	MOVW	len+16(FP), R2
713	MOVD	$SYS_connect, R8
714	SVC
715	MOVW	R0, ret+24(FP)
716	RET
717
718// int socket(int domain, int typ, int prot)
719TEXT runtime·socket(SB),NOSPLIT,$0-20
720	MOVW	domain+0(FP), R0
721	MOVW	typ+4(FP), R1
722	MOVW	prot+8(FP), R2
723	MOVD	$SYS_socket, R8
724	SVC
725	MOVW	R0, ret+16(FP)
726	RET
727
728// func sbrk0() uintptr
729TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
730	// Implemented as brk(NULL).
731	MOVD	$0, R0
732	MOVD	$SYS_brk, R8
733	SVC
734	MOVD	R0, ret+0(FP)
735	RET
736
737TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
738	RET
739