4
| The entry point sSCALE computes the destination operand
5
| scaled by the source operand. If the absolute value of
6
| the source operand is (>= 2^14) an overflow or underflow
9
| The entry point sscale is called from do_func to emulate
10
| the fscale unimplemented instruction.
12
| Input: Double-extended destination operand in FPTEMP,
13
| double-extended source operand in ETEMP.
15
| Output: The function returns scale(X,Y) to fp0.
21
| Copyright (C) Motorola, Inc. 1990
24
| For details on the license for this file, please see the
25
| file, README, in this same directory.
27
|SCALE idnt 2,1 | Motorola 040 Floating Point Software Package
38
SRC_BNDS: .short 0x3fff,0x400c
41
| This entry point is used by the unimplemented instruction exception
50
fmovel #0,%fpcr |clr user enabled exc
52
movew FPTEMP(%a6),%d1 |get dest exponent
53
smi L_SCR1(%a6) |use L_SCR1 to hold sign
54
andil #0x7fff,%d1 |strip sign
55
movew ETEMP(%a6),%d0 |check src bounds
56
andiw #0x7fff,%d0 |clr sign bit
59
cmpiw #0x400c,%d0 |test for too large
62
| The source input is below 1, so we check for denormalized numbers
70
st STORE_FLG(%a6) |dest already contains result
71
orl #unfl_mask,USER_FPSR(%a6) |set UNFL
76
fmovel USER_FPCR(%a6),%FPCR
77
fmovex FPTEMP(%a6),%fp0 |simply return dest
82
| Source is within 2^14 range. To perform the int operation,
86
fmovex ETEMP(%a6),%fp0 |move in src for int
87
fmovel #rz_mode,%fpcr |force rz for src conversion
88
fmovel %fp0,%d0 |int src to d0
89
fmovel #0,%FPSR |clr status from above
90
tstw ETEMP(%a6) |check src sign
93
| Source is positive. Add the src to the dest exponent.
94
| The result can be denormalized, if src = 0, or overflow,
95
| if the result of the add sets a bit in the upper word.
98
tstw %d1 |check for denorm
100
addl %d0,%d1 |add src to dest exp
101
beqs denorm |if zero, result is denorm
102
cmpil #0x7fff,%d1 |test for overflow
108
movew %d1,FPTEMP(%a6) |result in FPTEMP
109
fmovel USER_FPCR(%a6),%FPCR
110
fmovex FPTEMP(%a6),%fp0 |write result to fp0
117
movew FPTEMP(%a6),ETEMP(%a6) |result in ETEMP
118
movel FPTEMP_HI(%a6),ETEMP_HI(%a6)
119
movel FPTEMP_LO(%a6),ETEMP_LO(%a6)
127
tstl FPTEMP_HI(%a6) |check j bit
128
blts nden_exit |if set, not denorm
129
movew %d1,ETEMP(%a6) |input expected in ETEMP
130
movel FPTEMP_HI(%a6),ETEMP_HI(%a6)
131
movel FPTEMP_LO(%a6),ETEMP_LO(%a6)
132
orl #unfl_bit,USER_FPSR(%a6) |set unfl
136
movew %d1,FPTEMP(%a6) |result in FPTEMP
137
fmovel USER_FPCR(%a6),%FPCR
138
fmovex FPTEMP(%a6),%fp0 |write result to fp0
142
| Source is negative. Add the src to the dest exponent.
143
| (The result exponent will be reduced). The result can be
147
addl %d0,%d1 |add src to dest
148
beqs denorm |if zero, result is denorm
149
blts fix_dnrm |if negative, result is
150
| ;needing denormalization
155
movew %d1,FPTEMP(%a6) |result in FPTEMP
156
fmovel USER_FPCR(%a6),%FPCR
157
fmovex FPTEMP(%a6),%fp0 |write result to fp0
162
| The result exponent is below denorm value. Test for catastrophic
163
| underflow and force zero if true. If not, try to shift the
164
| mantissa right until a zero exponent exists.
167
cmpiw #0xffc0,%d1 |lower bound for normalization
168
blt fix_unfl |if lower, catastrophic unfl
169
movew %d1,%d0 |use d0 for exp
170
movel %d2,-(%a7) |free d2 for norm
171
movel FPTEMP_HI(%a6),%d1
172
movel FPTEMP_LO(%a6),%d2
175
addw #1,%d0 |drive d0 to 0
176
lsrl #1,%d1 |while shifting the
177
roxrl #1,%d2 |mantissa to the right
179
st L_SCR2(%a6) |use L_SCR2 to capture inex
181
tstw %d0 |it is finished when
182
blts fix_loop |d0 is zero or the mantissa
185
orl #unfl_inx_mask,USER_FPSR(%a6)
186
| ;set unfl, aunfl, ainex
188
| Test for zero. If zero, simply use fmove to return +/- zero
193
tstb L_SCR1(%a6) |test for sign
195
orw #0x8000,FPTEMP_EX(%a6) |set sign bit
197
movel %d1,FPTEMP_HI(%a6)
198
movel %d2,FPTEMP_LO(%a6)
205
| Result is zero. Check for rounding mode to set lsb. If the
206
| mode is rp, and the zero is positive, return smallest denorm.
207
| If the mode is rm, and the zero is negative, return smallest
210
btstb #5,FPCR_MODE(%a6) |test if rm or rp
212
btstb #4,FPCR_MODE(%a6) |check which one
215
tstb L_SCR1(%a6) |check sign
216
bnes no_dir |if set, neg op, no inc
217
movel #1,FPTEMP_LO(%a6) |set lsb
220
tstb L_SCR1(%a6) |check sign
221
beqs no_dir |if clr, neg op, no inc
222
movel #1,FPTEMP_LO(%a6) |set lsb
223
orl #neg_mask,USER_FPSR(%a6) |set N
226
fmovel USER_FPCR(%a6),%FPCR
227
fmovex FPTEMP(%a6),%fp0 |use fmove to set cc's
231
| The rounding mode changed the zero to a smallest denorm. Call
232
| t_resdnrm with exceptional operand in ETEMP.
235
movel FPTEMP_EX(%a6),ETEMP_EX(%a6)
236
movel FPTEMP_HI(%a6),ETEMP_HI(%a6)
237
movel FPTEMP_LO(%a6),ETEMP_LO(%a6)
242
| Result is still denormalized.
245
orl #unfl_mask,USER_FPSR(%a6) |set unfl
246
tstb L_SCR1(%a6) |check for sign
248
orl #neg_mask,USER_FPSR(%a6) |set N
254
| The result has underflowed to zero. Return zero and set
255
| unfl, aunfl, and ainex.
258
orl #unfl_inx_mask,USER_FPSR(%a6)
259
btstb #5,FPCR_MODE(%a6) |test if rm or rp
261
btstb #4,FPCR_MODE(%a6) |check which one
264
tstb L_SCR1(%a6) |check sign
265
bnes no_dir2 |if set, neg op, no inc
268
movel #1,FPTEMP_LO(%a6) |set lsb
269
bras sm_dnrm |return smallest denorm
271
tstb L_SCR1(%a6) |check sign
272
beqs no_dir2 |if clr, neg op, no inc
273
movew #0x8000,FPTEMP_EX(%a6)
275
movel #1,FPTEMP_LO(%a6) |set lsb
276
orl #neg_mask,USER_FPSR(%a6) |set N
277
bra sm_dnrm |return smallest denorm
283
clrl FP_SCR1(%a6) |clear the exceptional operand
284
clrl FP_SCR1+4(%a6) |for gen_except.
286
fmoves #0x80000000,%fp0
289
clrl FP_SCR1(%a6) |clear the exceptional operand
290
clrl FP_SCR1+4(%a6) |for gen_except.
292
fmoves #0x00000000,%fp0
296
| The destination is a denormalized number. It must be handled
297
| by first shifting the bits in the mantissa until it is normalized,
298
| then adding the remainder of the source to the exponent.
301
moveml %d2/%d3,-(%a7)
302
movew FPTEMP_EX(%a6),%d1
303
movel FPTEMP_HI(%a6),%d2
304
movel FPTEMP_LO(%a6),%d3
306
tstl %d2 |test for normalized result
307
blts dst_norm |exit loop if so
308
tstl %d0 |otherwise, test shift count
309
beqs dst_fin |if zero, shifting is done
310
subil #1,%d0 |dec src
315
| Destination became normalized. Simply add the remaining
316
| portion of the src to the exponent.
319
addw %d0,%d1 |dst is normalized; add src
324
movemw %d1,FPTEMP_EX(%a6)
325
moveml %d2,FPTEMP_HI(%a6)
326
moveml %d3,FPTEMP_LO(%a6)
327
fmovel USER_FPCR(%a6),%FPCR
328
fmovex FPTEMP(%a6),%fp0
329
moveml (%a7)+,%d2/%d3
333
| Destination remained denormalized. Call t_excdnrm with
334
| exceptional operand in ETEMP.
337
tstb L_SCR1(%a6) |check for sign
339
orl #neg_mask,USER_FPSR(%a6) |set N
342
movemw %d1,ETEMP_EX(%a6)
343
moveml %d2,ETEMP_HI(%a6)
344
moveml %d3,ETEMP_LO(%a6)
345
orl #unfl_mask,USER_FPSR(%a6) |set unfl
346
moveml (%a7)+,%d2/%d3
351
| Source is outside of 2^14 range. Test the sign and branch
352
| to the appropriate exception handler.
359
movel FPTEMP_HI(%a6),ETEMP_HI(%a6)
360
movel FPTEMP_LO(%a6),ETEMP_LO(%a6)
364
movew %d1,ETEMP(%a6) |result in ETEMP
367
movew %d1,ETEMP(%a6) |result in ETEMP