LE support: remove mixed endianness support, this causes libraries to be built with...
[zpugcc.git] / toolchain / gcc / libgloss / mips / crt0.S
blob8810afa6cb1f7cef41d4c05389a1ea6295de6bef
1 /*
2  * crt0.S -- startup file for MIPS.
3  *
4  * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
5  *
6  * The authors hereby grant permission to use, copy, modify, distribute,
7  * and license this software and its documentation for any purpose, provided
8  * that existing copyright notices are retained in all copies and that this
9  * notice is included verbatim in any distributions. No written agreement,
10  * license, or royalty fee is required for any of the authorized uses.
11  * Modifications to this software may be copyrighted by their authors
12  * and need not follow the licensing terms described here, provided that
13  * the new terms are clearly indicated on the first page of each file where
14  * they apply.
15  */
17 #ifdef __mips16
18 /* This file contains 32 bit assembly code.  */
19         .set nomips16
20 #endif
22 #include "regs.S"
25  * Set up some room for a stack. We just grab a chunk of memory.
26  */
27 #define STACK_SIZE  0x4000
28 #define GLOBAL_SIZE 0x2000
30 #define STARTUP_STACK_SIZE      0x0100
32 /* This is for referencing addresses that are not in the .sdata or
33    .sbss section under embedded-pic, or before we've set up gp.  */
34 #ifdef __mips_embedded_pic
35 # ifdef __mips64
36 #  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
37 # else
38 #  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
39 # endif
40 #else /* __mips_embedded_pic */
41 # define LA(t,x) la t,x
42 #endif /* __mips_embedded_pic */
44         .comm   __memsize, 12
45         .comm   __lstack, STARTUP_STACK_SIZE
47         .text
48         .align  2
50 /* Without the following nop, GDB thinks _start is a data variable.
51  * This is probably a bug in GDB in handling a symbol that is at the
52  * start of the .text section.
53  */
54         nop
56         .globl  hardware_hazard_hook .text
57         .globl  _start
58         .ent    _start
59 _start:
60         .set    noreorder
61 #ifdef __mips_embedded_pic
62 #define PICBASE start_PICBASE
63         PICBASE = .+8
64         bal     PICBASE
65         nop
66         move    s0,$31
67 #endif
68 #if !defined(__mips64) || (__mips_fpr==32)
69 #define STATUS_MASK (SR_CU1|SR_PE)
70 #else
71 # For mips3 or mips4, turn on 64-bit addressing and additional float regs
72 #define STATUS_MASK (SR_CU1|SR_PE|SR_FR|SR_KX|SR_SX|SR_UX)
73 #endif
74         li      v0, STATUS_MASK
75         mtc0    v0, C0_SR
76         mtc0    zero, C0_CAUSE
77         nop
79         /* Avoid hazard from FPU enable and other SR changes.  */
80         LA (t0, hardware_hazard_hook)
81         beq     t0,zero,1f
82         nop
83         jal     t0
84         nop
87 /* Check for FPU presence.  Don't check if we know that soft_float is
88    being used.  (This also avoids illegal instruction exceptions.)  */
90 #ifndef __mips_soft_float
91         li      t2,0xAAAA5555
92         mtc1    t2,fp0          /* write to FPR 0 */
93         mtc1    zero,fp1        /* write to FPR 1 */
94         mfc1    t0,fp0
95         mfc1    t1,fp1
96         nop
97         bne     t0,t2,1f        /* check for match */
98         nop
99         bne     t1,zero,1f      /* double check */
100         nop
101         j       2f              /* FPU is present. */
102         nop
103 #endif
105         /* FPU is not present.  Set status register to say that. */
106         li      v0, (STATUS_MASK-(STATUS_MASK & SR_CU1))
107         mtc0    v0, C0_SR
108         nop
109         /* Avoid hazard from FPU disable.  */
110         LA (t0, hardware_hazard_hook)
111         beq     t0,zero,2f
112         nop
113         jal     t0
114         nop
118 /* Fix high bits, if any, of the PC so that exception handling
119    doesn't get confused.  */
120         LA (v0, 3f)
121         jr      v0
122         nop
124         LA (gp, _gp)                            # set the global data pointer
125         .end _start
128  * zero out the bss section.
129  */
130         .globl  __memsize
131         .globl  get_mem_info .text
132         .globl  __stack
133         .globl  __global
134         .ent    zerobss
135 zerobss:
136         LA (v0, _fbss)
137         LA (v1, _end)
139         sw      zero,0(v0)
140         bltu    v0,v1,3b
141         addiu   v0,v0,4                         # executed in delay slot
143         la      t0, __lstack                    # make a small stack so we
144         addiu   sp, t0, STARTUP_STACK_SIZE      # can run some C code
145         la      a0, __memsize                   # get the usable memory size
146         jal     get_mem_info
147         nop
149         /* setup the stack pointer */
150         LA (t0, __stack)                        # is __stack set ?
151         bne     t0,zero,4f
152         nop
154         /* NOTE: a0[0] contains the amount of memory available, and
155                  not the last memory address. */
156         la      a0, __memsize
157         lw      t0,0(a0)                        # last address of memory available
158         la      t1,K0BASE                       # cached kernel memory
159         addu    t0,t0,t1                        # get the end of memory address
160         /* Allocate 32 bytes for the register parameters.  Allocate 16
161            bytes for a null argv and envp.  Round the result up to 64
162            bytes to preserve alignment.  */
163         subu    t0,t0,64
165         move    sp,t0                           # set stack pointer
166         .end    zerobss
169  * initialize target specific stuff. Only execute these
170  * functions it they exist.
171  */
172         .globl  hardware_init_hook .text
173         .globl  software_init_hook .text
174         .type   _fini,@function
175         .type   _init,@function
176         .globl  atexit .text
177         .globl  exit .text
178         .ent    init
179 init:
180         LA (t9, hardware_init_hook)             # init the hardware if needed
181         beq     t9,zero,6f
182         nop
183         jal     t9
184         nop
186         LA (t9, software_init_hook)             # init the hardware if needed
187         beq     t9,zero,7f
188         nop
189         jal     t9
190         nop
192         LA (a0, _fini)
193         jal     atexit
194         nop
196 #ifdef GCRT0
197         .globl  _ftext
198         .globl  _extext
199         LA (a0, _ftext)
200         LA (a1, _etext)
201         jal     monstartup
202         nop
203 #endif
206         jal     _init                           # run global constructors
207         nop
209         addiu   a1,sp,32                        # argv = sp + 32
210         addiu   a2,sp,40                        # envp = sp + 40
211 #if __mips64
212         sd      zero,(a1)                       # argv[argc] = 0
213         sd      zero,(a2)                       # envp[0] = 0
214 #else
215         sw      zero,(a1)
216         sw      zero,(a2)
217 #endif
218         jal     main                            # call the program start function
219         move    a0,zero                         # set argc to 0
221         # fall through to the "exit" routine
222         jal     exit                            # call libc exit to run the G++
223                                                 # destructors
224         move    a0,v0                           # pass through the exit code
225         .end    init
228 /* Assume the PICBASE set up above is no longer valid below here.  */
229 #ifdef __mips_embedded_pic
230 #undef PICBASE
231 #endif
232         
234  * _exit -- Exit from the application. Normally we cause a user trap
235  *          to return to the ROM monitor for another run. NOTE: This is
236  *          the only other routine we provide in the crt0.o object, since
237  *          it may be tied to the "_start" routine. It also allows
238  *          executables that contain a complete world to be linked with
239  *          just the crt0.o object.
240  */
241         .globl  hardware_exit_hook .text
242         .globl  _exit
243         .ent _exit
244 _exit:
246 #ifdef __mips_embedded_pic
247         /* Need to reinit PICBASE, since we might be called via exit()
248            rather than via a return path which would restore old s0.  */
249 #define PICBASE exit_PICBASE
250         PICBASE = .+8
251         bal     PICBASE
252         nop
253         move    s0,$31
254 #endif
255 #ifdef GCRT0
256         LA (t0, _mcleanup)
257         jal     t0
258         nop
259 #endif
260         LA (t0, hardware_exit_hook)
261         beq     t0,zero,1f
262         nop
263         jal     t0
264         nop
267         # break instruction can cope with 0xfffff, but GAS limits the range:
268         break   1023
269         b       7b                              # but loop back just in-case
270         nop
271         .end _exit
273 /* Assume the PICBASE set up above is no longer valid below here.  */
274 #ifdef __mips_embedded_pic
275 #undef PICBASE
276 #endif
278 /* EOF crt0.S */