Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m68k/fpsp040/get_op.S
10817 views
1
|
2
| get_op.sa 3.6 5/19/92
3
|
4
| get_op.sa 3.5 4/26/91
5
|
6
| Description: This routine is called by the unsupported format/data
7
| type exception handler ('unsupp' - vector 55) and the unimplemented
8
| instruction exception handler ('unimp' - vector 11). 'get_op'
9
| determines the opclass (0, 2, or 3) and branches to the
10
| opclass handler routine. See 68881/2 User's Manual table 4-11
11
| for a description of the opclasses.
12
|
13
| For UNSUPPORTED data/format (exception vector 55) and for
14
| UNIMPLEMENTED instructions (exception vector 11) the following
15
| applies:
16
|
17
| - For unnormalized numbers (opclass 0, 2, or 3) the
18
| number(s) is normalized and the operand type tag is updated.
19
|
20
| - For a packed number (opclass 2) the number is unpacked and the
21
| operand type tag is updated.
22
|
23
| - For denormalized numbers (opclass 0 or 2) the number(s) is not
24
| changed but passed to the next module. The next module for
25
| unimp is do_func, the next module for unsupp is res_func.
26
|
27
| For UNSUPPORTED data/format (exception vector 55) only the
28
| following applies:
29
|
30
| - If there is a move out with a packed number (opclass 3) the
31
| number is packed and written to user memory. For the other
32
| opclasses the number(s) are written back to the fsave stack
33
| and the instruction is then restored back into the '040. The
34
| '040 is then able to complete the instruction.
35
|
36
| For example:
37
| fadd.x fpm,fpn where the fpm contains an unnormalized number.
38
| The '040 takes an unsupported data trap and gets to this
39
| routine. The number is normalized, put back on the stack and
40
| then an frestore is done to restore the instruction back into
41
| the '040. The '040 then re-executes the fadd.x fpm,fpn with
42
| a normalized number in the source and the instruction is
43
| successful.
44
|
45
| Next consider if in the process of normalizing the un-
46
| normalized number it becomes a denormalized number. The
47
| routine which converts the unnorm to a norm (called mk_norm)
48
| detects this and tags the number as a denorm. The routine
49
| res_func sees the denorm tag and converts the denorm to a
50
| norm. The instruction is then restored back into the '040
51
| which re_executes the instruction.
52
|
53
|
54
| Copyright (C) Motorola, Inc. 1990
55
| All Rights Reserved
56
|
57
| For details on the license for this file, please see the
58
| file, README, in this same directory.
59
60
GET_OP: |idnt 2,1 | Motorola 040 Floating Point Software Package
61
62
|section 8
63
64
#include "fpsp.h"
65
66
.global PIRN,PIRZRM,PIRP
67
.global SMALRN,SMALRZRM,SMALRP
68
.global BIGRN,BIGRZRM,BIGRP
69
70
PIRN:
71
.long 0x40000000,0xc90fdaa2,0x2168c235 |pi
72
PIRZRM:
73
.long 0x40000000,0xc90fdaa2,0x2168c234 |pi
74
PIRP:
75
.long 0x40000000,0xc90fdaa2,0x2168c235 |pi
76
77
|round to nearest
78
SMALRN:
79
.long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2)
80
.long 0x40000000,0xadf85458,0xa2bb4a9a |e
81
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e)
82
.long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
83
.long 0x00000000,0x00000000,0x00000000 |0.0
84
| round to zero;round to negative infinity
85
SMALRZRM:
86
.long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2)
87
.long 0x40000000,0xadf85458,0xa2bb4a9a |e
88
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bb |log2(e)
89
.long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
90
.long 0x00000000,0x00000000,0x00000000 |0.0
91
| round to positive infinity
92
SMALRP:
93
.long 0x3ffd0000,0x9a209a84,0xfbcff799 |log10(2)
94
.long 0x40000000,0xadf85458,0xa2bb4a9b |e
95
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e)
96
.long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e)
97
.long 0x00000000,0x00000000,0x00000000 |0.0
98
99
|round to nearest
100
BIGRN:
101
.long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2)
102
.long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10)
103
.long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
104
105
.global PTENRN
106
PTENRN:
107
.long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
108
.long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
109
.long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
110
.long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
111
.long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
112
.long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32
113
.long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64
114
.long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128
115
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256
116
.long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512
117
.long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024
118
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048
119
.long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096
120
|round to minus infinity
121
BIGRZRM:
122
.long 0x3ffe0000,0xb17217f7,0xd1cf79ab |ln(2)
123
.long 0x40000000,0x935d8ddd,0xaaa8ac16 |ln(10)
124
.long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
125
126
.global PTENRM
127
PTENRM:
128
.long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
129
.long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
130
.long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
131
.long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
132
.long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
133
.long 0x40690000,0x9DC5ADA8,0x2B70B59D |10 ^ 32
134
.long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64
135
.long 0x41A80000,0x93BA47C9,0x80E98CDF |10 ^ 128
136
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8D |10 ^ 256
137
.long 0x46A30000,0xE319A0AE,0xA60E91C6 |10 ^ 512
138
.long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024
139
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048
140
.long 0x75250000,0xC4605202,0x8A20979A |10 ^ 4096
141
|round to positive infinity
142
BIGRP:
143
.long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2)
144
.long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10)
145
.long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0
146
147
.global PTENRP
148
PTENRP:
149
.long 0x40020000,0xA0000000,0x00000000 |10 ^ 1
150
.long 0x40050000,0xC8000000,0x00000000 |10 ^ 2
151
.long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4
152
.long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8
153
.long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16
154
.long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32
155
.long 0x40D30000,0xC2781F49,0xFFCFA6D6 |10 ^ 64
156
.long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128
157
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256
158
.long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512
159
.long 0x4D480000,0xC9767586,0x81750C18 |10 ^ 1024
160
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 |10 ^ 2048
161
.long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096
162
163
|xref nrm_zero
164
|xref decbin
165
|xref round
166
167
.global get_op
168
.global uns_getop
169
.global uni_getop
170
get_op:
171
clrb DY_MO_FLG(%a6)
172
tstb UFLG_TMP(%a6) |test flag for unsupp/unimp state
173
beq uni_getop
174
175
uns_getop:
176
btstb #direction_bit,CMDREG1B(%a6)
177
bne opclass3 |branch if a fmove out (any kind)
178
btstb #6,CMDREG1B(%a6)
179
beqs uns_notpacked
180
181
bfextu CMDREG1B(%a6){#3:#3},%d0
182
cmpb #3,%d0
183
beq pack_source |check for a packed src op, branch if so
184
uns_notpacked:
185
bsr chk_dy_mo |set the dyadic/monadic flag
186
tstb DY_MO_FLG(%a6)
187
beqs src_op_ck |if monadic, go check src op
188
| ;else, check dst op (fall through)
189
190
btstb #7,DTAG(%a6)
191
beqs src_op_ck |if dst op is norm, check src op
192
bras dst_ex_dnrm |else, handle destination unnorm/dnrm
193
194
uni_getop:
195
bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
196
cmpil #0x17,%d0 |if op class and size fields are $17,
197
| ;it is FMOVECR; if not, continue
198
|
199
| If the instruction is fmovecr, exit get_op. It is handled
200
| in do_func and smovecr.sa.
201
|
202
bne not_fmovecr |handle fmovecr as an unimplemented inst
203
rts
204
205
not_fmovecr:
206
btstb #E1,E_BYTE(%a6) |if set, there is a packed operand
207
bne pack_source |check for packed src op, branch if so
208
209
| The following lines of are coded to optimize on normalized operands
210
moveb STAG(%a6),%d0
211
orb DTAG(%a6),%d0 |check if either of STAG/DTAG msb set
212
bmis dest_op_ck |if so, some op needs to be fixed
213
rts
214
215
dest_op_ck:
216
btstb #7,DTAG(%a6) |check for unsupported data types in
217
beqs src_op_ck |the destination, if not, check src op
218
bsr chk_dy_mo |set dyadic/monadic flag
219
tstb DY_MO_FLG(%a6) |
220
beqs src_op_ck |if monadic, check src op
221
|
222
| At this point, destination has an extended denorm or unnorm.
223
|
224
dst_ex_dnrm:
225
movew FPTEMP_EX(%a6),%d0 |get destination exponent
226
andiw #0x7fff,%d0 |mask sign, check if exp = 0000
227
beqs src_op_ck |if denorm then check source op.
228
| ;denorms are taken care of in res_func
229
| ;(unsupp) or do_func (unimp)
230
| ;else unnorm fall through
231
leal FPTEMP(%a6),%a0 |point a0 to dop - used in mk_norm
232
bsr mk_norm |go normalize - mk_norm returns:
233
| ;L_SCR1{7:5} = operand tag
234
| ; (000 = norm, 100 = denorm)
235
| ;L_SCR1{4} = fpte15 or ete15
236
| ; 0 = exp > $3fff
237
| ; 1 = exp <= $3fff
238
| ;and puts the normalized num back
239
| ;on the fsave stack
240
|
241
moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15
242
| ;to the fsave stack and fall
243
| ;through to check source operand
244
|
245
src_op_ck:
246
btstb #7,STAG(%a6)
247
beq end_getop |check for unsupported data types on the
248
| ;source operand
249
btstb #5,STAG(%a6)
250
bnes src_sd_dnrm |if bit 5 set, handle sgl/dbl denorms
251
|
252
| At this point only unnorms or extended denorms are possible.
253
|
254
src_ex_dnrm:
255
movew ETEMP_EX(%a6),%d0 |get source exponent
256
andiw #0x7fff,%d0 |mask sign, check if exp = 0000
257
beq end_getop |if denorm then exit, denorms are
258
| ;handled in do_func
259
leal ETEMP(%a6),%a0 |point a0 to sop - used in mk_norm
260
bsr mk_norm |go normalize - mk_norm returns:
261
| ;L_SCR1{7:5} = operand tag
262
| ; (000 = norm, 100 = denorm)
263
| ;L_SCR1{4} = fpte15 or ete15
264
| ; 0 = exp > $3fff
265
| ; 1 = exp <= $3fff
266
| ;and puts the normalized num back
267
| ;on the fsave stack
268
|
269
moveb L_SCR1(%a6),STAG(%a6) |write the new tag & ete15
270
rts |end_getop
271
272
|
273
| At this point, only single or double denorms are possible.
274
| If the inst is not fmove, normalize the source. If it is,
275
| do nothing to the input.
276
|
277
src_sd_dnrm:
278
btstb #4,CMDREG1B(%a6) |differentiate between sgl/dbl denorm
279
bnes is_double
280
is_single:
281
movew #0x3f81,%d1 |write bias for sgl denorm
282
bras common |goto the common code
283
is_double:
284
movew #0x3c01,%d1 |write the bias for a dbl denorm
285
common:
286
btstb #sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa
287
beqs pos
288
bset #15,%d1 |set sign bit because it is negative
289
pos:
290
movew %d1,ETEMP_EX(%a6)
291
| ;put exponent on stack
292
293
movew CMDREG1B(%a6),%d1
294
andw #0xe3ff,%d1 |clear out source specifier
295
orw #0x0800,%d1 |set source specifier to extended prec
296
movew %d1,CMDREG1B(%a6) |write back to the command word in stack
297
| ;this is needed to fix unsupp data stack
298
leal ETEMP(%a6),%a0 |point a0 to sop
299
300
bsr mk_norm |convert sgl/dbl denorm to norm
301
moveb L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0
302
rts |end_getop
303
|
304
| At this point, the source is definitely packed, whether
305
| instruction is dyadic or monadic is still unknown
306
|
307
pack_source:
308
movel FPTEMP_LO(%a6),ETEMP(%a6) |write ms part of packed
309
| ;number to etemp slot
310
bsr chk_dy_mo |set dyadic/monadic flag
311
bsr unpack
312
313
tstb DY_MO_FLG(%a6)
314
beqs end_getop |if monadic, exit
315
| ;else, fix FPTEMP
316
pack_dya:
317
bfextu CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg
318
movel #7,%d1
319
subl %d0,%d1
320
clrl %d0
321
bsetl %d1,%d0 |set up d0 as a dynamic register mask
322
fmovemx %d0,FPTEMP(%a6) |write to FPTEMP
323
324
btstb #7,DTAG(%a6) |check dest tag for unnorm or denorm
325
bne dst_ex_dnrm |else, handle the unnorm or ext denorm
326
|
327
| Dest is not denormalized. Check for norm, and set fpte15
328
| accordingly.
329
|
330
moveb DTAG(%a6),%d0
331
andib #0xf0,%d0 |strip to only dtag:fpte15
332
tstb %d0 |check for normalized value
333
bnes end_getop |if inf/nan/zero leave get_op
334
movew FPTEMP_EX(%a6),%d0
335
andiw #0x7fff,%d0
336
cmpiw #0x3fff,%d0 |check if fpte15 needs setting
337
bges end_getop |if >= $3fff, leave fpte15=0
338
orb #0x10,DTAG(%a6)
339
bras end_getop
340
341
|
342
| At this point, it is either an fmoveout packed, unnorm or denorm
343
|
344
opclass3:
345
clrb DY_MO_FLG(%a6) |set dyadic/monadic flag to monadic
346
bfextu CMDREG1B(%a6){#4:#2},%d0
347
cmpib #3,%d0
348
bne src_ex_dnrm |if not equal, must be unnorm or denorm
349
| ;else it is a packed move out
350
| ;exit
351
end_getop:
352
rts
353
354
|
355
| Sets the DY_MO_FLG correctly. This is used only on if it is an
356
| unsupported data type exception. Set if dyadic.
357
|
358
chk_dy_mo:
359
movew CMDREG1B(%a6),%d0
360
btstl #5,%d0 |testing extension command word
361
beqs set_mon |if bit 5 = 0 then monadic
362
btstl #4,%d0 |know that bit 5 = 1
363
beqs set_dya |if bit 4 = 0 then dyadic
364
andiw #0x007f,%d0 |get rid of all but extension bits {6:0}
365
cmpiw #0x0038,%d0 |if extension = $38 then fcmp (dyadic)
366
bnes set_mon
367
set_dya:
368
st DY_MO_FLG(%a6) |set the inst flag type to dyadic
369
rts
370
set_mon:
371
clrb DY_MO_FLG(%a6) |set the inst flag type to monadic
372
rts
373
|
374
| MK_NORM
375
|
376
| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
377
| exception if denorm.
378
|
379
| CASE opclass 0x0 unsupp
380
| mk_norm till msb set
381
| set tag = norm
382
|
383
| CASE opclass 0x0 unimp
384
| mk_norm till msb set or exp = 0
385
| if integer bit = 0
386
| tag = denorm
387
| else
388
| tag = norm
389
|
390
| CASE opclass 011 unsupp
391
| mk_norm till msb set or exp = 0
392
| if integer bit = 0
393
| tag = denorm
394
| set unfl_nmcexe = 1
395
| else
396
| tag = norm
397
|
398
| if exp <= $3fff
399
| set ete15 or fpte15 = 1
400
| else set ete15 or fpte15 = 0
401
402
| input:
403
| a0 = points to operand to be normalized
404
| output:
405
| L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
406
| L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
407
| the normalized operand is placed back on the fsave stack
408
mk_norm:
409
clrl L_SCR1(%a6)
410
bclrb #sign_bit,LOCAL_EX(%a0)
411
sne LOCAL_SGN(%a0) |transform into internal extended format
412
413
cmpib #0x2c,1+EXC_VEC(%a6) |check if unimp
414
bnes uns_data |branch if unsupp
415
bsr uni_inst |call if unimp (opclass 0x0)
416
bras reload
417
uns_data:
418
btstb #direction_bit,CMDREG1B(%a6) |check transfer direction
419
bnes bit_set |branch if set (opclass 011)
420
bsr uns_opx |call if opclass 0x0
421
bras reload
422
bit_set:
423
bsr uns_op3 |opclass 011
424
reload:
425
cmpw #0x3fff,LOCAL_EX(%a0) |if exp > $3fff
426
bgts end_mk | fpte15/ete15 already set to 0
427
bsetb #4,L_SCR1(%a6) |else set fpte15/ete15 to 1
428
| ;calling routine actually sets the
429
| ;value on the stack (along with the
430
| ;tag), since this routine doesn't
431
| ;know if it should set ete15 or fpte15
432
| ;ie, it doesn't know if this is the
433
| ;src op or dest op.
434
end_mk:
435
bfclr LOCAL_SGN(%a0){#0:#8}
436
beqs end_mk_pos
437
bsetb #sign_bit,LOCAL_EX(%a0) |convert back to IEEE format
438
end_mk_pos:
439
rts
440
|
441
| CASE opclass 011 unsupp
442
|
443
uns_op3:
444
bsr nrm_zero |normalize till msb = 1 or exp = zero
445
btstb #7,LOCAL_HI(%a0) |if msb = 1
446
bnes no_unfl |then branch
447
set_unfl:
448
orw #dnrm_tag,L_SCR1(%a6) |set denorm tag
449
bsetb #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit
450
no_unfl:
451
rts
452
|
453
| CASE opclass 0x0 unsupp
454
|
455
uns_opx:
456
bsr nrm_zero |normalize the number
457
btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set
458
beqs uns_den |if clear then now have a denorm
459
uns_nrm:
460
orb #norm_tag,L_SCR1(%a6) |set tag to norm
461
rts
462
uns_den:
463
orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm
464
rts
465
|
466
| CASE opclass 0x0 unimp
467
|
468
uni_inst:
469
bsr nrm_zero
470
btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set
471
beqs uni_den |if clear then now have a denorm
472
uni_nrm:
473
orb #norm_tag,L_SCR1(%a6) |set tag to norm
474
rts
475
uni_den:
476
orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm
477
rts
478
479
|
480
| Decimal to binary conversion
481
|
482
| Special cases of inf and NaNs are completed outside of decbin.
483
| If the input is an snan, the snan bit is not set.
484
|
485
| input:
486
| ETEMP(a6) - points to packed decimal string in memory
487
| output:
488
| fp0 - contains packed string converted to extended precision
489
| ETEMP - same as fp0
490
unpack:
491
movew CMDREG1B(%a6),%d0 |examine command word, looking for fmove's
492
andw #0x3b,%d0
493
beq move_unpack |special handling for fmove: must set FPSR_CC
494
495
movew ETEMP(%a6),%d0 |get word with inf information
496
bfextu %d0{#20:#12},%d1 |get exponent into d1
497
cmpiw #0x0fff,%d1 |test for inf or NaN
498
bnes try_zero |if not equal, it is not special
499
bfextu %d0{#17:#3},%d1 |get SE and y bits into d1
500
cmpiw #7,%d1 |SE and y bits must be on for special
501
bnes try_zero |if not on, it is not special
502
|input is of the special cases of inf and NaN
503
tstl ETEMP_HI(%a6) |check ms mantissa
504
bnes fix_nan |if non-zero, it is a NaN
505
tstl ETEMP_LO(%a6) |check ls mantissa
506
bnes fix_nan |if non-zero, it is a NaN
507
bra finish |special already on stack
508
fix_nan:
509
btstb #signan_bit,ETEMP_HI(%a6) |test for snan
510
bne finish
511
orl #snaniop_mask,USER_FPSR(%a6) |always set snan if it is so
512
bra finish
513
try_zero:
514
movew ETEMP_EX+2(%a6),%d0 |get word 4
515
andiw #0x000f,%d0 |clear all but last ni(y)bble
516
tstw %d0 |check for zero.
517
bne not_spec
518
tstl ETEMP_HI(%a6) |check words 3 and 2
519
bne not_spec
520
tstl ETEMP_LO(%a6) |check words 1 and 0
521
bne not_spec
522
tstl ETEMP(%a6) |test sign of the zero
523
bges pos_zero
524
movel #0x80000000,ETEMP(%a6) |write neg zero to etemp
525
clrl ETEMP_HI(%a6)
526
clrl ETEMP_LO(%a6)
527
bra finish
528
pos_zero:
529
clrl ETEMP(%a6)
530
clrl ETEMP_HI(%a6)
531
clrl ETEMP_LO(%a6)
532
bra finish
533
534
not_spec:
535
fmovemx %fp0-%fp1,-(%a7) |save fp0 - decbin returns in it
536
bsr decbin
537
fmovex %fp0,ETEMP(%a6) |put the unpacked sop in the fsave stack
538
fmovemx (%a7)+,%fp0-%fp1
539
fmovel #0,%FPSR |clr fpsr from decbin
540
bra finish
541
542
|
543
| Special handling for packed move in: Same results as all other
544
| packed cases, but we must set the FPSR condition codes properly.
545
|
546
move_unpack:
547
movew ETEMP(%a6),%d0 |get word with inf information
548
bfextu %d0{#20:#12},%d1 |get exponent into d1
549
cmpiw #0x0fff,%d1 |test for inf or NaN
550
bnes mtry_zero |if not equal, it is not special
551
bfextu %d0{#17:#3},%d1 |get SE and y bits into d1
552
cmpiw #7,%d1 |SE and y bits must be on for special
553
bnes mtry_zero |if not on, it is not special
554
|input is of the special cases of inf and NaN
555
tstl ETEMP_HI(%a6) |check ms mantissa
556
bnes mfix_nan |if non-zero, it is a NaN
557
tstl ETEMP_LO(%a6) |check ls mantissa
558
bnes mfix_nan |if non-zero, it is a NaN
559
|input is inf
560
orl #inf_mask,USER_FPSR(%a6) |set I bit
561
tstl ETEMP(%a6) |check sign
562
bge finish
563
orl #neg_mask,USER_FPSR(%a6) |set N bit
564
bra finish |special already on stack
565
mfix_nan:
566
orl #nan_mask,USER_FPSR(%a6) |set NaN bit
567
moveb #nan_tag,STAG(%a6) |set stag to NaN
568
btstb #signan_bit,ETEMP_HI(%a6) |test for snan
569
bnes mn_snan
570
orl #snaniop_mask,USER_FPSR(%a6) |set snan bit
571
btstb #snan_bit,FPCR_ENABLE(%a6) |test for snan enabled
572
bnes mn_snan
573
bsetb #signan_bit,ETEMP_HI(%a6) |force snans to qnans
574
mn_snan:
575
tstl ETEMP(%a6) |check for sign
576
bge finish |if clr, go on
577
orl #neg_mask,USER_FPSR(%a6) |set N bit
578
bra finish
579
580
mtry_zero:
581
movew ETEMP_EX+2(%a6),%d0 |get word 4
582
andiw #0x000f,%d0 |clear all but last ni(y)bble
583
tstw %d0 |check for zero.
584
bnes mnot_spec
585
tstl ETEMP_HI(%a6) |check words 3 and 2
586
bnes mnot_spec
587
tstl ETEMP_LO(%a6) |check words 1 and 0
588
bnes mnot_spec
589
tstl ETEMP(%a6) |test sign of the zero
590
bges mpos_zero
591
orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z
592
movel #0x80000000,ETEMP(%a6) |write neg zero to etemp
593
clrl ETEMP_HI(%a6)
594
clrl ETEMP_LO(%a6)
595
bras finish
596
mpos_zero:
597
orl #z_mask,USER_FPSR(%a6) |set Z
598
clrl ETEMP(%a6)
599
clrl ETEMP_HI(%a6)
600
clrl ETEMP_LO(%a6)
601
bras finish
602
603
mnot_spec:
604
fmovemx %fp0-%fp1,-(%a7) |save fp0 ,fp1 - decbin returns in fp0
605
bsr decbin
606
fmovex %fp0,ETEMP(%a6)
607
| ;put the unpacked sop in the fsave stack
608
fmovemx (%a7)+,%fp0-%fp1
609
610
finish:
611
movew CMDREG1B(%a6),%d0 |get the command word
612
andw #0xfbff,%d0 |change the source specifier field to
613
| ;extended (was packed).
614
movew %d0,CMDREG1B(%a6) |write command word back to fsave stack
615
| ;we need to do this so the 040 will
616
| ;re-execute the inst. without taking
617
| ;another packed trap.
618
619
fix_stag:
620
|Converted result is now in etemp on fsave stack, now set the source
621
|tag (stag)
622
| if (ete =$7fff) then INF or NAN
623
| if (etemp = $x.0----0) then
624
| stag = INF
625
| else
626
| stag = NAN
627
| else
628
| if (ete = $0000) then
629
| stag = ZERO
630
| else
631
| stag = NORM
632
|
633
| Note also that the etemp_15 bit (just right of the stag) must
634
| be set accordingly.
635
|
636
movew ETEMP_EX(%a6),%d1
637
andiw #0x7fff,%d1 |strip sign
638
cmpw #0x7fff,%d1
639
bnes z_or_nrm
640
movel ETEMP_HI(%a6),%d1
641
bnes is_nan
642
movel ETEMP_LO(%a6),%d1
643
bnes is_nan
644
is_inf:
645
moveb #0x40,STAG(%a6)
646
movel #0x40,%d0
647
rts
648
is_nan:
649
moveb #0x60,STAG(%a6)
650
movel #0x60,%d0
651
rts
652
z_or_nrm:
653
tstw %d1
654
bnes is_nrm
655
is_zro:
656
| For a zero, set etemp_15
657
moveb #0x30,STAG(%a6)
658
movel #0x20,%d0
659
rts
660
is_nrm:
661
| For a norm, check if the exp <= $3fff; if so, set etemp_15
662
cmpiw #0x3fff,%d1
663
bles set_bit15
664
moveb #0,STAG(%a6)
665
bras end_is_nrm
666
set_bit15:
667
moveb #0x10,STAG(%a6)
668
end_is_nrm:
669
movel #0,%d0
670
end_fix:
671
rts
672
673
end_get:
674
rts
675
|end
676
677