ieee754-df.s

来自「俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)」· S 代码 · 共 1,226 行 · 第 1/2 页

S
1,226 行
字号
	RETLDM	"r4, r5, r6" le	@ Find out proper shift value.LSYM(Lml_r):	mvn	r4, r4, asr #19	subs	r4, r4, #30	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	movs	xh, xh, lsl #1	mov	xh, xh, lsr r4	mov	xh, xh, rrx	adds	xl, xl, r3, lsr #31	adc	xh, xh, #0	teq	lr, #0	teqeq	r3, #0x80000000	biceq	xl, xl, #1	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	teq	lr, #0	teqeq	r3, #0x80000000	biceq	xl, xl, #1	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	mov	r6, 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	r6, r6, lr	teqeq	r3, #0x80000000	biceq	xl, xl, #1	RETLDM	"r4, r5, r6"	@ One or both arguments are denormalized.	@ Scale them leftwards and preserve sign bit.LSYM(Lml_d):	mov	lr, #0	teq	r4, #0	bne	2f	and	r6, xh, #0x800000001:	movs	xl, xl, lsl #1	adc	xh, lr, xh, lsl #1	tst	xh, #0x00100000	subeq	r4, r4, #(1 << 19)	beq	1b	orr	xh, xh, r6	teq	r5, #0	bne	LSYM(Lml_x)2:	and	r6, yh, #0x800000003:	movs	yl, yl, lsl #1	adc	yh, lr, yh, lsl #1	tst	yh, #0x00100000	subeq	r5, r5, #(1 << 20)	beq	3b	orr	yh, yh, r6	b	LSYM(Lml_x)	@ One or both args are INF or NAN.LSYM(Lml_s):	orrs	r6, xl, xh, lsl #1	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	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 NAN.LSYM(Lml_n):	mov	xh, #0x7f000000	orr	xh, xh, #0x00f80000	RETLDM	"r4, r5, r6"	FUNC_END muldf3ARM_FUNC_START divdf3	stmfd	sp!, {r4, r5, r6, lr}	@ Mask out exponents.	mov	ip, #0x7f000000	orr	ip, ip, #0x00f00000	and	r4, xh, ip	and	r5, yh, ip	@ Trap any INF/NAN or zeroes.	teq	r4, ip	teqne	r5, ip	orrnes	r6, xl, xh, lsl #1	orrnes	r6, yl, yh, lsl #1	beq	LSYM(Ldv_s)	@ Shift exponents right one bit to make room for overflow bit.	@ If either of them is 0, scale denormalized arguments off line.	@ Then substract divisor exponent from dividend''s.	movs	r4, r4, lsr #1	teqne	r5, #0	beq	LSYM(Ldv_d)LSYM(Ldv_x):	sub	r4, r4, r5, asr #1	@ Preserve final sign into lr.	eor	lr, xh, yh	@ Convert mantissa to unsigned integer.	@ Dividend -> r5-r6, divisor -> yh-yl.	mov	r5, #0x10000000	mov	yh, yh, lsl #12	orr	yh, r5, yh, lsr #4	orr	yh, yh, yl, lsr #24	movs	yl, yl, lsl #8	mov	xh, xh, lsl #12	teqeq	yh, r5	beq	LSYM(Ldv_1)	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.	cmp	r5, yh	cmpeq	r6, yl	bcs	1f	sub	r4, r4, #(1 << 19)	movs	yh, yh, lsr #1	mov	yl, yl, rrx1:	@ Apply exponent bias, check range for over/underflow.	add	r4, r4, #0x1f000000	add	r4, r4, #0x00f80000	cmn	r4, #(53 << 19)	ble	LSYM(Ldv_z)	cmp	r4, ip, lsr #1	bge	LSYM(Lml_o)	@ 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 if denormalized result is needed.	cmp	r4, #0	ble	LSYM(Ldv_u)	@ Apply proper rounding.	subs	ip, r5, yh	subeqs	ip, r6, yl	adcs	xl, xl, #0	adc	xh, xh, #0	teq	ip, #0	biceq	xl, xl, #1	@ Add exponent to result.	bic	xh, xh, #0x00100000	orr	xh, xh, r4, lsl #1	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	add	r4, r4, #0x1f000000	add	r4, r4, #0x00f80000	cmp	r4, ip, lsr #1	bge	LSYM(Lml_o)	cmp	r4, #0	orrgt	xh, xh, r4, lsl #1	RETLDM	"r4, r5, r6" gt	cmn	r4, #(53 << 19)	ble	LSYM(Ldv_z)	orr	xh, xh, #0x00100000	mov	lr, #0	b	LSYM(Lml_r)	@ Result must be denormalized: put remainder in lr for	@ rounding considerations.LSYM(Ldv_u):	orr	lr, r5, r6	b	LSYM(Lml_r)	@ One or both arguments are denormalized.	@ Scale them leftwards and preserve sign bit.LSYM(Ldv_d):	mov	lr, #0	teq	r4, #0	bne	2f	and	r6, xh, #0x800000001:	movs	xl, xl, lsl #1	adc	xh, lr, xh, lsl #1	tst	xh, #0x00100000	subeq	r4, r4, #(1 << 19)	beq	1b	orr	xh, xh, r6	teq	r5, #0	bne	LSYM(Ldv_x)2:	and	r6, yh, #0x800000003:	movs	yl, yl, lsl #1	adc	yh, lr, yh, lsl #1	tst	yh, #0x00100000	subeq	r5, r5, #(1 << 20)	beq	3b	orr	yh, yh, r6	b	LSYM(Ldv_x)	@ One or both arguments is either INF, NAN or zero.LSYM(Ldv_s):	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	b	LSYM(Lml_i)		@ INF / <anything> -> INF1:	teq	r5, ip	bne	2f	orrs	r5, yl, yh, lsl #12	bne	LSYM(Lml_n)		@ <anything> / NAN -> NAN	b	LSYM(Lml_z)		@ <anything> / INF -> 02:	@ 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 divdf3#endif /* L_muldivdf3 */#ifdef L_cmpdf2ARM_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:	stmfd	sp!, {r4, r5, lr}	@ Trap any INF/NAN first.	mov	lr, #0x7f000000	orr	lr, lr, #0x00f00000	and	r4, xh, lr	and	r5, yh, lr	teq	r4, lr	teqne	r5, lr	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.	RETLDM	"r4, r5" eq	@ Check for sign difference.	teq	xh, yh	movmi	r0, xh, asr #31	orrmi	r0, r0, #1	RETLDM	"r4, r5" mi	@ Compare exponents.	cmp	r4, r5	@ Compare mantissa if exponents are equal.	moveq	xh, xh, lsl #12	cmpeq	xh, yh, lsl #12	cmpeq	xl, yl	movcs	r0, yh, asr #31	mvncc	r0, yh, asr #31	orr	r0, r0, #1	RETLDM	"r4, r5"	@ Look for a NAN.3:	teq	r4, lr	bne	4f	orrs	xl, xl, xh, lsl #12	bne	5f			@ x is NAN4:	teq	r5, lr	bne	2b	orrs	yl, yl, yh, lsl #12	beq	2b			@ y is not NAN5:	mov	r0, ip			@ return unordered code from ip	RETLDM	"r4, r5"	FUNC_END gedf2	FUNC_END gtdf2	FUNC_END ledf2	FUNC_END ltdf2	FUNC_END nedf2	FUNC_END eqdf2	FUNC_END cmpdf2#endif /* L_cmpdf2 */#ifdef L_unorddf2ARM_FUNC_START unorddf2	str	lr, [sp, #-4]!	mov	ip, #0x7f000000	orr	ip, ip, #0x00f00000	and	lr, xh, ip	teq	lr, ip	bne	1f	orrs	xl, xl, xh, lsl #12	bne	3f			@ x is NAN1:	and	lr, yh, ip	teq	lr, ip	bne	2f	orrs	yl, yl, yh, lsl #12	bne	3f			@ y is NAN2:	mov	r0, #0			@ arguments are ordered.	RETLDM3:	mov	r0, #1			@ arguments are unordered.	RETLDM	FUNC_END unorddf2#endif /* L_unorddf2 */#ifdef L_fixdfsiARM_FUNC_START fixdfsi	orrs	ip, xl, xh, lsl #1	beq	1f			@ value is 0.	mov	r3, r3, rrx		@ preserve C flag (the actual sign)	@ check exponent range.	mov	ip, #0x7f000000	orr	ip, ip, #0x00f00000	and	r2, xh, ip	teq	r2, ip	beq	2f			@ value is INF or NAN	bic	ip, ip, #0x40000000	cmp	r2, ip	bcc	1f			@ value is too small	add	ip, ip, #(31 << 20)	cmp	r2, ip	bcs	3f			@ value is too large	rsb	r2, r2, ip	mov	ip, xh, lsl #11	orr	ip, ip, #0x80000000	orr	ip, ip, xl, lsr #21	mov	r2, r2, lsr #20	tst	r3, #0x80000000		@ the sign bit	mov	r0, ip, lsr r2	rsbne	r0, r0, #0	RET1:	mov	r0, #0	RET2:	orrs	xl, xl, xh, lsl #12	bne	4f			@ r0 is NAN.3:	ands	r0, r3, #0x80000000	@ the sign bit	moveq	r0, #0x7fffffff		@ maximum signed positive si	RET4:	mov	r0, #0			@ How should we convert NAN?	RET	FUNC_END fixdfsi#endif /* L_fixdfsi */#ifdef L_fixunsdfsiARM_FUNC_START fixunsdfsi	orrs	ip, xl, xh, lsl #1	movcss	r0, #0			@ value is negative	RETc(eq)			@ or 0 (xl, xh overlap r0)	@ check exponent range.	mov	ip, #0x7f000000	orr	ip, ip, #0x00f00000	and	r2, xh, ip	teq	r2, ip	beq	2f			@ value is INF or NAN	bic	ip, ip, #0x40000000	cmp	r2, ip	bcc	1f			@ value is too small	add	ip, ip, #(31 << 20)	cmp	r2, ip	bhi	3f			@ value is too large	rsb	r2, r2, ip	mov	ip, xh, lsl #11	orr	ip, ip, #0x80000000	orr	ip, ip, xl, lsr #21	mov	r2, r2, lsr #20	mov	r0, ip, 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 fixunsdfsi#endif /* L_fixunsdfsi */#ifdef L_truncdfsf2ARM_FUNC_START truncdfsf2	orrs	r2, xl, xh, lsl #1	moveq	r0, r2, rrx	RETc(eq)			@ value is 0.0 or -0.0		@ check exponent range.	mov	ip, #0x7f000000	orr	ip, ip, #0x00f00000	and	r2, ip, xh	teq	r2, ip	beq	2f			@ value is INF or NAN	bic	xh, xh, ip	cmp	r2, #(0x380 << 20)	bls	4f			@ value is too small	@ shift and round mantissa1:	movs	r3, xl, lsr #29	adc	r3, r3, xh, lsl #3	@ if halfway between two numbers, round towards LSB = 0.	mov	xl, xl, lsl #3	teq	xl, #0x80000000	biceq	r3, r3, #1	@ rounding might have created an extra MSB.  If so adjust exponent.	tst	r3, #0x00800000	addne	r2, r2, #(1 << 20)	bicne	r3, r3, #0x00800000	@ check exponent for overflow	mov	ip, #(0x400 << 20)	orr	ip, ip, #(0x07f << 20)	cmp	r2, ip	bcs	3f			@ overflow	@ adjust exponent, merge with sign bit and mantissa.	movs	xh, xh, lsl #1	mov	r2, r2, lsl #4	orr	r0, r3, r2, rrx	eor	r0, r0, #0x40000000	RET2:	@ chech for NAN	orrs	xl, xl, xh, lsl #12	movne	r0, #0x7f000000	orrne	r0, r0, #0x00c00000	RETc(ne)			@ return NAN3:	@ return INF with sign	and	r0, xh, #0x80000000	orr	r0, r0, #0x7f000000	orr	r0, r0, #0x00800000	RET4:	@ check if denormalized value is possible	subs	r2, r2, #((0x380 - 24) << 20)	andle	r0, xh, #0x80000000	@ too small, return signed 0.	RETc(le)		@ denormalize value so we can resume with the code above afterwards.	orr	xh, xh, #0x00100000	mov	r2, r2, lsr #20	rsb	r2, r2, #25	cmp	r2, #20	bgt	6f	rsb	ip, r2, #32	mov	r3, xl, lsl ip	mov	xl, xl, lsr r2	orr	xl, xl, xh, lsl ip	movs	xh, xh, lsl #1	mov	xh, xh, lsr r2	mov	xh, xh, rrx5:	teq	r3, #0			@ fold r3 bits into the LSB	orrne	xl, xl, #1		@ for rounding considerations. 	mov	r2, #(0x380 << 20)	@ equivalent to the 0 float exponent	b	1b6:	rsb	r2, r2, #(12 + 20)	rsb	ip, r2, #32	mov	r3, xl, lsl r2	mov	xl, xl, lsr ip	orr	xl, xl, xh, lsl r2	and	xh, xh, #0x80000000	b	5b	FUNC_END truncdfsf2#endif /* L_truncdfsf2 */

⌨️ 快捷键说明

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