Cygwin: cygwin_GetCommandLineW/A: don't rely on __argv[0] content
[newlib-cygwin.git] / libgloss / arm / redboot-crt0.S
blob0e3a9b4e23fa60f547ca6659f780adbbe65e81ab
1 #include "arm.h"
2         
3     .file   "crt0.S"
4         
5 #define XGLUE(a,b) a##b
6 #define GLUE(a,b) XGLUE(a,b)
7         
8 #ifdef __USER_LABEL_PREFIX__
9 #define SYM_NAME( name ) GLUE (__USER_LABEL_PREFIX__, name)
10 #else
11 #error __USER_LABEL_PREFIX is not defined
12 #endif
14     .text
15         .syntax unified
16      /* Setup the assembly entry point.  */
17 #ifdef PREFER_THUMB
18 .macro FUNC_START name
19         .global \name
20         .thumb_func
21 \name:
22 .endm
23         .thumb
24 #else
25 .macro FUNC_START name
26         .global \name
27 \name:
28 .endm
29         .code 32
30 #endif
31         FUNC_START SYM_NAME(_start)
32     /* Unnecessary to set fp for v6-m/v7-m, which don't support
33        ARM state.  */
34 #if __ARM_ARCH_ISA_ARM
35         mov     fp, #0  /* Null frame pointer.  */
36 #endif
37         movs    r7, #0  /* Null frame pointer for Thumb.  */
39         /* Enable interrupts for gdb debugging.  */
40 #ifdef PREFER_THUMB
41         cpsie if
42 #else
43         mrs    r0, cpsr
44         bic    r0, r0, #0xC0
45         msr    cpsr, r0
46 #endif
47         
48         movs    a2, #0                  /* Second arg: fill value.  */
49         ldr     a1, .LC1                /* First arg: start of memory block.  */
50         ldr     a3, .LC2        
51         subs    a3, a3, a1              /* Third arg: length of block.  */
53 #ifdef  GCRT0
54         /* Zero out the bss without using memset. 
55            Using memset is bad because it may be instrumented for
56            profiling, but at this point, the profiling data structures
57            have not been set up. 
58            FIXME: This loop could be a lot more efficient.  */
59         subs    a3, a3, #0
60         beq     2f
61 1:      strb    a2, [a1]
62         subs    a3, a3, #1
63         add     a1, a1, #1
64         bne     1b
65 2:      
66         /* Nothing to left to clear.  */
67 #endif
69 #if __thumb__ && !defined(PREFER_THUMB)
70         /* Enter Thumb mode. */
71         add     a4, pc, #1      /* Get the address of the Thumb block.  */
72         bx      a4              /* Go there and start Thumb decoding.   */
74         .code 16
75         .global __change_mode
76         .thumb_func
77 __change_mode:  
78 #endif
80 #ifndef GCRT0
81         bl      SYM_NAME(memset)
82 #endif
83         bl      SYM_NAME(__get_memtop)
84         subs    r0, r0, #32
85         mov     sp, r0
87 #ifdef __USES_INITFINI__
88         /* Some arm/elf targets use the .init and .fini sections
89            to create constructors and destructors, and for these
90            targets we need to call the _init function and arrange
91            for _fini to be called at program exit.  */
92         ldr     r0, .Lfini
93         bl      SYM_NAME (atexit)
94         bl      SYM_NAME (_init)
95 #endif  
97         movs    a1, #0
98         ldr     a2, .LC3
99         movs    a3, a2
100         bl      SYM_NAME(main)
101     1:  bl      SYM_NAME(exit)
102         b       1b
103         .align  2
104 .LC1:
105         .word   __bss_start__
106 .LC2:
107         .word   __bss_end__
108 .LC3:
109         .word   0
110 #ifdef __USES_INITFINI__
111 .Lfini:
112         .word   SYM_NAME(_fini)
113 #endif
114 #if 0
115 #ifdef __thumb__
116         .code 16
117 #endif
118         .global SYM_NAME(__syscall)
119 #ifdef __thumb__
120         .thumb_func
121 #else
122         .align  4
123 #endif
124 SYM_NAME(__syscall):
125         mov     r12, lr
126 #ifdef __thumb__
127         swi     0x18
128 #else
129         swi     0x180001
130 #endif
131         mov     pc, r12
132 #endif