162306a36Sopenharmony_ci|
262306a36Sopenharmony_ci|	get_op.sa 3.6 5/19/92
362306a36Sopenharmony_ci|
462306a36Sopenharmony_ci|	get_op.sa 3.5 4/26/91
562306a36Sopenharmony_ci|
662306a36Sopenharmony_ci|  Description: This routine is called by the unsupported format/data
762306a36Sopenharmony_ci| type exception handler ('unsupp' - vector 55) and the unimplemented
862306a36Sopenharmony_ci| instruction exception handler ('unimp' - vector 11).  'get_op'
962306a36Sopenharmony_ci| determines the opclass (0, 2, or 3) and branches to the
1062306a36Sopenharmony_ci| opclass handler routine.  See 68881/2 User's Manual table 4-11
1162306a36Sopenharmony_ci| for a description of the opclasses.
1262306a36Sopenharmony_ci|
1362306a36Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) and for
1462306a36Sopenharmony_ci| UNIMPLEMENTED instructions (exception vector 11) the following
1562306a36Sopenharmony_ci| applies:
1662306a36Sopenharmony_ci|
1762306a36Sopenharmony_ci| - For unnormalized numbers (opclass 0, 2, or 3) the
1862306a36Sopenharmony_ci| number(s) is normalized and the operand type tag is updated.
1962306a36Sopenharmony_ci|
2062306a36Sopenharmony_ci| - For a packed number (opclass 2) the number is unpacked and the
2162306a36Sopenharmony_ci| operand type tag is updated.
2262306a36Sopenharmony_ci|
2362306a36Sopenharmony_ci| - For denormalized numbers (opclass 0 or 2) the number(s) is not
2462306a36Sopenharmony_ci| changed but passed to the next module.  The next module for
2562306a36Sopenharmony_ci| unimp is do_func, the next module for unsupp is res_func.
2662306a36Sopenharmony_ci|
2762306a36Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) only the
2862306a36Sopenharmony_ci| following applies:
2962306a36Sopenharmony_ci|
3062306a36Sopenharmony_ci| - If there is a move out with a packed number (opclass 3) the
3162306a36Sopenharmony_ci| number is packed and written to user memory.  For the other
3262306a36Sopenharmony_ci| opclasses the number(s) are written back to the fsave stack
3362306a36Sopenharmony_ci| and the instruction is then restored back into the '040.  The
3462306a36Sopenharmony_ci| '040 is then able to complete the instruction.
3562306a36Sopenharmony_ci|
3662306a36Sopenharmony_ci| For example:
3762306a36Sopenharmony_ci| fadd.x fpm,fpn where the fpm contains an unnormalized number.
3862306a36Sopenharmony_ci| The '040 takes an unsupported data trap and gets to this
3962306a36Sopenharmony_ci| routine.  The number is normalized, put back on the stack and
4062306a36Sopenharmony_ci| then an frestore is done to restore the instruction back into
4162306a36Sopenharmony_ci| the '040.  The '040 then re-executes the fadd.x fpm,fpn with
4262306a36Sopenharmony_ci| a normalized number in the source and the instruction is
4362306a36Sopenharmony_ci| successful.
4462306a36Sopenharmony_ci|
4562306a36Sopenharmony_ci| Next consider if in the process of normalizing the un-
4662306a36Sopenharmony_ci| normalized number it becomes a denormalized number.  The
4762306a36Sopenharmony_ci| routine which converts the unnorm to a norm (called mk_norm)
4862306a36Sopenharmony_ci| detects this and tags the number as a denorm.  The routine
4962306a36Sopenharmony_ci| res_func sees the denorm tag and converts the denorm to a
5062306a36Sopenharmony_ci| norm.  The instruction is then restored back into the '040
5162306a36Sopenharmony_ci| which re_executes the instruction.
5262306a36Sopenharmony_ci|
5362306a36Sopenharmony_ci|
5462306a36Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
5562306a36Sopenharmony_ci|			All Rights Reserved
5662306a36Sopenharmony_ci|
5762306a36Sopenharmony_ci|       For details on the license for this file, please see the
5862306a36Sopenharmony_ci|       file, README, in this same directory.
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciGET_OP:    |idnt    2,1 | Motorola 040 Floating Point Software Package
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	|section	8
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#include "fpsp.h"
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	.global	PIRN,PIRZRM,PIRP
6762306a36Sopenharmony_ci	.global	SMALRN,SMALRZRM,SMALRP
6862306a36Sopenharmony_ci	.global	BIGRN,BIGRZRM,BIGRP
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciPIRN:
7162306a36Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c235    |pi
7262306a36Sopenharmony_ciPIRZRM:
7362306a36Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c234    |pi
7462306a36Sopenharmony_ciPIRP:
7562306a36Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c235    |pi
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci|round to nearest
7862306a36Sopenharmony_ciSMALRN:
7962306a36Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff798    |log10(2)
8062306a36Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9a    |e
8162306a36Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    |log2(e)
8262306a36Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
8362306a36Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
8462306a36Sopenharmony_ci| round to zero;round to negative infinity
8562306a36Sopenharmony_ciSMALRZRM:
8662306a36Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff798    |log10(2)
8762306a36Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9a    |e
8862306a36Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bb    |log2(e)
8962306a36Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
9062306a36Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
9162306a36Sopenharmony_ci| round to positive infinity
9262306a36Sopenharmony_ciSMALRP:
9362306a36Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff799    |log10(2)
9462306a36Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9b    |e
9562306a36Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    |log2(e)
9662306a36Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
9762306a36Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci|round to nearest
10062306a36Sopenharmony_ciBIGRN:
10162306a36Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ac    |ln(2)
10262306a36Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac17    |ln(10)
10362306a36Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	.global	PTENRN
10662306a36Sopenharmony_ciPTENRN:
10762306a36Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
10862306a36Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
10962306a36Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
11062306a36Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
11162306a36Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
11262306a36Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59E    |10 ^ 32
11362306a36Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D5    |10 ^ 64
11462306a36Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CE0    |10 ^ 128
11562306a36Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    |10 ^ 256
11662306a36Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C7    |10 ^ 512
11762306a36Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C17    |10 ^ 1024
11862306a36Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    |10 ^ 2048
11962306a36Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979B    |10 ^ 4096
12062306a36Sopenharmony_ci|round to minus infinity
12162306a36Sopenharmony_ciBIGRZRM:
12262306a36Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ab    |ln(2)
12362306a36Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac16    |ln(10)
12462306a36Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	.global	PTENRM
12762306a36Sopenharmony_ciPTENRM:
12862306a36Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
12962306a36Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
13062306a36Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
13162306a36Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
13262306a36Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
13362306a36Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59D    |10 ^ 32
13462306a36Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D5    |10 ^ 64
13562306a36Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CDF    |10 ^ 128
13662306a36Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8D    |10 ^ 256
13762306a36Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C6    |10 ^ 512
13862306a36Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C17    |10 ^ 1024
13962306a36Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    |10 ^ 2048
14062306a36Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979A    |10 ^ 4096
14162306a36Sopenharmony_ci|round to positive infinity
14262306a36Sopenharmony_ciBIGRP:
14362306a36Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ac    |ln(2)
14462306a36Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac17    |ln(10)
14562306a36Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	.global	PTENRP
14862306a36Sopenharmony_ciPTENRP:
14962306a36Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
15062306a36Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
15162306a36Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
15262306a36Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
15362306a36Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
15462306a36Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59E    |10 ^ 32
15562306a36Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D6    |10 ^ 64
15662306a36Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CE0    |10 ^ 128
15762306a36Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    |10 ^ 256
15862306a36Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C7    |10 ^ 512
15962306a36Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C18    |10 ^ 1024
16062306a36Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE6    |10 ^ 2048
16162306a36Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979B    |10 ^ 4096
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	|xref	nrm_zero
16462306a36Sopenharmony_ci	|xref	decbin
16562306a36Sopenharmony_ci	|xref	round
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	.global    get_op
16862306a36Sopenharmony_ci	.global    uns_getop
16962306a36Sopenharmony_ci	.global    uni_getop
17062306a36Sopenharmony_ciget_op:
17162306a36Sopenharmony_ci	clrb	DY_MO_FLG(%a6)
17262306a36Sopenharmony_ci	tstb	UFLG_TMP(%a6)	|test flag for unsupp/unimp state
17362306a36Sopenharmony_ci	beq	uni_getop
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ciuns_getop:
17662306a36Sopenharmony_ci	btstb	#direction_bit,CMDREG1B(%a6)
17762306a36Sopenharmony_ci	bne	opclass3	|branch if a fmove out (any kind)
17862306a36Sopenharmony_ci	btstb	#6,CMDREG1B(%a6)
17962306a36Sopenharmony_ci	beqs	uns_notpacked
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	bfextu	CMDREG1B(%a6){#3:#3},%d0
18262306a36Sopenharmony_ci	cmpb	#3,%d0
18362306a36Sopenharmony_ci	beq	pack_source	|check for a packed src op, branch if so
18462306a36Sopenharmony_ciuns_notpacked:
18562306a36Sopenharmony_ci	bsr	chk_dy_mo	|set the dyadic/monadic flag
18662306a36Sopenharmony_ci	tstb	DY_MO_FLG(%a6)
18762306a36Sopenharmony_ci	beqs	src_op_ck	|if monadic, go check src op
18862306a36Sopenharmony_ci|				;else, check dst op (fall through)
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	btstb	#7,DTAG(%a6)
19162306a36Sopenharmony_ci	beqs	src_op_ck	|if dst op is norm, check src op
19262306a36Sopenharmony_ci	bras	dst_ex_dnrm	|else, handle destination unnorm/dnrm
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciuni_getop:
19562306a36Sopenharmony_ci	bfextu	CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
19662306a36Sopenharmony_ci	cmpil	#0x17,%d0		|if op class and size fields are $17,
19762306a36Sopenharmony_ci|				;it is FMOVECR; if not, continue
19862306a36Sopenharmony_ci|
19962306a36Sopenharmony_ci| If the instruction is fmovecr, exit get_op.  It is handled
20062306a36Sopenharmony_ci| in do_func and smovecr.sa.
20162306a36Sopenharmony_ci|
20262306a36Sopenharmony_ci	bne	not_fmovecr	|handle fmovecr as an unimplemented inst
20362306a36Sopenharmony_ci	rts
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cinot_fmovecr:
20662306a36Sopenharmony_ci	btstb	#E1,E_BYTE(%a6)	|if set, there is a packed operand
20762306a36Sopenharmony_ci	bne	pack_source	|check for packed src op, branch if so
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci| The following lines of are coded to optimize on normalized operands
21062306a36Sopenharmony_ci	moveb	STAG(%a6),%d0
21162306a36Sopenharmony_ci	orb	DTAG(%a6),%d0	|check if either of STAG/DTAG msb set
21262306a36Sopenharmony_ci	bmis	dest_op_ck	|if so, some op needs to be fixed
21362306a36Sopenharmony_ci	rts
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_cidest_op_ck:
21662306a36Sopenharmony_ci	btstb	#7,DTAG(%a6)	|check for unsupported data types in
21762306a36Sopenharmony_ci	beqs	src_op_ck	|the destination, if not, check src op
21862306a36Sopenharmony_ci	bsr	chk_dy_mo	|set dyadic/monadic flag
21962306a36Sopenharmony_ci	tstb	DY_MO_FLG(%a6)	|
22062306a36Sopenharmony_ci	beqs	src_op_ck	|if monadic, check src op
22162306a36Sopenharmony_ci|
22262306a36Sopenharmony_ci| At this point, destination has an extended denorm or unnorm.
22362306a36Sopenharmony_ci|
22462306a36Sopenharmony_cidst_ex_dnrm:
22562306a36Sopenharmony_ci	movew	FPTEMP_EX(%a6),%d0 |get destination exponent
22662306a36Sopenharmony_ci	andiw	#0x7fff,%d0	|mask sign, check if exp = 0000
22762306a36Sopenharmony_ci	beqs	src_op_ck	|if denorm then check source op.
22862306a36Sopenharmony_ci|				;denorms are taken care of in res_func
22962306a36Sopenharmony_ci|				;(unsupp) or do_func (unimp)
23062306a36Sopenharmony_ci|				;else unnorm fall through
23162306a36Sopenharmony_ci	leal	FPTEMP(%a6),%a0	|point a0 to dop - used in mk_norm
23262306a36Sopenharmony_ci	bsr	mk_norm		|go normalize - mk_norm returns:
23362306a36Sopenharmony_ci|				;L_SCR1{7:5} = operand tag
23462306a36Sopenharmony_ci|				;	(000 = norm, 100 = denorm)
23562306a36Sopenharmony_ci|				;L_SCR1{4} = fpte15 or ete15
23662306a36Sopenharmony_ci|				;	0 = exp >  $3fff
23762306a36Sopenharmony_ci|				;	1 = exp <= $3fff
23862306a36Sopenharmony_ci|				;and puts the normalized num back
23962306a36Sopenharmony_ci|				;on the fsave stack
24062306a36Sopenharmony_ci|
24162306a36Sopenharmony_ci	moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15
24262306a36Sopenharmony_ci|				;to the fsave stack and fall
24362306a36Sopenharmony_ci|				;through to check source operand
24462306a36Sopenharmony_ci|
24562306a36Sopenharmony_cisrc_op_ck:
24662306a36Sopenharmony_ci	btstb	#7,STAG(%a6)
24762306a36Sopenharmony_ci	beq	end_getop	|check for unsupported data types on the
24862306a36Sopenharmony_ci|				;source operand
24962306a36Sopenharmony_ci	btstb	#5,STAG(%a6)
25062306a36Sopenharmony_ci	bnes	src_sd_dnrm	|if bit 5 set, handle sgl/dbl denorms
25162306a36Sopenharmony_ci|
25262306a36Sopenharmony_ci| At this point only unnorms or extended denorms are possible.
25362306a36Sopenharmony_ci|
25462306a36Sopenharmony_cisrc_ex_dnrm:
25562306a36Sopenharmony_ci	movew	ETEMP_EX(%a6),%d0 |get source exponent
25662306a36Sopenharmony_ci	andiw	#0x7fff,%d0	|mask sign, check if exp = 0000
25762306a36Sopenharmony_ci	beq	end_getop	|if denorm then exit, denorms are
25862306a36Sopenharmony_ci|				;handled in do_func
25962306a36Sopenharmony_ci	leal	ETEMP(%a6),%a0	|point a0 to sop - used in mk_norm
26062306a36Sopenharmony_ci	bsr	mk_norm		|go normalize - mk_norm returns:
26162306a36Sopenharmony_ci|				;L_SCR1{7:5} = operand tag
26262306a36Sopenharmony_ci|				;	(000 = norm, 100 = denorm)
26362306a36Sopenharmony_ci|				;L_SCR1{4} = fpte15 or ete15
26462306a36Sopenharmony_ci|				;	0 = exp >  $3fff
26562306a36Sopenharmony_ci|				;	1 = exp <= $3fff
26662306a36Sopenharmony_ci|				;and puts the normalized num back
26762306a36Sopenharmony_ci|				;on the fsave stack
26862306a36Sopenharmony_ci|
26962306a36Sopenharmony_ci	moveb	L_SCR1(%a6),STAG(%a6) |write the new tag & ete15
27062306a36Sopenharmony_ci	rts			|end_getop
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci|
27362306a36Sopenharmony_ci| At this point, only single or double denorms are possible.
27462306a36Sopenharmony_ci| If the inst is not fmove, normalize the source.  If it is,
27562306a36Sopenharmony_ci| do nothing to the input.
27662306a36Sopenharmony_ci|
27762306a36Sopenharmony_cisrc_sd_dnrm:
27862306a36Sopenharmony_ci	btstb	#4,CMDREG1B(%a6)	|differentiate between sgl/dbl denorm
27962306a36Sopenharmony_ci	bnes	is_double
28062306a36Sopenharmony_ciis_single:
28162306a36Sopenharmony_ci	movew	#0x3f81,%d1	|write bias for sgl denorm
28262306a36Sopenharmony_ci	bras	common		|goto the common code
28362306a36Sopenharmony_ciis_double:
28462306a36Sopenharmony_ci	movew	#0x3c01,%d1	|write the bias for a dbl denorm
28562306a36Sopenharmony_cicommon:
28662306a36Sopenharmony_ci	btstb	#sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa
28762306a36Sopenharmony_ci	beqs	pos
28862306a36Sopenharmony_ci	bset	#15,%d1		|set sign bit because it is negative
28962306a36Sopenharmony_cipos:
29062306a36Sopenharmony_ci	movew	%d1,ETEMP_EX(%a6)
29162306a36Sopenharmony_ci|				;put exponent on stack
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	movew	CMDREG1B(%a6),%d1
29462306a36Sopenharmony_ci	andw	#0xe3ff,%d1	|clear out source specifier
29562306a36Sopenharmony_ci	orw	#0x0800,%d1	|set source specifier to extended prec
29662306a36Sopenharmony_ci	movew	%d1,CMDREG1B(%a6)	|write back to the command word in stack
29762306a36Sopenharmony_ci|				;this is needed to fix unsupp data stack
29862306a36Sopenharmony_ci	leal	ETEMP(%a6),%a0	|point a0 to sop
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	bsr	mk_norm		|convert sgl/dbl denorm to norm
30162306a36Sopenharmony_ci	moveb	L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0
30262306a36Sopenharmony_ci	rts			|end_getop
30362306a36Sopenharmony_ci|
30462306a36Sopenharmony_ci| At this point, the source is definitely packed, whether
30562306a36Sopenharmony_ci| instruction is dyadic or monadic is still unknown
30662306a36Sopenharmony_ci|
30762306a36Sopenharmony_cipack_source:
30862306a36Sopenharmony_ci	movel	FPTEMP_LO(%a6),ETEMP(%a6)	|write ms part of packed
30962306a36Sopenharmony_ci|				;number to etemp slot
31062306a36Sopenharmony_ci	bsr	chk_dy_mo	|set dyadic/monadic flag
31162306a36Sopenharmony_ci	bsr	unpack
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	tstb	DY_MO_FLG(%a6)
31462306a36Sopenharmony_ci	beqs	end_getop	|if monadic, exit
31562306a36Sopenharmony_ci|				;else, fix FPTEMP
31662306a36Sopenharmony_cipack_dya:
31762306a36Sopenharmony_ci	bfextu	CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg
31862306a36Sopenharmony_ci	movel	#7,%d1
31962306a36Sopenharmony_ci	subl	%d0,%d1
32062306a36Sopenharmony_ci	clrl	%d0
32162306a36Sopenharmony_ci	bsetl	%d1,%d0		|set up d0 as a dynamic register mask
32262306a36Sopenharmony_ci	fmovemx %d0,FPTEMP(%a6)	|write to FPTEMP
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	btstb	#7,DTAG(%a6)	|check dest tag for unnorm or denorm
32562306a36Sopenharmony_ci	bne	dst_ex_dnrm	|else, handle the unnorm or ext denorm
32662306a36Sopenharmony_ci|
32762306a36Sopenharmony_ci| Dest is not denormalized.  Check for norm, and set fpte15
32862306a36Sopenharmony_ci| accordingly.
32962306a36Sopenharmony_ci|
33062306a36Sopenharmony_ci	moveb	DTAG(%a6),%d0
33162306a36Sopenharmony_ci	andib	#0xf0,%d0		|strip to only dtag:fpte15
33262306a36Sopenharmony_ci	tstb	%d0		|check for normalized value
33362306a36Sopenharmony_ci	bnes	end_getop	|if inf/nan/zero leave get_op
33462306a36Sopenharmony_ci	movew	FPTEMP_EX(%a6),%d0
33562306a36Sopenharmony_ci	andiw	#0x7fff,%d0
33662306a36Sopenharmony_ci	cmpiw	#0x3fff,%d0	|check if fpte15 needs setting
33762306a36Sopenharmony_ci	bges	end_getop	|if >= $3fff, leave fpte15=0
33862306a36Sopenharmony_ci	orb	#0x10,DTAG(%a6)
33962306a36Sopenharmony_ci	bras	end_getop
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci|
34262306a36Sopenharmony_ci| At this point, it is either an fmoveout packed, unnorm or denorm
34362306a36Sopenharmony_ci|
34462306a36Sopenharmony_ciopclass3:
34562306a36Sopenharmony_ci	clrb	DY_MO_FLG(%a6)	|set dyadic/monadic flag to monadic
34662306a36Sopenharmony_ci	bfextu	CMDREG1B(%a6){#4:#2},%d0
34762306a36Sopenharmony_ci	cmpib	#3,%d0
34862306a36Sopenharmony_ci	bne	src_ex_dnrm	|if not equal, must be unnorm or denorm
34962306a36Sopenharmony_ci|				;else it is a packed move out
35062306a36Sopenharmony_ci|				;exit
35162306a36Sopenharmony_ciend_getop:
35262306a36Sopenharmony_ci	rts
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci|
35562306a36Sopenharmony_ci| Sets the DY_MO_FLG correctly. This is used only on if it is an
35662306a36Sopenharmony_ci| unsupported data type exception.  Set if dyadic.
35762306a36Sopenharmony_ci|
35862306a36Sopenharmony_cichk_dy_mo:
35962306a36Sopenharmony_ci	movew	CMDREG1B(%a6),%d0
36062306a36Sopenharmony_ci	btstl	#5,%d0		|testing extension command word
36162306a36Sopenharmony_ci	beqs	set_mon		|if bit 5 = 0 then monadic
36262306a36Sopenharmony_ci	btstl	#4,%d0		|know that bit 5 = 1
36362306a36Sopenharmony_ci	beqs	set_dya		|if bit 4 = 0 then dyadic
36462306a36Sopenharmony_ci	andiw	#0x007f,%d0	|get rid of all but extension bits {6:0}
36562306a36Sopenharmony_ci	cmpiw	#0x0038,%d0	|if extension = $38 then fcmp (dyadic)
36662306a36Sopenharmony_ci	bnes	set_mon
36762306a36Sopenharmony_ciset_dya:
36862306a36Sopenharmony_ci	st	DY_MO_FLG(%a6)	|set the inst flag type to dyadic
36962306a36Sopenharmony_ci	rts
37062306a36Sopenharmony_ciset_mon:
37162306a36Sopenharmony_ci	clrb	DY_MO_FLG(%a6)	|set the inst flag type to monadic
37262306a36Sopenharmony_ci	rts
37362306a36Sopenharmony_ci|
37462306a36Sopenharmony_ci|	MK_NORM
37562306a36Sopenharmony_ci|
37662306a36Sopenharmony_ci| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
37762306a36Sopenharmony_ci| exception if denorm.
37862306a36Sopenharmony_ci|
37962306a36Sopenharmony_ci| CASE opclass 0x0 unsupp
38062306a36Sopenharmony_ci|	mk_norm till msb set
38162306a36Sopenharmony_ci|	set tag = norm
38262306a36Sopenharmony_ci|
38362306a36Sopenharmony_ci| CASE opclass 0x0 unimp
38462306a36Sopenharmony_ci|	mk_norm till msb set or exp = 0
38562306a36Sopenharmony_ci|	if integer bit = 0
38662306a36Sopenharmony_ci|	   tag = denorm
38762306a36Sopenharmony_ci|	else
38862306a36Sopenharmony_ci|	   tag = norm
38962306a36Sopenharmony_ci|
39062306a36Sopenharmony_ci| CASE opclass 011 unsupp
39162306a36Sopenharmony_ci|	mk_norm till msb set or exp = 0
39262306a36Sopenharmony_ci|	if integer bit = 0
39362306a36Sopenharmony_ci|	   tag = denorm
39462306a36Sopenharmony_ci|	   set unfl_nmcexe = 1
39562306a36Sopenharmony_ci|	else
39662306a36Sopenharmony_ci|	   tag = norm
39762306a36Sopenharmony_ci|
39862306a36Sopenharmony_ci| if exp <= $3fff
39962306a36Sopenharmony_ci|   set ete15 or fpte15 = 1
40062306a36Sopenharmony_ci| else set ete15 or fpte15 = 0
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci| input:
40362306a36Sopenharmony_ci|	a0 = points to operand to be normalized
40462306a36Sopenharmony_ci| output:
40562306a36Sopenharmony_ci|	L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
40662306a36Sopenharmony_ci|	L_SCR1{4}   = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
40762306a36Sopenharmony_ci|	the normalized operand is placed back on the fsave stack
40862306a36Sopenharmony_cimk_norm:
40962306a36Sopenharmony_ci	clrl	L_SCR1(%a6)
41062306a36Sopenharmony_ci	bclrb	#sign_bit,LOCAL_EX(%a0)
41162306a36Sopenharmony_ci	sne	LOCAL_SGN(%a0)	|transform into internal extended format
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	cmpib	#0x2c,1+EXC_VEC(%a6) |check if unimp
41462306a36Sopenharmony_ci	bnes	uns_data	|branch if unsupp
41562306a36Sopenharmony_ci	bsr	uni_inst	|call if unimp (opclass 0x0)
41662306a36Sopenharmony_ci	bras	reload
41762306a36Sopenharmony_ciuns_data:
41862306a36Sopenharmony_ci	btstb	#direction_bit,CMDREG1B(%a6) |check transfer direction
41962306a36Sopenharmony_ci	bnes	bit_set		|branch if set (opclass 011)
42062306a36Sopenharmony_ci	bsr	uns_opx		|call if opclass 0x0
42162306a36Sopenharmony_ci	bras	reload
42262306a36Sopenharmony_cibit_set:
42362306a36Sopenharmony_ci	bsr	uns_op3		|opclass 011
42462306a36Sopenharmony_cireload:
42562306a36Sopenharmony_ci	cmpw	#0x3fff,LOCAL_EX(%a0) |if exp > $3fff
42662306a36Sopenharmony_ci	bgts	end_mk		|   fpte15/ete15 already set to 0
42762306a36Sopenharmony_ci	bsetb	#4,L_SCR1(%a6)	|else set fpte15/ete15 to 1
42862306a36Sopenharmony_ci|				;calling routine actually sets the
42962306a36Sopenharmony_ci|				;value on the stack (along with the
43062306a36Sopenharmony_ci|				;tag), since this routine doesn't
43162306a36Sopenharmony_ci|				;know if it should set ete15 or fpte15
43262306a36Sopenharmony_ci|				;ie, it doesn't know if this is the
43362306a36Sopenharmony_ci|				;src op or dest op.
43462306a36Sopenharmony_ciend_mk:
43562306a36Sopenharmony_ci	bfclr	LOCAL_SGN(%a0){#0:#8}
43662306a36Sopenharmony_ci	beqs	end_mk_pos
43762306a36Sopenharmony_ci	bsetb	#sign_bit,LOCAL_EX(%a0) |convert back to IEEE format
43862306a36Sopenharmony_ciend_mk_pos:
43962306a36Sopenharmony_ci	rts
44062306a36Sopenharmony_ci|
44162306a36Sopenharmony_ci|     CASE opclass 011 unsupp
44262306a36Sopenharmony_ci|
44362306a36Sopenharmony_ciuns_op3:
44462306a36Sopenharmony_ci	bsr	nrm_zero	|normalize till msb = 1 or exp = zero
44562306a36Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|if msb = 1
44662306a36Sopenharmony_ci	bnes	no_unfl		|then branch
44762306a36Sopenharmony_ciset_unfl:
44862306a36Sopenharmony_ci	orw	#dnrm_tag,L_SCR1(%a6) |set denorm tag
44962306a36Sopenharmony_ci	bsetb	#unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit
45062306a36Sopenharmony_cino_unfl:
45162306a36Sopenharmony_ci	rts
45262306a36Sopenharmony_ci|
45362306a36Sopenharmony_ci|     CASE opclass 0x0 unsupp
45462306a36Sopenharmony_ci|
45562306a36Sopenharmony_ciuns_opx:
45662306a36Sopenharmony_ci	bsr	nrm_zero	|normalize the number
45762306a36Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|check if integer bit (j-bit) is set
45862306a36Sopenharmony_ci	beqs	uns_den		|if clear then now have a denorm
45962306a36Sopenharmony_ciuns_nrm:
46062306a36Sopenharmony_ci	orb	#norm_tag,L_SCR1(%a6) |set tag to norm
46162306a36Sopenharmony_ci	rts
46262306a36Sopenharmony_ciuns_den:
46362306a36Sopenharmony_ci	orb	#dnrm_tag,L_SCR1(%a6) |set tag to denorm
46462306a36Sopenharmony_ci	rts
46562306a36Sopenharmony_ci|
46662306a36Sopenharmony_ci|     CASE opclass 0x0 unimp
46762306a36Sopenharmony_ci|
46862306a36Sopenharmony_ciuni_inst:
46962306a36Sopenharmony_ci	bsr	nrm_zero
47062306a36Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|check if integer bit (j-bit) is set
47162306a36Sopenharmony_ci	beqs	uni_den		|if clear then now have a denorm
47262306a36Sopenharmony_ciuni_nrm:
47362306a36Sopenharmony_ci	orb	#norm_tag,L_SCR1(%a6) |set tag to norm
47462306a36Sopenharmony_ci	rts
47562306a36Sopenharmony_ciuni_den:
47662306a36Sopenharmony_ci	orb	#dnrm_tag,L_SCR1(%a6) |set tag to denorm
47762306a36Sopenharmony_ci	rts
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci|
48062306a36Sopenharmony_ci|	Decimal to binary conversion
48162306a36Sopenharmony_ci|
48262306a36Sopenharmony_ci| Special cases of inf and NaNs are completed outside of decbin.
48362306a36Sopenharmony_ci| If the input is an snan, the snan bit is not set.
48462306a36Sopenharmony_ci|
48562306a36Sopenharmony_ci| input:
48662306a36Sopenharmony_ci|	ETEMP(a6)	- points to packed decimal string in memory
48762306a36Sopenharmony_ci| output:
48862306a36Sopenharmony_ci|	fp0	- contains packed string converted to extended precision
48962306a36Sopenharmony_ci|	ETEMP	- same as fp0
49062306a36Sopenharmony_ciunpack:
49162306a36Sopenharmony_ci	movew	CMDREG1B(%a6),%d0	|examine command word, looking for fmove's
49262306a36Sopenharmony_ci	andw	#0x3b,%d0
49362306a36Sopenharmony_ci	beq	move_unpack	|special handling for fmove: must set FPSR_CC
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	movew	ETEMP(%a6),%d0	|get word with inf information
49662306a36Sopenharmony_ci	bfextu	%d0{#20:#12},%d1	|get exponent into d1
49762306a36Sopenharmony_ci	cmpiw	#0x0fff,%d1	|test for inf or NaN
49862306a36Sopenharmony_ci	bnes	try_zero	|if not equal, it is not special
49962306a36Sopenharmony_ci	bfextu	%d0{#17:#3},%d1	|get SE and y bits into d1
50062306a36Sopenharmony_ci	cmpiw	#7,%d1		|SE and y bits must be on for special
50162306a36Sopenharmony_ci	bnes	try_zero	|if not on, it is not special
50262306a36Sopenharmony_ci|input is of the special cases of inf and NaN
50362306a36Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check ms mantissa
50462306a36Sopenharmony_ci	bnes	fix_nan		|if non-zero, it is a NaN
50562306a36Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check ls mantissa
50662306a36Sopenharmony_ci	bnes	fix_nan		|if non-zero, it is a NaN
50762306a36Sopenharmony_ci	bra	finish		|special already on stack
50862306a36Sopenharmony_cifix_nan:
50962306a36Sopenharmony_ci	btstb	#signan_bit,ETEMP_HI(%a6) |test for snan
51062306a36Sopenharmony_ci	bne	finish
51162306a36Sopenharmony_ci	orl	#snaniop_mask,USER_FPSR(%a6) |always set snan if it is so
51262306a36Sopenharmony_ci	bra	finish
51362306a36Sopenharmony_citry_zero:
51462306a36Sopenharmony_ci	movew	ETEMP_EX+2(%a6),%d0 |get word 4
51562306a36Sopenharmony_ci	andiw	#0x000f,%d0	|clear all but last ni(y)bble
51662306a36Sopenharmony_ci	tstw	%d0		|check for zero.
51762306a36Sopenharmony_ci	bne	not_spec
51862306a36Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check words 3 and 2
51962306a36Sopenharmony_ci	bne	not_spec
52062306a36Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check words 1 and 0
52162306a36Sopenharmony_ci	bne	not_spec
52262306a36Sopenharmony_ci	tstl	ETEMP(%a6)	|test sign of the zero
52362306a36Sopenharmony_ci	bges	pos_zero
52462306a36Sopenharmony_ci	movel	#0x80000000,ETEMP(%a6) |write neg zero to etemp
52562306a36Sopenharmony_ci	clrl	ETEMP_HI(%a6)
52662306a36Sopenharmony_ci	clrl	ETEMP_LO(%a6)
52762306a36Sopenharmony_ci	bra	finish
52862306a36Sopenharmony_cipos_zero:
52962306a36Sopenharmony_ci	clrl	ETEMP(%a6)
53062306a36Sopenharmony_ci	clrl	ETEMP_HI(%a6)
53162306a36Sopenharmony_ci	clrl	ETEMP_LO(%a6)
53262306a36Sopenharmony_ci	bra	finish
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_cinot_spec:
53562306a36Sopenharmony_ci	fmovemx %fp0-%fp1,-(%a7)	|save fp0 - decbin returns in it
53662306a36Sopenharmony_ci	bsr	decbin
53762306a36Sopenharmony_ci	fmovex %fp0,ETEMP(%a6)	|put the unpacked sop in the fsave stack
53862306a36Sopenharmony_ci	fmovemx (%a7)+,%fp0-%fp1
53962306a36Sopenharmony_ci	fmovel	#0,%FPSR		|clr fpsr from decbin
54062306a36Sopenharmony_ci	bra	finish
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci|
54362306a36Sopenharmony_ci| Special handling for packed move in:  Same results as all other
54462306a36Sopenharmony_ci| packed cases, but we must set the FPSR condition codes properly.
54562306a36Sopenharmony_ci|
54662306a36Sopenharmony_cimove_unpack:
54762306a36Sopenharmony_ci	movew	ETEMP(%a6),%d0	|get word with inf information
54862306a36Sopenharmony_ci	bfextu	%d0{#20:#12},%d1	|get exponent into d1
54962306a36Sopenharmony_ci	cmpiw	#0x0fff,%d1	|test for inf or NaN
55062306a36Sopenharmony_ci	bnes	mtry_zero	|if not equal, it is not special
55162306a36Sopenharmony_ci	bfextu	%d0{#17:#3},%d1	|get SE and y bits into d1
55262306a36Sopenharmony_ci	cmpiw	#7,%d1		|SE and y bits must be on for special
55362306a36Sopenharmony_ci	bnes	mtry_zero	|if not on, it is not special
55462306a36Sopenharmony_ci|input is of the special cases of inf and NaN
55562306a36Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check ms mantissa
55662306a36Sopenharmony_ci	bnes	mfix_nan		|if non-zero, it is a NaN
55762306a36Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check ls mantissa
55862306a36Sopenharmony_ci	bnes	mfix_nan		|if non-zero, it is a NaN
55962306a36Sopenharmony_ci|input is inf
56062306a36Sopenharmony_ci	orl	#inf_mask,USER_FPSR(%a6) |set I bit
56162306a36Sopenharmony_ci	tstl	ETEMP(%a6)	|check sign
56262306a36Sopenharmony_ci	bge	finish
56362306a36Sopenharmony_ci	orl	#neg_mask,USER_FPSR(%a6) |set N bit
56462306a36Sopenharmony_ci	bra	finish		|special already on stack
56562306a36Sopenharmony_cimfix_nan:
56662306a36Sopenharmony_ci	orl	#nan_mask,USER_FPSR(%a6) |set NaN bit
56762306a36Sopenharmony_ci	moveb	#nan_tag,STAG(%a6)	|set stag to NaN
56862306a36Sopenharmony_ci	btstb	#signan_bit,ETEMP_HI(%a6) |test for snan
56962306a36Sopenharmony_ci	bnes	mn_snan
57062306a36Sopenharmony_ci	orl	#snaniop_mask,USER_FPSR(%a6) |set snan bit
57162306a36Sopenharmony_ci	btstb	#snan_bit,FPCR_ENABLE(%a6) |test for snan enabled
57262306a36Sopenharmony_ci	bnes	mn_snan
57362306a36Sopenharmony_ci	bsetb	#signan_bit,ETEMP_HI(%a6) |force snans to qnans
57462306a36Sopenharmony_cimn_snan:
57562306a36Sopenharmony_ci	tstl	ETEMP(%a6)	|check for sign
57662306a36Sopenharmony_ci	bge	finish		|if clr, go on
57762306a36Sopenharmony_ci	orl	#neg_mask,USER_FPSR(%a6) |set N bit
57862306a36Sopenharmony_ci	bra	finish
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_cimtry_zero:
58162306a36Sopenharmony_ci	movew	ETEMP_EX+2(%a6),%d0 |get word 4
58262306a36Sopenharmony_ci	andiw	#0x000f,%d0	|clear all but last ni(y)bble
58362306a36Sopenharmony_ci	tstw	%d0		|check for zero.
58462306a36Sopenharmony_ci	bnes	mnot_spec
58562306a36Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check words 3 and 2
58662306a36Sopenharmony_ci	bnes	mnot_spec
58762306a36Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check words 1 and 0
58862306a36Sopenharmony_ci	bnes	mnot_spec
58962306a36Sopenharmony_ci	tstl	ETEMP(%a6)	|test sign of the zero
59062306a36Sopenharmony_ci	bges	mpos_zero
59162306a36Sopenharmony_ci	orl	#neg_mask+z_mask,USER_FPSR(%a6) |set N and Z
59262306a36Sopenharmony_ci	movel	#0x80000000,ETEMP(%a6) |write neg zero to etemp
59362306a36Sopenharmony_ci	clrl	ETEMP_HI(%a6)
59462306a36Sopenharmony_ci	clrl	ETEMP_LO(%a6)
59562306a36Sopenharmony_ci	bras	finish
59662306a36Sopenharmony_cimpos_zero:
59762306a36Sopenharmony_ci	orl	#z_mask,USER_FPSR(%a6) |set Z
59862306a36Sopenharmony_ci	clrl	ETEMP(%a6)
59962306a36Sopenharmony_ci	clrl	ETEMP_HI(%a6)
60062306a36Sopenharmony_ci	clrl	ETEMP_LO(%a6)
60162306a36Sopenharmony_ci	bras	finish
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_cimnot_spec:
60462306a36Sopenharmony_ci	fmovemx %fp0-%fp1,-(%a7)	|save fp0 ,fp1 - decbin returns in fp0
60562306a36Sopenharmony_ci	bsr	decbin
60662306a36Sopenharmony_ci	fmovex %fp0,ETEMP(%a6)
60762306a36Sopenharmony_ci|				;put the unpacked sop in the fsave stack
60862306a36Sopenharmony_ci	fmovemx (%a7)+,%fp0-%fp1
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_cifinish:
61162306a36Sopenharmony_ci	movew	CMDREG1B(%a6),%d0	|get the command word
61262306a36Sopenharmony_ci	andw	#0xfbff,%d0	|change the source specifier field to
61362306a36Sopenharmony_ci|				;extended (was packed).
61462306a36Sopenharmony_ci	movew	%d0,CMDREG1B(%a6)	|write command word back to fsave stack
61562306a36Sopenharmony_ci|				;we need to do this so the 040 will
61662306a36Sopenharmony_ci|				;re-execute the inst. without taking
61762306a36Sopenharmony_ci|				;another packed trap.
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_cifix_stag:
62062306a36Sopenharmony_ci|Converted result is now in etemp on fsave stack, now set the source
62162306a36Sopenharmony_ci|tag (stag)
62262306a36Sopenharmony_ci|	if (ete =$7fff) then INF or NAN
62362306a36Sopenharmony_ci|		if (etemp = $x.0----0) then
62462306a36Sopenharmony_ci|			stag = INF
62562306a36Sopenharmony_ci|		else
62662306a36Sopenharmony_ci|			stag = NAN
62762306a36Sopenharmony_ci|	else
62862306a36Sopenharmony_ci|		if (ete = $0000) then
62962306a36Sopenharmony_ci|			stag = ZERO
63062306a36Sopenharmony_ci|		else
63162306a36Sopenharmony_ci|			stag = NORM
63262306a36Sopenharmony_ci|
63362306a36Sopenharmony_ci| Note also that the etemp_15 bit (just right of the stag) must
63462306a36Sopenharmony_ci| be set accordingly.
63562306a36Sopenharmony_ci|
63662306a36Sopenharmony_ci	movew		ETEMP_EX(%a6),%d1
63762306a36Sopenharmony_ci	andiw		#0x7fff,%d1   |strip sign
63862306a36Sopenharmony_ci	cmpw		#0x7fff,%d1
63962306a36Sopenharmony_ci	bnes		z_or_nrm
64062306a36Sopenharmony_ci	movel		ETEMP_HI(%a6),%d1
64162306a36Sopenharmony_ci	bnes		is_nan
64262306a36Sopenharmony_ci	movel		ETEMP_LO(%a6),%d1
64362306a36Sopenharmony_ci	bnes		is_nan
64462306a36Sopenharmony_ciis_inf:
64562306a36Sopenharmony_ci	moveb		#0x40,STAG(%a6)
64662306a36Sopenharmony_ci	movel		#0x40,%d0
64762306a36Sopenharmony_ci	rts
64862306a36Sopenharmony_ciis_nan:
64962306a36Sopenharmony_ci	moveb		#0x60,STAG(%a6)
65062306a36Sopenharmony_ci	movel		#0x60,%d0
65162306a36Sopenharmony_ci	rts
65262306a36Sopenharmony_ciz_or_nrm:
65362306a36Sopenharmony_ci	tstw		%d1
65462306a36Sopenharmony_ci	bnes		is_nrm
65562306a36Sopenharmony_ciis_zro:
65662306a36Sopenharmony_ci| For a zero, set etemp_15
65762306a36Sopenharmony_ci	moveb		#0x30,STAG(%a6)
65862306a36Sopenharmony_ci	movel		#0x20,%d0
65962306a36Sopenharmony_ci	rts
66062306a36Sopenharmony_ciis_nrm:
66162306a36Sopenharmony_ci| For a norm, check if the exp <= $3fff; if so, set etemp_15
66262306a36Sopenharmony_ci	cmpiw		#0x3fff,%d1
66362306a36Sopenharmony_ci	bles		set_bit15
66462306a36Sopenharmony_ci	moveb		#0,STAG(%a6)
66562306a36Sopenharmony_ci	bras		end_is_nrm
66662306a36Sopenharmony_ciset_bit15:
66762306a36Sopenharmony_ci	moveb		#0x10,STAG(%a6)
66862306a36Sopenharmony_ciend_is_nrm:
66962306a36Sopenharmony_ci	movel		#0,%d0
67062306a36Sopenharmony_ciend_fix:
67162306a36Sopenharmony_ci	rts
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ciend_get:
67462306a36Sopenharmony_ci	rts
67562306a36Sopenharmony_ci	|end
676