#include "arm.h" .file "crt0.S" #define XGLUE(a,b) a##b #define GLUE(a,b) XGLUE(a,b) #ifdef __USER_LABEL_PREFIX__ #define SYM_NAME( name ) GLUE (__USER_LABEL_PREFIX__, name) #else #error __USER_LABEL_PREFIX is not defined #endif .text .syntax unified /* Setup the assembly entry point. */ #ifdef PREFER_THUMB .macro FUNC_START name .global \name .thumb_func \name: .endm .thumb #else .macro FUNC_START name .global \name \name: .endm .code 32 #endif FUNC_START SYM_NAME(_start) /* Unnecessary to set fp for v6-m/v7-m, which don't support ARM state. */ #if __ARM_ARCH_ISA_ARM mov fp, #0 /* Null frame pointer. */ #endif movs r7, #0 /* Null frame pointer for Thumb. */ /* Enable interrupts for gdb debugging. */ #ifdef PREFER_THUMB cpsie if #else mrs r0, cpsr bic r0, r0, #0xC0 msr cpsr, r0 #endif movs a2, #0 /* Second arg: fill value. */ ldr a1, .LC1 /* First arg: start of memory block. */ ldr a3, .LC2 subs a3, a3, a1 /* Third arg: length of block. */ #ifdef GCRT0 /* Zero out the bss without using memset. Using memset is bad because it may be instrumented for profiling, but at this point, the profiling data structures have not been set up. FIXME: This loop could be a lot more efficient. */ subs a3, a3, #0 beq 2f 1: strb a2, [a1] subs a3, a3, #1 add a1, a1, #1 bne 1b 2: /* Nothing to left to clear. */ #endif #if __thumb__ && !defined(PREFER_THUMB) /* Enter Thumb mode. */ add a4, pc, #1 /* Get the address of the Thumb block. */ bx a4 /* Go there and start Thumb decoding. */ .code 16 .global __change_mode .thumb_func __change_mode: #endif #ifndef GCRT0 bl SYM_NAME(memset) #endif bl SYM_NAME(__get_memtop) subs r0, r0, #32 mov sp, r0 #ifdef __USES_INITFINI__ /* Some arm/elf 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. */ ldr r0, .Lfini bl SYM_NAME (atexit) bl SYM_NAME (_init) #endif movs a1, #0 ldr a2, .LC3 movs a3, a2 bl SYM_NAME(main) 1: bl SYM_NAME(exit) b 1b .align 2 .LC1: .word __bss_start__ .LC2: .word __bss_end__ .LC3: .word 0 #ifdef __USES_INITFINI__ .Lfini: .word SYM_NAME(_fini) #endif #if 0 #ifdef __thumb__ .code 16 #endif .global SYM_NAME(__syscall) #ifdef __thumb__ .thumb_func #else .align 4 #endif SYM_NAME(__syscall): mov r12, lr #ifdef __thumb__ swi 0x18 #else swi 0x180001 #endif mov pc, r12 #endif