1/*
2 * Copyright (c) 2003 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <machine/asm.h>
28__FBSDID("$FreeBSD$");
29
30		.text
31
32/*
33 * void _start(char **ap, struct ps_strings *, void (*cleanup)(void));
34 */
35#define	AP		in0
36#define	CLEANUP		in2
37
38#define	GP		loc0
39#define	ARGC		loc1
40#define	ARGV		loc2
41#define	ENVP		loc3
42
43		.global		_start
44		.type		_start, @function
45		.proc		_start
46_start:
47		.prologue
48		.save		rp, r0
49		.body
50{		.mlx
51		alloc		r14=ar.pfs,3,4,3,0
52		movl		r15=@gprel(1f)
53}
541:
55{		.mmi
56		ld4		ARGC=[AP]
57		adds		ARGV=8,AP
58		mov		r16=ip
59		;;
60}
61{		.mmi
62		sub		gp=r16,r15
63		sub		GP=r16,r15
64		shladd		r14=ARGC,3,AP
65		;;
66}
67{		.mii
68		addl		r15=@ltoff(environ),gp
69		cmp4.ge		p6,p7=0,ARGC
70		adds		ENVP=16,r14
71		;;
72}
73{		.mmi
74		ld8		r14=[r15]
75(p7)		ld8		r15=[ARGV]
76		addl		r16=@gprel(__progname),gp
77		;;
78}
79{		.mib
80		st8		[r14]=ENVP
81(p7)		cmp.eq		p6,p0=0,r15
82(p6)		br.dpnt		.L1
83		;;
84}
85		/* Normalize __progname. */
86{		.mmi
87		st8		[r16]=r15
88		ld1		r14=[r15],1
89		nop		0
90		;;
91}
92.L0:
93{		.mib
94		cmp4.eq		p7,p0=0,r14
95		cmp4.eq		p6,p0=0x2f,r14
96(p7)		br.dptk		.L1
97		;;
98}
99{		.mmb
100(p6)		st8		[r16]=r15
101		ld1		r14=[r15],1
102		br.dptk.many	.L0
103}
104.L1:
105{		.mib
106		cmp.ne		p7,p0=0,CLEANUP
107		mov		out0=CLEANUP
108(p7)		br.call.sptk	b0=atexit
109		;;
110}
111{		.mfb
112		mov		gp=GP
113		nop		0
114		br.call.sptk	b0=_init_tls
115}
116#ifdef GCRT
117{		.mmi
118		mov		gp=GP
119		;;
120		addl		r14=@ltoff(@fptr(_mcleanup)),gp
121		nop		0
122		;;
123}
124{		.mfb
125		ld8		out0=[r14]
126		nop		0
127		br.call.sptk	b0=atexit
128		;;
129}
130#endif
131{		.mmi
132		mov		gp=GP
133		;;
134		addl		r14=@ltoff(@fptr(_fini)),gp
135		nop		0
136		;;
137}
138{		.mfb
139		ld8		out0=[r14]
140		nop		0
141		br.call.sptk	b0=atexit
142		;;
143}
144#ifdef GCRT
145{		.mmi
146		mov		gp=GP
147		;;
148		addl		r14=@ltoff(eprol),gp
149		addl		r15=@ltoff(etext),gp
150		;;
151}
152{		.mmb
153		ld8		out0=[r14]
154		ld8		out1=[r15]
155		br.call.sptk	b0=monstartup
156		;;
157}
158#endif
159{		.mfb
160		mov		gp=GP
161		nop		0
162		br.call.sptk	b0=_init
163		;;
164}
165{		.mmi
166		mov		gp=GP
167		mov		out0=ARGC
168		mov		out1=ARGV
169}
170{		.mfb
171		mov		out2=ENVP
172		nop		0
173		br.call.sptk	b0=main
174		;;
175}
176{		.mib
177		mov		gp=GP
178		mov		out0=r8
179		br.call.sptk	b0=exit
180		;;
181}
182		.endp		_start
183
184#ifdef GCRT
185eprol:
186#endif
187
188		.rodata
189.empty:		stringz		""
190
191		.sdata
192		.global		__progname
193		.size		__progname,8
194		.type		__progname,@object
195__progname:	data8		.empty
196
197		.common		environ,8,8
198