source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/rtems_skel.S @ 0162910

4.104.114.84.95
Last change on this file since 0162910 was 0162910, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 14, 1998 at 11:15:38 PM

Patch from Ralf Corsepius <corsepiu@…> to rename all
.s files to .S in conformance with GNU conventions. This is a
minor step along the way to supporting automake.

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