| [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 | 
|---|