source: rtems/bsps/m68k/shared/fpsp/rtems_skel.S @ 753873e5

Last change on this file since 753873e5 was 753873e5, checked in by Joel Sherrill <joel@…>, on 03/22/22 at 20:03:30

Update Eric Norum contact info and start to normalize file headers

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