Home | History | Annotate | Line # | Download | only in fpsp
      1 *	$NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd Exp $
      2 
      3 *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      4 *	M68000 Hi-Performance Microprocessor Division
      5 *	M68040 Software Package 
      6 *
      7 *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      8 *	All rights reserved.
      9 *
     10 *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     11 *	To the maximum extent permitted by applicable law,
     12 *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     13 *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     14 *	PARTICULAR PURPOSE and any warranty against infringement with
     15 *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     16 *	and any accompanying written materials. 
     17 *
     18 *	To the maximum extent permitted by applicable law,
     19 *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     20 *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     21 *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     22 *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     23 *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     24 *	and support of the SOFTWARE.  
     25 *
     26 *	You are hereby granted a copyright license to use, modify, and
     27 *	distribute the SOFTWARE so long as this entire notice is retained
     28 *	without alteration in any modified and/or redistributed versions,
     29 *	and that such modified versions are clearly identified as such.
     30 *	No licenses are granted by implication, estoppel or otherwise
     31 *	under any patents or trademarks of Motorola, Inc.
     32 
     33 *
     34 *	l_support.sa 1.2 5/1/91
     35 *
     36 
     37 L_SUPPORT    IDNT    2,1 Motorola 040 Floating Point Software Package
     38 
     39 	section    8
     40 
     41 mns_one  dc.l $bfff0000,$80000000,$00000000
     42 pls_one  dc.l $3fff0000,$80000000,$00000000
     43 pls_inf  dc.l $7fff0000,$00000000,$00000000
     44 pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff
     45 mns_huge dc.l $fffe0000,$ffffffff,$ffffffff
     46 pls_tiny dc.l $00000000,$80000000,$00000000
     47 mns_tiny dc.l $80000000,$80000000,$00000000
     48 small    dc.l $20000000,$80000000,$00000000
     49 pls_zero dc.l $00000000,$00000000,$00000000
     50 
     51 	include	l_fpsp.h
     52 
     53 *
     54 * 	tag --- determine the type of an extended precision operand
     55 *
     56 *	The tag values returned match the way the 68040 would have
     57 *	tagged them.
     58 *
     59 *	Input:	a0 points to operand
     60 *
     61 *	Output	d0.b	= $00 norm
     62 *			  $20 zero
     63 *			  $40 inf
     64 *			  $60 nan
     65 *			  $80 denorm
     66 *		All other registers are unchanged
     67 *
     68 	xdef	tag
     69 tag:
     70 	move.w	LOCAL_EX(a0),d0
     71 	andi.w	#$7fff,d0
     72 	beq.b	chk_zro
     73 	cmpi.w	#$7fff,d0
     74 	beq.b	chk_inf
     75 tag_nrm:
     76 	clr.b	d0
     77 	rts
     78 tag_nan:
     79 	move.b	#$60,d0
     80 	rts
     81 tag_dnrm:
     82 	move.b	#$80,d0
     83 	rts
     84 chk_zro:
     85 	btst.b	#7,LOCAL_HI(a0)	# check if J-bit is set
     86 	bne.b	tag_nrm
     87 	tst.l	LOCAL_HI(a0)
     88 	bne.b	tag_dnrm
     89 	tst.l	LOCAL_LO(a0)
     90 	bne.b	tag_dnrm
     91 tag_zero:
     92 	move.b	#$20,d0
     93 	rts
     94 chk_inf:
     95 	tst.l	LOCAL_HI(a0)
     96 	bne.b	tag_nan
     97 	tst.l	LOCAL_LO(a0)
     98 	bne.b	tag_nan
     99 tag_inf:
    100 	move.b	#$40,d0
    101 	rts
    102 
    103 *
    104 *	t_dz, t_dz2 --- divide by zero exception
    105 *
    106 * t_dz2 is used by monadic functions such as flogn (from do_func).
    107 * t_dz is used by monadic functions such as satanh (from the 
    108 * transcendental function).
    109 *
    110 	xdef    t_dz2
    111 t_dz2:
    112 	fmovem.x	mns_one,fp0
    113 	fmove.l	d1,fpcr
    114 	fdiv.x		pls_zero,fp0
    115 	rts
    116 
    117 	xdef	t_dz
    118 t_dz:
    119 	btst.b	#sign_bit,ETEMP_EX(a6)	;check sign for neg or pos
    120 	beq.b	p_inf			;branch if pos sign
    121 m_inf:
    122 	fmovem.x mns_one,fp0
    123 	fmove.l	d1,fpcr
    124 	fdiv.x		pls_zero,fp0
    125 	rts
    126 p_inf:
    127 	fmovem.x pls_one,fp0
    128 	fmove.l	d1,fpcr
    129 	fdiv.x		pls_zero,fp0
    130 	rts
    131 *
    132 *	t_operr --- Operand Error exception
    133 *
    134 	xdef    t_operr
    135 t_operr:
    136 	fmovem.x	pls_inf,fp0
    137 	fmove.l	d1,fpcr
    138 	fmul.x		pls_zero,fp0
    139 	rts
    140 
    141 *
    142 *	t_unfl --- UNFL exception
    143 *
    144 	xdef    t_unfl
    145 t_unfl:
    146 	btst.b	#sign_bit,ETEMP(a6)
    147 	beq.b	unf_pos
    148 unf_neg:
    149 	fmovem.x	mns_tiny,fp0
    150 	fmove.l	d1,fpcr
    151 	fmul.x	pls_tiny,fp0
    152 	rts
    153 	
    154 unf_pos:
    155 	fmovem.x	pls_tiny,fp0
    156 	fmove.l	d1,fpcr
    157 	fmul.x	fp0,fp0
    158 	rts
    159 *
    160 *	t_ovfl --- OVFL exception
    161 *
    162 *	t_ovfl is called as an exit for monadic functions.  t_ovfl2
    163 *	is for dyadic exits.
    164 *
    165 	xdef   		t_ovfl
    166 t_ovfl:
    167 	xdef   		t_ovfl2
    168 	move.l		d1,USER_FPCR(a6)	user's control register
    169 	move.l		#ovfinx_mask,d0
    170 	bra.b		t_work
    171 t_ovfl2:
    172 	move.l		#ovfl_inx_mask,d0
    173 t_work:
    174 	btst.b		#sign_bit,ETEMP(a6)
    175 	beq.b		ovf_pos
    176 ovf_neg:
    177 	fmovem.x	mns_huge,fp0
    178 	fmove.l		USER_FPCR(a6),fpcr
    179 	fmul.x		pls_huge,fp0
    180 	fmove.l		fpsr,d1
    181 	or.l		d1,d0
    182 	fmove.l		d0,fpsr
    183 	rts
    184 ovf_pos:
    185 	fmovem.x	pls_huge,fp0
    186 	fmove.l		USER_FPCR(a6),fpcr
    187 	fmul.x		pls_huge,fp0
    188 	fmove.l		fpsr,d1
    189 	or.l		d1,d0
    190 	fmove.l		d0,fpsr
    191 	rts
    192 *
    193 *	t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6))
    194 *
    195 	xdef    t_inx2
    196 t_inx2:
    197 	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
    198 	fmove.l		USER_FPCR(a6),fpcr
    199 *
    200 * create an inex2 exception by adding two numbers with very different exponents
    201 * do the add in fp1 so as to not disturb the result sitting in fp0
    202 *
    203 	fmove.x		pls_one,fp1
    204 	fadd.x		small,fp1
    205 *
    206 	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
    207 	fmove.l	USER_FPSR(a6),fpsr
    208 	rts
    209 *
    210 *	t_frcinx --- Force Inex2 (for monadic functions)
    211 *
    212 	xdef	t_frcinx
    213 t_frcinx:
    214 	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
    215 	fmove.l		d1,fpcr
    216 *
    217 * create an inex2 exception by adding two numbers with very different exponents
    218 * do the add in fp1 so as to not disturb the result sitting in fp0
    219 *
    220 	fmove.x		pls_one,fp1
    221 	fadd.x		small,fp1
    222 *
    223 	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
    224 	btst.b	#unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
    225 	beq.b	no_uacc1		;if clear, do not set aunfl
    226 	bset.b	#aunfl_bit,FPSR_AEXCEPT(a6)
    227 no_uacc1:
    228 	fmove.l	USER_FPSR(a6),fpsr
    229 	rts
    230 *
    231 *	dst_nan --- force result when destination is a NaN
    232 *
    233 	xdef	dst_nan
    234 dst_nan:
    235 	fmove.l	USER_FPCR(a6),fpcr
    236 	fmove.x FPTEMP(a6),fp0
    237 	rts
    238 
    239 *
    240 *	src_nan --- force result when source is a NaN
    241 *
    242 	xdef	src_nan
    243 src_nan:
    244 	fmove.l	USER_FPCR(a6),fpcr
    245 	fmove.x	ETEMP(a6),fp0
    246 	rts
    247 *
    248 *	mon_nan --- force result when source is a NaN (monadic version)
    249 *
    250 *	This is the same as src_nan except that the user's fpcr comes
    251 *	in via d1, not USER_FPCR(a6).
    252 *
    253 	xdef	mon_nan
    254 mon_nan:
    255 	fmove.l	d1,fpcr
    256 	fmove.x	ETEMP(a6),fp0
    257 	rts
    258 *
    259 *	t_extdnrm, t_resdnrm --- generate results for denorm inputs
    260 *
    261 *	For all functions that have a denormalized input and that f(x)=x,
    262 *	this is the entry point.
    263 *
    264 	xdef	t_extdnrm
    265 t_extdnrm:
    266 	fmove.l	d1,fpcr
    267 	fmove.x	LOCAL_EX(a0),fp0
    268 	fmove.l		fpsr,d0
    269 	or.l		#unfinx_mask,d0
    270 	fmove.l		d0,fpsr
    271 	rts
    272 
    273 	xdef	t_resdnrm
    274 t_resdnrm:
    275 	fmove.l	USER_FPCR(a6),fpcr
    276 	fmove.x	LOCAL_EX(a0),fp0
    277 	fmove.l		fpsr,d0
    278 	or.l		#unfl_mask,d0
    279 	fmove.l		d0,fpsr
    280 	rts
    281 *
    282 *
    283 *
    284 	xdef	t_avoid_unsupp
    285 t_avoid_unsupp:
    286 	fmove.x	fp0,fp0
    287 	rts
    288 
    289 	xdef	sto_cos
    290 sto_cos:
    291 	fmovem.x LOCAL_EX(a0),fp1
    292 	rts
    293 *
    294 *	Native instruction support
    295 *
    296 *	Some systems may need entry points even for 68040 native
    297 *	instructions.  These routines are provided for
    298 *	convenience.
    299 *
    300 	xdef	sadd
    301 sadd:
    302 	fmovem.x	FPTEMP(a6),fp0
    303 	fmove.l	USER_FPCR(a6),fpcr
    304 	fadd.x	ETEMP(a6),fp0
    305 	rts
    306 
    307 	xdef	ssub
    308 ssub:
    309 	fmovem.x	FPTEMP(a6),fp0
    310 	fmove.l	USER_FPCR(a6),fpcr
    311 	fsub.x	ETEMP(a6),fp0
    312 	rts
    313 
    314 	xdef	smul
    315 smul:
    316 	fmovem.x	FPTEMP(a6),fp0
    317 	fmove.l	USER_FPCR(a6),fpcr
    318 	fmul.x	ETEMP(a6),fp0
    319 	rts
    320 
    321 	xdef	sdiv
    322 sdiv:
    323 	fmovem.x	FPTEMP(a6),fp0
    324 	fmove.l	USER_FPCR(a6),fpcr
    325 	fdiv.x	ETEMP(a6),fp0
    326 	rts
    327 
    328 	xdef	sabs
    329 sabs:
    330 	fmovem.x	ETEMP(a6),fp0
    331 	fmove.l	d1,fpcr
    332 	fabs.x	fp0
    333 	rts
    334 
    335 	xdef	sneg
    336 sneg:
    337 	fmovem.x	ETEMP(a6),fp0
    338 	fmove.l	d1,fpcr
    339 	fneg.x	fp0
    340 	rts
    341 
    342 	xdef	ssqrt
    343 ssqrt:
    344 	fmovem.x	ETEMP(a6),fp0
    345 	fmove.l	d1,fpcr
    346 	fsqrt.x	fp0
    347 	rts
    348 
    349 *
    350 *	l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz
    351 *
    352 *	On entry, move the user's FPCR to USER_FPCR.
    353 *
    354 *	On return from, we need to pickup the INEX2/AINEX bits
    355 *	that are in USER_FPSR.
    356 *
    357 	xref	sint
    358 	xref	sintrz
    359 	xref	sintd
    360 
    361 	xdef	l_sint
    362 l_sint:
    363 	move.l	d1,USER_FPCR(a6)
    364 	jsr	sint
    365 	fmove.l	fpsr,d0
    366 	or.l	USER_FPSR(a6),d0
    367 	fmove.l	d0,fpsr
    368 	rts
    369 
    370 	xdef	l_sintrz
    371 l_sintrz:
    372 	move.l	d1,USER_FPCR(a6)
    373 	jsr	sintrz
    374 	fmove.l	fpsr,d0
    375 	or.l	USER_FPSR(a6),d0
    376 	fmove.l	d0,fpsr
    377 	rts
    378 
    379 	xdef	l_sintd
    380 l_sintd:
    381 	move.l	d1,USER_FPCR(a6)
    382 	jsr	sintd
    383 	fmove.l	fpsr,d0
    384 	or.l	USER_FPSR(a6),d0
    385 	fmove.l	d0,fpsr
    386 	rts
    387 
    388 	end
    389