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 #include "cgo/abi_amd64.h"
13
14 #define CLOCK_REALTIME 0
15 #define CLOCK_MONOTONIC 4
16 #define AMD64_SET_FSBASE 129
17
18 #define SYS_exit 1
19 #define SYS_read 3
20 #define SYS_write 4
21 #define SYS_open 5
22 #define SYS_close 6
23 #define SYS_getpid 20
24 #define SYS_kill 37
25 #define SYS_sigaltstack 53
26 #define SYS_munmap 73
27 #define SYS_madvise 75
28 #define SYS_setitimer 83
29 #define SYS_fcntl 92
30 #define SYS_sysarch 165
31 #define SYS___sysctl 202
32 #define SYS_clock_gettime 232
33 #define SYS_nanosleep 240
34 #define SYS_issetugid 253
35 #define SYS_sched_yield 331
36 #define SYS_sigprocmask 340
37 #define SYS_kqueue 362
38 #define SYS_sigaction 416
39 #define SYS_thr_exit 431
40 #define SYS_thr_self 432
41 #define SYS_thr_kill 433
42 #define SYS__umtx_op 454
43 #define SYS_thr_new 455
44 #define SYS_mmap 477
45 #define SYS_cpuset_getaffinity 487
46 #define SYS_pipe2 542
47 #define SYS_kevent 560
48
49 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
50 MOVQ addr+0(FP), DI
51 MOVL mode+8(FP), SI
52 MOVL val+12(FP), DX
53 MOVQ uaddr1+16(FP), R10
54 MOVQ ut+24(FP), R8
55 MOVL $SYS__umtx_op, AX
56 SYSCALL
57 JCC 2(PC)
58 NEGQ AX
59 MOVL AX, ret+32(FP)
60 RET
61
62 TEXT runtime·thr_new(SB),NOSPLIT,$0
63 MOVQ param+0(FP), DI
64 MOVL size+8(FP), SI
65 MOVL $SYS_thr_new, AX
66 SYSCALL
67 JCC 2(PC)
68 NEGQ AX
69 MOVL AX, ret+16(FP)
70 RET
71
72 TEXT runtime·thr_start(SB),NOSPLIT,$0
73 MOVQ DI, R13 // m
74
75 // set up FS to point at m->tls
76 LEAQ m_tls(R13), DI
77 CALL runtime·settls(SB) // smashes DI
78
79 // set up m, g
80 get_tls(CX)
81 MOVQ m_g0(R13), DI
82 MOVQ R13, g_m(DI)
83 MOVQ DI, g(CX)
84
85 CALL runtime·stackcheck(SB)
86 CALL runtime·mstart(SB)
87
88 MOVQ 0, AX // crash (not reached)
89
90 // Exit the entire program (like C exit)
91 TEXT runtime·exit(SB),NOSPLIT,$-8
92 MOVL code+0(FP), DI // arg 1 exit status
93 MOVL $SYS_exit, AX
94 SYSCALL
95 MOVL $0xf1, 0xf1 // crash
96 RET
97
98 // func exitThread(wait *atomic.uint32)
99 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
100 MOVQ wait+0(FP), AX
101 // We're done using the stack.
102 MOVL $0, (AX)
103 MOVL $0, DI // arg 1 long *state
104 MOVL $SYS_thr_exit, AX
105 SYSCALL
106 MOVL $0xf1, 0xf1 // crash
107 JMP 0(PC)
108
109 TEXT runtime·open(SB),NOSPLIT,$-8
110 MOVQ name+0(FP), DI // arg 1 pathname
111 MOVL mode+8(FP), SI // arg 2 flags
112 MOVL perm+12(FP), DX // arg 3 mode
113 MOVL $SYS_open, AX
114 SYSCALL
115 JCC 2(PC)
116 MOVL $-1, AX
117 MOVL AX, ret+16(FP)
118 RET
119
120 TEXT runtime·closefd(SB),NOSPLIT,$-8
121 MOVL fd+0(FP), DI // arg 1 fd
122 MOVL $SYS_close, AX
123 SYSCALL
124 JCC 2(PC)
125 MOVL $-1, AX
126 MOVL AX, ret+8(FP)
127 RET
128
129 TEXT runtime·read(SB),NOSPLIT,$-8
130 MOVL fd+0(FP), DI // arg 1 fd
131 MOVQ p+8(FP), SI // arg 2 buf
132 MOVL n+16(FP), DX // arg 3 count
133 MOVL $SYS_read, AX
134 SYSCALL
135 JCC 2(PC)
136 NEGQ AX // caller expects negative errno
137 MOVL AX, ret+24(FP)
138 RET
139
140 // func pipe2(flags int32) (r, w int32, errno int32)
141 TEXT runtime·pipe2(SB),NOSPLIT,$0-20
142 LEAQ r+8(FP), DI
143 MOVL flags+0(FP), SI
144 MOVL $SYS_pipe2, AX
145 SYSCALL
146 JCC 2(PC)
147 NEGQ AX
148 MOVL AX, errno+16(FP)
149 RET
150
151 TEXT runtime·write1(SB),NOSPLIT,$-8
152 MOVQ fd+0(FP), DI // arg 1 fd
153 MOVQ p+8(FP), SI // arg 2 buf
154 MOVL n+16(FP), DX // arg 3 count
155 MOVL $SYS_write, AX
156 SYSCALL
157 JCC 2(PC)
158 NEGQ AX // caller expects negative errno
159 MOVL AX, ret+24(FP)
160 RET
161
162 TEXT runtime·thr_self(SB),NOSPLIT,$0-8
163 // thr_self(&0(FP))
164 LEAQ ret+0(FP), DI // arg 1
165 MOVL $SYS_thr_self, AX
166 SYSCALL
167 RET
168
169 TEXT runtime·thr_kill(SB),NOSPLIT,$0-16
170 // thr_kill(tid, sig)
171 MOVQ tid+0(FP), DI // arg 1 id
172 MOVQ sig+8(FP), SI // arg 2 sig
173 MOVL $SYS_thr_kill, AX
174 SYSCALL
175 RET
176
177 TEXT runtime·raiseproc(SB),NOSPLIT,$0
178 // getpid
179 MOVL $SYS_getpid, AX
180 SYSCALL
181 // kill(self, sig)
182 MOVQ AX, DI // arg 1 pid
183 MOVL sig+0(FP), SI // arg 2 sig
184 MOVL $SYS_kill, AX
185 SYSCALL
186 RET
187
188 TEXT runtime·setitimer(SB), NOSPLIT, $-8
189 MOVL mode+0(FP), DI
190 MOVQ new+8(FP), SI
191 MOVQ old+16(FP), DX
192 MOVL $SYS_setitimer, AX
193 SYSCALL
194 RET
195
196 // func fallback_walltime() (sec int64, nsec int32)
197 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
198 MOVL $SYS_clock_gettime, AX
199 MOVQ $CLOCK_REALTIME, DI
200 LEAQ 8(SP), SI
201 SYSCALL
202 MOVQ 8(SP), AX // sec
203 MOVQ 16(SP), DX // nsec
204
205 // sec is in AX, nsec in DX
206 MOVQ AX, sec+0(FP)
207 MOVL DX, nsec+8(FP)
208 RET
209
210 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
211 MOVL $SYS_clock_gettime, AX
212 MOVQ $CLOCK_MONOTONIC, DI
213 LEAQ 8(SP), SI
214 SYSCALL
215 MOVQ 8(SP), AX // sec
216 MOVQ 16(SP), DX // nsec
217
218 // sec is in AX, nsec in DX
219 // return nsec in AX
220 IMULQ $1000000000, AX
221 ADDQ DX, AX
222 MOVQ AX, ret+0(FP)
223 RET
224
225 TEXT runtime·asmSigaction(SB),NOSPLIT,$0
226 MOVQ sig+0(FP), DI // arg 1 sig
227 MOVQ new+8(FP), SI // arg 2 act
228 MOVQ old+16(FP), DX // arg 3 oact
229 MOVL $SYS_sigaction, AX
230 SYSCALL
231 JCC 2(PC)
232 MOVL $-1, AX
233 MOVL AX, ret+24(FP)
234 RET
235
236 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
237 MOVQ sig+0(FP), DI // arg 1 sig
238 MOVQ new+8(FP), SI // arg 2 act
239 MOVQ old+16(FP), DX // arg 3 oact
240 MOVQ _cgo_sigaction(SB), AX
241 MOVQ SP, BX // callee-saved
242 ANDQ $~15, SP // alignment as per amd64 psABI
243 CALL AX
244 MOVQ BX, SP
245 MOVL AX, ret+24(FP)
246 RET
247
248 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
249 MOVQ fn+0(FP), AX
250 MOVL sig+8(FP), DI
251 MOVQ info+16(FP), SI
252 MOVQ ctx+24(FP), DX
253 MOVQ SP, BX // callee-saved
254 ANDQ $~15, SP // alignment for x86_64 ABI
255 CALL AX
256 MOVQ BX, SP
257 RET
258
259 // Called using C ABI.
260 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
261 // Transition from C ABI to Go ABI.
262 PUSH_REGS_HOST_TO_ABI0()
263
264 // Set up ABIInternal environment: g in R14, cleared X15.
265 get_tls(R12)
266 MOVQ g(R12), R14
267 PXOR X15, X15
268 #ifndef GOAMD64_v3
269 #ifndef GOAMD64_v4
270 CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $1
271 JNE 2(PC)
272 #endif
273 #endif
274 VXORPS X15, X15, X15
275
276 // Reserve space for spill slots.
277 NOP SP // disable vet stack checking
278 ADJSP $24
279
280 // Call into the Go signal handler
281 MOVQ DI, AX // sig
282 MOVQ SI, BX // info
283 MOVQ DX, CX // ctx
284 CALL ·sigtrampgo<ABIInternal>(SB)
285
286 ADJSP $-24
287
288 POP_REGS_HOST_TO_ABI0()
289 RET
290
291 // Called using C ABI.
292 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
293 // Transition from C ABI to Go ABI.
294 PUSH_REGS_HOST_TO_ABI0()
295
296 // Set up ABIInternal environment: g in R14, cleared X15.
297 get_tls(R12)
298 MOVQ g(R12), R14
299 PXOR X15, X15
300 #ifndef GOAMD64_v3
301 #ifndef GOAMD64_v4
302 CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $1
303 JNE 2(PC)
304 #endif
305 #endif
306 VXORPS X15, X15, X15
307
308 // Reserve space for spill slots.
309 NOP SP // disable vet stack checking
310 ADJSP $24
311
312 // Call into the Go signal handler
313 MOVQ DI, AX // sig
314 MOVQ SI, BX // info
315 MOVQ DX, CX // ctx
316 CALL ·sigprofNonGo<ABIInternal>(SB)
317
318 ADJSP $-24
319
320 POP_REGS_HOST_TO_ABI0()
321 RET
322
323 // Used instead of sigtramp in programs that use cgo.
324 // Arguments from kernel are in DI, SI, DX.
325 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
326 // If no traceback function, do usual sigtramp.
327 MOVQ runtime·cgoTraceback(SB), AX
328 TESTQ AX, AX
329 JZ sigtramp
330
331 // If no traceback support function, which means that
332 // runtime/cgo was not linked in, do usual sigtramp.
333 MOVQ _cgo_callers(SB), AX
334 TESTQ AX, AX
335 JZ sigtramp
336
337 // Figure out if we are currently in a cgo call.
338 // If not, just do usual sigtramp.
339 get_tls(CX)
340 MOVQ g(CX),AX
341 TESTQ AX, AX
342 JZ sigtrampnog // g == nil
343 MOVQ g_m(AX), AX
344 TESTQ AX, AX
345 JZ sigtramp // g.m == nil
346 MOVL m_ncgo(AX), CX
347 TESTL CX, CX
348 JZ sigtramp // g.m.ncgo == 0
349 MOVQ m_curg(AX), CX
350 TESTQ CX, CX
351 JZ sigtramp // g.m.curg == nil
352 MOVQ g_syscallsp(CX), CX
353 TESTQ CX, CX
354 JZ sigtramp // g.m.curg.syscallsp == 0
355 MOVQ m_cgoCallers(AX), R8
356 TESTQ R8, R8
357 JZ sigtramp // g.m.cgoCallers == nil
358 MOVL m_cgoCallersUse(AX), CX
359 TESTL CX, CX
360 JNZ sigtramp // g.m.cgoCallersUse != 0
361
362 // Jump to a function in runtime/cgo.
363 // That function, written in C, will call the user's traceback
364 // function with proper unwind info, and will then call back here.
365 // The first three arguments, and the fifth, are already in registers.
366 // Set the two remaining arguments now.
367 MOVQ runtime·cgoTraceback(SB), CX
368 MOVQ $runtime·sigtramp(SB), R9
369 MOVQ _cgo_callers(SB), AX
370 JMP AX
371
372 sigtramp:
373 JMP runtime·sigtramp(SB)
374
375 sigtrampnog:
376 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
377 // stack trace.
378 CMPL DI, $27 // 27 == SIGPROF
379 JNZ sigtramp
380
381 // Lock sigprofCallersUse.
382 MOVL $0, AX
383 MOVL $1, CX
384 MOVQ $runtime·sigprofCallersUse(SB), R11
385 LOCK
386 CMPXCHGL CX, 0(R11)
387 JNZ sigtramp // Skip stack trace if already locked.
388
389 // Jump to the traceback function in runtime/cgo.
390 // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
391 // the arguments to the Go calling convention.
392 // First three arguments to traceback function are in registers already.
393 MOVQ runtime·cgoTraceback(SB), CX
394 MOVQ $runtime·sigprofCallers(SB), R8
395 MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
396 MOVQ _cgo_callers(SB), AX
397 JMP AX
398
399 TEXT runtime·sysMmap(SB),NOSPLIT,$0
400 MOVQ addr+0(FP), DI // arg 1 addr
401 MOVQ n+8(FP), SI // arg 2 len
402 MOVL prot+16(FP), DX // arg 3 prot
403 MOVL flags+20(FP), R10 // arg 4 flags
404 MOVL fd+24(FP), R8 // arg 5 fid
405 MOVL off+28(FP), R9 // arg 6 offset
406 MOVL $SYS_mmap, AX
407 SYSCALL
408 JCC ok
409 MOVQ $0, p+32(FP)
410 MOVQ AX, err+40(FP)
411 RET
412 ok:
413 MOVQ AX, p+32(FP)
414 MOVQ $0, err+40(FP)
415 RET
416
417 // Call the function stored in _cgo_mmap using the GCC calling convention.
418 // This must be called on the system stack.
419 TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
420 MOVQ addr+0(FP), DI
421 MOVQ n+8(FP), SI
422 MOVL prot+16(FP), DX
423 MOVL flags+20(FP), CX
424 MOVL fd+24(FP), R8
425 MOVL off+28(FP), R9
426 MOVQ _cgo_mmap(SB), AX
427 MOVQ SP, BX
428 ANDQ $~15, SP // alignment as per amd64 psABI
429 MOVQ BX, 0(SP)
430 CALL AX
431 MOVQ 0(SP), SP
432 MOVQ AX, ret+32(FP)
433 RET
434
435 TEXT runtime·sysMunmap(SB),NOSPLIT,$0
436 MOVQ addr+0(FP), DI // arg 1 addr
437 MOVQ n+8(FP), SI // arg 2 len
438 MOVL $SYS_munmap, AX
439 SYSCALL
440 JCC 2(PC)
441 MOVL $0xf1, 0xf1 // crash
442 RET
443
444 // Call the function stored in _cgo_munmap using the GCC calling convention.
445 // This must be called on the system stack.
446 TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
447 MOVQ addr+0(FP), DI
448 MOVQ n+8(FP), SI
449 MOVQ _cgo_munmap(SB), AX
450 MOVQ SP, BX
451 ANDQ $~15, SP // alignment as per amd64 psABI
452 MOVQ BX, 0(SP)
453 CALL AX
454 MOVQ 0(SP), SP
455 RET
456
457 TEXT runtime·madvise(SB),NOSPLIT,$0
458 MOVQ addr+0(FP), DI
459 MOVQ n+8(FP), SI
460 MOVL flags+16(FP), DX
461 MOVQ $SYS_madvise, AX
462 SYSCALL
463 JCC 2(PC)
464 MOVL $-1, AX
465 MOVL AX, ret+24(FP)
466 RET
467
468 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
469 MOVQ new+0(FP), DI
470 MOVQ old+8(FP), SI
471 MOVQ $SYS_sigaltstack, AX
472 SYSCALL
473 JCC 2(PC)
474 MOVL $0xf1, 0xf1 // crash
475 RET
476
477 TEXT runtime·usleep(SB),NOSPLIT,$16
478 MOVL $0, DX
479 MOVL usec+0(FP), AX
480 MOVL $1000000, CX
481 DIVL CX
482 MOVQ AX, 0(SP) // tv_sec
483 MOVL $1000, AX
484 MULL DX
485 MOVQ AX, 8(SP) // tv_nsec
486
487 MOVQ SP, DI // arg 1 - rqtp
488 MOVQ $0, SI // arg 2 - rmtp
489 MOVL $SYS_nanosleep, AX
490 SYSCALL
491 RET
492
493 // set tls base to DI
494 TEXT runtime·settls(SB),NOSPLIT,$8
495 ADDQ $8, DI // adjust for ELF: wants to use -8(FS) for g and m
496 MOVQ DI, 0(SP)
497 MOVQ SP, SI
498 MOVQ $AMD64_SET_FSBASE, DI
499 MOVQ $SYS_sysarch, AX
500 SYSCALL
501 JCC 2(PC)
502 MOVL $0xf1, 0xf1 // crash
503 RET
504
505 TEXT runtime·sysctl(SB),NOSPLIT,$0
506 MOVQ mib+0(FP), DI // arg 1 - name
507 MOVL miblen+8(FP), SI // arg 2 - namelen
508 MOVQ out+16(FP), DX // arg 3 - oldp
509 MOVQ size+24(FP), R10 // arg 4 - oldlenp
510 MOVQ dst+32(FP), R8 // arg 5 - newp
511 MOVQ ndst+40(FP), R9 // arg 6 - newlen
512 MOVQ $SYS___sysctl, AX
513 SYSCALL
514 JCC 4(PC)
515 NEGQ AX
516 MOVL AX, ret+48(FP)
517 RET
518 MOVL $0, AX
519 MOVL AX, ret+48(FP)
520 RET
521
522 TEXT runtime·osyield(SB),NOSPLIT,$-4
523 MOVL $SYS_sched_yield, AX
524 SYSCALL
525 RET
526
527 TEXT runtime·sigprocmask(SB),NOSPLIT,$0
528 MOVL how+0(FP), DI // arg 1 - how
529 MOVQ new+8(FP), SI // arg 2 - set
530 MOVQ old+16(FP), DX // arg 3 - oset
531 MOVL $SYS_sigprocmask, AX
532 SYSCALL
533 JAE 2(PC)
534 MOVL $0xf1, 0xf1 // crash
535 RET
536
537 // int32 runtime·kqueue(void);
538 TEXT runtime·kqueue(SB),NOSPLIT,$0
539 MOVQ $0, DI
540 MOVQ $0, SI
541 MOVQ $0, DX
542 MOVL $SYS_kqueue, AX
543 SYSCALL
544 JCC 2(PC)
545 NEGQ AX
546 MOVL AX, ret+0(FP)
547 RET
548
549 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
550 TEXT runtime·kevent(SB),NOSPLIT,$0
551 MOVL kq+0(FP), DI
552 MOVQ ch+8(FP), SI
553 MOVL nch+16(FP), DX
554 MOVQ ev+24(FP), R10
555 MOVL nev+32(FP), R8
556 MOVQ ts+40(FP), R9
557 MOVL $SYS_kevent, AX
558 SYSCALL
559 JCC 2(PC)
560 NEGQ AX
561 MOVL AX, ret+48(FP)
562 RET
563
564 // func fcntl(fd, cmd, arg int32) (int32, int32)
565 TEXT runtime·fcntl(SB),NOSPLIT,$0
566 MOVL fd+0(FP), DI // fd
567 MOVL cmd+4(FP), SI // cmd
568 MOVL arg+8(FP), DX // arg
569 MOVL $SYS_fcntl, AX
570 SYSCALL
571 JCC noerr
572 MOVL $-1, ret+16(FP)
573 MOVL AX, errno+20(FP)
574 RET
575 noerr:
576 MOVL AX, ret+16(FP)
577 MOVL $0, errno+20(FP)
578 RET
579
580 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
581 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-44
582 MOVQ level+0(FP), DI
583 MOVQ which+8(FP), SI
584 MOVQ id+16(FP), DX
585 MOVQ size+24(FP), R10
586 MOVQ mask+32(FP), R8
587 MOVL $SYS_cpuset_getaffinity, AX
588 SYSCALL
589 JCC 2(PC)
590 NEGQ AX
591 MOVL AX, ret+40(FP)
592 RET
593
594 // func issetugid() int32
595 TEXT runtime·issetugid(SB),NOSPLIT,$0
596 MOVQ $0, DI
597 MOVQ $0, SI
598 MOVQ $0, DX
599 MOVL $SYS_issetugid, AX
600 SYSCALL
601 MOVL AX, ret+0(FP)
602 RET
603
View as plain text