No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / m68k / fpsp / skeleton.sa
blob9f9dcaff3a7e0791ef183c35efce0bacaeea3e18
1 *       $NetBSD: skeleton.sa,v 1.3 1994/10/26 07:49:50 cgd Exp $
3 *       MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 *       M68000 Hi-Performance Microprocessor Division
5 *       M68040 Software Package 
7 *       M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 *       All rights reserved.
10 *       THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11 *       To the maximum extent permitted by applicable law,
12 *       MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13 *       INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14 *       PARTICULAR PURPOSE and any warranty against infringement with
15 *       regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16 *       and any accompanying written materials. 
18 *       To the maximum extent permitted by applicable law,
19 *       IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20 *       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21 *       PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22 *       OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23 *       SOFTWARE.  Motorola assumes no responsibility for the maintenance
24 *       and support of the SOFTWARE.  
26 *       You are hereby granted a copyright license to use, modify, and
27 *       distribute the SOFTWARE so long as this entire notice is retained
28 *       without alteration in any modified and/or redistributed versions,
29 *       and that such modified versions are clearly identified as such.
30 *       No licenses are granted by implication, estoppel or otherwise
31 *       under any patents or trademarks of Motorola, Inc.
34 *       skeleton.sa 3.2 4/26/91
36 *       This file contains code that is system dependent and will
37 *       need to be modified to install the FPSP.
39 *       Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
40 *       Put any target system specific handling that must be done immediately
41 *       before the jump instruction.  If there no handling necessary, then
42 *       the 'fpsp_xxxx' handler entry point should be placed in the exception
43 *       table so that the 'jmp' can be eliminated. If the FPSP determines that the
44 *       exception is one that must be reported then there will be a
45 *       return from the package by a 'jmp real_xxxx'.  At that point
46 *       the machine state will be identical to the state before
47 *       the FPSP was entered.  In particular, whatever condition
48 *       that caused the exception will still be pending when the FPSP
49 *       package returns.  Thus, there will be system specific code
50 *       to handle the exception.
52 *       If the exception was completely handled by the package, then
53 *       the return will be via a 'jmp fpsp_done'.  Unless there is 
54 *       OS specific work to be done (such as handling a context switch or
55 *       interrupt) the user program can be resumed via 'rte'.
57 *       In the following skeleton code, some typical 'real_xxxx' handling
58 *       code is shown.  This code may need to be moved to an appropriate
59 *       place in the target system, or rewritten.
60 *       
62 SKELETON        IDNT    2,1 Motorola 040 Floating Point Software Package
64         section 15
66 *       The following counters are used for standalone testing
68 sigunimp        dc.l    0
69 sigbsun         dc.l    0
70 siginex         dc.l    0
71 sigdz           dc.l    0
72 sigunfl         dc.l    0
73 sigovfl         dc.l    0
74 sigoperr        dc.l    0
75 sigsnan         dc.l    0
76 sigunsupp       dc.l    0
78         section 8
80         include fpsp.h
82         xref    b1238_fix
85 *       Divide by Zero exception
87 *       All dz exceptions are 'real', hence no fpsp_dz entry point.
89         xdef    dz
90         xdef    real_dz
91 dz:
92 real_dz:
93         link            a6,#-LOCAL_SIZE
94         fsave           -(sp)
95         bclr.b          #E1,E_BYTE(a6)
96         frestore        (sp)+
97         unlk            a6
99         add.l   #1,sigdz                ;for standalone testing
101         rte
103 *       Inexact exception
105 *       All inexact exceptions are real, but the 'real' handler
106 *       will probably want to clear the pending exception.
107 *       The provided code will clear the E3 exception (if pending), 
108 *       otherwise clear the E1 exception.  The frestore is not really
109 *       necessary for E1 exceptions.
111 * Code following the 'inex' label is to handle bug #1232.  In this
112 * bug, if an E1 snan, ovfl, or unfl occurred, and the process was
113 * swapped out before taking the exception, the exception taken on
114 * return was inex, rather than the correct exception.  The snan, ovfl,
115 * and unfl exception to be taken must not have been enabled.  The
116 * fix is to check for E1, and the existence of one of snan, ovfl,
117 * or unfl bits set in the fpsr.  If any of these are set, branch
118 * to the appropriate  handler for the exception in the fpsr.  Note
119 * that this fix is only for d43b parts, and is skipped if the
120 * version number is not $40.
123         xdef    real_inex
124         xdef    inex
125 inex:
126         link            a6,#-LOCAL_SIZE
127         fsave           -(sp)
128         cmpi.b          #VER_40,(sp)            ;test version number
129         bne.b           not_fmt40
130         fmove.l         fpsr,-(sp)
131         btst.b          #E1,E_BYTE(a6)          ;test for E1 set
132         beq.b           not_b1232
133         btst.b          #snan_bit,2(sp) ;test for snan
134         beq             inex_ckofl
135         add.l           #4,sp
136         frestore        (sp)+
137         unlk            a6
138         bra             snan
139 inex_ckofl:
140         btst.b          #ovfl_bit,2(sp) ;test for ovfl
141         beq             inex_ckufl 
142         add.l           #4,sp
143         frestore        (sp)+
144         unlk            a6
145         bra             ovfl
146 inex_ckufl:
147         btst.b          #unfl_bit,2(sp) ;test for unfl
148         beq             not_b1232
149         add.l           #4,sp
150         frestore        (sp)+
151         unlk            a6
152         bra             unfl
155 * We do not have the bug 1232 case.  Clean up the stack and call
156 * real_inex.
158 not_b1232:
159         add.l           #4,sp
160         frestore        (sp)+
161         unlk            a6
163 real_inex:
165         add.l           #1,siginex              ;for standalone testing
167         link            a6,#-LOCAL_SIZE
168         fsave           -(sp)
169 not_fmt40:
170         bclr.b          #E3,E_BYTE(a6)          ;clear and test E3 flag
171         beq.b           inex_cke1
173 * Clear dirty bit on dest resister in the frame before branching
174 * to b1238_fix.
176         movem.l         d0/d1,USER_DA(a6)
177         bfextu          CMDREG1B(a6){6:3},d0            ;get dest reg no
178         bclr.b          d0,FPR_DIRTY_BITS(a6)   ;clr dest dirty bit
179         bsr.l           b1238_fix               ;test for bug1238 case
180         movem.l         USER_DA(a6),d0/d1
181         bra.b           inex_done
182 inex_cke1:
183         bclr.b          #E1,E_BYTE(a6)
184 inex_done:
185         frestore        (sp)+
186         unlk            a6
187         rte
188         
190 *       Overflow exception
192         xref    fpsp_ovfl
193         xdef    real_ovfl
194         xdef    ovfl
195 ovfl:
196         jmp     fpsp_ovfl
197 real_ovfl:
199         add.l           #1,sigovfl              ;for standalone testing
201         link            a6,#-LOCAL_SIZE
202         fsave           -(sp)
203         bclr.b          #E3,E_BYTE(a6)          ;clear and test E3 flag
204         bne.b           ovfl_done
205         bclr.b          #E1,E_BYTE(a6)
206 ovfl_done:
207         frestore        (sp)+
208         unlk            a6
209         rte
210         
212 *       Underflow exception
214         xref    fpsp_unfl
215         xdef    real_unfl
216         xdef    unfl
217 unfl:
218         jmp     fpsp_unfl
219 real_unfl:
221         add.l           #1,sigunfl              ;for standalone testing
223         link            a6,#-LOCAL_SIZE
224         fsave           -(sp)
225         bclr.b          #E3,E_BYTE(a6)          ;clear and test E3 flag
226         bne.b           unfl_done
227         bclr.b          #E1,E_BYTE(a6)
228 unfl_done:
229         frestore        (sp)+
230         unlk            a6
231         rte
232         
234 *       Signalling NAN exception
236         xref    fpsp_snan
237         xdef    real_snan
238         xdef    snan
239 snan:
240         jmp     fpsp_snan
241 real_snan:
242         link            a6,#-LOCAL_SIZE
243         fsave           -(sp)
244         bclr.b          #E1,E_BYTE(a6)  ;snan is always an E1 exception
245         frestore        (sp)+
246         unlk            a6
248         add.l           #1,sigsnan              ;for standalone testing
249         rte
250         
252 *       Operand Error exception
254         xref    fpsp_operr
255         xdef    real_operr
256         xdef    operr
257 operr:
258         jmp     fpsp_operr
259 real_operr:
260         link            a6,#-LOCAL_SIZE
261         fsave           -(sp)
262         bclr.b          #E1,E_BYTE(a6)  ;operr is always an E1 exception
263         frestore        (sp)+
264         unlk            a6
266         add.l           #1,sigoperr             ;for standalone testing
268         rte
269         
271 *       BSUN exception
273 *       This sample handler simply clears the nan bit in the FPSR.
275         xref    fpsp_bsun
276         xdef    real_bsun
277         xdef    bsun
278 bsun:
279         jmp     fpsp_bsun
280 real_bsun:
281         link            a6,#-LOCAL_SIZE
282         fsave           -(sp)
283         bclr.b          #E1,E_BYTE(a6)  ;bsun is always an E1 exception
284         fmove.l         FPSR,-(sp)
285         bclr.b          #nan_bit,(sp)
286         fmove.l         (sp)+,FPSR
287         frestore        (sp)+
288         unlk            a6
290         add.l           #1,sigbsun              ;for standalone testing
292         rte
295 *       F-line exception
297 *       A 'real' F-line exception is one that the FPSP isn't supposed to 
298 *       handle. E.g. an instruction with a co-processor ID that is not 1.
301         xref    fpsp_fline
302         xdef    real_fline
303         xdef    fline
304 fline:
305         jmp     fpsp_fline
306 real_fline:
308         add.l           #1,sigunimp             ;for standalone testing
310         rte
313 *       Unsupported data type exception
315         xref    fpsp_unsupp
316         xdef    real_unsupp
317         xdef    unsupp
318 unsupp:
319         jmp     fpsp_unsupp
320 real_unsupp:
321         link            a6,#-LOCAL_SIZE
322         fsave           -(sp)
323         bclr.b          #E1,E_BYTE(a6)  ;unsupp is always an E1 exception
324         frestore        (sp)+
325         unlk            a6
327         add.l           #1,sigunsupp            ;for standalone testing
329         rte
332 *       Trace exception
334         xdef    real_trace
335 real_trace:
336         rte
339 *       fpsp_fmt_error --- exit point for frame format error
341 *       The fpu stack frame does not match the frames existing
342 *       or planned at the time of this writing.  The fpsp is
343 *       unable to handle frame sizes not in the following
344 *       version:size pairs:
346 *       {4060, 4160} - busy frame
347 *       {4028, 4130} - unimp frame
348 *       {4000, 4100} - idle frame
350 *       This entry point simply holds an f-line illegal value.  
351 *       Replace this with a call to your kernel panic code or
352 *       code to handle future revisions of the fpu.
354         xdef    fpsp_fmt_error
355 fpsp_fmt_error:
357         dc.l    $f27f0000       ;f-line illegal 
360 *       fpsp_done --- FPSP exit point
362 *       The exception has been handled by the package and we are ready
363 *       to return to user mode, but there may be OS specific code
364 *       to execute before we do.  If there is, do it now.
367         xdef    fpsp_done
368 fpsp_done:
369         rte
372 *       mem_write --- write to user or supervisor address space
374 * Writes to memory while in supervisor mode.  copyout accomplishes
375 * this via a 'moves' instruction.  copyout is a UNIX SVR3 (and later) function.
376 * If you don't have copyout, use the local copy of the function below.
378 *       a0 - supervisor source address
379 *       a1 - user destination address
380 *       d0 - number of bytes to write (maximum count is 12)
382 * The supervisor source address is guaranteed to point into the supervisor
383 * stack.  The result is that a UNIX
384 * process is allowed to sleep as a consequence of a page fault during
385 * copyout.  The probability of a page fault is exceedingly small because
386 * the 68040 always reads the destination address and thus the page
387 * faults should have already been handled.
389 * If the EXC_SR shows that the exception was from supervisor space,
390 * then just do a dumb (and slow) memory move.  In a UNIX environment
391 * there shouldn't be any supervisor mode floating point exceptions.
393         xdef    mem_write
394 mem_write:
395         btst.b  #5,EXC_SR(a6)   ;check for supervisor state
396         beq.b   user_write
397 super_write:
398         move.b  (a0)+,(a1)+
399         subq.l  #1,d0
400         bne.b   super_write
401         rts
402 user_write:
403         move.l  d1,-(sp)        ;preserve d1 just in case
404         move.l  d0,-(sp)
405         move.l  a1,-(sp)
406         move.l  a0,-(sp)
407         jsr             copyout
408         add.l   #12,sp
409         move.l  (sp)+,d1
410         rts
412 *       mem_read --- read from user or supervisor address space
414 * Reads from memory while in supervisor mode.  copyin accomplishes
415 * this via a 'moves' instruction.  copyin is a UNIX SVR3 (and later) function.
416 * If you don't have copyin, use the local copy of the function below.
418 * The FPSP calls mem_read to read the original F-line instruction in order
419 * to extract the data register number when the 'Dn' addressing mode is
420 * used.
422 *Input:
423 *       a0 - user source address
424 *       a1 - supervisor destination address
425 *       d0 - number of bytes to read (maximum count is 12)
427 * Like mem_write, mem_read always reads with a supervisor 
428 * destination address on the supervisor stack.  Also like mem_write,
429 * the EXC_SR is checked and a simple memory copy is done if reading
430 * from supervisor space is indicated.
432         xdef    mem_read
433 mem_read:
434         btst.b  #5,EXC_SR(a6)   ;check for supervisor state
435         beq.b   user_read
436 super_read:
437         move.b  (a0)+,(a1)+
438         subq.l  #1,d0
439         bne.b   super_read
440         rts
441 user_read:
442         move.l  d1,-(sp)        ;preserve d1 just in case
443         move.l  d0,-(sp)
444         move.l  a1,-(sp)
445         move.l  a0,-(sp)
446         jsr             copyin
447         add.l   #12,sp
448         move.l  (sp)+,d1
449         rts
452 * Use these routines if your kernel doesn't have copyout/copyin equivalents.
453 * Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
454 * and copyin overwrites SFC.
456 copyout:
457         move.l  4(sp),a0        ; source
458         move.l  8(sp),a1        ; destination
459         move.l  12(sp),d0       ; count
460         sub.l   #1,d0           ; dec count by 1 for dbra
461         move.l  #1,d1
462         movec   d1,DFC          ; set dfc for user data space
463 moreout:
464         move.b  (a0)+,d1        ; fetch supervisor byte
465         moves.b d1,(a1)+        ; write user byte
466         dbf.w   d0,moreout
467         rts
469 copyin:
470         move.l  4(sp),a0        ; source
471         move.l  8(sp),a1        ; destination
472         move.l  12(sp),d0       ; count
473         sub.l   #1,d0           ; dec count by 1 for dbra
474         move.l  #1,d1
475         movec   d1,SFC          ; set sfc for user space
476 morein:
477         moves.b (a0)+,d1        ; fetch user byte
478         move.b  d1,(a1)+        ; write supervisor byte
479         dbf.w   d0,morein
480         rts
482         end