162306a36Sopenharmony_ci|
262306a36Sopenharmony_ci|	sgetem.sa 3.1 12/10/90
362306a36Sopenharmony_ci|
462306a36Sopenharmony_ci|	The entry point sGETEXP returns the exponent portion
562306a36Sopenharmony_ci|	of the input argument.  The exponent bias is removed
662306a36Sopenharmony_ci|	and the exponent value is returned as an extended
762306a36Sopenharmony_ci|	precision number in fp0.  sGETEXPD handles denormalized
862306a36Sopenharmony_ci|	numbers.
962306a36Sopenharmony_ci|
1062306a36Sopenharmony_ci|	The entry point sGETMAN extracts the mantissa of the
1162306a36Sopenharmony_ci|	input argument.  The mantissa is converted to an
1262306a36Sopenharmony_ci|	extended precision number and returned in fp0.  The
1362306a36Sopenharmony_ci|	range of the result is [1.0 - 2.0).
1462306a36Sopenharmony_ci|
1562306a36Sopenharmony_ci|
1662306a36Sopenharmony_ci|	Input:  Double-extended number X in the ETEMP space in
1762306a36Sopenharmony_ci|		the floating-point save stack.
1862306a36Sopenharmony_ci|
1962306a36Sopenharmony_ci|	Output:	The functions return exp(X) or man(X) in fp0.
2062306a36Sopenharmony_ci|
2162306a36Sopenharmony_ci|	Modified: fp0.
2262306a36Sopenharmony_ci|
2362306a36Sopenharmony_ci|
2462306a36Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
2562306a36Sopenharmony_ci|			All Rights Reserved
2662306a36Sopenharmony_ci|
2762306a36Sopenharmony_ci|       For details on the license for this file, please see the
2862306a36Sopenharmony_ci|       file, README, in this same directory.
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci|SGETEM	idnt	2,1 | Motorola 040 Floating Point Software Package
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	|section 8
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#include "fpsp.h"
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	|xref	nrm_set
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci|
3962306a36Sopenharmony_ci| This entry point is used by the unimplemented instruction exception
4062306a36Sopenharmony_ci| handler.  It points a0 to the input operand.
4162306a36Sopenharmony_ci|
4262306a36Sopenharmony_ci|
4362306a36Sopenharmony_ci|
4462306a36Sopenharmony_ci|	SGETEXP
4562306a36Sopenharmony_ci|
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	.global	sgetexp
4862306a36Sopenharmony_cisgetexp:
4962306a36Sopenharmony_ci	movew	LOCAL_EX(%a0),%d0	|get the exponent
5062306a36Sopenharmony_ci	bclrl	#15,%d0		|clear the sign bit
5162306a36Sopenharmony_ci	subw	#0x3fff,%d0	|subtract off the bias
5262306a36Sopenharmony_ci	fmovew  %d0,%fp0		|move the exp to fp0
5362306a36Sopenharmony_ci	rts
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	.global	sgetexpd
5662306a36Sopenharmony_cisgetexpd:
5762306a36Sopenharmony_ci	bclrb	#sign_bit,LOCAL_EX(%a0)
5862306a36Sopenharmony_ci	bsr	nrm_set		|normalize (exp will go negative)
5962306a36Sopenharmony_ci	movew	LOCAL_EX(%a0),%d0	|load resulting exponent into d0
6062306a36Sopenharmony_ci	subw	#0x3fff,%d0	|subtract off the bias
6162306a36Sopenharmony_ci	fmovew	%d0,%fp0		|move the exp to fp0
6262306a36Sopenharmony_ci	rts
6362306a36Sopenharmony_ci|
6462306a36Sopenharmony_ci|
6562306a36Sopenharmony_ci| This entry point is used by the unimplemented instruction exception
6662306a36Sopenharmony_ci| handler.  It points a0 to the input operand.
6762306a36Sopenharmony_ci|
6862306a36Sopenharmony_ci|
6962306a36Sopenharmony_ci|
7062306a36Sopenharmony_ci|	SGETMAN
7162306a36Sopenharmony_ci|
7262306a36Sopenharmony_ci|
7362306a36Sopenharmony_ci| For normalized numbers, leave the mantissa alone, simply load
7462306a36Sopenharmony_ci| with an exponent of +/- $3fff.
7562306a36Sopenharmony_ci|
7662306a36Sopenharmony_ci	.global	sgetman
7762306a36Sopenharmony_cisgetman:
7862306a36Sopenharmony_ci	movel	USER_FPCR(%a6),%d0
7962306a36Sopenharmony_ci	andil	#0xffffff00,%d0	|clear rounding precision and mode
8062306a36Sopenharmony_ci	fmovel	%d0,%fpcr		|this fpcr setting is used by the 882
8162306a36Sopenharmony_ci	movew	LOCAL_EX(%a0),%d0	|get the exp (really just want sign bit)
8262306a36Sopenharmony_ci	orw	#0x7fff,%d0	|clear old exp
8362306a36Sopenharmony_ci	bclrl	#14,%d0		|make it the new exp +-3fff
8462306a36Sopenharmony_ci	movew	%d0,LOCAL_EX(%a0)	|move the sign & exp back to fsave stack
8562306a36Sopenharmony_ci	fmovex	(%a0),%fp0	|put new value back in fp0
8662306a36Sopenharmony_ci	rts
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci|
8962306a36Sopenharmony_ci| For denormalized numbers, shift the mantissa until the j-bit = 1,
9062306a36Sopenharmony_ci| then load the exponent with +/1 $3fff.
9162306a36Sopenharmony_ci|
9262306a36Sopenharmony_ci	.global	sgetmand
9362306a36Sopenharmony_cisgetmand:
9462306a36Sopenharmony_ci	movel	LOCAL_HI(%a0),%d0	|load ms mant in d0
9562306a36Sopenharmony_ci	movel	LOCAL_LO(%a0),%d1	|load ls mant in d1
9662306a36Sopenharmony_ci	bsr	shft		|shift mantissa bits till msbit is set
9762306a36Sopenharmony_ci	movel	%d0,LOCAL_HI(%a0)	|put ms mant back on stack
9862306a36Sopenharmony_ci	movel	%d1,LOCAL_LO(%a0)	|put ls mant back on stack
9962306a36Sopenharmony_ci	bras	sgetman
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci|
10262306a36Sopenharmony_ci|	SHFT
10362306a36Sopenharmony_ci|
10462306a36Sopenharmony_ci|	Shifts the mantissa bits until msbit is set.
10562306a36Sopenharmony_ci|	input:
10662306a36Sopenharmony_ci|		ms mantissa part in d0
10762306a36Sopenharmony_ci|		ls mantissa part in d1
10862306a36Sopenharmony_ci|	output:
10962306a36Sopenharmony_ci|		shifted bits in d0 and d1
11062306a36Sopenharmony_cishft:
11162306a36Sopenharmony_ci	tstl	%d0		|if any bits set in ms mant
11262306a36Sopenharmony_ci	bnes	upper		|then branch
11362306a36Sopenharmony_ci|				;else no bits set in ms mant
11462306a36Sopenharmony_ci	tstl	%d1		|test if any bits set in ls mant
11562306a36Sopenharmony_ci	bnes	cont		|if set then continue
11662306a36Sopenharmony_ci	bras	shft_end	|else return
11762306a36Sopenharmony_cicont:
11862306a36Sopenharmony_ci	movel	%d3,-(%a7)	|save d3
11962306a36Sopenharmony_ci	exg	%d0,%d1		|shift ls mant to ms mant
12062306a36Sopenharmony_ci	bfffo	%d0{#0:#32},%d3	|find first 1 in ls mant to d0
12162306a36Sopenharmony_ci	lsll	%d3,%d0		|shift first 1 to integer bit in ms mant
12262306a36Sopenharmony_ci	movel	(%a7)+,%d3	|restore d3
12362306a36Sopenharmony_ci	bras	shft_end
12462306a36Sopenharmony_ciupper:
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	moveml	%d3/%d5/%d6,-(%a7)	|save registers
12762306a36Sopenharmony_ci	bfffo	%d0{#0:#32},%d3	|find first 1 in ls mant to d0
12862306a36Sopenharmony_ci	lsll	%d3,%d0		|shift ms mant until j-bit is set
12962306a36Sopenharmony_ci	movel	%d1,%d6		|save ls mant in d6
13062306a36Sopenharmony_ci	lsll	%d3,%d1		|shift ls mant by count
13162306a36Sopenharmony_ci	movel	#32,%d5
13262306a36Sopenharmony_ci	subl	%d3,%d5		|sub 32 from shift for ls mant
13362306a36Sopenharmony_ci	lsrl	%d5,%d6		|shift off all bits but those that will
13462306a36Sopenharmony_ci|				;be shifted into ms mant
13562306a36Sopenharmony_ci	orl	%d6,%d0		|shift the ls mant bits into the ms mant
13662306a36Sopenharmony_ci	moveml	(%a7)+,%d3/%d5/%d6	|restore registers
13762306a36Sopenharmony_cishft_end:
13862306a36Sopenharmony_ci	rts
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	|end
141