scale.sa revision 1.3 1 1.3 cgd * $NetBSD: scale.sa,v 1.3 1994/10/26 07:49:34 cgd Exp $
2 1.3 cgd
3 1.1 mycroft * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 1.1 mycroft * M68000 Hi-Performance Microprocessor Division
5 1.1 mycroft * M68040 Software Package
6 1.1 mycroft *
7 1.1 mycroft * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 1.1 mycroft * All rights reserved.
9 1.1 mycroft *
10 1.1 mycroft * THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11 1.1 mycroft * To the maximum extent permitted by applicable law,
12 1.1 mycroft * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13 1.1 mycroft * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14 1.1 mycroft * PARTICULAR PURPOSE and any warranty against infringement with
15 1.1 mycroft * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16 1.1 mycroft * and any accompanying written materials.
17 1.1 mycroft *
18 1.1 mycroft * To the maximum extent permitted by applicable law,
19 1.1 mycroft * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20 1.1 mycroft * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21 1.1 mycroft * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22 1.1 mycroft * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23 1.1 mycroft * SOFTWARE. Motorola assumes no responsibility for the maintenance
24 1.1 mycroft * and support of the SOFTWARE.
25 1.1 mycroft *
26 1.1 mycroft * You are hereby granted a copyright license to use, modify, and
27 1.1 mycroft * distribute the SOFTWARE so long as this entire notice is retained
28 1.1 mycroft * without alteration in any modified and/or redistributed versions,
29 1.1 mycroft * and that such modified versions are clearly identified as such.
30 1.1 mycroft * No licenses are granted by implication, estoppel or otherwise
31 1.1 mycroft * under any patents or trademarks of Motorola, Inc.
32 1.1 mycroft
33 1.1 mycroft *
34 1.1 mycroft * scale.sa 3.3 7/30/91
35 1.1 mycroft *
36 1.1 mycroft * The entry point sSCALE computes the destination operand
37 1.1 mycroft * scaled by the source operand. If the absoulute value of
38 1.1 mycroft * the source operand is (>= 2^14) an overflow or underflow
39 1.1 mycroft * is returned.
40 1.1 mycroft *
41 1.1 mycroft * The entry point sscale is called from do_func to emulate
42 1.1 mycroft * the fscale unimplemented instruction.
43 1.1 mycroft *
44 1.1 mycroft * Input: Double-extended destination operand in FPTEMP,
45 1.1 mycroft * double-extended source operand in ETEMP.
46 1.1 mycroft *
47 1.1 mycroft * Output: The function returns scale(X,Y) to fp0.
48 1.1 mycroft *
49 1.1 mycroft * Modifies: fp0.
50 1.1 mycroft *
51 1.1 mycroft * Algorithm:
52 1.1 mycroft *
53 1.1 mycroft
54 1.1 mycroft SCALE IDNT 2,1 Motorola 040 Floating Point Software Package
55 1.1 mycroft
56 1.1 mycroft section 8
57 1.1 mycroft
58 1.1 mycroft include fpsp.h
59 1.1 mycroft
60 1.1 mycroft xref t_ovfl2
61 1.1 mycroft xref t_unfl
62 1.1 mycroft xref round
63 1.1 mycroft xref t_resdnrm
64 1.1 mycroft
65 1.1 mycroft SRC_BNDS dc.w $3fff,$400c
66 1.1 mycroft
67 1.1 mycroft *
68 1.1 mycroft * This entry point is used by the unimplemented instruction exception
69 1.1 mycroft * handler.
70 1.1 mycroft *
71 1.1 mycroft *
72 1.1 mycroft *
73 1.1 mycroft * FSCALE
74 1.1 mycroft *
75 1.1 mycroft xdef sscale
76 1.1 mycroft sscale:
77 1.1 mycroft fmove.l #0,fpcr ;clr user enabled exc
78 1.1 mycroft clr.l d1
79 1.1 mycroft move.w FPTEMP(a6),d1 ;get dest exponent
80 1.1 mycroft smi L_SCR1(a6) ;use L_SCR1 to hold sign
81 1.1 mycroft andi.l #$7fff,d1 ;strip sign
82 1.1 mycroft move.w ETEMP(a6),d0 ;check src bounds
83 1.1 mycroft andi.w #$7fff,d0 ;clr sign bit
84 1.1 mycroft cmp2.w SRC_BNDS,d0
85 1.1 mycroft bcc.b src_in
86 1.1 mycroft cmpi.w #$400c,d0 ;test for too large
87 1.1 mycroft bge.w src_out
88 1.1 mycroft *
89 1.1 mycroft * The source input is below 1, so we check for denormalized numbers
90 1.1 mycroft * and set unfl.
91 1.1 mycroft *
92 1.1 mycroft src_small:
93 1.1 mycroft move.b DTAG(a6),d0
94 1.1 mycroft andi.b #$e0,d0
95 1.1 mycroft tst.b d0
96 1.1 mycroft beq.b no_denorm
97 1.1 mycroft st STORE_FLG(a6) ;dest already contains result
98 1.1 mycroft or.l #unfl_mask,USER_FPSR(a6) ;set UNFL
99 1.1 mycroft den_done:
100 1.1 mycroft lea.l FPTEMP(a6),a0
101 1.1 mycroft bra t_resdnrm
102 1.1 mycroft no_denorm:
103 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
104 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;simply return dest
105 1.1 mycroft rts
106 1.1 mycroft
107 1.1 mycroft
108 1.1 mycroft *
109 1.1 mycroft * Source is within 2^14 range. To perform the int operation,
110 1.1 mycroft * move it to d0.
111 1.1 mycroft *
112 1.1 mycroft src_in:
113 1.1 mycroft fmove.x ETEMP(a6),fp0 ;move in src for int
114 1.1 mycroft fmove.l #rz_mode,fpcr ;force rz for src conversion
115 1.1 mycroft fmove.l fp0,d0 ;int src to d0
116 1.1 mycroft fmove.l #0,FPSR ;clr status from above
117 1.1 mycroft tst.w ETEMP(a6) ;check src sign
118 1.1 mycroft blt.w src_neg
119 1.1 mycroft *
120 1.1 mycroft * Source is positive. Add the src to the dest exponent.
121 1.1 mycroft * The result can be denormalized, if src = 0, or overflow,
122 1.1 mycroft * if the result of the add sets a bit in the upper word.
123 1.1 mycroft *
124 1.1 mycroft src_pos:
125 1.1 mycroft tst.w d1 ;check for denorm
126 1.1 mycroft beq.w dst_dnrm
127 1.1 mycroft add.l d0,d1 ;add src to dest exp
128 1.1 mycroft beq.b denorm ;if zero, result is denorm
129 1.1 mycroft cmpi.l #$7fff,d1 ;test for overflow
130 1.1 mycroft bge.b ovfl
131 1.1 mycroft tst.b L_SCR1(a6)
132 1.1 mycroft beq.b spos_pos
133 1.1 mycroft or.w #$8000,d1
134 1.1 mycroft spos_pos:
135 1.1 mycroft move.w d1,FPTEMP(a6) ;result in FPTEMP
136 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
137 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;write result to fp0
138 1.1 mycroft rts
139 1.1 mycroft ovfl:
140 1.1 mycroft tst.b L_SCR1(a6)
141 1.1 mycroft beq.b sovl_pos
142 1.1 mycroft or.w #$8000,d1
143 1.1 mycroft sovl_pos:
144 1.1 mycroft move.w FPTEMP(a6),ETEMP(a6) ;result in ETEMP
145 1.1 mycroft move.l FPTEMP_HI(a6),ETEMP_HI(a6)
146 1.1 mycroft move.l FPTEMP_LO(a6),ETEMP_LO(a6)
147 1.1 mycroft bra t_ovfl2
148 1.1 mycroft
149 1.1 mycroft denorm:
150 1.1 mycroft tst.b L_SCR1(a6)
151 1.1 mycroft beq.b den_pos
152 1.1 mycroft or.w #$8000,d1
153 1.1 mycroft den_pos:
154 1.1 mycroft tst.l FPTEMP_HI(a6) ;check j bit
155 1.1 mycroft blt.b nden_exit ;if set, not denorm
156 1.1 mycroft move.w d1,ETEMP(a6) ;input expected in ETEMP
157 1.1 mycroft move.l FPTEMP_HI(a6),ETEMP_HI(a6)
158 1.1 mycroft move.l FPTEMP_LO(a6),ETEMP_LO(a6)
159 1.1 mycroft or.l #unfl_bit,USER_FPSR(a6) ;set unfl
160 1.1 mycroft lea.l ETEMP(a6),a0
161 1.1 mycroft bra t_resdnrm
162 1.1 mycroft nden_exit:
163 1.1 mycroft move.w d1,FPTEMP(a6) ;result in FPTEMP
164 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
165 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;write result to fp0
166 1.1 mycroft rts
167 1.1 mycroft
168 1.1 mycroft *
169 1.1 mycroft * Source is negative. Add the src to the dest exponent.
170 1.1 mycroft * (The result exponent will be reduced). The result can be
171 1.1 mycroft * denormalized.
172 1.1 mycroft *
173 1.1 mycroft src_neg:
174 1.1 mycroft add.l d0,d1 ;add src to dest
175 1.1 mycroft beq.b denorm ;if zero, result is denorm
176 1.1 mycroft blt.b fix_dnrm ;if negative, result is
177 1.1 mycroft * ;needing denormalization
178 1.1 mycroft tst.b L_SCR1(a6)
179 1.1 mycroft beq.b sneg_pos
180 1.1 mycroft or.w #$8000,d1
181 1.1 mycroft sneg_pos:
182 1.1 mycroft move.w d1,FPTEMP(a6) ;result in FPTEMP
183 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
184 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;write result to fp0
185 1.1 mycroft rts
186 1.1 mycroft
187 1.1 mycroft
188 1.1 mycroft *
189 1.1 mycroft * The result exponent is below denorm value. Test for catastrophic
190 1.1 mycroft * underflow and force zero if true. If not, try to shift the
191 1.1 mycroft * mantissa right until a zero exponent exists.
192 1.1 mycroft *
193 1.1 mycroft fix_dnrm:
194 1.1 mycroft cmpi.w #$ffc0,d1 ;lower bound for normalization
195 1.1 mycroft blt.w fix_unfl ;if lower, catastrophic unfl
196 1.1 mycroft move.w d1,d0 ;use d0 for exp
197 1.1 mycroft move.l d2,-(a7) ;free d2 for norm
198 1.1 mycroft move.l FPTEMP_HI(a6),d1
199 1.1 mycroft move.l FPTEMP_LO(a6),d2
200 1.1 mycroft clr.l L_SCR2(a6)
201 1.1 mycroft fix_loop:
202 1.1 mycroft add.w #1,d0 ;drive d0 to 0
203 1.1 mycroft lsr.l #1,d1 ;while shifting the
204 1.1 mycroft roxr.l #1,d2 ;mantissa to the right
205 1.1 mycroft bcc.b no_carry
206 1.1 mycroft st L_SCR2(a6) ;use L_SCR2 to capture inex
207 1.1 mycroft no_carry:
208 1.1 mycroft tst.w d0 ;it is finished when
209 1.1 mycroft blt.b fix_loop ;d0 is zero or the mantissa
210 1.1 mycroft tst.b L_SCR2(a6)
211 1.1 mycroft beq.b tst_zero
212 1.1 mycroft or.l #unfl_inx_mask,USER_FPSR(a6)
213 1.1 mycroft * ;set unfl, aunfl, ainex
214 1.1 mycroft *
215 1.1 mycroft * Test for zero. If zero, simply use fmove to return +/- zero
216 1.1 mycroft * to the fpu.
217 1.1 mycroft *
218 1.1 mycroft tst_zero:
219 1.1 mycroft clr.w FPTEMP_EX(a6)
220 1.1 mycroft tst.b L_SCR1(a6) ;test for sign
221 1.1 mycroft beq.b tst_con
222 1.1 mycroft or.w #$8000,FPTEMP_EX(a6) ;set sign bit
223 1.1 mycroft tst_con:
224 1.1 mycroft move.l d1,FPTEMP_HI(a6)
225 1.1 mycroft move.l d2,FPTEMP_LO(a6)
226 1.1 mycroft move.l (a7)+,d2
227 1.1 mycroft tst.l d1
228 1.1 mycroft bne.b not_zero
229 1.1 mycroft tst.l FPTEMP_LO(a6)
230 1.1 mycroft bne.b not_zero
231 1.1 mycroft *
232 1.1 mycroft * Result is zero. Check for rounding mode to set lsb. If the
233 1.1 mycroft * mode is rp, and the zero is positive, return smallest denorm.
234 1.1 mycroft * If the mode is rm, and the zero is negative, return smallest
235 1.1 mycroft * negative denorm.
236 1.1 mycroft *
237 1.1 mycroft btst.b #5,FPCR_MODE(a6) ;test if rm or rp
238 1.1 mycroft beq.b no_dir
239 1.1 mycroft btst.b #4,FPCR_MODE(a6) ;check which one
240 1.1 mycroft beq.b zer_rm
241 1.1 mycroft zer_rp:
242 1.1 mycroft tst.b L_SCR1(a6) ;check sign
243 1.1 mycroft bne.b no_dir ;if set, neg op, no inc
244 1.1 mycroft move.l #1,FPTEMP_LO(a6) ;set lsb
245 1.1 mycroft bra.b sm_dnrm
246 1.1 mycroft zer_rm:
247 1.1 mycroft tst.b L_SCR1(a6) ;check sign
248 1.1 mycroft beq.b no_dir ;if clr, neg op, no inc
249 1.1 mycroft move.l #1,FPTEMP_LO(a6) ;set lsb
250 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N
251 1.1 mycroft bra.b sm_dnrm
252 1.1 mycroft no_dir:
253 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
254 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;use fmove to set cc's
255 1.1 mycroft rts
256 1.1 mycroft
257 1.1 mycroft *
258 1.1 mycroft * The rounding mode changed the zero to a smallest denorm. Call
259 1.1 mycroft * t_resdnrm with exceptional operand in ETEMP.
260 1.1 mycroft *
261 1.1 mycroft sm_dnrm:
262 1.1 mycroft move.l FPTEMP_EX(a6),ETEMP_EX(a6)
263 1.1 mycroft move.l FPTEMP_HI(a6),ETEMP_HI(a6)
264 1.1 mycroft move.l FPTEMP_LO(a6),ETEMP_LO(a6)
265 1.1 mycroft lea.l ETEMP(a6),a0
266 1.1 mycroft bra t_resdnrm
267 1.1 mycroft
268 1.1 mycroft *
269 1.1 mycroft * Result is still denormalized.
270 1.1 mycroft *
271 1.1 mycroft not_zero:
272 1.1 mycroft or.l #unfl_mask,USER_FPSR(a6) ;set unfl
273 1.1 mycroft tst.b L_SCR1(a6) ;check for sign
274 1.1 mycroft beq.b fix_exit
275 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N
276 1.1 mycroft fix_exit:
277 1.1 mycroft bra.b sm_dnrm
278 1.1 mycroft
279 1.1 mycroft
280 1.1 mycroft *
281 1.1 mycroft * The result has underflowed to zero. Return zero and set
282 1.1 mycroft * unfl, aunfl, and ainex.
283 1.1 mycroft *
284 1.1 mycroft fix_unfl:
285 1.1 mycroft or.l #unfl_inx_mask,USER_FPSR(a6)
286 1.1 mycroft btst.b #5,FPCR_MODE(a6) ;test if rm or rp
287 1.1 mycroft beq.b no_dir2
288 1.1 mycroft btst.b #4,FPCR_MODE(a6) ;check which one
289 1.1 mycroft beq.b zer_rm2
290 1.1 mycroft zer_rp2:
291 1.1 mycroft tst.b L_SCR1(a6) ;check sign
292 1.1 mycroft bne.b no_dir2 ;if set, neg op, no inc
293 1.1 mycroft clr.l FPTEMP_EX(a6)
294 1.1 mycroft clr.l FPTEMP_HI(a6)
295 1.1 mycroft move.l #1,FPTEMP_LO(a6) ;set lsb
296 1.1 mycroft bra.b sm_dnrm ;return smallest denorm
297 1.1 mycroft zer_rm2:
298 1.1 mycroft tst.b L_SCR1(a6) ;check sign
299 1.1 mycroft beq.b no_dir2 ;if clr, neg op, no inc
300 1.1 mycroft move.w #$8000,FPTEMP_EX(a6)
301 1.1 mycroft clr.l FPTEMP_HI(a6)
302 1.1 mycroft move.l #1,FPTEMP_LO(a6) ;set lsb
303 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N
304 1.1 mycroft bra.w sm_dnrm ;return smallest denorm
305 1.1 mycroft
306 1.1 mycroft no_dir2:
307 1.1 mycroft tst.b L_SCR1(a6)
308 1.1 mycroft bge.b pos_zero
309 1.1 mycroft neg_zero:
310 1.1 mycroft clr.l FP_SCR1(a6) ;clear the exceptional operand
311 1.1 mycroft clr.l FP_SCR1+4(a6) ;for gen_except.
312 1.1 mycroft clr.l FP_SCR1+8(a6)
313 1.1 mycroft fmove.s #:80000000,fp0
314 1.1 mycroft rts
315 1.1 mycroft pos_zero:
316 1.1 mycroft clr.l FP_SCR1(a6) ;clear the exceptional operand
317 1.1 mycroft clr.l FP_SCR1+4(a6) ;for gen_except.
318 1.1 mycroft clr.l FP_SCR1+8(a6)
319 1.1 mycroft fmove.s #:00000000,fp0
320 1.1 mycroft rts
321 1.1 mycroft
322 1.1 mycroft *
323 1.1 mycroft * The destination is a denormalized number. It must be handled
324 1.1 mycroft * by first shifting the bits in the mantissa until it is normalized,
325 1.1 mycroft * then adding the remainder of the source to the exponent.
326 1.1 mycroft *
327 1.1 mycroft dst_dnrm:
328 1.1 mycroft movem.l d2/d3,-(a7)
329 1.1 mycroft move.w FPTEMP_EX(a6),d1
330 1.1 mycroft move.l FPTEMP_HI(a6),d2
331 1.1 mycroft move.l FPTEMP_LO(a6),d3
332 1.1 mycroft dst_loop:
333 1.1 mycroft tst.l d2 ;test for normalized result
334 1.1 mycroft blt.b dst_norm ;exit loop if so
335 1.1 mycroft tst.l d0 ;otherwise, test shift count
336 1.1 mycroft beq.b dst_fin ;if zero, shifting is done
337 1.2 mycroft subq.l #1,d0 ;dec src
338 1.2 mycroft add.l d3,d3
339 1.2 mycroft addx.l d2,d2
340 1.1 mycroft bra.b dst_loop
341 1.1 mycroft *
342 1.1 mycroft * Destination became normalized. Simply add the remaining
343 1.1 mycroft * portion of the src to the exponent.
344 1.1 mycroft *
345 1.1 mycroft dst_norm:
346 1.1 mycroft add.w d0,d1 ;dst is normalized; add src
347 1.1 mycroft tst.b L_SCR1(a6)
348 1.1 mycroft beq.b dnrm_pos
349 1.2 mycroft or.w #$8000,d1
350 1.1 mycroft dnrm_pos:
351 1.1 mycroft movem.w d1,FPTEMP_EX(a6)
352 1.1 mycroft movem.l d2,FPTEMP_HI(a6)
353 1.1 mycroft movem.l d3,FPTEMP_LO(a6)
354 1.1 mycroft fmove.l USER_FPCR(a6),FPCR
355 1.1 mycroft fmove.x FPTEMP(a6),fp0
356 1.1 mycroft movem.l (a7)+,d2/d3
357 1.1 mycroft rts
358 1.1 mycroft
359 1.1 mycroft *
360 1.1 mycroft * Destination remained denormalized. Call t_excdnrm with
361 1.1 mycroft * exceptional operand in ETEMP.
362 1.1 mycroft *
363 1.1 mycroft dst_fin:
364 1.1 mycroft tst.b L_SCR1(a6) ;check for sign
365 1.1 mycroft beq.b dst_exit
366 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N
367 1.2 mycroft or.w #$8000,d1
368 1.1 mycroft dst_exit:
369 1.1 mycroft movem.w d1,ETEMP_EX(a6)
370 1.1 mycroft movem.l d2,ETEMP_HI(a6)
371 1.1 mycroft movem.l d3,ETEMP_LO(a6)
372 1.1 mycroft or.l #unfl_mask,USER_FPSR(a6) ;set unfl
373 1.1 mycroft movem.l (a7)+,d2/d3
374 1.1 mycroft lea.l ETEMP(a6),a0
375 1.1 mycroft bra t_resdnrm
376 1.1 mycroft
377 1.1 mycroft *
378 1.1 mycroft * Source is outside of 2^14 range. Test the sign and branch
379 1.1 mycroft * to the appropriate exception handler.
380 1.1 mycroft *
381 1.1 mycroft src_out:
382 1.1 mycroft tst.b L_SCR1(a6)
383 1.1 mycroft beq.b scro_pos
384 1.2 mycroft or.w #$8000,d1
385 1.1 mycroft scro_pos:
386 1.1 mycroft move.l FPTEMP_HI(a6),ETEMP_HI(a6)
387 1.1 mycroft move.l FPTEMP_LO(a6),ETEMP_LO(a6)
388 1.1 mycroft tst.w ETEMP(a6)
389 1.1 mycroft blt.b res_neg
390 1.1 mycroft res_pos:
391 1.1 mycroft move.w d1,ETEMP(a6) ;result in ETEMP
392 1.1 mycroft bra t_ovfl2
393 1.1 mycroft res_neg:
394 1.1 mycroft move.w d1,ETEMP(a6) ;result in ETEMP
395 1.1 mycroft lea.l ETEMP(a6),a0
396 1.1 mycroft bra t_unfl
397 1.1 mycroft end
398