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

📄 fp.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
div_d:	jal	get_ft_fs_d	xor	t0, t0, t4			# compute sign of result	move	t4, t0	bne	t1, DEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, result_fs_d		# if FS is NAN, result is FS	bne	t3, zero, result_fs_d	bne	t5, DEXP_INF, result_fs_d	# is FT an infinity?	bne	t6, zero, result_ft_d		# if FT is NAN, result is FT	bne	t7, zero, result_ft_d	b	invalid_d			# infinity/infinity is invalid1:	bne	t5, DEXP_INF, 1f		# is FT an infinity?	bne	t6, zero, result_ft_d		# if FT is NAN, result is FT	bne	t7, zero, result_ft_d	move	t1, zero			# x / infinity is zero	move	t2, zero	move	t3, zero	b	result_fs_d1:	bne	t1, zero, 2f			# is FS zero?	bne	t2, zero, 1f	bne	t3, zero, 1f	bne	t5, zero, result_fs_d		# FS=zero, is FT zero?	bne	t6, zero, result_fs_d	beq	t7, zero, invalid_d		# 0 / 0	b	result_fs_d			# result = 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	bne	t7, 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, DEXP_INF			# result is infinity	move	t2, zero	move	t3, zero	b	result_fs_d1:	jal	renorm_ft_d	b	3f2:	subu	t5, t5, DEXP_BIAS		# unbias FT exponent	or	t6, t6, DIMPL_ONE		# set implied one bit3:	subu	t1, t1, t5			# compute exponent	subu	t1, t1, 3			# compensate for result position	li	v0, DFRAC_BITS+3		# number of bits to divide	move	t8, t2				# init dividend	move	t9, t3	move	t2, zero			# init result	move	t3, zero1:	bltu	t8, t6, 3f			# is dividend >= divisor?	bne	t8, t6, 2f	bltu	t9, t7, 3f2:	sltu	v1, t9, t7			# subtract divisor from dividend	subu	t9, t9, t7	subu	t8, t8, t6	subu	t8, t8, v1	or	t3, t3, 1			# remember that we did	bne	t8, zero, 3f			# if not done, continue	bne	t9, zero, 3f	li	v1, 32				# shift result to final position	blt	v0, v1, 2f			# shift < 32 bits?	subu	v0, v0, v1			# shift by > 32 bits	sll	t2, t3, v0			# shift upper part	move	t3, zero	b	norm_d2:	subu	v1, v1, v0			# shift by < 32 bits	sll	t2, t2, v0			# shift upper part	srl	t9, t3, v1			# save bits shifted out	or	t2, t2, t9			# and put into upper part	sll	t3, t3, v0	b	norm_d3:	sll	t8, t8, 1			# shift dividend	srl	v1, t9, 31			# save bit shifted out	or	t8, t8, v1			# and put into upper part	sll	t9, t9, 1	sll	t2, t2, 1			# shift result	srl	v1, t3, 31			# save bit shifted out	or	t2, t2, v1			# and put into upper part	sll	t3, t3, 1	subu	v0, v0, 1			# are we done?	bne	v0, zero, 1b			# no, continue	sltu	v0, zero, t9			# be sure to save any one bits	or	t8, t8, v0			# from the lower remainder	b	norm_d/* * Single precision absolute value. */abs_s:	jal	get_fs_s	move	t0, zero			# set sign positive	b	result_fs_s/* * Double precision absolute value. */abs_d:	jal	get_fs_d	move	t0, zero			# set sign positive	b	result_fs_d/* * Single precision move. */mov_s:	jal	get_fs_s	b	result_fs_s/* * Double precision move. */mov_d:	jal	get_fs_d	b	result_fs_d/* * Single precision negate. */neg_s:	jal	get_fs_s	xor	t0, t0, 1			# reverse sign	b	result_fs_s/* * Double precision negate. */neg_d:	jal	get_fs_d	xor	t0, t0, 1			# reverse sign	b	result_fs_d/* * Convert double to single. */cvt_s_d:	jal	get_fs_d	bne	t1, DEXP_INF, 1f		# is FS an infinity?	li	t1, SEXP_INF			# convert to single	sll	t2, t2, 3			# convert D fraction to S	srl	t8, t3, 32 - 3	or	t2, t2, t8	b	result_fs_s1:	bne	t1, zero, 2f			# is FS zero?	bne	t2, zero, 1f	beq	t3, zero, result_fs_s		# result=01:	jal	renorm_fs_d	subu	t1, t1, 3			# correct exp for shift below	b	3f2:	subu	t1, t1, DEXP_BIAS		# unbias exponent	or	t2, t2, DIMPL_ONE		# add implied one bit3:	sll	t2, t2, 3			# convert D fraction to S	srl	t8, t3, 32 - 3	or	t2, t2, t8	sll	t8, t3, 3	b	norm_noshift_s/* * Convert integer to single. */cvt_s_w:	jal	get_fs_int	bne	t2, zero, 1f			# check for zero	move	t1, zero	b	result_fs_s/* * Find out how many leading zero bits are in t2 and put in t9. */1:	move	v0, t2	move	t9, zero	srl	v1, v0, 16	bne	v1, zero, 1f	addu	t9, 16	sll	v0, 161:	srl	v1, v0, 24	bne	v1, zero, 1f	addu	t9, 8	sll	v0, 81:	srl	v1, v0, 28	bne	v1, zero, 1f	addu	t9, 4	sll	v0, 41:	srl	v1, v0, 30	bne	v1, zero, 1f	addu	t9, 2	sll	v0, 21:	srl	v1, v0, 31	bne	v1, zero, 1f	addu	t9, 1/* * Now shift t2 the correct number of bits. */1:	subu	t9, t9, SLEAD_ZEROS		# dont count leading zeros	li	t1, 23				# init exponent	subu	t1, t1, t9			# compute exponent	beq	t9, zero, 1f	li	v0, 32	blt	t9, zero, 2f			# if shift < 0, shift right	subu	v0, v0, t9	sll	t2, t2, t9			# shift left1:	add	t1, t1, SEXP_BIAS		# bias exponent	and	t2, t2, ~SIMPL_ONE		# clear implied one bit	b	result_fs_s2:	negu	t9				# shift right by t9	subu	v0, v0, t9	sll	t8, t2, v0			# save bits shifted out	srl	t2, t2, t9	b	norm_noshift_s/* * Convert single to double. */cvt_d_s:	jal	get_fs_s	move	t3, zero	bne	t1, SEXP_INF, 1f		# is FS an infinity?	li	t1, DEXP_INF			# convert to double	b	result_fs_d1:	bne	t1, zero, 2f			# is FS denormalized or zero?	beq	t2, zero, result_fs_d		# is FS zero?	jal	renorm_fs_s	move	t8, zero	b	norm_d2:	addu	t1, t1, DEXP_BIAS - SEXP_BIAS	# bias exponent correctly	sll	t3, t2, 32 - 3			# convert S fraction to D	srl	t2, t2, 3	b	result_fs_d/* * Convert integer to double. */cvt_d_w:	jal	get_fs_int	bne	t2, zero, 1f			# check for zero	move	t1, zero			# result=0	move	t3, zero	b	result_fs_d/* * Find out how many leading zero bits are in t2 and put in t9. */1:	move	v0, t2	move	t9, zero	srl	v1, v0, 16	bne	v1, zero, 1f	addu	t9, 16	sll	v0, 161:	srl	v1, v0, 24	bne	v1, zero, 1f	addu	t9, 8	sll	v0, 81:	srl	v1, v0, 28	bne	v1, zero, 1f	addu	t9, 4	sll	v0, 41:	srl	v1, v0, 30	bne	v1, zero, 1f	addu	t9, 2	sll	v0, 21:	srl	v1, v0, 31	bne	v1, zero, 1f	addu	t9, 1/* * Now shift t2 the correct number of bits. */1:	subu	t9, t9, DLEAD_ZEROS		# dont count leading zeros	li	t1, DEXP_BIAS + 20		# init exponent	subu	t1, t1, t9			# compute exponent	beq	t9, zero, 1f	li	v0, 32	blt	t9, zero, 2f			# if shift < 0, shift right	subu	v0, v0, t9	sll	t2, t2, t9			# shift left1:	and	t2, t2, ~DIMPL_ONE		# clear implied one bit	move	t3, zero	b	result_fs_d2:	negu	t9				# shift right by t9	subu	v0, v0, t9	sll	t3, t2, v0	srl	t2, t2, t9	and	t2, t2, ~DIMPL_ONE		# clear implied one bit	b	result_fs_d/* * Convert single to integer. */cvt_w_s:	jal	get_fs_s	bne	t1, SEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, invalid_w		# invalid conversion1:	bne	t1, zero, 1f			# is FS zero?	beq	t2, zero, result_fs_w		# result is zero	move	t2, zero			# result is an inexact zero	b	inexact_w1:	subu	t1, t1, SEXP_BIAS		# unbias exponent	or	t2, t2, SIMPL_ONE		# add implied one bit	sll	t3, t2, 32 - 3			# convert S fraction to D	srl	t2, t2, 3	b	cvt_w/* * Convert double to integer. */cvt_w_d:	jal	get_fs_d	bne	t1, DEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, invalid_w		# invalid conversion	bne	t3, zero, invalid_w		# invalid conversion1:	bne	t1, zero, 2f			# is FS zero?	bne	t2, zero, 1f	beq	t3, zero, result_fs_w		# result is zero1:	move	t2, zero			# result is an inexact zero	b	inexact_w2:	subu	t1, t1, DEXP_BIAS		# unbias exponent	or	t2, t2, DIMPL_ONE		# add implied one bitcvt_w:	blt	t1, WEXP_MIN, underflow_w	# is exponent too small?	li	v0, WEXP_MAX+1	bgt	t1, v0, overflow_w		# is exponent too large?	bne	t1, v0, 1f			# special check for INT_MIN	beq	t0, zero, overflow_w		# if positive, overflow	bne	t2, DIMPL_ONE, overflow_w	bne	t3, zero, overflow_w	li	t2, INT_MIN			# result is INT_MIN	b	result_fs_w1:	subu	v0, t1, 20			# compute amount to shift	beq	v0, zero, 2f			# is shift needed?	li	v1, 32	blt	v0, zero, 1f			# if shift < 0, shift right	subu	v1, v1, v0			# shift left	sll	t2, t2, v0	srl	t9, t3, v1			# save bits shifted out of t3	or	t2, t2, t9			# and put into t2	sll	t3, t3, v0			# shift FSs fraction	b	2f1:	negu	v0				# shift right by v0	subu	v1, v1, v0	sll	t8, t3, v1			# save bits shifted out	sltu	t8, zero, t8			# dont lose any ones	srl	t3, t3, v0			# shift FSs fraction	or	t3, t3, t8	sll	t9, t2, v1			# save bits shifted out of t2	or	t3, t3, t9			# and put into t3	srl	t2, t2, v0/* * round result (t0 is sign, t2 is integer part, t3 is fractional part). */2:	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	beq	v0, MACH_FPC_ROUND_RN, 3f	# round to nearest	beq	v0, MACH_FPC_ROUND_RZ, 5f	# round to zero (truncate)	beq	v0, MACH_FPC_ROUND_RP, 1f	# round to +infinity	beq	t0, zero, 5f			# if sign is positive, truncate	b	2f1:	bne	t0, zero, 5f			# if sign is negative, truncate2:	beq	t3, zero, 5f			# if no fraction bits, continue	addu	t2, t2, 1			# add rounding bit	blt	t2, zero, overflow_w		# overflow?	b	5f3:	li	v0, GUARDBIT			# load guard bit for rounding	addu	v0, v0, t3			# add remainder	sltu	v1, v0, t3			# compute carry out	beq	v1, zero, 4f			# if no carry, continue	addu	t2, t2, 1			# add carry to result	blt	t2, zero, overflow_w		# overflow?4:	bne	v0, zero, 5f			# if rounded remainder is zero	and	t2, t2, ~1			#  clear LSB (round to nearest)5:	beq	t0, zero, 1f			# result positive?	negu	t2				# convert to negative integer1:	beq	t3, zero, result_fs_w		# is result exact?/* * Handle inexact exception. */inexact_w:	or	a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT	and	v0, a1, MACH_FPC_ENABLE_INEXACT	bne	v0, zero, fpe_trap	ctc1	a1, MACH_FPC_CSR		# save exceptions	b	result_fs_w/* * Conversions to integer which overflow will trap (if enabled), * or generate an inexact trap (if enabled), * or generate an invalid exception. */overflow_w:	or	a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW	and	v0, a1, MACH_FPC_ENABLE_OVERFLOW	bne	v0, zero, fpe_trap	and	v0, a1, MACH_FPC_ENABLE_INEXACT	bne	v0, zero, inexact_w		# inexact traps enabled?	b	invalid_w/* * Conversions to integer which underflow will trap (if enabled), * or generate an inexact trap (if enabled), * or generate an invalid exception. */underflow_w:	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW	and	v0, a1, MACH_FPC_ENABLE_UNDERFLOW	bne	v0, zero, fpe_trap	and	v0, a1, MACH_FPC_ENABLE_INEXACT	bne	v0, zero, inexact_w		# inexact traps enabled?	b	invalid_w/* * Compare single. */cmp_s:	jal	get_cmp_s	bne	t1, SEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, unordered		# FS is a NAN1:	bne	t5, SEXP_INF, 2f		# is FT an infinity?	bne	t6, zero, unordered		# FT is a NAN2:	sll	t1, t1, 23			# reassemble exp & frac	or	t1, t1, t2	sll	t5, t5, 23			# reassemble exp & frac	or	t5, t5, t6	beq	t0, zero, 1f			# is FS positive?	negu	t11:	beq	t4, zero, 1f			# is FT positive?	negu	t51:	li	v0, COND_LESS	blt	t1, t5, test_cond		# is FS < FT?	li	v0, COND_EQUAL	beq	t1, t5, test_cond		# is FS == FT?	move	v0, zero			# FS > FT	b	test_cond/* * Compare double. */cmp_d:	jal	get_cmp_d	bne	t1, DEXP_INF, 1f		# is FS an infinity?	bne	t2, zero, unordered	bne	t3, zero, unordered		# FS is a NAN1:	bne	t5, DEXP_INF, 2f		# is FT an infinity?	bne	t6, zero, unordered	bne	t7, zero, unordered		# FT is a NAN2:	sll	t1, t1, 20			# reassemble exp & frac	or	t1, t1, t2	sll	t5, t5, 20			# reassemble exp & frac	or	t5, t5, t6	beq	t0, zero, 1f			# is FS positive?	not	t3				# negate t1,t3	not	t1	addu	t3, t3, 1	seq	v0, t3, zero			# compute carry	addu	t1, t1, v01:	beq	t4, zero, 1f			# is FT positive?	not	t7				# negate t5,t7	not	t5	addu	t7, t7, 1	seq	v0, t7, zero			# compute carry	addu	t5, t5, v01:	li	v0, COND_LESS	blt	t1, t5, test_cond		# is FS(MSW) < FT(MSW)?	move	v0, zero	bne	t1, t5, test_cond		# is FS(MSW) > FT(MSW)?	li	v0, COND_LESS	bltu	t3, t7, test_cond		# is FS(LSW) < FT(LSW)?	li	v0, COND_EQUAL	beq	t3, t7, test_cond		# is FS(LSW) == FT(LSW)?	move	v0, zero			# FS > FTtest_cond:	and	v0, v0, a0			# condition match instruction?set_cond:	bne	v0, zero, 1f	and	a1, a1, ~MACH_FPC_COND_BIT	# clear condition bit	b	2f1:	or	a1, a1, MACH_FPC_COND_BIT	# set condition bit2:	ctc1	a1, MACH_FPC_CSR		# save condition bit	b	doneunordered:	and	v0, a0, COND_UNORDERED		# this cmp match unordered?	bne	v0, zero, 1f	and	a1, a1, ~MACH_FPC_COND_BIT	# clear condition bit	b	2f1:	or	a1, a1, MACH_FPC_COND_BIT	# set condition bit2:	and	v0, a0, COND_SIGNAL	beq	v0, zero, 1f			# is this a signaling cmp?	or	a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID	and	v0, a1, MACH_FPC_ENABLE_INVALID	bne	v0, zero, fpe_trap1:	ctc1	a1, MACH_FPC_CSR		# save condition bit	b	done/* * Determine the amount to shift the fraction in order to restore the * normalized position. After that, round and handle exceptions. */norm_s:	move	v0, t2	move	t9, zero			# t9 = num of leading zeros	bne	t2, zero, 1f	move	v0, t8

⌨️ 快捷键说明

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