source: trunk/libs/newlib/src/libgloss/mips/crt0.S @ 686

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

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

File size: 7.3 KB
Line 
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/* This file does not use any floating-point ABI.  */
18        .gnu_attribute 4,0
19
20#ifdef __mips16
21/* This file contains 32 bit assembly code.  */
22        .set nomips16
23#endif
24
25#include "regs.S"
26#include "abiflags.S"
27
28/*
29 * Set up some room for a stack. We just grab a chunk of memory.
30 */
31#define STACK_SIZE  0x4000
32#define GLOBAL_SIZE 0x2000
33
34#define STARTUP_STACK_SIZE      0x0100
35
36/* This is for referencing addresses that are not in the .sdata or
37   .sbss section under embedded-pic, or before we've set up gp.  */
38#ifdef __mips_embedded_pic
39# ifdef __mips64
40#  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
41# else
42#  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
43# endif
44#else /* __mips_embedded_pic */
45# define LA(t,x) la t,x
46#endif /* __mips_embedded_pic */
47
48        .comm   __memsize, 12
49        .comm   __lstack, STARTUP_STACK_SIZE
50
51        .text
52        .align  2
53
54/* Without the following nop, GDB thinks _start is a data variable.
55 * This is probably a bug in GDB in handling a symbol that is at the
56 * start of the .text section.
57 */
58        nop
59
60        .globl  hardware_hazard_hook .text
61        .globl  _start
62        .ent    _start
63_start:
64#ifdef __mips_embedded_pic
65#define PICBASE start_PICBASE
66        .set    noreorder
67        PICBASE = .+8
68        bal     PICBASE
69        nop
70        move    s0,$31
71        .set    reorder
72#endif
73#if __mips<3
74#  define STATUS_MASK (SR_CU1|SR_PE)
75#else
76/* Post-mips2 has no SR_PE bit.  */
77#  ifdef __mips64
78/* Turn on 64-bit addressing and additional float regs.  */
79#    define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
80#  else
81#    if __mips_fpr==32
82#      define STATUS_MASK (SR_CU1)
83#    else
84/* Turn on additional float regs.  */
85#      define STATUS_MASK (SR_CU1|SR_FR)
86#    endif
87#  endif
88#endif
89
90        /* Clear Cause register.  */
91        mtc0    zero,C0_CAUSE
92        nop
93
94        /* Read MIPS_abiflags structure and set status/config registers
95           accordingly.  */
96        .weak   __MIPS_abiflags_start
97        .weak   __MIPS_abiflags_end
98        LA      (t0,__MIPS_abiflags_start)
99        LA      (t1,__MIPS_abiflags_end)
100        addiu   t1,t1,-24
101        move    v0,zero                 /* Mask for C0_SR.  */
102
103        /* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.  This
104           indicates it is either missing or corrupt.  */
105        bne     t0,t1,1f
106
107        /* Check isa_level.  */
108        lbu     t1,ABIFlags_isa_level(t0)
109        sltu    v1,t1,3                 /* Is MIPS < 3?  */
110        xori    t1,t1,64                /* Is MIPS64?  */
111        beq     v1,zero,4f
112        li      v1,SR_PE
113        or      v0,v0,v1                /* Enable soft reset.  */
1144:
115        li      v1,(SR_KX|SR_SX|SR_UX)
116        bne     t1,zero,5f
117        or      v0,v0,v1                /* Enable extended addressing.  */
1185:
119        /* Check fp_abi.  */
120        lbu     t1,ABIFlags_fp_abi(t0)
121        xori    t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
122        li      v1,SR_CU1
123        beq     t1,zero,2f              /* Skip MSA and cpr1_size checks.  */
124        or      v0,v0,v1                /* Enable co-processor 1.  */
125
126        /* Check cpr1_size.  */
127        lbu     t1,ABIFlags_cpr1_size(t0)
128        xori    t1,t1,AFL_REG_64
129        li      v1,SR_FR
130        bne     t1,zero,3f
131        or      v0,v0,v1                /* Enable 64-bit FPU registers.  */
1323:
133        /* Check ases.  */
134        lw      t1,ABIFlags_ases(t0)
135        andi    t1,t1,AFL_ASE_MSA
136        li      v1,SR_FR
137        beq     t1,zero,2f
138        or      v0,v0,v1                /* Enable 64-bit FPU registers.  */
139        li      v1,SR_MSA
140        .set    push
141        .set    mips32
142        mtc0    v1,C0_CONFIG,5          /* Enable MSA.  */
143        .set    pop
144        b       2f
145
1461:
147        /* MIPS_abiflags structure is not available.  Set status/config
148           registers based on flags defined by compiler.  */
149#ifdef __mips_soft_float
150        li      v0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
151#else
152        li      v0,STATUS_MASK
153#endif
154
1552:
156        /* Set C0_SR,  */
157        mtc0    v0,C0_SR
158        nop
159
160        /* Avoid hazard from C0_SR changes.  */
161        LA      (t0, hardware_hazard_hook)
162        beq     t0,zero,2f
163        jalr    t0
1642:
165
166
167/* Fix high bits, if any, of the PC so that exception handling doesn't get
168   confused.  */
169        LA (v0, 3f)
170        jr      v0
1713:
172        LA (gp, _gp)                            # set the global data pointer
173        .end _start
174
175/*
176 * zero out the bss section.
177 */
178        .globl  __memsize
179        .globl  get_mem_info .text
180        .globl  __stack
181        .globl  __global
182        .ent    zerobss
183zerobss:
184        LA (v0, _fbss)
185        LA (v1, _end)
186        beq     v0,v1,2f
1871:
188        addiu   v0,v0,4
189        sw      zero,-4(v0)
190        bne     v0,v1,1b
1912:
192        la      t0, __lstack                    # make a small stack so we
193        addiu   sp, t0, STARTUP_STACK_SIZE      # can run some C code
194        la      a0, __memsize                   # get the usable memory size
195        jal     get_mem_info
196
197        /* setup the stack pointer */
198        LA (t0, __stack)                        # is __stack set ?
199        bne     t0,zero,4f
200
201        /* NOTE: a0[0] contains the amount of memory available, and
202                 not the last memory address. */
203        la      a0, __memsize
204        lw      t0,0(a0)                        # last address of memory available
205        la      t1,K0BASE                       # cached kernel memory
206        addu    t0,t0,t1                        # get the end of memory address
207        /* Allocate 32 bytes for the register parameters.  Allocate 16
208           bytes for a null argv and envp.  Round the result up to 64
209           bytes to preserve alignment.  */
210        subu    t0,t0,64
2114:
212        move    sp,t0                           # set stack pointer
213        .end    zerobss
214
215/*
216 * initialize target specific stuff. Only execute these
217 * functions it they exist.
218 */
219        .globl  hardware_init_hook .text
220        .globl  software_init_hook .text
221        .type   _fini,@function
222        .type   _init,@function
223        .globl  atexit .text
224        .globl  exit .text
225        .ent    init
226init:
227        LA (t9, hardware_init_hook)             # init the hardware if needed
228        beq     t9,zero,6f
229        jalr    t9
2306:
231        LA (t9, software_init_hook)             # init the hardware if needed
232        beq     t9,zero,7f
233        jalr    t9
2347:
235        LA (a0, _fini)
236        jal     atexit
237
238#ifdef GCRT0
239        .globl  _ftext
240        .globl  _extext
241        LA (a0, _ftext)
242        LA (a1, _etext)
243        jal     monstartup
244#endif
245
246
247        jal     _init                           # run global constructors
248
249        addiu   a1,sp,32                        # argv = sp + 32
250        addiu   a2,sp,40                        # envp = sp + 40
251#if __mips64
252        sd      zero,(a1)                       # argv[argc] = 0
253        sd      zero,(a2)                       # envp[0] = 0
254#else
255        sw      zero,(a1)
256        sw      zero,(a2)
257#endif
258        move    a0,zero                         # set argc to 0
259        jal     main                            # call the program start function
260
261        # fall through to the "exit" routine
262        move    a0,v0                           # pass through the exit code
263        jal     exit                            # call libc exit to run the G++
264                                                # destructors
265        .end    init
266
267 
268/* Assume the PICBASE set up above is no longer valid below here.  */
269#ifdef __mips_embedded_pic
270#undef PICBASE
271#endif
272       
273/*
274 * _exit -- Exit from the application. Normally we cause a user trap
275 *          to return to the ROM monitor for another run. NOTE: This is
276 *          the only other routine we provide in the crt0.o object, since
277 *          it may be tied to the "_start" routine. It also allows
278 *          executables that contain a complete world to be linked with
279 *          just the crt0.o object.
280 */
281        .globl  hardware_exit_hook .text
282        .globl  _exit
283        .ent _exit
284_exit:
2857:
286#ifdef __mips_embedded_pic
287        /* Need to reinit PICBASE, since we might be called via exit()
288           rather than via a return path which would restore old s0.  */
289#define PICBASE exit_PICBASE
290        .set    noreorder
291        PICBASE = .+8
292        bal     PICBASE
293        nop
294        move    s0,$31
295        .set    reorder
296#endif
297#ifdef GCRT0
298        LA (t0, _mcleanup)
299        jalr    t0
300#endif
301        LA (t0, hardware_exit_hook)
302        beq     t0,zero,1f
303        jalr    t0
3041:
305
306        # break instruction can cope with 0xfffff, but GAS limits the range:
307        break   1023
308        b       7b                              # but loop back just in-case
309        .end _exit
310 
311/* Assume the PICBASE set up above is no longer valid below here.  */
312#ifdef __mips_embedded_pic
313#undef PICBASE
314#endif
315
316/* EOF crt0.S */
Note: See TracBrowser for help on using the repository browser.