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

📄 ieee754-df.s

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
	cmphi	ip, #0x700	bhi	LSYM(Lml_u)	@ Round the result, merge final exponent.	cmp	lr, #0x80000000	moveqs	lr, xl, lsr #1	adcs	xl, xl, #0	adc	xh, xh, r4, lsl #20	RETLDM	"r4, r5, r6"	@ Multiplication by 0x1p*: let''s shortcut a lot of code.LSYM(Lml_1):	and	r6, r6, #0x80000000	orr	xh, r6, xh	orr	xl, xl, yl	eor	xh, xh, yh	subs	r4, r4, ip, lsr #1	rsbgts	r5, r4, ip	orrgt	xh, xh, r4, lsl #20	RETLDM	"r4, r5, r6" gt	@ Under/overflow: fix things up for the code below.	orr	xh, xh, #0x00100000	mov	lr, #0	subs	r4, r4, #1LSYM(Lml_u):	@ Overflow?	bgt	LSYM(Lml_o)	@ Check if denormalized result is possible, otherwise return signed 0.	cmn	r4, #(53 + 1)	movle	xl, #0	bicle	xh, xh, #0x7fffffff	RETLDM	"r4, r5, r6" le	@ Find out proper shift value.	rsb	r4, r4, #0	subs	r4, r4, #32	bge	2f	adds	r4, r4, #12	bgt	1f	@ shift result right of 1 to 20 bits, preserve sign bit, round, etc.	add	r4, r4, #20	rsb	r5, r4, #32	mov	r3, xl, lsl r5	mov	xl, xl, lsr r4	orr	xl, xl, xh, lsl r5	and	r2, xh, #0x80000000	bic	xh, xh, #0x80000000	adds	xl, xl, r3, lsr #31	adc	xh, r2, xh, lsr r4	orrs	lr, lr, r3, lsl #1	biceq	xl, xl, r3, lsr #31	RETLDM	"r4, r5, r6"	@ shift result right of 21 to 31 bits, or left 11 to 1 bits after	@ a register switch from xh to xl. Then round.1:	rsb	r4, r4, #12	rsb	r5, r4, #32	mov	r3, xl, lsl r4	mov	xl, xl, lsr r5	orr	xl, xl, xh, lsl r4	bic	xh, xh, #0x7fffffff	adds	xl, xl, r3, lsr #31	adc	xh, xh, #0	orrs	lr, lr, r3, lsl #1	biceq	xl, xl, r3, lsr #31	RETLDM	"r4, r5, r6"	@ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch	@ from xh to xl.  Leftover bits are in r3-r6-lr for rounding.2:	rsb	r5, r4, #32	orr	lr, lr, xl, lsl r5	mov	r3, xl, lsr r4	orr	r3, r3, xh, lsl r5	mov	xl, xh, lsr r4	bic	xh, xh, #0x7fffffff	bic	xl, xl, xh, lsr r4	add	xl, xl, r3, lsr #31	orrs	lr, lr, r3, lsl #1	biceq	xl, xl, r3, lsr #31	RETLDM	"r4, r5, r6"	@ One or both arguments are denormalized.	@ Scale them leftwards and preserve sign bit.LSYM(Lml_d):	teq	r4, #0	bne	2f	and	r6, xh, #0x800000001:	movs	xl, xl, lsl #1	adc	xh, xh, xh	tst	xh, #0x00100000	subeq	r4, r4, #1	beq	1b	orr	xh, xh, r6	teq	r5, #0	movne	pc, lr2:	and	r6, yh, #0x800000003:	movs	yl, yl, lsl #1	adc	yh, yh, yh	tst	yh, #0x00100000	subeq	r5, r5, #1	beq	3b	orr	yh, yh, r6	mov	pc, lrLSYM(Lml_s):	@ Isolate the INF and NAN cases away	teq	r4, ip	and	r5, ip, yh, lsr #20	teqne	r5, ip	beq	1f	@ Here, one or more arguments are either denormalized or zero.	orrs	r6, xl, xh, lsl #1	orrnes	r6, yl, yh, lsl #1	bne	LSYM(Lml_d)	@ Result is 0, but determine sign anyway.LSYM(Lml_z):	eor	xh, xh, yh	bic	xh, xh, #0x7fffffff	mov	xl, #0	RETLDM	"r4, r5, r6"1:	@ One or both args are INF or NAN.	orrs	r6, xl, xh, lsl #1	moveq	xl, yl	moveq	xh, yh	orrnes	r6, yl, yh, lsl #1	beq	LSYM(Lml_n)		@ 0 * INF or INF * 0 -> NAN	teq	r4, ip	bne	1f	orrs	r6, xl, xh, lsl #12	bne	LSYM(Lml_n)		@ NAN * <anything> -> NAN1:	teq	r5, ip	bne	LSYM(Lml_i)	orrs	r6, yl, yh, lsl #12	movne	xl, yl	movne	xh, yh	bne	LSYM(Lml_n)		@ <anything> * NAN -> NAN	@ Result is INF, but we need to determine its sign.LSYM(Lml_i):	eor	xh, xh, yh	@ Overflow: return INF (sign already in xh).LSYM(Lml_o):	and	xh, xh, #0x80000000	orr	xh, xh, #0x7f000000	orr	xh, xh, #0x00f00000	mov	xl, #0	RETLDM	"r4, r5, r6"	@ Return a quiet NAN.LSYM(Lml_n):	orr	xh, xh, #0x7f000000	orr	xh, xh, #0x00f80000	RETLDM	"r4, r5, r6"	FUNC_END aeabi_dmul	FUNC_END muldf3ARM_FUNC_START divdf3ARM_FUNC_ALIAS aeabi_ddiv divdf3		stmfd	sp!, {r4, r5, r6, lr}	@ Mask out exponents, trap any zero/denormal/INF/NAN.	mov	ip, #0xff	orr	ip, ip, #0x700	ands	r4, ip, xh, lsr #20	andnes	r5, ip, yh, lsr #20	teqne	r4, ip	teqne	r5, ip	bleq	LSYM(Ldv_s)	@ Substract divisor exponent from dividend''s.	sub	r4, r4, r5	@ Preserve final sign into lr.	eor	lr, xh, yh	@ Convert mantissa to unsigned integer.	@ Dividend -> r5-r6, divisor -> yh-yl.	orrs	r5, yl, yh, lsl #12	mov	xh, xh, lsl #12	beq	LSYM(Ldv_1)	mov	yh, yh, lsl #12	mov	r5, #0x10000000	orr	yh, r5, yh, lsr #4	orr	yh, yh, yl, lsr #24	mov	yl, yl, lsl #8	orr	r5, r5, xh, lsr #4	orr	r5, r5, xl, lsr #24	mov	r6, xl, lsl #8	@ Initialize xh with final sign bit.	and	xh, lr, #0x80000000	@ Ensure result will land to known bit position.	@ Apply exponent bias accordingly.	cmp	r5, yh	cmpeq	r6, yl	adc	r4, r4, #(255 - 2)	add	r4, r4, #0x300	bcs	1f	movs	yh, yh, lsr #1	mov	yl, yl, rrx1:	@ Perform first substraction to align result to a nibble.	subs	r6, r6, yl	sbc	r5, r5, yh	movs	yh, yh, lsr #1	mov	yl, yl, rrx	mov	xl, #0x00100000	mov	ip, #0x00080000	@ The actual division loop.1:	subs	lr, r6, yl	sbcs	lr, r5, yh	subcs	r6, r6, yl	movcs	r5, lr	orrcs	xl, xl, ip	movs	yh, yh, lsr #1	mov	yl, yl, rrx	subs	lr, r6, yl	sbcs	lr, r5, yh	subcs	r6, r6, yl	movcs	r5, lr	orrcs	xl, xl, ip, lsr #1	movs	yh, yh, lsr #1	mov	yl, yl, rrx	subs	lr, r6, yl	sbcs	lr, r5, yh	subcs	r6, r6, yl	movcs	r5, lr	orrcs	xl, xl, ip, lsr #2	movs	yh, yh, lsr #1	mov	yl, yl, rrx	subs	lr, r6, yl	sbcs	lr, r5, yh	subcs	r6, r6, yl	movcs	r5, lr	orrcs	xl, xl, ip, lsr #3	orrs	lr, r5, r6	beq	2f	mov	r5, r5, lsl #4	orr	r5, r5, r6, lsr #28	mov	r6, r6, lsl #4	mov	yh, yh, lsl #3	orr	yh, yh, yl, lsr #29	mov	yl, yl, lsl #3	movs	ip, ip, lsr #4	bne	1b	@ We are done with a word of the result.	@ Loop again for the low word if this pass was for the high word.	tst	xh, #0x00100000	bne	3f	orr	xh, xh, xl	mov	xl, #0	mov	ip, #0x80000000	b	1b2:	@ Be sure result starts in the high word.	tst	xh, #0x00100000	orreq	xh, xh, xl	moveq	xl, #03:	@ Check exponent range for under/overflow.	subs	ip, r4, #(254 - 1)	cmphi	ip, #0x700	bhi	LSYM(Lml_u)	@ Round the result, merge final exponent.	subs	ip, r5, yh	subeqs	ip, r6, yl	moveqs	ip, xl, lsr #1	adcs	xl, xl, #0	adc	xh, xh, r4, lsl #20	RETLDM	"r4, r5, r6"	@ Division by 0x1p*: shortcut a lot of code.LSYM(Ldv_1):	and	lr, lr, #0x80000000	orr	xh, lr, xh, lsr #12	adds	r4, r4, ip, lsr #1	rsbgts	r5, r4, ip	orrgt	xh, xh, r4, lsl #20	RETLDM	"r4, r5, r6" gt	orr	xh, xh, #0x00100000	mov	lr, #0	subs	r4, r4, #1	b	LSYM(Lml_u)	@ Result mightt need to be denormalized: put remainder bits	@ in lr for rounding considerations.LSYM(Ldv_u):	orr	lr, r5, r6	b	LSYM(Lml_u)	@ One or both arguments is either INF, NAN or zero.LSYM(Ldv_s):	and	r5, ip, yh, lsr #20	teq	r4, ip	teqeq	r5, ip	beq	LSYM(Lml_n)		@ INF/NAN / INF/NAN -> NAN	teq	r4, ip	bne	1f	orrs	r4, xl, xh, lsl #12	bne	LSYM(Lml_n)		@ NAN / <anything> -> NAN	teq	r5, ip	bne	LSYM(Lml_i)		@ INF / <anything> -> INF	mov	xl, yl	mov	xh, yh	b	LSYM(Lml_n)		@ INF / (INF or NAN) -> NAN1:	teq	r5, ip	bne	2f	orrs	r5, yl, yh, lsl #12	beq	LSYM(Lml_z)		@ <anything> / INF -> 0	mov	xl, yl	mov	xh, yh	b	LSYM(Lml_n)		@ <anything> / NAN -> NAN2:	@ If both are non-zero, we need to normalize and resume above.	orrs	r6, xl, xh, lsl #1	orrnes	r6, yl, yh, lsl #1	bne	LSYM(Lml_d)	@ One or both arguments are 0.	orrs	r4, xl, xh, lsl #1	bne	LSYM(Lml_i)		@ <non_zero> / 0 -> INF	orrs	r5, yl, yh, lsl #1	bne	LSYM(Lml_z)		@ 0 / <non_zero> -> 0	b	LSYM(Lml_n)		@ 0 / 0 -> NAN	FUNC_END aeabi_ddiv	FUNC_END divdf3#endif /* L_muldivdf3 */#ifdef L_cmpdf2@ Note: only r0 (return value) and ip are clobbered here.ARM_FUNC_START gtdf2ARM_FUNC_ALIAS gedf2 gtdf2	mov	ip, #-1	b	1fARM_FUNC_START ltdf2ARM_FUNC_ALIAS ledf2 ltdf2	mov	ip, #1	b	1fARM_FUNC_START cmpdf2ARM_FUNC_ALIAS nedf2 cmpdf2ARM_FUNC_ALIAS eqdf2 cmpdf2	mov	ip, #1			@ how should we specify unordered here?1:	str	ip, [sp, #-4]	@ Trap any INF/NAN first.	mov	ip, xh, lsl #1	mvns	ip, ip, asr #21	mov	ip, yh, lsl #1	mvnnes	ip, ip, asr #21	beq	3f	@ Test for equality.	@ Note that 0.0 is equal to -0.0.2:	orrs	ip, xl, xh, lsl #1	@ if x == 0.0 or -0.0	orreqs	ip, yl, yh, lsl #1	@ and y == 0.0 or -0.0	teqne	xh, yh			@ or xh == yh	teqeq	xl, yl			@ and xl == yl	moveq	r0, #0			@ then equal.	RETc(eq)	@ Clear C flag	cmn	r0, #0	@ Compare sign, 	teq	xh, yh	@ Compare values if same sign	cmppl	xh, yh	cmpeq	xl, yl	@ Result:	movcs	r0, yh, asr #31	mvncc	r0, yh, asr #31	orr	r0, r0, #1	RET	@ Look for a NAN.3:	mov	ip, xh, lsl #1	mvns	ip, ip, asr #21	bne	4f	orrs	ip, xl, xh, lsl #12	bne	5f			@ x is NAN4:	mov	ip, yh, lsl #1	mvns	ip, ip, asr #21	bne	2b	orrs	ip, yl, yh, lsl #12	beq	2b			@ y is not NAN5:	ldr	r0, [sp, #-4]		@ unordered return code	RET	FUNC_END gedf2	FUNC_END gtdf2	FUNC_END ledf2	FUNC_END ltdf2	FUNC_END nedf2	FUNC_END eqdf2	FUNC_END cmpdf2ARM_FUNC_START aeabi_cdrcmple	mov	ip, r0	mov	r0, r2	mov	r2, ip	mov	ip, r1	mov	r1, r3	mov	r3, ip	b	6f	ARM_FUNC_START aeabi_cdcmpeqARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq	@ The status-returning routines are required to preserve all	@ registers except ip, lr, and cpsr.6:	stmfd	sp!, {r0, lr}	ARM_CALL cmpdf2	@ Set the Z flag correctly, and the C flag unconditionally.	cmp	 r0, #0	@ Clear the C flag if the return value was -1, indicating	@ that the first operand was smaller than the second.	cmnmi	 r0, #0	RETLDM   "r0"	FUNC_END aeabi_cdcmple	FUNC_END aeabi_cdcmpeq	FUNC_END aeabi_cdrcmple	ARM_FUNC_START	aeabi_dcmpeq	str	lr, [sp, #-4]!	ARM_CALL aeabi_cdcmple	moveq	r0, #1	@ Equal to.	movne	r0, #0	@ Less than, greater than, or unordered.	RETLDM	FUNC_END aeabi_dcmpeqARM_FUNC_START	aeabi_dcmplt	str	lr, [sp, #-4]!	ARM_CALL aeabi_cdcmple	movcc	r0, #1	@ Less than.	movcs	r0, #0	@ Equal to, greater than, or unordered.	RETLDM	FUNC_END aeabi_dcmpltARM_FUNC_START	aeabi_dcmple	str	lr, [sp, #-4]!	ARM_CALL aeabi_cdcmple	movls	r0, #1  @ Less than or equal to.	movhi	r0, #0	@ Greater than or unordered.	RETLDM	FUNC_END aeabi_dcmpleARM_FUNC_START	aeabi_dcmpge	str	lr, [sp, #-4]!	ARM_CALL aeabi_cdrcmple	movls	r0, #1	@ Operand 2 is less than or equal to operand 1.	movhi	r0, #0	@ Operand 2 greater than operand 1, or unordered.	RETLDM	FUNC_END aeabi_dcmpgeARM_FUNC_START	aeabi_dcmpgt	str	lr, [sp, #-4]!	ARM_CALL aeabi_cdrcmple	movcc	r0, #1	@ Operand 2 is less than operand 1.	movcs	r0, #0  @ Operand 2 is greater than or equal to operand 1,			@ or they are unordered.	RETLDM	FUNC_END aeabi_dcmpgt#endif /* L_cmpdf2 */#ifdef L_unorddf2ARM_FUNC_START unorddf2ARM_FUNC_ALIAS aeabi_dcmpun unorddf2	mov	ip, xh, lsl #1	mvns	ip, ip, asr #21	bne	1f	orrs	ip, xl, xh, lsl #12	bne	3f			@ x is NAN1:	mov	ip, yh, lsl #1	mvns	ip, ip, asr #21	bne	2f	orrs	ip, yl, yh, lsl #12	bne	3f			@ y is NAN2:	mov	r0, #0			@ arguments are ordered.	RET3:	mov	r0, #1			@ arguments are unordered.	RET	FUNC_END aeabi_dcmpun	FUNC_END unorddf2#endif /* L_unorddf2 */#ifdef L_fixdfsiARM_FUNC_START fixdfsiARM_FUNC_ALIAS aeabi_d2iz fixdfsi	@ check exponent range.	mov	r2, xh, lsl #1	adds	r2, r2, #(1 << 21)	bcs	2f			@ value is INF or NAN	bpl	1f			@ value is too small	mov	r3, #(0xfffffc00 + 31)	subs	r2, r3, r2, asr #21	bls	3f			@ value is too large	@ scale value	mov	r3, xh, lsl #11	orr	r3, r3, #0x80000000	orr	r3, r3, xl, lsr #21	tst	xh, #0x80000000		@ the sign bit	mov	r0, r3, lsr r2	rsbne	r0, r0, #0	RET1:	mov	r0, #0	RET2:	orrs	xl, xl, xh, lsl #12	bne	4f			@ x is NAN.3:	ands	r0, xh, #0x80000000	@ the sign bit	moveq	r0, #0x7fffffff		@ maximum signed positive si	RET4:	mov	r0, #0			@ How should we convert NAN?	RET	FUNC_END aeabi_d2iz	FUNC_END fixdfsi#endif /* L_fixdfsi */#ifdef L_fixunsdfsiARM_FUNC_START fixunsdfsiARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi	@ check exponent range.	movs	r2, xh, lsl #1	bcs	1f			@ value is negative	adds	r2, r2, #(1 << 21)	bcs	2f			@ value is INF or NAN	bpl	1f			@ value is too small	mov	r3, #(0xfffffc00 + 31)	subs	r2, r3, r2, asr #21	bmi	3f			@ value is too large	@ scale value	mov	r3, xh, lsl #11	orr	r3, r3, #0x80000000	orr	r3, r3, xl, lsr #21	mov	r0, r3, lsr r2	RET1:	mov	r0, #0	RET2:	orrs	xl, xl, xh, lsl #12	bne	4f			@ value is NAN.3:	mov	r0, #0xffffffff		@ maximum unsigned si	RET4:	mov	r0, #0			@ How should we convert NAN?	RET	FUNC_END aeabi_d2uiz	FUNC_END fixunsdfsi#endif /* L_fixunsdfsi */#ifdef L_truncdfsf2ARM_FUNC_START truncdfsf2ARM_FUNC_ALIAS aeabi_d2f truncdfsf2	@ check exponent range.	mov	r2, xh, lsl #1	subs	r3, r2, #((1023 - 127) << 21)	subcss	ip, r3, #(1 << 21)	rsbcss	ip, ip, #(254 << 21)	bls	2f			@ value is out of range1:	@ shift and round mantissa	and	ip, xh, #0x80000000	mov	r2, xl, lsl #3	orr	xl, ip, xl, lsr #29	cmp	r2, #0x80000000	adc	r0, xl, r3, lsl #2	biceq	r0, r0, #1	RET2:	@ either overflow or underflow	tst	xh, #0x40000000	bne	3f			@ overflow	@ check if denormalized value is possible	adds	r2, r3, #(23 << 21)	andlt	r0, xh, #0x80000000	@ too small, return signed 0.	RETc(lt)	@ denormalize value so we can resume with the code above afterwards.	orr	xh, xh, #0x00100000	mov	r2, r2, lsr #21	rsb	r2, r2, #24	rsb	ip, r2, #32	movs	r3, xl, lsl ip	mov	xl, xl, lsr r2	orrne	xl, xl, #1		@ fold r3 for rounding considerations. 	mov	r3, xh, lsl #11	mov	r3, r3, lsr #11	orr	xl, xl, r3, lsl ip	mov	r3, r3, lsr r2	mov	r3, r3, lsl #1	b	1b3:	@ chech for NAN	mvns	r3, r2, asr #21	bne	5f			@ simple overflow	orrs	r3, xl, xh, lsl #12	movne	r0, #0x7f000000	orrne	r0, r0, #0x00c00000	RETc(ne)			@ return NAN5:	@ return INF with sign	and	r0, xh, #0x80000000	orr	r0, r0, #0x7f000000	orr	r0, r0, #0x00800000	RET	FUNC_END aeabi_d2f	FUNC_END truncdfsf2#endif /* L_truncdfsf2 */

⌨️ 快捷键说明

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