Cygwin: fhandler_virtual: move fileid to path_conv member
[newlib-cygwin.git] / libgloss / xtensa / crt1-sim.S
blob4f9924c3b041bb0ce171a19a7eb89fa611b199ff
1 // crt1-sim.S
2 // For the Xtensa simulator target, this code sets up the C calling context
3 // and calls main()  (via __clibrary_start).
4 // Control arrives here at _start from the reset vector or from crt0-app.S.
6 // Copyright (c) 1998-2012 Tensilica Inc.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be included
17 // in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include <xtensa/config/core-isa.h>
28 #include <xtensa/corebits.h>
29 #include <syscalls.h>
31 // Exports
32 .global _start
34 // Imports
35 //   __clibrary_init    from C library (eg. newlib or uclibc)
36 //   exit               from C library
37 //   main               from user application
38 //   __stack            from linker script (see LSP Ref Manual)
40 .type   __clibrary_init, @function
41 .type   main, @function
42 .type   exit, @function
44 # define CALL   call4
45 # define CALLX  callx4
46 # define ARG1   a6      /* 1st outgoing call argument */
47 # define ARG2   a7      /* 2nd outgoing call argument */
48 # define ARG3   a8      /* 3rd outgoing call argument */
49 # define ARG4   a9      /* 4th outgoing call argument */
50 # define ARG5   a10     /* 5th outgoing call argument */
52                 .data
53                 .weak   _start_envp     // allow overriding
54                 .align  4
55 _start_envp:    .word   0               // empty environ
57         .text
58         .align 4
60 _start:
61         //  _start is typically NOT at the beginning of the text segment --
62         //  it is always called from either the reset vector or other code
63         //  that does equivalent initialization (such as crt0-app.S).
64         //
65         //  Assumptions on entry to _start:
66         //      - low (level-one) and medium priority interrupts are disabled
67         //        via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
68         //        be zeroed, to potentially enable them, before calling main)
69         //      - C calling context not initialized:
70         //        - PS not initialized
71         //        - SP not initialized
72         //      - the following are initialized:
73         //        - LITBASE, cache attributes, WindowBase, WindowStart,
74         //          CPENABLE, FP's FCR and FSR, EXCSAVE[n]
76         // Keep a0 zero.  It is used to initialize a few things.
77         // It is also the return address, where zero indicates
78         // that the frame used by _start is the bottommost frame.
79         //
80         movi    a0, 0           // keep this register zero.
82         wsr     a0, INTENABLE   // INTENABLE value is not defined after reset.
83                                 //make sure that interrupts are shut off (*before* we lower PS.INTLEVEL and PS.EXCM!)
85         //  Windowed register init, so we can call windowed code (eg. C code).
86         movi    a1, 1
87         wsr     a1, WINDOWSTART
88         //  The processor always clears WINDOWBASE at reset, so no need to clear it here.
89         //  It resets WINDOWSTART to 1 starting with LX2.0/X7.0 (RB-2006.0).
90         //  However, assuming hard reset is not yet always practical, so do this anyway:
91         wsr     a0, WINDOWBASE
92         rsync
94         // Set VECBASE to use our vectors instead vectors in ROM
95         movi    a1, _vector_table
96         wsr     a1, VECBASE
99         // Run only one core
100         // Multi-threading could be supported in future
101         rsr.prid a1             // core and multiprocessor ID
102         extui   a1, a1, 13, 1   // extract core ID
103         beqz    a1, .Lcore0     // goto Lcore0 for core0 only
104 .Lsuspend:                      // other cores are suspended
105         waiti   0
106         j       .Lsuspend
108 .Lcore0:
109         // Initialize the stack pointer.
110         // See the "ABI and Software Conventions" chapter in the
111         // Xtensa ISA Reference manual for details.
113         // NOTE: Because the _start routine does not use any memory in its
114         // stack frame, and because all of its CALL instructions use a
115         // window size of 4, the stack frame for _start can be empty.
116         movi    sp, __stack
118         // reserve stack space for
119         //    - argv array
120         //    - argument strings
121         movi    a2, SYS_argv_size
122         simcall         // returns size of argv[] + its strings in a2
124         // The stack only needs 16-byte alignment.
125         // However, here we round up the argv size further to 128 byte multiples
126         // so that in most cases, variations in argv[0]'s path do not result in
127         // different stack allocation.  Otherwise, such variations can impact
128         // execution timing (eg. due to cache effects etc) for the same code and data.
129         // If we have a PIF, it's more likely the extra required space is okay.
130         addi    a2, a2, 127
131         srli    a2, a2, 7
132         slli    a2, a2, 7
134         // No need to use MOVSP because we have no caller (we're the
135         // base caller); in fact it's better not to use MOVSP in this
136         // context, to avoid unnecessary ALLOCA exceptions and copying
137         // from undefined memory:
138         //   sub     a3, sp, a2
139         //   movsp   sp, a3
140         sub     sp, sp, a2
142         /*
143          *  Now that sp (a1) is set, we can set PS as per the application
144          *  (user vector mode, enable interrupts, enable window exceptions if applicable).
145          */
146         movi    a3, PS_UM|PS_WOE        // PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
147         wsr     a3, PS
148         rsync
150         #if XCHAL_HAVE_FP || XCHAL_HAVE_DFP
151         movi    a3, 1
152         wsr     a3, CPENABLE
153         #endif
157         /*
158          *  Clear the BSS (uninitialized data) segments.
159          *  This code supports multiple zeroed sections (*.bss).
160          *  For speed, we clear memory using an ISS simcall
161          *  (see crt1-boards.S for more generic BSS clearing code).
162          */
163         movi    a6, __bss_start
164         movi    a7, _end
165         bgeu    a6, a7, .Lnobss
166 .Lbssloop:
167         movi    a2, SYS_memset
168         l32i    a3, a6, 0       // arg1 = fill start address
169         movi    a4, 0           // arg2 = fill pattern
170         l32i    a5, a6, 4       // get end address
171         addi    a6, a6, 8       // next bss table entry
172         sub     a5, a5, a3      // arg3 = fill size in bytes
173         simcall                 // memset(a3,a4,a5)
174         bltu    a6, a7, .Lbssloop       // loop until end of bss table
175 .Lnobss:
177         mov     a3, sp                  // tell simcall where to write argv[]
178         movi    a2, SYS_argv
179         simcall                 // write argv[] array at a3
181         movi    a2, SYS_argc
182         simcall                 // put argc in a2
184         .weak   _init
185         .weak   _fini
186         mov     ARG2, sp                // argv
187         movi    ARG3, _start_envp       // envp
188         movi    ARG4, _init             // _init
189         movi    ARG5, _fini             // _fini
190         CALL    __clibrary_init
192         mov     ARG1, a2                // argc
193         mov     ARG2, sp                // argv
194         CALL    main
196         //  The return value is the same register as the first outgoing argument.
197         CALL    exit                    // exit with main's return value
198         // Does not return here.
200         .size   _start, . - _start