source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/rtems_skel.s @ 010e7582

4.104.114.84.95
Last change on this file since 010e7582 was 010e7582, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 16, 1997 at 5:34:23 PM

Added CVS Id's

  • Property mode set to 100644
File size: 9.8 KB
Line 
1//
2//      skeleton.sa 3.2 4/26/91
3//
4//      This file contains code that is system dependent and will
5//      need to be modified to install the FPSP.
6//
7//      Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
8//      Put any target system specific handling that must be done immediately
9//      before the jump instruction.  If there no handling necessary, then
10//      the 'fpsp_xxxx' handler entry point should be placed in the exception
11//      table so that the 'jmp' can be eliminated. If the FPSP determines that the
12//      exception is one that must be reported then there will be a
13//      return from the package by a 'jmp real_xxxx'.  At that point
14//      the machine state will be identical to the state before
15//      the FPSP was entered.  In particular, whatever condition
16//      that caused the exception will still be pending when the FPSP
17//      package returns.  Thus, there will be system specific code
18//      to handle the exception.
19//
20//      If the exception was completely handled by the package, then
21//      the return will be via a 'jmp fpsp_done'.  Unless there is
22//      OS specific work to be done (such as handling a context switch or
23//      interrupt) the user program can be resumed via 'rte'.
24//
25//      In the following skeleton code, some typical 'real_xxxx' handling
26//      code is shown.  This code may need to be moved to an appropriate
27//      place in the target system, or rewritten.
28//     
29
30//              Copyright (C) Motorola, Inc. 1990
31//                      All Rights Reserved
32//
33//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
34//      The copyright notice above does not evidence any 
35//      actual or intended publication of such source code.
36
37//  $Id$
38
39//
40//      Modified for Linux-1.3.x by Jes Sorensen (jds@kom.auc.dk)
41//      Modified for RTEMS 4.0.0 by Eric Norum (eric@skatter.usask.ca)
42//
43
44#include <asm.h>
45
46//SKELETON      idnt    2,1 | Motorola 040 Floating Point Software Package
47
48        .include "fpsp.defs"
49
50//
51//      Divide by Zero exception
52//
53//      All dz exceptions are 'real', hence no fpsp_dz entry point.
54//
55        .global SYM(_fpspEntry_dz)
56SYM(_fpspEntry_dz):
57        link            %a6,#-LOCAL_SIZE
58        fsave           -(%sp)
59        bclrb           #E1,E_BYTE(%a6)
60        frestore        (%sp)+
61        unlk            %a6
62        jmp             ([SYM(M68040FPSPUserExceptionHandlers)+3*4],za0)
63
64//
65//      Inexact exception
66//
67//      All inexact exceptions are real, but the 'real' handler
68//      will probably want to clear the pending exception.
69//      The provided code will clear the E3 exception (if pending), 
70//      otherwise clear the E1 exception.  The frestore is not really
71//      necessary for E1 exceptions.
72//
73// Code following the 'inex' label is to handle bug #1232.  In this
74// bug, if an E1 snan, ovfl, or unfl occurred, and the process was
75// swapped out before taking the exception, the exception taken on
76// return was inex, rather than the correct exception.  The snan, ovfl,
77// and unfl exception to be taken must not have been enabled.  The
78// fix is to check for E1, and the existence of one of snan, ovfl,
79// or unfl bits set in the fpsr.  If any of these are set, branch
80// to the appropriate  handler for the exception in the fpsr.  Note
81// that this fix is only for d43b parts, and is skipped if the
82// version number is not $40.
83// 
84//
85        .global SYM(_fpspEntry_inex)
86        .global real_inex
87SYM(_fpspEntry_inex):
88        link            %a6,#-LOCAL_SIZE
89        fsave           -(%sp)
90        cmpib           #VER_40,(%sp)           //test version number
91        bnes            not_fmt40
92        fmovel          %fpsr,-(%sp)
93        btstb           #E1,E_BYTE(%a6)         //test for E1 set
94        beqs            not_b1232
95        btstb           #snan_bit,2(%sp) //test for snan
96        beq             inex_ckofl
97        addl            #4,%sp
98        frestore        (%sp)+
99        unlk            %a6
100        bra             snan
101inex_ckofl:
102        btstb           #ovfl_bit,2(%sp) //test for ovfl
103        beq             inex_ckufl
104        addl            #4,%sp
105        frestore        (%sp)+
106        unlk            %a6
107        bra             SYM(_fpspEntry_ovfl)
108inex_ckufl:
109        btstb           #unfl_bit,2(%sp) //test for unfl
110        beq             not_b1232
111        addl            #4,%sp
112        frestore        (%sp)+
113        unlk            %a6
114        bra             SYM(_fpspEntry_unfl)
115
116//
117// We do not have the bug 1232 case.  Clean up the stack and call
118// real_inex.
119//
120not_b1232:
121        addl            #4,%sp
122        frestore        (%sp)+
123        unlk            %a6
124
125real_inex:
126        link            %a6,#-LOCAL_SIZE
127        fsave           -(%sp)
128not_fmt40:
129        bclrb           #E3,E_BYTE(%a6)         //clear and test E3 flag
130        beqs            inex_cke1
131//
132// Clear dirty bit on dest resister in the frame before branching
133// to b1238_fix.
134//
135        moveml          %d0/%d1,USER_DA(%a6)
136        bfextu          CMDREG1B(%a6){#6:#3},%d0                //get dest reg no
137        bclrb           %d0,FPR_DIRTY_BITS(%a6) //clr dest dirty bit
138        bsrl            b1238_fix               //test for bug1238 case
139        moveml          USER_DA(%a6),%d0/%d1
140        bras            inex_done
141inex_cke1:
142        bclrb           #E1,E_BYTE(%a6)
143inex_done:
144        frestore        (%sp)+
145        unlk            %a6
146        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+2*4],za0)
147       
148//
149//      Overflow exception
150//
151        .global SYM(_fpspEntry_ovfl)
152        .global real_ovfl
153SYM(_fpspEntry_ovfl):
154        jmp     fpsp_ovfl
155real_ovfl:
156        link            %a6,#-LOCAL_SIZE
157        fsave           -(%sp)
158        bclrb           #E3,E_BYTE(%a6)         //clear and test E3 flag
159        bnes            ovfl_done
160        bclrb           #E1,E_BYTE(%a6)
161ovfl_done:
162        frestore        (%sp)+
163        unlk            %a6
164        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+6*4],za0)
165       
166//
167//      Underflow exception
168//
169        .global SYM(_fpspEntry_unfl)
170        .global real_unfl
171SYM(_fpspEntry_unfl):
172        jmp     fpsp_unfl
173real_unfl:
174        link            %a6,#-LOCAL_SIZE
175        fsave           -(%sp)
176        bclrb           #E3,E_BYTE(%a6)         //clear and test E3 flag
177        bnes            unfl_done
178        bclrb           #E1,E_BYTE(%a6)
179unfl_done:
180        frestore        (%sp)+
181        unlk            %a6
182        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+4*4],za0)
183       
184//
185//      Signalling NAN exception
186//
187        .global SYM(_fpspEntry_snan)
188        .global real_snan
189SYM(_fpspEntry_snan):
190snan:
191        jmp     fpsp_snan
192real_snan:
193        link            %a6,#-LOCAL_SIZE
194        fsave           -(%sp)
195        bclrb           #E1,E_BYTE(%a6) //snan is always an E1 exception
196        frestore        (%sp)+
197        unlk            %a6
198        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+7*4],za0)
199
200//
201//      Operand Error exception
202//
203        .global SYM(_fpspEntry_operr)
204        .global real_operr
205SYM(_fpspEntry_operr):
206        jmp     fpsp_operr
207real_operr:
208        link            %a6,#-LOCAL_SIZE
209        fsave           -(%sp)
210        bclrb           #E1,E_BYTE(%a6) //operr is always an E1 exception
211        frestore        (%sp)+
212        unlk            %a6
213        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+5*4],za0)
214       
215//
216//      BSUN exception
217//
218//      This sample handler simply clears the nan bit in the FPSR.
219//
220        .global SYM(_fpspEntry_bsun)
221        .global real_bsun
222SYM(_fpspEntry_bsun):
223        jmp     fpsp_bsun
224real_bsun:
225        link            %a6,#-LOCAL_SIZE
226        fsave           -(%sp)
227        bclrb           #E1,E_BYTE(%a6) //bsun is always an E1 exception
228        fmovel          %FPSR,-(%sp)
229        bclrb           #nan_bit,(%sp)
230        fmovel          (%sp)+,%FPSR
231        frestore        (%sp)+
232        unlk            %a6
233        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+1*4],za0)
234
235//
236//      F-line exception
237//
238//      A 'real' F-line exception is one that the FPSP is not supposed to
239//      handle. E.g. an instruction with a co-processor ID that is not 1.
240//
241        .global SYM(_fpspEntry_fline)
242        .global real_fline
243SYM(_fpspEntry_fline):
244        jmp     fpsp_fline
245real_fline:
246        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+0*4],za0)
247
248//
249//      Unsupported data type exception
250//
251        .global SYM(_fpspEntry_unsupp)
252        .global real_unsupp
253SYM(_fpspEntry_unsupp):
254        jmp     fpsp_unsupp
255real_unsupp:
256        link            %a6,#-LOCAL_SIZE
257        fsave           -(%sp)
258        bclrb           #E1,E_BYTE(%a6) //unsupp is always an E1 exception
259        frestore        (%sp)+
260        unlk            %a6
261        jmp     ([SYM(M68040FPSPUserExceptionHandlers)+8*4],za0)
262
263//
264//      Trace exception
265//
266        .global real_trace
267real_trace:
268        trap    #10
269
270//
271//      fpsp_fmt_error --- exit point for frame format error
272//
273//      The fpu stack frame does not match the frames existing
274//      or planned at the time of this writing.  The fpsp is
275//      unable to handle frame sizes not in the following
276//      version:size pairs:
277//
278//      {4060, 4160} - busy frame
279//      {4028, 4130} - unimp frame
280//      {4000, 4100} - idle frame
281//
282        .global fpsp_fmt_error
283fpsp_fmt_error:
284        trap    #11
285
286//
287//      fpsp_done --- FPSP exit point
288//
289//      The exception has been handled by the package and we are ready
290//      to return to user mode, but there may be OS specific code
291//      to execute before we do.  If there is, do it now.
292//
293// For now, the RTEMS does not bother looking at the
294// possibility that it is time to reschedule....
295//
296
297        .global fpsp_done
298fpsp_done:
299        rte
300
301//
302//      mem_write --- write to user or supervisor address space
303//
304// Writes to memory while in supervisor mode.
305//
306//      a0 - supervisor source address
307//      a1 - user/supervisor destination address
308//      d0 - number of bytes to write (maximum count is 12)
309//
310        .global mem_write
311mem_write:
312        btstb   #5,EXC_SR(%a6)  //check for supervisor state
313        beqs    user_write
314super_write:
315        moveb   (%a0)+,(%a1)+
316        subql   #1,%d0
317        bnes    super_write
318        rts
319user_write:
320        movel   %d1,-(%sp)      //preserve d1 just in case
321        movel   %d0,-(%sp)
322        movel   %a1,-(%sp)
323        movel   %a0,-(%sp)
324        jsr             copyout
325        addw    #12,%sp
326        movel   (%sp)+,%d1
327        rts
328//
329//      mem_read --- read from user or supervisor address space
330//
331// Reads from memory while in supervisor mode.
332//
333// The FPSP calls mem_read to read the original F-line instruction in order
334// to extract the data register number when the 'Dn' addressing mode is
335// used.
336//
337//Input:
338//      a0 - user/supervisor source address
339//      a1 - supervisor destination address
340//      d0 - number of bytes to read (maximum count is 12)
341//
342// Like mem_write, mem_read always reads with a supervisor
343// destination address on the supervisor stack.  Also like mem_write,
344// the EXC_SR is checked and a simple memory copy is done if reading
345// from supervisor space is indicated.
346//
347        .global mem_read
348mem_read:
349        btstb   #5,EXC_SR(%a6)  //check for supervisor state
350        beqs    user_read
351super_read:
352        moveb   (%a0)+,(%a1)+
353        subql   #1,%d0
354        bnes    super_read
355        rts
356user_read:
357        movel   %d1,-(%sp)      //preserve d1 just in case
358        movel   %d0,-(%sp)
359        movel   %a1,-(%sp)
360        movel   %a0,-(%sp)
361        jsr             copyin
362        addw    #12,%sp
363        movel   (%sp)+,%d1
364        rts
365
366//
367// Use these routines if your kernel does not have copyout/copyin equivalents.
368// Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
369// and copyin overwrites SFC.
370//
371copyout:
372        movel   4(%sp),%a0      // source
373        movel   8(%sp),%a1      // destination
374        movel   12(%sp),%d0     // count
375        subl    #1,%d0          // dec count by 1 for dbra
376        movel   #1,%d1
377        movec   %d1,%DFC                // set dfc for user data space
378moreout:
379        moveb   (%a0)+,%d1      // fetch supervisor byte
380        movesb  %d1,(%a1)+      // write user byte
381        dbf     %d0,moreout
382        rts
383
384copyin:
385        movel   4(%sp),%a0      // source
386        movel   8(%sp),%a1      // destination
387        movel   12(%sp),%d0     // count
388        subl    #1,%d0          // dec count by 1 for dbra
389        movel   #1,%d1
390        movec   %d1,%SFC                // set sfc for user space
391morein:
392        movesb  (%a0)+,%d1      // fetch user byte
393        moveb   %d1,(%a1)+      // write supervisor byte
394        dbf     %d0,morein
395        rts
396
397        |end
Note: See TracBrowser for help on using the repository browser.