...

Text file src/runtime/sys_linux_arm64.s

Documentation: runtime

     1// Copyright 2014 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 arm64, Linux
     7//
     8
     9#include "go_asm.h"
    10#include "go_tls.h"
    11#include "textflag.h"
    12#include "cgo/abi_arm64.h"
    13
    14#define AT_FDCWD -100
    15
    16#define CLOCK_REALTIME 0
    17#define CLOCK_MONOTONIC 1
    18
    19#define SYS_exit		93
    20#define SYS_read		63
    21#define SYS_write		64
    22#define SYS_openat		56
    23#define SYS_close		57
    24#define SYS_pipe2		59
    25#define SYS_nanosleep		101
    26#define SYS_mmap		222
    27#define SYS_munmap		215
    28#define SYS_setitimer		103
    29#define SYS_clone		220
    30#define SYS_sched_yield		124
    31#define SYS_rt_sigreturn	139
    32#define SYS_rt_sigaction	134
    33#define SYS_rt_sigprocmask	135
    34#define SYS_sigaltstack		132
    35#define SYS_madvise		233
    36#define SYS_mincore		232
    37#define SYS_getpid		172
    38#define SYS_gettid		178
    39#define SYS_kill		129
    40#define SYS_tgkill		131
    41#define SYS_futex		98
    42#define SYS_sched_getaffinity	123
    43#define SYS_exit_group		94
    44#define SYS_clock_gettime	113
    45#define SYS_faccessat		48
    46#define SYS_socket		198
    47#define SYS_connect		203
    48#define SYS_brk			214
    49#define SYS_timer_create	107
    50#define SYS_timer_settime	110
    51#define SYS_timer_delete	111
    52
    53TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
    54	MOVW	code+0(FP), R0
    55	MOVD	$SYS_exit_group, R8
    56	SVC
    57	RET
    58
    59// func exitThread(wait *atomic.Uint32)
    60TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
    61	MOVD	wait+0(FP), R0
    62	// We're done using the stack.
    63	MOVW	$0, R1
    64	STLRW	R1, (R0)
    65	MOVW	$0, R0	// exit code
    66	MOVD	$SYS_exit, R8
    67	SVC
    68	JMP	0(PC)
    69
    70TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
    71	MOVD	$AT_FDCWD, R0
    72	MOVD	name+0(FP), R1
    73	MOVW	mode+8(FP), R2
    74	MOVW	perm+12(FP), R3
    75	MOVD	$SYS_openat, R8
    76	SVC
    77	CMN	$4095, R0
    78	BCC	done
    79	MOVW	$-1, R0
    80done:
    81	MOVW	R0, ret+16(FP)
    82	RET
    83
    84TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
    85	MOVW	fd+0(FP), R0
    86	MOVD	$SYS_close, R8
    87	SVC
    88	CMN	$4095, R0
    89	BCC	done
    90	MOVW	$-1, R0
    91done:
    92	MOVW	R0, ret+8(FP)
    93	RET
    94
    95TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
    96	MOVD	fd+0(FP), R0
    97	MOVD	p+8(FP), R1
    98	MOVW	n+16(FP), R2
    99	MOVD	$SYS_write, R8
   100	SVC
   101	MOVW	R0, ret+24(FP)
   102	RET
   103
   104TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
   105	MOVW	fd+0(FP), R0
   106	MOVD	p+8(FP), R1
   107	MOVW	n+16(FP), R2
   108	MOVD	$SYS_read, R8
   109	SVC
   110	MOVW	R0, ret+24(FP)
   111	RET
   112
   113// func pipe2(flags int32) (r, w int32, errno int32)
   114TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
   115	MOVD	$r+8(FP), R0
   116	MOVW	flags+0(FP), R1
   117	MOVW	$SYS_pipe2, R8
   118	SVC
   119	MOVW	R0, errno+16(FP)
   120	RET
   121
   122TEXT runtime·usleep(SB),NOSPLIT,$24-4
   123	MOVWU	usec+0(FP), R3
   124	MOVD	R3, R5
   125	MOVW	$1000000, R4
   126	UDIV	R4, R3
   127	MOVD	R3, 8(RSP)
   128	MUL	R3, R4
   129	SUB	R4, R5
   130	MOVW	$1000, R4
   131	MUL	R4, R5
   132	MOVD	R5, 16(RSP)
   133
   134	// nanosleep(&ts, 0)
   135	ADD	$8, RSP, R0
   136	MOVD	$0, R1
   137	MOVD	$SYS_nanosleep, R8
   138	SVC
   139	RET
   140
   141TEXT runtime·gettid(SB),NOSPLIT,$0-4
   142	MOVD	$SYS_gettid, R8
   143	SVC
   144	MOVW	R0, ret+0(FP)
   145	RET
   146
   147TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
   148	MOVD	$SYS_getpid, R8
   149	SVC
   150	MOVW	R0, R19
   151	MOVD	$SYS_gettid, R8
   152	SVC
   153	MOVW	R0, R1	// arg 2 tid
   154	MOVW	R19, R0	// arg 1 pid
   155	MOVW	sig+0(FP), R2	// arg 3
   156	MOVD	$SYS_tgkill, R8
   157	SVC
   158	RET
   159
   160TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
   161	MOVD	$SYS_getpid, R8
   162	SVC
   163	MOVW	R0, R0		// arg 1 pid
   164	MOVW	sig+0(FP), R1	// arg 2
   165	MOVD	$SYS_kill, R8
   166	SVC
   167	RET
   168
   169TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
   170	MOVD	$SYS_getpid, R8
   171	SVC
   172	MOVD	R0, ret+0(FP)
   173	RET
   174
   175TEXT ·tgkill(SB),NOSPLIT,$0-24
   176	MOVD	tgid+0(FP), R0
   177	MOVD	tid+8(FP), R1
   178	MOVD	sig+16(FP), R2
   179	MOVD	$SYS_tgkill, R8
   180	SVC
   181	RET
   182
   183TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
   184	MOVW	mode+0(FP), R0
   185	MOVD	new+8(FP), R1
   186	MOVD	old+16(FP), R2
   187	MOVD	$SYS_setitimer, R8
   188	SVC
   189	RET
   190
   191TEXT runtime·timer_create(SB),NOSPLIT,$0-28
   192	MOVW	clockid+0(FP), R0
   193	MOVD	sevp+8(FP), R1
   194	MOVD	timerid+16(FP), R2
   195	MOVD	$SYS_timer_create, R8
   196	SVC
   197	MOVW	R0, ret+24(FP)
   198	RET
   199
   200TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
   201	MOVW	timerid+0(FP), R0
   202	MOVW	flags+4(FP), R1
   203	MOVD	new+8(FP), R2
   204	MOVD	old+16(FP), R3
   205	MOVD	$SYS_timer_settime, R8
   206	SVC
   207	MOVW	R0, ret+24(FP)
   208	RET
   209
   210TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
   211	MOVW	timerid+0(FP), R0
   212	MOVD	$SYS_timer_delete, R8
   213	SVC
   214	MOVW	R0, ret+8(FP)
   215	RET
   216
   217TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
   218	MOVD	addr+0(FP), R0
   219	MOVD	n+8(FP), R1
   220	MOVD	dst+16(FP), R2
   221	MOVD	$SYS_mincore, R8
   222	SVC
   223	MOVW	R0, ret+24(FP)
   224	RET
   225
   226// func walltime() (sec int64, nsec int32)
   227TEXT runtime·walltime(SB),NOSPLIT,$24-12
   228	MOVD	RSP, R20	// R20 is unchanged by C code
   229	MOVD	RSP, R1
   230
   231	MOVD	g_m(g), R21	// R21 = m
   232
   233	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   234	// Save the old values on stack and restore them on exit,
   235	// so this function is reentrant.
   236	MOVD	m_vdsoPC(R21), R2
   237	MOVD	m_vdsoSP(R21), R3
   238	MOVD	R2, 8(RSP)
   239	MOVD	R3, 16(RSP)
   240
   241	MOVD	$ret-8(FP), R2 // caller's SP
   242	MOVD	LR, m_vdsoPC(R21)
   243	MOVD	R2, m_vdsoSP(R21)
   244
   245	MOVD	m_curg(R21), R0
   246	CMP	g, R0
   247	BNE	noswitch
   248
   249	MOVD	m_g0(R21), R3
   250	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
   251
   252noswitch:
   253	SUB	$16, R1
   254	BIC	$15, R1	// Align for C code
   255	MOVD	R1, RSP
   256
   257	MOVW	$CLOCK_REALTIME, R0
   258	MOVD	runtime·vdsoClockgettimeSym(SB), R2
   259	CBZ	R2, fallback
   260
   261	// Store g on gsignal's stack, so if we receive a signal
   262	// during VDSO code we can find the g.
   263	// If we don't have a signal stack, we won't receive signal,
   264	// so don't bother saving g.
   265	// When using cgo, we already saved g on TLS, also don't save
   266	// g here.
   267	// Also don't save g if we are already on the signal stack.
   268	// We won't get a nested signal.
   269	MOVBU	runtime·iscgo(SB), R22
   270	CBNZ	R22, nosaveg
   271	MOVD	m_gsignal(R21), R22          // g.m.gsignal
   272	CBZ	R22, nosaveg
   273	CMP	g, R22
   274	BEQ	nosaveg
   275	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   276	MOVD	g, (R22)
   277
   278	BL	(R2)
   279
   280	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
   281
   282	B	finish
   283
   284nosaveg:
   285	BL	(R2)
   286	B	finish
   287
   288fallback:
   289	MOVD	$SYS_clock_gettime, R8
   290	SVC
   291
   292finish:
   293	MOVD	0(RSP), R3	// sec
   294	MOVD	8(RSP), R5	// nsec
   295
   296	MOVD	R20, RSP	// restore SP
   297	// Restore vdsoPC, vdsoSP
   298	// We don't worry about being signaled between the two stores.
   299	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   300	// and no one will care about vdsoPC. If we are in a signal handler,
   301	// we cannot receive another signal.
   302	MOVD	16(RSP), R1
   303	MOVD	R1, m_vdsoSP(R21)
   304	MOVD	8(RSP), R1
   305	MOVD	R1, m_vdsoPC(R21)
   306
   307	MOVD	R3, sec+0(FP)
   308	MOVW	R5, nsec+8(FP)
   309	RET
   310
   311TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
   312	MOVD	RSP, R20	// R20 is unchanged by C code
   313	MOVD	RSP, R1
   314
   315	MOVD	g_m(g), R21	// R21 = m
   316
   317	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   318	// Save the old values on stack and restore them on exit,
   319	// so this function is reentrant.
   320	MOVD	m_vdsoPC(R21), R2
   321	MOVD	m_vdsoSP(R21), R3
   322	MOVD	R2, 8(RSP)
   323	MOVD	R3, 16(RSP)
   324
   325	MOVD	$ret-8(FP), R2 // caller's SP
   326	MOVD	LR, m_vdsoPC(R21)
   327	MOVD	R2, m_vdsoSP(R21)
   328
   329	MOVD	m_curg(R21), R0
   330	CMP	g, R0
   331	BNE	noswitch
   332
   333	MOVD	m_g0(R21), R3
   334	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
   335
   336noswitch:
   337	SUB	$32, R1
   338	BIC	$15, R1
   339	MOVD	R1, RSP
   340
   341	MOVW	$CLOCK_MONOTONIC, R0
   342	MOVD	runtime·vdsoClockgettimeSym(SB), R2
   343	CBZ	R2, fallback
   344
   345	// Store g on gsignal's stack, so if we receive a signal
   346	// during VDSO code we can find the g.
   347	// If we don't have a signal stack, we won't receive signal,
   348	// so don't bother saving g.
   349	// When using cgo, we already saved g on TLS, also don't save
   350	// g here.
   351	// Also don't save g if we are already on the signal stack.
   352	// We won't get a nested signal.
   353	MOVBU	runtime·iscgo(SB), R22
   354	CBNZ	R22, nosaveg
   355	MOVD	m_gsignal(R21), R22          // g.m.gsignal
   356	CBZ	R22, nosaveg
   357	CMP	g, R22
   358	BEQ	nosaveg
   359	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   360	MOVD	g, (R22)
   361
   362	BL	(R2)
   363
   364	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
   365
   366	B	finish
   367
   368nosaveg:
   369	BL	(R2)
   370	B	finish
   371
   372fallback:
   373	MOVD	$SYS_clock_gettime, R8
   374	SVC
   375
   376finish:
   377	MOVD	0(RSP), R3	// sec
   378	MOVD	8(RSP), R5	// nsec
   379
   380	MOVD	R20, RSP	// restore SP
   381	// Restore vdsoPC, vdsoSP
   382	// We don't worry about being signaled between the two stores.
   383	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   384	// and no one will care about vdsoPC. If we are in a signal handler,
   385	// we cannot receive another signal.
   386	MOVD	16(RSP), R1
   387	MOVD	R1, m_vdsoSP(R21)
   388	MOVD	8(RSP), R1
   389	MOVD	R1, m_vdsoPC(R21)
   390
   391	// sec is in R3, nsec in R5
   392	// return nsec in R3
   393	MOVD	$1000000000, R4
   394	MUL	R4, R3
   395	ADD	R5, R3
   396	MOVD	R3, ret+0(FP)
   397	RET
   398
   399TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
   400	MOVW	how+0(FP), R0
   401	MOVD	new+8(FP), R1
   402	MOVD	old+16(FP), R2
   403	MOVW	size+24(FP), R3
   404	MOVD	$SYS_rt_sigprocmask, R8
   405	SVC
   406	CMN	$4095, R0
   407	BCC	done
   408	MOVD	$0, R0
   409	MOVD	R0, (R0)	// crash
   410done:
   411	RET
   412
   413TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
   414	MOVD	sig+0(FP), R0
   415	MOVD	new+8(FP), R1
   416	MOVD	old+16(FP), R2
   417	MOVD	size+24(FP), R3
   418	MOVD	$SYS_rt_sigaction, R8
   419	SVC
   420	MOVW	R0, ret+32(FP)
   421	RET
   422
   423// Call the function stored in _cgo_sigaction using the GCC calling convention.
   424TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
   425	MOVD	sig+0(FP), R0
   426	MOVD	new+8(FP), R1
   427	MOVD	old+16(FP), R2
   428	MOVD	 _cgo_sigaction(SB), R3
   429	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   430	BL	R3
   431	ADD	$16, RSP
   432	MOVW	R0, ret+24(FP)
   433	RET
   434
   435TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   436	MOVW	sig+8(FP), R0
   437	MOVD	info+16(FP), R1
   438	MOVD	ctx+24(FP), R2
   439	MOVD	fn+0(FP), R11
   440	BL	(R11)
   441	RET
   442
   443// Called from c-abi, R0: sig, R1: info, R2: cxt
   444TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
   445	// Save callee-save registers in the case of signal forwarding.
   446	// Please refer to https://golang.org/issue/31827 .
   447	SAVE_R19_TO_R28(8*4)
   448	SAVE_F8_TO_F15(8*14)
   449
   450	// this might be called in external code context,
   451	// where g is not set.
   452	// first save R0, because runtime·load_g will clobber it
   453	MOVW	R0, 8(RSP)
   454	MOVBU	runtime·iscgo(SB), R0
   455	CBZ	R0, 2(PC)
   456	BL	runtime·load_g(SB)
   457
   458	// Restore signum to R0.
   459	MOVW	8(RSP), R0
   460	// R1 and R2 already contain info and ctx, respectively.
   461	MOVD	$runtime·sigtrampgo<ABIInternal>(SB), R3
   462	BL	(R3)
   463
   464	// Restore callee-save registers.
   465	RESTORE_R19_TO_R28(8*4)
   466	RESTORE_F8_TO_F15(8*14)
   467
   468	RET
   469
   470// Called from c-abi, R0: sig, R1: info, R2: cxt
   471TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$176
   472	// Save callee-save registers because it's a callback from c code.
   473	SAVE_R19_TO_R28(8*4)
   474	SAVE_F8_TO_F15(8*14)
   475
   476	// R0, R1 and R2 already contain sig, info and ctx, respectively.
   477	CALL	runtime·sigprofNonGo<ABIInternal>(SB)
   478
   479	// Restore callee-save registers.
   480	RESTORE_R19_TO_R28(8*4)
   481	RESTORE_F8_TO_F15(8*14)
   482	RET
   483
   484// Called from c-abi, R0: sig, R1: info, R2: cxt
   485TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
   486	// The stack unwinder, presumably written in C, may not be able to
   487	// handle Go frame correctly. So, this function is NOFRAME, and we
   488	// save/restore LR manually.
   489	MOVD	LR, R10
   490	// Save R27, g because they will be clobbered,
   491	// we need to restore them before jump to sigtramp.
   492	MOVD	R27, R11
   493	MOVD	g, R12
   494
   495	// If no traceback function, do usual sigtramp.
   496	MOVD	runtime·cgoTraceback(SB), R6
   497	CBZ	R6, sigtramp
   498
   499	// If no traceback support function, which means that
   500	// runtime/cgo was not linked in, do usual sigtramp.
   501	MOVD	_cgo_callers(SB), R7
   502	CBZ	R7, sigtramp
   503
   504	// Figure out if we are currently in a cgo call.
   505	// If not, just do usual sigtramp.
   506	// first save R0, because runtime·load_g will clobber it.
   507	MOVD	R0, R8
   508	// Set up g register.
   509	CALL	runtime·load_g(SB)
   510	MOVD	R8, R0
   511
   512	CBZ	g, sigtrampnog // g == nil
   513	MOVD	g_m(g), R6
   514	CBZ	R6, sigtramp    // g.m == nil
   515	MOVW	m_ncgo(R6), R7
   516	CBZW	R7, sigtramp    // g.m.ncgo = 0
   517	MOVD	m_curg(R6), R8
   518	CBZ	R8, sigtramp    // g.m.curg == nil
   519	MOVD	g_syscallsp(R8), R7
   520	CBZ	R7,	sigtramp    // g.m.curg.syscallsp == 0
   521	MOVD	m_cgoCallers(R6), R4 // R4 is the fifth arg in C calling convention.
   522	CBZ	R4,	sigtramp    // g.m.cgoCallers == nil
   523	MOVW	m_cgoCallersUse(R6), R8
   524	CBNZW	R8, sigtramp    // g.m.cgoCallersUse != 0
   525
   526	// Jump to a function in runtime/cgo.
   527	// That function, written in C, will call the user's traceback
   528	// function with proper unwind info, and will then call back here.
   529	// The first three arguments, and the fifth, are already in registers.
   530	// Set the two remaining arguments now.
   531	MOVD	runtime·cgoTraceback(SB), R3
   532	MOVD	$runtime·sigtramp(SB), R5
   533	MOVD	_cgo_callers(SB), R13
   534	MOVD	R10, LR // restore
   535	MOVD	R11, R27
   536	MOVD	R12, g
   537	B	(R13)
   538
   539sigtramp:
   540	MOVD	R10, LR // restore
   541	MOVD	R11, R27
   542	MOVD	R12, g
   543	B	runtime·sigtramp(SB)
   544
   545sigtrampnog:
   546	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   547	// stack trace.
   548	CMPW	$27, R0 // 27 == SIGPROF
   549	BNE	sigtramp
   550
   551	// Lock sigprofCallersUse (cas from 0 to 1).
   552	MOVW	$1, R7
   553	MOVD	$runtime·sigprofCallersUse(SB), R8
   554load_store_loop:
   555	LDAXRW	(R8), R9
   556	CBNZW	R9, sigtramp // Skip stack trace if already locked.
   557	STLXRW	R7, (R8), R9
   558	CBNZ	R9, load_store_loop
   559
   560	// Jump to the traceback function in runtime/cgo.
   561	// It will call back to sigprofNonGo, which will ignore the
   562	// arguments passed in registers.
   563	// First three arguments to traceback function are in registers already.
   564	MOVD	runtime·cgoTraceback(SB), R3
   565	MOVD	$runtime·sigprofCallers(SB), R4
   566	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R5
   567	MOVD	_cgo_callers(SB), R13
   568	MOVD	R10, LR // restore
   569	MOVD	R11, R27
   570	MOVD	R12, g
   571	B	(R13)
   572
   573TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
   574	MOVD	addr+0(FP), R0
   575	MOVD	n+8(FP), R1
   576	MOVW	prot+16(FP), R2
   577	MOVW	flags+20(FP), R3
   578	MOVW	fd+24(FP), R4
   579	MOVW	off+28(FP), R5
   580
   581	MOVD	$SYS_mmap, R8
   582	SVC
   583	CMN	$4095, R0
   584	BCC	ok
   585	NEG	R0,R0
   586	MOVD	$0, p+32(FP)
   587	MOVD	R0, err+40(FP)
   588	RET
   589ok:
   590	MOVD	R0, p+32(FP)
   591	MOVD	$0, err+40(FP)
   592	RET
   593
   594// Call the function stored in _cgo_mmap using the GCC calling convention.
   595// This must be called on the system stack.
   596TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
   597	MOVD	addr+0(FP), R0
   598	MOVD	n+8(FP), R1
   599	MOVW	prot+16(FP), R2
   600	MOVW	flags+20(FP), R3
   601	MOVW	fd+24(FP), R4
   602	MOVW	off+28(FP), R5
   603	MOVD	_cgo_mmap(SB), R9
   604	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   605	BL	R9
   606	ADD	$16, RSP
   607	MOVD	R0, ret+32(FP)
   608	RET
   609
   610TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
   611	MOVD	addr+0(FP), R0
   612	MOVD	n+8(FP), R1
   613	MOVD	$SYS_munmap, R8
   614	SVC
   615	CMN	$4095, R0
   616	BCC	cool
   617	MOVD	R0, 0xf0(R0)
   618cool:
   619	RET
   620
   621// Call the function stored in _cgo_munmap using the GCC calling convention.
   622// This must be called on the system stack.
   623TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
   624	MOVD	addr+0(FP), R0
   625	MOVD	n+8(FP), R1
   626	MOVD	_cgo_munmap(SB), R9
   627	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   628	BL	R9
   629	ADD	$16, RSP
   630	RET
   631
   632TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
   633	MOVD	addr+0(FP), R0
   634	MOVD	n+8(FP), R1
   635	MOVW	flags+16(FP), R2
   636	MOVD	$SYS_madvise, R8
   637	SVC
   638	MOVW	R0, ret+24(FP)
   639	RET
   640
   641// int64 futex(int32 *uaddr, int32 op, int32 val,
   642//	struct timespec *timeout, int32 *uaddr2, int32 val2);
   643TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
   644	MOVD	addr+0(FP), R0
   645	MOVW	op+8(FP), R1
   646	MOVW	val+12(FP), R2
   647	MOVD	ts+16(FP), R3
   648	MOVD	addr2+24(FP), R4
   649	MOVW	val3+32(FP), R5
   650	MOVD	$SYS_futex, R8
   651	SVC
   652	MOVW	R0, ret+40(FP)
   653	RET
   654
   655// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
   656TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
   657	MOVW	flags+0(FP), R0
   658	MOVD	stk+8(FP), R1
   659
   660	// Copy mp, gp, fn off parent stack for use by child.
   661	MOVD	mp+16(FP), R10
   662	MOVD	gp+24(FP), R11
   663	MOVD	fn+32(FP), R12
   664
   665	MOVD	R10, -8(R1)
   666	MOVD	R11, -16(R1)
   667	MOVD	R12, -24(R1)
   668	MOVD	$1234, R10
   669	MOVD	R10, -32(R1)
   670
   671	MOVD	$SYS_clone, R8
   672	SVC
   673
   674	// In parent, return.
   675	CMP	ZR, R0
   676	BEQ	child
   677	MOVW	R0, ret+40(FP)
   678	RET
   679child:
   680
   681	// In child, on new stack.
   682	MOVD	-32(RSP), R10
   683	MOVD	$1234, R0
   684	CMP	R0, R10
   685	BEQ	good
   686	MOVD	$0, R0
   687	MOVD	R0, (R0)	// crash
   688
   689good:
   690	// Initialize m->procid to Linux tid
   691	MOVD	$SYS_gettid, R8
   692	SVC
   693
   694	MOVD	-24(RSP), R12     // fn
   695	MOVD	-16(RSP), R11     // g
   696	MOVD	-8(RSP), R10      // m
   697
   698	CMP	$0, R10
   699	BEQ	nog
   700	CMP	$0, R11
   701	BEQ	nog
   702
   703	MOVD	R0, m_procid(R10)
   704
   705	// TODO: setup TLS.
   706
   707	// In child, set up new stack
   708	MOVD	R10, g_m(R11)
   709	MOVD	R11, g
   710	//CALL	runtime·stackcheck(SB)
   711
   712nog:
   713	// Call fn
   714	MOVD	R12, R0
   715	BL	(R0)
   716
   717	// It shouldn't return.	 If it does, exit that thread.
   718	MOVW	$111, R0
   719again:
   720	MOVD	$SYS_exit, R8
   721	SVC
   722	B	again	// keep exiting
   723
   724TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
   725	MOVD	new+0(FP), R0
   726	MOVD	old+8(FP), R1
   727	MOVD	$SYS_sigaltstack, R8
   728	SVC
   729	CMN	$4095, R0
   730	BCC	ok
   731	MOVD	$0, R0
   732	MOVD	R0, (R0)	// crash
   733ok:
   734	RET
   735
   736TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
   737	MOVD	$SYS_sched_yield, R8
   738	SVC
   739	RET
   740
   741TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
   742	MOVD	pid+0(FP), R0
   743	MOVD	len+8(FP), R1
   744	MOVD	buf+16(FP), R2
   745	MOVD	$SYS_sched_getaffinity, R8
   746	SVC
   747	MOVW	R0, ret+24(FP)
   748	RET
   749
   750// int access(const char *name, int mode)
   751TEXT runtime·access(SB),NOSPLIT,$0-20
   752	MOVD	$AT_FDCWD, R0
   753	MOVD	name+0(FP), R1
   754	MOVW	mode+8(FP), R2
   755	MOVD	$SYS_faccessat, R8
   756	SVC
   757	MOVW	R0, ret+16(FP)
   758	RET
   759
   760// int connect(int fd, const struct sockaddr *addr, socklen_t len)
   761TEXT runtime·connect(SB),NOSPLIT,$0-28
   762	MOVW	fd+0(FP), R0
   763	MOVD	addr+8(FP), R1
   764	MOVW	len+16(FP), R2
   765	MOVD	$SYS_connect, R8
   766	SVC
   767	MOVW	R0, ret+24(FP)
   768	RET
   769
   770// int socket(int domain, int typ, int prot)
   771TEXT runtime·socket(SB),NOSPLIT,$0-20
   772	MOVW	domain+0(FP), R0
   773	MOVW	typ+4(FP), R1
   774	MOVW	prot+8(FP), R2
   775	MOVD	$SYS_socket, R8
   776	SVC
   777	MOVW	R0, ret+16(FP)
   778	RET
   779
   780// func sbrk0() uintptr
   781TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
   782	// Implemented as brk(NULL).
   783	MOVD	$0, R0
   784	MOVD	$SYS_brk, R8
   785	SVC
   786	MOVD	R0, ret+0(FP)
   787	RET

View as plain text