1; Copyright (c) 2000-2009 ARC International
2	.file	"crt1cl.s"
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;;; Startup
6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7	.text
8	.weak	_SDA_BASE_
9
10	.macro jmpl,target
11		jl	target		; "large" model call
12	.endm
13
14    	.on	assume_short, assume_nop_short
15	.define S, _s
16
17	; Indicate whether registers should be initialized with 0
18	; This might be desirable if executing in an environment where
19	; registers may contain undefined values on startup.
20	.define PERFORM_REGISTER_INITIALIZATION, 0
21
22	.section .text$crt00, text
23	.global	_start
24	.type	_start, @function
25	.reloc __crt_callmain, 0
26_start:
27
28.if PERFORM_REGISTER_INITIALIZATION
29	; Initialize the register file.
30	; Compiled code may generate sub  r0, r1, r1, expecting to
31	; load 0 into r0, but in some execution environments the individual
32	; reads of r1 for the two source operands may return different
33	; (garbage) values if r1 had never been written to since reset.
34
35    .ifdef _ARC_RF16
36	.irep num, 1, 2, 3, 10, 11, 12, 13, 14, 15
37		mov	r\&num, 0
38	.endr
39    .else
40	.irep num, 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
41		mov	r\&num, 0
42	.endr
43    .endif
44
45.endif
46
47	.weak __xcheck
48
49.ifdef _PICTABLE
50	; under PICTABLE, r0 is assumed to contain the base of the data segment
51	; so must preserve it.  __xcheck modifies only r0 and r1 and is
52	; position-independent
53	mov	r2, r0
54        mov.f	r0, __xcheck
55	beq	.Linit_pic
56
57	bl	__xcheck
58	mov	r0, r2
59
60    .Linit_pic:
61	.weak	__PICTABLE__
62	; In PIC mode, we assume that we were loaded by a loader and may not
63	; reside at the addresses that the ELF file was linked with.  In
64	; this case, the address of where the data segment has been loaded
65	; is passed to _start in the r0 register.  We figure out the new code
66	; segment base ourselves.
67	mov	r2, __PICTABLE__
68	sub.f	0, r2, 0
69	nop		; required for -a4 -core5
70	beq	no_pic
71	bl	_init_pic
72
73no_pic:
74.endif
75
76    .Lsetstack:
77	; like smp_processor_id() from arc.h
78    ; AUX_IDENTITY Reg [ 3  2  1  0 ]
79    ;                  ^^^      => 0 for Master, !0 otherwise
80    ; Note: this is setup for 2 cores and needs to be augmented if more than 2 cores
81    lr   r0, [identity]
82    lsr  r0, r0, 8
83    bmsk r0, r0, 7
84    .ifndef TX_ZERO_BASED_CORE_ID
85    breq r0, 2, .Lsecondary
86    .else
87    breq r0, 1, .Lsecondary
88    .endif
89    mov sp, STACK1_END ; initialize stack pointer, core 1
90	b .Lcontinue
91.Lsecondary:
92    mov sp, STACK2_END ; initialize stack pointer, core 2
93.Lcontinue:
94	mov	gp, _SDA_BASE_	; initialize small-data base register
95	mov	fp, 0		; initialize frame pointer
96
97__crt_start:
98	; various components may get placed here by the linker:
99	; priority    optional component                  command-line option
100	;----------------------------------------------------------------------
101	; 10          _init_ldi,_init_jli,_init_ei,       automated
102	;             _init_sjli
103	; 20          __crt_initcopy                      -Hcrt_initcopy
104	; 25          __crt_initbss                       -Hcrt_initbss
105	; 30          __crt_invcache                      -Hcrt_invcache
106	; 70          __crt_inittimer                     -Hcrt_inittimer
107	; 80          _init                               forced included below
108	; 90          __crt_callmain                      forced, with
109	;                                                   optional -Hcrt_argv
110
111	.cfa_bf	_start
112
113	.section .text$crt99, text
114	.sectflag .text$crt99, include
115; INIT CODE FALLS THROUGH TO _exit_halt
116	.cfa_ef
117
118	.global	_exit_halt
119	.type	_exit_halt, @function
120_exit_halt:
121	.cfa_bf	_exit_halt
122
123	flag	0x01
124	nop
125    .if ! $is_arcv2
126	; ARC 700 serializes on 'flag', so no way to get back to here.
127	nop
128	nop
129    .endif
130	b	_exit_halt
131
132	.reloc	main, 0; force main in if its in a library
133	.cfa_ef
134
135	.section .text$crt80, text
136	.sectflag .text$crt80, include
137__crt_init:
138	bl	_init
139
140	.previous
141	; weak versions of small data symbols normally defined by the linker.
142	.weak	_fsbss
143	.weak	_esbss
144	.set	_fsbss,0
145	.set	_esbss,0
146
147	; weak versions of BSS section symbols in case there is no .bss section
148	.weak	_fbss
149	.weak	_ebss
150	.set	_fbss,0
151	.set	_ebss,0
152
153	; weak versions of heap section boundaries.  If a .heap section
154	; is provided, our low-level allocator "sbrk" allocates within it.
155	; If no .heap is provided, we allocate from _end to the end of memory.
156	.weak	_fheap
157	.weak	_eheap
158	.set	_fheap,0
159	.set	_eheap,0
160
161	; reference the beginning of the stack for debugger's stack checking
162	.weak	_fstack
163	.set	_fstack,0
164
165	.end
166
167