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