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