1// Copyright 2022 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#include "textflag.h"
6
7// On FreeBSD argc/argv are passed in R0, not X2
8TEXT _rt0_riscv64_freebsd(SB),NOSPLIT|NOFRAME,$0
9	ADD	$8, A0, A1	// argv
10	MOV	0(A0), A0	// argc
11	JMP	main(SB)
12
13// When building with -buildmode=c-shared, this symbol is called when the shared
14// library is loaded.
15TEXT _rt0_riscv64_freebsd_lib(SB),NOSPLIT,$224
16	// Preserve callee-save registers, along with X1 (LR).
17	MOV	X1, (8*3)(X2)
18	MOV	X8, (8*4)(X2)
19	MOV	X9, (8*5)(X2)
20	MOV	X18, (8*6)(X2)
21	MOV	X19, (8*7)(X2)
22	MOV	X20, (8*8)(X2)
23	MOV	X21, (8*9)(X2)
24	MOV	X22, (8*10)(X2)
25	MOV	X23, (8*11)(X2)
26	MOV	X24, (8*12)(X2)
27	MOV	X25, (8*13)(X2)
28	MOV	X26, (8*14)(X2)
29	MOV	g, (8*15)(X2)
30	MOVD	F8, (8*16)(X2)
31	MOVD	F9, (8*17)(X2)
32	MOVD	F18, (8*18)(X2)
33	MOVD	F19, (8*19)(X2)
34	MOVD	F20, (8*20)(X2)
35	MOVD	F21, (8*21)(X2)
36	MOVD	F22, (8*22)(X2)
37	MOVD	F23, (8*23)(X2)
38	MOVD	F24, (8*24)(X2)
39	MOVD	F25, (8*25)(X2)
40	MOVD	F26, (8*26)(X2)
41	MOVD	F27, (8*27)(X2)
42
43	// Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
44	MOV	X0, g
45
46	MOV	A0, _rt0_riscv64_freebsd_lib_argc<>(SB)
47	MOV	A1, _rt0_riscv64_freebsd_lib_argv<>(SB)
48
49	// Synchronous initialization.
50	MOV	$runtime·libpreinit(SB), T0
51	JALR	RA, T0
52
53	// Create a new thread to do the runtime initialization and return.
54	MOV	_cgo_sys_thread_create(SB), T0
55	BEQZ	T0, nocgo
56	MOV	$_rt0_riscv64_freebsd_lib_go(SB), A0
57	MOV	$0, A1
58	JALR	RA, T0
59	JMP	restore
60
61nocgo:
62	MOV	$0x800000, A0                     // stacksize = 8192KB
63	MOV	$_rt0_riscv64_freebsd_lib_go(SB), A1
64	MOV	A0, 8(X2)
65	MOV	A1, 16(X2)
66	MOV	$runtime·newosproc0(SB), T0
67	JALR	RA, T0
68
69restore:
70	// Restore callee-save registers, along with X1 (LR).
71	MOV	(8*3)(X2), X1
72	MOV	(8*4)(X2), X8
73	MOV	(8*5)(X2), X9
74	MOV	(8*6)(X2), X18
75	MOV	(8*7)(X2), X19
76	MOV	(8*8)(X2), X20
77	MOV	(8*9)(X2), X21
78	MOV	(8*10)(X2), X22
79	MOV	(8*11)(X2), X23
80	MOV	(8*12)(X2), X24
81	MOV	(8*13)(X2), X25
82	MOV	(8*14)(X2), X26
83	MOV	(8*15)(X2), g
84	MOVD	(8*16)(X2), F8
85	MOVD	(8*17)(X2), F9
86	MOVD	(8*18)(X2), F18
87	MOVD	(8*19)(X2), F19
88	MOVD	(8*20)(X2), F20
89	MOVD	(8*21)(X2), F21
90	MOVD	(8*22)(X2), F22
91	MOVD	(8*23)(X2), F23
92	MOVD	(8*24)(X2), F24
93	MOVD	(8*25)(X2), F25
94	MOVD	(8*26)(X2), F26
95	MOVD	(8*27)(X2), F27
96
97	RET
98
99TEXT _rt0_riscv64_freebsd_lib_go(SB),NOSPLIT,$0
100	MOV	_rt0_riscv64_freebsd_lib_argc<>(SB), A0
101	MOV	_rt0_riscv64_freebsd_lib_argv<>(SB), A1
102	MOV	$runtime·rt0_go(SB), T0
103	JALR	ZERO, T0
104
105DATA _rt0_riscv64_freebsd_lib_argc<>(SB)/8, $0
106GLOBL _rt0_riscv64_freebsd_lib_argc<>(SB),NOPTR, $8
107DATA _rt0_riscv64_freebsd_lib_argv<>(SB)/8, $0
108GLOBL _rt0_riscv64_freebsd_lib_argv<>(SB),NOPTR, $8
109
110TEXT main(SB),NOSPLIT|NOFRAME,$0
111	MOV	$runtime·rt0_go(SB), T0
112	JALR	ZERO, T0
113