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

📄 fp.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
	.word	cmp_d		# 55	.word	ill		# 55	.word	ill		# 55	.word	ill		# 55	.word	ill		# 55	.word	ill		# 55	.word	ill		# 55	.word	cmp_s		# 56	.word	cmp_d		# 56	.word	ill		# 56	.word	ill		# 56	.word	ill		# 56	.word	ill		# 56	.word	ill		# 56	.word	ill		# 56	.word	cmp_s		# 57	.word	cmp_d		# 57	.word	ill		# 57	.word	ill		# 57	.word	ill		# 57	.word	ill		# 57	.word	ill		# 57	.word	ill		# 57	.word	cmp_s		# 58	.word	cmp_d		# 58	.word	ill		# 58	.word	ill		# 58	.word	ill		# 58	.word	ill		# 58	.word	ill		# 58	.word	ill		# 58	.word	cmp_s		# 59	.word	cmp_d		# 59	.word	ill		# 59	.word	ill		# 59	.word	ill		# 59	.word	ill		# 59	.word	ill		# 59	.word	ill		# 59	.word	cmp_s		# 60	.word	cmp_d		# 60	.word	ill		# 60	.word	ill		# 60	.word	ill		# 60	.word	ill		# 60	.word	ill		# 60	.word	ill		# 60	.word	cmp_s		# 61	.word	cmp_d		# 61	.word	ill		# 61	.word	ill		# 61	.word	ill		# 61	.word	ill		# 61	.word	ill		# 61	.word	ill		# 61	.word	cmp_s		# 62	.word	cmp_d		# 62	.word	ill		# 62	.word	ill		# 62	.word	ill		# 62	.word	ill		# 62	.word	ill		# 62	.word	ill		# 62	.word	cmp_s		# 63	.word	cmp_d		# 63	.word	ill		# 63	.word	ill		# 63	.word	ill		# 63	.word	ill		# 63	.word	ill		# 63	.word	ill		# 63	.text/* * Single precision subtract. */sub_s:	jal	get_ft_fs_s	xor	t4, t4, 1			# negate FT sign bit	b	add_sub_s/* * Single precision add. */add_s:	jal	get_ft_fs_sadd_sub_s:	bne	t1, SEXP_INF, 1f		# is FS an infinity?	bne	t5, SEXP_INF, result_fs_s	# if FT is not inf, result=FS	bne	t2, zero, result_fs_s		# if FS is NAN, result is FS	bne	t6, zero, result_ft_s		# if FT is NAN, result is FT	bne	t0, t4, invalid_s		# both infinities same sign?	b	result_fs_s			# result is in FS1:	beq	t5, SEXP_INF, result_ft_s	# if FT is inf, result=FT	bne	t1, zero, 4f			# is FS a denormalized num?	beq	t2, zero, 3f			# is FS zero?	bne	t5, zero, 2f			# is FT a denormalized num?	beq	t6, zero, result_fs_s		# FT is zero, result=FS	jal	renorm_fs_s	jal	renorm_ft_s	b	5f2:	jal	renorm_fs_s	subu	t5, t5, SEXP_BIAS		# unbias FT exponent	or	t6, t6, SIMPL_ONE		# set implied one bit	b	5f3:	bne	t5, zero, result_ft_s		# if FT != 0, result=FT	bne	t6, zero, result_ft_s	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	bne	v0, MACH_FPC_ROUND_RM, 1f	# round to -infinity?	or	t0, t0, t4			# compute result sign	b	result_fs_s1:	and	t0, t0, t4			# compute result sign	b	result_fs_s4:	bne	t5, zero, 2f			# is FT a denormalized num?	beq	t6, zero, result_fs_s		# FT is zero, result=FS	subu	t1, t1, SEXP_BIAS		# unbias FS exponent	or	t2, t2, SIMPL_ONE		# set implied one bit	jal	renorm_ft_s	b	5f2:	subu	t1, t1, SEXP_BIAS		# unbias FS exponent	or	t2, t2, SIMPL_ONE		# set implied one bit	subu	t5, t5, SEXP_BIAS		# unbias FT exponent	or	t6, t6, SIMPL_ONE		# set implied one bit/* * Perform the addition. */5:	move	t8, zero			# no shifted bits (sticky reg)	beq	t1, t5, 4f			# no shift needed	subu	v0, t1, t5			# v0 = difference of exponents	move	v1, v0				# v1 = abs(difference)	bge	v0, zero, 1f	negu	v11:	ble	v1, SFRAC_BITS+2, 2f		# is difference too great?	li	t8, STICKYBIT			# set the sticky bit	bge	v0, zero, 1f			# check which exp is larger	move	t1, t5				# result exp is FTs	move	t2, zero			# FSs fraction shifted is zero	b	4f1:	move	t6, zero			# FTs fraction shifted is zero	b	4f2:	li	t9, 32				# compute 32 - abs(exp diff)	subu	t9, t9, v1	bgt	v0, zero, 3f			# if FS > FT, shift FTs frac	move	t1, t5				# FT > FS, result exp is FTs	sll	t8, t2, t9			# save bits shifted out	srl	t2, t2, v1			# shift FSs fraction	b	4f3:	sll	t8, t6, t9			# save bits shifted out	srl	t6, t6, v1			# shift FTs fraction4:	bne	t0, t4, 1f			# if signs differ, subtract	addu	t2, t2, t6			# add fractions	b	norm_s1:	blt	t2, t6, 3f			# subtract larger from smaller	bne	t2, t6, 2f			# if same, result=0	move	t1, zero			# result=0	move	t2, zero	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	bne	v0, MACH_FPC_ROUND_RM, 1f	# round to -infinity?	or	t0, t0, t4			# compute result sign	b	result_fs_s1:	and	t0, t0, t4			# compute result sign	b	result_fs_s2:	sltu	t9, zero, t8			# compute t2:zero - t6:t8	subu	t8, zero, t8	subu	t2, t2, t6			# subtract fractions	subu	t2, t2, t9			# subtract barrow	b	norm_s3:	move	t0, t4				# sign of result = FTs	sltu	t9, zero, t8			# compute t6:zero - t2:t8	subu	t8, zero, t8	subu	t2, t6, t2			# subtract fractions	subu	t2, t2, t9			# subtract barrow	b	norm_s/* * Double precision subtract. */sub_d:	jal	get_ft_fs_d	xor	t4, t4, 1			# negate sign bit	b	add_sub_d/* * Double precision add. */add_d:	jal	get_ft_fs_dadd_sub_d:	bne	t1, DEXP_INF, 1f		# is FS an infinity?	bne	t5, DEXP_INF, result_fs_d	# if FT is not inf, result=FS	bne	t2, zero, result_fs_d		# if FS is NAN, result is FS	bne	t3, zero, result_fs_d	bne	t6, zero, result_ft_d		# if FT is NAN, result is FT	bne	t7, zero, result_ft_d	bne	t0, t4, invalid_d		# both infinities same sign?	b	result_fs_d			# result is in FS1:	beq	t5, DEXP_INF, result_ft_d	# if FT is inf, result=FT	bne	t1, zero, 4f			# is FS a denormalized num?	bne	t2, zero, 1f			# is FS zero?	beq	t3, zero, 3f1:	bne	t5, zero, 2f			# is FT a denormalized num?	bne	t6, zero, 1f	beq	t7, zero, result_fs_d		# FT is zero, result=FS1:	jal	renorm_fs_d	jal	renorm_ft_d	b	5f2:	jal	renorm_fs_d	subu	t5, t5, DEXP_BIAS		# unbias FT exponent	or	t6, t6, DIMPL_ONE		# set implied one bit	b	5f3:	bne	t5, zero, result_ft_d		# if FT != 0, result=FT	bne	t6, zero, result_ft_d	bne	t7, zero, result_ft_d	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	bne	v0, MACH_FPC_ROUND_RM, 1f	# round to -infinity?	or	t0, t0, t4			# compute result sign	b	result_fs_d1:	and	t0, t0, t4			# compute result sign	b	result_fs_d4:	bne	t5, zero, 2f			# is FT a denormalized num?	bne	t6, zero, 1f	beq	t7, zero, result_fs_d		# FT is zero, result=FS1:	subu	t1, t1, DEXP_BIAS		# unbias FS exponent	or	t2, t2, DIMPL_ONE		# set implied one bit	jal	renorm_ft_d	b	5f2:	subu	t1, t1, DEXP_BIAS		# unbias FS exponent	or	t2, t2, DIMPL_ONE		# set implied one bit	subu	t5, t5, DEXP_BIAS		# unbias FT exponent	or	t6, t6, DIMPL_ONE		# set implied one bit/* * Perform the addition. */5:	move	t8, zero			# no shifted bits (sticky reg)	beq	t1, t5, 4f			# no shift needed	subu	v0, t1, t5			# v0 = difference of exponents	move	v1, v0				# v1 = abs(difference)	bge	v0, zero, 1f	negu	v11:	ble	v1, DFRAC_BITS+2, 2f		# is difference too great?	li	t8, STICKYBIT			# set the sticky bit	bge	v0, zero, 1f			# check which exp is larger	move	t1, t5				# result exp is FTs	move	t2, zero			# FSs fraction shifted is zero	move	t3, zero	b	4f1:	move	t6, zero			# FTs fraction shifted is zero	move	t7, zero	b	4f2:	li	t9, 32	bge	v0, zero, 3f			# if FS > FT, shift FTs frac	move	t1, t5				# FT > FS, result exp is FTs	blt	v1, t9, 1f			# shift right by < 32?	subu	v1, v1, t9	subu	t9, t9, v1	sll	t8, t2, t9			# save bits shifted out	sltu	t9, zero, t3			# dont lose any one bits	or	t8, t8, t9			# save sticky bit	srl	t3, t2, v1			# shift FSs fraction	move	t2, zero	b	4f1:	subu	t9, t9, v1	sll	t8, t3, t9			# save bits shifted out	srl	t3, t3, v1			# shift FSs fraction	sll	t9, t2, t9			# save bits shifted out of t2	or	t3, t3, t9			# and put into t3	srl	t2, t2, v1	b	4f3:	blt	v1, t9, 1f			# shift right by < 32?	subu	v1, v1, t9	subu	t9, t9, v1	sll	t8, t6, t9			# save bits shifted out	srl	t7, t6, v1			# shift FTs fraction	move	t6, zero	b	4f1:	subu	t9, t9, v1	sll	t8, t7, t9			# save bits shifted out	srl	t7, t7, v1			# shift FTs fraction	sll	t9, t6, t9			# save bits shifted out of t2	or	t7, t7, t9			# and put into t3	srl	t6, t6, v14:	bne	t0, t4, 1f			# if signs differ, subtract	addu	t3, t3, t7			# add fractions	sltu	t9, t3, t7			# compute carry	addu	t2, t2, t6			# add fractions	addu	t2, t2, t9			# add carry	b	norm_d1:	blt	t2, t6, 3f			# subtract larger from smaller	bne	t2, t6, 2f	bltu	t3, t7, 3f	bne	t3, t7, 2f			# if same, result=0	move	t1, zero			# result=0	move	t2, zero	move	t3, zero	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	bne	v0, MACH_FPC_ROUND_RM, 1f	# round to -infinity?	or	t0, t0, t4			# compute result sign	b	result_fs_d1:	and	t0, t0, t4			# compute result sign	b	result_fs_d2:	beq	t8, zero, 1f			# compute t2:t3:zero - t6:t7:t8	subu	t8, zero, t8	sltu	v0, t3, 1			# compute barrow out	subu	t3, t3, 1			# subtract barrow	subu	t2, t2, v01:	sltu	v0, t3, t7	subu	t3, t3, t7			# subtract fractions	subu	t2, t2, t6			# subtract fractions	subu	t2, t2, v0			# subtract barrow	b	norm_d3:	move	t0, t4				# sign of result = FTs	beq	t8, zero, 1f			# compute t6:t7:zero - t2:t3:t8	subu	t8, zero, t8	sltu	v0, t7, 1			# compute barrow out	subu	t7, t7, 1			# subtract barrow	subu	t6, t6, v01:	sltu	v0, t7, t3	subu	t3, t7, t3			# subtract fractions	subu	t2, t6, t2			# subtract fractions	subu	t2, t2, v0			# subtract barrow	b	norm_d/* * Single precision multiply. */mul_s:	jal	get_ft_fs_s	xor	t0, t0, t4			# compute sign of result	move	t4, t0	bne	t1, SEXP_INF, 2f		# is FS an infinity?	bne	t2, zero, result_fs_s		# if FS is a NAN, result=FS	bne	t5, SEXP_INF, 1f		# FS is inf, is FT an infinity?	bne	t6, zero, result_ft_s		# if FT is a NAN, result=FT	b	result_fs_s			# result is infinity1:	bne	t5, zero, result_fs_s		# inf * zero? if no, result=FS	bne	t6, zero, result_fs_s	b	invalid_s			# infinity * zero is invalid2:	bne	t5, SEXP_INF, 1f		# FS != inf, is FT an infinity?	bne	t1, zero, result_ft_s		# zero * inf? if no, result=FT	bne	t2, zero, result_ft_s	bne	t6, zero, result_ft_s		# if FT is a NAN, result=FT	b	invalid_s			# zero * infinity is invalid1:	bne	t1, zero, 1f			# is FS zero?	beq	t2, zero, result_fs_s		# result is zero	jal	renorm_fs_s	b	2f1:	subu	t1, t1, SEXP_BIAS		# unbias FS exponent	or	t2, t2, SIMPL_ONE		# set implied one bit2:	bne	t5, zero, 1f			# is FT zero?	beq	t6, zero, result_ft_s		# result is zero	jal	renorm_ft_s	b	2f1:	subu	t5, t5, SEXP_BIAS		# unbias FT exponent	or	t6, t6, SIMPL_ONE		# set implied one bit2:	addu	t1, t1, t5			# compute result exponent	addu	t1, t1, 9			# account for binary point	multu	t2, t6				# multiply fractions	mflo	t8	mfhi	t2	b	norm_s/* * Double precision multiply. */mul_d:	jal	get_ft_fs_d	xor	t0, t0, t4			# compute sign of result	move	t4, t0	bne	t1, DEXP_INF, 2f		# is FS an infinity?	bne	t2, zero, result_fs_d		# if FS is a NAN, result=FS	bne	t3, zero, result_fs_d	bne	t5, DEXP_INF, 1f		# FS is inf, is FT an infinity?	bne	t6, zero, result_ft_d		# if FT is a NAN, result=FT	bne	t7, zero, result_ft_d	b	result_fs_d			# result is infinity1:	bne	t5, zero, result_fs_d		# inf * zero? if no, result=FS	bne	t6, zero, result_fs_d	bne	t7, zero, result_fs_d	b	invalid_d			# infinity * zero is invalid2:	bne	t5, DEXP_INF, 1f		# FS != inf, is FT an infinity?	bne	t1, zero, result_ft_d		# zero * inf? if no, result=FT	bne	t2, zero, result_ft_d		# if FS is a NAN, result=FS	bne	t3, zero, result_ft_d	bne	t6, zero, result_ft_d		# if FT is a NAN, result=FT	bne	t7, zero, result_ft_d	b	invalid_d			# zero * infinity is invalid1:	bne	t1, zero, 2f			# is FS zero?	bne	t2, zero, 1f	beq	t3, zero, result_fs_d		# result is zero1:	jal	renorm_fs_d	b	3f2:	subu	t1, t1, DEXP_BIAS		# unbias FS exponent	or	t2, t2, DIMPL_ONE		# set implied one bit3:	bne	t5, zero, 2f			# is FT zero?	bne	t6, zero, 1f	beq	t7, zero, result_ft_d		# result is zero1:	jal	renorm_ft_d	b	3f2:	subu	t5, t5, DEXP_BIAS		# unbias FT exponent	or	t6, t6, DIMPL_ONE		# set implied one bit3:	addu	t1, t1, t5			# compute result exponent	addu	t1, t1, 12			# ???	multu	t3, t7				# multiply fractions (low * low)	move	t4, t2				# free up t2,t3 for result	move	t5, t3	mflo	a3				# save low order bits	mfhi	t8	not	v0, t8	multu	t4, t7				# multiply FS(high) * FT(low)	mflo	v1	mfhi	t3				# init low result	sltu	v0, v0, v1			# compute carry	addu	t8, v1	multu	t5, t6				# multiply FS(low) * FT(high)	addu	t3, t3, v0			# add carry	not	v0, t8	mflo	v1	mfhi	t2	sltu	v0, v0, v1	addu	t8, v1	multu	t4, t6				# multiply FS(high) * FT(high)	addu	t3, v0	not	v1, t3	sltu	v1, v1, t2	addu	t3, t2	not	v0, t3	mfhi	t2	addu	t2, v1	mflo	v1	sltu	v0, v0, v1	addu	t2, v0	addu	t3, v1	sltu	a3, zero, a3			# reduce t8,a3 to just t8	or	t8, a3	b	norm_d/* * Single precision divide. */div_s:	jal	get_ft_fs_s	xor	t0, t0, t4			# compute sign of result	move	t4, t0	bne	t1, SEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, result_fs_s		# if FS is NAN, result is FS	bne	t5, SEXP_INF, result_fs_s	# is FT an infinity?	bne	t6, zero, result_ft_s		# if FT is NAN, result is FT	b	invalid_s			# infinity/infinity is invalid1:	bne	t5, SEXP_INF, 1f		# is FT an infinity?	bne	t6, zero, result_ft_s		# if FT is NAN, result is FT	move	t1, zero			# x / infinity is zero	move	t2, zero	b	result_fs_s1:	bne	t1, zero, 2f			# is FS zero?	bne	t2, zero, 1f	bne	t5, zero, result_fs_s		# FS=zero, is FT zero?	beq	t6, zero, invalid_s		# 0 / 0	b	result_fs_s			# result = zero1:	jal	renorm_fs_s	b	3f2:	subu	t1, t1, SEXP_BIAS		# unbias FS exponent	or	t2, t2, SIMPL_ONE		# set implied one bit3:	bne	t5, zero, 2f			# is FT zero?	bne	t6, zero, 1f	or	a1, a1, MACH_FPC_EXCEPTION_DIV0 | MACH_FPC_STICKY_DIV0	and	v0, a1, MACH_FPC_ENABLE_DIV0	# trap enabled?	bne	v0, zero, fpe_trap	ctc1	a1, MACH_FPC_CSR		# save exceptions	li	t1, SEXP_INF			# result is infinity	move	t2, zero	b	result_fs_s1:	jal	renorm_ft_s	b	3f2:	subu	t5, t5, SEXP_BIAS		# unbias FT exponent	or	t6, t6, SIMPL_ONE		# set implied one bit3:	subu	t1, t1, t5			# compute exponent	subu	t1, t1, 3			# compensate for result position	li	v0, SFRAC_BITS+3		# number of bits to divide	move	t8, t2				# init dividend	move	t2, zero			# init result1:	bltu	t8, t6, 3f			# is dividend >= divisor?2:	subu	t8, t8, t6			# subtract divisor from dividend	or	t2, t2, 1			# remember that we did	bne	t8, zero, 3f			# if not done, continue	sll	t2, t2, v0			# shift result to final position	b	norm_s3:	sll	t8, t8, 1			# shift dividend	sll	t2, t2, 1			# shift result	subu	v0, v0, 1			# are we done?	bne	v0, zero, 1b			# no, continue	b	norm_s/* * Double precision divide. */

⌨️ 快捷键说明

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