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

📄 fp.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
	addu	t9, 321:	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,t8 the correct number of bits. */1:	subu	t9, t9, SLEAD_ZEROS		# dont count leading zeros	subu	t1, t1, t9			# adjust the exponent	beq	t9, zero, norm_noshift_s	li	v1, 32	blt	t9, zero, 1f			# if shift < 0, shift right	subu	v1, v1, t9	sll	t2, t2, t9			# shift t2,t8 left	srl	v0, t8, v1			# save bits shifted out	or	t2, t2, v0	sll	t8, t8, t9	b	norm_noshift_s1:	negu	t9				# shift t2,t8 right by t9	subu	v1, v1, t9	sll	v0, t8, v1			# save bits shifted out	sltu	v0, zero, v0			# be sure to save any one bits	srl	t8, t8, t9	or	t8, t8, v0	sll	v0, t2, v1			# save bits shifted out	or	t8, t8, v0	srl	t2, t2, t9norm_noshift_s:	move	t5, t1				# save unrounded exponent	move	t6, t2				# save unrounded fraction	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	t8, zero, 5f			# if exact, continue	addu	t2, t2, 1			# add rounding bit	bne	t2, SIMPL_ONE<<1, 5f		# need to adjust exponent?	addu	t1, t1, 1			# adjust exponent	srl	t2, t2, 1			# renormalize fraction	b	5f3:	li	v0, GUARDBIT			# load guard bit for rounding	addu	v0, v0, t8			# add remainder	sltu	v1, v0, t8			# compute carry out	beq	v1, zero, 4f			# if no carry, continue	addu	t2, t2, 1			# add carry to result	bne	t2, SIMPL_ONE<<1, 4f		# need to adjust exponent?	addu	t1, t1, 1			# adjust exponent	srl	t2, t2, 1			# renormalize fraction4:	bne	v0, zero, 5f			# if rounded remainder is zero	and	t2, t2, ~1			#  clear LSB (round to nearest)5:	bgt	t1, SEXP_MAX, overflow_s	# overflow?	blt	t1, SEXP_MIN, underflow_s	# underflow?	bne	t8, zero, inexact_s		# is result inexact?	addu	t1, t1, SEXP_BIAS		# bias exponent	and	t2, t2, ~SIMPL_ONE		# clear implied one bit	b	result_fs_s/* * Handle inexact exception. */inexact_s:	addu	t1, t1, SEXP_BIAS		# bias exponent	and	t2, t2, ~SIMPL_ONE		# clear implied one bitinexact_nobias_s:	jal	set_fd_s			# save result	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	done/* * Overflow will trap (if enabled), * or generate an inexact trap (if enabled), * or generate an infinity. */overflow_s:	or	a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW	and	v0, a1, MACH_FPC_ENABLE_OVERFLOW	beq	v0, zero, 1f	subu	t1, t1, 192			# bias exponent	and	t2, t2, ~SIMPL_ONE		# clear implied one bit	jal	set_fd_s			# save result	b	fpe_trap1:	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, 1f	# round to zero (truncate)	beq	v0, MACH_FPC_ROUND_RP, 2f	# round to +infinity	bne	t0, zero, 3f1:	li	t1, SEXP_MAX			# result is max finite	li	t2, 0x007fffff	b	inexact_s2:	bne	t0, zero, 1b3:	li	t1, SEXP_MAX + 1		# result is infinity	move	t2, zero	b	inexact_s/* * In this implementation, "tininess" is detected "after rounding" and * "loss of accuracy" is detected as "an inexact result". */underflow_s:	and	v0, a1, MACH_FPC_ENABLE_UNDERFLOW	beq	v0, zero, 1f/* * Underflow is enabled so compute the result and trap. */	addu	t1, t1, 192			# bias exponent	and	t2, t2, ~SIMPL_ONE		# clear implied one bit	jal	set_fd_s			# save result	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW	b	fpe_trap/* * Underflow is not enabled so compute the result, * signal inexact result (if it is) and trap (if enabled). */1:	move	t1, t5				# get unrounded exponent	move	t2, t6				# get unrounded fraction	li	t9, SEXP_MIN			# compute shift amount	subu	t9, t9, t1			# shift t2,t8 right by t9	blt	t9, SFRAC_BITS+2, 3f		# shift all the bits out?	move	t1, zero			# result is inexact zero	move	t2, zero	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW/* * Now round the zero result. * Only need to worry about rounding to +- infinity when the sign matches. */	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	beq	v0, MACH_FPC_ROUND_RN, inexact_nobias_s	# round to nearest	beq	v0, MACH_FPC_ROUND_RZ, inexact_nobias_s	# round to zero	beq	v0, MACH_FPC_ROUND_RP, 1f	# round to +infinity	beq	t0, zero, inexact_nobias_s	# if sign is positive, truncate	b	2f1:	bne	t0, zero, inexact_nobias_s	# if sign is negative, truncate2:	addu	t2, t2, 1			# add rounding bit	b	inexact_nobias_s3:	li	v1, 32	subu	v1, v1, t9	sltu	v0, zero, t8			# be sure to save any one bits	sll	t8, t2, v1			# save bits shifted out	or	t8, t8, v0			# include sticky bits	srl	t2, t2, t9/* * Now round the denormalized result. */	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	t8, zero, 5f			# if exact, continue	addu	t2, t2, 1			# add rounding bit	b	5f3:	li	v0, GUARDBIT			# load guard bit for rounding	addu	v0, v0, t8			# add remainder	sltu	v1, v0, t8			# compute carry out	beq	v1, zero, 4f			# if no carry, continue	addu	t2, t2, 1			# add carry to result4:	bne	v0, zero, 5f			# if rounded remainder is zero	and	t2, t2, ~1			#  clear LSB (round to nearest)5:	move	t1, zero			# denorm or zero exponent	jal	set_fd_s			# save result	beq	t8, zero, done			# check for exact result	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW	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	done/* * Determine the amount to shift the fraction in order to restore the * normalized position. After that, round and handle exceptions. */norm_d:	move	v0, t2	move	t9, zero			# t9 = num of leading zeros	bne	t2, zero, 1f	move	v0, t3	addu	t9, 32	bne	t3, zero, 1f	move	v0, t8	addu	t9, 321:	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,t3,t8 the correct number of bits. */1:	subu	t9, t9, DLEAD_ZEROS		# dont count leading zeros	subu	t1, t1, t9			# adjust the exponent	beq	t9, zero, norm_noshift_d	li	v1, 32	blt	t9, zero, 2f			# if shift < 0, shift right	blt	t9, v1, 1f			# shift by < 32?	subu	t9, t9, v1			# shift by >= 32	subu	v1, v1, t9	sll	t2, t3, t9			# shift left by t9	srl	v0, t8, v1			# save bits shifted out	or	t2, t2, v0	sll	t3, t8, t9	move	t8, zero	b	norm_noshift_d1:	subu	v1, v1, t9	sll	t2, t2, t9			# shift left by t9	srl	v0, t3, v1			# save bits shifted out	or	t2, t2, v0	sll	t3, t3, t9	srl	v0, t8, v1			# save bits shifted out	or	t3, t3, v0	sll	t8, t8, t9	b	norm_noshift_d2:	negu	t9				# shift right by t9	subu	v1, v1, t9			#  (known to be < 32 bits)	sll	v0, t8, v1			# save bits shifted out	sltu	v0, zero, v0			# be sure to save any one bits	srl	t8, t8, t9	or	t8, t8, v0	sll	v0, t3, v1			# save bits shifted out	or	t8, t8, v0	srl	t3, t3, t9	sll	v0, t2, v1			# save bits shifted out	or	t3, t3, v0	srl	t2, t2, t9norm_noshift_d:	move	t5, t1				# save unrounded exponent	move	t6, t2				# save unrounded fraction (MS)	move	t7, t3				# save unrounded fraction (LS)	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	t8, zero, 5f			# if exact, continue	addu	t3, t3, 1			# add rounding bit	bne	t3, zero, 5f			# branch if no carry	addu	t2, t2, 1			# add carry	bne	t2, DIMPL_ONE<<1, 5f		# need to adjust exponent?	addu	t1, t1, 1			# adjust exponent	srl	t2, t2, 1			# renormalize fraction	b	5f3:	li	v0, GUARDBIT			# load guard bit for rounding	addu	v0, v0, t8			# add remainder	sltu	v1, v0, t8			# compute carry out	beq	v1, zero, 4f			# branch if no carry	addu	t3, t3, 1			# add carry	bne	t3, zero, 4f			# branch if no carry	addu	t2, t2, 1			# add carry to result	bne	t2, DIMPL_ONE<<1, 4f		# need to adjust exponent?	addu	t1, t1, 1			# adjust exponent	srl	t2, t2, 1			# renormalize fraction4:	bne	v0, zero, 5f			# if rounded remainder is zero	and	t3, t3, ~1			#  clear LSB (round to nearest)5:	bgt	t1, DEXP_MAX, overflow_d	# overflow?	blt	t1, DEXP_MIN, underflow_d	# underflow?	bne	t8, zero, inexact_d		# is result inexact?	addu	t1, t1, DEXP_BIAS		# bias exponent	and	t2, t2, ~DIMPL_ONE		# clear implied one bit	b	result_fs_d/* * Handle inexact exception. */inexact_d:	addu	t1, t1, DEXP_BIAS		# bias exponent	and	t2, t2, ~DIMPL_ONE		# clear implied one bitinexact_nobias_d:	jal	set_fd_d			# save result	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	done/* * Overflow will trap (if enabled), * or generate an inexact trap (if enabled), * or generate an infinity. */overflow_d:	or	a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW	and	v0, a1, MACH_FPC_ENABLE_OVERFLOW	beq	v0, zero, 1f	subu	t1, t1, 1536			# bias exponent	and	t2, t2, ~DIMPL_ONE		# clear implied one bit	jal	set_fd_d			# save result	b	fpe_trap1:	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, 1f	# round to zero (truncate)	beq	v0, MACH_FPC_ROUND_RP, 2f	# round to +infinity	bne	t0, zero, 3f1:	li	t1, DEXP_MAX			# result is max finite	li	t2, 0x000fffff	li	t3, 0xffffffff	b	inexact_d2:	bne	t0, zero, 1b3:	li	t1, DEXP_MAX + 1		# result is infinity	move	t2, zero	move	t3, zero	b	inexact_d/* * In this implementation, "tininess" is detected "after rounding" and * "loss of accuracy" is detected as "an inexact result". */underflow_d:	and	v0, a1, MACH_FPC_ENABLE_UNDERFLOW	beq	v0, zero, 1f/* * Underflow is enabled so compute the result and trap. */	addu	t1, t1, 1536			# bias exponent	and	t2, t2, ~DIMPL_ONE		# clear implied one bit	jal	set_fd_d			# save result	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW	b	fpe_trap/* * Underflow is not enabled so compute the result, * signal inexact result (if it is) and trap (if enabled). */1:	move	t1, t5				# get unrounded exponent	move	t2, t6				# get unrounded fraction (MS)	move	t3, t7				# get unrounded fraction (LS)	li	t9, DEXP_MIN			# compute shift amount	subu	t9, t9, t1			# shift t2,t8 right by t9	blt	t9, DFRAC_BITS+2, 3f		# shift all the bits out?	move	t1, zero			# result is inexact zero	move	t2, zero	move	t3, zero	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW/* * Now round the zero result. * Only need to worry about rounding to +- infinity when the sign matches. */	and	v0, a1, MACH_FPC_ROUNDING_BITS	# get rounding mode	beq	v0, MACH_FPC_ROUND_RN, inexact_nobias_d	# round to nearest	beq	v0, MACH_FPC_ROUND_RZ, inexact_nobias_d	# round to zero	beq	v0, MACH_FPC_ROUND_RP, 1f	# round to +infinity	beq	t0, zero, inexact_nobias_d	# if sign is positive, truncate	b	2f1:	bne	t0, zero, inexact_nobias_d	# if sign is negative, truncate2:	addu	t3, t3, 1			# add rounding bit	b	inexact_nobias_d3:	li	v1, 32	blt	t9, v1, 1f			# shift by < 32?	subu	t9, t9, v1			# shift right by >= 32	subu	v1, v1, t9	sltu	v0, zero, t8			# be sure to save any one bits	sll	t8, t2, v1			# save bits shifted out	or	t8, t8, v0			# include sticky bits	srl	t3, t2, t9	move	t2, zero	b	2f1:	subu	v1, v1, t9			# shift right by t9	sltu	v0, zero, t8			# be sure to save any one bits	sll	t8, t3, v1			# save bits shifted out	or	t8, t8, v0			# include sticky bits	srl	t3, t3, t9	sll	v0, t2, v1			# save bits shifted out	or	t3, t3, v0	srl	t2, t2, t9/* * Now round the denormalized result. */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	t8, zero, 5f			# if exact, continue	addu	t3, t3, 1			# add rounding bit	bne	t3, zero, 5f			# if no carry, continue	addu	t2, t2, 1			# add carry	b	5f3:	li	v0, GUARDBIT			# load guard bit for rounding	addu	v0, v0, t8			# add remainder	sltu	v1, v0, t8			# compute carry out	beq	v1, zero, 4f			# if no carry, continue	addu	t3, t3, 1			# add rounding bit	bne	t3, zero, 4f			# if no carry, continue	addu	t2, t2, 1			# add carry4:	bne	v0, zero, 5f			# if rounded remainder is zero	and	t3, t3, ~1			#  clear LSB (round to nearest)5:	move	t1, zero			# denorm or zero exponent	jal	set_fd_d			# save result	beq	t8, zero, done			# check for exact result	or	a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW	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	done/* * Signal an invalid operation if the trap is enabled; otherwise, * the result is a quiet NAN. */invalid_s:					# trap invalid operation	or	a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID	and	v0, a1, MACH_FPC_ENABLE_INVALID	bne	v0, zero, fpe_trap	ctc1	a1, MACH_FPC_CSR		# save exceptions	move	t0, zero			# result is a quiet NAN	li	t1, SEXP_INF	li	t2, SQUIET_NAN	jal	set_fd_s			# save result (in t0,t1,t2)	b	done/* * Signal an invalid operation if the trap is enabled; otherwise, * the result is a quiet NAN. */invalid_d:					# trap invalid operation	or	a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID	and	v0, a1, MACH_FPC_ENABLE_INVALID	bne	v0, zero, fpe_trap	ctc1	a1, MACH_FPC_CSR		# save exceptions	move	t0, zero			# result is a quiet NAN	li	t1, DEXP_INF	li	t2, DQUIET_NAN0	li	t3, DQUIET_NAN1	jal	set_fd_d			# save result (in t0,t1,t2,t3)	b	done/* * Signal an invalid operation if the trap is enabled; otherwise, * the result is INT_MAX or INT_MIN. */invalid_w:					# trap invalid operation	or	a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID	and	v0, a1, MACH_FPC_ENABLE_INVALID	bne	v0, zero, fpe_trap	ctc1	a1, MACH_FPC_CSR		# save exceptions	bne	t0, zero, 1f	li	t2, INT_MAX			# result is INT_MAX	b	result_fs_w1:	li	t2, INT_MIN			# result is INT_MIN	b	result_fs_w/* * Trap if the hardware should have handled this case. */fpe_trap:	move	a2, a1				# code = FP CSR	ctc1	a1, MACH_FPC_CSR		# save exceptions	break	0/* * Send an illegal instruction signal to the current process. */ill:	ctc1	a1, MACH_FPC_CSR		# save exceptions	move	a2, a0				# code = FP instruction	break	0result_ft_s:	move	t0, t4				# result is FT	move	t1, t5	move	t2, t6result_fs_s:					# result is FS	jal	set_fd_s			# save result (in t0,t1,t2)	b	done

⌨️ 快捷键说明

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