source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/x_snan.S @ f8e4755f

5
Last change on this file since f8e4755f was f8e4755f, checked in by Sebastian Huber <sebastian.huber@…>, on 03/26/18 at 09:59:23

bsps/m68k: Use namespace header

This patch is a part of the BSP source reorganization.

Update #3285.

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