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

4.104.114.84.95
Last change on this file since 1d320bac was 1d320bac, checked in by Joel Sherrill <joel.sherrill@…>, on 07/09/97 at 23:41:20

This code was in the tree but not actually being compiled. There
were a number of minor problems which had to be fixed to get it
to compile including modifying the compile rule to handle C++ comments,
changing the syntax of the include statement, and getting rid of "%"
as part of register names.

  • 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.