fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / sys / a29khif / signal.s
blob29273a0d30a5f495806b2dbbe8dbda04936148a7
1 ;@(#)signal.s 2.15 90/10/14 21:57:55, AMD
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ; Copyright 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
8 ; are reserved by AMD.
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
22 ; Mail Stop 573
23 ; 5900 E. Ben White Blvd.
24 ; Austin, TX 78741
25 ; 800-292-9263
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27 .file "signal.s"
29 ; SigEntry is the address of an array of C-level user code signal handlers.
30 ; They must return to the top-level before doing a sigret() return function.
31 ; Nested signals are supported.
33 .extern V_SPILL, V_FILL
34 .extern fill ; In crt0.s
36 .align 4
37 .comm WindowSize, 4
38 .data
39 SigEntry:
40 .word 0 ; reserved
41 .word 0 ; adds. of #2 SIGINT handler
42 .word 0 ; reserved
43 .word 0 ; reserved
44 .word 0 ; reserved
45 .word 0 ; reserved
46 .word 0 ; reserved
47 .word 0 ; adds. of #8 SIGFPE handler
49 .text
51 .reg v0, gr96
52 .reg v1, gr97
53 .reg v2, gr98
54 .reg v3, gr99
56 .reg tav, gr121
57 .reg tpc, gr122
58 .reg lrp, gr123
59 .reg slp, gr124
60 .reg msp, gr125
61 .reg rab, gr126
62 .reg rfb, gr127
64 ;=================================================================== setjmp()
65 ; int
66 ; setjmp(label_t jmpbuf)
67 ; {
68 ; *jmpbuf = {gr1, msp, lr0, lr1};
69 ; return 0;
70 ; }
72 .global _setjmp
73 _setjmp:
74 store 0, 0, gr1, lr2
75 add lr2, lr2, 4
76 store 0, 0, msp, lr2
77 add lr2, lr2, 4
78 store 0, 0, lr0, lr2
79 add lr2, lr2, 4
80 store 0, 0, lr1, lr2
81 jmpi lr0
82 const v0, 0
84 ;==================================================================== longjmp()
85 ; int
86 ; longjmp(label_t jmpbuf, int value)
87 ; {
88 ; /* BUG: check for this
89 ; if (msp > jmpbuf->msp || gr1 > jmpbuf->gr1)
90 ; longjmperror();
91 ; */
93 ; gr1 = jmpbuf->gr1;
94 ; lr2addr = jmpbuf->gr1 + 8;
95 ; msp = jmpbuf->msp;
97 ; /* saved lr1 is invalid if saved lr2addr > rfb */
98 ; if (lr2addr > rfb) {
99 ; /*
100 ; * None of the registers are useful.
101 ; * Set rfb to lr2addr - 512 & rab to rfb - 512.
102 ; * the FILL assert will take care of filling
103 ; */
104 ; lr1 = jmpbuf->lr1;
105 ; rab = lr2addr - windowsize;
106 ; rfb = lr2addr;
109 ; lr0 = jmpbuf->lr0;
110 ; if (rfb < lr1)
111 ; raise V_FILL;
112 ; return value;
115 .global _longjmp
116 _longjmp:
117 load 0, 0, tav, lr2 ; copy in gr1
118 add v1, lr2, 4 ; v1 points to msp
119 ; make sure we return a non-zero value
120 cpeq v0, lr3, 0
121 srl v0, v0, 31
122 or v0, lr3, v0
124 add gr1, tav, 0 ; now update gr1
125 add tav, tav, 8 ; calculate lr2addr
126 load 0, 0, msp, v1 ; update msp from jmpbuf
127 cpleu v3, tav, rfb ; if (lr2addr > rfb)
128 jmpt v3, $1 ; {
129 add v1, v1, 4 ; v1 points to lr0
130 add v2, v1, 4 ; v2 points to lr1
131 load 0, 0, lr1, v2 ; lr1 = value from jmpbuf
132 sub v3, rfb, rab ;
133 sub rab, tav, v3 ; rab = lr2addr - windowsize
134 add rfb, tav, 0 ; rfb = lr2addr
135 $1: ; }
136 load 0, 0, lr0, v1
137 jmpi lr0
138 asgeu V_FILL, rfb, lr1 ; may fill from rfb to lr1
140 ;================================================================== sigcode
141 ; About to deliver a signal to a user mode signal handler.
142 ; msp+(15*4) = signal_number
143 ; msp+(14*4) = gr1
144 ; msp+(13*4) = rab
145 ; msp+(12*4) = PC0
146 ; msp+(11*4) = PC1
147 ; msp+(10*4) = PC2
148 ; msp+( 9*4) = CHA
149 ; msp+( 8*4) = CHD
150 ; msp+( 7*4) = CHC
151 ; msp+( 6*4) = ALU
152 ; msp+( 5*4) = OPS
153 ; msp+( 4*4) = gr121
154 ; msp+( 3*4) = gr99
155 ; msp+( 2*4) = gr98
156 ; msp+( 1*4) = gr97
157 ; msp = gr96
158 ; The state of all the registers (except for msp, chc and rab)
159 ; is the same as when the process was interrupted.
161 ; We must make the stack and window consistent before calling the handler
162 ; The orignal rab value is on the stack. The interrupt handler placed
163 ; rfb-Windowsize in rab. This is required to support nested interrupts.
165 ; Note that the window becomes incosistent only during certain
166 ; critical sections in spill, fill, longjmp and sigcode.
167 ; rfb - rab > windowsize => we are in spill
168 ; rfb - rab < windowsize => we are in fill
169 ; gr1 + 8 > rfb => we are in long-longjmp case
170 ; In case of spill, fill and lonjmp; rab is modified first,
171 ; so if we are in one of these critical sections,
172 ; we set rab to rfb - WINDOWSIZE.
174 .equ SIGCTX_SIZE, (16)*4
175 .equ SIGCTX_SIGNUMB, (15)*4
176 .equ SIGCTX_GR1_OFFSET, (14)*4
177 .equ SIGCTX_RAB_OFFSET, (13)*4
178 .equ SIGCTX_PC0_OFFSET, (12)*4
179 .equ SIGCTX_PC1_OFFSET, (11)*4
180 .equ SIGCTX_PC2_OFFSET, (10)*4
181 .equ SIGCTX_CHC_OFFSET, (7)*4
182 .equ SIGCTX_OPS_OFFSET, (5)*4
183 .equ SIGCTX_TAV_OFFSET, (4)*4
184 .global sigcode
185 sigcode:
186 ; -------------------------------------------------------- R-Stack fixup
187 const v0, WindowSize ; get register cache size
188 consth v0, WindowSize
189 load 0, 0, v0, v0
190 add v2, msp, SIGCTX_RAB_OFFSET
191 load 0, 0, v2, v2 ; get interrupted rab value
192 sub v1, rfb, v2 ; determine if rfb-rab <= WINDOW_SIZE
193 cpgeu v1, v1, v0 ;
194 jmpt v1, nfill ; jmp if spill or 'normal' interrupt
195 add v1, gr1, 8
196 cpgt v1, v1, rfb ; interrupted longjmp can look like fill
197 jmpf v1, nfill ; test for long-longjmp interruption
198 nop ; jmp if gr1+8 <= rfb
199 ; Fixup signal stack to re-start interrupted fill
200 ; backup pc1 -- this is needed for the partial fill case.
201 ; Clear chc so an interrupted load/store does not restart.
202 ; Reset rab to a window distance below rfb, rab shall be
203 ; decremented again on re-starting the interrupted fill.
204 ; The interrupt handler set rab=rfb-WindowSize.
206 add v0, msp, SIGCTX_RAB_OFFSET
207 store 0, 0, rab, v0 ; re-store (rfb-WindowSize) for rab
208 const v2, fill
209 consth v2, fill
210 add v0, msp, SIGCTX_PC1_OFFSET
211 store 0, 0, v2, v0
212 sub v2, v2, 4 ; determine pc0
213 add v0, msp, SIGCTX_PC0_OFFSET
214 store 0, 0, v2, v0
215 const v2, 0 ; clear chc
216 add v0, msp, SIGCTX_CHC_OFFSET
217 store 0, 0, v2, v0
219 nfill:
220 cpgt v0, gr1, rfb ; if gr1 > rfb then gr1 = rfb
221 jmpt v0, lower
222 cplt v0, gr1, rab ; if gr1 < rab then gr1 = rab
223 jmpt v0, raise
225 ; -------------------------------------------------------- save_regs
226 sig1: sub msp, msp, (4+2+25)*4 ; reserve space for regs
227 mfsr gr96, ipc
228 mfsr gr97, ipa
229 mfsr gr98, ipb
230 mfsr gr99, q
231 mtsrim cr, 4-1
232 storem 0, 0, gr96, msp
233 ; "push" registers stack support
234 add gr96, lr1, 0
235 add gr97, rfb, 0
236 mtsrim cr, 2-1
237 add gr99, msp, 2*4
238 storem 0, 0, gr96, gr99
239 ; "push" remaining global registers
240 mtsrim cr, 25-1 ; gr100-gr124
241 add gr96, msp, (4+2)*4
242 storem 0, 0, gr100, gr96
244 ; -------------------------------------------------------- Dummy Call
245 .equ RALLOC, 4*4 ; make space for function calls
246 add v0, rfb, 0 ; store original rfb
247 sub gr1, gr1, RALLOC
248 asgeu V_SPILL, gr1, rab
249 add lr1, v0, 0 ; set lr1 = original rfb
250 add v1, msp, (4+2+25)*4 + SIGCTX_SIGNUMB
251 load 0, 0, lr2, v1 ; restore signal number
252 sub v1, lr2, 1 ; get handler index
253 sll v1, v1, 2 ; point to addresses
255 ; -------------------------------------------------------- call C-level
256 ; Handler must not use HIF services other than the _sigret() type.
257 const v0, SigEntry
258 consth v0, SigEntry
259 add v0, v0, v1
260 load 0, 0, v0, v0 ; determine if handler registered
261 cpeq v1, v0, 0
262 jmpt v1, NoHandler
264 calli lr0, v0 ; call C-level signal handler
267 ; -------------------------------------------------------- default return
268 NoHandler:
269 jmp __sigdfl
272 ; -------------------------------------------------------- support bits
273 lower: sll gr1, rfb, 0
274 jmp sig1
276 raise: sll gr1, rab, 0
277 jmp sig1
280 ; -------------------------------------------------------- repair_regs
281 mtsrim cr, 4-1
282 loadm 0, 0, gr96, msp
283 mtsr ipc, gr96
284 mtsr ipa, gr97
285 mtsr ipb, gr98
286 mtsr Q, gr99
287 ; "pop" registers stack support
288 mtsrim cr, 2-1
289 add gr99, msp, 2*4
290 loadm 0, 0, gr96, gr99
291 add lr1, gr96, 0
292 add rfb, gr97, 0
293 ; "pop" remaining global registers
294 mtsrim cr, 25-1 ; gr100-gr124
295 add gr96, msp, (4+2)*4
296 loadm 0, 0, gr100, gr96
297 add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value
298 ; -------------------------------------------------------- end repair
301 ; ======================================================== _sigret()
302 .global __sigret
303 __sigret:
304 ; repair_regs
305 ; -------------------------------------------------------- repair_regs
306 mtsrim cr, 4-1
307 loadm 0, 0, gr96, msp
308 mtsr ipc, gr96
309 mtsr ipa, gr97
310 mtsr ipb, gr98
311 mtsr q, gr99
312 ; "pop" registers stack support
313 mtsrim cr, 2-1
314 add gr99, msp, 2*4
315 loadm 0, 0, gr96, gr99
316 add lr1, gr96, 0
317 add rfb, gr97, 0
318 ; "pop" remaining global registers
319 mtsrim cr, 25-1 ; gr100-gr124
320 add gr96, msp, (4+2)*4
321 loadm 0, 0, gr100, gr96
322 add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value
323 ; -------------------------------------------------------- end repair
324 const tav, 323 ; HIF _sigret
325 asneq 69, gr1,gr1
326 halt ; commit suicide if returns
328 ; ======================================================== _sigdfl()
329 .global __sigdfl
330 __sigdfl:
331 ; repair_regs
332 ; -------------------------------------------------------- repair_regs
333 mtsrim cr, 4-1
334 loadm 0, 0, gr96, msp
335 mtsr ipc, gr96
336 mtsr ipa, gr97
337 mtsr ipb, gr98
338 mtsr q, gr99
339 ; "pop" registers stack support
340 mtsrim cr, 2-1
341 add gr99, msp, 2*4
342 loadm 0, 0, gr96, gr99
343 add lr1, gr96, 0
344 add rfb, gr97, 0
345 ; "pop" remaining global registers
346 mtsrim cr, 25-1 ; gr100-gr124
347 add gr96, msp, (4+2)*4
348 loadm 0, 0, gr100, gr96
349 add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value
350 ; -------------------------------------------------------- end repair
351 const tav, 322 ; HIF _sigdfl
352 asneq 69, gr1,gr1
353 halt ; commit suicide if returns
355 ; ======================================================== _sigrep()
356 __sigrep:
357 .global __sigrep
358 ; repair_regs
359 ; -------------------------------------------------------- repair_regs
360 mtsrim cr, 4-1
361 loadm 0, 0, gr96, msp
362 mtsr ipc, gr96
363 mtsr ipa, gr97
364 mtsr ipb, gr98
365 mtsr q, gr99
366 ; "pop" registers stack support
367 mtsrim cr, 2-1
368 add gr99, msp, 2*4
369 loadm 0, 0, gr96, gr99
370 add lr1, gr96, 0
371 add rfb, gr97, 0
372 ; "pop" remaining global registers
373 mtsrim cr, 25-1 ; gr100-gr124
374 add gr96, msp, (4+2)*4
375 loadm 0, 0, gr100, gr96
376 add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value
377 ; -------------------------------------------------------- end repair
378 const tav, 324 ; HIF _sigrep
379 asneq 69, gr1,gr1
380 halt ; commit suicide if returns
382 ; ======================================================== _sigskp()
383 .global __sigskp
384 __sigskp:
385 ; repair_regs
386 ; -------------------------------------------------------- repair_regs
387 mtsrim cr, 4-1
388 loadm 0, 0, gr96, msp
389 mtsr ipc, gr96
390 mtsr ipa, gr97
391 mtsr ipb, gr98
392 mtsr q, gr99
393 ; "pop" registers stack support
394 mtsrim cr, 2-1
395 add gr99, msp, 2*4
396 loadm 0, 0, gr96, gr99
397 add lr1, gr96, 0
398 add rfb, gr97, 0
399 ; "pop" remaining global registers
400 mtsrim cr, 25-1 ; gr100-gr124
401 add gr96, msp, (4+2)*4
402 loadm 0, 0, gr100, gr96
403 add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value
404 ; -------------------------------------------------------- end repair
405 const tav, 325 ; HIF _sigskp
406 asneq 69, gr1,gr1
407 halt ; commit suicide if returns
409 ; ======================================================== _sendsig()
410 ; lr2 = signal number
411 .global _raise
412 .global __sendsig
413 _raise:
414 __sendsig:
415 const tav, 326 ; HIF sendsig
416 asneq 69, gr1,gr1
417 jmpi lr0
421 ; ======================================================== signal()
422 ; lr2 = signal number
423 ; lr3 = handler address
424 .global _signal
425 _signal:
426 ; the memory variable WindowSize must be initalised at the
427 ; start when rfb and rab are a window size apart.
428 const v0, WindowSize ; get register cache size
429 consth v0, WindowSize
430 load 0, 0, v1, v0
431 cpeq v1, v1, 0
432 jmpf v1, WindowSizeOK
433 sub v1, rfb, rab ; rfb-rab = WINDOW_SIZE
434 store 0, 0, v1, v0
435 WindowSizeOK:
436 const v1, SigEntry
437 consth v1, SigEntry
438 sub v3, lr2, 1 ; get handler index
439 sll v3, v3, 2 ; pointer to addresses
440 add v1, v1, v3
441 store 0,0, lr3, v1 ; save new handler
443 const lr2, sigcode
444 consth lr2, sigcode
445 ;Fall through to __signal
446 ; ======================================================== _signal()
447 .global __signal
448 __signal:
449 const tav, 321 ; HIF signal
450 asneq 69, gr1,gr1
451 jmpi lr0