18c2ecf20Sopenharmony_ci|
28c2ecf20Sopenharmony_ci|	get_op.sa 3.6 5/19/92
38c2ecf20Sopenharmony_ci|
48c2ecf20Sopenharmony_ci|	get_op.sa 3.5 4/26/91
58c2ecf20Sopenharmony_ci|
68c2ecf20Sopenharmony_ci|  Description: This routine is called by the unsupported format/data
78c2ecf20Sopenharmony_ci| type exception handler ('unsupp' - vector 55) and the unimplemented
88c2ecf20Sopenharmony_ci| instruction exception handler ('unimp' - vector 11).  'get_op'
98c2ecf20Sopenharmony_ci| determines the opclass (0, 2, or 3) and branches to the
108c2ecf20Sopenharmony_ci| opclass handler routine.  See 68881/2 User's Manual table 4-11
118c2ecf20Sopenharmony_ci| for a description of the opclasses.
128c2ecf20Sopenharmony_ci|
138c2ecf20Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) and for
148c2ecf20Sopenharmony_ci| UNIMPLEMENTED instructions (exception vector 11) the following
158c2ecf20Sopenharmony_ci| applies:
168c2ecf20Sopenharmony_ci|
178c2ecf20Sopenharmony_ci| - For unnormalized numbers (opclass 0, 2, or 3) the
188c2ecf20Sopenharmony_ci| number(s) is normalized and the operand type tag is updated.
198c2ecf20Sopenharmony_ci|
208c2ecf20Sopenharmony_ci| - For a packed number (opclass 2) the number is unpacked and the
218c2ecf20Sopenharmony_ci| operand type tag is updated.
228c2ecf20Sopenharmony_ci|
238c2ecf20Sopenharmony_ci| - For denormalized numbers (opclass 0 or 2) the number(s) is not
248c2ecf20Sopenharmony_ci| changed but passed to the next module.  The next module for
258c2ecf20Sopenharmony_ci| unimp is do_func, the next module for unsupp is res_func.
268c2ecf20Sopenharmony_ci|
278c2ecf20Sopenharmony_ci| For UNSUPPORTED data/format (exception vector 55) only the
288c2ecf20Sopenharmony_ci| following applies:
298c2ecf20Sopenharmony_ci|
308c2ecf20Sopenharmony_ci| - If there is a move out with a packed number (opclass 3) the
318c2ecf20Sopenharmony_ci| number is packed and written to user memory.  For the other
328c2ecf20Sopenharmony_ci| opclasses the number(s) are written back to the fsave stack
338c2ecf20Sopenharmony_ci| and the instruction is then restored back into the '040.  The
348c2ecf20Sopenharmony_ci| '040 is then able to complete the instruction.
358c2ecf20Sopenharmony_ci|
368c2ecf20Sopenharmony_ci| For example:
378c2ecf20Sopenharmony_ci| fadd.x fpm,fpn where the fpm contains an unnormalized number.
388c2ecf20Sopenharmony_ci| The '040 takes an unsupported data trap and gets to this
398c2ecf20Sopenharmony_ci| routine.  The number is normalized, put back on the stack and
408c2ecf20Sopenharmony_ci| then an frestore is done to restore the instruction back into
418c2ecf20Sopenharmony_ci| the '040.  The '040 then re-executes the fadd.x fpm,fpn with
428c2ecf20Sopenharmony_ci| a normalized number in the source and the instruction is
438c2ecf20Sopenharmony_ci| successful.
448c2ecf20Sopenharmony_ci|
458c2ecf20Sopenharmony_ci| Next consider if in the process of normalizing the un-
468c2ecf20Sopenharmony_ci| normalized number it becomes a denormalized number.  The
478c2ecf20Sopenharmony_ci| routine which converts the unnorm to a norm (called mk_norm)
488c2ecf20Sopenharmony_ci| detects this and tags the number as a denorm.  The routine
498c2ecf20Sopenharmony_ci| res_func sees the denorm tag and converts the denorm to a
508c2ecf20Sopenharmony_ci| norm.  The instruction is then restored back into the '040
518c2ecf20Sopenharmony_ci| which re_executes the instruction.
528c2ecf20Sopenharmony_ci|
538c2ecf20Sopenharmony_ci|
548c2ecf20Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
558c2ecf20Sopenharmony_ci|			All Rights Reserved
568c2ecf20Sopenharmony_ci|
578c2ecf20Sopenharmony_ci|       For details on the license for this file, please see the
588c2ecf20Sopenharmony_ci|       file, README, in this same directory.
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciGET_OP:    |idnt    2,1 | Motorola 040 Floating Point Software Package
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	|section	8
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#include "fpsp.h"
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	.global	PIRN,PIRZRM,PIRP
678c2ecf20Sopenharmony_ci	.global	SMALRN,SMALRZRM,SMALRP
688c2ecf20Sopenharmony_ci	.global	BIGRN,BIGRZRM,BIGRP
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciPIRN:
718c2ecf20Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c235    |pi
728c2ecf20Sopenharmony_ciPIRZRM:
738c2ecf20Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c234    |pi
748c2ecf20Sopenharmony_ciPIRP:
758c2ecf20Sopenharmony_ci	.long 0x40000000,0xc90fdaa2,0x2168c235    |pi
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci|round to nearest
788c2ecf20Sopenharmony_ciSMALRN:
798c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff798    |log10(2)
808c2ecf20Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9a    |e
818c2ecf20Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    |log2(e)
828c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
838c2ecf20Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
848c2ecf20Sopenharmony_ci| round to zero;round to negative infinity
858c2ecf20Sopenharmony_ciSMALRZRM:
868c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff798    |log10(2)
878c2ecf20Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9a    |e
888c2ecf20Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bb    |log2(e)
898c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
908c2ecf20Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
918c2ecf20Sopenharmony_ci| round to positive infinity
928c2ecf20Sopenharmony_ciSMALRP:
938c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0x9a209a84,0xfbcff799    |log10(2)
948c2ecf20Sopenharmony_ci	.long 0x40000000,0xadf85458,0xa2bb4a9b    |e
958c2ecf20Sopenharmony_ci	.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    |log2(e)
968c2ecf20Sopenharmony_ci	.long 0x3ffd0000,0xde5bd8a9,0x37287195    |log10(e)
978c2ecf20Sopenharmony_ci	.long 0x00000000,0x00000000,0x00000000    |0.0
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci|round to nearest
1008c2ecf20Sopenharmony_ciBIGRN:
1018c2ecf20Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ac    |ln(2)
1028c2ecf20Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac17    |ln(10)
1038c2ecf20Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	.global	PTENRN
1068c2ecf20Sopenharmony_ciPTENRN:
1078c2ecf20Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
1088c2ecf20Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
1098c2ecf20Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
1108c2ecf20Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
1118c2ecf20Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
1128c2ecf20Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59E    |10 ^ 32
1138c2ecf20Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D5    |10 ^ 64
1148c2ecf20Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CE0    |10 ^ 128
1158c2ecf20Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    |10 ^ 256
1168c2ecf20Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C7    |10 ^ 512
1178c2ecf20Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C17    |10 ^ 1024
1188c2ecf20Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    |10 ^ 2048
1198c2ecf20Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979B    |10 ^ 4096
1208c2ecf20Sopenharmony_ci|round to minus infinity
1218c2ecf20Sopenharmony_ciBIGRZRM:
1228c2ecf20Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ab    |ln(2)
1238c2ecf20Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac16    |ln(10)
1248c2ecf20Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	.global	PTENRM
1278c2ecf20Sopenharmony_ciPTENRM:
1288c2ecf20Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
1298c2ecf20Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
1308c2ecf20Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
1318c2ecf20Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
1328c2ecf20Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
1338c2ecf20Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59D    |10 ^ 32
1348c2ecf20Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D5    |10 ^ 64
1358c2ecf20Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CDF    |10 ^ 128
1368c2ecf20Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8D    |10 ^ 256
1378c2ecf20Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C6    |10 ^ 512
1388c2ecf20Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C17    |10 ^ 1024
1398c2ecf20Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    |10 ^ 2048
1408c2ecf20Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979A    |10 ^ 4096
1418c2ecf20Sopenharmony_ci|round to positive infinity
1428c2ecf20Sopenharmony_ciBIGRP:
1438c2ecf20Sopenharmony_ci	.long 0x3ffe0000,0xb17217f7,0xd1cf79ac    |ln(2)
1448c2ecf20Sopenharmony_ci	.long 0x40000000,0x935d8ddd,0xaaa8ac17    |ln(10)
1458c2ecf20Sopenharmony_ci	.long 0x3fff0000,0x80000000,0x00000000    |10 ^ 0
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	.global	PTENRP
1488c2ecf20Sopenharmony_ciPTENRP:
1498c2ecf20Sopenharmony_ci	.long 0x40020000,0xA0000000,0x00000000    |10 ^ 1
1508c2ecf20Sopenharmony_ci	.long 0x40050000,0xC8000000,0x00000000    |10 ^ 2
1518c2ecf20Sopenharmony_ci	.long 0x400C0000,0x9C400000,0x00000000    |10 ^ 4
1528c2ecf20Sopenharmony_ci	.long 0x40190000,0xBEBC2000,0x00000000    |10 ^ 8
1538c2ecf20Sopenharmony_ci	.long 0x40340000,0x8E1BC9BF,0x04000000    |10 ^ 16
1548c2ecf20Sopenharmony_ci	.long 0x40690000,0x9DC5ADA8,0x2B70B59E    |10 ^ 32
1558c2ecf20Sopenharmony_ci	.long 0x40D30000,0xC2781F49,0xFFCFA6D6    |10 ^ 64
1568c2ecf20Sopenharmony_ci	.long 0x41A80000,0x93BA47C9,0x80E98CE0    |10 ^ 128
1578c2ecf20Sopenharmony_ci	.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    |10 ^ 256
1588c2ecf20Sopenharmony_ci	.long 0x46A30000,0xE319A0AE,0xA60E91C7    |10 ^ 512
1598c2ecf20Sopenharmony_ci	.long 0x4D480000,0xC9767586,0x81750C18    |10 ^ 1024
1608c2ecf20Sopenharmony_ci	.long 0x5A920000,0x9E8B3B5D,0xC53D5DE6    |10 ^ 2048
1618c2ecf20Sopenharmony_ci	.long 0x75250000,0xC4605202,0x8A20979B    |10 ^ 4096
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	|xref	nrm_zero
1648c2ecf20Sopenharmony_ci	|xref	decbin
1658c2ecf20Sopenharmony_ci	|xref	round
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	.global    get_op
1688c2ecf20Sopenharmony_ci	.global    uns_getop
1698c2ecf20Sopenharmony_ci	.global    uni_getop
1708c2ecf20Sopenharmony_ciget_op:
1718c2ecf20Sopenharmony_ci	clrb	DY_MO_FLG(%a6)
1728c2ecf20Sopenharmony_ci	tstb	UFLG_TMP(%a6)	|test flag for unsupp/unimp state
1738c2ecf20Sopenharmony_ci	beq	uni_getop
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciuns_getop:
1768c2ecf20Sopenharmony_ci	btstb	#direction_bit,CMDREG1B(%a6)
1778c2ecf20Sopenharmony_ci	bne	opclass3	|branch if a fmove out (any kind)
1788c2ecf20Sopenharmony_ci	btstb	#6,CMDREG1B(%a6)
1798c2ecf20Sopenharmony_ci	beqs	uns_notpacked
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	bfextu	CMDREG1B(%a6){#3:#3},%d0
1828c2ecf20Sopenharmony_ci	cmpb	#3,%d0
1838c2ecf20Sopenharmony_ci	beq	pack_source	|check for a packed src op, branch if so
1848c2ecf20Sopenharmony_ciuns_notpacked:
1858c2ecf20Sopenharmony_ci	bsr	chk_dy_mo	|set the dyadic/monadic flag
1868c2ecf20Sopenharmony_ci	tstb	DY_MO_FLG(%a6)
1878c2ecf20Sopenharmony_ci	beqs	src_op_ck	|if monadic, go check src op
1888c2ecf20Sopenharmony_ci|				;else, check dst op (fall through)
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	btstb	#7,DTAG(%a6)
1918c2ecf20Sopenharmony_ci	beqs	src_op_ck	|if dst op is norm, check src op
1928c2ecf20Sopenharmony_ci	bras	dst_ex_dnrm	|else, handle destination unnorm/dnrm
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ciuni_getop:
1958c2ecf20Sopenharmony_ci	bfextu	CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
1968c2ecf20Sopenharmony_ci	cmpil	#0x17,%d0		|if op class and size fields are $17,
1978c2ecf20Sopenharmony_ci|				;it is FMOVECR; if not, continue
1988c2ecf20Sopenharmony_ci|
1998c2ecf20Sopenharmony_ci| If the instruction is fmovecr, exit get_op.  It is handled
2008c2ecf20Sopenharmony_ci| in do_func and smovecr.sa.
2018c2ecf20Sopenharmony_ci|
2028c2ecf20Sopenharmony_ci	bne	not_fmovecr	|handle fmovecr as an unimplemented inst
2038c2ecf20Sopenharmony_ci	rts
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cinot_fmovecr:
2068c2ecf20Sopenharmony_ci	btstb	#E1,E_BYTE(%a6)	|if set, there is a packed operand
2078c2ecf20Sopenharmony_ci	bne	pack_source	|check for packed src op, branch if so
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci| The following lines of are coded to optimize on normalized operands
2108c2ecf20Sopenharmony_ci	moveb	STAG(%a6),%d0
2118c2ecf20Sopenharmony_ci	orb	DTAG(%a6),%d0	|check if either of STAG/DTAG msb set
2128c2ecf20Sopenharmony_ci	bmis	dest_op_ck	|if so, some op needs to be fixed
2138c2ecf20Sopenharmony_ci	rts
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cidest_op_ck:
2168c2ecf20Sopenharmony_ci	btstb	#7,DTAG(%a6)	|check for unsupported data types in
2178c2ecf20Sopenharmony_ci	beqs	src_op_ck	|the destination, if not, check src op
2188c2ecf20Sopenharmony_ci	bsr	chk_dy_mo	|set dyadic/monadic flag
2198c2ecf20Sopenharmony_ci	tstb	DY_MO_FLG(%a6)	|
2208c2ecf20Sopenharmony_ci	beqs	src_op_ck	|if monadic, check src op
2218c2ecf20Sopenharmony_ci|
2228c2ecf20Sopenharmony_ci| At this point, destination has an extended denorm or unnorm.
2238c2ecf20Sopenharmony_ci|
2248c2ecf20Sopenharmony_cidst_ex_dnrm:
2258c2ecf20Sopenharmony_ci	movew	FPTEMP_EX(%a6),%d0 |get destination exponent
2268c2ecf20Sopenharmony_ci	andiw	#0x7fff,%d0	|mask sign, check if exp = 0000
2278c2ecf20Sopenharmony_ci	beqs	src_op_ck	|if denorm then check source op.
2288c2ecf20Sopenharmony_ci|				;denorms are taken care of in res_func
2298c2ecf20Sopenharmony_ci|				;(unsupp) or do_func (unimp)
2308c2ecf20Sopenharmony_ci|				;else unnorm fall through
2318c2ecf20Sopenharmony_ci	leal	FPTEMP(%a6),%a0	|point a0 to dop - used in mk_norm
2328c2ecf20Sopenharmony_ci	bsr	mk_norm		|go normalize - mk_norm returns:
2338c2ecf20Sopenharmony_ci|				;L_SCR1{7:5} = operand tag
2348c2ecf20Sopenharmony_ci|				;	(000 = norm, 100 = denorm)
2358c2ecf20Sopenharmony_ci|				;L_SCR1{4} = fpte15 or ete15
2368c2ecf20Sopenharmony_ci|				;	0 = exp >  $3fff
2378c2ecf20Sopenharmony_ci|				;	1 = exp <= $3fff
2388c2ecf20Sopenharmony_ci|				;and puts the normalized num back
2398c2ecf20Sopenharmony_ci|				;on the fsave stack
2408c2ecf20Sopenharmony_ci|
2418c2ecf20Sopenharmony_ci	moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15
2428c2ecf20Sopenharmony_ci|				;to the fsave stack and fall
2438c2ecf20Sopenharmony_ci|				;through to check source operand
2448c2ecf20Sopenharmony_ci|
2458c2ecf20Sopenharmony_cisrc_op_ck:
2468c2ecf20Sopenharmony_ci	btstb	#7,STAG(%a6)
2478c2ecf20Sopenharmony_ci	beq	end_getop	|check for unsupported data types on the
2488c2ecf20Sopenharmony_ci|				;source operand
2498c2ecf20Sopenharmony_ci	btstb	#5,STAG(%a6)
2508c2ecf20Sopenharmony_ci	bnes	src_sd_dnrm	|if bit 5 set, handle sgl/dbl denorms
2518c2ecf20Sopenharmony_ci|
2528c2ecf20Sopenharmony_ci| At this point only unnorms or extended denorms are possible.
2538c2ecf20Sopenharmony_ci|
2548c2ecf20Sopenharmony_cisrc_ex_dnrm:
2558c2ecf20Sopenharmony_ci	movew	ETEMP_EX(%a6),%d0 |get source exponent
2568c2ecf20Sopenharmony_ci	andiw	#0x7fff,%d0	|mask sign, check if exp = 0000
2578c2ecf20Sopenharmony_ci	beq	end_getop	|if denorm then exit, denorms are
2588c2ecf20Sopenharmony_ci|				;handled in do_func
2598c2ecf20Sopenharmony_ci	leal	ETEMP(%a6),%a0	|point a0 to sop - used in mk_norm
2608c2ecf20Sopenharmony_ci	bsr	mk_norm		|go normalize - mk_norm returns:
2618c2ecf20Sopenharmony_ci|				;L_SCR1{7:5} = operand tag
2628c2ecf20Sopenharmony_ci|				;	(000 = norm, 100 = denorm)
2638c2ecf20Sopenharmony_ci|				;L_SCR1{4} = fpte15 or ete15
2648c2ecf20Sopenharmony_ci|				;	0 = exp >  $3fff
2658c2ecf20Sopenharmony_ci|				;	1 = exp <= $3fff
2668c2ecf20Sopenharmony_ci|				;and puts the normalized num back
2678c2ecf20Sopenharmony_ci|				;on the fsave stack
2688c2ecf20Sopenharmony_ci|
2698c2ecf20Sopenharmony_ci	moveb	L_SCR1(%a6),STAG(%a6) |write the new tag & ete15
2708c2ecf20Sopenharmony_ci	rts			|end_getop
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci|
2738c2ecf20Sopenharmony_ci| At this point, only single or double denorms are possible.
2748c2ecf20Sopenharmony_ci| If the inst is not fmove, normalize the source.  If it is,
2758c2ecf20Sopenharmony_ci| do nothing to the input.
2768c2ecf20Sopenharmony_ci|
2778c2ecf20Sopenharmony_cisrc_sd_dnrm:
2788c2ecf20Sopenharmony_ci	btstb	#4,CMDREG1B(%a6)	|differentiate between sgl/dbl denorm
2798c2ecf20Sopenharmony_ci	bnes	is_double
2808c2ecf20Sopenharmony_ciis_single:
2818c2ecf20Sopenharmony_ci	movew	#0x3f81,%d1	|write bias for sgl denorm
2828c2ecf20Sopenharmony_ci	bras	common		|goto the common code
2838c2ecf20Sopenharmony_ciis_double:
2848c2ecf20Sopenharmony_ci	movew	#0x3c01,%d1	|write the bias for a dbl denorm
2858c2ecf20Sopenharmony_cicommon:
2868c2ecf20Sopenharmony_ci	btstb	#sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa
2878c2ecf20Sopenharmony_ci	beqs	pos
2888c2ecf20Sopenharmony_ci	bset	#15,%d1		|set sign bit because it is negative
2898c2ecf20Sopenharmony_cipos:
2908c2ecf20Sopenharmony_ci	movew	%d1,ETEMP_EX(%a6)
2918c2ecf20Sopenharmony_ci|				;put exponent on stack
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	movew	CMDREG1B(%a6),%d1
2948c2ecf20Sopenharmony_ci	andw	#0xe3ff,%d1	|clear out source specifier
2958c2ecf20Sopenharmony_ci	orw	#0x0800,%d1	|set source specifier to extended prec
2968c2ecf20Sopenharmony_ci	movew	%d1,CMDREG1B(%a6)	|write back to the command word in stack
2978c2ecf20Sopenharmony_ci|				;this is needed to fix unsupp data stack
2988c2ecf20Sopenharmony_ci	leal	ETEMP(%a6),%a0	|point a0 to sop
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	bsr	mk_norm		|convert sgl/dbl denorm to norm
3018c2ecf20Sopenharmony_ci	moveb	L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0
3028c2ecf20Sopenharmony_ci	rts			|end_getop
3038c2ecf20Sopenharmony_ci|
3048c2ecf20Sopenharmony_ci| At this point, the source is definitely packed, whether
3058c2ecf20Sopenharmony_ci| instruction is dyadic or monadic is still unknown
3068c2ecf20Sopenharmony_ci|
3078c2ecf20Sopenharmony_cipack_source:
3088c2ecf20Sopenharmony_ci	movel	FPTEMP_LO(%a6),ETEMP(%a6)	|write ms part of packed
3098c2ecf20Sopenharmony_ci|				;number to etemp slot
3108c2ecf20Sopenharmony_ci	bsr	chk_dy_mo	|set dyadic/monadic flag
3118c2ecf20Sopenharmony_ci	bsr	unpack
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	tstb	DY_MO_FLG(%a6)
3148c2ecf20Sopenharmony_ci	beqs	end_getop	|if monadic, exit
3158c2ecf20Sopenharmony_ci|				;else, fix FPTEMP
3168c2ecf20Sopenharmony_cipack_dya:
3178c2ecf20Sopenharmony_ci	bfextu	CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg
3188c2ecf20Sopenharmony_ci	movel	#7,%d1
3198c2ecf20Sopenharmony_ci	subl	%d0,%d1
3208c2ecf20Sopenharmony_ci	clrl	%d0
3218c2ecf20Sopenharmony_ci	bsetl	%d1,%d0		|set up d0 as a dynamic register mask
3228c2ecf20Sopenharmony_ci	fmovemx %d0,FPTEMP(%a6)	|write to FPTEMP
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	btstb	#7,DTAG(%a6)	|check dest tag for unnorm or denorm
3258c2ecf20Sopenharmony_ci	bne	dst_ex_dnrm	|else, handle the unnorm or ext denorm
3268c2ecf20Sopenharmony_ci|
3278c2ecf20Sopenharmony_ci| Dest is not denormalized.  Check for norm, and set fpte15
3288c2ecf20Sopenharmony_ci| accordingly.
3298c2ecf20Sopenharmony_ci|
3308c2ecf20Sopenharmony_ci	moveb	DTAG(%a6),%d0
3318c2ecf20Sopenharmony_ci	andib	#0xf0,%d0		|strip to only dtag:fpte15
3328c2ecf20Sopenharmony_ci	tstb	%d0		|check for normalized value
3338c2ecf20Sopenharmony_ci	bnes	end_getop	|if inf/nan/zero leave get_op
3348c2ecf20Sopenharmony_ci	movew	FPTEMP_EX(%a6),%d0
3358c2ecf20Sopenharmony_ci	andiw	#0x7fff,%d0
3368c2ecf20Sopenharmony_ci	cmpiw	#0x3fff,%d0	|check if fpte15 needs setting
3378c2ecf20Sopenharmony_ci	bges	end_getop	|if >= $3fff, leave fpte15=0
3388c2ecf20Sopenharmony_ci	orb	#0x10,DTAG(%a6)
3398c2ecf20Sopenharmony_ci	bras	end_getop
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci|
3428c2ecf20Sopenharmony_ci| At this point, it is either an fmoveout packed, unnorm or denorm
3438c2ecf20Sopenharmony_ci|
3448c2ecf20Sopenharmony_ciopclass3:
3458c2ecf20Sopenharmony_ci	clrb	DY_MO_FLG(%a6)	|set dyadic/monadic flag to monadic
3468c2ecf20Sopenharmony_ci	bfextu	CMDREG1B(%a6){#4:#2},%d0
3478c2ecf20Sopenharmony_ci	cmpib	#3,%d0
3488c2ecf20Sopenharmony_ci	bne	src_ex_dnrm	|if not equal, must be unnorm or denorm
3498c2ecf20Sopenharmony_ci|				;else it is a packed move out
3508c2ecf20Sopenharmony_ci|				;exit
3518c2ecf20Sopenharmony_ciend_getop:
3528c2ecf20Sopenharmony_ci	rts
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci|
3558c2ecf20Sopenharmony_ci| Sets the DY_MO_FLG correctly. This is used only on if it is an
3568c2ecf20Sopenharmony_ci| unsupported data type exception.  Set if dyadic.
3578c2ecf20Sopenharmony_ci|
3588c2ecf20Sopenharmony_cichk_dy_mo:
3598c2ecf20Sopenharmony_ci	movew	CMDREG1B(%a6),%d0
3608c2ecf20Sopenharmony_ci	btstl	#5,%d0		|testing extension command word
3618c2ecf20Sopenharmony_ci	beqs	set_mon		|if bit 5 = 0 then monadic
3628c2ecf20Sopenharmony_ci	btstl	#4,%d0		|know that bit 5 = 1
3638c2ecf20Sopenharmony_ci	beqs	set_dya		|if bit 4 = 0 then dyadic
3648c2ecf20Sopenharmony_ci	andiw	#0x007f,%d0	|get rid of all but extension bits {6:0}
3658c2ecf20Sopenharmony_ci	cmpiw	#0x0038,%d0	|if extension = $38 then fcmp (dyadic)
3668c2ecf20Sopenharmony_ci	bnes	set_mon
3678c2ecf20Sopenharmony_ciset_dya:
3688c2ecf20Sopenharmony_ci	st	DY_MO_FLG(%a6)	|set the inst flag type to dyadic
3698c2ecf20Sopenharmony_ci	rts
3708c2ecf20Sopenharmony_ciset_mon:
3718c2ecf20Sopenharmony_ci	clrb	DY_MO_FLG(%a6)	|set the inst flag type to monadic
3728c2ecf20Sopenharmony_ci	rts
3738c2ecf20Sopenharmony_ci|
3748c2ecf20Sopenharmony_ci|	MK_NORM
3758c2ecf20Sopenharmony_ci|
3768c2ecf20Sopenharmony_ci| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
3778c2ecf20Sopenharmony_ci| exception if denorm.
3788c2ecf20Sopenharmony_ci|
3798c2ecf20Sopenharmony_ci| CASE opclass 0x0 unsupp
3808c2ecf20Sopenharmony_ci|	mk_norm till msb set
3818c2ecf20Sopenharmony_ci|	set tag = norm
3828c2ecf20Sopenharmony_ci|
3838c2ecf20Sopenharmony_ci| CASE opclass 0x0 unimp
3848c2ecf20Sopenharmony_ci|	mk_norm till msb set or exp = 0
3858c2ecf20Sopenharmony_ci|	if integer bit = 0
3868c2ecf20Sopenharmony_ci|	   tag = denorm
3878c2ecf20Sopenharmony_ci|	else
3888c2ecf20Sopenharmony_ci|	   tag = norm
3898c2ecf20Sopenharmony_ci|
3908c2ecf20Sopenharmony_ci| CASE opclass 011 unsupp
3918c2ecf20Sopenharmony_ci|	mk_norm till msb set or exp = 0
3928c2ecf20Sopenharmony_ci|	if integer bit = 0
3938c2ecf20Sopenharmony_ci|	   tag = denorm
3948c2ecf20Sopenharmony_ci|	   set unfl_nmcexe = 1
3958c2ecf20Sopenharmony_ci|	else
3968c2ecf20Sopenharmony_ci|	   tag = norm
3978c2ecf20Sopenharmony_ci|
3988c2ecf20Sopenharmony_ci| if exp <= $3fff
3998c2ecf20Sopenharmony_ci|   set ete15 or fpte15 = 1
4008c2ecf20Sopenharmony_ci| else set ete15 or fpte15 = 0
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci| input:
4038c2ecf20Sopenharmony_ci|	a0 = points to operand to be normalized
4048c2ecf20Sopenharmony_ci| output:
4058c2ecf20Sopenharmony_ci|	L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
4068c2ecf20Sopenharmony_ci|	L_SCR1{4}   = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
4078c2ecf20Sopenharmony_ci|	the normalized operand is placed back on the fsave stack
4088c2ecf20Sopenharmony_cimk_norm:
4098c2ecf20Sopenharmony_ci	clrl	L_SCR1(%a6)
4108c2ecf20Sopenharmony_ci	bclrb	#sign_bit,LOCAL_EX(%a0)
4118c2ecf20Sopenharmony_ci	sne	LOCAL_SGN(%a0)	|transform into internal extended format
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	cmpib	#0x2c,1+EXC_VEC(%a6) |check if unimp
4148c2ecf20Sopenharmony_ci	bnes	uns_data	|branch if unsupp
4158c2ecf20Sopenharmony_ci	bsr	uni_inst	|call if unimp (opclass 0x0)
4168c2ecf20Sopenharmony_ci	bras	reload
4178c2ecf20Sopenharmony_ciuns_data:
4188c2ecf20Sopenharmony_ci	btstb	#direction_bit,CMDREG1B(%a6) |check transfer direction
4198c2ecf20Sopenharmony_ci	bnes	bit_set		|branch if set (opclass 011)
4208c2ecf20Sopenharmony_ci	bsr	uns_opx		|call if opclass 0x0
4218c2ecf20Sopenharmony_ci	bras	reload
4228c2ecf20Sopenharmony_cibit_set:
4238c2ecf20Sopenharmony_ci	bsr	uns_op3		|opclass 011
4248c2ecf20Sopenharmony_cireload:
4258c2ecf20Sopenharmony_ci	cmpw	#0x3fff,LOCAL_EX(%a0) |if exp > $3fff
4268c2ecf20Sopenharmony_ci	bgts	end_mk		|   fpte15/ete15 already set to 0
4278c2ecf20Sopenharmony_ci	bsetb	#4,L_SCR1(%a6)	|else set fpte15/ete15 to 1
4288c2ecf20Sopenharmony_ci|				;calling routine actually sets the
4298c2ecf20Sopenharmony_ci|				;value on the stack (along with the
4308c2ecf20Sopenharmony_ci|				;tag), since this routine doesn't
4318c2ecf20Sopenharmony_ci|				;know if it should set ete15 or fpte15
4328c2ecf20Sopenharmony_ci|				;ie, it doesn't know if this is the
4338c2ecf20Sopenharmony_ci|				;src op or dest op.
4348c2ecf20Sopenharmony_ciend_mk:
4358c2ecf20Sopenharmony_ci	bfclr	LOCAL_SGN(%a0){#0:#8}
4368c2ecf20Sopenharmony_ci	beqs	end_mk_pos
4378c2ecf20Sopenharmony_ci	bsetb	#sign_bit,LOCAL_EX(%a0) |convert back to IEEE format
4388c2ecf20Sopenharmony_ciend_mk_pos:
4398c2ecf20Sopenharmony_ci	rts
4408c2ecf20Sopenharmony_ci|
4418c2ecf20Sopenharmony_ci|     CASE opclass 011 unsupp
4428c2ecf20Sopenharmony_ci|
4438c2ecf20Sopenharmony_ciuns_op3:
4448c2ecf20Sopenharmony_ci	bsr	nrm_zero	|normalize till msb = 1 or exp = zero
4458c2ecf20Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|if msb = 1
4468c2ecf20Sopenharmony_ci	bnes	no_unfl		|then branch
4478c2ecf20Sopenharmony_ciset_unfl:
4488c2ecf20Sopenharmony_ci	orw	#dnrm_tag,L_SCR1(%a6) |set denorm tag
4498c2ecf20Sopenharmony_ci	bsetb	#unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit
4508c2ecf20Sopenharmony_cino_unfl:
4518c2ecf20Sopenharmony_ci	rts
4528c2ecf20Sopenharmony_ci|
4538c2ecf20Sopenharmony_ci|     CASE opclass 0x0 unsupp
4548c2ecf20Sopenharmony_ci|
4558c2ecf20Sopenharmony_ciuns_opx:
4568c2ecf20Sopenharmony_ci	bsr	nrm_zero	|normalize the number
4578c2ecf20Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|check if integer bit (j-bit) is set
4588c2ecf20Sopenharmony_ci	beqs	uns_den		|if clear then now have a denorm
4598c2ecf20Sopenharmony_ciuns_nrm:
4608c2ecf20Sopenharmony_ci	orb	#norm_tag,L_SCR1(%a6) |set tag to norm
4618c2ecf20Sopenharmony_ci	rts
4628c2ecf20Sopenharmony_ciuns_den:
4638c2ecf20Sopenharmony_ci	orb	#dnrm_tag,L_SCR1(%a6) |set tag to denorm
4648c2ecf20Sopenharmony_ci	rts
4658c2ecf20Sopenharmony_ci|
4668c2ecf20Sopenharmony_ci|     CASE opclass 0x0 unimp
4678c2ecf20Sopenharmony_ci|
4688c2ecf20Sopenharmony_ciuni_inst:
4698c2ecf20Sopenharmony_ci	bsr	nrm_zero
4708c2ecf20Sopenharmony_ci	btstb	#7,LOCAL_HI(%a0)	|check if integer bit (j-bit) is set
4718c2ecf20Sopenharmony_ci	beqs	uni_den		|if clear then now have a denorm
4728c2ecf20Sopenharmony_ciuni_nrm:
4738c2ecf20Sopenharmony_ci	orb	#norm_tag,L_SCR1(%a6) |set tag to norm
4748c2ecf20Sopenharmony_ci	rts
4758c2ecf20Sopenharmony_ciuni_den:
4768c2ecf20Sopenharmony_ci	orb	#dnrm_tag,L_SCR1(%a6) |set tag to denorm
4778c2ecf20Sopenharmony_ci	rts
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci|
4808c2ecf20Sopenharmony_ci|	Decimal to binary conversion
4818c2ecf20Sopenharmony_ci|
4828c2ecf20Sopenharmony_ci| Special cases of inf and NaNs are completed outside of decbin.
4838c2ecf20Sopenharmony_ci| If the input is an snan, the snan bit is not set.
4848c2ecf20Sopenharmony_ci|
4858c2ecf20Sopenharmony_ci| input:
4868c2ecf20Sopenharmony_ci|	ETEMP(a6)	- points to packed decimal string in memory
4878c2ecf20Sopenharmony_ci| output:
4888c2ecf20Sopenharmony_ci|	fp0	- contains packed string converted to extended precision
4898c2ecf20Sopenharmony_ci|	ETEMP	- same as fp0
4908c2ecf20Sopenharmony_ciunpack:
4918c2ecf20Sopenharmony_ci	movew	CMDREG1B(%a6),%d0	|examine command word, looking for fmove's
4928c2ecf20Sopenharmony_ci	andw	#0x3b,%d0
4938c2ecf20Sopenharmony_ci	beq	move_unpack	|special handling for fmove: must set FPSR_CC
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	movew	ETEMP(%a6),%d0	|get word with inf information
4968c2ecf20Sopenharmony_ci	bfextu	%d0{#20:#12},%d1	|get exponent into d1
4978c2ecf20Sopenharmony_ci	cmpiw	#0x0fff,%d1	|test for inf or NaN
4988c2ecf20Sopenharmony_ci	bnes	try_zero	|if not equal, it is not special
4998c2ecf20Sopenharmony_ci	bfextu	%d0{#17:#3},%d1	|get SE and y bits into d1
5008c2ecf20Sopenharmony_ci	cmpiw	#7,%d1		|SE and y bits must be on for special
5018c2ecf20Sopenharmony_ci	bnes	try_zero	|if not on, it is not special
5028c2ecf20Sopenharmony_ci|input is of the special cases of inf and NaN
5038c2ecf20Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check ms mantissa
5048c2ecf20Sopenharmony_ci	bnes	fix_nan		|if non-zero, it is a NaN
5058c2ecf20Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check ls mantissa
5068c2ecf20Sopenharmony_ci	bnes	fix_nan		|if non-zero, it is a NaN
5078c2ecf20Sopenharmony_ci	bra	finish		|special already on stack
5088c2ecf20Sopenharmony_cifix_nan:
5098c2ecf20Sopenharmony_ci	btstb	#signan_bit,ETEMP_HI(%a6) |test for snan
5108c2ecf20Sopenharmony_ci	bne	finish
5118c2ecf20Sopenharmony_ci	orl	#snaniop_mask,USER_FPSR(%a6) |always set snan if it is so
5128c2ecf20Sopenharmony_ci	bra	finish
5138c2ecf20Sopenharmony_citry_zero:
5148c2ecf20Sopenharmony_ci	movew	ETEMP_EX+2(%a6),%d0 |get word 4
5158c2ecf20Sopenharmony_ci	andiw	#0x000f,%d0	|clear all but last ni(y)bble
5168c2ecf20Sopenharmony_ci	tstw	%d0		|check for zero.
5178c2ecf20Sopenharmony_ci	bne	not_spec
5188c2ecf20Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check words 3 and 2
5198c2ecf20Sopenharmony_ci	bne	not_spec
5208c2ecf20Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check words 1 and 0
5218c2ecf20Sopenharmony_ci	bne	not_spec
5228c2ecf20Sopenharmony_ci	tstl	ETEMP(%a6)	|test sign of the zero
5238c2ecf20Sopenharmony_ci	bges	pos_zero
5248c2ecf20Sopenharmony_ci	movel	#0x80000000,ETEMP(%a6) |write neg zero to etemp
5258c2ecf20Sopenharmony_ci	clrl	ETEMP_HI(%a6)
5268c2ecf20Sopenharmony_ci	clrl	ETEMP_LO(%a6)
5278c2ecf20Sopenharmony_ci	bra	finish
5288c2ecf20Sopenharmony_cipos_zero:
5298c2ecf20Sopenharmony_ci	clrl	ETEMP(%a6)
5308c2ecf20Sopenharmony_ci	clrl	ETEMP_HI(%a6)
5318c2ecf20Sopenharmony_ci	clrl	ETEMP_LO(%a6)
5328c2ecf20Sopenharmony_ci	bra	finish
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_cinot_spec:
5358c2ecf20Sopenharmony_ci	fmovemx %fp0-%fp1,-(%a7)	|save fp0 - decbin returns in it
5368c2ecf20Sopenharmony_ci	bsr	decbin
5378c2ecf20Sopenharmony_ci	fmovex %fp0,ETEMP(%a6)	|put the unpacked sop in the fsave stack
5388c2ecf20Sopenharmony_ci	fmovemx (%a7)+,%fp0-%fp1
5398c2ecf20Sopenharmony_ci	fmovel	#0,%FPSR		|clr fpsr from decbin
5408c2ecf20Sopenharmony_ci	bra	finish
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci|
5438c2ecf20Sopenharmony_ci| Special handling for packed move in:  Same results as all other
5448c2ecf20Sopenharmony_ci| packed cases, but we must set the FPSR condition codes properly.
5458c2ecf20Sopenharmony_ci|
5468c2ecf20Sopenharmony_cimove_unpack:
5478c2ecf20Sopenharmony_ci	movew	ETEMP(%a6),%d0	|get word with inf information
5488c2ecf20Sopenharmony_ci	bfextu	%d0{#20:#12},%d1	|get exponent into d1
5498c2ecf20Sopenharmony_ci	cmpiw	#0x0fff,%d1	|test for inf or NaN
5508c2ecf20Sopenharmony_ci	bnes	mtry_zero	|if not equal, it is not special
5518c2ecf20Sopenharmony_ci	bfextu	%d0{#17:#3},%d1	|get SE and y bits into d1
5528c2ecf20Sopenharmony_ci	cmpiw	#7,%d1		|SE and y bits must be on for special
5538c2ecf20Sopenharmony_ci	bnes	mtry_zero	|if not on, it is not special
5548c2ecf20Sopenharmony_ci|input is of the special cases of inf and NaN
5558c2ecf20Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check ms mantissa
5568c2ecf20Sopenharmony_ci	bnes	mfix_nan		|if non-zero, it is a NaN
5578c2ecf20Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check ls mantissa
5588c2ecf20Sopenharmony_ci	bnes	mfix_nan		|if non-zero, it is a NaN
5598c2ecf20Sopenharmony_ci|input is inf
5608c2ecf20Sopenharmony_ci	orl	#inf_mask,USER_FPSR(%a6) |set I bit
5618c2ecf20Sopenharmony_ci	tstl	ETEMP(%a6)	|check sign
5628c2ecf20Sopenharmony_ci	bge	finish
5638c2ecf20Sopenharmony_ci	orl	#neg_mask,USER_FPSR(%a6) |set N bit
5648c2ecf20Sopenharmony_ci	bra	finish		|special already on stack
5658c2ecf20Sopenharmony_cimfix_nan:
5668c2ecf20Sopenharmony_ci	orl	#nan_mask,USER_FPSR(%a6) |set NaN bit
5678c2ecf20Sopenharmony_ci	moveb	#nan_tag,STAG(%a6)	|set stag to NaN
5688c2ecf20Sopenharmony_ci	btstb	#signan_bit,ETEMP_HI(%a6) |test for snan
5698c2ecf20Sopenharmony_ci	bnes	mn_snan
5708c2ecf20Sopenharmony_ci	orl	#snaniop_mask,USER_FPSR(%a6) |set snan bit
5718c2ecf20Sopenharmony_ci	btstb	#snan_bit,FPCR_ENABLE(%a6) |test for snan enabled
5728c2ecf20Sopenharmony_ci	bnes	mn_snan
5738c2ecf20Sopenharmony_ci	bsetb	#signan_bit,ETEMP_HI(%a6) |force snans to qnans
5748c2ecf20Sopenharmony_cimn_snan:
5758c2ecf20Sopenharmony_ci	tstl	ETEMP(%a6)	|check for sign
5768c2ecf20Sopenharmony_ci	bge	finish		|if clr, go on
5778c2ecf20Sopenharmony_ci	orl	#neg_mask,USER_FPSR(%a6) |set N bit
5788c2ecf20Sopenharmony_ci	bra	finish
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_cimtry_zero:
5818c2ecf20Sopenharmony_ci	movew	ETEMP_EX+2(%a6),%d0 |get word 4
5828c2ecf20Sopenharmony_ci	andiw	#0x000f,%d0	|clear all but last ni(y)bble
5838c2ecf20Sopenharmony_ci	tstw	%d0		|check for zero.
5848c2ecf20Sopenharmony_ci	bnes	mnot_spec
5858c2ecf20Sopenharmony_ci	tstl	ETEMP_HI(%a6)	|check words 3 and 2
5868c2ecf20Sopenharmony_ci	bnes	mnot_spec
5878c2ecf20Sopenharmony_ci	tstl	ETEMP_LO(%a6)	|check words 1 and 0
5888c2ecf20Sopenharmony_ci	bnes	mnot_spec
5898c2ecf20Sopenharmony_ci	tstl	ETEMP(%a6)	|test sign of the zero
5908c2ecf20Sopenharmony_ci	bges	mpos_zero
5918c2ecf20Sopenharmony_ci	orl	#neg_mask+z_mask,USER_FPSR(%a6) |set N and Z
5928c2ecf20Sopenharmony_ci	movel	#0x80000000,ETEMP(%a6) |write neg zero to etemp
5938c2ecf20Sopenharmony_ci	clrl	ETEMP_HI(%a6)
5948c2ecf20Sopenharmony_ci	clrl	ETEMP_LO(%a6)
5958c2ecf20Sopenharmony_ci	bras	finish
5968c2ecf20Sopenharmony_cimpos_zero:
5978c2ecf20Sopenharmony_ci	orl	#z_mask,USER_FPSR(%a6) |set Z
5988c2ecf20Sopenharmony_ci	clrl	ETEMP(%a6)
5998c2ecf20Sopenharmony_ci	clrl	ETEMP_HI(%a6)
6008c2ecf20Sopenharmony_ci	clrl	ETEMP_LO(%a6)
6018c2ecf20Sopenharmony_ci	bras	finish
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_cimnot_spec:
6048c2ecf20Sopenharmony_ci	fmovemx %fp0-%fp1,-(%a7)	|save fp0 ,fp1 - decbin returns in fp0
6058c2ecf20Sopenharmony_ci	bsr	decbin
6068c2ecf20Sopenharmony_ci	fmovex %fp0,ETEMP(%a6)
6078c2ecf20Sopenharmony_ci|				;put the unpacked sop in the fsave stack
6088c2ecf20Sopenharmony_ci	fmovemx (%a7)+,%fp0-%fp1
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_cifinish:
6118c2ecf20Sopenharmony_ci	movew	CMDREG1B(%a6),%d0	|get the command word
6128c2ecf20Sopenharmony_ci	andw	#0xfbff,%d0	|change the source specifier field to
6138c2ecf20Sopenharmony_ci|				;extended (was packed).
6148c2ecf20Sopenharmony_ci	movew	%d0,CMDREG1B(%a6)	|write command word back to fsave stack
6158c2ecf20Sopenharmony_ci|				;we need to do this so the 040 will
6168c2ecf20Sopenharmony_ci|				;re-execute the inst. without taking
6178c2ecf20Sopenharmony_ci|				;another packed trap.
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_cifix_stag:
6208c2ecf20Sopenharmony_ci|Converted result is now in etemp on fsave stack, now set the source
6218c2ecf20Sopenharmony_ci|tag (stag)
6228c2ecf20Sopenharmony_ci|	if (ete =$7fff) then INF or NAN
6238c2ecf20Sopenharmony_ci|		if (etemp = $x.0----0) then
6248c2ecf20Sopenharmony_ci|			stag = INF
6258c2ecf20Sopenharmony_ci|		else
6268c2ecf20Sopenharmony_ci|			stag = NAN
6278c2ecf20Sopenharmony_ci|	else
6288c2ecf20Sopenharmony_ci|		if (ete = $0000) then
6298c2ecf20Sopenharmony_ci|			stag = ZERO
6308c2ecf20Sopenharmony_ci|		else
6318c2ecf20Sopenharmony_ci|			stag = NORM
6328c2ecf20Sopenharmony_ci|
6338c2ecf20Sopenharmony_ci| Note also that the etemp_15 bit (just right of the stag) must
6348c2ecf20Sopenharmony_ci| be set accordingly.
6358c2ecf20Sopenharmony_ci|
6368c2ecf20Sopenharmony_ci	movew		ETEMP_EX(%a6),%d1
6378c2ecf20Sopenharmony_ci	andiw		#0x7fff,%d1   |strip sign
6388c2ecf20Sopenharmony_ci	cmpw		#0x7fff,%d1
6398c2ecf20Sopenharmony_ci	bnes		z_or_nrm
6408c2ecf20Sopenharmony_ci	movel		ETEMP_HI(%a6),%d1
6418c2ecf20Sopenharmony_ci	bnes		is_nan
6428c2ecf20Sopenharmony_ci	movel		ETEMP_LO(%a6),%d1
6438c2ecf20Sopenharmony_ci	bnes		is_nan
6448c2ecf20Sopenharmony_ciis_inf:
6458c2ecf20Sopenharmony_ci	moveb		#0x40,STAG(%a6)
6468c2ecf20Sopenharmony_ci	movel		#0x40,%d0
6478c2ecf20Sopenharmony_ci	rts
6488c2ecf20Sopenharmony_ciis_nan:
6498c2ecf20Sopenharmony_ci	moveb		#0x60,STAG(%a6)
6508c2ecf20Sopenharmony_ci	movel		#0x60,%d0
6518c2ecf20Sopenharmony_ci	rts
6528c2ecf20Sopenharmony_ciz_or_nrm:
6538c2ecf20Sopenharmony_ci	tstw		%d1
6548c2ecf20Sopenharmony_ci	bnes		is_nrm
6558c2ecf20Sopenharmony_ciis_zro:
6568c2ecf20Sopenharmony_ci| For a zero, set etemp_15
6578c2ecf20Sopenharmony_ci	moveb		#0x30,STAG(%a6)
6588c2ecf20Sopenharmony_ci	movel		#0x20,%d0
6598c2ecf20Sopenharmony_ci	rts
6608c2ecf20Sopenharmony_ciis_nrm:
6618c2ecf20Sopenharmony_ci| For a norm, check if the exp <= $3fff; if so, set etemp_15
6628c2ecf20Sopenharmony_ci	cmpiw		#0x3fff,%d1
6638c2ecf20Sopenharmony_ci	bles		set_bit15
6648c2ecf20Sopenharmony_ci	moveb		#0,STAG(%a6)
6658c2ecf20Sopenharmony_ci	bras		end_is_nrm
6668c2ecf20Sopenharmony_ciset_bit15:
6678c2ecf20Sopenharmony_ci	moveb		#0x10,STAG(%a6)
6688c2ecf20Sopenharmony_ciend_is_nrm:
6698c2ecf20Sopenharmony_ci	movel		#0,%d0
6708c2ecf20Sopenharmony_ciend_fix:
6718c2ecf20Sopenharmony_ci	rts
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ciend_get:
6748c2ecf20Sopenharmony_ci	rts
6758c2ecf20Sopenharmony_ci	|end
676