Home | History | Annotate | Line # | Download | only in fpsp
do_func.sa revision 1.2
      1  1.2      cgd *	$NetBSD: do_func.sa,v 1.2 1994/10/26 07:49:02 cgd Exp $
      2  1.2      cgd 
      3  1.1  mycroft *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      4  1.1  mycroft *	M68000 Hi-Performance Microprocessor Division
      5  1.1  mycroft *	M68040 Software Package 
      6  1.1  mycroft *
      7  1.1  mycroft *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      8  1.1  mycroft *	All rights reserved.
      9  1.1  mycroft *
     10  1.1  mycroft *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     11  1.1  mycroft *	To the maximum extent permitted by applicable law,
     12  1.1  mycroft *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     13  1.1  mycroft *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     14  1.1  mycroft *	PARTICULAR PURPOSE and any warranty against infringement with
     15  1.1  mycroft *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     16  1.1  mycroft *	and any accompanying written materials. 
     17  1.1  mycroft *
     18  1.1  mycroft *	To the maximum extent permitted by applicable law,
     19  1.1  mycroft *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     20  1.1  mycroft *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     21  1.1  mycroft *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     22  1.1  mycroft *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     23  1.1  mycroft *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     24  1.1  mycroft *	and support of the SOFTWARE.  
     25  1.1  mycroft *
     26  1.1  mycroft *	You are hereby granted a copyright license to use, modify, and
     27  1.1  mycroft *	distribute the SOFTWARE so long as this entire notice is retained
     28  1.1  mycroft *	without alteration in any modified and/or redistributed versions,
     29  1.1  mycroft *	and that such modified versions are clearly identified as such.
     30  1.1  mycroft *	No licenses are granted by implication, estoppel or otherwise
     31  1.1  mycroft *	under any patents or trademarks of Motorola, Inc.
     32  1.1  mycroft 
     33  1.1  mycroft *
     34  1.1  mycroft *	do_func.sa 3.4 2/18/91
     35  1.1  mycroft *
     36  1.1  mycroft * Do_func performs the unimplemented operation.  The operation
     37  1.1  mycroft * to be performed is determined from the lower 7 bits of the
     38  1.1  mycroft * extension word (except in the case of fmovecr and fsincos).
     39  1.1  mycroft * The opcode and tag bits form an index into a jump table in 
     40  1.1  mycroft * tbldo.sa.  Cases of zero, infinity and NaN are handled in 
     41  1.1  mycroft * do_func by forcing the default result.  Normalized and
     42  1.1  mycroft * denormalized (there are no unnormalized numbers at this
     43  1.1  mycroft * point) are passed onto the emulation code.  
     44  1.1  mycroft *
     45  1.1  mycroft * CMDREG1B and STAG are extracted from the fsave frame
     46  1.1  mycroft * and combined to form the table index.  The function called
     47  1.1  mycroft * will start with a0 pointing to the ETEMP operand.  Dyadic
     48  1.1  mycroft * functions can find FPTEMP at -12(a0).
     49  1.1  mycroft *
     50  1.1  mycroft * Called functions return their result in fp0.  Sincos returns
     51  1.1  mycroft * sin(x) in fp0 and cos(x) in fp1.
     52  1.1  mycroft *
     53  1.1  mycroft 
     54  1.1  mycroft DO_FUNC	IDNT    2,1 Motorola 040 Floating Point Software Package
     55  1.1  mycroft 
     56  1.1  mycroft 	section	8
     57  1.1  mycroft 
     58  1.1  mycroft 	include	fpsp.h
     59  1.1  mycroft 
     60  1.1  mycroft 	xref	t_dz2
     61  1.1  mycroft 	xref	t_operr
     62  1.1  mycroft 	xref	t_inx2
     63  1.1  mycroft 	xref 	t_resdnrm
     64  1.1  mycroft 	xref	dst_nan
     65  1.1  mycroft 	xref	src_nan
     66  1.1  mycroft 	xref	nrm_set
     67  1.1  mycroft 	xref	sto_cos
     68  1.1  mycroft 
     69  1.1  mycroft 	xref	tblpre
     70  1.1  mycroft 	xref	slognp1,slogn,slog10,slog2
     71  1.1  mycroft 	xref	slognd,slog10d,slog2d
     72  1.1  mycroft 	xref	smod,srem
     73  1.1  mycroft 	xref	sscale
     74  1.1  mycroft 	xref	smovcr
     75  1.1  mycroft 
     76  1.1  mycroft PONE	dc.l	$3fff0000,$80000000,$00000000	;+1
     77  1.1  mycroft MONE	dc.l	$bfff0000,$80000000,$00000000	;-1
     78  1.1  mycroft PZERO	dc.l	$00000000,$00000000,$00000000	;+0
     79  1.1  mycroft MZERO	dc.l	$80000000,$00000000,$00000000	;-0
     80  1.1  mycroft PINF	dc.l	$7fff0000,$00000000,$00000000	;+inf
     81  1.1  mycroft MINF	dc.l	$ffff0000,$00000000,$00000000	;-inf
     82  1.1  mycroft QNAN	dc.l	$7fff0000,$ffffffff,$ffffffff	;non-signaling nan
     83  1.1  mycroft PPIBY2  dc.l	$3FFF0000,$C90FDAA2,$2168C235	;+PI/2
     84  1.1  mycroft MPIBY2  dc.l	$bFFF0000,$C90FDAA2,$2168C235	;-PI/2
     85  1.1  mycroft 
     86  1.1  mycroft 	xdef	do_func
     87  1.1  mycroft do_func:
     88  1.1  mycroft 	clr.b	CU_ONLY(a6)
     89  1.1  mycroft *
     90  1.1  mycroft * Check for fmovecr.  It does not follow the format of fp gen
     91  1.1  mycroft * unimplemented instructions.  The test is on the upper 6 bits;
     92  1.1  mycroft * if they are $17, the inst is fmovecr.  Call entry smovcr
     93  1.1  mycroft * directly.
     94  1.1  mycroft *
     95  1.1  mycroft 	bfextu	CMDREG1B(a6){0:6},d0 ;get opclass and src fields
     96  1.1  mycroft 	cmpi.l	#$17,d0		;if op class and size fields are $17, 
     97  1.1  mycroft *				;it is FMOVECR; if not, continue
     98  1.1  mycroft 	bne.b	not_fmovecr
     99  1.1  mycroft 	jmp	smovcr		;fmovecr; jmp directly to emulation
    100  1.1  mycroft 
    101  1.1  mycroft not_fmovecr:
    102  1.1  mycroft 	move.w	CMDREG1B(a6),d0
    103  1.1  mycroft 	and.l	#$7F,d0
    104  1.1  mycroft 	cmpi.l	#$38,d0		;if the extension is >= $38, 
    105  1.1  mycroft 	bge.b	serror		;it is illegal
    106  1.1  mycroft 	bfextu	STAG(a6){0:3},d1
    107  1.1  mycroft 	lsl.l	#3,d0		;make room for STAG
    108  1.1  mycroft 	add.l	d1,d0		;combine for final index into table
    109  1.1  mycroft 	lea.l	tblpre,a1	;start of monster jump table
    110  1.1  mycroft 	move.l	(a1,d0.w*4),a1	;real target address
    111  1.1  mycroft 	lea.l	ETEMP(a6),a0	;a0 is pointer to src op
    112  1.1  mycroft 	move.l	USER_FPCR(a6),d1
    113  1.1  mycroft 	and.l	#$FF,d1		; discard all but rounding mode/prec
    114  1.1  mycroft 	fmove.l	#0,fpcr
    115  1.1  mycroft 	jmp	(a1)
    116  1.1  mycroft *
    117  1.1  mycroft *	ERROR
    118  1.1  mycroft *
    119  1.1  mycroft 	xdef	serror
    120  1.1  mycroft serror:
    121  1.1  mycroft 	st.b	STORE_FLG(a6)
    122  1.1  mycroft 	rts
    123  1.1  mycroft *
    124  1.1  mycroft * These routines load forced values into fp0.  They are called
    125  1.1  mycroft * by index into tbldo.
    126  1.1  mycroft *
    127  1.1  mycroft * Load a signed zero to fp0 and set inex2/ainex
    128  1.1  mycroft *
    129  1.1  mycroft 	xdef	snzrinx
    130  1.1  mycroft snzrinx:
    131  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    132  1.1  mycroft 	bne.b	ld_mzinx	;if negative, branch
    133  1.1  mycroft 	bsr	ld_pzero	;bsr so we can return and set inx
    134  1.1  mycroft 	bra	t_inx2		;now, set the inx for the next inst
    135  1.1  mycroft ld_mzinx:
    136  1.1  mycroft 	bsr	ld_mzero	;if neg, load neg zero, return here
    137  1.1  mycroft 	bra	t_inx2		;now, set the inx for the next inst
    138  1.1  mycroft *
    139  1.1  mycroft * Load a signed zero to fp0; do not set inex2/ainex 
    140  1.1  mycroft *
    141  1.1  mycroft 	xdef	szero
    142  1.1  mycroft szero:
    143  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) ;get sign of source operand
    144  1.1  mycroft 	bne	ld_mzero	;if neg, load neg zero
    145  1.1  mycroft 	bra	ld_pzero	;load positive zero
    146  1.1  mycroft *
    147  1.1  mycroft * Load a signed infinity to fp0; do not set inex2/ainex 
    148  1.1  mycroft *
    149  1.1  mycroft 	xdef	sinf
    150  1.1  mycroft sinf:
    151  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    152  1.1  mycroft 	bne	ld_minf			;if negative branch
    153  1.1  mycroft 	bra	ld_pinf
    154  1.1  mycroft *
    155  1.1  mycroft * Load a signed one to fp0; do not set inex2/ainex 
    156  1.1  mycroft *
    157  1.1  mycroft 	xdef	sone
    158  1.1  mycroft sone:
    159  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    160  1.1  mycroft 	bne	ld_mone
    161  1.1  mycroft 	bra	ld_pone
    162  1.1  mycroft *
    163  1.1  mycroft * Load a signed pi/2 to fp0; do not set inex2/ainex 
    164  1.1  mycroft *
    165  1.1  mycroft 	xdef	spi_2
    166  1.1  mycroft spi_2:
    167  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    168  1.1  mycroft 	bne	ld_mpi2
    169  1.1  mycroft 	bra	ld_ppi2
    170  1.1  mycroft *
    171  1.1  mycroft * Load either a +0 or +inf for plus/minus operand
    172  1.1  mycroft *
    173  1.1  mycroft 	xdef	szr_inf
    174  1.1  mycroft szr_inf:
    175  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    176  1.1  mycroft 	bne	ld_pzero
    177  1.1  mycroft 	bra	ld_pinf
    178  1.1  mycroft *
    179  1.1  mycroft * Result is either an operr or +inf for plus/minus operand
    180  1.1  mycroft * [Used by slogn, slognp1, slog10, and slog2]
    181  1.1  mycroft *
    182  1.1  mycroft 	xdef	sopr_inf
    183  1.1  mycroft sopr_inf:
    184  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    185  1.1  mycroft 	bne	t_operr
    186  1.1  mycroft 	bra	ld_pinf
    187  1.1  mycroft *
    188  1.1  mycroft *	FLOGNP1 
    189  1.1  mycroft *
    190  1.1  mycroft 	xdef	sslognp1
    191  1.1  mycroft sslognp1:
    192  1.1  mycroft 	fmovem.x (a0),fp0
    193  1.1  mycroft 	fcmp.b	#-1,fp0
    194  1.1  mycroft 	fbgt	slognp1		
    195  1.1  mycroft 	fbeq	t_dz2		;if = -1, divide by zero exception
    196  1.1  mycroft 	fmove.l	#0,FPSR		;clr N flag
    197  1.1  mycroft 	bra	t_operr		;take care of operands < -1
    198  1.1  mycroft *
    199  1.1  mycroft *	FETOXM1
    200  1.1  mycroft *
    201  1.1  mycroft 	xdef	setoxm1i
    202  1.1  mycroft setoxm1i:
    203  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    204  1.1  mycroft 	bne	ld_mone
    205  1.1  mycroft 	bra	ld_pinf
    206  1.1  mycroft *
    207  1.1  mycroft *	FLOGN
    208  1.1  mycroft *
    209  1.1  mycroft * Test for 1.0 as an input argument, returning +zero.  Also check
    210  1.1  mycroft * the sign and return operr if negative.
    211  1.1  mycroft *
    212  1.1  mycroft 	xdef	sslogn
    213  1.1  mycroft sslogn:
    214  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    215  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    216  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    217  1.1  mycroft 	bne	slogn
    218  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    219  1.1  mycroft 	bne	slogn
    220  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    221  1.1  mycroft 	bne	slogn
    222  1.1  mycroft 	fmove.x	PZERO,fp0
    223  1.1  mycroft 	rts
    224  1.1  mycroft 
    225  1.1  mycroft 	xdef	sslognd
    226  1.1  mycroft sslognd:
    227  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    228  1.1  mycroft 	beq	slognd
    229  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    230  1.1  mycroft 
    231  1.1  mycroft *
    232  1.1  mycroft *	FLOG10
    233  1.1  mycroft *
    234  1.1  mycroft 	xdef	sslog10
    235  1.1  mycroft sslog10:
    236  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)
    237  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    238  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    239  1.1  mycroft 	bne	slog10
    240  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    241  1.1  mycroft 	bne	slog10
    242  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    243  1.1  mycroft 	bne	slog10
    244  1.1  mycroft 	fmove.x	PZERO,fp0
    245  1.1  mycroft 	rts
    246  1.1  mycroft 
    247  1.1  mycroft 	xdef	sslog10d
    248  1.1  mycroft sslog10d:
    249  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    250  1.1  mycroft 	beq	slog10d
    251  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    252  1.1  mycroft 
    253  1.1  mycroft *
    254  1.1  mycroft *	FLOG2
    255  1.1  mycroft *
    256  1.1  mycroft 	xdef	sslog2
    257  1.1  mycroft sslog2:
    258  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)
    259  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    260  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    261  1.1  mycroft 	bne	slog2
    262  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    263  1.1  mycroft 	bne	slog2
    264  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    265  1.1  mycroft 	bne	slog2
    266  1.1  mycroft 	fmove.x	PZERO,fp0
    267  1.1  mycroft 	rts
    268  1.1  mycroft 
    269  1.1  mycroft 	xdef	sslog2d
    270  1.1  mycroft sslog2d:
    271  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    272  1.1  mycroft 	beq	slog2d
    273  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    274  1.1  mycroft 
    275  1.1  mycroft *
    276  1.1  mycroft *	FMOD
    277  1.1  mycroft *
    278  1.1  mycroft pmodt:
    279  1.1  mycroft *				;$21 fmod
    280  1.1  mycroft *				;dtag,stag
    281  1.1  mycroft 	dc.l	smod		;  00,00  norm,norm = normal
    282  1.1  mycroft 	dc.l	smod_oper	;  00,01  norm,zero = nan with operr
    283  1.1  mycroft 	dc.l	smod_fpn	;  00,10  norm,inf  = fpn
    284  1.1  mycroft 	dc.l	smod_snan	;  00,11  norm,nan  = nan
    285  1.1  mycroft 	dc.l	smod_zro	;  01,00  zero,norm = +-zero
    286  1.1  mycroft 	dc.l	smod_oper	;  01,01  zero,zero = nan with operr
    287  1.1  mycroft 	dc.l	smod_zro	;  01,10  zero,inf  = +-zero
    288  1.1  mycroft 	dc.l	smod_snan	;  01,11  zero,nan  = nan
    289  1.1  mycroft 	dc.l	smod_oper	;  10,00  inf,norm  = nan with operr
    290  1.1  mycroft 	dc.l	smod_oper	;  10,01  inf,zero  = nan with operr
    291  1.1  mycroft 	dc.l	smod_oper	;  10,10  inf,inf   = nan with operr
    292  1.1  mycroft 	dc.l	smod_snan	;  10,11  inf,nan   = nan
    293  1.1  mycroft 	dc.l	smod_dnan	;  11,00  nan,norm  = nan
    294  1.1  mycroft 	dc.l	smod_dnan	;  11,01  nan,zero  = nan
    295  1.1  mycroft 	dc.l	smod_dnan	;  11,10  nan,inf   = nan
    296  1.1  mycroft 	dc.l	smod_dnan	;  11,11  nan,nan   = nan
    297  1.1  mycroft 
    298  1.1  mycroft 	xdef	pmod
    299  1.1  mycroft pmod:
    300  1.1  mycroft 	clr.b	FPSR_QBYTE(a6) ; clear quotient field
    301  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    302  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    303  1.1  mycroft 
    304  1.1  mycroft *
    305  1.1  mycroft * Alias extended denorms to norms for the jump table.
    306  1.1  mycroft *
    307  1.1  mycroft 	bclr.l	#2,d0
    308  1.1  mycroft 	bclr.l	#2,d1
    309  1.1  mycroft 
    310  1.1  mycroft 	lsl.b	#2,d1
    311  1.1  mycroft 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    312  1.1  mycroft *				;Tag values:
    313  1.1  mycroft *				;00 = norm or denorm
    314  1.1  mycroft *				;01 = zero
    315  1.1  mycroft *				;10 = inf
    316  1.1  mycroft *				;11 = nan
    317  1.1  mycroft 	lea	pmodt,a1
    318  1.1  mycroft 	move.l	(a1,d1.w*4),a1
    319  1.1  mycroft 	jmp	(a1)
    320  1.1  mycroft 
    321  1.1  mycroft smod_snan:
    322  1.1  mycroft 	bra	src_nan
    323  1.1  mycroft smod_dnan:
    324  1.1  mycroft 	bra	dst_nan
    325  1.1  mycroft smod_oper:
    326  1.1  mycroft 	bra	t_operr
    327  1.1  mycroft smod_zro:
    328  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    329  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    330  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    331  1.1  mycroft 	btst.l	#7,d1		;test for sign
    332  1.1  mycroft 	beq.b	smod_zsn	;if clr, do not set sign big
    333  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    334  1.1  mycroft smod_zsn:
    335  1.1  mycroft 	btst.l	#7,d0		;test if + or -
    336  1.1  mycroft 	beq	ld_pzero	;if pos then load +0
    337  1.1  mycroft 	bra	ld_mzero	;else neg load -0
    338  1.1  mycroft 	
    339  1.1  mycroft smod_fpn:
    340  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    341  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    342  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    343  1.1  mycroft 	btst.l	#7,d1		;test for sign
    344  1.1  mycroft 	beq.b	smod_fsn	;if clr, do not set sign big
    345  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    346  1.1  mycroft smod_fsn:
    347  1.1  mycroft 	tst.b	DTAG(a6)	;filter out denormal destination case
    348  1.1  mycroft 	bpl.b	smod_nrm	;
    349  1.1  mycroft 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    350  1.1  mycroft 	bra	t_resdnrm	;force UNFL(but exact) result
    351  1.1  mycroft smod_nrm:
    352  1.1  mycroft 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    353  1.1  mycroft 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    354  1.1  mycroft 	rts
    355  1.1  mycroft 		
    356  1.1  mycroft *
    357  1.1  mycroft *	FREM
    358  1.1  mycroft *
    359  1.1  mycroft premt:
    360  1.1  mycroft *				;$25 frem
    361  1.1  mycroft *				;dtag,stag
    362  1.1  mycroft 	dc.l	srem		;  00,00  norm,norm = normal
    363  1.1  mycroft 	dc.l	srem_oper	;  00,01  norm,zero = nan with operr
    364  1.1  mycroft 	dc.l	srem_fpn	;  00,10  norm,inf  = fpn
    365  1.1  mycroft 	dc.l	srem_snan	;  00,11  norm,nan  = nan
    366  1.1  mycroft 	dc.l	srem_zro	;  01,00  zero,norm = +-zero
    367  1.1  mycroft 	dc.l	srem_oper	;  01,01  zero,zero = nan with operr
    368  1.1  mycroft 	dc.l	srem_zro	;  01,10  zero,inf  = +-zero
    369  1.1  mycroft 	dc.l	srem_snan	;  01,11  zero,nan  = nan
    370  1.1  mycroft 	dc.l	srem_oper	;  10,00  inf,norm  = nan with operr
    371  1.1  mycroft 	dc.l	srem_oper	;  10,01  inf,zero  = nan with operr
    372  1.1  mycroft 	dc.l	srem_oper	;  10,10  inf,inf   = nan with operr
    373  1.1  mycroft 	dc.l	srem_snan	;  10,11  inf,nan   = nan
    374  1.1  mycroft 	dc.l	srem_dnan	;  11,00  nan,norm  = nan
    375  1.1  mycroft 	dc.l	srem_dnan	;  11,01  nan,zero  = nan
    376  1.1  mycroft 	dc.l	srem_dnan	;  11,10  nan,inf   = nan
    377  1.1  mycroft 	dc.l	srem_dnan	;  11,11  nan,nan   = nan
    378  1.1  mycroft 
    379  1.1  mycroft 	xdef	prem
    380  1.1  mycroft prem:
    381  1.1  mycroft 	clr.b	FPSR_QBYTE(a6)   ;clear quotient field
    382  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    383  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    384  1.1  mycroft *
    385  1.1  mycroft * Alias extended denorms to norms for the jump table.
    386  1.1  mycroft *
    387  1.1  mycroft 	bclr	#2,d0
    388  1.1  mycroft 	bclr	#2,d1
    389  1.1  mycroft 
    390  1.1  mycroft 	lsl.b	#2,d1
    391  1.1  mycroft 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    392  1.1  mycroft *				;Tag values:
    393  1.1  mycroft *				;00 = norm or denorm
    394  1.1  mycroft *				;01 = zero
    395  1.1  mycroft *				;10 = inf
    396  1.1  mycroft *				;11 = nan
    397  1.1  mycroft 	lea	premt,a1
    398  1.1  mycroft 	move.l	(a1,d1.w*4),a1
    399  1.1  mycroft 	jmp	(a1)
    400  1.1  mycroft 	
    401  1.1  mycroft srem_snan:
    402  1.1  mycroft 	bra	src_nan
    403  1.1  mycroft srem_dnan:
    404  1.1  mycroft 	bra	dst_nan
    405  1.1  mycroft srem_oper:
    406  1.1  mycroft 	bra	t_operr
    407  1.1  mycroft srem_zro:
    408  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    409  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    410  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    411  1.1  mycroft 	btst.l	#7,d1		;test for sign
    412  1.1  mycroft 	beq.b	srem_zsn	;if clr, do not set sign big
    413  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    414  1.1  mycroft srem_zsn:
    415  1.1  mycroft 	btst.l	#7,d0		;test if + or -
    416  1.1  mycroft 	beq	ld_pzero	;if pos then load +0
    417  1.1  mycroft 	bra	ld_mzero	;else neg load -0
    418  1.1  mycroft 	
    419  1.1  mycroft srem_fpn:
    420  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    421  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    422  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    423  1.1  mycroft 	btst.l	#7,d1		;test for sign
    424  1.1  mycroft 	beq.b	srem_fsn	;if clr, do not set sign big
    425  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    426  1.1  mycroft srem_fsn:
    427  1.1  mycroft 	tst.b	DTAG(a6)	;filter out denormal destination case
    428  1.1  mycroft 	bpl.b	srem_nrm	;
    429  1.1  mycroft 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    430  1.1  mycroft 	bra	t_resdnrm	;force UNFL(but exact) result
    431  1.1  mycroft srem_nrm:
    432  1.1  mycroft 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    433  1.1  mycroft 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    434  1.1  mycroft 	rts
    435  1.1  mycroft *
    436  1.1  mycroft *	FSCALE
    437  1.1  mycroft *
    438  1.1  mycroft pscalet:
    439  1.1  mycroft *				;$26 fscale
    440  1.1  mycroft *				;dtag,stag
    441  1.1  mycroft 	dc.l	sscale		;  00,00  norm,norm = result
    442  1.1  mycroft 	dc.l	sscale		;  00,01  norm,zero = fpn
    443  1.1  mycroft 	dc.l	scl_opr		;  00,10  norm,inf  = nan with operr
    444  1.1  mycroft 	dc.l	scl_snan	;  00,11  norm,nan  = nan
    445  1.1  mycroft 	dc.l	scl_zro		;  01,00  zero,norm = +-zero
    446  1.1  mycroft 	dc.l	scl_zro		;  01,01  zero,zero = +-zero
    447  1.1  mycroft 	dc.l	scl_opr		;  01,10  zero,inf  = nan with operr
    448  1.1  mycroft 	dc.l	scl_snan	;  01,11  zero,nan  = nan
    449  1.1  mycroft 	dc.l	scl_inf		;  10,00  inf,norm  = +-inf
    450  1.1  mycroft 	dc.l	scl_inf		;  10,01  inf,zero  = +-inf
    451  1.1  mycroft 	dc.l	scl_opr		;  10,10  inf,inf   = nan with operr
    452  1.1  mycroft  	dc.l	scl_snan	;  10,11  inf,nan   = nan
    453  1.1  mycroft  	dc.l	scl_dnan	;  11,00  nan,norm  = nan
    454  1.1  mycroft  	dc.l	scl_dnan	;  11,01  nan,zero  = nan
    455  1.1  mycroft  	dc.l	scl_dnan	;  11,10  nan,inf   = nan
    456  1.1  mycroft 	dc.l	scl_dnan	;  11,11  nan,nan   = nan
    457  1.1  mycroft 
    458  1.1  mycroft 	xdef	pscale
    459  1.1  mycroft pscale:
    460  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag in d0
    461  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag in d1
    462  1.1  mycroft 	bclr.l	#2,d0		;alias  denorm into norm
    463  1.1  mycroft 	bclr.l	#2,d1		;alias  denorm into norm
    464  1.1  mycroft 	lsl.b	#2,d1
    465  1.1  mycroft 	or.b	d0,d1		;d1{4:2} = dtag, d1{1:0} = stag
    466  1.1  mycroft *				;dtag values     stag values:
    467  1.1  mycroft *				;000 = norm      00 = norm
    468  1.1  mycroft *				;001 = zero	 01 = zero
    469  1.1  mycroft *				;010 = inf	 10 = inf
    470  1.1  mycroft *				;011 = nan	 11 = nan
    471  1.1  mycroft *				;100 = dnrm
    472  1.1  mycroft *
    473  1.1  mycroft *
    474  1.1  mycroft 	lea.l	pscalet,a1	;load start of jump table
    475  1.1  mycroft 	move.l	(a1,d1.w*4),a1	;load a1 with label depending on tag
    476  1.1  mycroft 	jmp	(a1)		;go to the routine
    477  1.1  mycroft 
    478  1.1  mycroft scl_opr:
    479  1.1  mycroft 	bra	t_operr
    480  1.1  mycroft 
    481  1.1  mycroft scl_dnan:
    482  1.1  mycroft 	bra	dst_nan
    483  1.1  mycroft 
    484  1.1  mycroft scl_zro:
    485  1.1  mycroft 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    486  1.1  mycroft 	beq	ld_pzero		;if pos then load +0
    487  1.1  mycroft 	bra	ld_mzero		;if neg then load -0
    488  1.1  mycroft scl_inf:
    489  1.1  mycroft 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    490  1.1  mycroft 	beq	ld_pinf			;if pos then load +inf
    491  1.1  mycroft 	bra	ld_minf			;else neg load -inf
    492  1.1  mycroft scl_snan:
    493  1.1  mycroft 	bra	src_nan
    494  1.1  mycroft *
    495  1.1  mycroft *	FSINCOS
    496  1.1  mycroft *
    497  1.1  mycroft 	xdef	ssincosz
    498  1.1  mycroft ssincosz:
    499  1.1  mycroft 	btst.b	#sign_bit,ETEMP(a6)	;get sign
    500  1.1  mycroft 	beq.b	sincosp
    501  1.1  mycroft 	fmove.x	MZERO,fp0
    502  1.1  mycroft 	bra.b	sincoscom
    503  1.1  mycroft sincosp:
    504  1.1  mycroft 	fmove.x PZERO,fp0
    505  1.1  mycroft sincoscom:
    506  1.1  mycroft   	fmovem.x PONE,fp1	;do not allow FPSR to be affected
    507  1.1  mycroft 	bra	sto_cos		;store cosine result
    508  1.1  mycroft 
    509  1.1  mycroft 	xdef	ssincosi
    510  1.1  mycroft ssincosi:
    511  1.1  mycroft 	fmove.x QNAN,fp1	;load NAN
    512  1.1  mycroft 	bsr	sto_cos		;store cosine result
    513  1.1  mycroft 	fmove.x QNAN,fp0	;load NAN
    514  1.1  mycroft 	bra	t_operr
    515  1.1  mycroft 
    516  1.1  mycroft 	xdef	ssincosnan
    517  1.1  mycroft ssincosnan:
    518  1.1  mycroft 	move.l	ETEMP_EX(a6),FP_SCR1(a6)
    519  1.1  mycroft 	move.l	ETEMP_HI(a6),FP_SCR1+4(a6)
    520  1.1  mycroft 	move.l	ETEMP_LO(a6),FP_SCR1+8(a6)
    521  1.1  mycroft 	bset.b	#signan_bit,FP_SCR1+4(a6)
    522  1.1  mycroft 	fmovem.x FP_SCR1(a6),fp1
    523  1.1  mycroft 	bsr	sto_cos
    524  1.1  mycroft 	bra	src_nan
    525  1.1  mycroft *
    526  1.1  mycroft * This code forces default values for the zero, inf, and nan cases 
    527  1.1  mycroft * in the transcendentals code.  The CC bits must be set in the
    528  1.1  mycroft * stacked FPSR to be correctly reported.
    529  1.1  mycroft *
    530  1.1  mycroft ***Returns +PI/2
    531  1.1  mycroft 	xdef	ld_ppi2
    532  1.1  mycroft ld_ppi2:
    533  1.1  mycroft 	fmove.x PPIBY2,fp0		;load +pi/2
    534  1.1  mycroft 	bra	t_inx2			;set inex2 exc
    535  1.1  mycroft 
    536  1.1  mycroft ***Returns -PI/2
    537  1.1  mycroft 	xdef	ld_mpi2
    538  1.1  mycroft ld_mpi2:
    539  1.1  mycroft 	fmove.x MPIBY2,fp0		;load -pi/2
    540  1.1  mycroft 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    541  1.1  mycroft 	bra	t_inx2			;set inex2 exc
    542  1.1  mycroft 
    543  1.1  mycroft ***Returns +inf
    544  1.1  mycroft 	xdef	ld_pinf
    545  1.1  mycroft ld_pinf:
    546  1.1  mycroft 	fmove.x PINF,fp0		;load +inf
    547  1.1  mycroft 	or.l	#inf_mask,USER_FPSR(a6)	;set I bit
    548  1.1  mycroft 	rts
    549  1.1  mycroft 
    550  1.1  mycroft ***Returns -inf
    551  1.1  mycroft 	xdef	ld_minf
    552  1.1  mycroft ld_minf:
    553  1.1  mycroft 	fmove.x MINF,fp0		;load -inf
    554  1.1  mycroft 	or.l	#neg_mask+inf_mask,USER_FPSR(a6)	;set N and I bits
    555  1.1  mycroft 	rts
    556  1.1  mycroft 
    557  1.1  mycroft ***Returns +1
    558  1.1  mycroft 	xdef	ld_pone
    559  1.1  mycroft ld_pone:
    560  1.1  mycroft 	fmove.x PONE,fp0		;load +1
    561  1.1  mycroft 	rts
    562  1.1  mycroft 
    563  1.1  mycroft ***Returns -1
    564  1.1  mycroft 	xdef	ld_mone
    565  1.1  mycroft ld_mone:
    566  1.1  mycroft 	fmove.x MONE,fp0		;load -1
    567  1.1  mycroft 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    568  1.1  mycroft 	rts
    569  1.1  mycroft 
    570  1.1  mycroft ***Returns +0
    571  1.1  mycroft 	xdef	ld_pzero
    572  1.1  mycroft ld_pzero:
    573  1.1  mycroft 	fmove.x PZERO,fp0		;load +0
    574  1.1  mycroft 	or.l	#z_mask,USER_FPSR(a6)	;set Z bit
    575  1.1  mycroft 	rts
    576  1.1  mycroft 
    577  1.1  mycroft ***Returns -0
    578  1.1  mycroft 	xdef	ld_mzero
    579  1.1  mycroft ld_mzero:
    580  1.1  mycroft 	fmove.x MZERO,fp0		;load -0
    581  1.1  mycroft 	or.l	#neg_mask+z_mask,USER_FPSR(a6)	;set N and Z bits
    582  1.1  mycroft 	rts
    583  1.1  mycroft 
    584  1.1  mycroft 	end
    585