OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains3x.git] / newlib / libc / sys / a29khif / crt0.s
1 ; @(#)crt0.s    2.7 90/10/15 13:17:57, AMD
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc.
4 ;
5 ; This software is the property of Advanced Micro Devices, Inc  (AMD)  which
6 ; specifically  grants the user the right to modify, use and distribute this
7 ; software provided this notice is not removed or altered.  All other rights
8 ; are reserved by AMD.
9 ;
10 ; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
11 ; SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
12 ; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
13 ; USE OF THIS SOFTWARE.
14 ;
15 ; So that all may benefit from your experience, please report  any  problems
16 ; or  suggestions about this software to the 29K Technical Support Center at
17 ; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
18 ; 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
19 ;
20 ; Advanced Micro Devices, Inc.
21 ; 29K Support Products
22 ; Mail Stop 573
23 ; 5900 E. Ben White Blvd.
24 ; Austin, TX 78741
25 ; 800-292-9263
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27         .file   "crt0.s"
28 ; crt0.s version 2.1-7
29 ;
30 ; This module gets control from the OS.
31 ; It saves away the Am29027 Mode register settings and
32 ; then sets up the pointers to the resident spill and fill
33 ; trap handlers. It then establishes argv and argc for passing
34 ; to main. It then calls _main. If main returns, it calls _exit.
35 ;
36 ;       void = start( );
37 ;       NOTE - not C callable (no lead underscore)
38 ;
39         .include        "sys/sysmac.h"
40 ;
41 ;
42         .extern V_SPILL, V_FILL
43         .comm   __29027Mode, 8  ; A shadow of the mode register
44         .comm   __LibInit, 4
45         .comm   __environ, 4    ; Environment variables, currently none.
46         .text
47         .extern _main, _exit
48         .extern _memset
49
50         .word   0                       ; Terminating tag word
51         .global start
52 start:
53         sub     gr1, gr1, 6 * 4
54         asgeu   V_SPILL, gr1, rab       ; better not ever happen
55         add     lr1, gr1, 6 * 4
56 ;
57 ; Initialize the .bss section to zero by using the memset library function.
58 ; The .bss initialization section below has been commented out as it breaks
59 ; XRAY29K that has been released. The operators sizeof and startof create
60 ; new sections that are not recognized by XRAY29k, but will be implemented
61 ; in the next release (2.0).
62 ;
63 ;       const   lr4, $sizeof(.bss)      ; get size of .bss section to zero out
64 ;       consth  lr4, $sizeof(.bss)
65 ;       const   lr2, $startof(.bss)     ; Get start address of .bss section
66 ;       consth  lr2, $startof(.bss)
67 ;       const   lr0, _memset            ; address of memset function
68 ;       consth  lr0, _memset
69 ;       calli   lr0, lr0                ; call memset function
70 ;       const   lr3, 0
71
72 ; Save the initial value of the Am29027's Mode register
73 ; If your const tav,HIF_does @ asneq V_SYSCALL,gr1,gr1 @ jmpti tav,lr0 @ const tpc,_errno @ consth tpc,_errno @ store 0,0,tav,tpc @ jmpi lr0 @ constn v0,-1 not enter crt0 with value for Am29027's Mode register
74 ; in gr96 and gr97, and also if the coprocessor is active uncomment the
75 ; next 4 lines.
76 ;       const   gr96, 0xfc00820
77 ;       consth  gr96, 0xfc00820
78 ;       const   gr97, 0x1375
79 ;       store   1, 3, gr96, gr97
80 ;
81         const   gr98, __29027Mode
82         consth  gr98, __29027Mode
83         store   0, 0, gr96, gr98
84         add     gr98, gr98, 4
85         store   0, 0, gr97, gr98
86 ;
87 ; Now call the const tav,HIF_to @ asneq V_SYSCALL,gr1,gr1 @ jmpti tav,lr0 @ const tpc,_errno @ consth tpc,_errno @ store 0,0,tav,tpc @ jmpi lr0 @ constn v0,-1 setup the spill and fill trap handlers
88 ;
89         const   lr3, spill
90         consth  lr3, spill
91         const   lr2, V_SPILL
92         const tav,HIF_setvec @ asneq V_SYSCALL,gr1,gr1
93         const   lr3, fill
94         consth  lr3, fill
95         const   lr2, V_FILL
96         const tav,HIF_setvec @ asneq V_SYSCALL,gr1,gr1
97 ;
98 ; Set up dividu handler, since native one don't work?!
99 ; Set it up by hand (FIXME) since HIF_settrap doesn't work either!
100 ;
101 ;       const   lr3,Edividu
102 ;       consth  lr3,Edividu
103 ;
104 ;       const   lr2,35
105 ;       const tav,HIF_settrap @ asneq V_SYSCALL,gr1,gr1
106 ;       asge    0x50,gr121,0    ; check whether it failed
107 ;       const   lr2,0x8000008c  ; abs addr of dividu trap handler on EB
108 ;       consth  lr2,0x8000008c
109 ;       store   0,0,lr3,lr2     ; Clobber vector FIXME
110
111 ;
112 ;       Get the argv base address and calculate argc.
113 ;
114         const tav,HIF_getargs @ asneq V_SYSCALL,gr1,gr1
115         add     lr3, v0, 0              ; argv
116         add     lr4, v0, 0
117         constn  lr2, -1
118 argcloop:                               ; scan for NULL terminator
119         load    0, 0, gr97, lr4
120         add     lr4, lr4, 4
121         cpeq    gr97, gr97, 0
122         jmpf    gr97, argcloop
123         add     lr2, lr2, 1
124 ;
125 ; Now call LibInit, if there is one. To aid runtime libraries
126 ; that need to do some startup initialization, we have created
127 ; a bss variable called LibInit. If the library doesn't need
128 ; any run-time initialization, the variable is still 0. If the
129 ; library does need run-time initialization, the library will
130 ; contain a definition like
131 ; void (*_LibInit)(void) = LibInitFunction;
132 ; The linker will match up our bss LibInit with this data LibInit
133 ; and the variable will not be 0.
134 ;
135         const   lr0, __LibInit
136         consth  lr0, __LibInit
137         load    0, 0, lr0, lr0
138         cpeq    gr96, lr0, 0
139         jmpt    gr96, NoLibInit
140         nop
141         calli   lr0, lr0
142         nop
143 NoLibInit:
144 ;
145 ; call main, passing it 2 arguments. main( argc, argv )
146 ;
147         const   lr0, _main
148         consth  lr0, _main
149         calli   lr0, lr0
150         nop
151 ;
152 ; call exit
153 ;
154         const   lr0, _exit
155         consth  lr0, _exit
156         calli   lr0, lr0
157         add     lr2, gr96, 0
158 ;
159 ; Should never get here, but just in case
160 ;
161 loop:
162         const tav,HIF_exit @ asneq V_SYSCALL,gr1,gr1
163         jmp     loop
164         nop
165         .sbttl  "Spill and Fill trap handlers"
166         .eject
167 ;
168 ;       SPILL, FILL trap handlers
169 ;
170 ; Note that these Spill and Fill trap handlers allow the OS to
171 ; assume that the only registers of use are between gr1 and rfb.
172 ; Therefore, if the OS desires to, it may simply preserve from
173 ; lr0 for (rfb-gr1)/4 registers when doing a context save.
174 ;
175 ;
176 ; Here is the spill handler
177 ;
178 ; spill registers from [*gr1..*rab)
179 ; and move rab downto where gr1 points
180 ;
181 ; rab must change before rfb for signals to work
182 ;
183 ; On entry:     rfb - rab = windowsize, gr1 < rab
184 ; Near the end: rfb - rab > windowsize, gr1 == rab
185 ; On exit:      rfb - rab = windowsize, gr1 == rab
186 ;
187         .global spill
188 spill:
189         sub     tav, rab, gr1   ; tav = number of bytes to spill
190         srl     tav, tav, 2     ; change byte count to word count
191         sub     tav, tav, 1     ; make count zero based
192         mtsr    cr, tav         ; set Count Remaining register
193         sub     tav, rab, gr1
194         sub     tav, rfb, tav   ; pull down free bound and save it in rab
195         add     rab, gr1, 0     ; first pull down allocate bound
196         storem  0, 0, lr0, tav  ; store lr0..lr(tav) into rfb
197         jmpi    tpc             ; return...
198           add   rfb, tav, 0
199 ;
200 ; Here is the fill handler
201 ;
202 ; fill registers from [*rfb..*lr1)
203 ; and move rfb upto where lr1 points.
204 ;
205 ; rab must change before rfb for signals to work
206 ;
207 ; On entry:     rfb - rab = windowsize, lr1 > rfb
208 ; Near the end: rfb - rab < windowsize, lr1 == rab + windowsize
209 ; On exit:      rfb - rab = windowsize, lr1 == rfb
210 ;
211         .global fill
212 fill:
213         const   tav, 0x80 << 2
214         or      tav, tav, rfb   ; tav = ((rfb>>2) | 0x80)<<2 == [rfb]<<2
215         mtsr    ipa, tav        ; ipa = [rfb]<<2 == 1st reg to fill
216                                 ; gr0 is now the first reg to spill
217         sub     tav, lr1, rfb   ; tav = number of bytes to spill
218         add     rab, rab, tav   ; push up allocate bound
219         srl     tav, tav, 2     ; change byte count to word count
220         sub     tav, tav, 1     ; make count zero based
221         mtsr    cr, tav         ; set Count Remaining register
222         loadm   0, 0, gr0, rfb  ; load registers
223         jmpi    tpc             ; return...
224           add   rfb, lr1, 0     ; ... first pushing up free bound
225
226         .end