get_op.sa revision 1.2
11.1Smycroft*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
21.1Smycroft*	M68000 Hi-Performance Microprocessor Division
31.1Smycroft*	M68040 Software Package 
41.1Smycroft*
51.1Smycroft*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
61.1Smycroft*	All rights reserved.
71.1Smycroft*
81.1Smycroft*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
91.1Smycroft*	To the maximum extent permitted by applicable law,
101.1Smycroft*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
111.1Smycroft*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
121.1Smycroft*	PARTICULAR PURPOSE and any warranty against infringement with
131.1Smycroft*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
141.1Smycroft*	and any accompanying written materials. 
151.1Smycroft*
161.1Smycroft*	To the maximum extent permitted by applicable law,
171.1Smycroft*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
181.1Smycroft*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
191.1Smycroft*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
201.1Smycroft*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
211.1Smycroft*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
221.1Smycroft*	and support of the SOFTWARE.  
231.1Smycroft*
241.1Smycroft*	You are hereby granted a copyright license to use, modify, and
251.1Smycroft*	distribute the SOFTWARE so long as this entire notice is retained
261.1Smycroft*	without alteration in any modified and/or redistributed versions,
271.1Smycroft*	and that such modified versions are clearly identified as such.
281.1Smycroft*	No licenses are granted by implication, estoppel or otherwise
291.1Smycroft*	under any patents or trademarks of Motorola, Inc.
301.1Smycroft
311.1Smycroft*
321.1Smycroft*	get_op.sa 3.6 5/19/92
331.1Smycroft*
341.1Smycroft*	get_op.sa 3.5 4/26/91
351.1Smycroft*
361.1Smycroft*  Description: This routine is called by the unsupported format/data
371.1Smycroft* type exception handler ('unsupp' - vector 55) and the unimplemented
381.1Smycroft* instruction exception handler ('unimp' - vector 11).  'get_op'
391.1Smycroft* determines the opclass (0, 2, or 3) and branches to the
401.1Smycroft* opclass handler routine.  See 68881/2 User's Manual table 4-11
411.1Smycroft* for a description of the opclasses.
421.1Smycroft*
431.1Smycroft* For UNSUPPORTED data/format (exception vector 55) and for
441.1Smycroft* UNIMPLEMENTED instructions (exception vector 11) the following
451.1Smycroft* applies:
461.1Smycroft*
471.1Smycroft* - For unnormormalized numbers (opclass 0, 2, or 3) the
481.1Smycroft* number(s) is normalized and the operand type tag is updated.
491.1Smycroft*		
501.1Smycroft* - For a packed number (opclass 2) the number is unpacked and the
511.1Smycroft* operand type tag is updated.
521.1Smycroft*
531.1Smycroft* - For denormalized numbers (opclass 0 or 2) the number(s) is not
541.1Smycroft* changed but passed to the next module.  The next module for
551.1Smycroft* unimp is do_func, the next module for unsupp is res_func.
561.1Smycroft*
571.1Smycroft* For UNSUPPORTED data/format (exception vector 55) only the
581.1Smycroft* following applies:
591.1Smycroft*
601.1Smycroft* - If there is a move out with a packed number (opclass 3) the
611.1Smycroft* number is packed and written to user memory.  For the other
621.1Smycroft* opclasses the number(s) are written back to the fsave stack
631.1Smycroft* and the instruction is then restored back into the '040.  The
641.1Smycroft* '040 is then able to complete the instruction.
651.1Smycroft*
661.1Smycroft* For example:
671.1Smycroft* fadd.x fpm,fpn where the fpm contains an unnormalized number.
681.1Smycroft* The '040 takes an unsupported data trap and gets to this
691.1Smycroft* routine.  The number is normalized, put back on the stack and
701.1Smycroft* then an frestore is done to restore the instruction back into
711.1Smycroft* the '040.  The '040 then re-executes the fadd.x fpm,fpn with
721.1Smycroft* a normalized number in the source and the instruction is
731.1Smycroft* successful.
741.1Smycroft*		
751.1Smycroft* Next consider if in the process of normalizing the un-
761.1Smycroft* normalized number it becomes a denormalized number.  The
771.1Smycroft* routine which converts the unnorm to a norm (called mk_norm)
781.1Smycroft* detects this and tags the number as a denorm.  The routine
791.1Smycroft* res_func sees the denorm tag and converts the denorm to a
801.1Smycroft* norm.  The instruction is then restored back into the '040
811.1Smycroft* which re_executess the instruction.
821.1Smycroft*
831.1Smycroft
841.1SmycroftGET_OP    IDNT    2,1 Motorola 040 Floating Point Software Package
851.1Smycroft
861.1Smycroft	section	8
871.1Smycroft
881.1Smycroft	include	fpsp.h
891.1Smycroft
901.1Smycroft	xdef	PIRN,PIRZRM,PIRP
911.1Smycroft	xdef	SMALRN,SMALRZRM,SMALRP
921.1Smycroft	xdef	BIGRN,BIGRZRM,BIGRP
931.1Smycroft
941.1SmycroftPIRN:
951.1Smycroft	dc.l $40000000,$c90fdaa2,$2168c235    ;pi
961.1SmycroftPIRZRM:
971.1Smycroft	dc.l $40000000,$c90fdaa2,$2168c234    ;pi
981.1SmycroftPIRP:
991.1Smycroft	dc.l $40000000,$c90fdaa2,$2168c235    ;pi
1001.1Smycroft
1011.1Smycroft*round to nearest
1021.1SmycroftSMALRN:
1031.1Smycroft	dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
1041.1Smycroft	dc.l $40000000,$adf85458,$a2bb4a9a    ;e
1051.1Smycroft	dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
1061.1Smycroft	dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
1071.1Smycroft	dc.l $00000000,$00000000,$00000000    ;0.0
1081.1Smycroft* round to zero;round to negative infinity
1091.1SmycroftSMALRZRM:
1101.1Smycroft	dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
1111.1Smycroft	dc.l $40000000,$adf85458,$a2bb4a9a    ;e
1121.1Smycroft	dc.l $3fff0000,$b8aa3b29,$5c17f0bb    ;log2(e)
1131.1Smycroft	dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
1141.1Smycroft	dc.l $00000000,$00000000,$00000000    ;0.0
1151.1Smycroft* round to positive infinity
1161.1SmycroftSMALRP:
1171.1Smycroft	dc.l $3ffd0000,$9a209a84,$fbcff799    ;log10(2)
1181.1Smycroft	dc.l $40000000,$adf85458,$a2bb4a9b    ;e
1191.1Smycroft	dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
1201.1Smycroft	dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
1211.1Smycroft	dc.l $00000000,$00000000,$00000000    ;0.0
1221.1Smycroft
1231.1Smycroft*round to nearest
1241.1SmycroftBIGRN:
1251.1Smycroft	dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
1261.1Smycroft	dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
1271.1Smycroft	dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
1281.1Smycroft
1291.1Smycroft	xdef	PTENRN
1301.1SmycroftPTENRN:
1311.1Smycroft	dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
1321.1Smycroft	dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
1331.1Smycroft	dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
1341.1Smycroft	dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
1351.1Smycroft	dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
1361.1Smycroft	dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
1371.1Smycroft	dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
1381.1Smycroft	dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
1391.1Smycroft	dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
1401.1Smycroft	dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
1411.1Smycroft	dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
1421.1Smycroft	dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
1431.1Smycroft	dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
1441.1Smycroft*round to minus infinity
1451.1SmycroftBIGRZRM:
1461.1Smycroft	dc.l $3ffe0000,$b17217f7,$d1cf79ab    ;ln(2)
1471.1Smycroft	dc.l $40000000,$935d8ddd,$aaa8ac16    ;ln(10)
1481.1Smycroft	dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
1491.1Smycroft
1501.1Smycroft	xdef	PTENRM
1511.1SmycroftPTENRM:
1521.1Smycroft	dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
1531.1Smycroft	dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
1541.1Smycroft	dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
1551.1Smycroft	dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
1561.1Smycroft	dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
1571.1Smycroft	dc.l $40690000,$9DC5ADA8,$2B70B59D    ;10 ^ 32
1581.1Smycroft	dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
1591.1Smycroft	dc.l $41A80000,$93BA47C9,$80E98CDF    ;10 ^ 128
1601.1Smycroft	dc.l $43510000,$AA7EEBFB,$9DF9DE8D    ;10 ^ 256
1611.1Smycroft	dc.l $46A30000,$E319A0AE,$A60E91C6    ;10 ^ 512
1621.1Smycroft	dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
1631.1Smycroft	dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
1641.1Smycroft	dc.l $75250000,$C4605202,$8A20979A    ;10 ^ 4096
1651.1Smycroft*round to positive infinity
1661.1SmycroftBIGRP:
1671.1Smycroft	dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
1681.1Smycroft	dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
1691.1Smycroft	dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
1701.1Smycroft
1711.1Smycroft	xdef	PTENRP
1721.1SmycroftPTENRP:
1731.1Smycroft	dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
1741.1Smycroft	dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
1751.1Smycroft	dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
1761.1Smycroft	dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
1771.1Smycroft	dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
1781.1Smycroft	dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
1791.1Smycroft	dc.l $40D30000,$C2781F49,$FFCFA6D6    ;10 ^ 64
1801.1Smycroft	dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
1811.1Smycroft	dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
1821.1Smycroft	dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
1831.1Smycroft	dc.l $4D480000,$C9767586,$81750C18    ;10 ^ 1024
1841.1Smycroft	dc.l $5A920000,$9E8B3B5D,$C53D5DE6    ;10 ^ 2048
1851.1Smycroft	dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
1861.1Smycroft
1871.1Smycroft	xref	nrm_zero
1881.1Smycroft	xref	decbin
1891.1Smycroft	xref	round
1901.1Smycroft
1911.1Smycroft	xdef    get_op
1921.1Smycroft	xdef    uns_getop
1931.1Smycroft	xdef    uni_getop
1941.1Smycroftget_op:
1951.1Smycroft	clr.b	DY_MO_FLG(a6)
1961.1Smycroft	tst.b	UFLG_TMP(a6)	;test flag for unsupp/unimp state
1971.1Smycroft	beq.b	uni_getop
1981.1Smycroft
1991.1Smycroftuns_getop:
2001.1Smycroft	btst.b	#direction_bit,CMDREG1B(a6)
2011.1Smycroft	bne.w	opclass3	;branch if a fmove out (any kind)
2021.1Smycroft	btst.b	#6,CMDREG1B(a6)
2031.1Smycroft	beq.b	uns_notpacked
2041.1Smycroft
2051.1Smycroft	bfextu	CMDREG1B(a6){3:3},d0
2061.1Smycroft	cmp.b	#3,d0
2071.1Smycroft	beq.w	pack_source	;check for a packed src op, branch if so
2081.1Smycroftuns_notpacked:
2091.1Smycroft	bsr	chk_dy_mo	;set the dyadic/monadic flag
2101.1Smycroft	tst.b	DY_MO_FLG(a6)
2111.1Smycroft	beq.b	src_op_ck	;if monadic, go check src op
2121.1Smycroft*				;else, check dst op (fall through)
2131.1Smycroft
2141.1Smycroft	btst.b	#7,DTAG(a6)
2151.1Smycroft	beq.b	src_op_ck	;if dst op is norm, check src op
2161.1Smycroft	bra.b	dst_ex_dnrm	;else, handle destination unnorm/dnrm
2171.1Smycroft
2181.1Smycroftuni_getop:
2191.1Smycroft	bfextu	CMDREG1B(a6){0:6},d0 ;get opclass and src fields
2201.1Smycroft	cmpi.l	#$17,d0		;if op class and size fields are $17, 
2211.1Smycroft*				;it is FMOVECR; if not, continue
2221.1Smycroft*
2231.1Smycroft* If the instruction is fmovecr, exit get_op.  It is handled
2241.1Smycroft* in do_func and smovecr.sa.
2251.1Smycroft*
2261.1Smycroft	bne.w	not_fmovecr	;handle fmovecr as an unimplemented inst
2271.1Smycroft	rts
2281.1Smycroft
2291.1Smycroftnot_fmovecr:
2301.1Smycroft	btst.b	#E1,E_BYTE(a6)	;if set, there is a packed operand
2311.1Smycroft	bne.w	pack_source	;check for packed src op, branch if so
2321.1Smycroft
2331.1Smycroft* The following lines of are coded to optimize on normalized operands
2341.1Smycroft	move.b	STAG(a6),d0
2351.1Smycroft	or.b	DTAG(a6),d0	;check if either of STAG/DTAG msb set
2361.1Smycroft	bmi.b	dest_op_ck	;if so, some op needs to be fixed
2371.1Smycroft	rts
2381.1Smycroft
2391.1Smycroftdest_op_ck:
2401.1Smycroft	btst.b	#7,DTAG(a6)	;check for unsupported data types in
2411.1Smycroft	beq.b	src_op_ck	;the destination, if not, check src op
2421.1Smycroft	bsr	chk_dy_mo	;set dyadic/monadic flag
2431.1Smycroft	tst.b	DY_MO_FLG(a6)	;
2441.1Smycroft	beq.b	src_op_ck	;if monadic, check src op
2451.1Smycroft*
2461.1Smycroft* At this point, destination has an extended denorm or unnorm.
2471.1Smycroft*
2481.1Smycroftdst_ex_dnrm:
2491.1Smycroft	move.w	FPTEMP_EX(a6),d0 ;get destination exponent
2501.1Smycroft	andi.w	#$7fff,d0	;mask sign, check if exp = 0000
2511.1Smycroft	beq.b	src_op_ck	;if denorm then check source op.
2521.1Smycroft*				;denorms are taken care of in res_func 
2531.1Smycroft*				;(unsupp) or do_func (unimp)
2541.1Smycroft*				;else unnorm fall through
2551.1Smycroft	lea.l	FPTEMP(a6),a0	;point a0 to dop - used in mk_norm
2561.1Smycroft	bsr	mk_norm		;go normalize - mk_norm returns:
2571.1Smycroft*				;L_SCR1{7:5} = operand tag 
2581.1Smycroft*				;	(000 = norm, 100 = denorm)
2591.1Smycroft*				;L_SCR1{4} = fpte15 or ete15 
2601.1Smycroft*				;	0 = exp >  $3fff
2611.1Smycroft*				;	1 = exp <= $3fff
2621.1Smycroft*				;and puts the normalized num back 
2631.1Smycroft*				;on the fsave stack
2641.1Smycroft*
2651.1Smycroft	move.b L_SCR1(a6),DTAG(a6) ;write the new tag & fpte15 
2661.1Smycroft*				;to the fsave stack and fall 
2671.1Smycroft*				;through to check source operand
2681.1Smycroft*
2691.1Smycroftsrc_op_ck:
2701.1Smycroft	btst.b	#7,STAG(a6)
2711.1Smycroft	beq.w	end_getop	;check for unsupported data types on the
2721.1Smycroft*				;source operand
2731.1Smycroft	btst.b	#5,STAG(a6)
2741.1Smycroft	bne.b	src_sd_dnrm	;if bit 5 set, handle sgl/dbl denorms
2751.1Smycroft*
2761.1Smycroft* At this point only unnorms or extended denorms are possible.
2771.1Smycroft*
2781.1Smycroftsrc_ex_dnrm:
2791.1Smycroft	move.w	ETEMP_EX(a6),d0 ;get source exponent
2801.1Smycroft	andi.w	#$7fff,d0	;mask sign, check if exp = 0000
2811.1Smycroft	beq.w	end_getop	;if denorm then exit, denorms are 
2821.1Smycroft*				;handled in do_func
2831.1Smycroft	lea.l	ETEMP(a6),a0	;point a0 to sop - used in mk_norm
2841.1Smycroft	bsr	mk_norm		;go normalize - mk_norm returns:
2851.1Smycroft*				;L_SCR1{7:5} = operand tag 
2861.1Smycroft*				;	(000 = norm, 100 = denorm)
2871.1Smycroft*				;L_SCR1{4} = fpte15 or ete15 
2881.1Smycroft*				;	0 = exp >  $3fff
2891.1Smycroft*				;	1 = exp <= $3fff
2901.1Smycroft*				;and puts the normalized num back 
2911.1Smycroft*				;on the fsave stack
2921.1Smycroft*
2931.1Smycroft	move.b	L_SCR1(a6),STAG(a6) ;write the new tag & ete15 
2941.1Smycroft	rts			;end_getop
2951.1Smycroft
2961.1Smycroft*
2971.1Smycroft* At this point, only single or double denorms are possible.
2981.1Smycroft* If the inst is not fmove, normalize the source.  If it is,
2991.1Smycroft* do nothing to the input.
3001.1Smycroft*
3011.1Smycroftsrc_sd_dnrm:
3021.1Smycroft	btst.b	#4,CMDREG1B(a6)	;differentiate between sgl/dbl denorm
3031.1Smycroft	bne.b	is_double
3041.1Smycroftis_single:
3051.1Smycroft	move.w	#$3f81,d1	;write bias for sgl denorm
3061.1Smycroft	bra.b	common		;goto the common code
3071.1Smycroftis_double:
3081.1Smycroft	move.w	#$3c01,d1	;write the bias for a dbl denorm
3091.1Smycroftcommon:
3101.1Smycroft	btst.b	#sign_bit,ETEMP_EX(a6) ;grab sign bit of mantissa
3111.1Smycroft	beq.b	pos	
3121.1Smycroft	bset	#15,d1		;set sign bit because it is negative
3131.1Smycroftpos:
3141.1Smycroft	move.w	d1,ETEMP_EX(a6)
3151.1Smycroft*				;put exponent on stack
3161.1Smycroft
3171.1Smycroft	move.w	CMDREG1B(a6),d1
3181.1Smycroft	and.w	#$e3ff,d1	;clear out source specifier
3191.1Smycroft	or.w	#$0800,d1	;set source specifier to extended prec
3201.1Smycroft	move.w	d1,CMDREG1B(a6)	;write back to the command word in stack
3211.1Smycroft*				;this is needed to fix unsupp data stack
3221.1Smycroft	lea.l	ETEMP(a6),a0	;point a0 to sop
3231.1Smycroft	
3241.1Smycroft	bsr	mk_norm		;convert sgl/dbl denorm to norm
3251.1Smycroft	move.b	L_SCR1(a6),STAG(a6) ;put tag into source tag reg - d0
3261.1Smycroft	rts			;end_getop
3271.1Smycroft*
3281.1Smycroft* At this point, the source is definitely packed, whether
3291.1Smycroft* instruction is dyadic or monadic is still unknown
3301.1Smycroft*
3311.1Smycroftpack_source:
3321.1Smycroft	move.l	FPTEMP_LO(a6),ETEMP(a6)	;write ms part of packed 
3331.1Smycroft*				;number to etemp slot
3341.1Smycroft	bsr	chk_dy_mo	;set dyadic/monadic flag
3351.1Smycroft	bsr	unpack
3361.1Smycroft
3371.1Smycroft	tst.b	DY_MO_FLG(a6)
3381.1Smycroft	beq.b	end_getop	;if monadic, exit
3391.1Smycroft*				;else, fix FPTEMP
3401.1Smycroftpack_dya:
3411.1Smycroft	bfextu	CMDREG1B(a6){6:3},d0 ;extract dest fp reg
3421.1Smycroft	move.l	#7,d1
3431.1Smycroft	sub.l	d0,d1
3441.1Smycroft	clr.l	d0
3451.1Smycroft	bset.l	d1,d0		;set up d0 as a dynamic register mask
3461.1Smycroft	fmovem.x d0,FPTEMP(a6)	;write to FPTEMP
3471.1Smycroft
3481.1Smycroft	btst.b	#7,DTAG(a6)	;check dest tag for unnorm or denorm
3491.1Smycroft	bne.w	dst_ex_dnrm	;else, handle the unnorm or ext denorm
3501.1Smycroft*
3511.1Smycroft* Dest is not denormalized.  Check for norm, and set fpte15 
3521.1Smycroft* accordingly.
3531.1Smycroft*
3541.1Smycroft	move.b	DTAG(a6),d0
3551.1Smycroft	andi.b	#$f0,d0		;strip to only dtag:fpte15
3561.1Smycroft	tst.b	d0		;check for normalized value
3571.1Smycroft	bne.b	end_getop	;if inf/nan/zero leave get_op
3581.1Smycroft	move.w	FPTEMP_EX(a6),d0
3591.1Smycroft	andi.w	#$7fff,d0
3601.1Smycroft	cmpi.w	#$3fff,d0	;check if fpte15 needs setting
3611.1Smycroft	bge.b	end_getop	;if >= $3fff, leave fpte15=0
3621.1Smycroft	or.b	#$10,DTAG(a6)
3631.1Smycroft	bra.b	end_getop
3641.1Smycroft
3651.1Smycroft*
3661.1Smycroft* At this point, it is either an fmoveout packed, unnorm or denorm
3671.1Smycroft*
3681.1Smycroftopclass3:
3691.1Smycroft	clr.b	DY_MO_FLG(a6)	;set dyadic/monadic flag to monadic
3701.1Smycroft	bfextu	CMDREG1B(a6){4:2},d0
3711.1Smycroft	cmpi.b	#3,d0
3721.1Smycroft	bne.w	src_ex_dnrm	;if not equal, must be unnorm or denorm
3731.1Smycroft*				;else it is a packed move out
3741.1Smycroft*				;exit
3751.1Smycroftend_getop:
3761.1Smycroft	rts
3771.1Smycroft
3781.1Smycroft*
3791.1Smycroft* Sets the DY_MO_FLG correctly. This is used only on if it is an
3801.1Smycroft* unuspported data type exception.  Set if dyadic.
3811.1Smycroft*
3821.1Smycroftchk_dy_mo:
3831.1Smycroft	move.w	CMDREG1B(a6),d0	
3841.1Smycroft	btst.l	#5,d0		;testing extension command word
3851.1Smycroft	beq.b	set_mon		;if bit 5 = 0 then monadic
3861.1Smycroft	btst.l	#4,d0		;know that bit 5 = 1
3871.1Smycroft	beq.b	set_dya		;if bit 4 = 0 then dyadic
3881.1Smycroft	andi.w	#$007f,d0	;get rid of all but extension bits {6:0}
3891.1Smycroft	cmpi.w 	#$0038,d0	;if extension = $38 then fcmp (dyadic)
3901.1Smycroft	bne.b	set_mon
3911.1Smycroftset_dya:
3921.1Smycroft	st.b	DY_MO_FLG(a6)	;set the inst flag type to dyadic
3931.1Smycroft	rts
3941.1Smycroftset_mon:
3951.1Smycroft	clr.b	DY_MO_FLG(a6)	;set the inst flag type to monadic
3961.1Smycroft	rts
3971.1Smycroft*
3981.1Smycroft*	MK_NORM
3991.1Smycroft*
4001.1Smycroft* Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
4011.1Smycroft* exception if denorm.
4021.1Smycroft*
4031.1Smycroft* CASE opclass 0x0 unsupp
4041.1Smycroft*	mk_norm till msb set
4051.1Smycroft*	set tag = norm
4061.1Smycroft*
4071.1Smycroft* CASE opclass 0x0 unimp
4081.1Smycroft*	mk_norm till msb set or exp = 0
4091.1Smycroft*	if integer bit = 0
4101.1Smycroft*	   tag = denorm
4111.1Smycroft*	else
4121.1Smycroft*	   tag = norm
4131.1Smycroft*
4141.1Smycroft* CASE opclass 011 unsupp
4151.1Smycroft*	mk_norm till msb set or exp = 0
4161.1Smycroft*	if integer bit = 0
4171.1Smycroft*	   tag = denorm
4181.1Smycroft*	   set unfl_nmcexe = 1
4191.1Smycroft*	else
4201.1Smycroft*	   tag = norm
4211.1Smycroft*
4221.1Smycroft* if exp <= $3fff
4231.1Smycroft*   set ete15 or fpte15 = 1
4241.1Smycroft* else set ete15 or fpte15 = 0
4251.1Smycroft
4261.1Smycroft* input:
4271.1Smycroft*	a0 = points to operand to be normalized
4281.1Smycroft* output:
4291.1Smycroft*	L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
4301.1Smycroft*	L_SCR1{4}   = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
4311.1Smycroft*	the normalized operand is placed back on the fsave stack
4321.1Smycroftmk_norm:	
4331.1Smycroft	clr.l	L_SCR1(a6)
4341.1Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)
4351.1Smycroft	sne	LOCAL_SGN(a0)	;transform into internal extended format
4361.1Smycroft
4371.1Smycroft	cmpi.b	#$2c,1+EXC_VEC(a6) ;check if unimp
4381.1Smycroft	bne.b	uns_data	;branch if unsupp
4391.1Smycroft	bsr	uni_inst	;call if unimp (opclass 0x0)
4401.1Smycroft	bra.b	reload
4411.1Smycroftuns_data:
4421.1Smycroft	btst.b	#direction_bit,CMDREG1B(a6) ;check transfer direction
4431.1Smycroft	bne.b	bit_set		;branch if set (opclass 011)
4441.1Smycroft	bsr	uns_opx		;call if opclass 0x0
4451.1Smycroft	bra.b	reload
4461.1Smycroftbit_set:
4471.1Smycroft	bsr	uns_op3		;opclass 011
4481.1Smycroftreload:
4491.1Smycroft	cmp.w	#$3fff,LOCAL_EX(a0) ;if exp > $3fff
4501.1Smycroft	bgt.b	end_mk		;   fpte15/ete15 already set to 0
4511.1Smycroft	bset.b	#4,L_SCR1(a6)	;else set fpte15/ete15 to 1
4521.1Smycroft*				;calling routine actually sets the 
4531.1Smycroft*				;value on the stack (along with the 
4541.1Smycroft*				;tag), since this routine doesn't 
4551.1Smycroft*				;know if it should set ete15 or fpte15
4561.1Smycroft*				;ie, it doesn't know if this is the 
4571.1Smycroft*				;src op or dest op.
4581.1Smycroftend_mk:
4591.1Smycroft	bfclr	LOCAL_SGN(a0){0:8}
4601.1Smycroft	beq.b	end_mk_pos
4611.1Smycroft	bset.b	#sign_bit,LOCAL_EX(a0) ;convert back to IEEE format
4621.1Smycroftend_mk_pos:
4631.1Smycroft	rts
4641.1Smycroft*
4651.1Smycroft*     CASE opclass 011 unsupp
4661.1Smycroft*
4671.1Smycroftuns_op3:
4681.1Smycroft	bsr	nrm_zero	;normalize till msb = 1 or exp = zero
4691.1Smycroft	btst.b	#7,LOCAL_HI(a0)	;if msb = 1
4701.1Smycroft	bne.b	no_unfl		;then branch
4711.1Smycroftset_unfl:
4721.2Smycroft	or.b	#dnrm_tag,L_SCR1(a6) ;set denorm tag
4731.1Smycroft	bset.b	#unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit
4741.1Smycroftno_unfl:
4751.1Smycroft	rts
4761.1Smycroft*
4771.1Smycroft*     CASE opclass 0x0 unsupp
4781.1Smycroft*
4791.1Smycroftuns_opx:
4801.1Smycroft	bsr	nrm_zero	;normalize the number
4811.1Smycroft	btst.b	#7,LOCAL_HI(a0)	;check if integer bit (j-bit) is set 
4821.1Smycroft	beq.b	uns_den		;if clear then now have a denorm
4831.1Smycroftuns_nrm:
4841.1Smycroft	or.b	#norm_tag,L_SCR1(a6) ;set tag to norm
4851.1Smycroft	rts
4861.1Smycroftuns_den:
4871.1Smycroft	or.b	#dnrm_tag,L_SCR1(a6) ;set tag to denorm
4881.1Smycroft	rts
4891.1Smycroft*
4901.1Smycroft*     CASE opclass 0x0 unimp
4911.1Smycroft*
4921.1Smycroftuni_inst:
4931.1Smycroft	bsr	nrm_zero
4941.1Smycroft	btst.b	#7,LOCAL_HI(a0)	;check if integer bit (j-bit) is set 
4951.1Smycroft	beq.b	uni_den		;if clear then now have a denorm
4961.1Smycroftuni_nrm:
4971.1Smycroft	or.b	#norm_tag,L_SCR1(a6) ;set tag to norm
4981.1Smycroft	rts
4991.1Smycroftuni_den:
5001.1Smycroft	or.b	#dnrm_tag,L_SCR1(a6) ;set tag to denorm
5011.1Smycroft	rts
5021.1Smycroft
5031.1Smycroft*
5041.1Smycroft*	Decimal to binary conversion
5051.1Smycroft*
5061.1Smycroft* Special cases of inf and NaNs are completed outside of decbin.  
5071.1Smycroft* If the input is an snan, the snan bit is not set.
5081.1Smycroft* 
5091.1Smycroft* input:
5101.1Smycroft*	ETEMP(a6)	- points to packed decimal string in memory
5111.1Smycroft* output:
5121.1Smycroft*	fp0	- contains packed string converted to extended precision
5131.1Smycroft*	ETEMP	- same as fp0
5141.1Smycroftunpack:
5151.1Smycroft	move.w	CMDREG1B(a6),d0	;examine command word, looking for fmove's
5161.1Smycroft	and.w	#$3b,d0
5171.1Smycroft	beq	move_unpack	;special handling for fmove: must set FPSR_CC
5181.1Smycroft
5191.1Smycroft	move.w	ETEMP(a6),d0	;get word with inf information
5201.1Smycroft	bfextu	d0{20:12},d1	;get exponent into d1
5211.1Smycroft	cmpi.w	#$0fff,d1	;test for inf or NaN
5221.1Smycroft	bne.b	try_zero	;if not equal, it is not special
5231.1Smycroft	bfextu	d0{17:3},d1	;get SE and y bits into d1
5241.1Smycroft	cmpi.w	#7,d1		;SE and y bits must be on for special
5251.1Smycroft	bne.b	try_zero	;if not on, it is not special
5261.1Smycroft*input is of the special cases of inf and NaN
5271.1Smycroft	tst.l	ETEMP_HI(a6)	;check ms mantissa
5281.1Smycroft	bne.b	fix_nan		;if non-zero, it is a NaN
5291.1Smycroft	tst.l	ETEMP_LO(a6)	;check ls mantissa
5301.1Smycroft	bne.b	fix_nan		;if non-zero, it is a NaN
5311.1Smycroft	bra.w	finish		;special already on stack
5321.1Smycroftfix_nan:
5331.1Smycroft	btst.b	#signan_bit,ETEMP_HI(a6) ;test for snan
5341.1Smycroft	bne.w	finish
5351.1Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;always set snan if it is so
5361.1Smycroft	bra.w	finish
5371.1Smycrofttry_zero:
5381.1Smycroft	move.w	ETEMP_EX+2(a6),d0 ;get word 4
5391.1Smycroft	andi.w	#$000f,d0	;clear all but last ni(y)bble
5401.1Smycroft	tst.w	d0		;check for zero.
5411.1Smycroft	bne.w	not_spec
5421.1Smycroft	tst.l	ETEMP_HI(a6)	;check words 3 and 2
5431.1Smycroft	bne.w	not_spec
5441.1Smycroft	tst.l	ETEMP_LO(a6)	;check words 1 and 0
5451.1Smycroft	bne.w	not_spec
5461.1Smycroft	tst.l	ETEMP(a6)	;test sign of the zero
5471.1Smycroft	bge.b	pos_zero
5481.1Smycroft	move.l	#$80000000,ETEMP(a6) ;write neg zero to etemp
5491.1Smycroft	clr.l	ETEMP_HI(a6)
5501.1Smycroft	clr.l	ETEMP_LO(a6)
5511.1Smycroft	bra.w	finish
5521.1Smycroftpos_zero:
5531.1Smycroft	clr.l	ETEMP(a6)
5541.1Smycroft	clr.l	ETEMP_HI(a6)
5551.1Smycroft	clr.l	ETEMP_LO(a6)
5561.1Smycroft	bra.w	finish
5571.1Smycroft
5581.1Smycroftnot_spec:
5591.1Smycroft	fmovem.x fp0-fp1,-(a7)	;save fp0 - decbin returns in it
5601.1Smycroft	bsr	decbin
5611.1Smycroft	fmove.x fp0,ETEMP(a6)	;put the unpacked sop in the fsave stack
5621.1Smycroft	fmovem.x (a7)+,fp0-fp1
5631.1Smycroft	fmove.l	#0,FPSR		;clr fpsr from decbin
5641.1Smycroft	bra	finish
5651.1Smycroft
5661.1Smycroft*
5671.1Smycroft* Special handling for packed move in:  Same results as all other
5681.1Smycroft* packed cases, but we must set the FPSR condition codes properly.
5691.1Smycroft*
5701.1Smycroftmove_unpack:
5711.1Smycroft	move.w	ETEMP(a6),d0	;get word with inf information
5721.1Smycroft	bfextu	d0{20:12},d1	;get exponent into d1
5731.1Smycroft	cmpi.w	#$0fff,d1	;test for inf or NaN
5741.1Smycroft	bne.b	mtry_zero	;if not equal, it is not special
5751.1Smycroft	bfextu	d0{17:3},d1	;get SE and y bits into d1
5761.1Smycroft	cmpi.w	#7,d1		;SE and y bits must be on for special
5771.1Smycroft	bne.b	mtry_zero	;if not on, it is not special
5781.1Smycroft*input is of the special cases of inf and NaN
5791.1Smycroft	tst.l	ETEMP_HI(a6)	;check ms mantissa
5801.1Smycroft	bne.b	mfix_nan		;if non-zero, it is a NaN
5811.1Smycroft	tst.l	ETEMP_LO(a6)	;check ls mantissa
5821.1Smycroft	bne.b	mfix_nan		;if non-zero, it is a NaN
5831.1Smycroft*input is inf
5841.1Smycroft	or.l	#inf_mask,USER_FPSR(a6) ;set I bit
5851.1Smycroft	tst.l	ETEMP(a6)	;check sign
5861.1Smycroft	bge.w	finish
5871.1Smycroft	or.l	#neg_mask,USER_FPSR(a6) ;set N bit
5881.1Smycroft	bra.w	finish		;special already on stack
5891.1Smycroftmfix_nan:
5901.1Smycroft	or.l	#nan_mask,USER_FPSR(a6) ;set NaN bit
5911.1Smycroft	move.b	#nan_tag,STAG(a6)	;set stag to NaN
5921.1Smycroft	btst.b	#signan_bit,ETEMP_HI(a6) ;test for snan
5931.1Smycroft	bne.b	mn_snan
5941.1Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set snan bit
5951.1Smycroft	btst.b	#snan_bit,FPCR_ENABLE(a6) ;test for snan enabled
5961.1Smycroft	bne.b	mn_snan
5971.1Smycroft	bset.b	#signan_bit,ETEMP_HI(a6) ;force snans to qnans
5981.1Smycroftmn_snan:
5991.1Smycroft	tst.l	ETEMP(a6)	;check for sign
6001.1Smycroft	bge.w	finish		;if clr, go on
6011.1Smycroft	or.l	#neg_mask,USER_FPSR(a6) ;set N bit
6021.1Smycroft	bra.w	finish
6031.1Smycroft
6041.1Smycroftmtry_zero:
6051.1Smycroft	move.w	ETEMP_EX+2(a6),d0 ;get word 4
6061.1Smycroft	andi.w	#$000f,d0	;clear all but last ni(y)bble
6071.1Smycroft	tst.w	d0		;check for zero.
6081.1Smycroft	bne.b	mnot_spec
6091.1Smycroft	tst.l	ETEMP_HI(a6)	;check words 3 and 2
6101.1Smycroft	bne.b	mnot_spec
6111.1Smycroft	tst.l	ETEMP_LO(a6)	;check words 1 and 0
6121.1Smycroft	bne.b	mnot_spec
6131.1Smycroft	tst.l	ETEMP(a6)	;test sign of the zero
6141.1Smycroft	bge.b	mpos_zero
6151.1Smycroft	or.l	#neg_mask+z_mask,USER_FPSR(a6) ;set N and Z
6161.1Smycroft	move.l	#$80000000,ETEMP(a6) ;write neg zero to etemp
6171.1Smycroft	clr.l	ETEMP_HI(a6)
6181.1Smycroft	clr.l	ETEMP_LO(a6)
6191.1Smycroft	bra.b	finish
6201.1Smycroftmpos_zero:
6211.1Smycroft	or.l	#z_mask,USER_FPSR(a6) ;set Z
6221.1Smycroft	clr.l	ETEMP(a6)
6231.1Smycroft	clr.l	ETEMP_HI(a6)
6241.1Smycroft	clr.l	ETEMP_LO(a6)
6251.1Smycroft	bra.b	finish
6261.1Smycroft
6271.1Smycroftmnot_spec:
6281.1Smycroft	fmovem.x fp0-fp1,-(a7)	;save fp0 ,fp1 - decbin returns in fp0
6291.1Smycroft	bsr	decbin
6301.1Smycroft	fmove.x fp0,ETEMP(a6)
6311.1Smycroft*				;put the unpacked sop in the fsave stack
6321.1Smycroft	fmovem.x (a7)+,fp0-fp1
6331.1Smycroft
6341.1Smycroftfinish:
6351.1Smycroft	move.w	CMDREG1B(a6),d0	;get the command word
6361.1Smycroft	and.w	#$fbff,d0	;change the source specifier field to 
6371.1Smycroft*				;extended (was packed).
6381.1Smycroft	move.w	d0,CMDREG1B(a6)	;write command word back to fsave stack
6391.1Smycroft*				;we need to do this so the 040 will 
6401.1Smycroft*				;re-execute the inst. without taking 
6411.1Smycroft*				;another packed trap.
6421.1Smycroft
6431.1Smycroftfix_stag:
6441.1Smycroft*Converted result is now in etemp on fsave stack, now set the source 
6451.1Smycroft*tag (stag) 
6461.1Smycroft*	if (ete =$7fff) then INF or NAN
6471.1Smycroft*		if (etemp = $x.0----0) then
6481.1Smycroft*			stag = INF
6491.1Smycroft*		else
6501.1Smycroft*			stag = NAN
6511.1Smycroft*	else
6521.1Smycroft*		if (ete = $0000) then
6531.1Smycroft*			stag = ZERO
6541.1Smycroft*		else
6551.1Smycroft*			stag = NORM
6561.1Smycroft*
6571.1Smycroft* Note also that the etemp_15 bit (just right of the stag) must
6581.1Smycroft* be set accordingly.  
6591.1Smycroft*
6601.1Smycroft	move.w		ETEMP_EX(a6),d1
6611.1Smycroft	andi.w		#$7fff,d1   ;strip sign
6621.1Smycroft	cmp.w  		#$7fff,d1
6631.1Smycroft	bne.b  		z_or_nrm
6641.1Smycroft	move.l		ETEMP_HI(a6),d1
6651.1Smycroft	bne.b		is_nan
6661.1Smycroft	move.l		ETEMP_LO(a6),d1
6671.1Smycroft	bne.b		is_nan
6681.1Smycroftis_inf:
6691.1Smycroft	move.b		#$40,STAG(a6)
6701.1Smycroft	move.l		#$40,d0
6711.1Smycroft	rts
6721.1Smycroftis_nan:
6731.1Smycroft	move.b		#$60,STAG(a6)
6741.1Smycroft	move.l		#$60,d0
6751.1Smycroft	rts
6761.1Smycroftz_or_nrm:
6771.1Smycroft	tst.w		d1  
6781.1Smycroft	bne.b		is_nrm
6791.1Smycroftis_zro:
6801.1Smycroft* For a zero, set etemp_15
6811.1Smycroft	move.b		#$30,STAG(a6)
6821.1Smycroft	move.l		#$20,d0
6831.1Smycroft	rts
6841.1Smycroftis_nrm:
6851.1Smycroft* For a norm, check if the exp <= $3fff; if so, set etemp_15
6861.1Smycroft	cmpi.w		#$3fff,d1
6871.1Smycroft	ble.b		set_bit15
6881.2Smycroft	clr.b		STAG(a6)
6891.1Smycroft	bra.b		end_is_nrm
6901.1Smycroftset_bit15:
6911.1Smycroft	move.b		#$10,STAG(a6)
6921.1Smycroftend_is_nrm:
6931.2Smycroft	clr.l		d0
6941.1Smycroftend_fix:
6951.1Smycroft	rts
6961.1Smycroft 
6971.1Smycroftend_get:
6981.1Smycroft	rts
6991.1Smycroft	end
700