blob: 8a8f3cce8bfa9608093ec4ee9b5403989842928a [file] [log] [blame]
Rob Pike8e82a672008-06-30 11:50:36 -07001// 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//
6// System calls and other sys.stuff for AMD64, Linux
7//
8
Russ Cox15ced2d2014-11-11 17:06:22 -05009#include "go_asm.h"
10#include "go_tls.h"
Russ Coxcb040d52014-09-04 23:05:18 -040011#include "textflag.h"
Russ Cox7343e032009-06-17 15:12:16 -070012
Russ Cox25f6b022014-08-27 11:32:17 -040013TEXT runtime·exit(SB),NOSPLIT,$0-4
14 MOVL code+0(FP), DI
Christopher Wedgwoodd166d162010-03-29 22:51:39 -070015 MOVL $231, AX // exitgroup - force all os threads to exit
Russ Coxd28acc42008-08-04 16:43:49 -070016 SYSCALL
17 RET
18
Russ Cox25f6b022014-08-27 11:32:17 -040019TEXT runtime·exit1(SB),NOSPLIT,$0-4
20 MOVL code+0(FP), DI
Russ Cox96824002008-08-05 14:18:47 -070021 MOVL $60, AX // exit - exit the current os thread
Rob Pike8e82a672008-06-30 11:50:36 -070022 SYSCALL
23 RET
24
Russ Cox25f6b022014-08-27 11:32:17 -040025TEXT runtime·open(SB),NOSPLIT,$0-20
26 MOVQ name+0(FP), DI
27 MOVL mode+8(FP), SI
28 MOVL perm+12(FP), DX
Rob Pike8e82a672008-06-30 11:50:36 -070029 MOVL $2, AX // syscall entry
30 SYSCALL
Keith Randallf584c052015-03-02 20:16:48 -080031 CMPQ AX, $0xfffffffffffff001
32 JLS 2(PC)
33 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040034 MOVL AX, ret+16(FP)
Rob Pike8e82a672008-06-30 11:50:36 -070035 RET
36
David Crawshawcea272d2015-04-13 19:37:04 -040037TEXT runtime·closefd(SB),NOSPLIT,$0-12
Russ Cox25f6b022014-08-27 11:32:17 -040038 MOVL fd+0(FP), DI
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -040039 MOVL $3, AX // syscall entry
40 SYSCALL
Keith Randallf584c052015-03-02 20:16:48 -080041 CMPQ AX, $0xfffffffffffff001
42 JLS 2(PC)
43 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040044 MOVL AX, ret+8(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -040045 RET
46
Russ Cox25f6b022014-08-27 11:32:17 -040047TEXT runtime·write(SB),NOSPLIT,$0-28
48 MOVQ fd+0(FP), DI
49 MOVQ p+8(FP), SI
50 MOVL n+16(FP), DX
Rob Pikecbdaa102008-07-15 08:27:50 -070051 MOVL $1, AX // syscall entry
52 SYSCALL
Keith Randallf584c052015-03-02 20:16:48 -080053 CMPQ AX, $0xfffffffffffff001
54 JLS 2(PC)
55 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040056 MOVL AX, ret+24(FP)
Rob Pikecbdaa102008-07-15 08:27:50 -070057 RET
58
Russ Cox25f6b022014-08-27 11:32:17 -040059TEXT runtime·read(SB),NOSPLIT,$0-28
60 MOVL fd+0(FP), DI
61 MOVQ p+8(FP), SI
62 MOVL n+16(FP), DX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -040063 MOVL $0, AX // syscall entry
64 SYSCALL
Keith Randallf584c052015-03-02 20:16:48 -080065 CMPQ AX, $0xfffffffffffff001
66 JLS 2(PC)
67 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040068 MOVL AX, ret+24(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -040069 RET
70
Russ Cox25f6b022014-08-27 11:32:17 -040071TEXT runtime·getrlimit(SB),NOSPLIT,$0-20
72 MOVL kind+0(FP), DI
73 MOVQ limit+8(FP), SI
Russ Cox102274a2012-02-24 15:28:51 -050074 MOVL $97, AX // syscall entry
75 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -040076 MOVL AX, ret+16(FP)
Russ Cox102274a2012-02-24 15:28:51 -050077 RET
78
Keith Randall0273dc12013-08-07 12:20:05 -070079TEXT runtime·usleep(SB),NOSPLIT,$16
Russ Coxd324f212011-09-30 09:40:01 -040080 MOVL $0, DX
81 MOVL usec+0(FP), AX
82 MOVL $1000000, CX
83 DIVL CX
84 MOVQ AX, 0(SP)
85 MOVQ DX, 8(SP)
86
87 // select(0, 0, 0, 0, &tv)
88 MOVL $0, DI
89 MOVL $0, SI
90 MOVL $0, DX
91 MOVL $0, R10
92 MOVQ SP, R8
93 MOVL $23, AX
94 SYSCALL
95 RET
96
Russ Coxa9e53642015-06-22 12:32:05 -040097TEXT runtime·gettid(SB),NOSPLIT,$0-4
98 MOVL $186, AX // syscall - gettid
99 SYSCALL
100 MOVL AX, ret+0(FP)
101 RET
102
Russ Cox4a000b92014-02-25 17:00:08 -0500103TEXT runtime·raise(SB),NOSPLIT,$0
Russ Cox8698bb62011-04-25 16:58:00 -0400104 MOVL $186, AX // syscall - gettid
105 SYSCALL
106 MOVL AX, DI // arg 1 tid
Russ Cox5146a932013-03-15 01:11:03 -0400107 MOVL sig+0(FP), SI // arg 2
Russ Cox8698bb62011-04-25 16:58:00 -0400108 MOVL $200, AX // syscall - tkill
109 SYSCALL
110 RET
111
Russ Cox5bfed7c2015-01-14 11:18:24 -0500112TEXT runtime·raiseproc(SB),NOSPLIT,$0
113 MOVL $39, AX // syscall - getpid
114 SYSCALL
115 MOVL AX, DI // arg 1 pid
116 MOVL sig+0(FP), SI // arg 2
117 MOVL $62, AX // syscall - kill
118 SYSCALL
119 RET
120
Keith Randall0273dc12013-08-07 12:20:05 -0700121TEXT runtime·setitimer(SB),NOSPLIT,$0-24
Russ Cox25f6b022014-08-27 11:32:17 -0400122 MOVL mode+0(FP), DI
123 MOVQ new+8(FP), SI
124 MOVQ old+16(FP), DX
Russ Cox8dee8722011-03-23 11:31:42 -0400125 MOVL $38, AX // syscall entry
126 SYSCALL
127 RET
128
Russ Cox25f6b022014-08-27 11:32:17 -0400129TEXT runtime·mincore(SB),NOSPLIT,$0-28
130 MOVQ addr+0(FP), DI
131 MOVQ n+8(FP), SI
132 MOVQ dst+16(FP), DX
Jonathan Markddde52a2011-06-07 21:50:10 -0700133 MOVL $27, AX // syscall entry
134 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400135 MOVL AX, ret+24(FP)
Jonathan Markddde52a2011-06-07 21:50:10 -0700136 RET
137
Russ Coxefe3d352011-11-30 11:59:44 -0500138// func now() (sec int64, nsec int32)
Keith Randall0273dc12013-08-07 12:20:05 -0700139TEXT time·now(SB),NOSPLIT,$16
Shenghou Ma26377772012-11-27 01:42:01 +0800140 // Be careful. We're calling a function with gcc calling convention here.
141 // We're guaranteed 128 bytes on entry, and we've taken 16, and the
142 // call uses another 8.
143 // That leaves 104 for the gettime code to use. Hope that's enough!
Shenghou Ma4022fc42012-11-09 14:19:07 +0800144 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX
145 CMPQ AX, $0
Russ Coxb55791e2014-10-28 21:50:16 -0400146 JEQ fallback
Shenghou Ma4022fc42012-11-09 14:19:07 +0800147 MOVL $0, DI // CLOCK_REALTIME
Shenghou Ma26377772012-11-27 01:42:01 +0800148 LEAQ 0(SP), SI
Shenghou Ma4022fc42012-11-09 14:19:07 +0800149 CALL AX
Shenghou Ma26377772012-11-27 01:42:01 +0800150 MOVQ 0(SP), AX // sec
151 MOVQ 8(SP), DX // nsec
Shenghou Ma4022fc42012-11-09 14:19:07 +0800152 MOVQ AX, sec+0(FP)
153 MOVL DX, nsec+8(FP)
154 RET
Russ Coxb55791e2014-10-28 21:50:16 -0400155fallback:
Shenghou Ma26377772012-11-27 01:42:01 +0800156 LEAQ 0(SP), DI
Russ Coxefe3d352011-11-30 11:59:44 -0500157 MOVQ $0, SI
Anthony Martin024a92c2012-11-07 18:29:31 -0800158 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX
Russ Coxefe3d352011-11-30 11:59:44 -0500159 CALL AX
Shenghou Ma26377772012-11-27 01:42:01 +0800160 MOVQ 0(SP), AX // sec
161 MOVL 8(SP), DX // usec
Russ Coxefe3d352011-11-30 11:59:44 -0500162 IMULQ $1000, DX
Shenghou Ma4022fc42012-11-09 14:19:07 +0800163 MOVQ AX, sec+0(FP)
Russ Coxefe3d352011-11-30 11:59:44 -0500164 MOVL DX, nsec+8(FP)
165 RET
166
Keith Randall0273dc12013-08-07 12:20:05 -0700167TEXT runtime·nanotime(SB),NOSPLIT,$16
Shenghou Ma26377772012-11-27 01:42:01 +0800168 // Duplicate time.now here to avoid using up precious stack space.
169 // See comment above in time.now.
170 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX
171 CMPQ AX, $0
Russ Coxb55791e2014-10-28 21:50:16 -0400172 JEQ fallback
Jay Weisskopf86c976f2014-02-24 10:57:46 -0500173 MOVL $1, DI // CLOCK_MONOTONIC
Shenghou Ma26377772012-11-27 01:42:01 +0800174 LEAQ 0(SP), SI
175 CALL AX
Shenghou Ma4022fc42012-11-09 14:19:07 +0800176 MOVQ 0(SP), AX // sec
Shenghou Ma26377772012-11-27 01:42:01 +0800177 MOVQ 8(SP), DX // nsec
178 // sec is in AX, nsec in DX
179 // return nsec in AX
180 IMULQ $1000000000, AX
181 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400182 MOVQ AX, ret+0(FP)
Shenghou Ma26377772012-11-27 01:42:01 +0800183 RET
Russ Coxb55791e2014-10-28 21:50:16 -0400184fallback:
Shenghou Ma26377772012-11-27 01:42:01 +0800185 LEAQ 0(SP), DI
186 MOVQ $0, SI
187 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX
188 CALL AX
189 MOVQ 0(SP), AX // sec
190 MOVL 8(SP), DX // usec
191 IMULQ $1000, DX
192 // sec is in AX, nsec in DX
Russ Coxf4373312011-11-03 17:35:28 -0400193 // return nsec in AX
194 IMULQ $1000000000, AX
Russ Coxf4373312011-11-03 17:35:28 -0400195 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400196 MOVQ AX, ret+0(FP)
Russ Coxe4f06812010-02-08 14:32:22 -0800197 RET
198
Russ Cox25f6b022014-08-27 11:32:17 -0400199TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
200 MOVL sig+0(FP), DI
201 MOVQ new+8(FP), SI
202 MOVQ old+16(FP), DX
203 MOVL size+24(FP), R10
Russ Cox240b1d52012-02-23 14:43:58 -0500204 MOVL $14, AX // syscall entry
205 SYSCALL
206 CMPQ AX, $0xfffffffffffff001
207 JLS 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500208 MOVL $0xf1, 0xf1 // crash
Russ Cox240b1d52012-02-23 14:43:58 -0500209 RET
210
Russ Cox25f6b022014-08-27 11:32:17 -0400211TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
212 MOVQ sig+0(FP), DI
213 MOVQ new+8(FP), SI
214 MOVQ old+16(FP), DX
215 MOVQ size+24(FP), R10
Rob Pike8e82a672008-06-30 11:50:36 -0700216 MOVL $13, AX // syscall entry
217 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400218 MOVL AX, ret+32(FP)
Rob Pike8e82a672008-06-30 11:50:36 -0700219 RET
220
Srdjan Petrovic5c8fbc62015-04-09 11:12:12 -0700221TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
Ian Lance Taylor872b1682015-07-21 22:34:48 -0700222 MOVL sig+8(FP), DI
Srdjan Petrovic5c8fbc62015-04-09 11:12:12 -0700223 MOVQ info+16(FP), SI
224 MOVQ ctx+24(FP), DX
225 MOVQ fn+0(FP), AX
Shenghou Ma2f1ead72013-07-12 04:39:39 +0800226 CALL AX
Alan Donovan532dee32012-09-04 14:40:49 -0400227 RET
Russ Coxb2369112012-03-12 15:55:18 -0400228
Srdjan Petrovic5c8fbc62015-04-09 11:12:12 -0700229TEXT runtime·sigtramp(SB),NOSPLIT,$24
230 MOVQ DI, 0(SP) // signum
231 MOVQ SI, 8(SP) // info
232 MOVQ DX, 16(SP) // ctx
233 MOVQ $runtime·sigtrampgo(SB), AX
234 CALL AX
Rob Pike8e82a672008-06-30 11:50:36 -0700235 RET
236
Ian Lance Taylorea306ae2015-12-11 17:16:48 -0800237// Used instead of sigtramp in programs that use cgo.
238// Arguments from kernel are in DI, SI, DX.
239TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
240 // If no traceback function, do usual sigtramp.
241 MOVQ runtime·cgoTraceback(SB), AX
242 TESTQ AX, AX
243 JZ sigtramp
244
245 // If no traceback support function, which means that
246 // runtime/cgo was not linked in, do usual sigtramp.
247 MOVQ _cgo_callers(SB), AX
248 TESTQ AX, AX
249 JZ sigtramp
250
251 // Figure out if we are currently in a cgo call.
252 // If not, just do usual sigtramp.
253 get_tls(CX)
254 MOVQ g(CX),AX
255 TESTQ AX, AX
Ian Lance Taylor84d8aff2016-06-07 21:46:25 -0700256 JZ sigtrampnog // g == nil
Ian Lance Taylorea306ae2015-12-11 17:16:48 -0800257 MOVQ g_m(AX), AX
258 TESTQ AX, AX
259 JZ sigtramp // g.m == nil
260 MOVL m_ncgo(AX), CX
261 TESTL CX, CX
262 JZ sigtramp // g.m.ncgo == 0
263 MOVQ m_curg(AX), CX
264 TESTQ CX, CX
265 JZ sigtramp // g.m.curg == nil
266 MOVQ g_syscallsp(CX), CX
267 TESTQ CX, CX
268 JZ sigtramp // g.m.curg.syscallsp == 0
269 MOVQ m_cgoCallers(AX), R8
270 TESTQ R8, R8
271 JZ sigtramp // g.m.cgoCallers == nil
272 MOVL m_cgoCallersUse(AX), CX
273 TESTL CX, CX
274 JNZ sigtramp // g.m.cgoCallersUse != 0
275
276 // Jump to a function in runtime/cgo.
277 // That function, written in C, will call the user's traceback
278 // function with proper unwind info, and will then call back here.
Ian Lance Taylor84d8aff2016-06-07 21:46:25 -0700279 // The first three arguments, and the fifth, are already in registers.
280 // Set the two remaining arguments now.
Ian Lance Taylorea306ae2015-12-11 17:16:48 -0800281 MOVQ runtime·cgoTraceback(SB), CX
282 MOVQ $runtime·sigtramp(SB), R9
283 MOVQ _cgo_callers(SB), AX
284 JMP AX
285
286sigtramp:
287 JMP runtime·sigtramp(SB)
288
Ian Lance Taylor84d8aff2016-06-07 21:46:25 -0700289sigtrampnog:
290 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
291 // stack trace.
292 CMPL DI, $27 // 27 == SIGPROF
293 JNZ sigtramp
294
295 // Lock sigprofCallersUse.
296 MOVL $0, AX
297 MOVL $1, CX
298 MOVQ $runtime·sigprofCallersUse(SB), BX
299 LOCK
300 CMPXCHGL CX, 0(BX)
301 JNZ sigtramp // Skip stack trace if already locked.
302
303 // Jump to the traceback function in runtime/cgo.
304 // It will call back to sigprofNonGo, which will ignore the
305 // arguments passed in registers.
306 // First three arguments to traceback function are in registers already.
307 MOVQ runtime·cgoTraceback(SB), CX
308 MOVQ $runtime·sigprofCallers(SB), R8
309 MOVQ $runtime·sigprofNonGo(SB), R9
310 MOVQ _cgo_callers(SB), AX
311 JMP AX
312
Ian Lance Taylorea306ae2015-12-11 17:16:48 -0800313// For cgo unwinding to work, this function must look precisely like
314// the one in glibc. The glibc source code is:
315// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c
316// The code that cares about the precise instructions used is:
317// https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup
Keith Randall0273dc12013-08-07 12:20:05 -0700318TEXT runtime·sigreturn(SB),NOSPLIT,$0
Ian Lance Taylorea306ae2015-12-11 17:16:48 -0800319 MOVQ $15, AX // rt_sigreturn
Russ Coxdfa58932008-12-03 14:21:28 -0800320 SYSCALL
321 INT $3 // not reached
322
Ian Lance Taylor0c1f0542015-09-29 21:24:13 -0700323TEXT runtime·sysMmap(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400324 MOVQ addr+0(FP), DI
325 MOVQ n+8(FP), SI
326 MOVL prot+16(FP), DX
327 MOVL flags+20(FP), R10
328 MOVL fd+24(FP), R8
329 MOVL off+28(FP), R9
Rob Pike8e82a672008-06-30 11:50:36 -0700330
Russ Coxd4cc5572010-09-07 09:57:22 -0400331 MOVL $9, AX // mmap
Rob Pike8e82a672008-06-30 11:50:36 -0700332 SYSCALL
333 CMPQ AX, $0xfffffffffffff001
Adam Langley3f7a3242009-11-13 10:08:51 -0800334 JLS 3(PC)
335 NOTQ AX
336 INCQ AX
Russ Cox25f6b022014-08-27 11:32:17 -0400337 MOVQ AX, ret+32(FP)
Rob Pike8e82a672008-06-30 11:50:36 -0700338 RET
339
Ian Lance Taylor0c1f0542015-09-29 21:24:13 -0700340// Call the function stored in _cgo_mmap using the GCC calling convention.
341// This must be called on the system stack.
Shenghou Ma315f4c72016-02-18 16:29:39 -0500342TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
Ian Lance Taylor0c1f0542015-09-29 21:24:13 -0700343 MOVQ addr+0(FP), DI
344 MOVQ n+8(FP), SI
345 MOVL prot+16(FP), DX
346 MOVL flags+20(FP), CX
347 MOVL fd+24(FP), R8
348 MOVL off+28(FP), R9
349 MOVQ _cgo_mmap(SB), AX
Shenghou Ma315f4c72016-02-18 16:29:39 -0500350 MOVQ SP, BX
351 ANDQ $~15, SP // alignment as per amd64 psABI
352 MOVQ BX, 0(SP)
Ian Lance Taylor0c1f0542015-09-29 21:24:13 -0700353 CALL AX
Shenghou Ma315f4c72016-02-18 16:29:39 -0500354 MOVQ 0(SP), SP
Ian Lance Taylor0c1f0542015-09-29 21:24:13 -0700355 MOVQ AX, ret+32(FP)
356 RET
357
Keith Randall0273dc12013-08-07 12:20:05 -0700358TEXT runtime·munmap(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400359 MOVQ addr+0(FP), DI
360 MOVQ n+8(FP), SI
Russ Coxd4cc5572010-09-07 09:57:22 -0400361 MOVQ $11, AX // munmap
362 SYSCALL
363 CMPQ AX, $0xfffffffffffff001
364 JLS 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500365 MOVL $0xf1, 0xf1 // crash
Russ Coxd4cc5572010-09-07 09:57:22 -0400366 RET
367
Keith Randall0273dc12013-08-07 12:20:05 -0700368TEXT runtime·madvise(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400369 MOVQ addr+0(FP), DI
370 MOVQ n+8(FP), SI
371 MOVL flags+16(FP), DX
Sébastien Paolaccie6f5a902011-12-12 16:33:13 -0500372 MOVQ $28, AX // madvise
373 SYSCALL
Russ Cox295a4d82012-12-22 15:06:28 -0500374 // ignore failure - maybe pages are locked
Rob Pike8e82a672008-06-30 11:50:36 -0700375 RET
376
Russ Cox96824002008-08-05 14:18:47 -0700377// int64 futex(int32 *uaddr, int32 op, int32 val,
Russ Coxd28acc42008-08-04 16:43:49 -0700378// struct timespec *timeout, int32 *uaddr2, int32 val2);
Keith Randall0273dc12013-08-07 12:20:05 -0700379TEXT runtime·futex(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400380 MOVQ addr+0(FP), DI
381 MOVL op+8(FP), SI
382 MOVL val+12(FP), DX
383 MOVQ ts+16(FP), R10
384 MOVQ addr2+24(FP), R8
385 MOVL val3+32(FP), R9
Russ Coxd28acc42008-08-04 16:43:49 -0700386 MOVL $202, AX
387 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400388 MOVL AX, ret+40(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700389 RET
390
Russ Cox25f6b022014-08-27 11:32:17 -0400391// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
Keith Randall0273dc12013-08-07 12:20:05 -0700392TEXT runtime·clone(SB),NOSPLIT,$0
Srdjan Petrovicca9128f2015-04-17 17:27:07 -0700393 MOVL flags+0(FP), DI
394 MOVQ stack+8(FP), SI
395 MOVQ $0, DX
396 MOVQ $0, R10
Russ Coxf7f63292008-08-05 14:21:42 -0700397
Jingcheng Zhang70e967b2012-12-19 00:30:29 +0800398 // Copy mp, gp, fn off parent stack for use by child.
Russ Coxd28acc42008-08-04 16:43:49 -0700399 // Careful: Linux system call clobbers CX and R11.
Srdjan Petrovicca9128f2015-04-17 17:27:07 -0700400 MOVQ mp+16(FP), R8
401 MOVQ gp+24(FP), R9
402 MOVQ fn+32(FP), R12
Russ Coxd28acc42008-08-04 16:43:49 -0700403
404 MOVL $56, AX
405 SYSCALL
406
407 // In parent, return.
408 CMPQ AX, $0
Russ Cox25f6b022014-08-27 11:32:17 -0400409 JEQ 3(PC)
410 MOVL AX, ret+40(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700411 RET
Russ Coxd324f212011-09-30 09:40:01 -0400412
Russ Coxe473f422010-08-04 17:50:22 -0700413 // In child, on new stack.
Russ Coxd28acc42008-08-04 16:43:49 -0700414 MOVQ SI, SP
Russ Coxd324f212011-09-30 09:40:01 -0400415
Srdjan Petrovicca9128f2015-04-17 17:27:07 -0700416 // If g or m are nil, skip Go-related setup.
417 CMPQ R8, $0 // m
418 JEQ nog
419 CMPQ R9, $0 // g
420 JEQ nog
421
Russ Cox376898c2008-09-09 11:50:14 -0700422 // Initialize m->procid to Linux tid
423 MOVL $186, AX // gettid
424 SYSCALL
Russ Coxe473f422010-08-04 17:50:22 -0700425 MOVQ AX, m_procid(R8)
426
427 // Set FS to point at m->tls.
428 LEAQ m_tls(R8), DI
Russ Cox68b42552010-11-04 14:00:19 -0400429 CALL runtime·settls(SB)
Russ Coxe473f422010-08-04 17:50:22 -0700430
431 // In child, set up new stack
432 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400433 MOVQ R8, g_m(R9)
Russ Coxe473f422010-08-04 17:50:22 -0700434 MOVQ R9, g(CX)
Russ Cox68b42552010-11-04 14:00:19 -0400435 CALL runtime·stackcheck(SB)
Russ Cox36096242009-01-16 14:58:14 -0800436
Srdjan Petrovicca9128f2015-04-17 17:27:07 -0700437nog:
Russ Cox376898c2008-09-09 11:50:14 -0700438 // Call fn
Russ Coxd28acc42008-08-04 16:43:49 -0700439 CALL R12
Russ Coxf7f63292008-08-05 14:21:42 -0700440
Brad Fitzpatrick5fea2cc2016-03-01 23:21:55 +0000441 // It shouldn't return. If it does, exit that thread.
Russ Coxd28acc42008-08-04 16:43:49 -0700442 MOVL $111, DI
443 MOVL $60, AX
444 SYSCALL
445 JMP -3(PC) // keep exiting
446
Keith Randall0273dc12013-08-07 12:20:05 -0700447TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
Russ Coxa67258f2008-09-18 15:56:46 -0700448 MOVQ new+8(SP), DI
449 MOVQ old+16(SP), SI
450 MOVQ $131, AX
451 SYSCALL
452 CMPQ AX, $0xfffffffffffff001
453 JLS 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500454 MOVL $0xf1, 0xf1 // crash
Russ Coxa67258f2008-09-18 15:56:46 -0700455 RET
Russ Coxe473f422010-08-04 17:50:22 -0700456
457// set tls base to DI
Keith Randall0273dc12013-08-07 12:20:05 -0700458TEXT runtime·settls(SB),NOSPLIT,$32
Hyang-Ah Hana Kimdfc86492015-10-16 14:04:29 -0400459#ifdef GOOS_android
460 // Same as in sys_darwin_386.s:/ugliness, different constant.
461 // DI currently holds m->tls, which must be fs:0x1d0.
462 // See cgo/gcc_android_amd64.c for the derivation of the constant.
463 SUBQ $0x1d0, DI // In android, the tls base
464#else
Michael Hudson-Doyle658a3382015-03-04 16:28:45 +1300465 ADDQ $8, DI // ELF wants to use -8(FS)
Hyang-Ah Hana Kimdfc86492015-10-16 14:04:29 -0400466#endif
Russ Coxe473f422010-08-04 17:50:22 -0700467 MOVQ DI, SI
468 MOVQ $0x1002, DI // ARCH_SET_FS
469 MOVQ $158, AX // arch_prctl
470 SYSCALL
471 CMPQ AX, $0xfffffffffffff001
472 JLS 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500473 MOVL $0xf1, 0xf1 // crash
Russ Coxe473f422010-08-04 17:50:22 -0700474 RET
475
Keith Randall0273dc12013-08-07 12:20:05 -0700476TEXT runtime·osyield(SB),NOSPLIT,$0
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400477 MOVL $24, AX
478 SYSCALL
479 RET
Shenghou Ma4f308ed2012-08-10 10:05:26 +0800480
Keith Randall0273dc12013-08-07 12:20:05 -0700481TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400482 MOVQ pid+0(FP), DI
483 MOVQ len+8(FP), SI
484 MOVQ buf+16(FP), DX
Shenghou Ma4f308ed2012-08-10 10:05:26 +0800485 MOVL $204, AX // syscall entry
486 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400487 MOVL AX, ret+24(FP)
Shenghou Ma4f308ed2012-08-10 10:05:26 +0800488 RET
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400489
490// int32 runtime·epollcreate(int32 size);
Keith Randall0273dc12013-08-07 12:20:05 -0700491TEXT runtime·epollcreate(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400492 MOVL size+0(FP), DI
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400493 MOVL $213, AX // syscall entry
494 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400495 MOVL AX, ret+8(FP)
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400496 RET
497
498// int32 runtime·epollcreate1(int32 flags);
Keith Randall0273dc12013-08-07 12:20:05 -0700499TEXT runtime·epollcreate1(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400500 MOVL flags+0(FP), DI
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400501 MOVL $291, AX // syscall entry
502 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400503 MOVL AX, ret+8(FP)
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400504 RET
505
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +0400506// func epollctl(epfd, op, fd int32, ev *epollEvent) int
Keith Randall0273dc12013-08-07 12:20:05 -0700507TEXT runtime·epollctl(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400508 MOVL epfd+0(FP), DI
509 MOVL op+4(FP), SI
510 MOVL fd+8(FP), DX
511 MOVQ ev+16(FP), R10
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400512 MOVL $233, AX // syscall entry
513 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400514 MOVL AX, ret+24(FP)
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400515 RET
516
517// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
Keith Randall0273dc12013-08-07 12:20:05 -0700518TEXT runtime·epollwait(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400519 MOVL epfd+0(FP), DI
520 MOVQ ev+8(FP), SI
521 MOVL nev+16(FP), DX
522 MOVL timeout+20(FP), R10
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400523 MOVL $232, AX // syscall entry
524 SYSCALL
Russ Cox25f6b022014-08-27 11:32:17 -0400525 MOVL AX, ret+24(FP)
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400526 RET
527
528// void runtime·closeonexec(int32 fd);
Keith Randall0273dc12013-08-07 12:20:05 -0700529TEXT runtime·closeonexec(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400530 MOVL fd+0(FP), DI // fd
Dmitriy Vyukov49e03002013-03-14 19:06:35 +0400531 MOVQ $2, SI // F_SETFD
532 MOVQ $1, DX // FD_CLOEXEC
533 MOVL $72, AX // fcntl
534 SYSCALL
535 RET
Hyang-Ah Hana Kim30ee5912015-10-16 14:17:25 -0400536
537
538// int access(const char *name, int mode)
539TEXT runtime·access(SB),NOSPLIT,$0
540 MOVQ name+0(FP), DI
541 MOVL mode+8(FP), SI
542 MOVL $21, AX // syscall entry
543 SYSCALL
544 MOVL AX, ret+16(FP)
545 RET
546
547// int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
548TEXT runtime·connect(SB),NOSPLIT,$0-28
549 MOVL fd+0(FP), DI
550 MOVQ addr+8(FP), SI
551 MOVL addrlen+16(FP), DX
552 MOVL $42, AX // syscall entry
553 SYSCALL
554 MOVL AX, ret+24(FP)
555 RET
556
557// int socket(int domain, int type, int protocol)
558TEXT runtime·socket(SB),NOSPLIT,$0-20
559 MOVL domain+0(FP), DI
560 MOVL type+4(FP), SI
561 MOVL protocol+8(FP), DX
562 MOVL $41, AX // syscall entry
563 SYSCALL
564 MOVL AX, ret+16(FP)
565 RET