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