source: trunk/libs/newlib/src/libgloss/arc/crt0.S @ 476

Last change on this file since 476 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 8.1 KB
Line 
1/*
2   Copyright (c) 2015-2016, Synopsys, Inc. All rights reserved.
3
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are met:
6
7   1) Redistributions of source code must retain the above copyright notice,
8   this list of conditions and the following disclaimer.
9
10   2) Redistributions in binary form must reproduce the above copyright notice,
11   this list of conditions and the following disclaimer in the documentation
12   and/or other materials provided with the distribution.
13
14   3) Neither the name of the Synopsys, Inc., nor the names of its contributors
15   may be used to endorse or promote products derived from this software
16   without specific prior written permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28   POSSIBILITY OF SUCH DAMAGE.
29*/
30
31/*
32   The startup code for the ARC family of processors does the following before
33   transferring control to user defined main label:
34       1.  Set sp to __stack_top (link time variable)
35       2.  Set fp to zero
36       3.  Zero out the bss section (for uninitialized globals)
37   After returning from main, the processor is halted and the pipeline is
38   flushed out.
39
40   We expect argc in r0 and argv in r1.  These are saved in r13 / r14 during
41   the initialization code.
42*/
43
44/* Compatibility with older ARC GCC, that doesn't provide some of the
45   preprocessor defines used by newlib and libgloss for ARC.  */
46#if defined (__Xbarrel_shifter) && !defined (__ARC_BARREL_SHIFTER__)
47#define __ARC_BARREL_SHIFTER__ 1
48#endif
49
50#if defined (__EM__) && !defined (__ARCEM__)
51#define __ARCEM__ 1
52#endif
53
54#if defined (__HS__) && !defined (__ARCHS__)
55#define __ARCHS__ 1
56#endif
57
58        .file   "crt0.S"
59        .extern main
60
61#if defined (__ARCEM__) || defined (__ARCHS__)
62        .section .ivt, "a", @progbits
63
64; Helper macro to define weak symbols to include into interrupt vector table.
65; User code may define those functions in them, so user function will be
66; referenced in the IVT. By default all handlers point to _exit_halt - so they
67; always cause application halt, because if application causes an exception or
68; interrupt, but doesn't set a handler for it - something is wrong in
69; application. Exception is "start" entry of IVT, which points to __start
70; function.
71#define IVT_ENTRY(name) \
72    .word name `\
73    .weak name `\
74    .set name, _exit_halt
75
76; handler's name,          number, name,       offset in IVT (hex/dec)
77.word __start                ; 0   program entry point  0x0     0
78IVT_ENTRY(memory_error)      ; 1   memory_error         0x4     4
79IVT_ENTRY(instruction_error) ; 2   instruction_error    0x8     8
80IVT_ENTRY(EV_MachineCheck)   ; 3   EV_MachineCheck      0xC     12
81IVT_ENTRY(EV_TLBMissI)       ; 4   EV_TLBMissI          0x10    16
82IVT_ENTRY(EV_TLBMissD)       ; 5   EV_TLBMissD          0x14    20
83IVT_ENTRY(EV_ProtV)          ; 6   EV_ProtV             0x18    24
84IVT_ENTRY(EV_PrivilegeV)     ; 7   EV_PrivilegeV        0x1C    28
85IVT_ENTRY(EV_SWI)            ; 8   EV_SWI               0x20    32
86IVT_ENTRY(EV_Trap)           ; 9   EV_Trap              0x24    36
87IVT_ENTRY(EV_Extension)      ; 10  EV_Extension         0x28    40
88IVT_ENTRY(EV_DivZero)        ; 11  EV_DivZero           0x2C    44
89IVT_ENTRY(EV_DCError)        ; 12  EV_DCError           0x30    48
90IVT_ENTRY(EV_Maligned)       ; 13  EV_Maligned          0x34    52
91IVT_ENTRY(EV_Ex14)           ; 14  unused               0x38    56
92IVT_ENTRY(EV_Ex15)           ; 15  unused               0x3C    60
93IVT_ENTRY(IRQ_Timer0)        ; 16  Timer 0              0x40    64
94IVT_ENTRY(IRQ_Timer1)        ; 17  Timer 1              0x44    68
95IVT_ENTRY(IRQ_18)            ; 18                       0x48    72
96IVT_ENTRY(IRQ_19)            ; 19                       0x4C    76
97IVT_ENTRY(IRQ_20)            ; 20                       0x50    80
98
99        .section .text.__startup, "ax", @progbits
100#else
101        .text
102#endif /* __ARCEM__ || __ARCHS__ */
103
104        .global __start
105        .type   __start, @function
106        .align 4
107#ifdef __ARC601__
108; Startup code for the ARC601 processor
109__start:
110        mov     gp, @__SDATA_BEGIN__
111        mov     sp, @__stack_top        ; Point to top of stack
112        mov     r5, 0                   ; Zero value
113        mov_s   r2, @__sbss_start       ; r2 = start of the bss section
114        sub     r3, @_end, r2           ; r3 = size of the bss section in bytes
115
116        asr_s   r3, r3
117        asr_s   r3, r3                  ; r3 = size of bss in words
118
119.Lbss_loop:
120        cmp     r3, 0xff                ; Check for max lp_count
121        mov.le  lp_count, r3
122        mov.gt  lp_count, 0xff
123        lpnz    2f                      ; Loop to zero bss
124        st.ab   r5,[r2, 4]              ; Write word of zeros
125        nop
1262:
127        sub.f   r3, r3, 0xff            ; Decrement word count
128        jp      .Lbss_loop
129
130#else   /* __ARC601__ */
131
132; Startup code for the ARC600, ARC700 and ARCv2 processors
133; NOTE:  The following restrictions apply on zero overhead loops (other
134; restrictions are not pertinent to this code)
135; - loop end should be 4 instruction words away from the lp_count setting
136;   instruction
137; - loop body should have at least two instruction words
138__start:
139#if defined (__ARCHS__)
140        ; Allow unaligned accesses.
141        lr      r2, [0xA]
142        bset    r2, r2, 19
143        flag    r2
144#endif
145
146#if defined (__ARC_CODE_DENSITY__)
147        ;; Initialize jli_base
148        sr      @__JLI_TABLE__,[jli_base]
149#endif
150        mov     gp, @__SDATA_BEGIN__
151        mov_s   r2, @__sbss_start       ; r2 = start of the bss section
152        sub     r3, @_end, r2           ; r3 = size of the bss section in bytes
153        ; set up the loop counter register to the size (in words) of the bss section
154#if defined (__ARC_BARREL_SHIFTER__)
155        asr.f        lp_count, r3, 2
156#else
157        asr_s        r13, r3
158        asr.f        lp_count, r13
159#endif
160#if defined (__ARC600__)
161        ; loop to zero out the bss.  Enter loop only if lp_count != 0
162        lpnz    @.Lend_zbss
163        add     r3, pcl, 20
164        sr      r3, [2]                 ; LP_END
165        ; initialize stack pointer, and this instruction has 2 words
166        mov     sp, @__stack_top
167        mov_s   r3, 0
168        st.ab   r3, [r2, 4]             ; zero out the word
169.Lend_zbss:
170#else
171        mov     sp, @__stack_top        ; initialize stack pointer
172        mov_s   r3,0
173        ; loop to zero out the bss.  Enter loop only if lp_count != 0
174        lpnz    @.Lend_zbss
175        st.ab   r3,[r2, 4]              ; zero out the word
176        nop
177.Lend_zbss:
178#endif
179
180#endif /* !__ARC601__ */
181
182; Some  targets use the .init and .fini sections to create constructors and
183; destructors, and for these targets we need to call the _init function and
184; arrange for _fini to be called at program exit.
185        mov_s   r13, r0
186        mov_s   r14, r1
187        ; calling atexit drags in malloc, so instead poke the function
188        ; address directly into the reent structure
189        ld      r1, [gp, @_impure_ptr@sda]
190        mov_s   r0, @_fini
191        add     r1, r1, 0x14c           ; &_GLOBAL_REENT->atexit0
192        st      r1, [r1, -4]            ; _GLOBAL_REENT->atexit
193        st_s    r0, [r1, 8]             ; _GLOBAL_REENT->atexit0._fns[0]
194        mov_s   r0, 1
195        st_s    r0, [r1, 4]             ; _GLOBAL_REENT->atexit0._ind
196; branch to _init
197#if defined (__ARCEM__) || defined (__ARCHS__)
198        jl      @_init
199#else
200        bl      @_init
201#endif /* __ARCEM__ || __ARCHS__ */
202
203#ifdef PROFILE_SUPPORT /* Defined in gcrt0.S.  */
204        mov     r0,@__start
205        mov     r1,@_etext
206        jl      @_monstartup
207#endif /* PROFILE_SUPPORT */
208
209        mov_s   r0, r13
210        mov_s   r1, r14
211; branch to main
212#if defined (__ARCEM__) || defined (__ARCHS__)
213        mov     fp,0                    ; initialize frame pointer
214        jl      @main
215#else
216        bl.d    @main
217        mov     fp, 0                   ; initialize frame pointer
218#endif /* __ARCEM__ || __ARCHS__ */
219
220#ifdef PROFILE_SUPPORT
221        mov     r13, r0         ; Save return code
222        jl      @_mcleanup
223        mov     r0, r13
224#endif /* PROFILE_SUPPORT */
225
226        ; r0 contains exit code
227        j       @exit
228
229.section .text._exit_halt,"ax",@progbits
230.global  _exit_halt
231.type    _exit_halt, @function
232        .align 4
233_exit_halt:
234        ; r0 contains exit code
235        flag    1
236#if defined (__ARC600__) || defined (__ARC700__)
237        ; ARCompact requires 3 nops after flag 1
238        nop
239        nop
240        nop
241#endif
242        b       @_exit_halt
243.balign 4
Note: See TracBrowser for help on using the repository browser.