diff options
Diffstat (limited to 'libgloss/arc/crt0.S')
-rw-r--r-- | libgloss/arc/crt0.S | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/libgloss/arc/crt0.S b/libgloss/arc/crt0.S new file mode 100644 index 000000000..e4a15eb48 --- /dev/null +++ b/libgloss/arc/crt0.S @@ -0,0 +1,241 @@ +/* + Copyright (c) 2015, Synopsys, Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1) Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2) Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3) Neither the name of the Synopsys, Inc., nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The startup code for the ARC family of processors does the following before + transferring control to user defined main label: + 1. Set sp to __stack_top (link time variable) + 2. Set fp to zero + 3. Zero out the bss section (for uninitialized globals) + After returning from main, the processor is halted and the pipeline is + flushed out. + + We expect argc in r0 and argv in r1. These are saved in r13 / r14 during + the initialization code. +*/ + + .file "crt0.S" + .extern main + +#if defined (__EM__) || defined (__HS__) + .section .ivt, "a", @progbits + +; handler's name, type, number,name, offset in IVT (hex/dec) +.word __start ; exception 0 program entry point 0x0 0 +.word memory_error ; exception 1 memory_error 0x4 4 +.word instruction_error ; exception 2 instruction_error 0x8 8 +.word EV_MachineCheck ; exception 3 EV_MachineCheck 0xC 12 +.word EV_TLBMissI ; exception 4 EV_TLBMissI 0x10 16 +.word EV_TLBMissD ; exception 5 EV_TLBMissD 0x14 20 +.word EV_ProtV ; exception 6 EV_ProtV 0x18 24 +.word EV_PrivilegeV ; exception 7 EV_PrivilegeV 0x1C 28 +.word EV_SWI ; exception 8 EV_SWI 0x20 32 +.word EV_Trap ; exception 9 EV_Trap 0x24 36 +.word EV_Extension ; exception 10 EV_Extension 0x28 40 +.word EV_DivZero ; exception 11 EV_DivZero 0x2C 44 +.word EV_DCError ; exception 12 EV_DCError 0x30 48 +.word EV_Malignedr ; exception 13 EV_Maligned 0x34 52 +.word _exit_halt ; exception 14 unused 0x38 56 +.word _exit_halt ; exception 15 unused 0x3C 60 +.word IRQ_Timer0 ; IRQ 16 Timer 0 0x40 64 +.word IRQ_Timer1 ; IRQ 17 Timer 1 0x44 68 +.word IRQ_18 ; IRQ 18 0x48 72 +.word IRQ_19 ; IRQ 19 0x4C 76 +.word IRQ_20 ; IRQ 20 0x50 80 + + + .section .text.__startup, "ax", @progbits +#else + .text +#endif + + .global __start + .type __start, @function + +#ifdef __ARC601__ +; Startup code for the ARC601 processor +__start: + mov gp, @__SDATA_BEGIN__ + mov sp, @__stack_top ; Point to top of stack + mov r5, 0 ; Zero value + mov_s r2, @__sbss_start ; r2 = start of the bss section + sub r3, @_end, r2 ; r3 = size of the bss section in bytes + + asr_s r3, r3 + asr_s r3, r3 ; r3 = size of bss in words + +.Lbss_loop: + cmp r3, 0xff ; Check for max lp_count + mov.le lp_count, r3 + mov.gt lp_count, 0xff + lpnz 2f ; Loop to zero bss + st.ab r5,[r2, 4] ; Write word of zeros + nop +2: + sub.f r3, r3, 0xff ; Decrement word count + jp .Lbss_loop + +#else /* __ARC601__ */ + +; Startup code for the ARC600, ARC700 and ARCv2 processors +; NOTE: The following restrictions apply on zero overhead loops (other +; restrictions are not pertinent to this code) +; - loop end should be 4 instruction words away from the lp_count setting +; instruction +; - loop body should have at least two instruction words +__start: +#if defined (__HS__) + ; Allow unaligned accesses. + lr r2, [0xA] + bset r2, r2, 19 + flag r2 +#endif + mov gp, @__SDATA_BEGIN__ + mov_s r2, @__sbss_start ; r2 = start of the bss section + sub r3, @_end, r2 ; r3 = size of the bss section in bytes + ; set up the loop counter register to the size (in words) of the bss section + asr.f lp_count, r3, 2 +#if defined (__ARC600__) + ; loop to zero out the bss. Enter loop only if lp_count != 0 + lpnz @.Lend_zbss + add r3, pcl, 20 + sr r3, [2] ; LP_END + ; initialize stack pointer, and this instruction has 2 words + mov sp, @__stack_top + mov_s r3, 0 + st.ab r3, [r2, 4] ; zero out the word +.Lend_zbss: +#else + mov sp, @__stack_top ; initialize stack pointer + mov_s r3,0 + ; loop to zero out the bss. Enter loop only if lp_count != 0 + lpnz @.Lend_zbss + st.ab r3,[r2, 4] ; zero out the word + nop +.Lend_zbss: +#endif + +#endif /* !__ARC601__ */ + +; Some targets use the .init and .fini sections to create constructors and +; destructors, and for these targets we need to call the _init function and +; arrange for _fini to be called at program exit. + mov_s r13, r0 + mov_s r14, r1 + ; calling atexit drags in malloc, so instead poke the function + ; address directly into the reent structure + ld r1, [gp, @_impure_ptr@sda] + mov_s r0, @_fini + add r1, r1, 0x14c ; &_GLOBAL_REENT->atexit0 + st r1, [r1, -4] ; _GLOBAL_REENT->atexit + st_s r0, [r1, 8] ; _GLOBAL_REENT->atexit0._fns[0] + mov_s r0, 1 + st_s r0, [r1, 4] ; _GLOBAL_REENT->atexit0._ind +; branch to _init +#if defined (__EM__) || defined (__HS__) + jl @_init +#else + bl @_init +#endif + mov_s r0, r13 + mov_s r1, r14 +; branch to main +#if defined (__EM__) || defined (__HS__) + mov fp,0 ; initialize frame pointer + jl @main +#else + bl.d @main + mov fp, 0 ; initialize frame pointer +#endif + ; r0 contains exit code + j @exit + +#if defined (__EM__) || defined (__HS__) +; ARCv2 default interrupt routines, defined as weak symbols. +; Default implementation halts the core. To conserve code size those symbols +; share a single implementation, however as a downside debugger and +; disassembler will not be able to distinguish one from another. +.weak memory_error +.weak instruction_error +.weak EV_MachineCheck +.weak EV_TLBMissI +.weak EV_TLBMissD +.weak EV_ProtV +.weak EV_PrivilegeV +.weak EV_SWI +.weak EV_Trap +.weak EV_Extension +.weak EV_DivZero +.weak EV_DCError +.weak EV_Malignedr +.weak IRQ_Timer0 +.weak IRQ_Timer1 +.weak IRQ_18 +.weak IRQ_19 +.weak IRQ_20 + +.balign 4 +memory_error : +instruction_error : +EV_MachineCheck : +EV_TLBMissI : +EV_TLBMissD : +EV_ProtV : +EV_PrivilegeV : +EV_SWI : +EV_Trap : +EV_Extension : +EV_DivZero : +EV_DCError : +EV_Malignedr : +IRQ_Timer0 : +IRQ_Timer1 : +IRQ_18 : +IRQ_19 : +IRQ_20 : +.Lloop_halt: + flag 0x01 + nop + b .Lloop_halt + nop +#endif + + .section .text._exit_halt,"ax",@progbits + .global _exit_halt + .type _exit_halt, @function + +_exit_halt: + ; r0 contains exit code + flag 0x01 + nop + nop ; ARCompact requires 3 nops after flag 1 + nop + b @_exit_halt + nop |