summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/nds32/crt1.S
blob: 54544010f591bc2d56397f16761c82fc826dc49e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
 * Copyright (C) 2016 Andes Technology, Inc.
 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 */

/* Startup code compliant to the ELF NDS32 ABI */

#include <sys/regdef.h>
#include <features.h>
#define BP_SYM(name) name

/* We need to call:
   __uClibc_main (int (*main) (int, char **, char **), int argc,
		      char **argv, void (*init) (void), void (*fini) (void),
		      void (*rtld_fini) (void), void *stack_end)
*/

.text
	.globl	_start
	.type	_start,@function
	.type	_init,@function
	.type	_fini,@function
#ifndef __UCLIBC_CTOR_DTOR__
	.weak	_init
	.weak	_fini
#endif
	.type	    main,@function
	.type	    __uClibc_main,@function
#ifdef SHARED
.pic
1:
	ret
#endif

_start:
	movi    $fp,	0		! clear FP
	lwi	$r1,	[$sp + 0]	! r1 = argc
	addi	$r2,	$sp,	4	! r2 = argv

	/* align sp to 8-byte boundary */
	movi	$r0,	-8
	and	$sp,	$sp,	$r0

	addi	$r6,	$sp,	0	! r6 = stack top

#ifdef SHARED
	/* set gp register */
#ifdef __NDS32_N1213_43U1H__
	jal	1b
	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_)
	ori	$gp,	$gp, LO12(_GLOBAL_OFFSET_TABLE_ + 4)
	add	$gp,	$lp,	$gp
#else
	mfusr 	$r15, 	$PC
	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_+4)
	ori	$gp,	$gp, LO12(_GLOBAL_OFFSET_TABLE_ + 8)
	add	$gp,	$r15,	$gp
#endif

	la		$r3,	_init@GOTOFF
	la		$r4,	_fini@GOTOFF
	la		$r0,	main@GOT

	/* push everything to stack, r5 is rtld_fini and r7 is garbage */
	pushm	$r0,	$r7

	/* now start it up */
	bal	__uClibc_main@PLT

	/* should never get here */
	bal	abort@PLT
#else
	la      $gp, _SDA_BASE_ ! init GP for small data access

	la		$r3,	_init
	la		$r4,	_fini
	la		$r0,	main

	/* push everything to stack, r5 is rtld_fini and r7 is garbage */
	pushm	$r0,	$r7

	/* now start it up */
	bal	__uClibc_main

	/* should never get here */
	bal	abort
#endif
	ret

/* Define a symbol for the first piece of initialized data.  */
	.data
	.globl __data_start
__data_start:
	.long	0
	.weak data_start
	data_start = __data_start