make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / arch / m68k-all / m680x0 / fpsp / x_store.sa
blob56210da3d579afebaa5c89940eb4a507fc23d41c
1 *       $NetBSD: x_store.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $
3 *       MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 *       M68000 Hi-Performance Microprocessor Division
5 *       M68040 Software Package 
7 *       M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 *       All rights reserved.
10 *       THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11 *       To the maximum extent permitted by applicable law,
12 *       MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13 *       INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14 *       PARTICULAR PURPOSE and any warranty against infringement with
15 *       regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16 *       and any accompanying written materials. 
18 *       To the maximum extent permitted by applicable law,
19 *       IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20 *       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21 *       PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22 *       OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23 *       SOFTWARE.  Motorola assumes no responsibility for the maintenance
24 *       and support of the SOFTWARE.  
26 *       You are hereby granted a copyright license to use, modify, and
27 *       distribute the SOFTWARE so long as this entire notice is retained
28 *       without alteration in any modified and/or redistributed versions,
29 *       and that such modified versions are clearly identified as such.
30 *       No licenses are granted by implication, estoppel or otherwise
31 *       under any patents or trademarks of Motorola, Inc.
34 *       x_store.sa 3.2 1/24/91
36 *       store --- store operand to memory or register
38 *       Used by underflow and overflow handlers.
40 *       a6 = points to fp value to be stored.
43 X_STORE IDNT    2,1 Motorola 040 Floating Point Software Package
45         section 8
47 fpreg_mask:
48         dc.b    $80,$40,$20,$10,$08,$04,$02,$01
50         include fpsp.h
52         xref    mem_write
53         xref    get_fline
54         xref    g_opcls
55         xref    g_dfmtou
56         xref    reg_dest
58         xdef    dest_ext
59         xdef    dest_dbl
60         xdef    dest_sgl
62         xdef    store
63 store:
64         btst.b  #E3,E_BYTE(a6)
65         beq.b   E1_sto
66 E3_sto:
67         move.l  CMDREG3B(a6),d0
68         bfextu  d0{6:3},d0              ;isolate dest. reg from cmdreg3b
69 sto_fp:
70         lea     fpreg_mask,a1
71         move.b  (a1,d0.w),d0            ;convert reg# to dynamic register mask
72         tst.b   LOCAL_SGN(a0)
73         beq.b   is_pos
74         bset.b  #sign_bit,LOCAL_EX(a0)
75 is_pos:
76         fmovem.x (a0),d0                ;move to correct register
78 *       if fp0-fp3 is being modified, we must put a copy
79 *       in the USER_FPn variable on the stack because all exception
80 *       handlers restore fp0-fp3 from there.
82         cmp.b   #$80,d0         
83         bne.b   not_fp0
84         fmovem.x fp0,USER_FP0(a6)
85         rts
86 not_fp0:
87         cmp.b   #$40,d0
88         bne.b   not_fp1
89         fmovem.x fp1,USER_FP1(a6)
90         rts
91 not_fp1:
92         cmp.b   #$20,d0
93         bne.b   not_fp2
94         fmovem.x fp2,USER_FP2(a6)
95         rts
96 not_fp2:
97         cmp.b   #$10,d0
98         bne.b   not_fp3
99         fmovem.x fp3,USER_FP3(a6)
100         rts
101 not_fp3:
102         rts
104 E1_sto:
105         bsr.l   g_opcls         ;returns opclass in d0
106         cmpi.b  #3,d0
107         beq     opc011          ;branch if opclass 3
108         move.l  CMDREG1B(a6),d0
109         bfextu  d0{6:3},d0      ;extract destination register
110         bra.b   sto_fp
112 opc011:
113         bsr.l   g_dfmtou        ;returns dest format in d0
114 *                               ;ext=00, sgl=01, dbl=10
115         move.l  a0,a1           ;save source addr in a1
116         move.l  EXC_EA(a6),a0   ;get the address
117         tst.l   d0              ;if dest format is extended
118         beq.w   dest_ext        ;then branch
119         cmpi.l  #1,d0           ;if dest format is single
120         beq.b   short_dest_sgl  ;then branch
122 *       fall through to dest_dbl
126 *       dest_dbl --- write double precision value to user space
128 *Input
129 *       a0 -> destination address
130 *       a1 -> source in extended precision
131 *Output
132 *       a0 -> destroyed
133 *       a1 -> destroyed
134 *       d0 -> 0
136 *Changes extended precision to double precision.
137 * Note: no attempt is made to round the extended value to double.
138 *       dbl_sign = ext_sign
139 *       dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
140 *       get rid of ext integer bit
141 *       dbl_mant = ext_mant{62:12}
143 *               ---------------   ---------------    ---------------
144 *  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
145 *               ---------------   ---------------    ---------------
146 *                95         64    63 62       32      31     11   0
147 *                                    |                       |
148 *                                    |                       |
149 *                                    |                       |
150 *                                    v                       v
151 *                             ---------------   ---------------
152 *  double   ->                |s|exp| mant  |   |  mant       |
153 *                             ---------------   ---------------
154 *                             63     51   32   31              0
156 dest_dbl:
157         clr.l   d0              ;clear d0
158         move.w  LOCAL_EX(a1),d0 ;get exponent
159         sub.w   #$3fff,d0       ;subtract extended precision bias
160         cmp.w   #$4000,d0       ;check if inf
161         beq.b   inf             ;if so, special case
162         add.w   #$3ff,d0        ;add double precision bias
163         swap    d0              ;d0 now in upper word
164         lsl.l   #4,d0           ;d0 now in proper place for dbl prec exp
165         tst.b   LOCAL_SGN(a1)   
166         beq.b   get_mant        ;if postive, go process mantissa
167         bset.l  #31,d0          ;if negative, put in sign information
168 *                               ; before continuing
169         bra.b   get_mant        ;go process mantissa
170 inf:
171         move.l  #$7ff00000,d0   ;load dbl inf exponent
172         clr.l   LOCAL_HI(a1)    ;clear msb
173         tst.b   LOCAL_SGN(a1)
174         beq.b   dbl_inf         ;if positive, go ahead and write it
175         bset.l  #31,d0          ;if negative put in sign information
176 dbl_inf:
177         move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
178         bra.b   dbl_wrt
179 get_mant:
180         move.l  LOCAL_HI(a1),d1 ;get ms mantissa
181         bfextu  d1{1:20},d1     ;get upper 20 bits of ms
182         or.l    d1,d0           ;put these bits in ms word of double
183         move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
184         move.l  LOCAL_HI(a1),d1 ;get ms mantissa
185         move.l  #21,d0          ;load shift count
186         lsl.l   d0,d1           ;put lower 11 bits in upper bits
187         move.l  d1,LOCAL_HI(a1) ;build lower lword in memory
188         move.l  LOCAL_LO(a1),d1 ;get ls mantissa
189         bfextu  d1{0:21},d0     ;get ls 21 bits of double
190         or.l    d0,LOCAL_HI(a1) ;put them in double result
191 dbl_wrt:
192         move.l  #$8,d0          ;byte count for double precision number
193         exg     a0,a1           ;a0=supervisor source, a1=user dest
194         bsr.l   mem_write       ;move the number to the user's memory
195         rts
197 *       dest_sgl --- write single precision value to user space
199 *Input
200 *       a0 -> destination address
201 *       a1 -> source in extended precision
203 *Output
204 *       a0 -> destroyed
205 *       a1 -> destroyed
206 *       d0 -> 0
208 *Changes extended precision to single precision.
209 *       sgl_sign = ext_sign
210 *       sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
211 *       get rid of ext integer bit
212 *       sgl_mant = ext_mant{62:12}
214 *               ---------------   ---------------    ---------------
215 *  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
216 *               ---------------   ---------------    ---------------
217 *                95         64    63 62    40 32      31     12   0
218 *                                    |     |
219 *                                    |     |
220 *                                    |     |
221 *                                    v     v
222 *                             ---------------
223 *  single   ->                |s|exp| mant  |
224 *                             ---------------
225 *                             31     22     0
227 dest_sgl:
228 short_dest_sgl:
229         clr.l   d0
230         move.w  LOCAL_EX(a1),d0 ;get exponent
231         sub.w   #$3fff,d0       ;subtract extended precision bias
232         cmp.w   #$4000,d0       ;check if inf
233         beq.b   sinf            ;if so, special case
234         add.w   #$7f,d0         ;add single precision bias
235         swap    d0              ;put exp in upper word of d0
236         lsl.l   #7,d0           ;shift it into single exp bits
237         tst.b   LOCAL_SGN(a1)   
238         beq.b   get_sman        ;if positive, continue
239         bset.l  #31,d0          ;if negative, put in sign first
240         bra.b   get_sman        ;get mantissa
241 sinf:
242         move.l  #$7f800000,d0   ;load single inf exp to d0
243         tst.b   LOCAL_SGN(a1)
244         beq.b   sgl_wrt         ;if positive, continue
245         bset.l  #31,d0          ;if negative, put in sign info
246         bra.b   sgl_wrt
248 get_sman:
249         move.l  LOCAL_HI(a1),d1 ;get ms mantissa
250         bfextu  d1{1:23},d1     ;get upper 23 bits of ms
251         or.l    d1,d0           ;put these bits in ms word of single
253 sgl_wrt:
254         move.l  d0,L_SCR1(a6)   ;put the new exp back on the stack
255         move.l  #$4,d0          ;byte count for single precision number
256         tst.l   a0              ;users destination address
257         beq.b   sgl_Dn          ;destination is a data register
258         exg     a0,a1           ;a0=supervisor source, a1=user dest
259         lea.l   L_SCR1(a6),a0   ;point a0 to data
260         bsr.l   mem_write       ;move the number to the user's memory
261         rts
262 sgl_Dn:
263         bsr.l   get_fline       ;returns fline word in d0
264         and.w   #$7,d0          ;isolate register number
265         move.l  d0,d1           ;d1 has size:reg formatted for reg_dest
266         or.l    #$10,d1         ;reg_dest wants size added to reg#
267         bra.l   reg_dest        ;size is X, rts in reg_dest will
268 *                               ;return to caller of dest_sgl
269         
270 dest_ext:
271         tst.b   LOCAL_SGN(a1)   ;put back sign into exponent word
272         beq.b   dstx_cont
273         bset.b  #sign_bit,LOCAL_EX(a1)
274 dstx_cont:
275         clr.b   LOCAL_SGN(a1)   ;clear out the sign byte
277         move.l  #$0c,d0         ;byte count for extended number
278         exg     a0,a1           ;a0=supervisor source, a1=user dest
279         bsr.l   mem_write       ;move the number to the user's memory
280         rts
282         end