148 lines
2.9 KiB
ArmAsm
148 lines
2.9 KiB
ArmAsm
/*
|
|
* C startup code for the Fujitsu SPARClite demo board
|
|
*
|
|
* Copyright (c) 1995, 1996 Cygnus Support
|
|
*
|
|
* The authors hereby grant permission to use, copy, modify, distribute,
|
|
* and license this software and its documentation for any purpose, provided
|
|
* that existing copyright notices are retained in all copies and that this
|
|
* notice is included verbatim in any distributions. No written agreement,
|
|
* license, or royalty fee is required for any of the authorized uses.
|
|
* Modifications to this software may be copyrighted by their authors
|
|
* and need not follow the licensing terms described here, provided that
|
|
* the new terms are clearly indicated on the first page of each file where
|
|
* they apply.
|
|
*/
|
|
#include "asm.h"
|
|
|
|
#ifdef TARGET_CPU_SPARC64
|
|
#define STACK_BIAS 2047
|
|
#define SAVE_SIZE -128
|
|
#else
|
|
#define SAVE_SIZE -64
|
|
#endif
|
|
|
|
.register %g2, #scratch
|
|
.register %g3, #scratch
|
|
|
|
.data
|
|
.align 8
|
|
SYM(environ): ! this is the first address in the data section
|
|
.long 0
|
|
|
|
SYM(argc):
|
|
.long 0
|
|
|
|
.text
|
|
.align 8
|
|
|
|
.globl SYM(start)
|
|
.globl start
|
|
SYM(start):
|
|
start:
|
|
/* see if the stack is already setup. if not, then default
|
|
* to using the value of %sp as set by the ROM monitor
|
|
*/
|
|
sethi %hi(__stack), %g1
|
|
or %g1,%lo(__stack),%g1
|
|
cmp %g0,%g1
|
|
be 1f
|
|
nop
|
|
#ifdef STACK_BIAS
|
|
sub %g1, STACK_BIAS, %g1
|
|
#endif
|
|
mov %g1, %sp ! set the stack pointer
|
|
mov 0, %fp
|
|
1:
|
|
|
|
/* zero the bss section */
|
|
sethi %hi(__bss_start),%g2
|
|
or %g2,%lo(__bss_start),%g2 ! start of bss
|
|
sethi %hi(_end),%g3
|
|
or %g3,%lo(_end),%g3 ! end of bss
|
|
mov %g0,%g1 ! so std has two zeros
|
|
zerobss:
|
|
std %g0,[%g2]
|
|
add %g2,8,%g2
|
|
cmp %g2,%g3
|
|
bleu,a zerobss
|
|
nop
|
|
|
|
/*
|
|
* initialize target specific stuff. Only execute these
|
|
* functions it they exist.
|
|
*/
|
|
init:
|
|
sethi %hi(SYM(hardware_init_hook)), %g1
|
|
or %g1,%lo(SYM(hardware_init_hook)),%g1
|
|
cmp %g0,%g1
|
|
be 1f
|
|
nop
|
|
call SYM(hardware_init_hook)
|
|
nop
|
|
|
|
1:
|
|
sethi %hi(SYM(software_init_hook)), %g1
|
|
or %g1,%lo(SYM(software_init_hook)),%g1
|
|
cmp %g0,%g1
|
|
be 2f
|
|
nop
|
|
call SYM(software_init_hook)
|
|
nop
|
|
2:
|
|
set SYM(__sigtramp), %o0
|
|
call SYM(__install_signal_handler)
|
|
nop
|
|
|
|
set do_dtors,%o0
|
|
call SYM(atexit)
|
|
nop
|
|
|
|
call do_ctors
|
|
nop
|
|
|
|
set SYM(argc), %o0
|
|
call SYM(__getProgramArgs)
|
|
nop
|
|
|
|
mov %o0, %o1
|
|
set SYM(argc), %o0
|
|
ld [%o0], %o0
|
|
call SYM(main)
|
|
nop
|
|
|
|
/* call exit from the C library so atexit gets called, and the
|
|
* C++ destructors get run. This calls our exit routine below
|
|
* when it's done.
|
|
*/
|
|
call SYM(exit)
|
|
nop
|
|
|
|
do_ctors:
|
|
save %sp,SAVE_SIZE,%sp
|
|
set __CTOR_LIST__,%l0
|
|
our_entry:
|
|
ld [%l0],%l1
|
|
add %l0,4,%l0
|
|
tst %l1
|
|
1:
|
|
beq 2f
|
|
nop
|
|
ld [%l0],%l2
|
|
add %l0,4,%l0
|
|
|
|
call %l2
|
|
nop
|
|
deccc %l1
|
|
b 1b
|
|
nop
|
|
2:
|
|
ret
|
|
restore
|
|
|
|
do_dtors:
|
|
save %sp,SAVE_SIZE,%sp
|
|
set __DTOR_LIST__,%l0
|
|
b our_entry
|
|
nop
|