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 AMD64, FreeBSD
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
13TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
14	MOVQ addr+0(FP), DI
15	MOVL mode+8(FP), SI
16	MOVL val+12(FP), DX
17	MOVQ uaddr1+16(FP), R10
18	MOVQ ut+24(FP), R8
19	MOVL $454, AX
20	SYSCALL
21	MOVL	AX, ret+32(FP)
22	RET
23
24TEXT runtime·thr_new(SB),NOSPLIT,$0
25	MOVQ param+0(FP), DI
26	MOVL size+8(FP), SI
27	MOVL $455, AX
28	SYSCALL
29	MOVL	AX, ret+16(FP)
30	RET
31
32TEXT runtime·thr_start(SB),NOSPLIT,$0
33	MOVQ	DI, R13 // m
34
35	// set up FS to point at m->tls
36	LEAQ	m_tls(R13), DI
37	CALL	runtime·settls(SB)	// smashes DI
38
39	// set up m, g
40	get_tls(CX)
41	MOVQ	m_g0(R13), DI
42	MOVQ	R13, g_m(DI)
43	MOVQ	DI, g(CX)
44
45	CALL	runtime·stackcheck(SB)
46	CALL	runtime·mstart(SB)
47
48	MOVQ 0, AX			// crash (not reached)
49
50// Exit the entire program (like C exit)
51TEXT runtime·exit(SB),NOSPLIT,$-8
52	MOVL	code+0(FP), DI		// arg 1 exit status
53	MOVL	$1, AX
54	SYSCALL
55	MOVL	$0xf1, 0xf1  // crash
56	RET
57
58// func exitThread(wait *uint32)
59TEXT runtime·exitThread(SB),NOSPLIT,$0-8
60	MOVQ	wait+0(FP), AX
61	// We're done using the stack.
62	MOVL	$0, (AX)
63	MOVL	$0, DI		// arg 1 long *state
64	MOVL	$431, AX	// thr_exit
65	SYSCALL
66	MOVL	$0xf1, 0xf1  // crash
67	JMP	0(PC)
68
69TEXT runtime·open(SB),NOSPLIT,$-8
70	MOVQ	name+0(FP), DI		// arg 1 pathname
71	MOVL	mode+8(FP), SI		// arg 2 flags
72	MOVL	perm+12(FP), DX		// arg 3 mode
73	MOVL	$5, AX
74	SYSCALL
75	JCC	2(PC)
76	MOVL	$-1, AX
77	MOVL	AX, ret+16(FP)
78	RET
79
80TEXT runtime·closefd(SB),NOSPLIT,$-8
81	MOVL	fd+0(FP), DI		// arg 1 fd
82	MOVL	$6, AX
83	SYSCALL
84	JCC	2(PC)
85	MOVL	$-1, AX
86	MOVL	AX, ret+8(FP)
87	RET
88
89TEXT runtime·read(SB),NOSPLIT,$-8
90	MOVL	fd+0(FP), DI		// arg 1 fd
91	MOVQ	p+8(FP), SI		// arg 2 buf
92	MOVL	n+16(FP), DX		// arg 3 count
93	MOVL	$3, AX
94	SYSCALL
95	JCC	2(PC)
96	NEGQ	AX			// caller expects negative errno
97	MOVL	AX, ret+24(FP)
98	RET
99
100// func pipe() (r, w int32, errno int32)
101TEXT runtime·pipe(SB),NOSPLIT,$0-12
102	MOVL	$42, AX
103	SYSCALL
104	JCC	ok
105	MOVL	$0, r+0(FP)
106	MOVL	$0, w+4(FP)
107	MOVL	AX, errno+8(FP)
108	RET
109ok:
110	MOVL	AX, r+0(FP)
111	MOVL	DX, w+4(FP)
112	MOVL	$0, errno+8(FP)
113	RET
114
115// func pipe2(flags int32) (r, w int32, errno int32)
116TEXT runtime·pipe2(SB),NOSPLIT,$0-20
117	LEAQ	r+8(FP), DI
118	MOVL	flags+0(FP), SI
119	MOVL	$542, AX
120	SYSCALL
121	MOVL	AX, errno+16(FP)
122	RET
123
124TEXT runtime·write1(SB),NOSPLIT,$-8
125	MOVQ	fd+0(FP), DI		// arg 1 fd
126	MOVQ	p+8(FP), SI		// arg 2 buf
127	MOVL	n+16(FP), DX		// arg 3 count
128	MOVL	$4, AX
129	SYSCALL
130	JCC	2(PC)
131	NEGQ	AX			// caller expects negative errno
132	MOVL	AX, ret+24(FP)
133	RET
134
135TEXT runtime·thr_self(SB),NOSPLIT,$0-8
136	// thr_self(&0(FP))
137	LEAQ	ret+0(FP), DI	// arg 1
138	MOVL	$432, AX
139	SYSCALL
140	RET
141
142TEXT runtime·thr_kill(SB),NOSPLIT,$0-16
143	// thr_kill(tid, sig)
144	MOVQ	tid+0(FP), DI	// arg 1 id
145	MOVQ	sig+8(FP), SI	// arg 2 sig
146	MOVL	$433, AX
147	SYSCALL
148	RET
149
150TEXT runtime·raiseproc(SB),NOSPLIT,$0
151	// getpid
152	MOVL	$20, AX
153	SYSCALL
154	// kill(self, sig)
155	MOVQ	AX, DI		// arg 1 pid
156	MOVL	sig+0(FP), SI	// arg 2 sig
157	MOVL	$37, AX
158	SYSCALL
159	RET
160
161TEXT runtime·setitimer(SB), NOSPLIT, $-8
162	MOVL	mode+0(FP), DI
163	MOVQ	new+8(FP), SI
164	MOVQ	old+16(FP), DX
165	MOVL	$83, AX
166	SYSCALL
167	RET
168
169// func fallback_walltime() (sec int64, nsec int32)
170TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
171	MOVL	$232, AX	// clock_gettime
172	MOVQ	$0, DI		// CLOCK_REALTIME
173	LEAQ	8(SP), SI
174	SYSCALL
175	MOVQ	8(SP), AX	// sec
176	MOVQ	16(SP), DX	// nsec
177
178	// sec is in AX, nsec in DX
179	MOVQ	AX, sec+0(FP)
180	MOVL	DX, nsec+8(FP)
181	RET
182
183TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
184	MOVL	$232, AX
185	MOVQ	$4, DI		// CLOCK_MONOTONIC
186	LEAQ	8(SP), SI
187	SYSCALL
188	MOVQ	8(SP), AX	// sec
189	MOVQ	16(SP), DX	// nsec
190
191	// sec is in AX, nsec in DX
192	// return nsec in AX
193	IMULQ	$1000000000, AX
194	ADDQ	DX, AX
195	MOVQ	AX, ret+0(FP)
196	RET
197
198TEXT runtime·asmSigaction(SB),NOSPLIT,$0
199	MOVQ	sig+0(FP), DI		// arg 1 sig
200	MOVQ	new+8(FP), SI		// arg 2 act
201	MOVQ	old+16(FP), DX		// arg 3 oact
202	MOVL	$416, AX
203	SYSCALL
204	JCC	2(PC)
205	MOVL	$-1, AX
206	MOVL	AX, ret+24(FP)
207	RET
208
209TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
210	MOVQ	sig+0(FP), DI		// arg 1 sig
211	MOVQ	new+8(FP), SI		// arg 2 act
212	MOVQ	old+16(FP), DX		// arg 3 oact
213	MOVQ	_cgo_sigaction(SB), AX
214	MOVQ	SP, BX			// callee-saved
215	ANDQ	$~15, SP		// alignment as per amd64 psABI
216	CALL	AX
217	MOVQ	BX, SP
218	MOVL	AX, ret+24(FP)
219	RET
220
221TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
222	MOVQ	fn+0(FP),    AX
223	MOVL	sig+8(FP),   DI
224	MOVQ	info+16(FP), SI
225	MOVQ	ctx+24(FP),  DX
226	PUSHQ	BP
227	MOVQ	SP, BP
228	ANDQ	$~15, SP     // alignment for x86_64 ABI
229	CALL	AX
230	MOVQ	BP, SP
231	POPQ	BP
232	RET
233
234TEXT runtime·sigtramp(SB),NOSPLIT,$72
235	// Save callee-saved C registers, since the caller may be a C signal handler.
236	MOVQ	BX, bx-8(SP)
237	MOVQ	BP, bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
238	MOVQ	R12, r12-24(SP)
239	MOVQ	R13, r13-32(SP)
240	MOVQ	R14, r14-40(SP)
241	MOVQ	R15, r15-48(SP)
242	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
243	// modify them.
244
245	MOVQ	DX, ctx-56(SP)
246	MOVQ	SI, info-64(SP)
247	MOVQ	DI, signum-72(SP)
248	CALL	runtime·sigtrampgo(SB)
249
250	MOVQ	r15-48(SP), R15
251	MOVQ	r14-40(SP), R14
252	MOVQ	r13-32(SP), R13
253	MOVQ	r12-24(SP), R12
254	MOVQ	bp-16(SP),  BP
255	MOVQ	bx-8(SP),   BX
256	RET
257
258// Used instead of sigtramp in programs that use cgo.
259// Arguments from kernel are in DI, SI, DX.
260TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
261	// If no traceback function, do usual sigtramp.
262	MOVQ	runtime·cgoTraceback(SB), AX
263	TESTQ	AX, AX
264	JZ	sigtramp
265
266	// If no traceback support function, which means that
267	// runtime/cgo was not linked in, do usual sigtramp.
268	MOVQ	_cgo_callers(SB), AX
269	TESTQ	AX, AX
270	JZ	sigtramp
271
272	// Figure out if we are currently in a cgo call.
273	// If not, just do usual sigtramp.
274	get_tls(CX)
275	MOVQ	g(CX),AX
276	TESTQ	AX, AX
277	JZ	sigtrampnog     // g == nil
278	MOVQ	g_m(AX), AX
279	TESTQ	AX, AX
280	JZ	sigtramp        // g.m == nil
281	MOVL	m_ncgo(AX), CX
282	TESTL	CX, CX
283	JZ	sigtramp        // g.m.ncgo == 0
284	MOVQ	m_curg(AX), CX
285	TESTQ	CX, CX
286	JZ	sigtramp        // g.m.curg == nil
287	MOVQ	g_syscallsp(CX), CX
288	TESTQ	CX, CX
289	JZ	sigtramp        // g.m.curg.syscallsp == 0
290	MOVQ	m_cgoCallers(AX), R8
291	TESTQ	R8, R8
292	JZ	sigtramp        // g.m.cgoCallers == nil
293	MOVL	m_cgoCallersUse(AX), CX
294	TESTL	CX, CX
295	JNZ	sigtramp	// g.m.cgoCallersUse != 0
296
297	// Jump to a function in runtime/cgo.
298	// That function, written in C, will call the user's traceback
299	// function with proper unwind info, and will then call back here.
300	// The first three arguments, and the fifth, are already in registers.
301	// Set the two remaining arguments now.
302	MOVQ	runtime·cgoTraceback(SB), CX
303	MOVQ	$runtime·sigtramp(SB), R9
304	MOVQ	_cgo_callers(SB), AX
305	JMP	AX
306
307sigtramp:
308	JMP	runtime·sigtramp(SB)
309
310sigtrampnog:
311	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
312	// stack trace.
313	CMPL	DI, $27 // 27 == SIGPROF
314	JNZ	sigtramp
315
316	// Lock sigprofCallersUse.
317	MOVL	$0, AX
318	MOVL	$1, CX
319	MOVQ	$runtime·sigprofCallersUse(SB), R11
320	LOCK
321	CMPXCHGL	CX, 0(R11)
322	JNZ	sigtramp  // Skip stack trace if already locked.
323
324	// Jump to the traceback function in runtime/cgo.
325	// It will call back to sigprofNonGo, which will ignore the
326	// arguments passed in registers.
327	// First three arguments to traceback function are in registers already.
328	MOVQ	runtime·cgoTraceback(SB), CX
329	MOVQ	$runtime·sigprofCallers(SB), R8
330	MOVQ	$runtime·sigprofNonGo(SB), R9
331	MOVQ	_cgo_callers(SB), AX
332	JMP	AX
333
334TEXT runtime·mmap(SB),NOSPLIT,$0
335	MOVQ	addr+0(FP), DI		// arg 1 addr
336	MOVQ	n+8(FP), SI		// arg 2 len
337	MOVL	prot+16(FP), DX		// arg 3 prot
338	MOVL	flags+20(FP), R10		// arg 4 flags
339	MOVL	fd+24(FP), R8		// arg 5 fid
340	MOVL	off+28(FP), R9		// arg 6 offset
341	MOVL	$477, AX
342	SYSCALL
343	JCC	ok
344	MOVQ	$0, p+32(FP)
345	MOVQ	AX, err+40(FP)
346	RET
347ok:
348	MOVQ	AX, p+32(FP)
349	MOVQ	$0, err+40(FP)
350	RET
351
352TEXT runtime·munmap(SB),NOSPLIT,$0
353	MOVQ	addr+0(FP), DI		// arg 1 addr
354	MOVQ	n+8(FP), SI		// arg 2 len
355	MOVL	$73, AX
356	SYSCALL
357	JCC	2(PC)
358	MOVL	$0xf1, 0xf1  // crash
359	RET
360
361TEXT runtime·madvise(SB),NOSPLIT,$0
362	MOVQ	addr+0(FP), DI
363	MOVQ	n+8(FP), SI
364	MOVL	flags+16(FP), DX
365	MOVQ	$75, AX	// madvise
366	SYSCALL
367	JCC	2(PC)
368	MOVL	$-1, AX
369	MOVL	AX, ret+24(FP)
370	RET
371
372TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
373	MOVQ	new+0(FP), DI
374	MOVQ	old+8(FP), SI
375	MOVQ	$53, AX
376	SYSCALL
377	JCC	2(PC)
378	MOVL	$0xf1, 0xf1  // crash
379	RET
380
381TEXT runtime·usleep(SB),NOSPLIT,$16
382	MOVL	$0, DX
383	MOVL	usec+0(FP), AX
384	MOVL	$1000000, CX
385	DIVL	CX
386	MOVQ	AX, 0(SP)		// tv_sec
387	MOVL	$1000, AX
388	MULL	DX
389	MOVQ	AX, 8(SP)		// tv_nsec
390
391	MOVQ	SP, DI			// arg 1 - rqtp
392	MOVQ	$0, SI			// arg 2 - rmtp
393	MOVL	$240, AX		// sys_nanosleep
394	SYSCALL
395	RET
396
397// set tls base to DI
398TEXT runtime·settls(SB),NOSPLIT,$8
399	ADDQ	$8, DI	// adjust for ELF: wants to use -8(FS) for g and m
400	MOVQ	DI, 0(SP)
401	MOVQ	SP, SI
402	MOVQ	$129, DI	// AMD64_SET_FSBASE
403	MOVQ	$165, AX	// sysarch
404	SYSCALL
405	JCC	2(PC)
406	MOVL	$0xf1, 0xf1  // crash
407	RET
408
409TEXT runtime·sysctl(SB),NOSPLIT,$0
410	MOVQ	mib+0(FP), DI		// arg 1 - name
411	MOVL	miblen+8(FP), SI		// arg 2 - namelen
412	MOVQ	out+16(FP), DX		// arg 3 - oldp
413	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
414	MOVQ	dst+32(FP), R8		// arg 5 - newp
415	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
416	MOVQ	$202, AX		// sys___sysctl
417	SYSCALL
418	JCC 4(PC)
419	NEGQ	AX
420	MOVL	AX, ret+48(FP)
421	RET
422	MOVL	$0, AX
423	MOVL	AX, ret+48(FP)
424	RET
425
426TEXT runtime·osyield(SB),NOSPLIT,$-4
427	MOVL	$331, AX		// sys_sched_yield
428	SYSCALL
429	RET
430
431TEXT runtime·sigprocmask(SB),NOSPLIT,$0
432	MOVL	how+0(FP), DI		// arg 1 - how
433	MOVQ	new+8(FP), SI		// arg 2 - set
434	MOVQ	old+16(FP), DX		// arg 3 - oset
435	MOVL	$340, AX		// sys_sigprocmask
436	SYSCALL
437	JAE	2(PC)
438	MOVL	$0xf1, 0xf1  // crash
439	RET
440
441// int32 runtime·kqueue(void);
442TEXT runtime·kqueue(SB),NOSPLIT,$0
443	MOVQ	$0, DI
444	MOVQ	$0, SI
445	MOVQ	$0, DX
446	MOVL	$362, AX
447	SYSCALL
448	JCC	2(PC)
449	NEGQ	AX
450	MOVL	AX, ret+0(FP)
451	RET
452
453// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
454TEXT runtime·kevent(SB),NOSPLIT,$0
455	MOVL	kq+0(FP), DI
456	MOVQ	ch+8(FP), SI
457	MOVL	nch+16(FP), DX
458	MOVQ	ev+24(FP), R10
459	MOVL	nev+32(FP), R8
460	MOVQ	ts+40(FP), R9
461	MOVL	$363, AX
462	SYSCALL
463	JCC	2(PC)
464	NEGQ	AX
465	MOVL	AX, ret+48(FP)
466	RET
467
468// void runtime·closeonexec(int32 fd);
469TEXT runtime·closeonexec(SB),NOSPLIT,$0
470	MOVL	fd+0(FP), DI	// fd
471	MOVQ	$2, SI		// F_SETFD
472	MOVQ	$1, DX		// FD_CLOEXEC
473	MOVL	$92, AX		// fcntl
474	SYSCALL
475	RET
476
477// func runtime·setNonblock(int32 fd)
478TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
479	MOVL    fd+0(FP), DI  // fd
480	MOVQ    $3, SI  // F_GETFL
481	MOVQ    $0, DX
482	MOVL	$92, AX // fcntl
483	SYSCALL
484	MOVL	fd+0(FP), DI // fd
485	MOVQ	$4, SI // F_SETFL
486	MOVQ	$4, DX // O_NONBLOCK
487	ORL	AX, DX
488	MOVL	$92, AX // fcntl
489	SYSCALL
490	RET
491
492// func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
493TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-44
494	MOVQ	level+0(FP), DI
495	MOVQ	which+8(FP), SI
496	MOVQ	id+16(FP), DX
497	MOVQ	size+24(FP), R10
498	MOVQ	mask+32(FP), R8
499	MOVL	$487, AX
500	SYSCALL
501	JCC	2(PC)
502	NEGQ	AX
503	MOVL	AX, ret+40(FP)
504	RET
505