]> sourceware.org Git - newlib-cygwin.git/blob - libgloss/mips/crt0.S
2013-04-19 Steve Ellcey <sellcey@imgtec.com>
[newlib-cygwin.git] / libgloss / mips / crt0.S
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 */
16
17 #ifdef __mips16
18 /* This file contains 32 bit assembly code. */
19 .set nomips16
20 #endif
21
22 #include "regs.S"
23
24 /*
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
29
30 #define STARTUP_STACK_SIZE 0x0100
31
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 */
43
44 .comm __memsize, 12
45 .comm __lstack, STARTUP_STACK_SIZE
46
47 .text
48 .align 2
49
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
55
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 __mips<3
69 # define STATUS_MASK (SR_CU1|SR_PE)
70 #else
71 /* Post-mips2 has no SR_PE bit. */
72 # ifdef __mips64
73 /* Turn on 64-bit addressing and additional float regs. */
74 # define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
75 # else
76 # if __mips_fpr==32
77 # define STATUS_MASK (SR_CU1)
78 # else
79 /* Turn on additional float regs. */
80 # define STATUS_MASK (SR_CU1|SR_FR)
81 # endif
82 # endif
83 #endif
84 li v0, STATUS_MASK
85 mtc0 v0, C0_SR
86 mtc0 zero, C0_CAUSE
87 nop
88
89 /* Avoid hazard from FPU enable and other SR changes. */
90 LA (t0, hardware_hazard_hook)
91 beq t0,zero,1f
92 nop
93 jal t0
94 nop
95 1:
96
97 /* Check for FPU presence. Don't check if we know that soft_float is
98 being used. (This also avoids illegal instruction exceptions.) */
99
100 #ifndef __mips_soft_float
101 li t2,0xAAAA5555
102 mtc1 t2,fp0 /* write to FPR 0 */
103 mtc1 zero,fp1 /* write to FPR 1 */
104 mfc1 t0,fp0
105 mfc1 t1,fp1
106 nop
107 bne t0,t2,1f /* check for match */
108 nop
109 bne t1,zero,1f /* double check */
110 nop
111 j 2f /* FPU is present. */
112 nop
113 #endif
114 1:
115 /* FPU is not present. Set status register to say that. */
116 li v0, (STATUS_MASK-(STATUS_MASK & SR_CU1))
117 mtc0 v0, C0_SR
118 nop
119 /* Avoid hazard from FPU disable. */
120 LA (t0, hardware_hazard_hook)
121 beq t0,zero,2f
122 nop
123 jal t0
124 nop
125 2:
126
127
128 /* Fix high bits, if any, of the PC so that exception handling
129 doesn't get confused. */
130 LA (v0, 3f)
131 jr v0
132 nop
133 3:
134 LA (gp, _gp) # set the global data pointer
135 .end _start
136
137 /*
138 * zero out the bss section.
139 */
140 .globl __memsize
141 .globl get_mem_info .text
142 .globl __stack
143 .globl __global
144 .ent zerobss
145 zerobss:
146 LA (v0, _fbss)
147 LA (v1, _end)
148 3:
149 sw zero,0(v0)
150 bltu v0,v1,3b
151 addiu v0,v0,4 # executed in delay slot
152
153 la t0, __lstack # make a small stack so we
154 addiu sp, t0, STARTUP_STACK_SIZE # can run some C code
155 la a0, __memsize # get the usable memory size
156 jal get_mem_info
157 nop
158
159 /* setup the stack pointer */
160 LA (t0, __stack) # is __stack set ?
161 bne t0,zero,4f
162 nop
163
164 /* NOTE: a0[0] contains the amount of memory available, and
165 not the last memory address. */
166 la a0, __memsize
167 lw t0,0(a0) # last address of memory available
168 la t1,K0BASE # cached kernel memory
169 addu t0,t0,t1 # get the end of memory address
170 /* Allocate 32 bytes for the register parameters. Allocate 16
171 bytes for a null argv and envp. Round the result up to 64
172 bytes to preserve alignment. */
173 subu t0,t0,64
174 4:
175 move sp,t0 # set stack pointer
176 .end zerobss
177
178 /*
179 * initialize target specific stuff. Only execute these
180 * functions it they exist.
181 */
182 .globl hardware_init_hook .text
183 .globl software_init_hook .text
184 .type _fini,@function
185 .type _init,@function
186 .globl atexit .text
187 .globl exit .text
188 .ent init
189 init:
190 LA (t9, hardware_init_hook) # init the hardware if needed
191 beq t9,zero,6f
192 nop
193 jal t9
194 nop
195 6:
196 LA (t9, software_init_hook) # init the hardware if needed
197 beq t9,zero,7f
198 nop
199 jal t9
200 nop
201 7:
202 LA (a0, _fini)
203 jal atexit
204 nop
205
206 #ifdef GCRT0
207 .globl _ftext
208 .globl _extext
209 LA (a0, _ftext)
210 LA (a1, _etext)
211 jal monstartup
212 nop
213 #endif
214
215
216 jal _init # run global constructors
217 nop
218
219 addiu a1,sp,32 # argv = sp + 32
220 addiu a2,sp,40 # envp = sp + 40
221 #if __mips64
222 sd zero,(a1) # argv[argc] = 0
223 sd zero,(a2) # envp[0] = 0
224 #else
225 sw zero,(a1)
226 sw zero,(a2)
227 #endif
228 jal main # call the program start function
229 move a0,zero # set argc to 0
230
231 # fall through to the "exit" routine
232 jal exit # call libc exit to run the G++
233 # destructors
234 move a0,v0 # pass through the exit code
235 .end init
236
237
238 /* Assume the PICBASE set up above is no longer valid below here. */
239 #ifdef __mips_embedded_pic
240 #undef PICBASE
241 #endif
242
243 /*
244 * _exit -- Exit from the application. Normally we cause a user trap
245 * to return to the ROM monitor for another run. NOTE: This is
246 * the only other routine we provide in the crt0.o object, since
247 * it may be tied to the "_start" routine. It also allows
248 * executables that contain a complete world to be linked with
249 * just the crt0.o object.
250 */
251 .globl hardware_exit_hook .text
252 .globl _exit
253 .ent _exit
254 _exit:
255 7:
256 #ifdef __mips_embedded_pic
257 /* Need to reinit PICBASE, since we might be called via exit()
258 rather than via a return path which would restore old s0. */
259 #define PICBASE exit_PICBASE
260 PICBASE = .+8
261 bal PICBASE
262 nop
263 move s0,$31
264 #endif
265 #ifdef GCRT0
266 LA (t0, _mcleanup)
267 jal t0
268 nop
269 #endif
270 LA (t0, hardware_exit_hook)
271 beq t0,zero,1f
272 nop
273 jal t0
274 nop
275 1:
276
277 # break instruction can cope with 0xfffff, but GAS limits the range:
278 break 1023
279 b 7b # but loop back just in-case
280 nop
281 .end _exit
282
283 /* Assume the PICBASE set up above is no longer valid below here. */
284 #ifdef __mips_embedded_pic
285 #undef PICBASE
286 #endif
287
288 /* EOF crt0.S */
This page took 0.053682 seconds and 5 git commands to generate.