| 1 | /* | 
|---|
| 2 |  * crt0.S -- startup file for PowerPC systems. | 
|---|
| 3 |  * | 
|---|
| 4 |  * Copyright (c) 1995 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 | #include "ppc-asm.h" | 
|---|
| 18 |  | 
|---|
| 19 |         .file   "crt0.S" | 
|---|
| 20 |         .section ".got2","aw" | 
|---|
| 21 |         .align  2 | 
|---|
| 22 |  | 
|---|
| 23 | .LCTOC1 = .+32768 | 
|---|
| 24 |  | 
|---|
| 25 |         .extern FUNC_NAME(atexit) | 
|---|
| 26 |         .globl  FUNC_NAME(__atexit) | 
|---|
| 27 |         .section ".sdata","aw" | 
|---|
| 28 |         .align  2 | 
|---|
| 29 | FUNC_NAME(__atexit):                    /* tell C's eabi-ctor's we have an atexit function */ | 
|---|
| 30 |         .long   FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */ | 
|---|
| 31 |  | 
|---|
| 32 |         .section ".fixup","aw" | 
|---|
| 33 |         .align  2 | 
|---|
| 34 |         .long   FUNC_NAME(__atexit) | 
|---|
| 35 |  | 
|---|
| 36 |         .section ".got2","aw" | 
|---|
| 37 | .Ltable = .-.LCTOC1 | 
|---|
| 38 |         .long   .LCTOC1                 /* address we think .LCTOC1 is loaded at */ | 
|---|
| 39 |  | 
|---|
| 40 | .Lsbss_start = .-.LCTOC1 | 
|---|
| 41 |         .long   __sbss_start | 
|---|
| 42 |  | 
|---|
| 43 | .Lsbss_end = .-.LCTOC1 | 
|---|
| 44 |         .long   __sbss_end | 
|---|
| 45 |  | 
|---|
| 46 | .Lbss_start = .-.LCTOC1 | 
|---|
| 47 |         .long   __bss_start | 
|---|
| 48 |  | 
|---|
| 49 | .Lend = .-.LCTOC1 | 
|---|
| 50 |         .long   _end | 
|---|
| 51 |  | 
|---|
| 52 | .Lstack = .-.LCTOC1                     /* stack address if set by user */ | 
|---|
| 53 |         .long   __stack | 
|---|
| 54 |  | 
|---|
| 55 |         .text | 
|---|
| 56 | .Lptr: | 
|---|
| 57 |         .long .LCTOC1-.Laddr | 
|---|
| 58 |  | 
|---|
| 59 |         .globl  _start | 
|---|
| 60 |         .type   _start,@function | 
|---|
| 61 | _start: | 
|---|
| 62 |         bl      .Laddr                  /* get current address */ | 
|---|
| 63 | .Laddr: | 
|---|
| 64 |         mflr    r4                      /* real address of .Laddr */ | 
|---|
| 65 |         lwz     r5,(.Lptr-.Laddr)(r4)   /* linker generated address of .LCTOC1 */ | 
|---|
| 66 |         add     r5,r5,r4                /* correct to real pointer */ | 
|---|
| 67 |         lwz     r4,.Ltable(r5)          /* get linker's idea of where .Laddr is */ | 
|---|
| 68 |         subf    r4,r4,r5                /* calculate difference between where linked and current */ | 
|---|
| 69 |  | 
|---|
| 70 |         /* clear bss and sbss */ | 
|---|
| 71 |         lwz     r6,.Lbss_start(r5)      /* calculate beginning of the BSS */ | 
|---|
| 72 |         lwz     r7,.Lend(r5)            /* calculate end of the BSS */ | 
|---|
| 73 |         add     r6,r6,r4                /* adjust pointers */ | 
|---|
| 74 |         add     r7,r7,r4 | 
|---|
| 75 |  | 
|---|
| 76 |         cmplw   1,r6,r7 | 
|---|
| 77 |         bc      4,4,.Ldone1 | 
|---|
| 78 |  | 
|---|
| 79 |         subf    r8,r6,r7                /* number of bytes to zero */ | 
|---|
| 80 |         srwi    r9,r8,2                 /* number of words to zero */ | 
|---|
| 81 |         mtctr   r9 | 
|---|
| 82 |         li      r0,0                    /* zero to clear memory */ | 
|---|
| 83 |         addi    r6,r6,-4                /* adjust so we can use stwu */ | 
|---|
| 84 | .Lloop: | 
|---|
| 85 |         stwu    r0,4(r6)                /* zero bss */ | 
|---|
| 86 |         bdnz    .Lloop | 
|---|
| 87 |  | 
|---|
| 88 | .Ldone1: | 
|---|
| 89 |  | 
|---|
| 90 |         lwz     r6,.Lsbss_start(r5)     /* calculate beginning of the SBSS */ | 
|---|
| 91 |         lwz     r7,.Lsbss_end(r5)       /* calculate end of the SBSS */ | 
|---|
| 92 |         add     r6,r6,r4                /* adjust pointers */ | 
|---|
| 93 |         add     r7,r7,r4 | 
|---|
| 94 |  | 
|---|
| 95 |         cmplw   1,r6,r7 | 
|---|
| 96 |         bc      4,4,.Ldone | 
|---|
| 97 |  | 
|---|
| 98 |         subf    r8,r6,r7                /* number of bytes to zero */ | 
|---|
| 99 |         srwi    r9,r8,2                 /* number of words to zero */ | 
|---|
| 100 |         mtctr   r9 | 
|---|
| 101 |         li      r0,0                    /* zero to clear memory */ | 
|---|
| 102 |         addi    r6,r6,-4                /* adjust so we can use stwu */ | 
|---|
| 103 | .Lloop2: | 
|---|
| 104 |         stwu    r0,4(r6)                /* zero bss */ | 
|---|
| 105 |         bdnz    .Lloop2 | 
|---|
| 106 |  | 
|---|
| 107 | .Ldone: | 
|---|
| 108 |  | 
|---|
| 109 |         lwz     r0,.Lstack(r5)          /* stack address or 0 */ | 
|---|
| 110 |         cmplwi  1,r0,0                  /* equal to 0? */ | 
|---|
| 111 |         bc      12,6,.Lnostack          /* use default stack if == 0 */ | 
|---|
| 112 |         mr      sp,r0                   /* use user defined stack */ | 
|---|
| 113 |  | 
|---|
| 114 | .Lnostack: | 
|---|
| 115 |         /* set up initial stack frame */ | 
|---|
| 116 |         addi    sp,sp,-4                /* make sure we don't overwrite debug mem */ | 
|---|
| 117 |         lis     r0,0 | 
|---|
| 118 |         stw     r0,0(sp)                /* clear back chain */ | 
|---|
| 119 |         stwu    sp,-64(sp)              /* push another stack frame */ | 
|---|
| 120 |  | 
|---|
| 121 |         /* Let her rip */ | 
|---|
| 122 |         bl      FUNC_NAME(main) | 
|---|
| 123 |  | 
|---|
| 124 |         /* return value from main is argument to exit */ | 
|---|
| 125 |         bl      FUNC_NAME(exit) | 
|---|
| 126 |         trap | 
|---|
| 127 | .Lstart: | 
|---|
| 128 |         .size   _start,.Lstart-_start | 
|---|