1// Copyright 2018 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#include "asm_ppc64x.h"
7
8// _rt0_ppc64_aix is a function descriptor of the entrypoint function
9// __start. This name is needed by cmd/link.
10DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix, __start<>)
11
12// The starting function must return in the loader to
13// initialise some libraries, especially libthread which
14// creates the main thread and adds the TLS in R13
15// R19 contains a function descriptor to the loader function
16// which needs to be called.
17// This code is similar to the __start function in C
18TEXT __start<>(SB),NOSPLIT,$-8
19	XOR R0, R0
20	MOVD $libc___n_pthreads(SB), R4
21	MOVD 0(R4), R4
22	MOVD $libc___mod_init(SB), R5
23	MOVD 0(R5), R5
24	MOVD 0(R19), R0
25	MOVD R2, 40(R1)
26	MOVD 8(R19), R2
27	MOVD R18, R3
28	MOVD R0, CTR
29	BL (CTR) // Return to AIX loader
30
31	// Launch rt0_go
32	MOVD 40(R1), R2
33	MOVD R14, R3 // argc
34	MOVD R15, R4 // argv
35	BL _main(SB)
36
37
38DEFINE_PPC64X_FUNCDESC(main, _main)
39TEXT _main(SB),NOSPLIT,$-8
40	MOVD $runtime·rt0_go(SB), R12
41	MOVD R12, CTR
42	BR (CTR)
43
44// Paramater save space required to cross-call into _cgo_sys_thread_create
45#define PARAM_SPACE 16
46
47TEXT _rt0_ppc64_aix_lib(SB),NOSPLIT,$-8
48	// Start with standard C stack frame layout and linkage.
49	MOVD	LR, R0
50	MOVD	R0, 16(R1) // Save LR in caller's frame.
51	MOVW	CR, R0	   // Save CR in caller's frame
52	MOVD	R0, 8(R1)
53
54	MOVDU	R1, -344-PARAM_SPACE(R1) // Allocate frame.
55
56	// Preserve callee-save registers.
57	MOVD	R14, 48+PARAM_SPACE(R1)
58	MOVD	R15, 56+PARAM_SPACE(R1)
59	MOVD	R16, 64+PARAM_SPACE(R1)
60	MOVD	R17, 72+PARAM_SPACE(R1)
61	MOVD	R18, 80+PARAM_SPACE(R1)
62	MOVD	R19, 88+PARAM_SPACE(R1)
63	MOVD	R20, 96+PARAM_SPACE(R1)
64	MOVD	R21,104+PARAM_SPACE(R1)
65	MOVD	R22, 112+PARAM_SPACE(R1)
66	MOVD	R23, 120+PARAM_SPACE(R1)
67	MOVD	R24, 128+PARAM_SPACE(R1)
68	MOVD	R25, 136+PARAM_SPACE(R1)
69	MOVD	R26, 144+PARAM_SPACE(R1)
70	MOVD	R27, 152+PARAM_SPACE(R1)
71	MOVD	R28, 160+PARAM_SPACE(R1)
72	MOVD	R29, 168+PARAM_SPACE(R1)
73	MOVD	g, 176+PARAM_SPACE(R1) // R30
74	MOVD	R31, 184+PARAM_SPACE(R1)
75	FMOVD	F14, 192+PARAM_SPACE(R1)
76	FMOVD	F15, 200+PARAM_SPACE(R1)
77	FMOVD	F16, 208+PARAM_SPACE(R1)
78	FMOVD	F17, 216+PARAM_SPACE(R1)
79	FMOVD	F18, 224+PARAM_SPACE(R1)
80	FMOVD	F19, 232+PARAM_SPACE(R1)
81	FMOVD	F20, 240+PARAM_SPACE(R1)
82	FMOVD	F21, 248+PARAM_SPACE(R1)
83	FMOVD	F22, 256+PARAM_SPACE(R1)
84	FMOVD	F23, 264+PARAM_SPACE(R1)
85	FMOVD	F24, 272+PARAM_SPACE(R1)
86	FMOVD	F25, 280+PARAM_SPACE(R1)
87	FMOVD	F26, 288+PARAM_SPACE(R1)
88	FMOVD	F27, 296+PARAM_SPACE(R1)
89	FMOVD	F28, 304+PARAM_SPACE(R1)
90	FMOVD	F29, 312+PARAM_SPACE(R1)
91	FMOVD	F30, 320+PARAM_SPACE(R1)
92	FMOVD	F31, 328+PARAM_SPACE(R1)
93
94	// Synchronous initialization.
95	MOVD	$runtime·reginit(SB), R12
96	MOVD	R12, CTR
97	BL	(CTR)
98
99	MOVBZ	runtime·isarchive(SB), R3	// Check buildmode = c-archive
100	CMP		$0, R3
101	BEQ		done
102
103	MOVD	R14, _rt0_ppc64_aix_lib_argc<>(SB)
104	MOVD	R15, _rt0_ppc64_aix_lib_argv<>(SB)
105
106	MOVD	$runtime·libpreinit(SB), R12
107	MOVD	R12, CTR
108	BL	(CTR)
109
110	// Create a new thread to do the runtime initialization and return.
111	MOVD	_cgo_sys_thread_create(SB), R12
112	CMP	$0, R12
113	BEQ	nocgo
114	MOVD	$_rt0_ppc64_aix_lib_go(SB), R3
115	MOVD	$0, R4
116	MOVD	R2, 40(R1)
117	MOVD	8(R12), R2
118	MOVD	(R12), R12
119	MOVD	R12, CTR
120	BL	(CTR)
121	MOVD	40(R1), R2
122	BR	done
123
124nocgo:
125	MOVD	$0x800000, R12					   // stacksize = 8192KB
126	MOVD	R12, 8(R1)
127	MOVD	$_rt0_ppc64_aix_lib_go(SB), R12
128	MOVD	R12, 16(R1)
129	MOVD	$runtime·newosproc0(SB),R12
130	MOVD	R12, CTR
131	BL	(CTR)
132
133done:
134	// Restore saved registers.
135	MOVD	48+PARAM_SPACE(R1), R14
136	MOVD	56+PARAM_SPACE(R1), R15
137	MOVD	64+PARAM_SPACE(R1), R16
138	MOVD	72+PARAM_SPACE(R1), R17
139	MOVD	80+PARAM_SPACE(R1), R18
140	MOVD	88+PARAM_SPACE(R1), R19
141	MOVD	96+PARAM_SPACE(R1), R20
142	MOVD	104+PARAM_SPACE(R1), R21
143	MOVD	112+PARAM_SPACE(R1), R22
144	MOVD	120+PARAM_SPACE(R1), R23
145	MOVD	128+PARAM_SPACE(R1), R24
146	MOVD	136+PARAM_SPACE(R1), R25
147	MOVD	144+PARAM_SPACE(R1), R26
148	MOVD	152+PARAM_SPACE(R1), R27
149	MOVD	160+PARAM_SPACE(R1), R28
150	MOVD	168+PARAM_SPACE(R1), R29
151	MOVD	176+PARAM_SPACE(R1), g // R30
152	MOVD	184+PARAM_SPACE(R1), R31
153	FMOVD	196+PARAM_SPACE(R1), F14
154	FMOVD	200+PARAM_SPACE(R1), F15
155	FMOVD	208+PARAM_SPACE(R1), F16
156	FMOVD	216+PARAM_SPACE(R1), F17
157	FMOVD	224+PARAM_SPACE(R1), F18
158	FMOVD	232+PARAM_SPACE(R1), F19
159	FMOVD	240+PARAM_SPACE(R1), F20
160	FMOVD	248+PARAM_SPACE(R1), F21
161	FMOVD	256+PARAM_SPACE(R1), F22
162	FMOVD	264+PARAM_SPACE(R1), F23
163	FMOVD	272+PARAM_SPACE(R1), F24
164	FMOVD	280+PARAM_SPACE(R1), F25
165	FMOVD	288+PARAM_SPACE(R1), F26
166	FMOVD	296+PARAM_SPACE(R1), F27
167	FMOVD	304+PARAM_SPACE(R1), F28
168	FMOVD	312+PARAM_SPACE(R1), F29
169	FMOVD	320+PARAM_SPACE(R1), F30
170	FMOVD	328+PARAM_SPACE(R1), F31
171
172	ADD	$344+PARAM_SPACE, R1
173
174	MOVD	8(R1), R0
175	MOVFL	R0, $0xff
176	MOVD	16(R1), R0
177	MOVD	R0, LR
178	RET
179
180DEFINE_PPC64X_FUNCDESC(_rt0_ppc64_aix_lib_go, __rt0_ppc64_aix_lib_go)
181
182TEXT __rt0_ppc64_aix_lib_go(SB),NOSPLIT,$0
183	MOVD	_rt0_ppc64_aix_lib_argc<>(SB), R3
184	MOVD	_rt0_ppc64_aix_lib_argv<>(SB), R4
185	MOVD	$runtime·rt0_go(SB), R12
186	MOVD	R12, CTR
187	BR	(CTR)
188
189DATA _rt0_ppc64_aix_lib_argc<>(SB)/8, $0
190GLOBL _rt0_ppc64_aix_lib_argc<>(SB),NOPTR, $8
191DATA _rt0_ppc64_aix_lib_argv<>(SB)/8, $0
192GLOBL _rt0_ppc64_aix_lib_argv<>(SB),NOPTR, $8
193