[BACK]Return to l_support.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

File: [local] / sys / arch / m68k / fpsp / l_support.sa (download)

Revision 1.1, Tue Mar 4 16:07:06 2008 UTC (16 years, 2 months ago) by nbrk
Branch point for: MAIN

Initial revision

*	$OpenBSD: l_support.sa,v 1.2 1996/05/29 21:05:31 niklas Exp $
*	$NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd Exp $

*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
*	M68000 Hi-Performance Microprocessor Division
*	M68040 Software Package 
*
*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
*	All rights reserved.
*
*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
*	To the maximum extent permitted by applicable law,
*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
*	PARTICULAR PURPOSE and any warranty against infringement with
*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
*	and any accompanying written materials. 
*
*	To the maximum extent permitted by applicable law,
*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
*	and support of the SOFTWARE.  
*
*	You are hereby granted a copyright license to use, modify, and
*	distribute the SOFTWARE so long as this entire notice is retained
*	without alteration in any modified and/or redistributed versions,
*	and that such modified versions are clearly identified as such.
*	No licenses are granted by implication, estoppel or otherwise
*	under any patents or trademarks of Motorola, Inc.

*
*	l_support.sa 1.2 5/1/91
*

L_SUPPORT    IDNT    2,1 Motorola 040 Floating Point Software Package

	section    8

mns_one  dc.l $bfff0000,$80000000,$00000000
pls_one  dc.l $3fff0000,$80000000,$00000000
pls_inf  dc.l $7fff0000,$00000000,$00000000
pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff
mns_huge dc.l $fffe0000,$ffffffff,$ffffffff
pls_tiny dc.l $00000000,$80000000,$00000000
mns_tiny dc.l $80000000,$80000000,$00000000
small    dc.l $20000000,$80000000,$00000000
pls_zero dc.l $00000000,$00000000,$00000000

	include	l_fpsp.h

*
* 	tag --- determine the type of an extended precision operand
*
*	The tag values returned match the way the 68040 would have
*	tagged them.
*
*	Input:	a0 points to operand
*
*	Output	d0.b	= $00 norm
*			  $20 zero
*			  $40 inf
*			  $60 nan
*			  $80 denorm
*		All other registers are unchanged
*
	xdef	tag
tag:
	move.w	LOCAL_EX(a0),d0
	andi.w	#$7fff,d0
	beq.b	chk_zro
	cmpi.w	#$7fff,d0
	beq.b	chk_inf
tag_nrm:
	clr.b	d0
	rts
tag_nan:
	move.b	#$60,d0
	rts
tag_dnrm:
	move.b	#$80,d0
	rts
chk_zro:
	btst.b	#7,LOCAL_HI(a0)	# check if J-bit is set
	bne.b	tag_nrm
	tst.l	LOCAL_HI(a0)
	bne.b	tag_dnrm
	tst.l	LOCAL_LO(a0)
	bne.b	tag_dnrm
tag_zero:
	move.b	#$20,d0
	rts
chk_inf:
	tst.l	LOCAL_HI(a0)
	bne.b	tag_nan
	tst.l	LOCAL_LO(a0)
	bne.b	tag_nan
tag_inf:
	move.b	#$40,d0
	rts

*
*	t_dz, t_dz2 --- divide by zero exception
*
* t_dz2 is used by monadic functions such as flogn (from do_func).
* t_dz is used by monadic functions such as satanh (from the 
* transcendental function).
*
	xdef    t_dz2
t_dz2:
	fmovem.x	mns_one,fp0
	fmove.l	d1,fpcr
	fdiv.x		pls_zero,fp0
	rts

	xdef	t_dz
t_dz:
	btst.b	#sign_bit,ETEMP_EX(a6)	;check sign for neg or pos
	beq.b	p_inf			;branch if pos sign
m_inf:
	fmovem.x mns_one,fp0
	fmove.l	d1,fpcr
	fdiv.x		pls_zero,fp0
	rts
p_inf:
	fmovem.x pls_one,fp0
	fmove.l	d1,fpcr
	fdiv.x		pls_zero,fp0
	rts
*
*	t_operr --- Operand Error exception
*
	xdef    t_operr
t_operr:
	fmovem.x	pls_inf,fp0
	fmove.l	d1,fpcr
	fmul.x		pls_zero,fp0
	rts

*
*	t_unfl --- UNFL exception
*
	xdef    t_unfl
t_unfl:
	btst.b	#sign_bit,ETEMP(a6)
	beq.b	unf_pos
unf_neg:
	fmovem.x	mns_tiny,fp0
	fmove.l	d1,fpcr
	fmul.x	pls_tiny,fp0
	rts
	
unf_pos:
	fmovem.x	pls_tiny,fp0
	fmove.l	d1,fpcr
	fmul.x	fp0,fp0
	rts
*
*	t_ovfl --- OVFL exception
*
*	t_ovfl is called as an exit for monadic functions.  t_ovfl2
*	is for dyadic exits.
*
	xdef   		t_ovfl
t_ovfl:
	xdef   		t_ovfl2
	move.l		d1,USER_FPCR(a6)	user's control register
	move.l		#ovfinx_mask,d0
	bra.b		t_work
t_ovfl2:
	move.l		#ovfl_inx_mask,d0
t_work:
	btst.b		#sign_bit,ETEMP(a6)
	beq.b		ovf_pos
ovf_neg:
	fmovem.x	mns_huge,fp0
	fmove.l		USER_FPCR(a6),fpcr
	fmul.x		pls_huge,fp0
	fmove.l		fpsr,d1
	or.l		d1,d0
	fmove.l		d0,fpsr
	rts
