fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / libgloss / frv / crt0.S
blob1a906d8a52697d35bf856a0b2ecaa8b07f3dbae5
1 /* crt0.S -- startup file for frv.
2  * 
3  * Copyright (c) 2002, 2003 Red Hat, Inc
4  *
5  * The authors hereby grant permission to use, copy, modify, distribute,
6  * and license this software and its documentation for any purpose, provided
7  * that existing copyright notices are retained in all copies and that this
8  * notice is included verbatim in any distributions. No written agreement,
9  * license, or royalty fee is required for any of the authorized uses.
10  * Modifications to this software may be copyrighted by their authors
11  * and need not follow the licensing terms described here, provided that
12  * the new terms are clearly indicated on the first page of each file where
13  * they apply.
14  */
16 #include <frv-asm.h>
18         /* statically store .Lcall's address so we can see if we are running
19            at the location we were linked for or a different location.  */
20         .data
21         .type   EXT(__start_cmp),@object
22         .size   EXT(__start_cmp),4
23         .p2align 2
24 EXT(__start_cmp):
25         .picptr  .Lcall
26         
27         .globl  __start
28         .weak   _start
29         .text
30         .type   __start,@function
31 __start:
32 _start:
33         call    .Lcall                          /* set up _gp in a pic-friendly manor */
34 .Lcall: movsg   lr, gr4
35         P(sethi) #gprelhi(.Lcall), gr5
36         setlo    #gprello(.Lcall), gr5
37         P(sub)   gr4, gr5, gr16
39 #if ! __FRV_FDPIC__
40         sethi    #gprelhi(EXT(_stack)), sp      /* load up stack pointer */
41         P(setlo) #gprello(EXT(_stack)), sp
42         setlos   #0, fp                         /* zero fp to allow unwinders to stop */
43         P(add)   sp, gr16, sp
45 #define FDPIC(...)
46 #else
47 #define FDPIC(...) __VA_ARGS__
48         
49         /* The assembler will rightfully claim that
50         #hi/lo(__stacksize) are unsafe for PIC, but since __stacksize
51         is absolute, and we don't want it to be relocated, we should
52         be fine.  */
54         sethi   #gprelhi(EXT(__end)), gr6
55         P(sethi) #hi(EXT(__stacksize+7)), gr5
56         setlo   #gprello(EXT(__end)), gr6
57         P(setlo) #lo(EXT(__stacksize+7)), gr5
58         add     gr6, gr16, gr6
59         add     gr6, gr5, gr5
60         andi    gr5, -8, sp
62         /* Using GPREL to compute _GLOBAL_OFFSET_TABLE_'s will force
63         the entire program to relocate as a unit, which is fine for
64         frv-elf.  */
65         
66         P(sethi) #gprelhi(EXT(_GLOBAL_OFFSET_TABLE_)), gr15
67         setlo    #gprello(EXT(_GLOBAL_OFFSET_TABLE_)), gr15
68         /* We compute the value in a call-saved register (that happens
69         to be the PIC register in the EABI, and copy it to gr15 before
70         every call.  */
71         add      gr15, gr16, gr17
72 #endif
74         sethi    #gprelhi(EXT(__start_cmp)), gr5
75         setlo    #gprello(EXT(__start_cmp)), gr5
76         ld       @(gr5,gr16), gr6
77         subcc   gr4, gr6, gr8, icc0
78         beq     icc0, 0, .Lfixed
80         P(st)   gr4, @(gr5, gr16)       /* update so if we restart no need to fixup */
81         setlos  4, gr11
83 #if ! __FRV_FDPIC__
85                                         /* fixup the .ctors list */
86         sethi    #gprelhi(EXT(__CTOR_LIST__)), gr9
87         P(sethi) #gprelhi(EXT(__CTOR_END__)), gr10
88         setlo    #gprello(EXT(__CTOR_LIST__)), gr9
89         P(setlo) #gprello(EXT(__CTOR_END__)), gr10
90         add      gr9, gr16, gr9
91         P(add)   gr10, gr16, gr10
92         addi     gr9, 4, gr9
93         P(subi)  gr10, 4, gr10
94         call     EXT(__frv_fixptrs)
96                                         /* fixup the .dtors list */
97         P(sethi) #gprelhi(EXT(__DTOR_LIST__)), gr9
98         sethi    #gprelhi(EXT(__DTOR_END__)), gr10
99         P(setlo) #gprello(EXT(__DTOR_LIST__)), gr9
100         setlo    #gprello(EXT(__DTOR_END__)), gr10
101         P(add)   gr9, gr16, gr9
102         add      gr10, gr16, gr10
103         P(addi)  gr9, 4, gr9
104         subi     gr10, 4, gr10
105         call     EXT(__frv_fixptrs)
106 #endif /* ! __FRV_FDPIC__ */
108                                         /* fixup the .dtors list */
109         P(sethi) #gprelhi(EXT(__ROFIXUP_LIST__)), gr9
110         sethi    #gprelhi(EXT(__ROFIXUP_END__)), gr10
111         P(setlo) #gprello(EXT(__ROFIXUP_LIST__)), gr9
112         setlo    #gprello(EXT(__ROFIXUP_END__)), gr10
113         P(add)   gr9, gr16, gr9
114         add      gr10, gr16, gr10
115         FDPIC(mov gr17, gr15)
116         call     EXT(__frv_fix_usrptrs)
118 .Lfixed:
120 /* HSR flags */
121 #define HSR_ICE  0x80000000             /* Instruction cache enable */
122 #define HSR_DCE  0x40000000             /* Data cache enable */
123 #define HSR_CBM  0x08000000             /* Cache copy back mode */
124 #define HSR_EIMM 0x04000000             /* Enable Instruction MMU */
125 #define HSR_EDMM 0x02000000             /* Enable Data MMU */
126 #define HSR_EMEM 0x00800000             /* Enable MMU miss exception mask */
127 #define HSR_RME  0x00400000             /* Ram mode enable */
128 #define HSR_SA   0x00001000             /* Start address */
129 #define HSR_FRN  0x00000800             /* Number of FPRs */
130 #define HSR_GRN  0x00000400             /* Number of GPRs */
131 #define HSR_FRHE 0x00000200             /* FR Higher Enable */
132 #define HSR_FRLE 0x00000100             /* FR Lower Enable */
133 #define HSR_GRHE 0x00000080             /* GR Higher Enable */
134 #define HSR_GRLE 0x00000040             /* GR Lower Enable */
136 #ifndef HSR_CLEAR
137 #define HSR_CLEAR 0
138 #endif
140 #ifndef HSR_SET
141 #ifndef FRV_NO_CACHE
142 #define HSR_SET (HSR_ICE|HSR_DCE|HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
143 #else
144 #define HSR_SET (HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
145 #endif
146 #endif
148 /* PSR flags */
149 #define PSR_ICE  0x00010000             /* In circuit emulation mode */
150 #define PSR_NEM  0x00004000             /* Non-exception mode */
151 #define PSR_CM   0x00002000             /* Conditional mode */
152 #define PSR_BE   0x00001000             /* Big endian mode */
153 #define PSR_EF   0x00000100             /* Enable floating point */
154 #define PSR_EM   0x00000080             /* Enable media instructions */
155 #define PSR_S    0x00000004             /* Enable supervisor mode */
156 #define PSR_PS   0x00000002             /* Previous supervisor mode */
157 #define PSR_ET   0x00000001             /* Enable interrupts */
159 #ifndef PSR_CLEAR
160 #if __FRV_FPR__
161 #define PSR_CLEAR 0
162 #else
163 #define PSR_CLEAR (PSR_EF|PSR_EM)
164 #endif
165 #endif
167 #ifndef PSR_SET
168 #if __FRV_FPR__
169 #define PSR_SET (PSR_NEM|PSR_CM|PSR_EF|PSR_EM)
170 #else
171 #define PSR_SET (PSR_NEM|PSR_CM)
172 #endif
173 #endif
175         /* Enable floating point */
176         movsg     hsr0, gr4
177         P(sethi)  #hi(HSR_SET), gr5
178         setlo     #lo(HSR_SET), gr5
179         P(sethi)  #hi(~HSR_CLEAR), gr6
180         setlo     #lo(~HSR_CLEAR), gr6
181         or        gr4, gr5, gr4
182         and       gr4, gr6, gr4
183         movgs     gr4, hsr0
185         movsg     psr, gr4
186         P(sethi)  #hi(PSR_SET), gr5
187         setlo     #lo(PSR_SET), gr5
188         P(sethi)  #hi(~PSR_CLEAR), gr6
189         setlo     #lo(~PSR_CLEAR), gr6
190         or        gr4, gr5, gr4
191         and       gr4, gr6, gr4
192         movgs     gr4, psr
194         /* zero the bss area */
195         P(sethi)  #gprelhi(__bss_start), gr8
196         sethi     #gprelhi(__end), gr4
197         P(setlo)  #gprello(__bss_start), gr8
198         setlo     #gprello(__end), gr4
199         P(add)    gr8, gr16, gr8
200         add       gr4, gr16, gr4
201         P(setlos) #0, gr9
202         sub       gr4, gr8, gr10
203         FDPIC(mov gr17, gr15)
204         call      EXT(memset)
206         P(setlos) #0, gr8               /* zero argc, argv, envp */
207         setlos    #0, gr9
208         P(setlos) #0, gr10
210         FDPIC(mov gr17, gr15)
211         call      EXT(main)
212         FDPIC(mov gr17, gr15)
213         call      EXT(exit)
214 .Lend:
215         .size   __start,(.Lend-__start)
217 #if ! __FRV_FDPIC__
218         /* Routine to adjust pointers
219            gr8  = difference to adjust by
220            gr9  = starting address
221            gr10 = ending address + 4
222            gr11 = amount to add to the pointer each iteration.  */
223         .globl  EXT(__frv_fixptrs)
224         .type   EXT(__frv_fixptrs),@function
225 EXT(__frv_fixptrs):
226         P(sub)  gr9, gr11, gr9
227         sub     gr10, gr11, gr10
228 .Lloop2:
229         cmp     gr10, gr9, icc0
230         bls     icc0, 0, .Lret2
232         ldu     @(gr9,gr11), gr5
233         add     gr8, gr5, gr5
234         P(st)   gr5, @(gr9,gr0)
235         bra     .Lloop2
237 .Lret2: ret
238 .Lend2:
239         .size   EXT(__frv_fixptrs),.Lend2-EXT(__frv_fixptrs)
240 #endif /* ! __FRV_FDPIC__ */
242         /* Routine to adjust statically initialized pointers
243            Note since these are pointers to pointers, they
244            need to be adjusted themsevles.
246            gr8  = difference to adjust by
247            gr9  = starting address
248            gr10 = ending address + 4
249            gr11 = amount to add to the pointer each iteration.  */
250         .globl  EXT(__frv_fix_usrptrs)
251         .type   EXT(__frv_fix_usrptrs),@function
252 EXT(__frv_fix_usrptrs):
253         P(sub)  gr9, gr11, gr9
254         sub     gr10, gr11, gr10
255 .Lloop3:
256         cmp     gr10, gr9, icc0
257         bls     icc0, 0, .Lret3
259         ldu     @(gr9,gr11), gr5
260         ld      @(gr5, gr8), gr6
261         cmp     gr6, gr0, icc0          /* skip pointers initialized to 0 */
262         beq     icc0, 0, .Lloop3
264         add     gr8, gr6, gr6
265         P(st)   gr6, @(gr5,gr8)
266         bra     .Lloop3
268 .Lret3: ret
269 .Lend3:
270         .size   EXT(__frv_fix_usrptrs),.Lend2-EXT(__frv_fix_usrptrs)