?? ieee754-sf.s
字號:
rsbgts r3, r2, #255 orrgt r0, r0, r2, lsl #23 RETc(gt) @ Under/overflow: fix things up for the code below. orr r0, r0, #0x00800000 mov r3, #0 subs r2, r2, #1LSYM(Lml_u): @ Overflow? bgt LSYM(Lml_o) @ Check if denormalized result is possible, otherwise return signed 0. cmn r2, #(24 + 1) bicle r0, r0, #0x7fffffff RETc(le) @ Shift value right, round, etc. rsb r2, r2, #0 movs r1, r0, lsl #1 mov r1, r1, lsr r2 rsb r2, r2, #32 mov ip, r0, lsl r2 movs r0, r1, rrx adc r0, r0, #0 orrs r3, r3, ip, lsl #1 biceq r0, r0, ip, lsr #31 RET @ One or both arguments are denormalized. @ Scale them leftwards and preserve sign bit.LSYM(Lml_d): teq r2, #0 and ip, r0, #0x800000001: moveq r0, r0, lsl #1 tsteq r0, #0x00800000 subeq r2, r2, #1 beq 1b orr r0, r0, ip teq r3, #0 and ip, r1, #0x800000002: moveq r1, r1, lsl #1 tsteq r1, #0x00800000 subeq r3, r3, #1 beq 2b orr r1, r1, ip b LSYM(Lml_x)LSYM(Lml_s): @ Isolate the INF and NAN cases away and r3, ip, r1, lsr #23 teq r2, ip teqne r3, ip beq 1f @ Here, one or more arguments are either denormalized or zero. bics ip, r0, #0x80000000 bicnes ip, r1, #0x80000000 bne LSYM(Lml_d) @ Result is 0, but determine sign anyway.LSYM(Lml_z): eor r0, r0, r1 bic r0, r0, #0x7fffffff RET1: @ One or both args are INF or NAN. teq r0, #0x0 teqne r0, #0x80000000 moveq r0, r1 teqne r1, #0x0 teqne r1, #0x80000000 beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN teq r2, ip bne 1f movs r2, r0, lsl #9 bne LSYM(Lml_n) @ NAN * <anything> -> NAN1: teq r3, ip bne LSYM(Lml_i) movs r3, r1, lsl #9 movne r0, r1 bne LSYM(Lml_n) @ <anything> * NAN -> NAN @ Result is INF, but we need to determine its sign.LSYM(Lml_i): eor r0, r0, r1 @ Overflow: return INF (sign already in r0).LSYM(Lml_o): and r0, r0, #0x80000000 orr r0, r0, #0x7f000000 orr r0, r0, #0x00800000 RET @ Return a quiet NAN.LSYM(Lml_n): orr r0, r0, #0x7f000000 orr r0, r0, #0x00c00000 RET FUNC_END aeabi_fmul FUNC_END mulsf3ARM_FUNC_START divsf3ARM_FUNC_ALIAS aeabi_fdiv divsf3 @ Mask out exponents, trap any zero/denormal/INF/NAN. mov ip, #0xff ands r2, ip, r0, lsr #23 andnes r3, ip, r1, lsr #23 teqne r2, ip teqne r3, ip beq LSYM(Ldv_s)LSYM(Ldv_x): @ Substract divisor exponent from dividend''s sub r2, r2, r3 @ Preserve final sign into ip. eor ip, r0, r1 @ Convert mantissa to unsigned integer. @ Dividend -> r3, divisor -> r1. movs r1, r1, lsl #9 mov r0, r0, lsl #9 beq LSYM(Ldv_1) mov r3, #0x10000000 orr r1, r3, r1, lsr #4 orr r3, r3, r0, lsr #4 @ Initialize r0 (result) with final sign bit. and r0, ip, #0x80000000 @ Ensure result will land to known bit position. @ Apply exponent bias accordingly. cmp r3, r1 movcc r3, r3, lsl #1 adc r2, r2, #(127 - 2) @ The actual division loop. mov ip, #0x008000001: cmp r3, r1 subcs r3, r3, r1 orrcs r0, r0, ip cmp r3, r1, lsr #1 subcs r3, r3, r1, lsr #1 orrcs r0, r0, ip, lsr #1 cmp r3, r1, lsr #2 subcs r3, r3, r1, lsr #2 orrcs r0, r0, ip, lsr #2 cmp r3, r1, lsr #3 subcs r3, r3, r1, lsr #3 orrcs r0, r0, ip, lsr #3 movs r3, r3, lsl #4 movnes ip, ip, lsr #4 bne 1b @ Check exponent for under/overflow. cmp r2, #(254 - 1) bhi LSYM(Lml_u) @ Round the result, merge final exponent. cmp r3, r1 adc r0, r0, r2, lsl #23 biceq r0, r0, #1 RET @ Division by 0x1p*: let''s shortcut a lot of code.LSYM(Ldv_1): and ip, ip, #0x80000000 orr r0, ip, r0, lsr #9 adds r2, r2, #127 rsbgts r3, r2, #255 orrgt r0, r0, r2, lsl #23 RETc(gt) orr r0, r0, #0x00800000 mov r3, #0 subs r2, r2, #1 b LSYM(Lml_u) @ One or both arguments are denormalized. @ Scale them leftwards and preserve sign bit.LSYM(Ldv_d): teq r2, #0 and ip, r0, #0x800000001: moveq r0, r0, lsl #1 tsteq r0, #0x00800000 subeq r2, r2, #1 beq 1b orr r0, r0, ip teq r3, #0 and ip, r1, #0x800000002: moveq r1, r1, lsl #1 tsteq r1, #0x00800000 subeq r3, r3, #1 beq 2b orr r1, r1, ip b LSYM(Ldv_x) @ One or both arguments are either INF, NAN, zero or denormalized.LSYM(Ldv_s): and r3, ip, r1, lsr #23 teq r2, ip bne 1f movs r2, r0, lsl #9 bne LSYM(Lml_n) @ NAN / <anything> -> NAN teq r3, ip bne LSYM(Lml_i) @ INF / <anything> -> INF mov r0, r1 b LSYM(Lml_n) @ INF / (INF or NAN) -> NAN1: teq r3, ip bne 2f movs r3, r1, lsl #9 beq LSYM(Lml_z) @ <anything> / INF -> 0 mov r0, r1 b LSYM(Lml_n) @ <anything> / NAN -> NAN2: @ If both are non-zero, we need to normalize and resume above. bics ip, r0, #0x80000000 bicnes ip, r1, #0x80000000 bne LSYM(Ldv_d) @ One or both arguments are zero. bics r2, r0, #0x80000000 bne LSYM(Lml_i) @ <non_zero> / 0 -> INF bics r3, r1, #0x80000000 bne LSYM(Lml_z) @ 0 / <non_zero> -> 0 b LSYM(Lml_n) @ 0 / 0 -> NAN FUNC_END aeabi_fdiv FUNC_END divsf3#endif /* L_muldivsf3 */#ifdef L_cmpsf2 @ The return value in r0 is @ @ 0 if the operands are equal @ 1 if the first operand is greater than the second, or @ the operands are unordered and the operation is @ CMP, LT, LE, NE, or EQ. @ -1 if the first operand is less than the second, or @ the operands are unordered and the operation is GT @ or GE. @ @ The Z flag will be set iff the operands are equal. @ @ The following registers are clobbered by this function: @ ip, r0, r1, r2, r3ARM_FUNC_START gtsf2ARM_FUNC_ALIAS gesf2 gtsf2 mov ip, #-1 b 1fARM_FUNC_START ltsf2ARM_FUNC_ALIAS lesf2 ltsf2 mov ip, #1 b 1fARM_FUNC_START cmpsf2ARM_FUNC_ALIAS nesf2 cmpsf2ARM_FUNC_ALIAS eqsf2 cmpsf2 mov ip, #1 @ how should we specify unordered here?1: str ip, [sp, #-4] @ Trap any INF/NAN first. mov r2, r0, lsl #1 mov r3, r1, lsl #1 mvns ip, r2, asr #24 mvnnes ip, r3, asr #24 beq 3f @ Compare values. @ Note that 0.0 is equal to -0.0.2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag teqne r0, r1 @ if not 0 compare sign subpls r0, r2, r3 @ if same sign compare values, set r0 @ Result: movhi r0, r1, asr #31 mvnlo r0, r1, asr #31 orrne r0, r0, #1 RET @ Look for a NAN. 3: mvns ip, r2, asr #24 bne 4f movs ip, r0, lsl #9 bne 5f @ r0 is NAN4: mvns ip, r3, asr #24 bne 2b movs ip, r1, lsl #9 beq 2b @ r1 is not NAN5: ldr r0, [sp, #-4] @ return unordered code. RET FUNC_END gesf2 FUNC_END gtsf2 FUNC_END lesf2 FUNC_END ltsf2 FUNC_END nesf2 FUNC_END eqsf2 FUNC_END cmpsf2ARM_FUNC_START aeabi_cfrcmple mov ip, r0 mov r0, r1 mov r1, ip b 6fARM_FUNC_START aeabi_cfcmpeqARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq @ The status-returning routines are required to preserve all @ registers except ip, lr, and cpsr.6: stmfd sp!, {r0, r1, r2, r3, lr} ARM_CALL cmpsf2 @ 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, r1, r2, r3" FUNC_END aeabi_cfcmple FUNC_END aeabi_cfcmpeq FUNC_END aeabi_cfrcmpleARM_FUNC_START aeabi_fcmpeq str lr, [sp, #-4]! ARM_CALL aeabi_cfcmple moveq r0, #1 @ Equal to. movne r0, #0 @ Less than, greater than, or unordered. RETLDM FUNC_END aeabi_fcmpeqARM_FUNC_START aeabi_fcmplt str lr, [sp, #-4]! ARM_CALL aeabi_cfcmple movcc r0, #1 @ Less than. movcs r0, #0 @ Equal to, greater than, or unordered. RETLDM FUNC_END aeabi_fcmpltARM_FUNC_START aeabi_fcmple str lr, [sp, #-4]! ARM_CALL aeabi_cfcmple movls r0, #1 @ Less than or equal to. movhi r0, #0 @ Greater than or unordered. RETLDM FUNC_END aeabi_fcmpleARM_FUNC_START aeabi_fcmpge str lr, [sp, #-4]! ARM_CALL aeabi_cfrcmple 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_fcmpgeARM_FUNC_START aeabi_fcmpgt str lr, [sp, #-4]! ARM_CALL aeabi_cfrcmple 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_fcmpgt#endif /* L_cmpsf2 */#ifdef L_unordsf2ARM_FUNC_START unordsf2ARM_FUNC_ALIAS aeabi_fcmpun unordsf2 mov r2, r0, lsl #1 mov r3, r1, lsl #1 mvns ip, r2, asr #24 bne 1f movs ip, r0, lsl #9 bne 3f @ r0 is NAN1: mvns ip, r3, asr #24 bne 2f movs ip, r1, lsl #9 bne 3f @ r1 is NAN2: mov r0, #0 @ arguments are ordered. RET3: mov r0, #1 @ arguments are unordered. RET FUNC_END aeabi_fcmpun FUNC_END unordsf2#endif /* L_unordsf2 */#ifdef L_fixsfsiARM_FUNC_START fixsfsiARM_FUNC_ALIAS aeabi_f2iz fixsfsi @ check exponent range. mov r2, r0, lsl #1 cmp r2, #(127 << 24) bcc 1f @ value is too small mov r3, #(127 + 31) subs r2, r3, r2, lsr #24 bls 2f @ value is too large @ scale value mov r3, r0, lsl #8 orr r3, r3, #0x80000000 tst r0, #0x80000000 @ the sign bit mov r0, r3, lsr r2 rsbne r0, r0, #0 RET1: mov r0, #0 RET2: cmp r2, #(127 + 31 - 0xff) bne 3f movs r2, r0, lsl #9 bne 4f @ r0 is NAN.3: ands r0, r0, #0x80000000 @ the sign bit moveq r0, #0x7fffffff @ the maximum signed positive si RET4: mov r0, #0 @ What should we convert NAN to? RET FUNC_END aeabi_f2iz FUNC_END fixsfsi#endif /* L_fixsfsi */#ifdef L_fixunssfsiARM_FUNC_START fixunssfsiARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi @ check exponent range. movs r2, r0, lsl #1 bcs 1f @ value is negative cmp r2, #(127 << 24) bcc 1f @ value is too small mov r3, #(127 + 31) subs r2, r3, r2, lsr #24 bmi 2f @ value is too large @ scale the value mov r3, r0, lsl #8 orr r3, r3, #0x80000000 mov r0, r3, lsr r2 RET1: mov r0, #0 RET2: cmp r2, #(127 + 31 - 0xff) bne 3f movs r2, r0, lsl #9 bne 4f @ r0 is NAN.3: mov r0, #0xffffffff @ maximum unsigned si RET4: mov r0, #0 @ What should we convert NAN to? RET FUNC_END aeabi_f2uiz FUNC_END fixunssfsi#endif /* L_fixunssfsi */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -