chiark / gitweb /
[PATCH] added klibc version 0.82 (cvs tree) to the udev tree.
[elogind.git] / klibc / klibc / arch / sparc / crt0i.S
1 ! This file derived from the equivalent in newlib
2 !
3 ! C run time start off
4
5 ! This file supports:
6 !
7 ! - both 32bit pointer and 64bit pointer environments (at compile time)
8 ! - an imposed stack bias (of 2047) (at run time)
9 ! - medium/low and medium/anywhere code models (at run time)
10
11 ! Initial stack setup:
12 !
13 !    bottom of stack (higher memory address)
14 !       ...
15 !       text of environment strings
16 !       text of argument strings
17 !       envp[envc] = 0 (4/8 bytes)
18 !       ...
19 !       env[0] (4/8 bytes)
20 !       argv[argc] = 0 (4/8 bytes)
21 !       ...
22 !       argv[0] (4/8 bytes)
23 !       argc (4/8 bytes)
24 !       register save area (64 bits by 16 registers = 128 bytes)
25 !       top of stack (%sp)
26
27 ! Stack Bias:
28 !
29 ! It is the responsibility of the o/s to set this up.
30 ! We handle both a 0 and 2047 value for the stack bias.
31
32 ! Medium/Anywhere code model support:
33 !
34 ! In this model %g4 points to the start of the data segment.
35 ! The text segment can go anywhere, but %g4 points to the *data* segment.
36 ! It is up to the compiler/linker to get this right.
37 !
38 ! Since this model is statically linked the start of the data segment
39 ! is known at link time.  Eg:
40 !
41 !       sethi   %hh(data_start), %g1
42 !       sethi   %lm(data_start), %g4
43 !       or      %g1, %hm(data_start), %g1
44 !       or      %g4, %lo(data_start), %g4
45 !       sllx    %g1, 32, %g1
46 !       or      %g4, %g1, %g4
47 !
48 ! FIXME: For now we just assume 0.
49
50 ! FIXME: if %g1 contains a non-zero value, atexit() should be invoked
51 ! with this value.
52
53
54         .text
55         .align 4
56         .globl _start
57         .type _start, @function
58 _start:
59         clr     %fp
60
61 ! We use %g4 even if the code model is Medium/Low (simplifies the code).
62
63         clr     %g4                     ! Medium/Anywhere base reg
64
65 ! If there is a stack bias in effect, account for it in %g5.  Then always
66 ! add %g5 to stack references below.  This way the code can be used with
67 ! or without an imposed bias.
68
69         andcc   %sp, 1, %g5
70         bz,a .LNoBias
71          nop
72         mov     2047, %g5
73 .LNoBias:
74         add     %sp, %g5, %g5
75
76 ! On entry, the kernel leaves room for one register frame, but
77 ! the C API wants more free space.  Thus, we need to drop the stack
78 ! pointer additionally.   
79
80 #if TARGET_PTR_SIZE == 32
81         sub     %sp, 32, %sp            ! make room for incoming arguments
82 #else /* TARGET_PTR_SIZE == 64 */
83         sub     %sp, 64, %sp            ! make room for incoming arguments
84 #endif
85
86 ! Set up pointers to the ELF data structure (argc, argv, ...)
87 ! Pass as the first argument to __libc_init
88 #if TARGET_PTR_SIZE == 32
89         add     %g5, 0x40, %o0
90 #else /* TARGET_PTR_SIZE == 64 */
91         add     %g5, 0x80, %o0
92 #endif
93
94         call    __libc_init
95          mov    %g1, %o1        ! This is the "atexit" pointer;
96                                 ! pass as the second argument to __libc_init
97
98 ! If __libc_init returns, something is hosed.  Try an illegal insn.
99 ! If that does not work, the o/s is hosed more than we are.
100         .long 0