[444] | 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 | */ |
---|
| 15 | |
---|
| 16 | #include <frv-asm.h> |
---|
| 17 | |
---|
| 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 |
---|
| 38 | |
---|
| 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 |
---|
| 44 | |
---|
| 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. */ |
---|
| 53 | |
---|
| 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 |
---|
| 61 | |
---|
| 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 |
---|
| 73 | |
---|
| 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 |
---|
| 79 | |
---|
| 80 | P(st) gr4, @(gr5, gr16) /* update so if we restart no need to fixup */ |
---|
| 81 | setlos 4, gr11 |
---|
| 82 | |
---|
| 83 | #if ! __FRV_FDPIC__ |
---|
| 84 | |
---|
| 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) |
---|
| 95 | |
---|
| 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__ */ |
---|
| 107 | |
---|
| 108 | /* fixup the user .rofixup 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) |
---|
| 117 | |
---|
| 118 | .Lfixed: |
---|
| 119 | |
---|
| 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 */ |
---|
| 135 | |
---|
| 136 | #ifndef HSR_CLEAR |
---|
| 137 | #define HSR_CLEAR 0 |
---|
| 138 | #endif |
---|
| 139 | |
---|
| 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 |
---|
| 147 | |
---|
| 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 */ |
---|
| 158 | |
---|
| 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 |
---|
| 166 | |
---|
| 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 |
---|
| 174 | |
---|
| 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 |
---|
| 184 | |
---|
| 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 |
---|
| 193 | |
---|
| 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) |
---|
| 205 | |
---|
| 206 | P(setlos) #0, gr8 /* zero argc, argv, envp */ |
---|
| 207 | setlos #0, gr9 |
---|
| 208 | P(setlos) #0, gr10 |
---|
| 209 | |
---|
| 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) |
---|
| 216 | |
---|
| 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 |
---|
| 231 | |
---|
| 232 | ldu @(gr9,gr11), gr5 |
---|
| 233 | add gr8, gr5, gr5 |
---|
| 234 | P(st) gr5, @(gr9,gr0) |
---|
| 235 | bra .Lloop2 |
---|
| 236 | |
---|
| 237 | .Lret2: ret |
---|
| 238 | .Lend2: |
---|
| 239 | .size EXT(__frv_fixptrs),.Lend2-EXT(__frv_fixptrs) |
---|
| 240 | #endif /* ! __FRV_FDPIC__ */ |
---|
| 241 | |
---|
| 242 | /* Routine to adjust statically initialized pointers |
---|
| 243 | Note since these are pointers to pointers, they |
---|
| 244 | need to be adjusted themsevles. |
---|
| 245 | |
---|
| 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 |
---|
| 258 | |
---|
| 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 |
---|
| 263 | |
---|
| 264 | add gr8, gr6, gr6 |
---|
| 265 | P(st) gr6, @(gr5,gr8) |
---|
| 266 | bra .Lloop3 |
---|
| 267 | |
---|
| 268 | .Lret3: ret |
---|
| 269 | .Lend3: |
---|
| 270 | .size EXT(__frv_fix_usrptrs),.Lend3-EXT(__frv_fix_usrptrs) |
---|
| 271 | |
---|
| 272 | .section .data |
---|
| 273 | .global __dso_handle |
---|
| 274 | .weak __dso_handle |
---|
| 275 | __dso_handle: |
---|
| 276 | .long 0 |
---|