1// Copyright 2015 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 mips64 mips64le
7
8//
9// System calls and other sys.stuff for mips64, Linux
10//
11
12#include "go_asm.h"
13#include "go_tls.h"
14#include "textflag.h"
15
16#define SYS_exit		5058
17#define SYS_read		5000
18#define SYS_write		5001
19#define SYS_open		5002
20#define SYS_close		5003
21#define SYS_getpid		5038
22#define SYS_kill		5060
23#define SYS_fcntl		5080
24#define SYS_gettimeofday	5094
25#define SYS_mmap		5009
26#define SYS_munmap		5011
27#define SYS_setitimer		5036
28#define SYS_clone		5055
29#define SYS_newselect		5022
30#define SYS_sched_yield		5023
31#define SYS_rt_sigreturn	5211
32#define SYS_rt_sigaction	5013
33#define SYS_rt_sigprocmask	5014
34#define SYS_sigaltstack		5129
35#define SYS_getrlimit		5095
36#define SYS_madvise		5027
37#define SYS_mincore		5026
38#define SYS_gettid		5178
39#define SYS_tkill		5192
40#define SYS_futex		5194
41#define SYS_sched_getaffinity	5196
42#define SYS_exit_group		5205
43#define SYS_epoll_create	5207
44#define SYS_epoll_ctl		5208
45#define SYS_epoll_wait		5209
46#define SYS_clock_gettime	5222
47#define SYS_epoll_create1	5285
48#define SYS_brk			5012
49
50TEXT runtime·exit(SB),NOSPLIT,$-8-4
51	MOVW	code+0(FP), R4
52	MOVV	$SYS_exit_group, R2
53	SYSCALL
54	RET
55
56// func exitThread(wait *uint32)
57TEXT runtime·exitThread(SB),NOSPLIT,$-8-8
58	MOVV	wait+0(FP), R1
59	// We're done using the stack.
60	MOVW	$0, R2
61	SYNC
62	MOVW	R2, (R1)
63	SYNC
64	MOVW	$0, R4	// exit code
65	MOVV	$SYS_exit, R2
66	SYSCALL
67	JMP	0(PC)
68
69TEXT runtime·open(SB),NOSPLIT,$-8-20
70	MOVV	name+0(FP), R4
71	MOVW	mode+8(FP), R5
72	MOVW	perm+12(FP), R6
73	MOVV	$SYS_open, R2
74	SYSCALL
75	BEQ	R7, 2(PC)
76	MOVW	$-1, R2
77	MOVW	R2, ret+16(FP)
78	RET
79
80TEXT runtime·closefd(SB),NOSPLIT,$-8-12
81	MOVW	fd+0(FP), R4
82	MOVV	$SYS_close, R2
83	SYSCALL
84	BEQ	R7, 2(PC)
85	MOVW	$-1, R2
86	MOVW	R2, ret+8(FP)
87	RET
88
89TEXT runtime·write(SB),NOSPLIT,$-8-28
90	MOVV	fd+0(FP), R4
91	MOVV	p+8(FP), R5
92	MOVW	n+16(FP), R6
93	MOVV	$SYS_write, R2
94	SYSCALL
95	BEQ	R7, 2(PC)
96	MOVW	$-1, R2
97	MOVW	R2, ret+24(FP)
98	RET
99
100TEXT runtime·read(SB),NOSPLIT,$-8-28
101	MOVW	fd+0(FP), R4
102	MOVV	p+8(FP), R5
103	MOVW	n+16(FP), R6
104	MOVV	$SYS_read, R2
105	SYSCALL
106	BEQ	R7, 2(PC)
107	MOVW	$-1, R2
108	MOVW	R2, ret+24(FP)
109	RET
110
111TEXT runtime·getrlimit(SB),NOSPLIT,$-8-20
112	MOVW	kind+0(FP), R4	// _RLIMIT_AS = 6 on linux/mips
113	MOVV	limit+8(FP), R5
114	MOVV	$SYS_getrlimit, R2
115	SYSCALL
116	MOVW	R2, ret+16(FP)
117	RET
118
119TEXT runtime·usleep(SB),NOSPLIT,$16-4
120	MOVWU	usec+0(FP), R3
121	MOVV	R3, R5
122	MOVW	$1000000, R4
123	DIVVU	R4, R3
124	MOVV	LO, R3
125	MOVV	R3, 8(R29)
126	MULVU	R3, R4
127	MOVV	LO, R4
128	SUBVU	R4, R5
129	MOVV	R5, 16(R29)
130
131	// select(0, 0, 0, 0, &tv)
132	MOVW	$0, R4
133	MOVW	$0, R5
134	MOVW	$0, R6
135	MOVW	$0, R7
136	ADDV	$8, R29, R8
137	MOVV	$SYS_newselect, R2
138	SYSCALL
139	RET
140
141TEXT runtime·gettid(SB),NOSPLIT,$0-4
142	MOVV	$SYS_gettid, R2
143	SYSCALL
144	MOVW	R2, ret+0(FP)
145	RET
146
147TEXT runtime·raise(SB),NOSPLIT,$-8
148	MOVV	$SYS_gettid, R2
149	SYSCALL
150	MOVW	R2, R4	// arg 1 tid
151	MOVW	sig+0(FP), R5	// arg 2
152	MOVV	$SYS_tkill, R2
153	SYSCALL
154	RET
155
156TEXT runtime·raiseproc(SB),NOSPLIT,$-8
157	MOVV	$SYS_getpid, R2
158	SYSCALL
159	MOVW	R2, R4	// arg 1 pid
160	MOVW	sig+0(FP), R5	// arg 2
161	MOVV	$SYS_kill, R2
162	SYSCALL
163	RET
164
165TEXT runtime·setitimer(SB),NOSPLIT,$-8-24
166	MOVW	mode+0(FP), R4
167	MOVV	new+8(FP), R5
168	MOVV	old+16(FP), R6
169	MOVV	$SYS_setitimer, R2
170	SYSCALL
171	RET
172
173TEXT runtime·mincore(SB),NOSPLIT,$-8-28
174	MOVV	addr+0(FP), R4
175	MOVV	n+8(FP), R5
176	MOVV	dst+16(FP), R6
177	MOVV	$SYS_mincore, R2
178	SYSCALL
179	SUBVU	R2, R0, R2	// caller expects negative errno
180	MOVW	R2, ret+24(FP)
181	RET
182
183// func walltime() (sec int64, nsec int32)
184TEXT runtime·walltime(SB),NOSPLIT,$16
185	MOVW	$0, R4 // CLOCK_REALTIME
186	MOVV	$0(R29), R5
187	MOVV	$SYS_clock_gettime, R2
188	SYSCALL
189	MOVV	0(R29), R3	// sec
190	MOVV	8(R29), R5	// nsec
191	MOVV	R3, sec+0(FP)
192	MOVW	R5, nsec+8(FP)
193	RET
194
195TEXT runtime·nanotime(SB),NOSPLIT,$16
196	MOVW	$1, R4 // CLOCK_MONOTONIC
197	MOVV	$0(R29), R5
198	MOVV	$SYS_clock_gettime, R2
199	SYSCALL
200	MOVV	0(R29), R3	// sec
201	MOVV	8(R29), R5	// nsec
202	// sec is in R3, nsec in R5
203	// return nsec in R3
204	MOVV	$1000000000, R4
205	MULVU	R4, R3
206	MOVV	LO, R3
207	ADDVU	R5, R3
208	MOVV	R3, ret+0(FP)
209	RET
210
211TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-28
212	MOVW	how+0(FP), R4
213	MOVV	new+8(FP), R5
214	MOVV	old+16(FP), R6
215	MOVW	size+24(FP), R7
216	MOVV	$SYS_rt_sigprocmask, R2
217	SYSCALL
218	BEQ	R7, 2(PC)
219	MOVV	R0, 0xf1(R0)	// crash
220	RET
221
222TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-36
223	MOVV	sig+0(FP), R4
224	MOVV	new+8(FP), R5
225	MOVV	old+16(FP), R6
226	MOVV	size+24(FP), R7
227	MOVV	$SYS_rt_sigaction, R2
228	SYSCALL
229	MOVW	R2, ret+32(FP)
230	RET
231
232TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
233	MOVW	sig+8(FP), R4
234	MOVV	info+16(FP), R5
235	MOVV	ctx+24(FP), R6
236	MOVV	fn+0(FP), R25
237	JAL	(R25)
238	RET
239
240TEXT runtime·sigtramp(SB),NOSPLIT,$64
241	// initialize REGSB = PC&0xffffffff00000000
242	BGEZAL	R0, 1(PC)
243	SRLV	$32, R31, RSB
244	SLLV	$32, RSB
245
246	// this might be called in external code context,
247	// where g is not set.
248	MOVB	runtime·iscgo(SB), R1
249	BEQ	R1, 2(PC)
250	JAL	runtime·load_g(SB)
251
252	MOVW	R4, 8(R29)
253	MOVV	R5, 16(R29)
254	MOVV	R6, 24(R29)
255	MOVV	$runtime·sigtrampgo(SB), R1
256	JAL	(R1)
257	RET
258
259TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
260	JMP	runtime·sigtramp(SB)
261
262TEXT runtime·mmap(SB),NOSPLIT,$-8
263	MOVV	addr+0(FP), R4
264	MOVV	n+8(FP), R5
265	MOVW	prot+16(FP), R6
266	MOVW	flags+20(FP), R7
267	MOVW	fd+24(FP), R8
268	MOVW	off+28(FP), R9
269
270	MOVV	$SYS_mmap, R2
271	SYSCALL
272	BEQ	R7, ok
273	MOVV	$0, p+32(FP)
274	MOVV	R2, err+40(FP)
275	RET
276ok:
277	MOVV	R2, p+32(FP)
278	MOVV	$0, err+40(FP)
279	RET
280
281TEXT runtime·munmap(SB),NOSPLIT,$-8
282	MOVV	addr+0(FP), R4
283	MOVV	n+8(FP), R5
284	MOVV	$SYS_munmap, R2
285	SYSCALL
286	BEQ	R7, 2(PC)
287	MOVV	R0, 0xf3(R0)	// crash
288	RET
289
290TEXT runtime·madvise(SB),NOSPLIT,$-8
291	MOVV	addr+0(FP), R4
292	MOVV	n+8(FP), R5
293	MOVW	flags+16(FP), R6
294	MOVV	$SYS_madvise, R2
295	SYSCALL
296	// ignore failure - maybe pages are locked
297	RET
298
299// int64 futex(int32 *uaddr, int32 op, int32 val,
300//	struct timespec *timeout, int32 *uaddr2, int32 val2);
301TEXT runtime·futex(SB),NOSPLIT,$-8
302	MOVV	addr+0(FP), R4
303	MOVW	op+8(FP), R5
304	MOVW	val+12(FP), R6
305	MOVV	ts+16(FP), R7
306	MOVV	addr2+24(FP), R8
307	MOVW	val3+32(FP), R9
308	MOVV	$SYS_futex, R2
309	SYSCALL
310	MOVW	R2, ret+40(FP)
311	RET
312
313// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
314TEXT runtime·clone(SB),NOSPLIT,$-8
315	MOVW	flags+0(FP), R4
316	MOVV	stk+8(FP), R5
317
318	// Copy mp, gp, fn off parent stack for use by child.
319	// Careful: Linux system call clobbers ???.
320	MOVV	mp+16(FP), R16
321	MOVV	gp+24(FP), R17
322	MOVV	fn+32(FP), R18
323
324	MOVV	R16, -8(R5)
325	MOVV	R17, -16(R5)
326	MOVV	R18, -24(R5)
327	MOVV	$1234, R16
328	MOVV	R16, -32(R5)
329
330	MOVV	$SYS_clone, R2
331	SYSCALL
332
333	// In parent, return.
334	BEQ	R2, 3(PC)
335	MOVW	R2, ret+40(FP)
336	RET
337
338	// In child, on new stack.
339	MOVV	-32(R29), R16
340	MOVV	$1234, R1
341	BEQ	R16, R1, 2(PC)
342	MOVV	R0, 0(R0)
343
344	// Initialize m->procid to Linux tid
345	MOVV	$SYS_gettid, R2
346	SYSCALL
347
348	MOVV	-24(R29), R18		// fn
349	MOVV	-16(R29), R17		// g
350	MOVV	-8(R29), R16		// m
351
352	BEQ	R16, nog
353	BEQ	R17, nog
354
355	MOVV	R2, m_procid(R16)
356
357	// TODO: setup TLS.
358
359	// In child, set up new stack
360	MOVV	R16, g_m(R17)
361	MOVV	R17, g
362	//CALL	runtime·stackcheck(SB)
363
364nog:
365	// Call fn
366	JAL	(R18)
367
368	// It shouldn't return.	 If it does, exit that thread.
369	MOVW	$111, R4
370	MOVV	$SYS_exit, R2
371	SYSCALL
372	JMP	-3(PC)	// keep exiting
373
374TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
375	MOVV	new+0(FP), R4
376	MOVV	old+8(FP), R5
377	MOVV	$SYS_sigaltstack, R2
378	SYSCALL
379	BEQ	R7, 2(PC)
380	MOVV	R0, 0xf1(R0)	// crash
381	RET
382
383TEXT runtime·osyield(SB),NOSPLIT,$-8
384	MOVV	$SYS_sched_yield, R2
385	SYSCALL
386	RET
387
388TEXT runtime·sched_getaffinity(SB),NOSPLIT,$-8
389	MOVV	pid+0(FP), R4
390	MOVV	len+8(FP), R5
391	MOVV	buf+16(FP), R6
392	MOVV	$SYS_sched_getaffinity, R2
393	SYSCALL
394	MOVW	R2, ret+24(FP)
395	RET
396
397// int32 runtime·epollcreate(int32 size);
398TEXT runtime·epollcreate(SB),NOSPLIT,$-8
399	MOVW    size+0(FP), R4
400	MOVV	$SYS_epoll_create, R2
401	SYSCALL
402	MOVW	R2, ret+8(FP)
403	RET
404
405// int32 runtime·epollcreate1(int32 flags);
406TEXT runtime·epollcreate1(SB),NOSPLIT,$-8
407	MOVW	flags+0(FP), R4
408	MOVV	$SYS_epoll_create1, R2
409	SYSCALL
410	MOVW	R2, ret+8(FP)
411	RET
412
413// func epollctl(epfd, op, fd int32, ev *epollEvent) int
414TEXT runtime·epollctl(SB),NOSPLIT,$-8
415	MOVW	epfd+0(FP), R4
416	MOVW	op+4(FP), R5
417	MOVW	fd+8(FP), R6
418	MOVV	ev+16(FP), R7
419	MOVV	$SYS_epoll_ctl, R2
420	SYSCALL
421	MOVW	R2, ret+24(FP)
422	RET
423
424// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
425TEXT runtime·epollwait(SB),NOSPLIT,$-8
426	MOVW	epfd+0(FP), R4
427	MOVV	ev+8(FP), R5
428	MOVW	nev+16(FP), R6
429	MOVW	timeout+20(FP), R7
430	MOVV	$SYS_epoll_wait, R2
431	SYSCALL
432	MOVW	R2, ret+24(FP)
433	RET
434
435// void runtime·closeonexec(int32 fd);
436TEXT runtime·closeonexec(SB),NOSPLIT,$-8
437	MOVW    fd+0(FP), R4  // fd
438	MOVV    $2, R5  // F_SETFD
439	MOVV    $1, R6  // FD_CLOEXEC
440	MOVV	$SYS_fcntl, R2
441	SYSCALL
442	RET
443
444// func sbrk0() uintptr
445TEXT runtime·sbrk0(SB),NOSPLIT,$-8-8
446	// Implemented as brk(NULL).
447	MOVV	$0, R4
448	MOVV	$SYS_brk, R2
449	SYSCALL
450	MOVV	R2, ret+0(FP)
451	RET
452