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

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

Added the MC68040 Floating Point Support Package. This was ported
to RTEMS by Eric Norum. It is freely distributable and was acquired
from the Motorola WWW site. More info is in the FPSP README.

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