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// +build linux
6// +build ppc64 ppc64le
7
8//
9// System calls and other sys.stuff for ppc64, Linux
10//
11
12#include "go_asm.h"
13#include "go_tls.h"
14#include "textflag.h"
15#include "asm_ppc64x.h"
16
17#define SYS_exit		  1
18#define SYS_read		  3
19#define SYS_write		  4
20#define SYS_open		  5
21#define SYS_close		  6
22#define SYS_getpid		 20
23#define SYS_kill		 37
24#define SYS_pipe		 42
25#define SYS_brk			 45
26#define SYS_fcntl		 55
27#define SYS_mmap		 90
28#define SYS_munmap		 91
29#define SYS_setitimer		104
30#define SYS_clone		120
31#define SYS_sched_yield		158
32#define SYS_nanosleep		162
33#define SYS_rt_sigreturn	172
34#define SYS_rt_sigaction	173
35#define SYS_rt_sigprocmask	174
36#define SYS_sigaltstack		185
37#define SYS_madvise		205
38#define SYS_mincore		206
39#define SYS_gettid		207
40#define SYS_futex		221
41#define SYS_sched_getaffinity	223
42#define SYS_exit_group		234
43#define SYS_epoll_create	236
44#define SYS_epoll_ctl		237
45#define SYS_epoll_wait		238
46#define SYS_clock_gettime	246
47#define SYS_tgkill		250
48#define SYS_epoll_create1	315
49#define SYS_pipe2		317
50
51TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
52	MOVW	code+0(FP), R3
53	SYSCALL	$SYS_exit_group
54	RET
55
56// func exitThread(wait *uint32)
57TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
58	MOVD	wait+0(FP), R1
59	// We're done using the stack.
60	MOVW	$0, R2
61	SYNC
62	MOVW	R2, (R1)
63	MOVW	$0, R3	// exit code
64	SYSCALL	$SYS_exit
65	JMP	0(PC)
66
67TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
68	MOVD	name+0(FP), R3
69	MOVW	mode+8(FP), R4
70	MOVW	perm+12(FP), R5
71	SYSCALL	$SYS_open
72	BVC	2(PC)
73	MOVW	$-1, R3
74	MOVW	R3, ret+16(FP)
75	RET
76
77TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
78	MOVW	fd+0(FP), R3
79	SYSCALL	$SYS_close
80	BVC	2(PC)
81	MOVW	$-1, R3
82	MOVW	R3, ret+8(FP)
83	RET
84
85TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
86	MOVD	fd+0(FP), R3
87	MOVD	p+8(FP), R4
88	MOVW	n+16(FP), R5
89	SYSCALL	$SYS_write
90	BVC	2(PC)
91	NEG	R3	// caller expects negative errno
92	MOVW	R3, ret+24(FP)
93	RET
94
95TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
96	MOVW	fd+0(FP), R3
97	MOVD	p+8(FP), R4
98	MOVW	n+16(FP), R5
99	SYSCALL	$SYS_read
100	BVC	2(PC)
101	NEG	R3	// caller expects negative errno
102	MOVW	R3, ret+24(FP)
103	RET
104
105// func pipe() (r, w int32, errno int32)
106TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
107	ADD	$FIXED_FRAME, R1, R3
108	SYSCALL	$SYS_pipe
109	MOVW	R3, errno+8(FP)
110	RET
111
112// func pipe2(flags int32) (r, w int32, errno int32)
113TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
114	ADD	$FIXED_FRAME+8, R1, R3
115	MOVW	flags+0(FP), R4
116	SYSCALL	$SYS_pipe2
117	MOVW	R3, errno+16(FP)
118	RET
119
120TEXT runtime·usleep(SB),NOSPLIT,$16-4
121	MOVW	usec+0(FP), R3
122	MOVD	R3, R5
123	MOVW	$1000000, R4
124	DIVD	R4, R3
125	MOVD	R3, 8(R1)
126	MOVW	$1000, R4
127	MULLD	R3, R4
128	SUB	R4, R5
129	MOVD	R5, 16(R1)
130
131	// nanosleep(&ts, 0)
132	ADD	$8, R1, R3
133	MOVW	$0, R4
134	SYSCALL	$SYS_nanosleep
135	RET
136
137TEXT runtime·gettid(SB),NOSPLIT,$0-4
138	SYSCALL	$SYS_gettid
139	MOVW	R3, ret+0(FP)
140	RET
141
142TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
143	SYSCALL	$SYS_getpid
144	MOVW	R3, R14
145	SYSCALL	$SYS_gettid
146	MOVW	R3, R4	// arg 2 tid
147	MOVW	R14, R3	// arg 1 pid
148	MOVW	sig+0(FP), R5	// arg 3
149	SYSCALL	$SYS_tgkill
150	RET
151
152TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
153	SYSCALL	$SYS_getpid
154	MOVW	R3, R3	// arg 1 pid
155	MOVW	sig+0(FP), R4	// arg 2
156	SYSCALL	$SYS_kill
157	RET
158
159TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
160	SYSCALL $SYS_getpid
161	MOVD	R3, ret+0(FP)
162	RET
163
164TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
165	MOVD	tgid+0(FP), R3
166	MOVD	tid+8(FP), R4
167	MOVD	sig+16(FP), R5
168	SYSCALL $SYS_tgkill
169	RET
170
171TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
172	MOVW	mode+0(FP), R3
173	MOVD	new+8(FP), R4
174	MOVD	old+16(FP), R5
175	SYSCALL	$SYS_setitimer
176	RET
177
178TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
179	MOVD	addr+0(FP), R3
180	MOVD	n+8(FP), R4
181	MOVD	dst+16(FP), R5
182	SYSCALL	$SYS_mincore
183	NEG	R3		// caller expects negative errno
184	MOVW	R3, ret+24(FP)
185	RET
186
187// func walltime1() (sec int64, nsec int32)
188TEXT runtime·walltime1(SB),NOSPLIT,$16
189	MOVD	R1, R15		// R15 is unchanged by C code
190	MOVD	g_m(g), R21	// R21 = m
191
192	MOVD	$0, R3		// CLOCK_REALTIME
193
194	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
195	CMP	R12, R0
196	BEQ	fallback
197
198	// Set vdsoPC and vdsoSP for SIGPROF traceback.
199	MOVD	LR, R14
200	MOVD	R14, m_vdsoPC(R21)
201	MOVD	R15, m_vdsoSP(R21)
202
203	MOVD	m_curg(R21), R6
204	CMP	g, R6
205	BNE	noswitch
206
207	MOVD	m_g0(R21), R7
208	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
209
210noswitch:
211	SUB	$16, R1			// Space for results
212	RLDICR	$0, R1, $59, R1		// Align for C code
213	MOVD	R12, CTR
214	MOVD	R1, R4
215	BL	(CTR)			// Call from VDSO
216	MOVD	$0, R0			// Restore R0
217	MOVD	R0, m_vdsoSP(R21)	// Clear vdsoSP
218	MOVD	0(R1), R3		// sec
219	MOVD	8(R1), R5		// nsec
220	MOVD	R15, R1			// Restore SP
221
222finish:
223	MOVD	R3, sec+0(FP)
224	MOVW	R5, nsec+8(FP)
225	RET
226
227	// Syscall fallback
228fallback:
229	ADD	$32, R1, R4
230	SYSCALL $SYS_clock_gettime
231	MOVD	32(R1), R3
232	MOVD	40(R1), R5
233	JMP	finish
234
235TEXT runtime·nanotime1(SB),NOSPLIT,$16
236	MOVD	$1, R3		// CLOCK_MONOTONIC
237
238	MOVD	R1, R15		// R15 is unchanged by C code
239	MOVD	g_m(g), R21	// R21 = m
240
241	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
242	CMP	R12, R0
243	BEQ	fallback
244
245	// Set vdsoPC and vdsoSP for SIGPROF traceback.
246	MOVD	LR, R14		// R14 is unchanged by C code
247	MOVD	R14, m_vdsoPC(R21)
248	MOVD	R15, m_vdsoSP(R21)
249
250	MOVD	m_curg(R21), R6
251	CMP	g, R6
252	BNE	noswitch
253
254	MOVD	m_g0(R21), R7
255	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
256
257noswitch:
258	SUB	$16, R1			// Space for results
259	RLDICR	$0, R1, $59, R1		// Align for C code
260	MOVD	R12, CTR
261	MOVD	R1, R4
262	BL	(CTR)			// Call from VDSO
263	MOVD	$0, R0			// Restore R0
264	MOVD	$0, m_vdsoSP(R21)	// Clear vdsoSP
265	MOVD	0(R1), R3		// sec
266	MOVD	8(R1), R5		// nsec
267	MOVD	R15, R1			// Restore SP
268
269finish:
270	// sec is in R3, nsec in R5
271	// return nsec in R3
272	MOVD	$1000000000, R4
273	MULLD	R4, R3
274	ADD	R5, R3
275	MOVD	R3, ret+0(FP)
276	RET
277
278	// Syscall fallback
279fallback:
280	ADD	$32, R1, R4
281	SYSCALL $SYS_clock_gettime
282	MOVD	32(R1), R3
283	MOVD	40(R1), R5
284	JMP	finish
285
286TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
287	MOVW	how+0(FP), R3
288	MOVD	new+8(FP), R4
289	MOVD	old+16(FP), R5
290	MOVW	size+24(FP), R6
291	SYSCALL	$SYS_rt_sigprocmask
292	BVC	2(PC)
293	MOVD	R0, 0xf0(R0)	// crash
294	RET
295
296TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
297	MOVD	sig+0(FP), R3
298	MOVD	new+8(FP), R4
299	MOVD	old+16(FP), R5
300	MOVD	size+24(FP), R6
301	SYSCALL	$SYS_rt_sigaction
302	BVC	2(PC)
303	NEG	R3	// caller expects negative errno
304	MOVW	R3, ret+32(FP)
305	RET
306
307TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
308	MOVW	sig+8(FP), R3
309	MOVD	info+16(FP), R4
310	MOVD	ctx+24(FP), R5
311	MOVD	fn+0(FP), R12
312	MOVD	R12, CTR
313	BL	(CTR)
314	MOVD	24(R1), R2
315	RET
316
317TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
318	RET
319
320#ifdef GOARCH_ppc64le
321// ppc64le doesn't need function descriptors
322TEXT runtime·sigtramp(SB),NOSPLIT,$64
323#else
324// function descriptor for the real sigtramp
325TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
326	DWORD	$sigtramp<>(SB)
327	DWORD	$0
328	DWORD	$0
329TEXT sigtramp<>(SB),NOSPLIT,$64
330#endif
331	// initialize essential registers (just in case)
332	BL	runtime·reginit(SB)
333
334	// this might be called in external code context,
335	// where g is not set.
336	MOVBZ	runtime·iscgo(SB), R6
337	CMP 	R6, $0
338	BEQ	2(PC)
339	BL	runtime·load_g(SB)
340
341	MOVW	R3, FIXED_FRAME+0(R1)
342	MOVD	R4, FIXED_FRAME+8(R1)
343	MOVD	R5, FIXED_FRAME+16(R1)
344	MOVD	$runtime·sigtrampgo(SB), R12
345	MOVD	R12, CTR
346	BL	(CTR)
347	MOVD	24(R1), R2
348	RET
349
350#ifdef GOARCH_ppc64le
351// ppc64le doesn't need function descriptors
352TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
353	// The stack unwinder, presumably written in C, may not be able to
354	// handle Go frame correctly. So, this function is NOFRAME, and we
355	// save/restore LR manually.
356	MOVD	LR, R10
357
358	// We're coming from C code, initialize essential registers.
359	CALL	runtime·reginit(SB)
360
361	// If no traceback function, do usual sigtramp.
362	MOVD	runtime·cgoTraceback(SB), R6
363	CMP	$0, R6
364	BEQ	sigtramp
365
366	// If no traceback support function, which means that
367	// runtime/cgo was not linked in, do usual sigtramp.
368	MOVD	_cgo_callers(SB), R6
369	CMP	$0, R6
370	BEQ	sigtramp
371
372	// Set up g register.
373	CALL	runtime·load_g(SB)
374
375	// Figure out if we are currently in a cgo call.
376	// If not, just do usual sigtramp.
377	CMP	$0, g
378	BEQ	sigtrampnog // g == nil
379	MOVD	g_m(g), R6
380	CMP	$0, R6
381	BEQ	sigtramp    // g.m == nil
382	MOVW	m_ncgo(R6), R7
383	CMPW	$0, R7
384	BEQ	sigtramp    // g.m.ncgo = 0
385	MOVD	m_curg(R6), R7
386	CMP	$0, R7
387	BEQ	sigtramp    // g.m.curg == nil
388	MOVD	g_syscallsp(R7), R7
389	CMP	$0, R7
390	BEQ	sigtramp    // g.m.curg.syscallsp == 0
391	MOVD	m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
392	CMP	$0, R7
393	BEQ	sigtramp    // g.m.cgoCallers == nil
394	MOVW	m_cgoCallersUse(R6), R8
395	CMPW	$0, R8
396	BNE	sigtramp    // g.m.cgoCallersUse != 0
397
398	// Jump to a function in runtime/cgo.
399	// That function, written in C, will call the user's traceback
400	// function with proper unwind info, and will then call back here.
401	// The first three arguments, and the fifth, are already in registers.
402	// Set the two remaining arguments now.
403	MOVD	runtime·cgoTraceback(SB), R6
404	MOVD	$runtime·sigtramp(SB), R8
405	MOVD	_cgo_callers(SB), R12
406	MOVD	R12, CTR
407	MOVD	R10, LR // restore LR
408	JMP	(CTR)
409
410sigtramp:
411	MOVD	R10, LR // restore LR
412	JMP	runtime·sigtramp(SB)
413
414sigtrampnog:
415	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
416	// stack trace.
417	CMPW	R3, $27 // 27 == SIGPROF
418	BNE	sigtramp
419
420	// Lock sigprofCallersUse (cas from 0 to 1).
421	MOVW	$1, R7
422	MOVD	$runtime·sigprofCallersUse(SB), R8
423	SYNC
424	LWAR    (R8), R6
425	CMPW    $0, R6
426	BNE     sigtramp
427	STWCCC  R7, (R8)
428	BNE     -4(PC)
429	ISYNC
430
431	// Jump to the traceback function in runtime/cgo.
432	// It will call back to sigprofNonGo, which will ignore the
433	// arguments passed in registers.
434	// First three arguments to traceback function are in registers already.
435	MOVD	runtime·cgoTraceback(SB), R6
436	MOVD	$runtime·sigprofCallers(SB), R7
437	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R8
438	MOVD	_cgo_callers(SB), R12
439	MOVD	R12, CTR
440	MOVD	R10, LR // restore LR
441	JMP	(CTR)
442#else
443// function descriptor for the real sigtramp
444TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
445	DWORD	$cgoSigtramp<>(SB)
446	DWORD	$0
447	DWORD	$0
448TEXT cgoSigtramp<>(SB),NOSPLIT,$0
449	JMP	sigtramp<>(SB)
450#endif
451
452TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
453	// We're coming from C code, set up essential register, then call sigprofNonGo.
454	CALL	runtime·reginit(SB)
455	CALL	runtime·sigprofNonGo(SB)
456	RET
457
458TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
459	MOVD	addr+0(FP), R3
460	MOVD	n+8(FP), R4
461	MOVW	prot+16(FP), R5
462	MOVW	flags+20(FP), R6
463	MOVW	fd+24(FP), R7
464	MOVW	off+28(FP), R8
465
466	SYSCALL	$SYS_mmap
467	BVC	ok
468	MOVD	$0, p+32(FP)
469	MOVD	R3, err+40(FP)
470	RET
471ok:
472	MOVD	R3, p+32(FP)
473	MOVD	$0, err+40(FP)
474	RET
475
476TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
477	MOVD	addr+0(FP), R3
478	MOVD	n+8(FP), R4
479	SYSCALL	$SYS_munmap
480	BVC	2(PC)
481	MOVD	R0, 0xf0(R0)
482	RET
483
484TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
485	MOVD	addr+0(FP), R3
486	MOVD	n+8(FP), R4
487	MOVW	flags+16(FP), R5
488	SYSCALL	$SYS_madvise
489	MOVW	R3, ret+24(FP)
490	RET
491
492// int64 futex(int32 *uaddr, int32 op, int32 val,
493//	struct timespec *timeout, int32 *uaddr2, int32 val2);
494TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
495	MOVD	addr+0(FP), R3
496	MOVW	op+8(FP), R4
497	MOVW	val+12(FP), R5
498	MOVD	ts+16(FP), R6
499	MOVD	addr2+24(FP), R7
500	MOVW	val3+32(FP), R8
501	SYSCALL	$SYS_futex
502	BVC	2(PC)
503	NEG	R3	// caller expects negative errno
504	MOVW	R3, ret+40(FP)
505	RET
506
507// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
508TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
509	MOVW	flags+0(FP), R3
510	MOVD	stk+8(FP), R4
511
512	// Copy mp, gp, fn off parent stack for use by child.
513	// Careful: Linux system call clobbers ???.
514	MOVD	mp+16(FP), R7
515	MOVD	gp+24(FP), R8
516	MOVD	fn+32(FP), R12
517
518	MOVD	R7, -8(R4)
519	MOVD	R8, -16(R4)
520	MOVD	R12, -24(R4)
521	MOVD	$1234, R7
522	MOVD	R7, -32(R4)
523
524	SYSCALL $SYS_clone
525	BVC	2(PC)
526	NEG	R3	// caller expects negative errno
527
528	// In parent, return.
529	CMP	R3, $0
530	BEQ	3(PC)
531	MOVW	R3, ret+40(FP)
532	RET
533
534	// In child, on new stack.
535	// initialize essential registers
536	BL	runtime·reginit(SB)
537	MOVD	-32(R1), R7
538	CMP	R7, $1234
539	BEQ	2(PC)
540	MOVD	R0, 0(R0)
541
542	// Initialize m->procid to Linux tid
543	SYSCALL $SYS_gettid
544
545	MOVD	-24(R1), R12       // fn
546	MOVD	-16(R1), R8        // g
547	MOVD	-8(R1), R7         // m
548
549	CMP	R7, $0
550	BEQ	nog
551	CMP	R8, $0
552	BEQ	nog
553
554	MOVD	R3, m_procid(R7)
555
556	// TODO: setup TLS.
557
558	// In child, set up new stack
559	MOVD	R7, g_m(R8)
560	MOVD	R8, g
561	//CALL	runtime·stackcheck(SB)
562
563nog:
564	// Call fn
565	MOVD	R12, CTR
566	BL	(CTR)
567
568	// It shouldn't return.	 If it does, exit that thread.
569	MOVW	$111, R3
570	SYSCALL	$SYS_exit
571	BR	-2(PC)	// keep exiting
572
573TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
574	MOVD	new+0(FP), R3
575	MOVD	old+8(FP), R4
576	SYSCALL	$SYS_sigaltstack
577	BVC	2(PC)
578	MOVD	R0, 0xf0(R0)  // crash
579	RET
580
581TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
582	SYSCALL	$SYS_sched_yield
583	RET
584
585TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
586	MOVD	pid+0(FP), R3
587	MOVD	len+8(FP), R4
588	MOVD	buf+16(FP), R5
589	SYSCALL	$SYS_sched_getaffinity
590	BVC	2(PC)
591	NEG	R3	// caller expects negative errno
592	MOVW	R3, ret+24(FP)
593	RET
594
595// int32 runtime·epollcreate(int32 size);
596TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
597	MOVW    size+0(FP), R3
598	SYSCALL	$SYS_epoll_create
599	BVC	2(PC)
600	NEG	R3	// caller expects negative errno
601	MOVW	R3, ret+8(FP)
602	RET
603
604// int32 runtime·epollcreate1(int32 flags);
605TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
606	MOVW	flags+0(FP), R3
607	SYSCALL	$SYS_epoll_create1
608	BVC	2(PC)
609	NEG	R3	// caller expects negative errno
610	MOVW	R3, ret+8(FP)
611	RET
612
613// func epollctl(epfd, op, fd int32, ev *epollEvent) int
614TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
615	MOVW	epfd+0(FP), R3
616	MOVW	op+4(FP), R4
617	MOVW	fd+8(FP), R5
618	MOVD	ev+16(FP), R6
619	SYSCALL	$SYS_epoll_ctl
620	NEG	R3	// caller expects negative errno
621	MOVW	R3, ret+24(FP)
622	RET
623
624// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
625TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
626	MOVW	epfd+0(FP), R3
627	MOVD	ev+8(FP), R4
628	MOVW	nev+16(FP), R5
629	MOVW	timeout+20(FP), R6
630	SYSCALL	$SYS_epoll_wait
631	BVC	2(PC)
632	NEG	R3	// caller expects negative errno
633	MOVW	R3, ret+24(FP)
634	RET
635
636// void runtime·closeonexec(int32 fd);
637TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
638	MOVW    fd+0(FP), R3  // fd
639	MOVD    $2, R4  // F_SETFD
640	MOVD    $1, R5  // FD_CLOEXEC
641	SYSCALL	$SYS_fcntl
642	RET
643
644// func runtime·setNonblock(int32 fd)
645TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
646	MOVW	fd+0(FP), R3 // fd
647	MOVD	$3, R4	// F_GETFL
648	MOVD	$0, R5
649	SYSCALL	$SYS_fcntl
650	OR	$0x800, R3, R5 // O_NONBLOCK
651	MOVW	fd+0(FP), R3 // fd
652	MOVD	$4, R4	// F_SETFL
653	SYSCALL	$SYS_fcntl
654	RET
655
656// func sbrk0() uintptr
657TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
658	// Implemented as brk(NULL).
659	MOVD	$0, R3
660	SYSCALL	$SYS_brk
661	MOVD	R3, ret+0(FP)
662	RET
663
664TEXT runtime·access(SB),$0-20
665	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
666	MOVW	R0, ret+16(FP) // for vet
667	RET
668
669TEXT runtime·connect(SB),$0-28
670	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
671	MOVW	R0, ret+24(FP) // for vet
672	RET
673
674TEXT runtime·socket(SB),$0-20
675	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
676	MOVW	R0, ret+16(FP) // for vet
677	RET
678