1 ; @(#)crt0.s 2.7 90/10/15 13:17:57, AMD
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc.
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
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.
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.
20 ; Advanced Micro Devices, Inc.
21 ; 29K Support Products
23 ; 5900 E. Ben White Blvd.
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ; crt0.s version 2.1-7
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.
37 ; NOTE - not C callable (no lead underscore)
39 .include "sys/sysmac.h"
42 .extern V_SPILL, V_FILL
43 .comm __29027Mode, 8 ; A shadow of the mode register
45 .comm __environ, 4 ; Environment variables, currently none.
50 .word 0 ; Terminating tag word
54 asgeu V_SPILL, gr1, rab ; better not ever happen
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).
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
69 ; calli lr0, lr0 ; call memset function
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
76 ; const gr96, 0xfc00820
77 ; consth gr96, 0xfc00820
79 ; store 1, 3, gr96, gr97
81 const gr98, __29027Mode
82 consth gr98, __29027Mode
83 store 0, 0, gr96, gr98
85 store 0, 0, gr97, gr98
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
92 const tav,HIF_setvec @ asneq V_SYSCALL,gr1,gr1
96 const tav,HIF_setvec @ asneq V_SYSCALL,gr1,gr1
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!
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
112 ; Get the argv base address and calculate argc.
114 const tav,HIF_getargs @ asneq V_SYSCALL,gr1,gr1
115 add lr3, v0, 0 ; argv
118 argcloop: ; scan for NULL terminator
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.
136 consth lr0, __LibInit
145 ; call main, passing it 2 arguments. main( argc, argv )
159 ; Should never get here, but just in case
162 const tav,HIF_exit @ asneq V_SYSCALL,gr1,gr1
165 .sbttl "Spill and Fill trap handlers"
168 ; SPILL, FILL trap handlers
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.
176 ; Here is the spill handler
178 ; spill registers from [*gr1..*rab)
179 ; and move rab downto where gr1 points
181 ; rab must change before rfb for signals to work
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
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
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
200 ; Here is the fill handler
202 ; fill registers from [*rfb..*lr1)
203 ; and move rfb upto where lr1 points.
205 ; rab must change before rfb for signals to work
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
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
224 add rfb, lr1, 0 ; ... first pushing up free bound