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

4.104.114.84.95
Last change on this file since f9b93da was f9b93da, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/97 at 17:33:04

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: 6.7 KB
Line 
1//
2//      x_snan.sa 3.3 7/1/91
3//
4// fpsp_snan --- FPSP handler for signalling NAN exception
5//
6// SNAN for float -> integer conversions (integer conversion of
7// an SNAN) is a non-maskable run-time exception.
8//
9// For trap disabled the 040 does the following:
10// If the dest data format is s, d, or x, then the SNAN bit in the NAN
11// is set to one and the resulting non-signaling NAN (truncated if
12// necessary) is transferred to the dest.  If the dest format is b, w,
13// or l, then garbage is written to the dest (actually the upper 32 bits
14// of the mantissa are sent to the integer unit).
15//
16// For trap enabled the 040 does the following:
17// If the inst is move_out, then the results are the same as for trap
18// disabled with the exception posted.  If the instruction is not move_
19// out, the dest. is not modified, and the exception is posted.
20//
21
22//              Copyright (C) Motorola, Inc. 1990
23//                      All Rights Reserved
24//
25//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
26//      The copyright notice above does not evidence any 
27//      actual or intended publication of such source code.
28
29X_SNAN: //idnt    2,1 | Motorola 040 Floating Point Software Package
30
31        |section        8
32
33        .include "fpsp.defs"
34
35        |xref   get_fline
36        |xref   mem_write
37        |xref   real_snan
38        |xref   real_inex
39        |xref   fpsp_done
40        |xref   reg_dest
41
42        .global fpsp_snan
43fpsp_snan:
44        link            %a6,#-LOCAL_SIZE
45        fsave           -(%a7)
46        moveml          %d0-%d1/%a0-%a1,USER_DA(%a6)
47        fmovemx %fp0-%fp3,USER_FP0(%a6)
48        fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
49
50//
51// Check if trap enabled
52//
53        btstb           #snan_bit,FPCR_ENABLE(%a6)
54        bnes            ena             //If enabled, then branch
55
56        bsrl            move_out        //else SNAN disabled
57//
58// It is possible to have an inex1 exception with the
59// snan.  If the inex enable bit is set in the FPCR, and either
60// inex2 or inex1 occurred, we must clean up and branch to the
61// real inex handler.
62//
63ck_inex:
64        moveb   FPCR_ENABLE(%a6),%d0
65        andb    FPSR_EXCEPT(%a6),%d0
66        andib   #0x3,%d0
67        beq     end_snan
68//
69// Inexact enabled and reported, and we must take an inexact exception.
70//
71take_inex:
72        moveb           #INEX_VEC,EXC_VEC+1(%a6)
73        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
74        fmovemx USER_FP0(%a6),%fp0-%fp3
75        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
76        frestore        (%a7)+
77        unlk            %a6
78        bral            real_inex
79//
80// SNAN is enabled.  Check if inst is move_out.
81// Make any corrections to the 040 output as necessary.
82//
83ena:
84        btstb           #5,CMDREG1B(%a6) //if set, inst is move out
85        beq             not_out
86
87        bsrl            move_out
88
89report_snan:
90        moveb           (%a7),VER_TMP(%a6)
91        cmpib           #VER_40,(%a7)   //test for orig unimp frame
92        bnes            ck_rev
93        moveql          #13,%d0         //need to zero 14 lwords
94        bras            rep_con
95ck_rev:
96        moveql          #11,%d0         //need to zero 12 lwords
97rep_con:
98        clrl            (%a7)
99loop1:
100        clrl            -(%a7)          //clear and dec a7
101        dbra            %d0,loop1
102        moveb           VER_TMP(%a6),(%a7) //format a busy frame
103        moveb           #BUSY_SIZE-4,1(%a7)
104        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
105        orl             #sx_mask,E_BYTE(%a6)
106        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
107        fmovemx USER_FP0(%a6),%fp0-%fp3
108        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
109        frestore        (%a7)+
110        unlk            %a6
111        bral            real_snan
112//
113// Exit snan handler by expanding the unimp frame into a busy frame
114//
115end_snan:
116        bclrb           #E1,E_BYTE(%a6)
117
118        moveb           (%a7),VER_TMP(%a6)
119        cmpib           #VER_40,(%a7)   //test for orig unimp frame
120        bnes            ck_rev2
121        moveql          #13,%d0         //need to zero 14 lwords
122        bras            rep_con2
123ck_rev2:
124        moveql          #11,%d0         //need to zero 12 lwords
125rep_con2:
126        clrl            (%a7)
127loop2:
128        clrl            -(%a7)          //clear and dec a7
129        dbra            %d0,loop2
130        moveb           VER_TMP(%a6),(%a7) //format a busy frame
131        moveb           #BUSY_SIZE-4,1(%a7) //write busy size
132        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
133        orl             #sx_mask,E_BYTE(%a6)
134        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
135        fmovemx USER_FP0(%a6),%fp0-%fp3
136        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
137        frestore        (%a7)+
138        unlk            %a6
139        bral            fpsp_done
140
141//
142// Move_out
143//
144move_out:
145        movel           EXC_EA(%a6),%a0 //get <ea> from exc frame
146
147        bfextu          CMDREG1B(%a6){#3:#3},%d0 //move rx field to d0{2:0}
148        cmpil           #0,%d0          //check for long
149        beqs            sto_long        //branch if move_out long
150       
151        cmpil           #4,%d0          //check for word
152        beqs            sto_word        //branch if move_out word
153       
154        cmpil           #6,%d0          //check for byte
155        beqs            sto_byte        //branch if move_out byte
156       
157//
158// Not byte, word or long
159//
160        rts
161//     
162// Get the 32 most significant bits of etemp mantissa
163//
164sto_long:
165        movel           ETEMP_HI(%a6),%d1
166        movel           #4,%d0          //load byte count
167//
168// Set signalling nan bit
169//
170        bsetl           #30,%d1                 
171//
172// Store to the users destination address
173//
174        tstl            %a0             //check if <ea> is 0
175        beqs            wrt_dn          //destination is a data register
176       
177        movel           %d1,-(%a7)      //move the snan onto the stack
178        movel           %a0,%a1         //load dest addr into a1
179        movel           %a7,%a0         //load src addr of snan into a0
180        bsrl            mem_write       //write snan to user memory
181        movel           (%a7)+,%d1      //clear off stack
182        rts
183//
184// Get the 16 most significant bits of etemp mantissa
185//
186sto_word:
187        movel           ETEMP_HI(%a6),%d1
188        movel           #2,%d0          //load byte count
189//
190// Set signalling nan bit
191//
192        bsetl           #30,%d1                 
193//
194// Store to the users destination address
195//
196        tstl            %a0             //check if <ea> is 0
197        beqs            wrt_dn          //destination is a data register
198
199        movel           %d1,-(%a7)      //move the snan onto the stack
200        movel           %a0,%a1         //load dest addr into a1
201        movel           %a7,%a0         //point to low word
202        bsrl            mem_write       //write snan to user memory
203        movel           (%a7)+,%d1      //clear off stack
204        rts
205//
206// Get the 8 most significant bits of etemp mantissa
207//
208sto_byte:
209        movel           ETEMP_HI(%a6),%d1
210        movel           #1,%d0          //load byte count
211//
212// Set signalling nan bit
213//
214        bsetl           #30,%d1                 
215//
216// Store to the users destination address
217//
218        tstl            %a0             //check if <ea> is 0
219        beqs            wrt_dn          //destination is a data register
220        movel           %d1,-(%a7)      //move the snan onto the stack
221        movel           %a0,%a1         //load dest addr into a1
222        movel           %a7,%a0         //point to source byte
223        bsrl            mem_write       //write snan to user memory
224        movel           (%a7)+,%d1      //clear off stack
225        rts
226
227//
228//      wrt_dn --- write to a data register
229//
230//      We get here with D1 containing the data to write and D0 the
231//      number of bytes to write: 1=byte,2=word,4=long.
232//
233wrt_dn:
234        movel           %d1,L_SCR1(%a6) //data
235        movel           %d0,-(%a7)      //size
236        bsrl            get_fline       //returns fline word in d0
237        movel           %d0,%d1
238        andil           #0x7,%d1                //d1 now holds register number
239        movel           (%sp)+,%d0      //get original size
240        cmpil           #4,%d0
241        beqs            wrt_long
242        cmpil           #2,%d0
243        bnes            wrt_byte
244wrt_word:
245        orl             #0x8,%d1
246        bral            reg_dest
247wrt_long:
248        orl             #0x10,%d1
249        bral            reg_dest
250wrt_byte:
251        bral            reg_dest
252//
253// Check if it is a src nan or dst nan
254//
255not_out:
256        movel           DTAG(%a6),%d0   
257        bfextu          %d0{#0:#3},%d0  //isolate dtag in lsbs
258
259        cmpib           #3,%d0          //check for nan in destination
260        bnes            issrc           //destination nan has priority
261dst_nan:
262        btstb           #6,FPTEMP_HI(%a6) //check if dest nan is an snan
263        bnes            issrc           //no, so check source for snan
264        movew           FPTEMP_EX(%a6),%d0
265        bras            cont
266issrc:
267        movew           ETEMP_EX(%a6),%d0
268cont:
269        btstl           #15,%d0         //test for sign of snan
270        beqs            clr_neg
271        bsetb           #neg_bit,FPSR_CC(%a6)
272        bra             report_snan
273clr_neg:
274        bclrb           #neg_bit,FPSR_CC(%a6)
275        bra             report_snan
276
277        |end
Note: See TracBrowser for help on using the repository browser.