source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/x_store.S @ 5321250

4.104.114.84.95
Last change on this file since 5321250 was 54f440d, checked in by Joel Sherrill <joel.sherrill@…>, on 07/26/99 at 22:11:02

Patch from Charles-Antoine Gauthier <charles.gauthier@…>.
to address m68k-rtemself for the MVME167.

Here is the rtems patch I promissed you a long time ago to enable ELF
with m68k. The target name I selected is m68k-rtemself. It preserves the
m68k-rtems COFF target, and is parterned after the other ELF/COFF dual
targets.

The mvme167.cfg file causes the -qelf flag to be used during compilation
if the name of the compiler contains rtemself. This flag is used in the
bsp_specs file to select the elflinkcmds file rather than the linkcmds
file. The former is for ELF, the latter for COFF.

Some patches are required to the mc68040 FPSP code. Some of the
assembler files contain instructions that were rejected by the
m68k-rtemself-as assembler. This is a minor bug in the m68k ELF
assembler, I think.

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