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