Home | History | Annotate | Line # | Download | only in fpsp
      1  1.3   briggs *	$NetBSD: do_func.sa,v 1.3 2001/12/09 01:43:13 briggs 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.3   briggs 	bge.b	short_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.3   briggs short_serror:
    122  1.1  mycroft 	st.b	STORE_FLG(a6)
    123  1.1  mycroft 	rts
    124  1.1  mycroft *
    125  1.1  mycroft * These routines load forced values into fp0.  They are called
    126  1.1  mycroft * by index into tbldo.
    127  1.1  mycroft *
    128  1.1  mycroft * Load a signed zero to fp0 and set inex2/ainex
    129  1.1  mycroft *
    130  1.1  mycroft 	xdef	snzrinx
    131  1.1  mycroft snzrinx:
    132  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    133  1.1  mycroft 	bne.b	ld_mzinx	;if negative, branch
    134  1.1  mycroft 	bsr	ld_pzero	;bsr so we can return and set inx
    135  1.1  mycroft 	bra	t_inx2		;now, set the inx for the next inst
    136  1.1  mycroft ld_mzinx:
    137  1.1  mycroft 	bsr	ld_mzero	;if neg, load neg zero, return here
    138  1.1  mycroft 	bra	t_inx2		;now, set the inx for the next inst
    139  1.1  mycroft *
    140  1.1  mycroft * Load a signed zero to fp0; do not set inex2/ainex 
    141  1.1  mycroft *
    142  1.1  mycroft 	xdef	szero
    143  1.1  mycroft szero:
    144  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) ;get sign of source operand
    145  1.1  mycroft 	bne	ld_mzero	;if neg, load neg zero
    146  1.1  mycroft 	bra	ld_pzero	;load positive zero
    147  1.1  mycroft *
    148  1.1  mycroft * Load a signed infinity to fp0; do not set inex2/ainex 
    149  1.1  mycroft *
    150  1.1  mycroft 	xdef	sinf
    151  1.1  mycroft sinf:
    152  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    153  1.1  mycroft 	bne	ld_minf			;if negative branch
    154  1.1  mycroft 	bra	ld_pinf
    155  1.1  mycroft *
    156  1.1  mycroft * Load a signed one to fp0; do not set inex2/ainex 
    157  1.1  mycroft *
    158  1.1  mycroft 	xdef	sone
    159  1.1  mycroft sone:
    160  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    161  1.1  mycroft 	bne	ld_mone
    162  1.1  mycroft 	bra	ld_pone
    163  1.1  mycroft *
    164  1.1  mycroft * Load a signed pi/2 to fp0; do not set inex2/ainex 
    165  1.1  mycroft *
    166  1.1  mycroft 	xdef	spi_2
    167  1.1  mycroft spi_2:
    168  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    169  1.1  mycroft 	bne	ld_mpi2
    170  1.1  mycroft 	bra	ld_ppi2
    171  1.1  mycroft *
    172  1.1  mycroft * Load either a +0 or +inf for plus/minus operand
    173  1.1  mycroft *
    174  1.1  mycroft 	xdef	szr_inf
    175  1.1  mycroft szr_inf:
    176  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    177  1.1  mycroft 	bne	ld_pzero
    178  1.1  mycroft 	bra	ld_pinf
    179  1.1  mycroft *
    180  1.1  mycroft * Result is either an operr or +inf for plus/minus operand
    181  1.1  mycroft * [Used by slogn, slognp1, slog10, and slog2]
    182  1.1  mycroft *
    183  1.1  mycroft 	xdef	sopr_inf
    184  1.1  mycroft sopr_inf:
    185  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    186  1.1  mycroft 	bne	t_operr
    187  1.1  mycroft 	bra	ld_pinf
    188  1.1  mycroft *
    189  1.1  mycroft *	FLOGNP1 
    190  1.1  mycroft *
    191  1.1  mycroft 	xdef	sslognp1
    192  1.1  mycroft sslognp1:
    193  1.1  mycroft 	fmovem.x (a0),fp0
    194  1.1  mycroft 	fcmp.b	#-1,fp0
    195  1.1  mycroft 	fbgt	slognp1		
    196  1.1  mycroft 	fbeq	t_dz2		;if = -1, divide by zero exception
    197  1.1  mycroft 	fmove.l	#0,FPSR		;clr N flag
    198  1.1  mycroft 	bra	t_operr		;take care of operands < -1
    199  1.1  mycroft *
    200  1.1  mycroft *	FETOXM1
    201  1.1  mycroft *
    202  1.1  mycroft 	xdef	setoxm1i
    203  1.1  mycroft setoxm1i:
    204  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    205  1.1  mycroft 	bne	ld_mone
    206  1.1  mycroft 	bra	ld_pinf
    207  1.1  mycroft *
    208  1.1  mycroft *	FLOGN
    209  1.1  mycroft *
    210  1.1  mycroft * Test for 1.0 as an input argument, returning +zero.  Also check
    211  1.1  mycroft * the sign and return operr if negative.
    212  1.1  mycroft *
    213  1.1  mycroft 	xdef	sslogn
    214  1.1  mycroft sslogn:
    215  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    216  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    217  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    218  1.1  mycroft 	bne	slogn
    219  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    220  1.1  mycroft 	bne	slogn
    221  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    222  1.1  mycroft 	bne	slogn
    223  1.1  mycroft 	fmove.x	PZERO,fp0
    224  1.1  mycroft 	rts
    225  1.1  mycroft 
    226  1.1  mycroft 	xdef	sslognd
    227  1.1  mycroft sslognd:
    228  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    229  1.1  mycroft 	beq	slognd
    230  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    231  1.1  mycroft 
    232  1.1  mycroft *
    233  1.1  mycroft *	FLOG10
    234  1.1  mycroft *
    235  1.1  mycroft 	xdef	sslog10
    236  1.1  mycroft sslog10:
    237  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)
    238  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    239  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    240  1.1  mycroft 	bne	slog10
    241  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    242  1.1  mycroft 	bne	slog10
    243  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    244  1.1  mycroft 	bne	slog10
    245  1.1  mycroft 	fmove.x	PZERO,fp0
    246  1.1  mycroft 	rts
    247  1.1  mycroft 
    248  1.1  mycroft 	xdef	sslog10d
    249  1.1  mycroft sslog10d:
    250  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    251  1.1  mycroft 	beq	slog10d
    252  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    253  1.1  mycroft 
    254  1.1  mycroft *
    255  1.1  mycroft *	FLOG2
    256  1.1  mycroft *
    257  1.1  mycroft 	xdef	sslog2
    258  1.1  mycroft sslog2:
    259  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0)
    260  1.1  mycroft 	bne	t_operr		;take care of operands < 0
    261  1.1  mycroft 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    262  1.1  mycroft 	bne	slog2
    263  1.1  mycroft 	cmpi.l	#$80000000,LOCAL_HI(a0)
    264  1.1  mycroft 	bne	slog2
    265  1.1  mycroft 	tst.l	LOCAL_LO(a0)
    266  1.1  mycroft 	bne	slog2
    267  1.1  mycroft 	fmove.x	PZERO,fp0
    268  1.1  mycroft 	rts
    269  1.1  mycroft 
    270  1.1  mycroft 	xdef	sslog2d
    271  1.1  mycroft sslog2d:
    272  1.1  mycroft 	btst.b	#sign_bit,LOCAL_EX(a0) 
    273  1.1  mycroft 	beq	slog2d
    274  1.1  mycroft 	bra	t_operr		;take care of operands < 0
    275  1.1  mycroft 
    276  1.1  mycroft *
    277  1.1  mycroft *	FMOD
    278  1.1  mycroft *
    279  1.1  mycroft pmodt:
    280  1.1  mycroft *				;$21 fmod
    281  1.1  mycroft *				;dtag,stag
    282  1.1  mycroft 	dc.l	smod		;  00,00  norm,norm = normal
    283  1.1  mycroft 	dc.l	smod_oper	;  00,01  norm,zero = nan with operr
    284  1.1  mycroft 	dc.l	smod_fpn	;  00,10  norm,inf  = fpn
    285  1.1  mycroft 	dc.l	smod_snan	;  00,11  norm,nan  = nan
    286  1.1  mycroft 	dc.l	smod_zro	;  01,00  zero,norm = +-zero
    287  1.1  mycroft 	dc.l	smod_oper	;  01,01  zero,zero = nan with operr
    288  1.1  mycroft 	dc.l	smod_zro	;  01,10  zero,inf  = +-zero
    289  1.1  mycroft 	dc.l	smod_snan	;  01,11  zero,nan  = nan
    290  1.1  mycroft 	dc.l	smod_oper	;  10,00  inf,norm  = nan with operr
    291  1.1  mycroft 	dc.l	smod_oper	;  10,01  inf,zero  = nan with operr
    292  1.1  mycroft 	dc.l	smod_oper	;  10,10  inf,inf   = nan with operr
    293  1.1  mycroft 	dc.l	smod_snan	;  10,11  inf,nan   = nan
    294  1.1  mycroft 	dc.l	smod_dnan	;  11,00  nan,norm  = nan
    295  1.1  mycroft 	dc.l	smod_dnan	;  11,01  nan,zero  = nan
    296  1.1  mycroft 	dc.l	smod_dnan	;  11,10  nan,inf   = nan
    297  1.1  mycroft 	dc.l	smod_dnan	;  11,11  nan,nan   = nan
    298  1.1  mycroft 
    299  1.1  mycroft 	xdef	pmod
    300  1.1  mycroft pmod:
    301  1.1  mycroft 	clr.b	FPSR_QBYTE(a6) ; clear quotient field
    302  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    303  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    304  1.1  mycroft 
    305  1.1  mycroft *
    306  1.1  mycroft * Alias extended denorms to norms for the jump table.
    307  1.1  mycroft *
    308  1.1  mycroft 	bclr.l	#2,d0
    309  1.1  mycroft 	bclr.l	#2,d1
    310  1.1  mycroft 
    311  1.1  mycroft 	lsl.b	#2,d1
    312  1.1  mycroft 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    313  1.1  mycroft *				;Tag values:
    314  1.1  mycroft *				;00 = norm or denorm
    315  1.1  mycroft *				;01 = zero
    316  1.1  mycroft *				;10 = inf
    317  1.1  mycroft *				;11 = nan
    318  1.1  mycroft 	lea	pmodt,a1
    319  1.1  mycroft 	move.l	(a1,d1.w*4),a1
    320  1.1  mycroft 	jmp	(a1)
    321  1.1  mycroft 
    322  1.1  mycroft smod_snan:
    323  1.1  mycroft 	bra	src_nan
    324  1.1  mycroft smod_dnan:
    325  1.1  mycroft 	bra	dst_nan
    326  1.1  mycroft smod_oper:
    327  1.1  mycroft 	bra	t_operr
    328  1.1  mycroft smod_zro:
    329  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    330  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    331  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    332  1.1  mycroft 	btst.l	#7,d1		;test for sign
    333  1.1  mycroft 	beq.b	smod_zsn	;if clr, do not set sign big
    334  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    335  1.1  mycroft smod_zsn:
    336  1.1  mycroft 	btst.l	#7,d0		;test if + or -
    337  1.1  mycroft 	beq	ld_pzero	;if pos then load +0
    338  1.1  mycroft 	bra	ld_mzero	;else neg load -0
    339  1.1  mycroft 	
    340  1.1  mycroft smod_fpn:
    341  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    342  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    343  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    344  1.1  mycroft 	btst.l	#7,d1		;test for sign
    345  1.1  mycroft 	beq.b	smod_fsn	;if clr, do not set sign big
    346  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    347  1.1  mycroft smod_fsn:
    348  1.1  mycroft 	tst.b	DTAG(a6)	;filter out denormal destination case
    349  1.1  mycroft 	bpl.b	smod_nrm	;
    350  1.1  mycroft 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    351  1.1  mycroft 	bra	t_resdnrm	;force UNFL(but exact) result
    352  1.1  mycroft smod_nrm:
    353  1.1  mycroft 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    354  1.1  mycroft 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    355  1.1  mycroft 	rts
    356  1.1  mycroft 		
    357  1.1  mycroft *
    358  1.1  mycroft *	FREM
    359  1.1  mycroft *
    360  1.1  mycroft premt:
    361  1.1  mycroft *				;$25 frem
    362  1.1  mycroft *				;dtag,stag
    363  1.1  mycroft 	dc.l	srem		;  00,00  norm,norm = normal
    364  1.1  mycroft 	dc.l	srem_oper	;  00,01  norm,zero = nan with operr
    365  1.1  mycroft 	dc.l	srem_fpn	;  00,10  norm,inf  = fpn
    366  1.1  mycroft 	dc.l	srem_snan	;  00,11  norm,nan  = nan
    367  1.1  mycroft 	dc.l	srem_zro	;  01,00  zero,norm = +-zero
    368  1.1  mycroft 	dc.l	srem_oper	;  01,01  zero,zero = nan with operr
    369  1.1  mycroft 	dc.l	srem_zro	;  01,10  zero,inf  = +-zero
    370  1.1  mycroft 	dc.l	srem_snan	;  01,11  zero,nan  = nan
    371  1.1  mycroft 	dc.l	srem_oper	;  10,00  inf,norm  = nan with operr
    372  1.1  mycroft 	dc.l	srem_oper	;  10,01  inf,zero  = nan with operr
    373  1.1  mycroft 	dc.l	srem_oper	;  10,10  inf,inf   = nan with operr
    374  1.1  mycroft 	dc.l	srem_snan	;  10,11  inf,nan   = nan
    375  1.1  mycroft 	dc.l	srem_dnan	;  11,00  nan,norm  = nan
    376  1.1  mycroft 	dc.l	srem_dnan	;  11,01  nan,zero  = nan
    377  1.1  mycroft 	dc.l	srem_dnan	;  11,10  nan,inf   = nan
    378  1.1  mycroft 	dc.l	srem_dnan	;  11,11  nan,nan   = nan
    379  1.1  mycroft 
    380  1.1  mycroft 	xdef	prem
    381  1.1  mycroft prem:
    382  1.1  mycroft 	clr.b	FPSR_QBYTE(a6)   ;clear quotient field
    383  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    384  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    385  1.1  mycroft *
    386  1.1  mycroft * Alias extended denorms to norms for the jump table.
    387  1.1  mycroft *
    388  1.1  mycroft 	bclr	#2,d0
    389  1.1  mycroft 	bclr	#2,d1
    390  1.1  mycroft 
    391  1.1  mycroft 	lsl.b	#2,d1
    392  1.1  mycroft 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    393  1.1  mycroft *				;Tag values:
    394  1.1  mycroft *				;00 = norm or denorm
    395  1.1  mycroft *				;01 = zero
    396  1.1  mycroft *				;10 = inf
    397  1.1  mycroft *				;11 = nan
    398  1.1  mycroft 	lea	premt,a1
    399  1.1  mycroft 	move.l	(a1,d1.w*4),a1
    400  1.1  mycroft 	jmp	(a1)
    401  1.1  mycroft 	
    402  1.1  mycroft srem_snan:
    403  1.1  mycroft 	bra	src_nan
    404  1.1  mycroft srem_dnan:
    405  1.1  mycroft 	bra	dst_nan
    406  1.1  mycroft srem_oper:
    407  1.1  mycroft 	bra	t_operr
    408  1.1  mycroft srem_zro:
    409  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    410  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    411  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    412  1.1  mycroft 	btst.l	#7,d1		;test for sign
    413  1.1  mycroft 	beq.b	srem_zsn	;if clr, do not set sign big
    414  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    415  1.1  mycroft srem_zsn:
    416  1.1  mycroft 	btst.l	#7,d0		;test if + or -
    417  1.1  mycroft 	beq	ld_pzero	;if pos then load +0
    418  1.1  mycroft 	bra	ld_mzero	;else neg load -0
    419  1.1  mycroft 	
    420  1.1  mycroft srem_fpn:
    421  1.1  mycroft 	move.b	ETEMP(a6),d1	;get sign of src op
    422  1.1  mycroft 	move.b	FPTEMP(a6),d0	;get sign of dst op
    423  1.1  mycroft 	eor.b	d0,d1		;get exor of sign bits
    424  1.1  mycroft 	btst.l	#7,d1		;test for sign
    425  1.1  mycroft 	beq.b	srem_fsn	;if clr, do not set sign big
    426  1.1  mycroft 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    427  1.1  mycroft srem_fsn:
    428  1.1  mycroft 	tst.b	DTAG(a6)	;filter out denormal destination case
    429  1.1  mycroft 	bpl.b	srem_nrm	;
    430  1.1  mycroft 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    431  1.1  mycroft 	bra	t_resdnrm	;force UNFL(but exact) result
    432  1.1  mycroft srem_nrm:
    433  1.1  mycroft 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    434  1.1  mycroft 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    435  1.1  mycroft 	rts
    436  1.1  mycroft *
    437  1.1  mycroft *	FSCALE
    438  1.1  mycroft *
    439  1.1  mycroft pscalet:
    440  1.1  mycroft *				;$26 fscale
    441  1.1  mycroft *				;dtag,stag
    442  1.1  mycroft 	dc.l	sscale		;  00,00  norm,norm = result
    443  1.1  mycroft 	dc.l	sscale		;  00,01  norm,zero = fpn
    444  1.1  mycroft 	dc.l	scl_opr		;  00,10  norm,inf  = nan with operr
    445  1.1  mycroft 	dc.l	scl_snan	;  00,11  norm,nan  = nan
    446  1.1  mycroft 	dc.l	scl_zro		;  01,00  zero,norm = +-zero
    447  1.1  mycroft 	dc.l	scl_zro		;  01,01  zero,zero = +-zero
    448  1.1  mycroft 	dc.l	scl_opr		;  01,10  zero,inf  = nan with operr
    449  1.1  mycroft 	dc.l	scl_snan	;  01,11  zero,nan  = nan
    450  1.1  mycroft 	dc.l	scl_inf		;  10,00  inf,norm  = +-inf
    451  1.1  mycroft 	dc.l	scl_inf		;  10,01  inf,zero  = +-inf
    452  1.1  mycroft 	dc.l	scl_opr		;  10,10  inf,inf   = nan with operr
    453  1.1  mycroft  	dc.l	scl_snan	;  10,11  inf,nan   = nan
    454  1.1  mycroft  	dc.l	scl_dnan	;  11,00  nan,norm  = nan
    455  1.1  mycroft  	dc.l	scl_dnan	;  11,01  nan,zero  = nan
    456  1.1  mycroft  	dc.l	scl_dnan	;  11,10  nan,inf   = nan
    457  1.1  mycroft 	dc.l	scl_dnan	;  11,11  nan,nan   = nan
    458  1.1  mycroft 
    459  1.1  mycroft 	xdef	pscale
    460  1.1  mycroft pscale:
    461  1.1  mycroft 	bfextu	STAG(a6){0:3},d0 ;stag in d0
    462  1.1  mycroft 	bfextu	DTAG(a6){0:3},d1 ;dtag in d1
    463  1.1  mycroft 	bclr.l	#2,d0		;alias  denorm into norm
    464  1.1  mycroft 	bclr.l	#2,d1		;alias  denorm into norm
    465  1.1  mycroft 	lsl.b	#2,d1
    466  1.1  mycroft 	or.b	d0,d1		;d1{4:2} = dtag, d1{1:0} = stag
    467  1.1  mycroft *				;dtag values     stag values:
    468  1.1  mycroft *				;000 = norm      00 = norm
    469  1.1  mycroft *				;001 = zero	 01 = zero
    470  1.1  mycroft *				;010 = inf	 10 = inf
    471  1.1  mycroft *				;011 = nan	 11 = nan
    472  1.1  mycroft *				;100 = dnrm
    473  1.1  mycroft *
    474  1.1  mycroft *
    475  1.1  mycroft 	lea.l	pscalet,a1	;load start of jump table
    476  1.1  mycroft 	move.l	(a1,d1.w*4),a1	;load a1 with label depending on tag
    477  1.1  mycroft 	jmp	(a1)		;go to the routine
    478  1.1  mycroft 
    479  1.1  mycroft scl_opr:
    480  1.1  mycroft 	bra	t_operr
    481  1.1  mycroft 
    482  1.1  mycroft scl_dnan:
    483  1.1  mycroft 	bra	dst_nan
    484  1.1  mycroft 
    485  1.1  mycroft scl_zro:
    486  1.1  mycroft 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    487  1.1  mycroft 	beq	ld_pzero		;if pos then load +0
    488  1.1  mycroft 	bra	ld_mzero		;if neg then load -0
    489  1.1  mycroft scl_inf:
    490  1.1  mycroft 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    491  1.1  mycroft 	beq	ld_pinf			;if pos then load +inf
    492  1.1  mycroft 	bra	ld_minf			;else neg load -inf
    493  1.1  mycroft scl_snan:
    494  1.1  mycroft 	bra	src_nan
    495  1.1  mycroft *
    496  1.1  mycroft *	FSINCOS
    497  1.1  mycroft *
    498  1.1  mycroft 	xdef	ssincosz
    499  1.1  mycroft ssincosz:
    500  1.1  mycroft 	btst.b	#sign_bit,ETEMP(a6)	;get sign
    501  1.1  mycroft 	beq.b	sincosp
    502  1.1  mycroft 	fmove.x	MZERO,fp0
    503  1.1  mycroft 	bra.b	sincoscom
    504  1.1  mycroft sincosp:
    505  1.1  mycroft 	fmove.x PZERO,fp0
    506  1.1  mycroft sincoscom:
    507  1.1  mycroft   	fmovem.x PONE,fp1	;do not allow FPSR to be affected
    508  1.1  mycroft 	bra	sto_cos		;store cosine result
    509  1.1  mycroft 
    510  1.1  mycroft 	xdef	ssincosi
    511  1.1  mycroft ssincosi:
    512  1.1  mycroft 	fmove.x QNAN,fp1	;load NAN
    513  1.1  mycroft 	bsr	sto_cos		;store cosine result
    514  1.1  mycroft 	fmove.x QNAN,fp0	;load NAN
    515  1.1  mycroft 	bra	t_operr
    516  1.1  mycroft 
    517  1.1  mycroft 	xdef	ssincosnan
    518  1.1  mycroft ssincosnan:
    519  1.1  mycroft 	move.l	ETEMP_EX(a6),FP_SCR1(a6)
    520  1.1  mycroft 	move.l	ETEMP_HI(a6),FP_SCR1+4(a6)
    521  1.1  mycroft 	move.l	ETEMP_LO(a6),FP_SCR1+8(a6)
    522  1.1  mycroft 	bset.b	#signan_bit,FP_SCR1+4(a6)
    523  1.1  mycroft 	fmovem.x FP_SCR1(a6),fp1
    524  1.1  mycroft 	bsr	sto_cos
    525  1.1  mycroft 	bra	src_nan
    526  1.1  mycroft *
    527  1.1  mycroft * This code forces default values for the zero, inf, and nan cases 
    528  1.1  mycroft * in the transcendentals code.  The CC bits must be set in the
    529  1.1  mycroft * stacked FPSR to be correctly reported.
    530  1.1  mycroft *
    531  1.1  mycroft ***Returns +PI/2
    532  1.1  mycroft 	xdef	ld_ppi2
    533  1.1  mycroft ld_ppi2:
    534  1.1  mycroft 	fmove.x PPIBY2,fp0		;load +pi/2
    535  1.1  mycroft 	bra	t_inx2			;set inex2 exc
    536  1.1  mycroft 
    537  1.1  mycroft ***Returns -PI/2
    538  1.1  mycroft 	xdef	ld_mpi2
    539  1.1  mycroft ld_mpi2:
    540  1.1  mycroft 	fmove.x MPIBY2,fp0		;load -pi/2
    541  1.1  mycroft 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    542  1.1  mycroft 	bra	t_inx2			;set inex2 exc
    543  1.1  mycroft 
    544  1.1  mycroft ***Returns +inf
    545  1.1  mycroft 	xdef	ld_pinf
    546  1.1  mycroft ld_pinf:
    547  1.1  mycroft 	fmove.x PINF,fp0		;load +inf
    548  1.1  mycroft 	or.l	#inf_mask,USER_FPSR(a6)	;set I bit
    549  1.1  mycroft 	rts
    550  1.1  mycroft 
    551  1.1  mycroft ***Returns -inf
    552  1.1  mycroft 	xdef	ld_minf
    553  1.1  mycroft ld_minf:
    554  1.1  mycroft 	fmove.x MINF,fp0		;load -inf
    555  1.1  mycroft 	or.l	#neg_mask+inf_mask,USER_FPSR(a6)	;set N and I bits
    556  1.1  mycroft 	rts
    557  1.1  mycroft 
    558  1.1  mycroft ***Returns +1
    559  1.1  mycroft 	xdef	ld_pone
    560  1.1  mycroft ld_pone:
    561  1.1  mycroft 	fmove.x PONE,fp0		;load +1
    562  1.1  mycroft 	rts
    563  1.1  mycroft 
    564  1.1  mycroft ***Returns -1
    565  1.1  mycroft 	xdef	ld_mone
    566  1.1  mycroft ld_mone:
    567  1.1  mycroft 	fmove.x MONE,fp0		;load -1
    568  1.1  mycroft 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    569  1.1  mycroft 	rts
    570  1.1  mycroft 
    571  1.1  mycroft ***Returns +0
    572  1.1  mycroft 	xdef	ld_pzero
    573  1.1  mycroft ld_pzero:
    574  1.1  mycroft 	fmove.x PZERO,fp0		;load +0
    575  1.1  mycroft 	or.l	#z_mask,USER_FPSR(a6)	;set Z bit
    576  1.1  mycroft 	rts
    577  1.1  mycroft 
    578  1.1  mycroft ***Returns -0
    579  1.1  mycroft 	xdef	ld_mzero
    580  1.1  mycroft ld_mzero:
    581  1.1  mycroft 	fmove.x MZERO,fp0		;load -0
    582  1.1  mycroft 	or.l	#neg_mask+z_mask,USER_FPSR(a6)	;set N and Z bits
    583  1.1  mycroft 	rts
    584  1.1  mycroft 
    585  1.1  mycroft 	end
    586