⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 do_func.s

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 S
字号:
||	do_func.sa 3.4 2/18/91|| Do_func performs the unimplemented operation.  The operation| to be performed is determined from the lower 7 bits of the| extension word (except in the case of fmovecr and fsincos).| The opcode and tag bits form an index into a jump table in | tbldo.sa.  Cases of zero, infinity and NaN are handled in | do_func by forcing the default result.  Normalized and| denormalized (there are no unnormalized numbers at this| point) are passed onto the emulation code.  || CMDREG1B and STAG are extracted from the fsave frame| and combined to form the table index.  The function called| will start with a0 pointing to the ETEMP operand.  Dyadic| functions can find FPTEMP at -12(a0).|| Called functions return their result in fp0.  Sincos returns| sin(x) in fp0 and cos(x) in fp1.||		Copyright (C) Motorola, Inc. 1990|			All Rights Reserved||	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA |	The copyright notice above does not evidence any  |	actual or intended publication of such source code.DO_FUNC:	|idnt    2,1 | Motorola 040 Floating Point Software Package	|section	8	.include "fpsp.h"	|xref	t_dz2	|xref	t_operr	|xref	t_inx2	|xref 	t_resdnrm	|xref	dst_nan	|xref	src_nan	|xref	nrm_set	|xref	sto_cos	|xref	tblpre	|xref	slognp1,slogn,slog10,slog2	|xref	slognd,slog10d,slog2d	|xref	smod,srem	|xref	sscale	|xref	smovcrPONE:	.long	0x3fff0000,0x80000000,0x00000000	|+1MONE:	.long	0xbfff0000,0x80000000,0x00000000	|-1PZERO:	.long	0x00000000,0x00000000,0x00000000	|+0MZERO:	.long	0x80000000,0x00000000,0x00000000	|-0PINF:	.long	0x7fff0000,0x00000000,0x00000000	|+infMINF:	.long	0xffff0000,0x00000000,0x00000000	|-infQNAN:	.long	0x7fff0000,0xffffffff,0xffffffff	|non-signaling nanPPIBY2:  .long	0x3FFF0000,0xC90FDAA2,0x2168C235	|+PI/2MPIBY2:  .long	0xbFFF0000,0xC90FDAA2,0x2168C235	|-PI/2	.global	do_funcdo_func:	clrb	CU_ONLY(%a6)|| Check for fmovecr.  It does not follow the format of fp gen| unimplemented instructions.  The test is on the upper 6 bits;| if they are $17, the inst is fmovecr.  Call entry smovcr| directly.|	bfextu	CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields	cmpil	#0x17,%d0		|if op class and size fields are $17, |				;it is FMOVECR; if not, continue	bnes	not_fmovecr	jmp	smovcr		|fmovecr; jmp directly to emulationnot_fmovecr:	movew	CMDREG1B(%a6),%d0	andl	#0x7F,%d0	cmpil	#0x38,%d0		|if the extension is >= $38, 	bge	serror		|it is illegal	bfextu	STAG(%a6){#0:#3},%d1	lsll	#3,%d0		|make room for STAG	addl	%d1,%d0		|combine for final index into table	leal	tblpre,%a1	|start of monster jump table	movel	(%a1,%d0.w*4),%a1	|real target address	leal	ETEMP(%a6),%a0	|a0 is pointer to src op	movel	USER_FPCR(%a6),%d1	andl	#0xFF,%d1		| discard all but rounding mode/prec	fmovel	#0,%fpcr	jmp	(%a1)||	ERROR|	.global	serrorserror:	st	STORE_FLG(%a6)	rts|| These routines load forced values into fp0.  They are called| by index into tbldo.|| Load a signed zero to fp0 and set inex2/ainex|	.global	snzrinxsnzrinx:	btstb	#sign_bit,LOCAL_EX(%a0)	|get sign of source operand	bnes	ld_mzinx	|if negative, branch	bsr	ld_pzero	|bsr so we can return and set inx	bra	t_inx2		|now, set the inx for the next instld_mzinx:	bsr	ld_mzero	|if neg, load neg zero, return here	bra	t_inx2		|now, set the inx for the next inst|| Load a signed zero to fp0; do not set inex2/ainex |	.global	szeroszero:	btstb	#sign_bit,LOCAL_EX(%a0) |get sign of source operand	bne	ld_mzero	|if neg, load neg zero	bra	ld_pzero	|load positive zero|| Load a signed infinity to fp0; do not set inex2/ainex |	.global	sinfsinf:	btstb	#sign_bit,LOCAL_EX(%a0)	|get sign of source operand	bne	ld_minf			|if negative branch	bra	ld_pinf|| Load a signed one to fp0; do not set inex2/ainex |	.global	sonesone:	btstb	#sign_bit,LOCAL_EX(%a0)	|check sign of source	bne	ld_mone	bra	ld_pone|| Load a signed pi/2 to fp0; do not set inex2/ainex |	.global	spi_2spi_2:	btstb	#sign_bit,LOCAL_EX(%a0)	|check sign of source	bne	ld_mpi2	bra	ld_ppi2|| Load either a +0 or +inf for plus/minus operand|	.global	szr_infszr_inf:	btstb	#sign_bit,LOCAL_EX(%a0)	|check sign of source	bne	ld_pzero	bra	ld_pinf|| Result is either an operr or +inf for plus/minus operand| [Used by slogn, slognp1, slog10, and slog2]|	.global	sopr_infsopr_inf:	btstb	#sign_bit,LOCAL_EX(%a0)	|check sign of source	bne	t_operr	bra	ld_pinf||	FLOGNP1 |	.global	sslognp1sslognp1:	fmovemx (%a0),%fp0-%fp0	fcmpb	#-1,%fp0	fbgt	slognp1			fbeq	t_dz2		|if = -1, divide by zero exception	fmovel	#0,%FPSR		|clr N flag	bra	t_operr		|take care of operands < -1||	FETOXM1|	.global	setoxm1isetoxm1i:	btstb	#sign_bit,LOCAL_EX(%a0)	|check sign of source	bne	ld_mone	bra	ld_pinf||	FLOGN|| Test for 1.0 as an input argument, returning +zero.  Also check| the sign and return operr if negative.|	.global	sslognsslogn:	btstb	#sign_bit,LOCAL_EX(%a0) 	bne	t_operr		|take care of operands < 0	cmpiw	#0x3fff,LOCAL_EX(%a0) |test for 1.0 input	bne	slogn	cmpil	#0x80000000,LOCAL_HI(%a0)	bne	slogn	tstl	LOCAL_LO(%a0)	bne	slogn	fmovex	PZERO,%fp0	rts	.global	sslogndsslognd:	btstb	#sign_bit,LOCAL_EX(%a0) 	beq	slognd	bra	t_operr		|take care of operands < 0||	FLOG10|	.global	sslog10sslog10:	btstb	#sign_bit,LOCAL_EX(%a0)	bne	t_operr		|take care of operands < 0	cmpiw	#0x3fff,LOCAL_EX(%a0) |test for 1.0 input	bne	slog10	cmpil	#0x80000000,LOCAL_HI(%a0)	bne	slog10	tstl	LOCAL_LO(%a0)	bne	slog10	fmovex	PZERO,%fp0	rts	.global	sslog10dsslog10d:	btstb	#sign_bit,LOCAL_EX(%a0) 	beq	slog10d	bra	t_operr		|take care of operands < 0||	FLOG2|	.global	sslog2sslog2:	btstb	#sign_bit,LOCAL_EX(%a0)	bne	t_operr		|take care of operands < 0	cmpiw	#0x3fff,LOCAL_EX(%a0) |test for 1.0 input	bne	slog2	cmpil	#0x80000000,LOCAL_HI(%a0)	bne	slog2	tstl	LOCAL_LO(%a0)	bne	slog2	fmovex	PZERO,%fp0	rts	.global	sslog2dsslog2d:	btstb	#sign_bit,LOCAL_EX(%a0) 	beq	slog2d	bra	t_operr		|take care of operands < 0||	FMOD|pmodt:|				;$21 fmod|				;dtag,stag	.long	smod		|  00,00  norm,norm = normal	.long	smod_oper	|  00,01  norm,zero = nan with operr	.long	smod_fpn	|  00,10  norm,inf  = fpn	.long	smod_snan	|  00,11  norm,nan  = nan	.long	smod_zro	|  01,00  zero,norm = +-zero	.long	smod_oper	|  01,01  zero,zero = nan with operr	.long	smod_zro	|  01,10  zero,inf  = +-zero	.long	smod_snan	|  01,11  zero,nan  = nan	.long	smod_oper	|  10,00  inf,norm  = nan with operr	.long	smod_oper	|  10,01  inf,zero  = nan with operr	.long	smod_oper	|  10,10  inf,inf   = nan with operr	.long	smod_snan	|  10,11  inf,nan   = nan	.long	smod_dnan	|  11,00  nan,norm  = nan	.long	smod_dnan	|  11,01  nan,zero  = nan	.long	smod_dnan	|  11,10  nan,inf   = nan	.long	smod_dnan	|  11,11  nan,nan   = nan	.global	pmodpmod:	clrb	FPSR_QBYTE(%a6) | clear quotient field	bfextu	STAG(%a6){#0:#3},%d0 |stag = d0	bfextu	DTAG(%a6){#0:#3},%d1 |dtag = d1|| Alias extended denorms to norms for the jump table.|	bclrl	#2,%d0	bclrl	#2,%d1	lslb	#2,%d1	orb	%d0,%d1		|d1{3:2} = dtag, d1{1:0} = stag|				;Tag values:|				;00 = norm or denorm|				;01 = zero|				;10 = inf|				;11 = nan	lea	pmodt,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)smod_snan:	bra	src_nansmod_dnan:	bra	dst_nansmod_oper:	bra	t_operrsmod_zro:	moveb	ETEMP(%a6),%d1	|get sign of src op	moveb	FPTEMP(%a6),%d0	|get sign of dst op	eorb	%d0,%d1		|get exor of sign bits	btstl	#7,%d1		|test for sign	beqs	smod_zsn	|if clr, do not set sign big	bsetb	#q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bitsmod_zsn:	btstl	#7,%d0		|test if + or -	beq	ld_pzero	|if pos then load +0	bra	ld_mzero	|else neg load -0	smod_fpn:	moveb	ETEMP(%a6),%d1	|get sign of src op	moveb	FPTEMP(%a6),%d0	|get sign of dst op	eorb	%d0,%d1		|get exor of sign bits	btstl	#7,%d1		|test for sign	beqs	smod_fsn	|if clr, do not set sign big	bsetb	#q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bitsmod_fsn:	tstb	DTAG(%a6)	|filter out denormal destination case	bpls	smod_nrm	|	leal	FPTEMP(%a6),%a0	|a0<- addr(FPTEMP)	bra	t_resdnrm	|force UNFL(but exact) resultsmod_nrm:	fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision	fmovex FPTEMP(%a6),%fp0	|return dest to fp0	rts		||	FREM|premt:|				;$25 frem|				;dtag,stag	.long	srem		|  00,00  norm,norm = normal	.long	srem_oper	|  00,01  norm,zero = nan with operr	.long	srem_fpn	|  00,10  norm,inf  = fpn	.long	srem_snan	|  00,11  norm,nan  = nan	.long	srem_zro	|  01,00  zero,norm = +-zero	.long	srem_oper	|  01,01  zero,zero = nan with operr	.long	srem_zro	|  01,10  zero,inf  = +-zero	.long	srem_snan	|  01,11  zero,nan  = nan	.long	srem_oper	|  10,00  inf,norm  = nan with operr	.long	srem_oper	|  10,01  inf,zero  = nan with operr	.long	srem_oper	|  10,10  inf,inf   = nan with operr	.long	srem_snan	|  10,11  inf,nan   = nan	.long	srem_dnan	|  11,00  nan,norm  = nan	.long	srem_dnan	|  11,01  nan,zero  = nan	.long	srem_dnan	|  11,10  nan,inf   = nan	.long	srem_dnan	|  11,11  nan,nan   = nan	.global	premprem:	clrb	FPSR_QBYTE(%a6)   |clear quotient field	bfextu	STAG(%a6){#0:#3},%d0 |stag = d0	bfextu	DTAG(%a6){#0:#3},%d1 |dtag = d1|| Alias extended denorms to norms for the jump table.|	bclr	#2,%d0	bclr	#2,%d1	lslb	#2,%d1	orb	%d0,%d1		|d1{3:2} = dtag, d1{1:0} = stag|				;Tag values:|				;00 = norm or denorm|				;01 = zero|				;10 = inf|				;11 = nan	lea	premt,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)	srem_snan:	bra	src_nansrem_dnan:	bra	dst_nansrem_oper:	bra	t_operrsrem_zro:	moveb	ETEMP(%a6),%d1	|get sign of src op	moveb	FPTEMP(%a6),%d0	|get sign of dst op	eorb	%d0,%d1		|get exor of sign bits	btstl	#7,%d1		|test for sign	beqs	srem_zsn	|if clr, do not set sign big	bsetb	#q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bitsrem_zsn:	btstl	#7,%d0		|test if + or -	beq	ld_pzero	|if pos then load +0	bra	ld_mzero	|else neg load -0	srem_fpn:	moveb	ETEMP(%a6),%d1	|get sign of src op	moveb	FPTEMP(%a6),%d0	|get sign of dst op	eorb	%d0,%d1		|get exor of sign bits	btstl	#7,%d1		|test for sign	beqs	srem_fsn	|if clr, do not set sign big	bsetb	#q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bitsrem_fsn:	tstb	DTAG(%a6)	|filter out denormal destination case	bpls	srem_nrm	|	leal	FPTEMP(%a6),%a0	|a0<- addr(FPTEMP)	bra	t_resdnrm	|force UNFL(but exact) resultsrem_nrm:	fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision	fmovex FPTEMP(%a6),%fp0	|return dest to fp0	rts||	FSCALE|pscalet:|				;$26 fscale|				;dtag,stag	.long	sscale		|  00,00  norm,norm = result	.long	sscale		|  00,01  norm,zero = fpn	.long	scl_opr		|  00,10  norm,inf  = nan with operr	.long	scl_snan	|  00,11  norm,nan  = nan	.long	scl_zro		|  01,00  zero,norm = +-zero	.long	scl_zro		|  01,01  zero,zero = +-zero	.long	scl_opr		|  01,10  zero,inf  = nan with operr	.long	scl_snan	|  01,11  zero,nan  = nan	.long	scl_inf		|  10,00  inf,norm  = +-inf	.long	scl_inf		|  10,01  inf,zero  = +-inf	.long	scl_opr		|  10,10  inf,inf   = nan with operr 	.long	scl_snan	|  10,11  inf,nan   = nan 	.long	scl_dnan	|  11,00  nan,norm  = nan 	.long	scl_dnan	|  11,01  nan,zero  = nan 	.long	scl_dnan	|  11,10  nan,inf   = nan	.long	scl_dnan	|  11,11  nan,nan   = nan	.global	pscalepscale:	bfextu	STAG(%a6){#0:#3},%d0 |stag in d0	bfextu	DTAG(%a6){#0:#3},%d1 |dtag in d1	bclrl	#2,%d0		|alias  denorm into norm	bclrl	#2,%d1		|alias  denorm into norm	lslb	#2,%d1	orb	%d0,%d1		|d1{4:2} = dtag, d1{1:0} = stag|				;dtag values     stag values:|				;000 = norm      00 = norm|				;001 = zero	 01 = zero|				;010 = inf	 10 = inf|				;011 = nan	 11 = nan|				;100 = dnrm||	leal	pscalet,%a1	|load start of jump table	movel	(%a1,%d1.w*4),%a1	|load a1 with label depending on tag	jmp	(%a1)		|go to the routinescl_opr:	bra	t_operrscl_dnan:	bra	dst_nanscl_zro:	btstb	#sign_bit,FPTEMP_EX(%a6)	|test if + or -	beq	ld_pzero		|if pos then load +0	bra	ld_mzero		|if neg then load -0scl_inf:	btstb	#sign_bit,FPTEMP_EX(%a6)	|test if + or -	beq	ld_pinf			|if pos then load +inf	bra	ld_minf			|else neg load -infscl_snan:	bra	src_nan||	FSINCOS|	.global	ssincoszssincosz:	btstb	#sign_bit,ETEMP(%a6)	|get sign	beqs	sincosp	fmovex	MZERO,%fp0	bras	sincoscomsincosp:	fmovex PZERO,%fp0sincoscom:  	fmovemx PONE,%fp1-%fp1	|do not allow FPSR to be affected	bra	sto_cos		|store cosine result	.global	ssincosissincosi:	fmovex QNAN,%fp1	|load NAN	bsr	sto_cos		|store cosine result	fmovex QNAN,%fp0	|load NAN	bra	t_operr	.global	ssincosnanssincosnan:	movel	ETEMP_EX(%a6),FP_SCR1(%a6)	movel	ETEMP_HI(%a6),FP_SCR1+4(%a6)	movel	ETEMP_LO(%a6),FP_SCR1+8(%a6)	bsetb	#signan_bit,FP_SCR1+4(%a6)	fmovemx FP_SCR1(%a6),%fp1-%fp1	bsr	sto_cos	bra	src_nan|| This code forces default values for the zero, inf, and nan cases | in the transcendentals code.  The CC bits must be set in the| stacked FPSR to be correctly reported.||**Returns +PI/2	.global	ld_ppi2ld_ppi2:	fmovex PPIBY2,%fp0		|load +pi/2	bra	t_inx2			|set inex2 exc|**Returns -PI/2	.global	ld_mpi2ld_mpi2:	fmovex MPIBY2,%fp0		|load -pi/2	orl	#neg_mask,USER_FPSR(%a6)	|set N bit	bra	t_inx2			|set inex2 exc|**Returns +inf	.global	ld_pinfld_pinf:	fmovex PINF,%fp0		|load +inf	orl	#inf_mask,USER_FPSR(%a6)	|set I bit	rts|**Returns -inf	.global	ld_minfld_minf:	fmovex MINF,%fp0		|load -inf	orl	#neg_mask+inf_mask,USER_FPSR(%a6)	|set N and I bits	rts|**Returns +1	.global	ld_poneld_pone:	fmovex PONE,%fp0		|load +1	rts|**Returns -1	.global	ld_moneld_mone:	fmovex MONE,%fp0		|load -1	orl	#neg_mask,USER_FPSR(%a6)	|set N bit	rts|**Returns +0	.global	ld_pzerold_pzero:	fmovex PZERO,%fp0		|load +0	orl	#z_mask,USER_FPSR(%a6)	|set Z bit	rts|**Returns -0	.global	ld_mzerold_mzero:	fmovex MZERO,%fp0		|load -0	orl	#neg_mask+z_mask,USER_FPSR(%a6)	|set N and Z bits	rts	|end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -