Home | History | Annotate | Line # | Download | only in fpsp
bindec.sa revision 1.4.4.2
      1  1.4.4.2  nathanw *	$NetBSD: bindec.sa,v 1.4.4.2 2002/01/08 00:25:52 nathanw Exp $
      2  1.4.4.2  nathanw 
      3  1.4.4.2  nathanw *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      4  1.4.4.2  nathanw *	M68000 Hi-Performance Microprocessor Division
      5  1.4.4.2  nathanw *	M68040 Software Package 
      6  1.4.4.2  nathanw *
      7  1.4.4.2  nathanw *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      8  1.4.4.2  nathanw *	All rights reserved.
      9  1.4.4.2  nathanw *
     10  1.4.4.2  nathanw *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     11  1.4.4.2  nathanw *	To the maximum extent permitted by applicable law,
     12  1.4.4.2  nathanw *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     13  1.4.4.2  nathanw *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     14  1.4.4.2  nathanw *	PARTICULAR PURPOSE and any warranty against infringement with
     15  1.4.4.2  nathanw *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     16  1.4.4.2  nathanw *	and any accompanying written materials. 
     17  1.4.4.2  nathanw *
     18  1.4.4.2  nathanw *	To the maximum extent permitted by applicable law,
     19  1.4.4.2  nathanw *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     20  1.4.4.2  nathanw *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     21  1.4.4.2  nathanw *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     22  1.4.4.2  nathanw *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     23  1.4.4.2  nathanw *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     24  1.4.4.2  nathanw *	and support of the SOFTWARE.  
     25  1.4.4.2  nathanw *
     26  1.4.4.2  nathanw *	You are hereby granted a copyright license to use, modify, and
     27  1.4.4.2  nathanw *	distribute the SOFTWARE so long as this entire notice is retained
     28  1.4.4.2  nathanw *	without alteration in any modified and/or redistributed versions,
     29  1.4.4.2  nathanw *	and that such modified versions are clearly identified as such.
     30  1.4.4.2  nathanw *	No licenses are granted by implication, estoppel or otherwise
     31  1.4.4.2  nathanw *	under any patents or trademarks of Motorola, Inc.
     32  1.4.4.2  nathanw 
     33  1.4.4.2  nathanw *
     34  1.4.4.2  nathanw *	bindec.sa 3.4 1/3/91
     35  1.4.4.2  nathanw *
     36  1.4.4.2  nathanw *	bindec
     37  1.4.4.2  nathanw *
     38  1.4.4.2  nathanw *	Description:
     39  1.4.4.2  nathanw *		Converts an input in extended precision format
     40  1.4.4.2  nathanw *		to bcd format.
     41  1.4.4.2  nathanw *
     42  1.4.4.2  nathanw *	Input:
     43  1.4.4.2  nathanw *		a0 points to the input extended precision value
     44  1.4.4.2  nathanw *		value in memory; d0 contains the k-factor sign-extended
     45  1.4.4.2  nathanw *		to 32-bits.  The input may be either normalized,
     46  1.4.4.2  nathanw *		unnormalized, or denormalized.
     47  1.4.4.2  nathanw *
     48  1.4.4.2  nathanw *	Output:	result in the FP_SCR1 space on the stack.
     49  1.4.4.2  nathanw *
     50  1.4.4.2  nathanw *	Saves and Modifies: D2-D7,A2,FP2
     51  1.4.4.2  nathanw *
     52  1.4.4.2  nathanw *	Algorithm:
     53  1.4.4.2  nathanw *
     54  1.4.4.2  nathanw *	A1.	Set RM and size ext;  Set SIGMA = sign of input.  
     55  1.4.4.2  nathanw *		The k-factor is saved for use in d7. Clear the
     56  1.4.4.2  nathanw *		BINDEC_FLG for separating normalized/denormalized
     57  1.4.4.2  nathanw *		input.  If input is unnormalized or denormalized,
     58  1.4.4.2  nathanw *		normalize it.
     59  1.4.4.2  nathanw *
     60  1.4.4.2  nathanw *	A2.	Set X = abs(input).
     61  1.4.4.2  nathanw *
     62  1.4.4.2  nathanw *	A3.	Compute ILOG.
     63  1.4.4.2  nathanw *		ILOG is the log base 10 of the input value.  It is
     64  1.4.4.2  nathanw *		approximated by adding e + 0.f when the original 
     65  1.4.4.2  nathanw *		value is viewed as 2^^e * 1.f in extended precision.  
     66  1.4.4.2  nathanw *		This value is stored in d6.
     67  1.4.4.2  nathanw *
     68  1.4.4.2  nathanw *	A4.	Clr INEX bit.
     69  1.4.4.2  nathanw *		The operation in A3 above may have set INEX2.  
     70  1.4.4.2  nathanw *
     71  1.4.4.2  nathanw *	A5.	Set ICTR = 0;
     72  1.4.4.2  nathanw *		ICTR is a flag used in A13.  It must be set before the 
     73  1.4.4.2  nathanw *		loop entry A6.
     74  1.4.4.2  nathanw *
     75  1.4.4.2  nathanw *	A6.	Calculate LEN.
     76  1.4.4.2  nathanw *		LEN is the number of digits to be displayed.  The
     77  1.4.4.2  nathanw *		k-factor can dictate either the total number of digits,
     78  1.4.4.2  nathanw *		if it is a positive number, or the number of digits
     79  1.4.4.2  nathanw *		after the decimal point which are to be included as
     80  1.4.4.2  nathanw *		significant.  See the 68882 manual for examples.
     81  1.4.4.2  nathanw *		If LEN is computed to be greater than 17, set OPERR in
     82  1.4.4.2  nathanw *		USER_FPSR.  LEN is stored in d4.
     83  1.4.4.2  nathanw *
     84  1.4.4.2  nathanw *	A7.	Calculate SCALE.
     85  1.4.4.2  nathanw *		SCALE is equal to 10^ISCALE, where ISCALE is the number
     86  1.4.4.2  nathanw *		of decimal places needed to insure LEN integer digits
     87  1.4.4.2  nathanw *		in the output before conversion to bcd. LAMBDA is the
     88  1.4.4.2  nathanw *		sign of ISCALE, used in A9. Fp1 contains
     89  1.4.4.2  nathanw *		10^^(abs(ISCALE)) using a rounding mode which is a
     90  1.4.4.2  nathanw *		function of the original rounding mode and the signs
     91  1.4.4.2  nathanw *		of ISCALE and X.  A table is given in the code.
     92  1.4.4.2  nathanw *
     93  1.4.4.2  nathanw *	A8.	Clr INEX; Force RZ.
     94  1.4.4.2  nathanw *		The operation in A3 above may have set INEX2.  
     95  1.4.4.2  nathanw *		RZ mode is forced for the scaling operation to insure
     96  1.4.4.2  nathanw *		only one rounding error.  The grs bits are collected in 
     97  1.4.4.2  nathanw *		the INEX flag for use in A10.
     98  1.4.4.2  nathanw *
     99  1.4.4.2  nathanw *	A9.	Scale X -> Y.
    100  1.4.4.2  nathanw *		The mantissa is scaled to the desired number of
    101  1.4.4.2  nathanw *		significant digits.  The excess digits are collected
    102  1.4.4.2  nathanw *		in INEX2.
    103  1.4.4.2  nathanw *
    104  1.4.4.2  nathanw *	A10.	Or in INEX.
    105  1.4.4.2  nathanw *		If INEX is set, round error occurred.  This is
    106  1.4.4.2  nathanw *		compensated for by 'or-ing' in the INEX2 flag to
    107  1.4.4.2  nathanw *		the lsb of Y.
    108  1.4.4.2  nathanw *
    109  1.4.4.2  nathanw *	A11.	Restore original FPCR; set size ext.
    110  1.4.4.2  nathanw *		Perform FINT operation in the user's rounding mode.
    111  1.4.4.2  nathanw *		Keep the size to extended.
    112  1.4.4.2  nathanw *
    113  1.4.4.2  nathanw *	A12.	Calculate YINT = FINT(Y) according to user's rounding
    114  1.4.4.2  nathanw *		mode.  The FPSP routine sintd0 is used.  The output
    115  1.4.4.2  nathanw *		is in fp0.
    116  1.4.4.2  nathanw *
    117  1.4.4.2  nathanw *	A13.	Check for LEN digits.
    118  1.4.4.2  nathanw *		If the int operation results in more than LEN digits,
    119  1.4.4.2  nathanw *		or less than LEN -1 digits, adjust ILOG and repeat from
    120  1.4.4.2  nathanw *		A6.  This test occurs only on the first pass.  If the
    121  1.4.4.2  nathanw *		result is exactly 10^LEN, decrement ILOG and divide
    122  1.4.4.2  nathanw *		the mantissa by 10.
    123  1.4.4.2  nathanw *
    124  1.4.4.2  nathanw *	A14.	Convert the mantissa to bcd.
    125  1.4.4.2  nathanw *		The binstr routine is used to convert the LEN digit 
    126  1.4.4.2  nathanw *		mantissa to bcd in memory.  The input to binstr is
    127  1.4.4.2  nathanw *		to be a fraction; i.e. (mantissa)/10^LEN and adjusted
    128  1.4.4.2  nathanw *		such that the decimal point is to the left of bit 63.
    129  1.4.4.2  nathanw *		The bcd digits are stored in the correct position in 
    130  1.4.4.2  nathanw *		the final string area in memory.
    131  1.4.4.2  nathanw *
    132  1.4.4.2  nathanw *	A15.	Convert the exponent to bcd.
    133  1.4.4.2  nathanw *		As in A14 above, the exp is converted to bcd and the
    134  1.4.4.2  nathanw *		digits are stored in the final string.
    135  1.4.4.2  nathanw *		Test the length of the final exponent string.  If the
    136  1.4.4.2  nathanw *		length is 4, set operr.
    137  1.4.4.2  nathanw *
    138  1.4.4.2  nathanw *	A16.	Write sign bits to final string.
    139  1.4.4.2  nathanw *
    140  1.4.4.2  nathanw *	Implementation Notes:
    141  1.4.4.2  nathanw *
    142  1.4.4.2  nathanw *	The registers are used as follows:
    143  1.4.4.2  nathanw *
    144  1.4.4.2  nathanw *		d0: scratch; LEN input to binstr
    145  1.4.4.2  nathanw *		d1: scratch
    146  1.4.4.2  nathanw *		d2: upper 32-bits of mantissa for binstr
    147  1.4.4.2  nathanw *		d3: scratch;lower 32-bits of mantissa for binstr
    148  1.4.4.2  nathanw *		d4: LEN
    149  1.4.4.2  nathanw *      		d5: LAMBDA/ICTR
    150  1.4.4.2  nathanw *		d6: ILOG
    151  1.4.4.2  nathanw *		d7: k-factor
    152  1.4.4.2  nathanw *		a0: ptr for original operand/final result
    153  1.4.4.2  nathanw *		a1: scratch pointer
    154  1.4.4.2  nathanw *		a2: pointer to FP_X; abs(original value) in ext
    155  1.4.4.2  nathanw *		fp0: scratch
    156  1.4.4.2  nathanw *		fp1: scratch
    157  1.4.4.2  nathanw *		fp2: scratch
    158  1.4.4.2  nathanw *		F_SCR1:
    159  1.4.4.2  nathanw *		F_SCR2:
    160  1.4.4.2  nathanw *		L_SCR1:
    161  1.4.4.2  nathanw *		L_SCR2:
    162  1.4.4.2  nathanw *
    163  1.4.4.2  nathanw 
    164  1.4.4.2  nathanw BINDEC    IDNT    2,1 Motorola 040 Floating Point Software Package
    165  1.4.4.2  nathanw 
    166  1.4.4.2  nathanw 	include	fpsp.h
    167  1.4.4.2  nathanw 
    168  1.4.4.2  nathanw 	section	8
    169  1.4.4.2  nathanw 
    170  1.4.4.2  nathanw * Constants in extended precision
    171  1.4.4.2  nathanw LOG2 	dc.l	$3FFD0000,$9A209A84,$FBCFF798,$00000000
    172  1.4.4.2  nathanw LOG2UP1	dc.l	$3FFD0000,$9A209A84,$FBCFF799,$00000000
    173  1.4.4.2  nathanw 
    174  1.4.4.2  nathanw * Constants in single precision
    175  1.4.4.2  nathanw FONE 	dc.l	$3F800000,$00000000,$00000000,$00000000
    176  1.4.4.2  nathanw FTWO	dc.l	$40000000,$00000000,$00000000,$00000000
    177  1.4.4.2  nathanw FTEN 	dc.l	$41200000,$00000000,$00000000,$00000000
    178  1.4.4.2  nathanw F4933	dc.l	$459A2800,$00000000,$00000000,$00000000
    179  1.4.4.2  nathanw 
    180  1.4.4.2  nathanw RBDTBL 	dc.b	0,0,0,0
    181  1.4.4.2  nathanw 	dc.b	3,3,2,2
    182  1.4.4.2  nathanw 	dc.b	3,2,2,3
    183  1.4.4.2  nathanw 	dc.b	2,3,3,2
    184  1.4.4.2  nathanw 
    185  1.4.4.2  nathanw 	xref	binstr
    186  1.4.4.2  nathanw 	xref	sintdo
    187  1.4.4.2  nathanw 	xref	ptenrn,ptenrm,ptenrp
    188  1.4.4.2  nathanw 
    189  1.4.4.2  nathanw 	xdef	bindec
    190  1.4.4.2  nathanw 	xdef	sc_mul
    191  1.4.4.2  nathanw bindec:
    192  1.4.4.2  nathanw 	movem.l	d2-d7/a2,-(a7)
    193  1.4.4.2  nathanw 	fmovem.x fp0-fp2,-(a7)
    194  1.4.4.2  nathanw 
    195  1.4.4.2  nathanw * A1. Set RM and size ext. Set SIGMA = sign input;
    196  1.4.4.2  nathanw *     The k-factor is saved for use in d7.  Clear BINDEC_FLG for
    197  1.4.4.2  nathanw *     separating  normalized/denormalized input.  If the input
    198  1.4.4.2  nathanw *     is a denormalized number, set the BINDEC_FLG memory word
    199  1.4.4.2  nathanw *     to signal denorm.  If the input is unnormalized, normalize
    200  1.4.4.2  nathanw *     the input and test for denormalized result.  
    201  1.4.4.2  nathanw *
    202  1.4.4.2  nathanw 	fmove.l	#rm_mode,FPCR	;set RM and ext
    203  1.4.4.2  nathanw 	move.l	(a0),L_SCR2(a6)	;save exponent for sign check
    204  1.4.4.2  nathanw 	move.l	d0,d7		;move k-factor to d7
    205  1.4.4.2  nathanw 	clr.b	BINDEC_FLG(a6)	;clr norm/denorm flag
    206  1.4.4.2  nathanw 	move.w	STAG(a6),d0	;get stag
    207  1.4.4.2  nathanw 	andi.w	#$e000,d0	;isolate stag bits
    208  1.4.4.2  nathanw 	beq	A2_str		;if zero, input is norm
    209  1.4.4.2  nathanw *
    210  1.4.4.2  nathanw * Normalize the denorm
    211  1.4.4.2  nathanw *
    212  1.4.4.2  nathanw un_de_norm:
    213  1.4.4.2  nathanw 	move.w	(a0),d0
    214  1.4.4.2  nathanw 	andi.w	#$7fff,d0	;strip sign of normalized exp
    215  1.4.4.2  nathanw 	move.l	4(a0),d1
    216  1.4.4.2  nathanw 	move.l	8(a0),d2
    217  1.4.4.2  nathanw norm_loop:
    218  1.4.4.2  nathanw 	sub.w	#1,d0
    219  1.4.4.2  nathanw 	add.l	d2,d2
    220  1.4.4.2  nathanw 	addx.l	d1,d1
    221  1.4.4.2  nathanw 	tst.l	d1
    222  1.4.4.2  nathanw 	bge.b	norm_loop
    223  1.4.4.2  nathanw *
    224  1.4.4.2  nathanw * Test if the normalized input is denormalized
    225  1.4.4.2  nathanw *
    226  1.4.4.2  nathanw 	tst.w	d0
    227  1.4.4.2  nathanw 	bgt.b	pos_exp		;if greater than zero, it is a norm
    228  1.4.4.2  nathanw 	st	BINDEC_FLG(a6)	;set flag for denorm
    229  1.4.4.2  nathanw pos_exp:
    230  1.4.4.2  nathanw 	andi.w	#$7fff,d0	;strip sign of normalized exp
    231  1.4.4.2  nathanw 	move.w	d0,(a0)
    232  1.4.4.2  nathanw 	move.l	d1,4(a0)
    233  1.4.4.2  nathanw 	move.l	d2,8(a0)
    234  1.4.4.2  nathanw 
    235  1.4.4.2  nathanw * A2. Set X = abs(input).
    236  1.4.4.2  nathanw *
    237  1.4.4.2  nathanw A2_str:
    238  1.4.4.2  nathanw 	move.l	(a0),FP_SCR2(a6) ; move input to work space
    239  1.4.4.2  nathanw 	move.l	4(a0),FP_SCR2+4(a6) ; move input to work space
    240  1.4.4.2  nathanw 	move.l	8(a0),FP_SCR2+8(a6) ; move input to work space
    241  1.4.4.2  nathanw 	andi.l	#$7fffffff,FP_SCR2(a6) ;create abs(X)
    242  1.4.4.2  nathanw 
    243  1.4.4.2  nathanw * A3. Compute ILOG.
    244  1.4.4.2  nathanw *     ILOG is the log base 10 of the input value.  It is approx-
    245  1.4.4.2  nathanw *     imated by adding e + 0.f when the original value is viewed
    246  1.4.4.2  nathanw *     as 2^^e * 1.f in extended precision.  This value is stored
    247  1.4.4.2  nathanw *     in d6.
    248  1.4.4.2  nathanw *
    249  1.4.4.2  nathanw * Register usage:
    250  1.4.4.2  nathanw *	Input/Output
    251  1.4.4.2  nathanw *	d0: k-factor/exponent
    252  1.4.4.2  nathanw *	d2: x/x
    253  1.4.4.2  nathanw *	d3: x/x
    254  1.4.4.2  nathanw *	d4: x/x
    255  1.4.4.2  nathanw *	d5: x/x
    256  1.4.4.2  nathanw *	d6: x/ILOG
    257  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    258  1.4.4.2  nathanw *	a0: ptr for original operand/final result
    259  1.4.4.2  nathanw *	a1: x/x
    260  1.4.4.2  nathanw *	a2: x/x
    261  1.4.4.2  nathanw *	fp0: x/float(ILOG)
    262  1.4.4.2  nathanw *	fp1: x/x
    263  1.4.4.2  nathanw *	fp2: x/x
    264  1.4.4.2  nathanw *	F_SCR1:x/x
    265  1.4.4.2  nathanw *	F_SCR2:Abs(X)/Abs(X) with $3fff exponent
    266  1.4.4.2  nathanw *	L_SCR1:x/x
    267  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    268  1.4.4.2  nathanw 
    269  1.4.4.2  nathanw 	tst.b	BINDEC_FLG(a6)	;check for denorm
    270  1.4.4.2  nathanw 	beq.b	A3_cont		;if clr, continue with norm
    271  1.4.4.2  nathanw 	move.l	#-4933,d6	;force ILOG = -4933
    272  1.4.4.2  nathanw 	bra.b	A4_str
    273  1.4.4.2  nathanw A3_cont:
    274  1.4.4.2  nathanw 	move.w	FP_SCR2(a6),d0	;move exp to d0
    275  1.4.4.2  nathanw 	move.w	#$3fff,FP_SCR2(a6) ;replace exponent with 0x3fff
    276  1.4.4.2  nathanw 	fmove.x	FP_SCR2(a6),fp0	;now fp0 has 1.f
    277  1.4.4.2  nathanw 	sub.w	#$3fff,d0	;strip off bias
    278  1.4.4.2  nathanw 	fadd.w	d0,fp0		;add in exp
    279  1.4.4.2  nathanw 	fsub.s	FONE,fp0	;subtract off 1.0
    280  1.4.4.2  nathanw 	fbge.w	pos_res		;if pos, branch 
    281  1.4.4.2  nathanw 	fmul.x	LOG2UP1,fp0	;if neg, mul by LOG2UP1
    282  1.4.4.2  nathanw 	fmove.l	fp0,d6		;put ILOG in d6 as a lword
    283  1.4.4.2  nathanw 	bra.b	A4_str		;go move out ILOG
    284  1.4.4.2  nathanw pos_res:
    285  1.4.4.2  nathanw 	fmul.x	LOG2,fp0	;if pos, mul by LOG2
    286  1.4.4.2  nathanw 	fmove.l	fp0,d6		;put ILOG in d6 as a lword
    287  1.4.4.2  nathanw 
    288  1.4.4.2  nathanw 
    289  1.4.4.2  nathanw * A4. Clr INEX bit.
    290  1.4.4.2  nathanw *     The operation in A3 above may have set INEX2.  
    291  1.4.4.2  nathanw 
    292  1.4.4.2  nathanw A4_str:	
    293  1.4.4.2  nathanw 	fmove.l	#0,FPSR		;zero all of fpsr - nothing needed
    294  1.4.4.2  nathanw 
    295  1.4.4.2  nathanw 
    296  1.4.4.2  nathanw * A5. Set ICTR = 0;
    297  1.4.4.2  nathanw *     ICTR is a flag used in A13.  It must be set before the 
    298  1.4.4.2  nathanw *     loop entry A6. The lower word of d5 is used for ICTR.
    299  1.4.4.2  nathanw 
    300  1.4.4.2  nathanw 	clr.w	d5		;clear ICTR
    301  1.4.4.2  nathanw 
    302  1.4.4.2  nathanw 
    303  1.4.4.2  nathanw * A6. Calculate LEN.
    304  1.4.4.2  nathanw *     LEN is the number of digits to be displayed.  The k-factor
    305  1.4.4.2  nathanw *     can dictate either the total number of digits, if it is
    306  1.4.4.2  nathanw *     a positive number, or the number of digits after the
    307  1.4.4.2  nathanw *     original decimal point which are to be included as
    308  1.4.4.2  nathanw *     significant.  See the 68882 manual for examples.
    309  1.4.4.2  nathanw *     If LEN is computed to be greater than 17, set OPERR in
    310  1.4.4.2  nathanw *     USER_FPSR.  LEN is stored in d4.
    311  1.4.4.2  nathanw *
    312  1.4.4.2  nathanw * Register usage:
    313  1.4.4.2  nathanw *	Input/Output
    314  1.4.4.2  nathanw *	d0: exponent/Unchanged
    315  1.4.4.2  nathanw *	d2: x/x/scratch
    316  1.4.4.2  nathanw *	d3: x/x
    317  1.4.4.2  nathanw *	d4: exc picture/LEN
    318  1.4.4.2  nathanw *	d5: ICTR/Unchanged
    319  1.4.4.2  nathanw *	d6: ILOG/Unchanged
    320  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    321  1.4.4.2  nathanw *	a0: ptr for original operand/final result
    322  1.4.4.2  nathanw *	a1: x/x
    323  1.4.4.2  nathanw *	a2: x/x
    324  1.4.4.2  nathanw *	fp0: float(ILOG)/Unchanged
    325  1.4.4.2  nathanw *	fp1: x/x
    326  1.4.4.2  nathanw *	fp2: x/x
    327  1.4.4.2  nathanw *	F_SCR1:x/x
    328  1.4.4.2  nathanw *	F_SCR2:Abs(X) with $3fff exponent/Unchanged
    329  1.4.4.2  nathanw *	L_SCR1:x/x
    330  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    331  1.4.4.2  nathanw 
    332  1.4.4.2  nathanw A6_str:	
    333  1.4.4.2  nathanw 	tst.l	d7		;branch on sign of k
    334  1.4.4.2  nathanw 	ble.b	k_neg		;if k <= 0, LEN = ILOG + 1 - k
    335  1.4.4.2  nathanw 	move.l	d7,d4		;if k > 0, LEN = k
    336  1.4.4.2  nathanw 	bra.b	len_ck		;skip to LEN check
    337  1.4.4.2  nathanw k_neg:
    338  1.4.4.2  nathanw 	move.l	d6,d4		;first load ILOG to d4
    339  1.4.4.2  nathanw 	sub.l	d7,d4		;subtract off k
    340  1.4.4.2  nathanw 	addq.l	#1,d4		;add in the 1
    341  1.4.4.2  nathanw len_ck:
    342  1.4.4.2  nathanw 	tst.l	d4		;LEN check: branch on sign of LEN
    343  1.4.4.2  nathanw 	ble.b	LEN_ng		;if neg, set LEN = 1
    344  1.4.4.2  nathanw 	cmp.l	#17,d4		;test if LEN > 17
    345  1.4.4.2  nathanw 	ble.b	A7_str		;if not, forget it
    346  1.4.4.2  nathanw 	move.l	#17,d4		;set max LEN = 17
    347  1.4.4.2  nathanw 	tst.l	d7		;if negative, never set OPERR
    348  1.4.4.2  nathanw 	ble.b	A7_str		;if positive, continue
    349  1.4.4.2  nathanw 	or.l	#opaop_mask,USER_FPSR(a6) ;set OPERR & AIOP in USER_FPSR
    350  1.4.4.2  nathanw 	bra.b	A7_str		;finished here
    351  1.4.4.2  nathanw LEN_ng:
    352  1.4.4.2  nathanw 	moveq.l	#1,d4		;min LEN is 1
    353  1.4.4.2  nathanw 
    354  1.4.4.2  nathanw 
    355  1.4.4.2  nathanw * A7. Calculate SCALE.
    356  1.4.4.2  nathanw *     SCALE is equal to 10^ISCALE, where ISCALE is the number
    357  1.4.4.2  nathanw *     of decimal places needed to insure LEN integer digits
    358  1.4.4.2  nathanw *     in the output before conversion to bcd. LAMBDA is the sign
    359  1.4.4.2  nathanw *     of ISCALE, used in A9.  Fp1 contains 10^^(abs(ISCALE)) using
    360  1.4.4.2  nathanw *     the rounding mode as given in the following table (see
    361  1.4.4.2  nathanw *     Coonen, p. 7.23 as ref.; however, the SCALE variable is
    362  1.4.4.2  nathanw *     of opposite sign in bindec.sa from Coonen).
    363  1.4.4.2  nathanw *
    364  1.4.4.2  nathanw *	Initial					USE
    365  1.4.4.2  nathanw *	FPCR[6:5]	LAMBDA	SIGN(X)		FPCR[6:5]
    366  1.4.4.2  nathanw *	----------------------------------------------
    367  1.4.4.2  nathanw *	 RN	00	   0	   0		00/0	RN
    368  1.4.4.2  nathanw *	 RN	00	   0	   1		00/0	RN
    369  1.4.4.2  nathanw *	 RN	00	   1	   0		00/0	RN
    370  1.4.4.2  nathanw *	 RN	00	   1	   1		00/0	RN
    371  1.4.4.2  nathanw *	 RZ	01	   0	   0		11/3	RP
    372  1.4.4.2  nathanw *	 RZ	01	   0	   1		11/3	RP
    373  1.4.4.2  nathanw *	 RZ	01	   1	   0		10/2	RM
    374  1.4.4.2  nathanw *	 RZ	01	   1	   1		10/2	RM
    375  1.4.4.2  nathanw *	 RM	10	   0	   0		11/3	RP
    376  1.4.4.2  nathanw *	 RM	10	   0	   1		10/2	RM
    377  1.4.4.2  nathanw *	 RM	10	   1	   0		10/2	RM
    378  1.4.4.2  nathanw *	 RM	10	   1	   1		11/3	RP
    379  1.4.4.2  nathanw *	 RP	11	   0	   0		10/2	RM
    380  1.4.4.2  nathanw *	 RP	11	   0	   1		11/3	RP
    381  1.4.4.2  nathanw *	 RP	11	   1	   0		11/3	RP
    382  1.4.4.2  nathanw *	 RP	11	   1	   1		10/2	RM
    383  1.4.4.2  nathanw *
    384  1.4.4.2  nathanw * Register usage:
    385  1.4.4.2  nathanw *	Input/Output
    386  1.4.4.2  nathanw *	d0: exponent/scratch - final is 0
    387  1.4.4.2  nathanw *	d2: x/0 or 24 for A9
    388  1.4.4.2  nathanw *	d3: x/scratch - offset ptr into PTENRM array
    389  1.4.4.2  nathanw *	d4: LEN/Unchanged
    390  1.4.4.2  nathanw *	d5: 0/ICTR:LAMBDA
    391  1.4.4.2  nathanw *	d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
    392  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    393  1.4.4.2  nathanw *	a0: ptr for original operand/final result
    394  1.4.4.2  nathanw *	a1: x/ptr to PTENRM array
    395  1.4.4.2  nathanw *	a2: x/x
    396  1.4.4.2  nathanw *	fp0: float(ILOG)/Unchanged
    397  1.4.4.2  nathanw *	fp1: x/10^ISCALE
    398  1.4.4.2  nathanw *	fp2: x/x
    399  1.4.4.2  nathanw *	F_SCR1:x/x
    400  1.4.4.2  nathanw *	F_SCR2:Abs(X) with $3fff exponent/Unchanged
    401  1.4.4.2  nathanw *	L_SCR1:x/x
    402  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    403  1.4.4.2  nathanw 
    404  1.4.4.2  nathanw A7_str:	
    405  1.4.4.2  nathanw 	tst.l	d7		;test sign of k
    406  1.4.4.2  nathanw 	bgt.b	k_pos		;if pos and > 0, skip this
    407  1.4.4.2  nathanw 	cmp.l	d6,d7		;test k - ILOG
    408  1.4.4.2  nathanw 	blt.b	k_pos		;if ILOG >= k, skip this
    409  1.4.4.2  nathanw 	move.l	d7,d6		;if ((k<0) & (ILOG < k)) ILOG = k
    410  1.4.4.2  nathanw k_pos:	
    411  1.4.4.2  nathanw 	move.l	d6,d0		;calc ILOG + 1 - LEN in d0
    412  1.4.4.2  nathanw 	addq.l	#1,d0		;add the 1
    413  1.4.4.2  nathanw 	sub.l	d4,d0		;sub off LEN
    414  1.4.4.2  nathanw 	swap	d5		;use upper word of d5 for LAMBDA
    415  1.4.4.2  nathanw 	clr.w	d5		;set it zero initially
    416  1.4.4.2  nathanw 	clr.w	d2		;set up d2 for very small case
    417  1.4.4.2  nathanw 	tst.l	d0		;test sign of ISCALE
    418  1.4.4.2  nathanw 	bge.b	iscale		;if pos, skip next inst
    419  1.4.4.2  nathanw 	addq.w	#1,d5		;if neg, set LAMBDA true
    420  1.4.4.2  nathanw 	cmp.l	#$ffffecd4,d0	;test iscale <= -4908
    421  1.4.4.2  nathanw 	bgt.b	no_inf		;if false, skip rest
    422  1.4.4.2  nathanw 	addi.l	#24,d0		;add in 24 to iscale
    423  1.4.4.2  nathanw 	move.l	#24,d2		;put 24 in d2 for A9
    424  1.4.4.2  nathanw no_inf:	
    425  1.4.4.2  nathanw 	neg.l	d0		;and take abs of ISCALE
    426  1.4.4.2  nathanw iscale:	
    427  1.4.4.2  nathanw 	fmove.s	FONE,fp1	;init fp1 to 1
    428  1.4.4.2  nathanw 	bfextu	USER_FPCR(a6){26:2},d1 ;get initial rmode bits
    429  1.4.4.2  nathanw 	add.w	d1,d1		;put them in bits 2:1
    430  1.4.4.2  nathanw 	add.w	d5,d1		;add in LAMBDA
    431  1.4.4.2  nathanw 	add.w	d1,d1		;put them in bits 3:1
    432  1.4.4.2  nathanw 	tst.l	L_SCR2(a6)	;test sign of original x
    433  1.4.4.2  nathanw 	bge.b	x_pos		;if pos, don't set bit 0
    434  1.4.4.2  nathanw 	addq.l	#1,d1		;if neg, set bit 0
    435  1.4.4.2  nathanw x_pos:
    436  1.4.4.2  nathanw 	lea.l	RBDTBL,a2	;load rbdtbl base
    437  1.4.4.2  nathanw 	move.b	(a2,d1),d3	;load d3 with new rmode
    438  1.4.4.2  nathanw 	lsl.l	#4,d3		;put bits in proper position
    439  1.4.4.2  nathanw 	fmove.l	d3,fpcr		;load bits into fpu
    440  1.4.4.2  nathanw 	lsr.l	#4,d3		;put bits in proper position
    441  1.4.4.2  nathanw 	tst.b	d3		;decode new rmode for pten table
    442  1.4.4.2  nathanw 	bne.b	not_rn		;if zero, it is RN
    443  1.4.4.2  nathanw 	lea.l	PTENRN,a1	;load a1 with RN table base
    444  1.4.4.2  nathanw 	bra.b	rmode		;exit decode
    445  1.4.4.2  nathanw not_rn:
    446  1.4.4.2  nathanw 	lsr.b	#1,d3		;get lsb in carry
    447  1.4.4.2  nathanw 	bcc.b	not_rp		;if carry clear, it is RM
    448  1.4.4.2  nathanw 	lea.l	PTENRP,a1	;load a1 with RP table base
    449  1.4.4.2  nathanw 	bra.b	rmode		;exit decode
    450  1.4.4.2  nathanw not_rp:
    451  1.4.4.2  nathanw 	lea.l	PTENRM,a1	;load a1 with RM table base
    452  1.4.4.2  nathanw rmode:
    453  1.4.4.2  nathanw 	clr.l	d3		;clr table index
    454  1.4.4.2  nathanw e_loop:	
    455  1.4.4.2  nathanw 	lsr.l	#1,d0		;shift next bit into carry
    456  1.4.4.2  nathanw 	bcc.b	e_next		;if zero, skip the mul
    457  1.4.4.2  nathanw 	fmul.x	(a1,d3),fp1	;mul by 10**(d3_bit_no)
    458  1.4.4.2  nathanw e_next:	
    459  1.4.4.2  nathanw 	add.l	#12,d3		;inc d3 to next pwrten table entry
    460  1.4.4.2  nathanw 	tst.l	d0		;test if ISCALE is zero
    461  1.4.4.2  nathanw 	bne.b	e_loop		;if not, loop
    462  1.4.4.2  nathanw 
    463  1.4.4.2  nathanw 
    464  1.4.4.2  nathanw * A8. Clr INEX; Force RZ.
    465  1.4.4.2  nathanw *     The operation in A3 above may have set INEX2.  
    466  1.4.4.2  nathanw *     RZ mode is forced for the scaling operation to insure
    467  1.4.4.2  nathanw *     only one rounding error.  The grs bits are collected in 
    468  1.4.4.2  nathanw *     the INEX flag for use in A10.
    469  1.4.4.2  nathanw *
    470  1.4.4.2  nathanw * Register usage:
    471  1.4.4.2  nathanw *	Input/Output
    472  1.4.4.2  nathanw 
    473  1.4.4.2  nathanw 	fmove.l	#0,FPSR		;clr INEX 
    474  1.4.4.2  nathanw 	fmove.l	#rz_mode,FPCR	;set RZ rounding mode
    475  1.4.4.2  nathanw 
    476  1.4.4.2  nathanw 
    477  1.4.4.2  nathanw * A9. Scale X -> Y.
    478  1.4.4.2  nathanw *     The mantissa is scaled to the desired number of significant
    479  1.4.4.2  nathanw *     digits.  The excess digits are collected in INEX2. If mul,
    480  1.4.4.2  nathanw *     Check d2 for excess 10 exponential value.  If not zero, 
    481  1.4.4.2  nathanw *     the iscale value would have caused the pwrten calculation
    482  1.4.4.2  nathanw *     to overflow.  Only a negative iscale can cause this, so
    483  1.4.4.2  nathanw *     multiply by 10^(d2), which is now only allowed to be 24,
    484  1.4.4.2  nathanw *     with a multiply by 10^8 and 10^16, which is exact since
    485  1.4.4.2  nathanw *     10^24 is exact.  If the input was denormalized, we must
    486  1.4.4.2  nathanw *     create a busy stack frame with the mul command and the
    487  1.4.4.2  nathanw *     two operands, and allow the fpu to complete the multiply.
    488  1.4.4.2  nathanw *
    489  1.4.4.2  nathanw * Register usage:
    490  1.4.4.2  nathanw *	Input/Output
    491  1.4.4.2  nathanw *	d0: FPCR with RZ mode/Unchanged
    492  1.4.4.2  nathanw *	d2: 0 or 24/unchanged
    493  1.4.4.2  nathanw *	d3: x/x
    494  1.4.4.2  nathanw *	d4: LEN/Unchanged
    495  1.4.4.2  nathanw *	d5: ICTR:LAMBDA
    496  1.4.4.2  nathanw *	d6: ILOG/Unchanged
    497  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    498  1.4.4.2  nathanw *	a0: ptr for original operand/final result
    499  1.4.4.2  nathanw *	a1: ptr to PTENRM array/Unchanged
    500  1.4.4.2  nathanw *	a2: x/x
    501  1.4.4.2  nathanw *	fp0: float(ILOG)/X adjusted for SCALE (Y)
    502  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    503  1.4.4.2  nathanw *	fp2: x/x
    504  1.4.4.2  nathanw *	F_SCR1:x/x
    505  1.4.4.2  nathanw *	F_SCR2:Abs(X) with $3fff exponent/Unchanged
    506  1.4.4.2  nathanw *	L_SCR1:x/x
    507  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    508  1.4.4.2  nathanw 
    509  1.4.4.2  nathanw A9_str:	
    510  1.4.4.2  nathanw 	fmove.x	(a0),fp0	;load X from memory
    511  1.4.4.2  nathanw 	fabs.x	fp0		;use abs(X)
    512  1.4.4.2  nathanw 	tst.w	d5		;LAMBDA is in lower word of d5
    513  1.4.4.2  nathanw 	bne.b	short_sc_mul	;if neg (LAMBDA = 1), scale by mul
    514  1.4.4.2  nathanw 	fdiv.x	fp1,fp0		;calculate X / SCALE -> Y to fp0
    515  1.4.4.2  nathanw 	bra.b	A10_st		;branch to A10
    516  1.4.4.2  nathanw 
    517  1.4.4.2  nathanw sc_mul:
    518  1.4.4.2  nathanw short_sc_mul:
    519  1.4.4.2  nathanw 	tst.b	BINDEC_FLG(a6)	;check for denorm
    520  1.4.4.2  nathanw 	beq.b	A9_norm		;if norm, continue with mul
    521  1.4.4.2  nathanw 	fmovem.x fp1,-(a7)	;load ETEMP with 10^ISCALE
    522  1.4.4.2  nathanw 	move.l	8(a0),-(a7)	;load FPTEMP with input arg
    523  1.4.4.2  nathanw 	move.l	4(a0),-(a7)
    524  1.4.4.2  nathanw 	move.l	(a0),-(a7)
    525  1.4.4.2  nathanw 	move.l	#18,d3		;load count for busy stack
    526  1.4.4.2  nathanw A9_loop:
    527  1.4.4.2  nathanw 	clr.l	-(a7)		;clear lword on stack
    528  1.4.4.2  nathanw 	dbf.w	d3,A9_loop	
    529  1.4.4.2  nathanw 	move.b	VER_TMP(a6),(a7) ;write current version number
    530  1.4.4.2  nathanw 	move.b	#BUSY_SIZE-4,1(a7) ;write current busy size 
    531  1.4.4.2  nathanw 	move.b	#$10,$44(a7)	;set fcefpte[15] bit
    532  1.4.4.2  nathanw 	move.w	#$0023,$40(a7)	;load cmdreg1b with mul command
    533  1.4.4.2  nathanw 	move.b	#$fe,$8(a7)	;load all 1s to cu savepc
    534  1.4.4.2  nathanw 	frestore (a7)+		;restore frame to fpu for completion
    535  1.4.4.2  nathanw 	fmul.x	36(a1),fp0	;multiply fp0 by 10^8
    536  1.4.4.2  nathanw 	fmul.x	48(a1),fp0	;multiply fp0 by 10^16
    537  1.4.4.2  nathanw 	bra.b	A10_st
    538  1.4.4.2  nathanw A9_norm:
    539  1.4.4.2  nathanw 	tst.w	d2		;test for small exp case
    540  1.4.4.2  nathanw 	beq.b	A9_con		;if zero, continue as normal
    541  1.4.4.2  nathanw 	fmul.x	36(a1),fp0	;multiply fp0 by 10^8
    542  1.4.4.2  nathanw 	fmul.x	48(a1),fp0	;multiply fp0 by 10^16
    543  1.4.4.2  nathanw A9_con:
    544  1.4.4.2  nathanw 	fmul.x	fp1,fp0		;calculate X * SCALE -> Y to fp0
    545  1.4.4.2  nathanw 
    546  1.4.4.2  nathanw 
    547  1.4.4.2  nathanw * A10. Or in INEX.
    548  1.4.4.2  nathanw *      If INEX is set, round error occurred.  This is compensated
    549  1.4.4.2  nathanw *      for by 'or-ing' in the INEX2 flag to the lsb of Y.
    550  1.4.4.2  nathanw *
    551  1.4.4.2  nathanw * Register usage:
    552  1.4.4.2  nathanw *	Input/Output
    553  1.4.4.2  nathanw *	d0: FPCR with RZ mode/FPSR with INEX2 isolated
    554  1.4.4.2  nathanw *	d2: x/x
    555  1.4.4.2  nathanw *	d3: x/x
    556  1.4.4.2  nathanw *	d4: LEN/Unchanged
    557  1.4.4.2  nathanw *	d5: ICTR:LAMBDA
    558  1.4.4.2  nathanw *	d6: ILOG/Unchanged
    559  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    560  1.4.4.2  nathanw *	a0: ptr for original operand/final result
    561  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    562  1.4.4.2  nathanw *	a2: x/ptr to FP_SCR2(a6)
    563  1.4.4.2  nathanw *	fp0: Y/Y with lsb adjusted
    564  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    565  1.4.4.2  nathanw *	fp2: x/x
    566  1.4.4.2  nathanw 
    567  1.4.4.2  nathanw A10_st:	
    568  1.4.4.2  nathanw 	fmove.l	FPSR,d0		;get FPSR
    569  1.4.4.2  nathanw 	fmove.x	fp0,FP_SCR2(a6)	;move Y to memory
    570  1.4.4.2  nathanw 	lea.l	FP_SCR2(a6),a2	;load a2 with ptr to FP_SCR2
    571  1.4.4.2  nathanw 	btst.l	#9,d0		;check if INEX2 set
    572  1.4.4.2  nathanw 	beq.b	A11_st		;if clear, skip rest
    573  1.4.4.2  nathanw 	ori.l	#1,8(a2)	;or in 1 to lsb of mantissa
    574  1.4.4.2  nathanw 	fmove.x	FP_SCR2(a6),fp0	;write adjusted Y back to fpu
    575  1.4.4.2  nathanw 
    576  1.4.4.2  nathanw 
    577  1.4.4.2  nathanw * A11. Restore original FPCR; set size ext.
    578  1.4.4.2  nathanw *      Perform FINT operation in the user's rounding mode.  Keep
    579  1.4.4.2  nathanw *      the size to extended.  The sintdo entry point in the sint
    580  1.4.4.2  nathanw *      routine expects the FPCR value to be in USER_FPCR for
    581  1.4.4.2  nathanw *      mode and precision.  The original FPCR is saved in L_SCR1.
    582  1.4.4.2  nathanw 
    583  1.4.4.2  nathanw A11_st:	
    584  1.4.4.2  nathanw 	move.l	USER_FPCR(a6),L_SCR1(a6) ;save it for later
    585  1.4.4.2  nathanw 	andi.l	#$00000030,USER_FPCR(a6) ;set size to ext, 
    586  1.4.4.2  nathanw *					;block exceptions
    587  1.4.4.2  nathanw 
    588  1.4.4.2  nathanw 
    589  1.4.4.2  nathanw * A12. Calculate YINT = FINT(Y) according to user's rounding mode.
    590  1.4.4.2  nathanw *      The FPSP routine sintd0 is used.  The output is in fp0.
    591  1.4.4.2  nathanw *
    592  1.4.4.2  nathanw * Register usage:
    593  1.4.4.2  nathanw *	Input/Output
    594  1.4.4.2  nathanw *	d0: FPSR with AINEX cleared/FPCR with size set to ext
    595  1.4.4.2  nathanw *	d2: x/x/scratch
    596  1.4.4.2  nathanw *	d3: x/x
    597  1.4.4.2  nathanw *	d4: LEN/Unchanged
    598  1.4.4.2  nathanw *	d5: ICTR:LAMBDA/Unchanged
    599  1.4.4.2  nathanw *	d6: ILOG/Unchanged
    600  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    601  1.4.4.2  nathanw *	a0: ptr for original operand/src ptr for sintdo
    602  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    603  1.4.4.2  nathanw *	a2: ptr to FP_SCR2(a6)/Unchanged
    604  1.4.4.2  nathanw *	a6: temp pointer to FP_SCR2(a6) - orig value saved and restored
    605  1.4.4.2  nathanw *	fp0: Y/YINT
    606  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    607  1.4.4.2  nathanw *	fp2: x/x
    608  1.4.4.2  nathanw *	F_SCR1:x/x
    609  1.4.4.2  nathanw *	F_SCR2:Y adjusted for inex/Y with original exponent
    610  1.4.4.2  nathanw *	L_SCR1:x/original USER_FPCR
    611  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    612  1.4.4.2  nathanw 
    613  1.4.4.2  nathanw A12_st:
    614  1.4.4.2  nathanw 	movem.l	d0-d1/a0-a1,-(a7)	;save regs used by sintd0	
    615  1.4.4.2  nathanw 	move.l	L_SCR1(a6),-(a7)
    616  1.4.4.2  nathanw 	move.l	L_SCR2(a6),-(a7)
    617  1.4.4.2  nathanw 	lea.l	FP_SCR2(a6),a0		;a0 is ptr to F_SCR2(a6)
    618  1.4.4.2  nathanw 	fmove.x	fp0,(a0)		;move Y to memory at FP_SCR2(a6)
    619  1.4.4.2  nathanw 	tst.l	L_SCR2(a6)		;test sign of original operand
    620  1.4.4.2  nathanw 	bge.b	do_fint			;if pos, use Y 
    621  1.4.4.2  nathanw 	or.l	#$80000000,(a0)		;if neg, use -Y
    622  1.4.4.2  nathanw do_fint:
    623  1.4.4.2  nathanw 	move.l	USER_FPSR(a6),-(a7)
    624  1.4.4.2  nathanw 	bsr	sintdo			;sint routine returns int in fp0
    625  1.4.4.2  nathanw 	move.b	(a7),USER_FPSR(a6)
    626  1.4.4.2  nathanw 	add.l	#4,a7
    627  1.4.4.2  nathanw 	move.l	(a7)+,L_SCR2(a6)
    628  1.4.4.2  nathanw 	move.l	(a7)+,L_SCR1(a6)
    629  1.4.4.2  nathanw 	movem.l	(a7)+,d0-d1/a0-a1	;restore regs used by sint	
    630  1.4.4.2  nathanw 	move.l	L_SCR2(a6),FP_SCR2(a6)	;restore original exponent
    631  1.4.4.2  nathanw 	move.l	L_SCR1(a6),USER_FPCR(a6) ;restore user's FPCR
    632  1.4.4.2  nathanw 
    633  1.4.4.2  nathanw 
    634  1.4.4.2  nathanw * A13. Check for LEN digits.
    635  1.4.4.2  nathanw *      If the int operation results in more than LEN digits,
    636  1.4.4.2  nathanw *      or less than LEN -1 digits, adjust ILOG and repeat from
    637  1.4.4.2  nathanw *      A6.  This test occurs only on the first pass.  If the
    638  1.4.4.2  nathanw *      result is exactly 10^LEN, decrement ILOG and divide
    639  1.4.4.2  nathanw *      the mantissa by 10.  The calculation of 10^LEN cannot
    640  1.4.4.2  nathanw *      be inexact, since all powers of ten upto 10^27 are exact
    641  1.4.4.2  nathanw *      in extended precision, so the use of a previous power-of-ten
    642  1.4.4.2  nathanw *      table will introduce no error.
    643  1.4.4.2  nathanw *
    644  1.4.4.2  nathanw *
    645  1.4.4.2  nathanw * Register usage:
    646  1.4.4.2  nathanw *	Input/Output
    647  1.4.4.2  nathanw *	d0: FPCR with size set to ext/scratch final = 0
    648  1.4.4.2  nathanw *	d2: x/x
    649  1.4.4.2  nathanw *	d3: x/scratch final = x
    650  1.4.4.2  nathanw *	d4: LEN/LEN adjusted
    651  1.4.4.2  nathanw *	d5: ICTR:LAMBDA/LAMBDA:ICTR
    652  1.4.4.2  nathanw *	d6: ILOG/ILOG adjusted
    653  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    654  1.4.4.2  nathanw *	a0: pointer into memory for packed bcd string formation
    655  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    656  1.4.4.2  nathanw *	a2: ptr to FP_SCR2(a6)/Unchanged
    657  1.4.4.2  nathanw *	fp0: int portion of Y/abs(YINT) adjusted
    658  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    659  1.4.4.2  nathanw *	fp2: x/10^LEN
    660  1.4.4.2  nathanw *	F_SCR1:x/x
    661  1.4.4.2  nathanw *	F_SCR2:Y with original exponent/Unchanged
    662  1.4.4.2  nathanw *	L_SCR1:original USER_FPCR/Unchanged
    663  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    664  1.4.4.2  nathanw 
    665  1.4.4.2  nathanw A13_st:	
    666  1.4.4.2  nathanw 	swap	d5		;put ICTR in lower word of d5
    667  1.4.4.2  nathanw 	tst.w	d5		;check if ICTR = 0
    668  1.4.4.2  nathanw 	bne	not_zr		;if non-zero, go to second test
    669  1.4.4.2  nathanw *
    670  1.4.4.2  nathanw * Compute 10^(LEN-1)
    671  1.4.4.2  nathanw *
    672  1.4.4.2  nathanw 	fmove.s	FONE,fp2	;init fp2 to 1.0
    673  1.4.4.2  nathanw 	move.l	d4,d0		;put LEN in d0
    674  1.4.4.2  nathanw 	subq.l	#1,d0		;d0 = LEN -1
    675  1.4.4.2  nathanw 	clr.l	d3		;clr table index
    676  1.4.4.2  nathanw l_loop:	
    677  1.4.4.2  nathanw 	lsr.l	#1,d0		;shift next bit into carry
    678  1.4.4.2  nathanw 	bcc.b	l_next		;if zero, skip the mul
    679  1.4.4.2  nathanw 	fmul.x	(a1,d3),fp2	;mul by 10**(d3_bit_no)
    680  1.4.4.2  nathanw l_next:
    681  1.4.4.2  nathanw 	add.l	#12,d3		;inc d3 to next pwrten table entry
    682  1.4.4.2  nathanw 	tst.l	d0		;test if LEN is zero
    683  1.4.4.2  nathanw 	bne.b	l_loop		;if not, loop
    684  1.4.4.2  nathanw *
    685  1.4.4.2  nathanw * 10^LEN-1 is computed for this test and A14.  If the input was
    686  1.4.4.2  nathanw * denormalized, check only the case in which YINT > 10^LEN.
    687  1.4.4.2  nathanw *
    688  1.4.4.2  nathanw 	tst.b	BINDEC_FLG(a6)	;check if input was norm
    689  1.4.4.2  nathanw 	beq.b	A13_con		;if norm, continue with checking
    690  1.4.4.2  nathanw 	fabs.x	fp0		;take abs of YINT
    691  1.4.4.2  nathanw 	bra	test_2
    692  1.4.4.2  nathanw *
    693  1.4.4.2  nathanw * Compare abs(YINT) to 10^(LEN-1) and 10^LEN
    694  1.4.4.2  nathanw *
    695  1.4.4.2  nathanw A13_con:
    696  1.4.4.2  nathanw 	fabs.x	fp0		;take abs of YINT
    697  1.4.4.2  nathanw 	fcmp.x	fp2,fp0		;compare abs(YINT) with 10^(LEN-1)
    698  1.4.4.2  nathanw 	fbge.w	test_2		;if greater, do next test
    699  1.4.4.2  nathanw 	subq.l	#1,d6		;subtract 1 from ILOG
    700  1.4.4.2  nathanw 	move.w	#1,d5		;set ICTR
    701  1.4.4.2  nathanw 	fmove.l	#rm_mode,FPCR	;set rmode to RM
    702  1.4.4.2  nathanw 	fmul.s	FTEN,fp2	;compute 10^LEN 
    703  1.4.4.2  nathanw 	bra.w	A6_str		;return to A6 and recompute YINT
    704  1.4.4.2  nathanw test_2:
    705  1.4.4.2  nathanw 	fmul.s	FTEN,fp2	;compute 10^LEN
    706  1.4.4.2  nathanw 	fcmp.x	fp2,fp0		;compare abs(YINT) with 10^LEN
    707  1.4.4.2  nathanw 	fblt.w	A14_st		;if less, all is ok, go to A14
    708  1.4.4.2  nathanw 	fbgt.w	fix_ex		;if greater, fix and redo
    709  1.4.4.2  nathanw 	fdiv.s	FTEN,fp0	;if equal, divide by 10
    710  1.4.4.2  nathanw 	addq.l	#1,d6		; and inc ILOG
    711  1.4.4.2  nathanw 	bra.b	A14_st		; and continue elsewhere
    712  1.4.4.2  nathanw fix_ex:
    713  1.4.4.2  nathanw 	addq.l	#1,d6		;increment ILOG by 1
    714  1.4.4.2  nathanw 	move.w	#1,d5		;set ICTR
    715  1.4.4.2  nathanw 	fmove.l	#rm_mode,FPCR	;set rmode to RM
    716  1.4.4.2  nathanw 	bra.w	A6_str		;return to A6 and recompute YINT
    717  1.4.4.2  nathanw *
    718  1.4.4.2  nathanw * Since ICTR <> 0, we have already been through one adjustment, 
    719  1.4.4.2  nathanw * and shouldn't have another; this is to check if abs(YINT) = 10^LEN
    720  1.4.4.2  nathanw * 10^LEN is again computed using whatever table is in a1 since the
    721  1.4.4.2  nathanw * value calculated cannot be inexact.
    722  1.4.4.2  nathanw *
    723  1.4.4.2  nathanw not_zr:
    724  1.4.4.2  nathanw 	fmove.s	FONE,fp2	;init fp2 to 1.0
    725  1.4.4.2  nathanw 	move.l	d4,d0		;put LEN in d0
    726  1.4.4.2  nathanw 	clr.l	d3		;clr table index
    727  1.4.4.2  nathanw z_loop:
    728  1.4.4.2  nathanw 	lsr.l	#1,d0		;shift next bit into carry
    729  1.4.4.2  nathanw 	bcc.b	z_next		;if zero, skip the mul
    730  1.4.4.2  nathanw 	fmul.x	(a1,d3),fp2	;mul by 10**(d3_bit_no)
    731  1.4.4.2  nathanw z_next:
    732  1.4.4.2  nathanw 	add.l	#12,d3		;inc d3 to next pwrten table entry
    733  1.4.4.2  nathanw 	tst.l	d0		;test if LEN is zero
    734  1.4.4.2  nathanw 	bne.b	z_loop		;if not, loop
    735  1.4.4.2  nathanw 	fabs.x	fp0		;get abs(YINT)
    736  1.4.4.2  nathanw 	fcmp.x	fp2,fp0		;check if abs(YINT) = 10^LEN
    737  1.4.4.2  nathanw 	fbne.w	A14_st		;if not, skip this
    738  1.4.4.2  nathanw 	fdiv.s	FTEN,fp0	;divide abs(YINT) by 10
    739  1.4.4.2  nathanw 	addq.l	#1,d6		;and inc ILOG by 1
    740  1.4.4.2  nathanw 	addq.l	#1,d4		; and inc LEN
    741  1.4.4.2  nathanw 	fmul.s	FTEN,fp2	; if LEN++, the get 10^^LEN
    742  1.4.4.2  nathanw 
    743  1.4.4.2  nathanw 
    744  1.4.4.2  nathanw * A14. Convert the mantissa to bcd.
    745  1.4.4.2  nathanw *      The binstr routine is used to convert the LEN digit 
    746  1.4.4.2  nathanw *      mantissa to bcd in memory.  The input to binstr is
    747  1.4.4.2  nathanw *      to be a fraction; i.e. (mantissa)/10^LEN and adjusted
    748  1.4.4.2  nathanw *      such that the decimal point is to the left of bit 63.
    749  1.4.4.2  nathanw *      The bcd digits are stored in the correct position in 
    750  1.4.4.2  nathanw *      the final string area in memory.
    751  1.4.4.2  nathanw *
    752  1.4.4.2  nathanw *
    753  1.4.4.2  nathanw * Register usage:
    754  1.4.4.2  nathanw *	Input/Output
    755  1.4.4.2  nathanw *	d0: x/LEN call to binstr - final is 0
    756  1.4.4.2  nathanw *	d1: x/0
    757  1.4.4.2  nathanw *	d2: x/ms 32-bits of mant of abs(YINT)
    758  1.4.4.2  nathanw *	d3: x/ls 32-bits of mant of abs(YINT)
    759  1.4.4.2  nathanw *	d4: LEN/Unchanged
    760  1.4.4.2  nathanw *	d5: ICTR:LAMBDA/LAMBDA:ICTR
    761  1.4.4.2  nathanw *	d6: ILOG
    762  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    763  1.4.4.2  nathanw *	a0: pointer into memory for packed bcd string formation
    764  1.4.4.2  nathanw *	    /ptr to first mantissa byte in result string
    765  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    766  1.4.4.2  nathanw *	a2: ptr to FP_SCR2(a6)/Unchanged
    767  1.4.4.2  nathanw *	fp0: int portion of Y/abs(YINT) adjusted
    768  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    769  1.4.4.2  nathanw *	fp2: 10^LEN/Unchanged
    770  1.4.4.2  nathanw *	F_SCR1:x/Work area for final result
    771  1.4.4.2  nathanw *	F_SCR2:Y with original exponent/Unchanged
    772  1.4.4.2  nathanw *	L_SCR1:original USER_FPCR/Unchanged
    773  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    774  1.4.4.2  nathanw 
    775  1.4.4.2  nathanw A14_st:	
    776  1.4.4.2  nathanw 	fmove.l	#rz_mode,FPCR	;force rz for conversion
    777  1.4.4.2  nathanw 	fdiv.x	fp2,fp0		;divide abs(YINT) by 10^LEN
    778  1.4.4.2  nathanw 	lea.l	FP_SCR1(a6),a0
    779  1.4.4.2  nathanw 	fmove.x	fp0,(a0)	;move abs(YINT)/10^LEN to memory
    780  1.4.4.2  nathanw 	move.l	4(a0),d2	;move 2nd word of FP_RES to d2
    781  1.4.4.2  nathanw 	move.l	8(a0),d3	;move 3rd word of FP_RES to d3
    782  1.4.4.2  nathanw 	clr.l	4(a0)		;zero word 2 of FP_RES
    783  1.4.4.2  nathanw 	clr.l	8(a0)		;zero word 3 of FP_RES
    784  1.4.4.2  nathanw 	move.l	(a0),d0		;move exponent to d0
    785  1.4.4.2  nathanw 	swap	d0		;put exponent in lower word
    786  1.4.4.2  nathanw 	beq.b	no_sft		;if zero, don't shift
    787  1.4.4.2  nathanw 	subi.l	#$3ffd,d0	;sub bias less 2 to make fract
    788  1.4.4.2  nathanw 	tst.l	d0		;check if > 1
    789  1.4.4.2  nathanw 	bgt.b	no_sft		;if so, don't shift
    790  1.4.4.2  nathanw 	neg.l	d0		;make exp positive
    791  1.4.4.2  nathanw m_loop:
    792  1.4.4.2  nathanw 	lsr.l	#1,d2		;shift d2:d3 right, add 0s 
    793  1.4.4.2  nathanw 	roxr.l	#1,d3		;the number of places
    794  1.4.4.2  nathanw 	dbf.w	d0,m_loop	;given in d0
    795  1.4.4.2  nathanw no_sft:
    796  1.4.4.2  nathanw 	tst.l	d2		;check for mantissa of zero
    797  1.4.4.2  nathanw 	bne.b	no_zr		;if not, go on
    798  1.4.4.2  nathanw 	tst.l	d3		;continue zero check
    799  1.4.4.2  nathanw 	beq.b	zer_m		;if zero, go directly to binstr
    800  1.4.4.2  nathanw no_zr:
    801  1.4.4.2  nathanw 	clr.l	d1		;put zero in d1 for addx
    802  1.4.4.2  nathanw 	addi.l	#$00000080,d3	;inc at bit 7
    803  1.4.4.2  nathanw 	addx.l	d1,d2		;continue inc
    804  1.4.4.2  nathanw 	andi.l	#$ffffff80,d3	;strip off lsb not used by 882
    805  1.4.4.2  nathanw zer_m:
    806  1.4.4.2  nathanw 	move.l	d4,d0		;put LEN in d0 for binstr call
    807  1.4.4.2  nathanw 	addq.l	#3,a0		;a0 points to M16 byte in result
    808  1.4.4.2  nathanw 	bsr	binstr		;call binstr to convert mant
    809  1.4.4.2  nathanw 
    810  1.4.4.2  nathanw 
    811  1.4.4.2  nathanw * A15. Convert the exponent to bcd.
    812  1.4.4.2  nathanw *      As in A14 above, the exp is converted to bcd and the
    813  1.4.4.2  nathanw *      digits are stored in the final string.
    814  1.4.4.2  nathanw *
    815  1.4.4.2  nathanw *      Digits are stored in L_SCR1(a6) on return from BINDEC as:
    816  1.4.4.2  nathanw *
    817  1.4.4.2  nathanw *  	 32               16 15                0
    818  1.4.4.2  nathanw *	-----------------------------------------
    819  1.4.4.2  nathanw *  	|  0 | e3 | e2 | e1 | e4 |  X |  X |  X |
    820  1.4.4.2  nathanw *	-----------------------------------------
    821  1.4.4.2  nathanw *
    822  1.4.4.2  nathanw * And are moved into their proper places in FP_SCR1.  If digit e4
    823  1.4.4.2  nathanw * is non-zero, OPERR is signaled.  In all cases, all 4 digits are
    824  1.4.4.2  nathanw * written as specified in the 881/882 manual for packed decimal.
    825  1.4.4.2  nathanw *
    826  1.4.4.2  nathanw * Register usage:
    827  1.4.4.2  nathanw *	Input/Output
    828  1.4.4.2  nathanw *	d0: x/LEN call to binstr - final is 0
    829  1.4.4.2  nathanw *	d1: x/scratch (0);shift count for final exponent packing
    830  1.4.4.2  nathanw *	d2: x/ms 32-bits of exp fraction/scratch
    831  1.4.4.2  nathanw *	d3: x/ls 32-bits of exp fraction
    832  1.4.4.2  nathanw *	d4: LEN/Unchanged
    833  1.4.4.2  nathanw *	d5: ICTR:LAMBDA/LAMBDA:ICTR
    834  1.4.4.2  nathanw *	d6: ILOG
    835  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    836  1.4.4.2  nathanw *	a0: ptr to result string/ptr to L_SCR1(a6)
    837  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    838  1.4.4.2  nathanw *	a2: ptr to FP_SCR2(a6)/Unchanged
    839  1.4.4.2  nathanw *	fp0: abs(YINT) adjusted/float(ILOG)
    840  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    841  1.4.4.2  nathanw *	fp2: 10^LEN/Unchanged
    842  1.4.4.2  nathanw *	F_SCR1:Work area for final result/BCD result
    843  1.4.4.2  nathanw *	F_SCR2:Y with original exponent/ILOG/10^4
    844  1.4.4.2  nathanw *	L_SCR1:original USER_FPCR/Exponent digits on return from binstr
    845  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    846  1.4.4.2  nathanw 
    847  1.4.4.2  nathanw A15_st:	
    848  1.4.4.2  nathanw 	tst.b	BINDEC_FLG(a6)	;check for denorm
    849  1.4.4.2  nathanw 	beq.b	not_denorm
    850  1.4.4.2  nathanw 	ftst.x	fp0		;test for zero
    851  1.4.4.2  nathanw 	fbeq.w	den_zero	;if zero, use k-factor or 4933
    852  1.4.4.2  nathanw 	fmove.l	d6,fp0		;float ILOG
    853  1.4.4.2  nathanw 	fabs.x	fp0		;get abs of ILOG
    854  1.4.4.2  nathanw 	bra.b	convrt
    855  1.4.4.2  nathanw den_zero:
    856  1.4.4.2  nathanw 	tst.l	d7		;check sign of the k-factor
    857  1.4.4.2  nathanw 	blt.b	use_ilog	;if negative, use ILOG
    858  1.4.4.2  nathanw 	fmove.s	F4933,fp0	;force exponent to 4933
    859  1.4.4.2  nathanw 	bra.b	convrt		;do it
    860  1.4.4.2  nathanw use_ilog:
    861  1.4.4.2  nathanw 	fmove.l	d6,fp0		;float ILOG
    862  1.4.4.2  nathanw 	fabs.x	fp0		;get abs of ILOG
    863  1.4.4.2  nathanw 	bra.b	convrt
    864  1.4.4.2  nathanw not_denorm:
    865  1.4.4.2  nathanw 	ftst.x	fp0		;test for zero
    866  1.4.4.2  nathanw 	fbne.w	not_zero	;if zero, force exponent
    867  1.4.4.2  nathanw 	fmove.s	FONE,fp0	;force exponent to 1
    868  1.4.4.2  nathanw 	bra.b	convrt		;do it
    869  1.4.4.2  nathanw not_zero:	
    870  1.4.4.2  nathanw 	fmove.l	d6,fp0		;float ILOG
    871  1.4.4.2  nathanw 	fabs.x	fp0		;get abs of ILOG
    872  1.4.4.2  nathanw convrt:
    873  1.4.4.2  nathanw 	fdiv.x	24(a1),fp0	;compute ILOG/10^4
    874  1.4.4.2  nathanw 	fmove.x	fp0,FP_SCR2(a6)	;store fp0 in memory
    875  1.4.4.2  nathanw 	move.l	4(a2),d2	;move word 2 to d2
    876  1.4.4.2  nathanw 	move.l	8(a2),d3	;move word 3 to d3
    877  1.4.4.2  nathanw 	move.w	(a2),d0		;move exp to d0
    878  1.4.4.2  nathanw 	beq.b	x_loop_fin	;if zero, skip the shift
    879  1.4.4.2  nathanw 	subi.w	#$3ffd,d0	;subtract off bias
    880  1.4.4.2  nathanw 	neg.w	d0		;make exp positive
    881  1.4.4.2  nathanw x_loop:
    882  1.4.4.2  nathanw 	lsr.l	#1,d2		;shift d2:d3 right 
    883  1.4.4.2  nathanw 	roxr.l	#1,d3		;the number of places
    884  1.4.4.2  nathanw 	dbf.w	d0,x_loop	;given in d0
    885  1.4.4.2  nathanw x_loop_fin:
    886  1.4.4.2  nathanw 	clr.l	d1		;put zero in d1 for addx
    887  1.4.4.2  nathanw 	addi.l	#$00000080,d3	;inc at bit 6
    888  1.4.4.2  nathanw 	addx.l	d1,d2		;continue inc
    889  1.4.4.2  nathanw 	andi.l	#$ffffff80,d3	;strip off lsb not used by 882
    890  1.4.4.2  nathanw 	move.l	#4,d0		;put 4 in d0 for binstr call
    891  1.4.4.2  nathanw 	lea.l	L_SCR1(a6),a0	;a0 is ptr to L_SCR1 for exp digits
    892  1.4.4.2  nathanw 	bsr	binstr		;call binstr to convert exp
    893  1.4.4.2  nathanw 	move.l	L_SCR1(a6),d0	;load L_SCR1 lword to d0 
    894  1.4.4.2  nathanw 	move.l	#12,d1		;use d1 for shift count
    895  1.4.4.2  nathanw 	lsr.l	d1,d0		;shift d0 right by 12
    896  1.4.4.2  nathanw 	bfins	d0,FP_SCR1(a6){4:12} ;put e3:e2:e1 in FP_SCR1
    897  1.4.4.2  nathanw 	lsr.l	d1,d0		;shift d0 right by 12
    898  1.4.4.2  nathanw 	bfins	d0,FP_SCR1(a6){16:4} ;put e4 in FP_SCR1 
    899  1.4.4.2  nathanw 	tst.b	d0		;check if e4 is zero
    900  1.4.4.2  nathanw 	beq.b	A16_st		;if zero, skip rest
    901  1.4.4.2  nathanw 	or.l	#opaop_mask,USER_FPSR(a6) ;set OPERR & AIOP in USER_FPSR
    902  1.4.4.2  nathanw 
    903  1.4.4.2  nathanw 
    904  1.4.4.2  nathanw * A16. Write sign bits to final string.
    905  1.4.4.2  nathanw *	   Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
    906  1.4.4.2  nathanw *
    907  1.4.4.2  nathanw * Register usage:
    908  1.4.4.2  nathanw *	Input/Output
    909  1.4.4.2  nathanw *	d0: x/scratch - final is x
    910  1.4.4.2  nathanw *	d2: x/x
    911  1.4.4.2  nathanw *	d3: x/x
    912  1.4.4.2  nathanw *	d4: LEN/Unchanged
    913  1.4.4.2  nathanw *	d5: ICTR:LAMBDA/LAMBDA:ICTR
    914  1.4.4.2  nathanw *	d6: ILOG/ILOG adjusted
    915  1.4.4.2  nathanw *	d7: k-factor/Unchanged
    916  1.4.4.2  nathanw *	a0: ptr to L_SCR1(a6)/Unchanged
    917  1.4.4.2  nathanw *	a1: ptr to PTENxx array/Unchanged
    918  1.4.4.2  nathanw *	a2: ptr to FP_SCR2(a6)/Unchanged
    919  1.4.4.2  nathanw *	fp0: float(ILOG)/Unchanged
    920  1.4.4.2  nathanw *	fp1: 10^ISCALE/Unchanged
    921  1.4.4.2  nathanw *	fp2: 10^LEN/Unchanged
    922  1.4.4.2  nathanw *	F_SCR1:BCD result with correct signs
    923  1.4.4.2  nathanw *	F_SCR2:ILOG/10^4
    924  1.4.4.2  nathanw *	L_SCR1:Exponent digits on return from binstr
    925  1.4.4.2  nathanw *	L_SCR2:first word of X packed/Unchanged
    926  1.4.4.2  nathanw 
    927  1.4.4.2  nathanw A16_st:
    928  1.4.4.2  nathanw 	clr.l	d0		;clr d0 for collection of signs
    929  1.4.4.2  nathanw 	andi.b	#$0f,FP_SCR1(a6) ;clear first nibble of FP_SCR1 
    930  1.4.4.2  nathanw 	tst.l	L_SCR2(a6)	;check sign of original mantissa
    931  1.4.4.2  nathanw 	bge.b	mant_p		;if pos, don't set SM
    932  1.4.4.2  nathanw 	moveq.l	#2,d0		;move 2 in to d0 for SM
    933  1.4.4.2  nathanw mant_p:
    934  1.4.4.2  nathanw 	tst.l	d6		;check sign of ILOG
    935  1.4.4.2  nathanw 	bge.b	wr_sgn		;if pos, don't set SE
    936  1.4.4.2  nathanw 	addq.l	#1,d0		;set bit 0 in d0 for SE 
    937  1.4.4.2  nathanw wr_sgn:
    938  1.4.4.2  nathanw 	bfins	d0,FP_SCR1(a6){0:2} ;insert SM and SE into FP_SCR1
    939  1.4.4.2  nathanw 
    940  1.4.4.2  nathanw * Clean up and restore all registers used.
    941  1.4.4.2  nathanw 
    942  1.4.4.2  nathanw 	fmove.l	#0,FPSR		;clear possible inex2/ainex bits
    943  1.4.4.2  nathanw 	fmovem.x (a7)+,fp0-fp2
    944  1.4.4.2  nathanw 	movem.l	(a7)+,d2-d7/a2
    945  1.4.4.2  nathanw 	rts
    946  1.4.4.2  nathanw 
    947  1.4.4.2  nathanw 	end
    948