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
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
41 .word 0 ; adds. of #2 SIGINT handler
47 .word 0 ; adds. of #8 SIGFPE handler
64 ;
=================================================================== setjmp
()
66 ; setjmp
(label_t jmpbuf
)
68 ;
*jmpbuf
= {gr1
, msp
, lr0
, lr1
};
84 ;
==================================================================== longjmp
()
86 ; longjmp
(label_t jmpbuf
, int value
)
88 ;
/* BUG: check for this
89 ; if (msp > jmpbuf->msp || gr1 > jmpbuf->gr1)
94 ; lr2addr
= jmpbuf-
>gr1
+ 8;
97 ;
/* saved lr1 is invalid if saved lr2addr > rfb */
98 ; if
(lr2addr
> rfb
) {
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
105 ; rab
= lr2addr
- windowsize;
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
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
)
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
133 sub rab
, tav
, v3 ; rab
= lr2addr
- windowsize
134 add rfb
, tav
, 0 ; rfb
= lr2addr
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
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
186 ;
-------------------------------------------------------- R-Stack fixup
187 const v0
, WindowSize ; get register cache size
188 consth v0
, WindowSize
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
194 jmpt v1
, nfill ; jmp if spill
or 'normal' interrupt
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
210 add v0
, msp
, SIGCTX_PC1_OFFSET
212 sub v2
, v2
, 4 ; determine pc0
213 add v0
, msp
, SIGCTX_PC0_OFFSET
215 const v2
, 0 ; clear chc
216 add v0
, msp
, SIGCTX_CHC_OFFSET
220 cpgt v0
, gr1
, rfb ; if gr1
> rfb then gr1
= rfb
222 cplt v0
, gr1
, rab ; if gr1
< rab then gr1
= rab
225 ;
-------------------------------------------------------- save_regs
226 sig1
: sub msp
, msp
, (4+2+25)*4 ; reserve space for regs
232 storem
0, 0, gr96
, msp
233 ;
"push" registers stack support
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
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.
260 load
0, 0, v0
, v0 ; determine if handler registered
264 calli lr0
, v0 ; call C-level signal handler
267 ;
-------------------------------------------------------- default return
272 ;
-------------------------------------------------------- support bits
273 lower
: sll gr1
, rfb
, 0
276 raise
: sll gr1
, rab
, 0
280 ; -------------------------------------------------------- repair_regs
282 loadm 0, 0, gr96, msp
287 ; "pop" registers stack support
290 loadm 0, 0, gr96, gr99
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
()
305 ;
-------------------------------------------------------- repair_regs
307 loadm
0, 0, gr96
, msp
312 ;
"pop" registers stack support
315 loadm
0, 0, gr96
, gr99
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
326 halt ; commit suicide if returns
328 ;
======================================================== _sigdfl
()
332 ;
-------------------------------------------------------- repair_regs
334 loadm
0, 0, gr96
, msp
339 ;
"pop" registers stack support
342 loadm
0, 0, gr96
, gr99
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
353 halt ; commit suicide if returns
355 ;
======================================================== _sigrep
()
359 ;
-------------------------------------------------------- repair_regs
361 loadm
0, 0, gr96
, msp
366 ;
"pop" registers stack support
369 loadm
0, 0, gr96
, gr99
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
380 halt ; commit suicide if returns
382 ;
======================================================== _sigskp
()
386 ;
-------------------------------------------------------- repair_regs
388 loadm
0, 0, gr96
, msp
393 ;
"pop" registers stack support
396 loadm
0, 0, gr96
, gr99
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
407 halt ; commit suicide if returns
409 ;
======================================================== _sendsig
()
410 ; lr2
= signal number
415 const tav
, 326 ; HIF sendsig
421 ;
======================================================== signal
()
422 ; lr2
= signal number
423 ; lr3
= handler address
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
432 jmpf v1
, WindowSizeOK
433 sub v1
, rfb
, rab ; rfb-rab
= WINDOW_SIZE
438 sub v3
, lr2
, 1 ; get handler index
439 sll v3
, v3
, 2 ; pointer to addresses
441 store
0,0, lr3
, v1 ; save new handler
445 ;Fall through to __signal
446 ;
======================================================== _signal
()
449 const tav
, 321 ; HIF signal