ovf_pos:
	fmovem.x	pls_huge,fp0
	fmove.l		USER_FPCR(a6),fpcr
	fmul.x		pls_huge,fp0
	fmove.l		fpsr,d1
	or.l		d1,d0
	fmove.l		d0,fpsr
	rts
*
*	t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6))
*
	xdef    t_inx2
t_inx2:
	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
	fmove.l		USER_FPCR(a6),fpcr
*
* create an inex2 exception by adding two numbers with very different exponents
* do the add in fp1 so as to not disturb the result sitting in fp0
*
	fmove.x		pls_one,fp1
	fadd.x		small,fp1
*
	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
	fmove.l	USER_FPSR(a6),fpsr
	rts
*
*	t_frcinx --- Force Inex2 (for monadic functions)
*
	xdef	t_frcinx
t_frcinx:
	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
	fmove.l		d1,fpcr
*
* create an inex2 exception by adding two numbers with very different exponents
* do the add in fp1 so as to not disturb the result sitting in fp0
*
	fmove.x		pls_one,fp1
	fadd.x		small,fp1
*
	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
	btst.b	#unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
	beq.b	no_uacc1		;if clear, do not set aunfl
	bset.b	#aunfl_bit,FPSR_AEXCEPT(a6)
no_uacc1:
	fmove.l	USER_FPSR(a6),fpsr
	rts
*
*	dst_nan --- force result when destination is a NaN
*
	xdef	dst_nan
dst_nan:
	fmove.l	USER_FPCR(a6),fpcr
	fmove.x FPTEMP(a6),fp0
	rts

*
*	src_nan --- force result when source is a NaN
*
	xdef	src_nan
src_nan:
	fmove.l	USER_FPCR(a6),fpcr
	fmove.x	ETEMP(a6),fp0
	rts
*
*	mon_nan --- force result when source is a NaN (monadic version)
*
*	This is the same as src_nan except that the user's fpcr comes
*	in via d1, not USER_FPCR(a6).
*
	xdef	mon_nan
mon_nan:
	fmove.l	d1,fpcr
	fmove.x	ETEMP(a6),fp0
	rts
*
*	t_extdnrm, t_resdnrm --- generate results for denorm inputs
*
*	For all functions that have a denormalized input and that f(x)=x,
*	this is the entry point.
*
	xdef	t_extdnrm
t_extdnrm:
	fmove.l	d1,fpcr
	fmove.x	LOCAL_EX(a0),fp0
	fmove.l		fpsr,d0
	or.l		#unfinx_mask,d0
	fmove.l		d0,fpsr
	rts

	xdef	t_resdnrm
t_resdnrm:
	fmove.l	USER_FPCR(a6),fpcr
	fmove.x	LOCAL_EX(a0),fp0
	fmove.l		fpsr,d0
	or.l		#unfl_mask,d0
	fmove.l		d0,fpsr
	rts
*
*
*
	xdef	t_avoid_unsupp
t_avoid_unsupp:
	fmove.x	fp0,fp0
	rts

	xdef	sto_cos
sto_cos:
	fmovem.x LOCAL_EX(a0),fp1
	rts
*
*	Native instruction support
*
*	Some systems may need entry points even for 68040 native
*	instructions.  These routines are provided for
*	convenience.
*
	xdef	sadd
sadd:
	fmovem.x	FPTEMP(a6),fp0
	fmove.l	USER_FPCR(a6),fpcr
	fadd.x	ETEMP(a6),fp0
	rts

	xdef	ssub
ssub:
	fmovem.x	FPTEMP(a6),fp0
	fmove.l	USER_FPCR(a6),fpcr
	fsub.x	ETEMP(a6),fp0
	rts

	xdef	smul
smul:
	fmovem.x	FPTEMP(a6),fp0
	fmove.l	USER_FPCR(a6),fpcr
	fmul.x	ETEMP(a6),fp0
	rts

	xdef	sdiv
sdiv:
	fmovem.x	FPTEMP(a6),fp0
	fmove.l	USER_FPCR(a6),fpcr
	fdiv.x	ETEMP(a6),fp0
	rts

	xdef	sabs
sabs:
	fmovem.x	ETEMP(a6),fp0
	fmove.l	d1,fpcr
	fabs.x	fp0
	rts

	xdef	sneg
sneg:
	fmovem.x	ETEMP(a6),fp0
	fmove.l	d1,fpcr
	fneg.x	fp0
	rts

	xdef	ssqrt
ssqrt:
	fmovem.x	ETEMP(a6),fp0
	fmove.l	d1,fpcr
	fsqrt.x	fp0
	rts

*
*	l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz
*
*	On entry, move the user's FPCR to USER_FPCR.
*
*	On return from, we need to pickup the INEX2/AINEX bits
*	that are in USER_FPSR.
*
	xref	sint
	xref	sintrz
	xref	sintd

	xdef	l_sint
l_sint:
	move.l	d1,USER_FPCR(a6)
	jsr	sint
	fmove.l	fpsr,d0
	or.l	USER_FPSR(a6),d0
	fmove.l	d0,fpsr
	rts

	xdef	l_sintrz
l_sintrz:
	move.l	d1,USER_FPCR(a6)
	jsr	sintrz
	fmove.l	fpsr,d0
	or.l	USER_FPSR(a6),d0
	fmove.l	d0,fpsr
	rts

	xdef	l_sintd
l_sintd:
	move.l	d1,USER_FPCR(a6)
	jsr	sintd
	fmove.l	fpsr,d0
	or.l	USER_FPSR(a6),d0
	fmove.l	d0,fpsr
	rts

	end