xref: /netbsd-src/sys/arch/m68k/fpsp/kernel_ex.sa (revision 57fb77a14ebcd83f1fae16b59e7b83fd0f166e03)
1*57fb77a1Scgd*	$NetBSD: kernel_ex.sa,v 1.2 1994/10/26 07:49:12 cgd Exp $
2*57fb77a1Scgd
322ef5fa9Smycroft*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
422ef5fa9Smycroft*	M68000 Hi-Performance Microprocessor Division
522ef5fa9Smycroft*	M68040 Software Package
622ef5fa9Smycroft*
722ef5fa9Smycroft*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
822ef5fa9Smycroft*	All rights reserved.
922ef5fa9Smycroft*
1022ef5fa9Smycroft*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
1122ef5fa9Smycroft*	To the maximum extent permitted by applicable law,
1222ef5fa9Smycroft*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
1322ef5fa9Smycroft*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
1422ef5fa9Smycroft*	PARTICULAR PURPOSE and any warranty against infringement with
1522ef5fa9Smycroft*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
1622ef5fa9Smycroft*	and any accompanying written materials.
1722ef5fa9Smycroft*
1822ef5fa9Smycroft*	To the maximum extent permitted by applicable law,
1922ef5fa9Smycroft*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
2022ef5fa9Smycroft*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
2122ef5fa9Smycroft*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
2222ef5fa9Smycroft*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
2322ef5fa9Smycroft*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
2422ef5fa9Smycroft*	and support of the SOFTWARE.
2522ef5fa9Smycroft*
2622ef5fa9Smycroft*	You are hereby granted a copyright license to use, modify, and
2722ef5fa9Smycroft*	distribute the SOFTWARE so long as this entire notice is retained
2822ef5fa9Smycroft*	without alteration in any modified and/or redistributed versions,
2922ef5fa9Smycroft*	and that such modified versions are clearly identified as such.
3022ef5fa9Smycroft*	No licenses are granted by implication, estoppel or otherwise
3122ef5fa9Smycroft*	under any patents or trademarks of Motorola, Inc.
3222ef5fa9Smycroft
3322ef5fa9Smycroft*
3422ef5fa9Smycroft*	kernel_ex.sa 3.3 12/19/90
3522ef5fa9Smycroft*
3622ef5fa9Smycroft* This file contains routines to force exception status in the
3722ef5fa9Smycroft* fpu for exceptional cases detected or reported within the
3822ef5fa9Smycroft* transcendental functions.  Typically, the t_xx routine will
3922ef5fa9Smycroft* set the appropriate bits in the USER_FPSR word on the stack.
4022ef5fa9Smycroft* The bits are tested in gen_except.sa to determine if an exceptional
4122ef5fa9Smycroft* situation needs to be created on return from the FPSP.
4222ef5fa9Smycroft*
4322ef5fa9Smycroft
4422ef5fa9SmycroftKERNEL_EX    IDNT    2,1 Motorola 040 Floating Point Software Package
4522ef5fa9Smycroft
4622ef5fa9Smycroft	section    8
4722ef5fa9Smycroft
4822ef5fa9Smycroft	include	fpsp.h
4922ef5fa9Smycroft
5022ef5fa9Smycroftmns_inf  dc.l $ffff0000,$00000000,$00000000
5122ef5fa9Smycroftpls_inf  dc.l $7fff0000,$00000000,$00000000
5222ef5fa9Smycroftnan      dc.l $7fff0000,$ffffffff,$ffffffff
5322ef5fa9Smycrofthuge     dc.l $7ffe0000,$ffffffff,$ffffffff
5422ef5fa9Smycroft
5522ef5fa9Smycroft	xref	  ovf_r_k
5622ef5fa9Smycroft	xref	  unf_sub
5722ef5fa9Smycroft	xref	  nrm_set
5822ef5fa9Smycroft
5922ef5fa9Smycroft	xdef   	  t_dz
6022ef5fa9Smycroft	xdef      t_dz2
6122ef5fa9Smycroft	xdef      t_operr
6222ef5fa9Smycroft	xdef      t_unfl
6322ef5fa9Smycroft	xdef      t_ovfl
6422ef5fa9Smycroft	xdef      t_ovfl2
6522ef5fa9Smycroft	xdef      t_inx2
6622ef5fa9Smycroft	xdef	  t_frcinx
6722ef5fa9Smycroft	xdef	  t_extdnrm
6822ef5fa9Smycroft	xdef	  t_resdnrm
6922ef5fa9Smycroft	xdef	  dst_nan
7022ef5fa9Smycroft	xdef	  src_nan
7122ef5fa9Smycroft*
7222ef5fa9Smycroft*	DZ exception
7322ef5fa9Smycroft*
7422ef5fa9Smycroft*
7522ef5fa9Smycroft*	if dz trap disabled
7622ef5fa9Smycroft*		store properly signed inf (use sign of etemp) into fp0
7722ef5fa9Smycroft*		set FPSR exception status dz bit, condition code
7822ef5fa9Smycroft*		inf bit, and accrued dz bit
7922ef5fa9Smycroft*		return
8022ef5fa9Smycroft*		frestore the frame into the machine (done by unimp_hd)
8122ef5fa9Smycroft*
8222ef5fa9Smycroft*	else dz trap enabled
8322ef5fa9Smycroft*		set exception status bit & accrued bits in FPSR
8422ef5fa9Smycroft*		set flag to disable sto_res from corrupting fp register
8522ef5fa9Smycroft*		return
8622ef5fa9Smycroft*		frestore the frame into the machine (done by unimp_hd)
8722ef5fa9Smycroft*
8822ef5fa9Smycroft* t_dz2 is used by monadic functions such as flogn (from do_func).
8922ef5fa9Smycroft* t_dz is used by monadic functions such as satanh (from the
9022ef5fa9Smycroft* transcendental function).
9122ef5fa9Smycroft*
9222ef5fa9Smycroftt_dz2:
9322ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set neg bit in FPSR
9422ef5fa9Smycroft	fmove.l	#0,FPSR			;clr status bits (Z set)
9522ef5fa9Smycroft	btst.b	#dz_bit,FPCR_ENABLE(a6)	;test FPCR for dz exc enabled
9622ef5fa9Smycroft	bne.b	dz_ena_end
9722ef5fa9Smycroft	bra.b	m_inf			;flogx always returns -inf
9822ef5fa9Smycroftt_dz:
9922ef5fa9Smycroft	fmove.l	#0,FPSR			;clr status bits (Z set)
10022ef5fa9Smycroft	btst.b	#dz_bit,FPCR_ENABLE(a6)	;test FPCR for dz exc enabled
10122ef5fa9Smycroft	bne.b	dz_ena
10222ef5fa9Smycroft*
10322ef5fa9Smycroft*	dz disabled
10422ef5fa9Smycroft*
10522ef5fa9Smycroft	btst.b	#sign_bit,ETEMP_EX(a6)	;check sign for neg or pos
10622ef5fa9Smycroft	beq.b	p_inf			;branch if pos sign
10722ef5fa9Smycroft
10822ef5fa9Smycroftm_inf:
10922ef5fa9Smycroft	fmovem.x mns_inf,fp0		;load -inf
11022ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set neg bit in FPSR
11122ef5fa9Smycroft	bra.b	set_fpsr
11222ef5fa9Smycroftp_inf:
11322ef5fa9Smycroft	fmovem.x pls_inf,fp0		;load +inf
11422ef5fa9Smycroftset_fpsr:
11522ef5fa9Smycroft	or.l	#dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
11622ef5fa9Smycroft	rts
11722ef5fa9Smycroft*
11822ef5fa9Smycroft*	dz enabled
11922ef5fa9Smycroft*
12022ef5fa9Smycroftdz_ena:
12122ef5fa9Smycroft	btst.b	#sign_bit,ETEMP_EX(a6)	;check sign for neg or pos
12222ef5fa9Smycroft	beq.b	dz_ena_end
12322ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set neg bit in FPSR
12422ef5fa9Smycroftdz_ena_end:
12522ef5fa9Smycroft	or.l	#dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
12622ef5fa9Smycroft	st.b	STORE_FLG(a6)
12722ef5fa9Smycroft	rts
12822ef5fa9Smycroft*
12922ef5fa9Smycroft*	OPERR exception
13022ef5fa9Smycroft*
13122ef5fa9Smycroft*	if (operr trap disabled)
13222ef5fa9Smycroft*		set FPSR exception status operr bit, condition code
13322ef5fa9Smycroft*		nan bit; Store default NAN into fp0
13422ef5fa9Smycroft*		frestore the frame into the machine (done by unimp_hd)
13522ef5fa9Smycroft*
13622ef5fa9Smycroft*	else (operr trap enabled)
13722ef5fa9Smycroft*		set FPSR exception status operr bit, accrued operr bit
13822ef5fa9Smycroft*		set flag to disable sto_res from corrupting fp register
13922ef5fa9Smycroft*		frestore the frame into the machine (done by unimp_hd)
14022ef5fa9Smycroft*
14122ef5fa9Smycroftt_operr:
14222ef5fa9Smycroft	or.l	#opnan_mask,USER_FPSR(a6) ;set NaN, OPERR, AIOP
14322ef5fa9Smycroft
14422ef5fa9Smycroft	btst.b	#operr_bit,FPCR_ENABLE(a6) ;test FPCR for operr enabled
14522ef5fa9Smycroft	bne.b	op_ena
14622ef5fa9Smycroft
14722ef5fa9Smycroft	fmovem.x nan,fp0		;load default nan
14822ef5fa9Smycroft	rts
14922ef5fa9Smycroftop_ena:
15022ef5fa9Smycroft	st.b	STORE_FLG(a6)		;do not corrupt destination
15122ef5fa9Smycroft	rts
15222ef5fa9Smycroft
15322ef5fa9Smycroft*
15422ef5fa9Smycroft*	t_unfl --- UNFL exception
15522ef5fa9Smycroft*
15622ef5fa9Smycroft* This entry point is used by all routines requiring unfl, inex2,
15722ef5fa9Smycroft* aunfl, and ainex to be set on exit.
15822ef5fa9Smycroft*
15922ef5fa9Smycroft* On entry, a0 points to the exceptional operand.  The final exceptional
16022ef5fa9Smycroft* operand is built in FP_SCR1 and only the sign from the original operand
16122ef5fa9Smycroft* is used.
16222ef5fa9Smycroft*
16322ef5fa9Smycroftt_unfl:
16422ef5fa9Smycroft	clr.l	FP_SCR1(a6)		;set exceptional operand to zero
16522ef5fa9Smycroft	clr.l	FP_SCR1+4(a6)
16622ef5fa9Smycroft	clr.l	FP_SCR1+8(a6)
16722ef5fa9Smycroft	tst.b	(a0)			;extract sign from caller's exop
16822ef5fa9Smycroft	bpl.b	unfl_signok
16922ef5fa9Smycroft	bset	#sign_bit,FP_SCR1(a6)
17022ef5fa9Smycroftunfl_signok:
17122ef5fa9Smycroft	lea.l	FP_SCR1(a6),a0
17222ef5fa9Smycroft	or.l	#unfinx_mask,USER_FPSR(a6)
17322ef5fa9Smycroft*					;set UNFL, INEX2, AUNFL, AINEX
17422ef5fa9Smycroftunfl_con:
17522ef5fa9Smycroft	btst.b	#unfl_bit,FPCR_ENABLE(a6)
17622ef5fa9Smycroft	beq.b	unfl_dis
17722ef5fa9Smycroft
17822ef5fa9Smycroftunfl_ena:
17922ef5fa9Smycroft	bfclr	STAG(a6){5:3}		;clear wbtm66,wbtm1,wbtm0
18022ef5fa9Smycroft	bset.b	#wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
18122ef5fa9Smycroft	bset.b	#sticky_bit,STICKY(a6)	;set sticky bit
18222ef5fa9Smycroft
18322ef5fa9Smycroft	bclr.b	#E1,E_BYTE(a6)
18422ef5fa9Smycroft
18522ef5fa9Smycroftunfl_dis:
18622ef5fa9Smycroft	bfextu	FPCR_MODE(a6){0:2},d0	;get round precision
18722ef5fa9Smycroft
18822ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)
18922ef5fa9Smycroft	sne	LOCAL_SGN(a0)		;convert to internal ext format
19022ef5fa9Smycroft
19122ef5fa9Smycroft	bsr	unf_sub			;returns IEEE result at a0
19222ef5fa9Smycroft*					;and sets FPSR_CC accordingly
19322ef5fa9Smycroft
19422ef5fa9Smycroft	bfclr	LOCAL_SGN(a0){0:8}	;convert back to IEEE ext format
19522ef5fa9Smycroft	beq.b	unfl_fin
19622ef5fa9Smycroft
19722ef5fa9Smycroft	bset.b	#sign_bit,LOCAL_EX(a0)
19822ef5fa9Smycroft	bset.b	#sign_bit,FP_SCR1(a6)	;set sign bit of exc operand
19922ef5fa9Smycroft
20022ef5fa9Smycroftunfl_fin:
20122ef5fa9Smycroft	fmovem.x (a0),fp0		;store result in fp0
20222ef5fa9Smycroft	rts
20322ef5fa9Smycroft
20422ef5fa9Smycroft
20522ef5fa9Smycroft*
20622ef5fa9Smycroft*	t_ovfl2 --- OVFL exception (without inex2 returned)
20722ef5fa9Smycroft*
20822ef5fa9Smycroft* This entry is used by scale to force catastrophic overflow.  The
20922ef5fa9Smycroft* ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
21022ef5fa9Smycroft*
21122ef5fa9Smycroftt_ovfl2:
21222ef5fa9Smycroft	or.l	#ovfl_inx_mask,USER_FPSR(a6)
21322ef5fa9Smycroft	move.l	ETEMP(a6),FP_SCR1(a6)
21422ef5fa9Smycroft	move.l	ETEMP_HI(a6),FP_SCR1+4(a6)
21522ef5fa9Smycroft	move.l	ETEMP_LO(a6),FP_SCR1+8(a6)
21622ef5fa9Smycroft*
21722ef5fa9Smycroft* Check for single or double round precision.  If single, check if
21822ef5fa9Smycroft* the lower 40 bits of ETEMP are zero; if not, set inex2.  If double,
21922ef5fa9Smycroft* check if the lower 21 bits are zero; if not, set inex2.
22022ef5fa9Smycroft*
22122ef5fa9Smycroft	move.b	FPCR_MODE(a6),d0
22222ef5fa9Smycroft	andi.b	#$c0,d0
22322ef5fa9Smycroft	beq.w	t_work		;if extended, finish ovfl processing
22422ef5fa9Smycroft	cmpi.b	#$40,d0		;test for single
22522ef5fa9Smycroft	bne.b	t_dbl
22622ef5fa9Smycroftt_sgl:
22722ef5fa9Smycroft	tst.b	ETEMP_LO(a6)
22822ef5fa9Smycroft	bne.b	t_setinx2
22922ef5fa9Smycroft	move.l	ETEMP_HI(a6),d0
23022ef5fa9Smycroft	andi.l	#$ff,d0		;look at only lower 8 bits
23122ef5fa9Smycroft	bne.b	t_setinx2
23222ef5fa9Smycroft	bra.w	t_work
23322ef5fa9Smycroftt_dbl:
23422ef5fa9Smycroft	move.l	ETEMP_LO(a6),d0
23522ef5fa9Smycroft	andi.l	#$7ff,d0	;look at only lower 11 bits
23622ef5fa9Smycroft	beq.w	t_work
23722ef5fa9Smycroftt_setinx2:
23822ef5fa9Smycroft	or.l	#inex2_mask,USER_FPSR(a6)
23922ef5fa9Smycroft	bra.b	t_work
24022ef5fa9Smycroft*
24122ef5fa9Smycroft*	t_ovfl --- OVFL exception
24222ef5fa9Smycroft*
24322ef5fa9Smycroft*** Note: the exc operand is returned in ETEMP.
24422ef5fa9Smycroft*
24522ef5fa9Smycroftt_ovfl:
24622ef5fa9Smycroft	or.l	#ovfinx_mask,USER_FPSR(a6)
24722ef5fa9Smycroftt_work:
24822ef5fa9Smycroft	btst.b	#ovfl_bit,FPCR_ENABLE(a6) ;test FPCR for ovfl enabled
24922ef5fa9Smycroft	beq.b	ovf_dis
25022ef5fa9Smycroft
25122ef5fa9Smycroftovf_ena:
25222ef5fa9Smycroft	clr.l	FP_SCR1(a6)		;set exceptional operand
25322ef5fa9Smycroft	clr.l	FP_SCR1+4(a6)
25422ef5fa9Smycroft	clr.l	FP_SCR1+8(a6)
25522ef5fa9Smycroft
25622ef5fa9Smycroft	bfclr	STAG(a6){5:3}		;clear wbtm66,wbtm1,wbtm0
25722ef5fa9Smycroft	bclr.b	#wbtemp15_bit,WB_BYTE(a6) ;clear wbtemp15
25822ef5fa9Smycroft	bset.b	#sticky_bit,STICKY(a6)	;set sticky bit
25922ef5fa9Smycroft
26022ef5fa9Smycroft	bclr.b	#E1,E_BYTE(a6)
26122ef5fa9Smycroft*					;fall through to disabled case
26222ef5fa9Smycroft
26322ef5fa9Smycroft* For disabled overflow call 'ovf_r_k'.  This routine loads the
26422ef5fa9Smycroft* correct result based on the rounding precision, destination
26522ef5fa9Smycroft* format, rounding mode and sign.
26622ef5fa9Smycroft*
26722ef5fa9Smycroftovf_dis:
26822ef5fa9Smycroft	bsr	ovf_r_k			;returns unsigned ETEMP_EX
26922ef5fa9Smycroft*					;and sets FPSR_CC accordingly.
27022ef5fa9Smycroft	bfclr	ETEMP_SGN(a6){0:8}	;fix sign
27122ef5fa9Smycroft	beq.b	ovf_pos
27222ef5fa9Smycroft	bset.b	#sign_bit,ETEMP_EX(a6)
27322ef5fa9Smycroft	bset.b	#sign_bit,FP_SCR1(a6)	;set exceptional operand sign
27422ef5fa9Smycroftovf_pos:
27522ef5fa9Smycroft	fmovem.x ETEMP(a6),fp0		;move the result to fp0
27622ef5fa9Smycroft	rts
27722ef5fa9Smycroft
27822ef5fa9Smycroft
27922ef5fa9Smycroft*
28022ef5fa9Smycroft*	INEX2 exception
28122ef5fa9Smycroft*
28222ef5fa9Smycroft* The inex2 and ainex bits are set.
28322ef5fa9Smycroft*
28422ef5fa9Smycroftt_inx2:
28522ef5fa9Smycroft	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
28622ef5fa9Smycroft	rts
28722ef5fa9Smycroft
28822ef5fa9Smycroft*
28922ef5fa9Smycroft*	Force Inex2
29022ef5fa9Smycroft*
29122ef5fa9Smycroft* This routine is called by the transcendental routines to force
29222ef5fa9Smycroft* the inex2 exception bits set in the FPSR.  If the underflow bit
29322ef5fa9Smycroft* is set, but the underflow trap was not taken, the aunfl bit in
29422ef5fa9Smycroft* the FPSR must be set.
29522ef5fa9Smycroft*
29622ef5fa9Smycroftt_frcinx:
29722ef5fa9Smycroft	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
29822ef5fa9Smycroft	btst.b	#unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
29922ef5fa9Smycroft	beq.b	no_uacc1		;if clear, do not set aunfl
30022ef5fa9Smycroft	bset.b	#aunfl_bit,FPSR_AEXCEPT(a6)
30122ef5fa9Smycroftno_uacc1:
30222ef5fa9Smycroft	rts
30322ef5fa9Smycroft
30422ef5fa9Smycroft*
30522ef5fa9Smycroft*	DST_NAN
30622ef5fa9Smycroft*
30722ef5fa9Smycroft* Determine if the destination nan is signalling or non-signalling,
30822ef5fa9Smycroft* and set the FPSR bits accordingly.  See the MC68040 User's Manual
30922ef5fa9Smycroft* section 3.2.2.5 NOT-A-NUMBERS.
31022ef5fa9Smycroft*
31122ef5fa9Smycroftdst_nan:
31222ef5fa9Smycroft	btst.b	#sign_bit,FPTEMP_EX(a6) ;test sign of nan
31322ef5fa9Smycroft	beq.b	dst_pos			;if clr, it was positive
31422ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set N bit
31522ef5fa9Smycroftdst_pos:
31622ef5fa9Smycroft	btst.b	#signan_bit,FPTEMP_HI(a6) ;check if signalling
31722ef5fa9Smycroft	beq.b	dst_snan		;branch if signalling
31822ef5fa9Smycroft
31922ef5fa9Smycroft	fmove.l	d1,fpcr			;restore user's rmode/prec
32022ef5fa9Smycroft	fmove.x FPTEMP(a6),fp0		;return the non-signalling nan
32122ef5fa9Smycroft*
32222ef5fa9Smycroft* Check the source nan.  If it is signalling, snan will be reported.
32322ef5fa9Smycroft*
32422ef5fa9Smycroft	move.b	STAG(a6),d0
32522ef5fa9Smycroft	andi.b	#$e0,d0
32622ef5fa9Smycroft	cmpi.b	#$60,d0
32722ef5fa9Smycroft	bne.b	no_snan
32822ef5fa9Smycroft	btst.b	#signan_bit,ETEMP_HI(a6) ;check if signalling
32922ef5fa9Smycroft	bne.b	no_snan
33022ef5fa9Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
33122ef5fa9Smycroftno_snan:
33222ef5fa9Smycroft	rts
33322ef5fa9Smycroft
33422ef5fa9Smycroftdst_snan:
33522ef5fa9Smycroft	btst.b	#snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
33622ef5fa9Smycroft	beq.b	dst_dis			;branch if disabled
33722ef5fa9Smycroft
33822ef5fa9Smycroft	or.b	#nan_tag,DTAG(a6)	;set up dtag for nan
33922ef5fa9Smycroft	st.b	STORE_FLG(a6)		;do not store a result
34022ef5fa9Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
34122ef5fa9Smycroft	rts
34222ef5fa9Smycroft
34322ef5fa9Smycroftdst_dis:
34422ef5fa9Smycroft	bset.b	#signan_bit,FPTEMP_HI(a6) ;set SNAN bit in sop
34522ef5fa9Smycroft	fmove.l	d1,fpcr			;restore user's rmode/prec
34622ef5fa9Smycroft	fmove.x FPTEMP(a6),fp0		;load non-sign. nan
34722ef5fa9Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
34822ef5fa9Smycroft	rts
34922ef5fa9Smycroft
35022ef5fa9Smycroft*
35122ef5fa9Smycroft*	SRC_NAN
35222ef5fa9Smycroft*
35322ef5fa9Smycroft* Determine if the source nan is signalling or non-signalling,
35422ef5fa9Smycroft* and set the FPSR bits accordingly.  See the MC68040 User's Manual
35522ef5fa9Smycroft* section 3.2.2.5 NOT-A-NUMBERS.
35622ef5fa9Smycroft*
35722ef5fa9Smycroftsrc_nan:
35822ef5fa9Smycroft	btst.b	#sign_bit,ETEMP_EX(a6) ;test sign of nan
35922ef5fa9Smycroft	beq.b	src_pos			;if clr, it was positive
36022ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set N bit
36122ef5fa9Smycroftsrc_pos:
36222ef5fa9Smycroft	btst.b	#signan_bit,ETEMP_HI(a6) ;check if signalling
36322ef5fa9Smycroft	beq.b	src_snan		;branch if signalling
36422ef5fa9Smycroft	fmove.l	d1,fpcr			;restore user's rmode/prec
36522ef5fa9Smycroft	fmove.x ETEMP(a6),fp0		;return the non-signalling nan
36622ef5fa9Smycroft	rts
36722ef5fa9Smycroft
36822ef5fa9Smycroftsrc_snan:
36922ef5fa9Smycroft	btst.b	#snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
37022ef5fa9Smycroft	beq.b	src_dis			;branch if disabled
37122ef5fa9Smycroft	bset.b	#signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
37222ef5fa9Smycroft	or.b	#norm_tag,DTAG(a6)	;set up dtag for norm
37322ef5fa9Smycroft	or.b	#nan_tag,STAG(a6)	;set up stag for nan
37422ef5fa9Smycroft	st.b	STORE_FLG(a6)		;do not store a result
37522ef5fa9Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
37622ef5fa9Smycroft	rts
37722ef5fa9Smycroft
37822ef5fa9Smycroftsrc_dis:
37922ef5fa9Smycroft	bset.b	#signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
38022ef5fa9Smycroft	fmove.l	d1,fpcr			;restore user's rmode/prec
38122ef5fa9Smycroft	fmove.x ETEMP(a6),fp0		;load non-sign. nan
38222ef5fa9Smycroft	or.l	#snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
38322ef5fa9Smycroft	rts
38422ef5fa9Smycroft
38522ef5fa9Smycroft*
38622ef5fa9Smycroft* For all functions that have a denormalized input and that f(x)=x,
38722ef5fa9Smycroft* this is the entry point
38822ef5fa9Smycroft*
38922ef5fa9Smycroftt_extdnrm:
39022ef5fa9Smycroft	or.l	#unfinx_mask,USER_FPSR(a6)
39122ef5fa9Smycroft*					;set UNFL, INEX2, AUNFL, AINEX
39222ef5fa9Smycroft	bra.b	xdnrm_con
39322ef5fa9Smycroft*
39422ef5fa9Smycroft* Entry point for scale with extended denorm.  The function does
39522ef5fa9Smycroft* not set inex2, aunfl, or ainex.
39622ef5fa9Smycroft*
39722ef5fa9Smycroftt_resdnrm:
39822ef5fa9Smycroft	or.l	#unfl_mask,USER_FPSR(a6)
39922ef5fa9Smycroft
40022ef5fa9Smycroftxdnrm_con:
40122ef5fa9Smycroft	btst.b	#unfl_bit,FPCR_ENABLE(a6)
40222ef5fa9Smycroft	beq.b	xdnrm_dis
40322ef5fa9Smycroft
40422ef5fa9Smycroft*
40522ef5fa9Smycroft* If exceptions are enabled, the additional task of setting up WBTEMP
40622ef5fa9Smycroft* is needed so that when the underflow exception handler is entered,
40722ef5fa9Smycroft* the user perceives no difference between what the 040 provides vs.
40822ef5fa9Smycroft* what the FPSP provides.
40922ef5fa9Smycroft*
41022ef5fa9Smycroftxdnrm_ena:
41122ef5fa9Smycroft	move.l	a0,-(a7)
41222ef5fa9Smycroft
41322ef5fa9Smycroft	move.l	LOCAL_EX(a0),FP_SCR1(a6)
41422ef5fa9Smycroft	move.l	LOCAL_HI(a0),FP_SCR1+4(a6)
41522ef5fa9Smycroft	move.l	LOCAL_LO(a0),FP_SCR1+8(a6)
41622ef5fa9Smycroft
41722ef5fa9Smycroft	lea	FP_SCR1(a6),a0
41822ef5fa9Smycroft
41922ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)
42022ef5fa9Smycroft	sne	LOCAL_SGN(a0)		;convert to internal ext format
42122ef5fa9Smycroft	tst.w	LOCAL_EX(a0)		;check if input is denorm
42222ef5fa9Smycroft	beq.b	xdnrm_dn		;if so, skip nrm_set
42322ef5fa9Smycroft	bsr	nrm_set			;normalize the result (exponent
42422ef5fa9Smycroft*					;will be negative
42522ef5fa9Smycroftxdnrm_dn:
42622ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)	;take off false sign
42722ef5fa9Smycroft	bfclr	LOCAL_SGN(a0){0:8}	;change back to IEEE ext format
42822ef5fa9Smycroft	beq.b	xdep
42922ef5fa9Smycroft	bset.b	#sign_bit,LOCAL_EX(a0)
43022ef5fa9Smycroftxdep:
43122ef5fa9Smycroft	bfclr	STAG(a6){5:3}		;clear wbtm66,wbtm1,wbtm0
43222ef5fa9Smycroft	bset.b	#wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
43322ef5fa9Smycroft	bclr.b	#sticky_bit,STICKY(a6)	;clear sticky bit
43422ef5fa9Smycroft	bclr.b	#E1,E_BYTE(a6)
43522ef5fa9Smycroft	move.l	(a7)+,a0
43622ef5fa9Smycroftxdnrm_dis:
43722ef5fa9Smycroft	bfextu	FPCR_MODE(a6){0:2},d0	;get round precision
43822ef5fa9Smycroft	bne.b	not_ext			;if not round extended, store
43922ef5fa9Smycroft*					;IEEE defaults
44022ef5fa9Smycroftis_ext:
44122ef5fa9Smycroft	btst.b	#sign_bit,LOCAL_EX(a0)
44222ef5fa9Smycroft	beq.b	xdnrm_store
44322ef5fa9Smycroft
44422ef5fa9Smycroft	bset.b	#neg_bit,FPSR_CC(a6)	;set N bit in FPSR_CC
44522ef5fa9Smycroft
44622ef5fa9Smycroft	bra.b	xdnrm_store
44722ef5fa9Smycroft
44822ef5fa9Smycroftnot_ext:
44922ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)
45022ef5fa9Smycroft	sne	LOCAL_SGN(a0)		;convert to internal ext format
45122ef5fa9Smycroft	bsr	unf_sub			;returns IEEE result pointed by
45222ef5fa9Smycroft*					;a0; sets FPSR_CC accordingly
45322ef5fa9Smycroft	bfclr	LOCAL_SGN(a0){0:8}	;convert back to IEEE ext format
45422ef5fa9Smycroft	beq.b	xdnrm_store
45522ef5fa9Smycroft	bset.b	#sign_bit,LOCAL_EX(a0)
45622ef5fa9Smycroftxdnrm_store:
45722ef5fa9Smycroft	fmovem.x (a0),fp0		;store result in fp0
45822ef5fa9Smycroft	rts
45922ef5fa9Smycroft
46022ef5fa9Smycroft*
46122ef5fa9Smycroft* This subroutine is used for dyadic operations that use an extended
46222ef5fa9Smycroft* denorm within the kernel. The approach used is to capture the frame,
46322ef5fa9Smycroft* fix/restore.
46422ef5fa9Smycroft*
46522ef5fa9Smycroft	xdef	t_avoid_unsupp
46622ef5fa9Smycroftt_avoid_unsupp:
46722ef5fa9Smycroft	link	a2,#-LOCAL_SIZE		;so that a2 fpsp.h negative
46822ef5fa9Smycroft*					;offsets may be used
46922ef5fa9Smycroft	fsave	-(a7)
47022ef5fa9Smycroft	tst.b	1(a7)			;check if idle, exit if so
47122ef5fa9Smycroft	beq.w	idle_end
47222ef5fa9Smycroft	btst.b	#E1,E_BYTE(a2)		;check for an E1 exception if
47322ef5fa9Smycroft*					;enabled, there is an unsupp
47422ef5fa9Smycroft	beq.w	end_avun		;else, exit
47522ef5fa9Smycroft	btst.b	#7,DTAG(a2)		;check for denorm destination
47622ef5fa9Smycroft	beq.b	src_den			;else, must be a source denorm
47722ef5fa9Smycroft*
47822ef5fa9Smycroft* handle destination denorm
47922ef5fa9Smycroft*
48022ef5fa9Smycroft	lea	FPTEMP(a2),a0
48122ef5fa9Smycroft	btst.b	#sign_bit,LOCAL_EX(a0)
48222ef5fa9Smycroft	sne	LOCAL_SGN(a0)		;convert to internal ext format
48322ef5fa9Smycroft	bclr.b	#7,DTAG(a2)		;set DTAG to norm
48422ef5fa9Smycroft	bsr	nrm_set			;normalize result, exponent
48522ef5fa9Smycroft*					;will become negative
48622ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)	;get rid of fake sign
48722ef5fa9Smycroft	bfclr	LOCAL_SGN(a0){0:8}	;convert back to IEEE ext format
48822ef5fa9Smycroft	beq.b	ck_src_den		;check if source is also denorm
48922ef5fa9Smycroft	bset.b	#sign_bit,LOCAL_EX(a0)
49022ef5fa9Smycroftck_src_den:
49122ef5fa9Smycroft	btst.b	#7,STAG(a2)
49222ef5fa9Smycroft	beq.b	end_avun
49322ef5fa9Smycroftsrc_den:
49422ef5fa9Smycroft	lea	ETEMP(a2),a0
49522ef5fa9Smycroft	btst.b	#sign_bit,LOCAL_EX(a0)
49622ef5fa9Smycroft	sne	LOCAL_SGN(a0)		;convert to internal ext format
49722ef5fa9Smycroft	bclr.b	#7,STAG(a2)		;set STAG to norm
49822ef5fa9Smycroft	bsr	nrm_set			;normalize result, exponent
49922ef5fa9Smycroft*					;will become negative
50022ef5fa9Smycroft	bclr.b	#sign_bit,LOCAL_EX(a0)	;get rid of fake sign
50122ef5fa9Smycroft	bfclr	LOCAL_SGN(a0){0:8}	;convert back to IEEE ext format
50222ef5fa9Smycroft	beq.b	den_com
50322ef5fa9Smycroft	bset.b	#sign_bit,LOCAL_EX(a0)
50422ef5fa9Smycroftden_com:
50522ef5fa9Smycroft	move.b	#$fe,CU_SAVEPC(a2)	;set continue frame
50622ef5fa9Smycroft	clr.w	NMNEXC(a2)		;clear NMNEXC
50722ef5fa9Smycroft	bclr.b	#E1,E_BYTE(a2)
50822ef5fa9Smycroft*	fmove.l	FPSR,FPSR_SHADOW(a2)
50922ef5fa9Smycroft*	bset.b	#SFLAG,E_BYTE(a2)
51022ef5fa9Smycroft*	bset.b	#XFLAG,T_BYTE(a2)
51122ef5fa9Smycroftend_avun:
51222ef5fa9Smycroft	frestore (a7)+
51322ef5fa9Smycroft	unlk	a2
51422ef5fa9Smycroft	rts
51522ef5fa9Smycroftidle_end:
51622ef5fa9Smycroft	add.l	#4,a7
51722ef5fa9Smycroft	unlk	a2
51822ef5fa9Smycroft	rts
51922ef5fa9Smycroft	end
520