1 /* crt0.S -- startup file for frv.
3 * Copyright (c) 2002, 2003 Red Hat, Inc
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
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. */
21 .type EXT(__start_cmp),@object
22 .size EXT(__start_cmp),4
30 .type __start,@function
33 call .Lcall /* set up _gp in a pic-friendly manor */
35 P(sethi) #gprelhi(.Lcall), gr5
36 setlo #gprello(.Lcall), gr5
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 */
47 #define FDPIC(...) __VA_ARGS__
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
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
62 /* Using GPREL to compute _GLOBAL_OFFSET_TABLE_'s will force
63 the entire program to relocate as a unit, which is fine for
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
74 sethi #gprelhi(EXT(__start_cmp)), gr5
75 setlo #gprello(EXT(__start_cmp)), gr5
77 subcc gr4, gr6, gr8, icc0
80 P(st) gr4, @(gr5, gr16) /* update so if we restart no need to fixup */
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
91 P(add) gr10, gr16, 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
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
115 FDPIC(mov gr17, gr15)
116 call EXT(__frv_fix_usrptrs)
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 */
142 #define HSR_SET (HSR_ICE|HSR_DCE|HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
144 #define HSR_SET (HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
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 */
163 #define PSR_CLEAR (PSR_EF|PSR_EM)
169 #define PSR_SET (PSR_NEM|PSR_CM|PSR_EF|PSR_EM)
171 #define PSR_SET (PSR_NEM|PSR_CM)
175 /* Enable floating point */
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
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
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
203 FDPIC(mov gr17, gr15)
206 P(setlos) #0, gr8 /* zero argc, argv, envp */
210 FDPIC(mov gr17, gr15)
212 FDPIC(mov gr17, gr15)
215 .size __start,(.Lend-__start)
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
226 P(sub) gr9, gr11, gr9
234 P(st) gr5, @(gr9,gr0)
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
261 cmp gr6, gr0, icc0 /* skip pointers initialized to 0 */
265 P(st) gr6, @(gr5,gr8)
270 .size EXT(__frv_fix_usrptrs),.Lend2-EXT(__frv_fix_usrptrs)