source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/x_store.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: 7.1 KB
Line 
1//
2//      x_store.sa 3.2 1/24/91
3//
4//      store --- store operand to memory or register
5//
6//      Used by underflow and overflow handlers.
7//
8//      a6 = points to fp value to be stored.
9//
10
11//              Copyright (C) Motorola, Inc. 1990
12//                      All Rights Reserved
13//
14//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
15//      The copyright notice above does not evidence any 
16//      actual or intended publication of such source code.
17
18X_STORE:        //idnt    2,1 | Motorola 040 Floating Point Software Package
19
20        |section        8
21
22fpreg_mask:
23        .byte   0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
24
25        .include "fpsp.defs"
26
27        |xref   mem_write
28        |xref   get_fline
29        |xref   g_opcls
30        |xref   g_dfmtou
31        |xref   reg_dest
32
33        .global dest_ext
34        .global dest_dbl
35        .global dest_sgl
36
37        .global store
38store:
39        btstb   #E3,E_BYTE(%a6)
40        beqs    E1_sto
41E3_sto:
42        movel   CMDREG3B(%a6),%d0
43        bfextu  %d0{#6:#3},%d0          //isolate dest. reg from cmdreg3b
44sto_fp:
45        lea     fpreg_mask,%a1
46        moveb   (%a1,%d0.w),%d0         //convert reg# to dynamic register mask
47        tstb    LOCAL_SGN(%a0)
48        beqs    is_pos
49        bsetb   #sign_bit,LOCAL_EX(%a0)
50is_pos:
51        fmovemx (%a0),%d0               //move to correct register
52//
53//      if fp0-fp3 is being modified, we must put a copy
54//      in the USER_FPn variable on the stack because all exception
55//      handlers restore fp0-fp3 from there.
56//
57        cmpb    #0x80,%d0               
58        bnes    not_fp0
59        fmovemx %fp0-%fp0,USER_FP0(%a6)
60        rts
61not_fp0:
62        cmpb    #0x40,%d0
63        bnes    not_fp1
64        fmovemx %fp1-%fp1,USER_FP1(%a6)
65        rts
66not_fp1:
67        cmpb    #0x20,%d0
68        bnes    not_fp2
69        fmovemx %fp2-%fp2,USER_FP2(%a6)
70        rts
71not_fp2:
72        cmpb    #0x10,%d0
73        bnes    not_fp3
74        fmovemx %fp3-%fp3,USER_FP3(%a6)
75        rts
76not_fp3:
77        rts
78
79E1_sto:
80        bsrl    g_opcls         //returns opclass in d0
81        cmpib   #3,%d0
82        beq     opc011          //branch if opclass 3
83        movel   CMDREG1B(%a6),%d0
84        bfextu  %d0{#6:#3},%d0  //extract destination register
85        bras    sto_fp
86
87opc011:
88        bsrl    g_dfmtou        //returns dest format in d0
89//                              ;ext=00, sgl=01, dbl=10
90        movel   %a0,%a1         //save source addr in a1
91        movel   EXC_EA(%a6),%a0 //get the address
92        cmpil   #0,%d0          //if dest format is extended
93        beq     dest_ext        //then branch
94        cmpil   #1,%d0          //if dest format is single
95        beqs    dest_sgl        //then branch
96//
97//      fall through to dest_dbl
98//
99
100//
101//      dest_dbl --- write double precision value to user space
102//
103//Input
104//      a0 -> destination address
105//      a1 -> source in extended precision
106//Output
107//      a0 -> destroyed
108//      a1 -> destroyed
109//      d0 -> 0
110//
111//Changes extended precision to double precision.
112// Note: no attempt is made to round the extended value to double.
113//      dbl_sign = ext_sign
114//      dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
115//      get rid of ext integer bit
116//      dbl_mant = ext_mant{62:12}
117//
118//              ---------------   ---------------    ---------------
119//  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
120//              ---------------   ---------------    ---------------
121//               95         64    63 62       32      31     11   0
122//                                   |                       |
123//                                   |                       |
124//                                   |                       |
125//                                   v                       v
126//                            ---------------   ---------------
127//  double   ->               |s|exp| mant  |   |  mant       |
128//                            ---------------   ---------------
129//                            63     51   32   31              0
130//
131dest_dbl:
132        clrl    %d0             //clear d0
133        movew   LOCAL_EX(%a1),%d0       //get exponent
134        subw    #0x3fff,%d0     //subtract extended precision bias
135        cmpw    #0x4000,%d0     //check if inf
136        beqs    inf             //if so, special case
137        addw    #0x3ff,%d0      //add double precision bias
138        swap    %d0             //d0 now in upper word
139        lsll    #4,%d0          //d0 now in proper place for dbl prec exp
140        tstb    LOCAL_SGN(%a1) 
141        beqs    get_mant        //if positive, go process mantissa
142        bsetl   #31,%d0         //if negative, put in sign information
143//                              ; before continuing
144        bras    get_mant        //go process mantissa
145inf:
146        movel   #0x7ff00000,%d0 //load dbl inf exponent
147        clrl    LOCAL_HI(%a1)   //clear msb
148        tstb    LOCAL_SGN(%a1)
149        beqs    dbl_inf         //if positive, go ahead and write it
150        bsetl   #31,%d0         //if negative put in sign information
151dbl_inf:
152        movel   %d0,LOCAL_EX(%a1)       //put the new exp back on the stack
153        bras    dbl_wrt
154get_mant:
155        movel   LOCAL_HI(%a1),%d1       //get ms mantissa
156        bfextu  %d1{#1:#20},%d1 //get upper 20 bits of ms
157        orl     %d1,%d0         //put these bits in ms word of double
158        movel   %d0,LOCAL_EX(%a1)       //put the new exp back on the stack
159        movel   LOCAL_HI(%a1),%d1       //get ms mantissa
160        movel   #21,%d0         //load shift count
161        lsll    %d0,%d1         //put lower 11 bits in upper bits
162        movel   %d1,LOCAL_HI(%a1)       //build lower lword in memory
163        movel   LOCAL_LO(%a1),%d1       //get ls mantissa
164        bfextu  %d1{#0:#21},%d0 //get ls 21 bits of double
165        orl     %d0,LOCAL_HI(%a1)       //put them in double result
166dbl_wrt:
167        movel   #0x8,%d0                //byte count for double precision number
168        exg     %a0,%a1         //a0=supervisor source, a1=user dest
169        bsrl    mem_write       //move the number to the user's memory
170        rts
171//
172//      dest_sgl --- write single precision value to user space
173//
174//Input
175//      a0 -> destination address
176//      a1 -> source in extended precision
177//
178//Output
179//      a0 -> destroyed
180//      a1 -> destroyed
181//      d0 -> 0
182//
183//Changes extended precision to single precision.
184//      sgl_sign = ext_sign
185//      sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
186//      get rid of ext integer bit
187//      sgl_mant = ext_mant{62:12}
188//
189//              ---------------   ---------------    ---------------
190//  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
191//              ---------------   ---------------    ---------------
192//               95         64    63 62    40 32      31     12   0
193//                                   |     |
194//                                   |     |
195//                                   |     |
196//                                   v     v
197//                            ---------------
198//  single   ->               |s|exp| mant  |
199//                            ---------------
200//                            31     22     0
201//
202dest_sgl:
203        clrl    %d0
204        movew   LOCAL_EX(%a1),%d0       //get exponent
205        subw    #0x3fff,%d0     //subtract extended precision bias
206        cmpw    #0x4000,%d0     //check if inf
207        beqs    sinf            //if so, special case
208        addw    #0x7f,%d0               //add single precision bias
209        swap    %d0             //put exp in upper word of d0
210        lsll    #7,%d0          //shift it into single exp bits
211        tstb    LOCAL_SGN(%a1) 
212        beqs    get_sman        //if positive, continue
213        bsetl   #31,%d0         //if negative, put in sign first
214        bras    get_sman        //get mantissa
215sinf:
216        movel   #0x7f800000,%d0 //load single inf exp to d0
217        tstb    LOCAL_SGN(%a1)
218        beqs    sgl_wrt         //if positive, continue
219        bsetl   #31,%d0         //if negative, put in sign info
220        bras    sgl_wrt
221
222get_sman:
223        movel   LOCAL_HI(%a1),%d1       //get ms mantissa
224        bfextu  %d1{#1:#23},%d1 //get upper 23 bits of ms
225        orl     %d1,%d0         //put these bits in ms word of single
226
227sgl_wrt:
228        movel   %d0,L_SCR1(%a6) //put the new exp back on the stack
229        movel   #0x4,%d0                //byte count for single precision number
230        tstl    %a0             //users destination address
231        beqs    sgl_Dn          //destination is a data register
232        exg     %a0,%a1         //a0=supervisor source, a1=user dest
233        leal    L_SCR1(%a6),%a0 //point a0 to data
234        bsrl    mem_write       //move the number to the user's memory
235        rts
236sgl_Dn:
237        bsrl    get_fline       //returns fline word in d0
238        andw    #0x7,%d0                //isolate register number
239        movel   %d0,%d1         //d1 has size:reg formatted for reg_dest
240        orl     #0x10,%d1               //reg_dest wants size added to reg#
241        bral    reg_dest        //size is X, rts in reg_dest will
242//                              ;return to caller of dest_sgl
243       
244dest_ext:
245        tstb    LOCAL_SGN(%a1)  //put back sign into exponent word
246        beqs    dstx_cont
247        bsetb   #sign_bit,LOCAL_EX(%a1)
248dstx_cont:
249        clrb    LOCAL_SGN(%a1)  //clear out the sign byte
250
251        movel   #0x0c,%d0               //byte count for extended number
252        exg     %a0,%a1         //a0=supervisor source, a1=user dest
253        bsrl    mem_write       //move the number to the user's memory
254        rts
255
256        |end
Note: See TracBrowser for help on using the repository browser.