📄 lib1funcs.asm
字号:
@ depth 4, accumulated bits -5 mov lr, lr, lsr #1 blt L.4.1010 @ remainder is positive subs r3, r3, lr sub r2, r2, #9 b 9f L.4.1010: @ remainder is negative adds r3, r3, lr sub r2, r2, #11 b 9f L.3.1012: @ remainder is negative adds r3, r3, lr @ depth 4, accumulated bits -7 mov lr, lr, lsr #1 blt L.4.1008 @ remainder is positive subs r3, r3, lr sub r2, r2, #13 b 9f L.4.1008: @ remainder is negative adds r3, r3, lr sub r2, r2, #15 b 9f 9:Lend_regular_divide: subs ip, ip, #1 bge Ldivloop cmp r3, #0 @ non-restoring fixup here (one instruction only!) sublt r2, r2, #1Lgot_result: mov r0, r2 ldmia sp!, {r4, r5, pc}Ldiv_zero: @ Divide by zero trap. If it returns, return 0 (about as @ wrong as possible, but that is what SunOS does...). bl ___div0 mov r0, #0 ldmia sp!, {r4, r5, pc}#endif /* L_udivsi3 */#ifdef L_divsi3ip .req r12sp .req r13lr .req r14pc .req r15.text .globl ___divsi3 .align 0___divsi3: stmdb sp!, {r4, r5, r6, lr} @ compute sign of result; if neither is negative, no problem eor r6, r1, r0 @ compute sign cmp r1, #0 rsbmi r1, r1, #0 beq Ldiv_zero mov lr, r1 movs r3, r0 rsbmi r3, r3, #0 @ make dividend nonnegative cmp r3, lr @ if r1 exceeds r0, done mov r2, #0 bcc Lgot_result @ (and algorithm fails otherwise) mov r4, #(1 << (32 - 4 - 1)) cmp r3, r4 mov ip, #0 bcc Lnot_really_big @ Here the dividend is >= 2^(31-N) or so. We must be careful here, @ as our usual N-at-a-shot divide step will cause overflow and havoc. @ The number of bits in the result here is N*ITER+SC, where SC <= N. @ Compute ITER in an unorthodox manner: know we need to shift V into @ the top decade: so do not even bother to compare to R. mov r5, #1 1: cmp lr, r4 bcs 3f mov lr, lr, lsl #4 add ip, ip, #1 b 1b @ Now compute r5. 2: adds lr, lr, lr add r5, r5, #1 bcc Lnot_too_big @ We get here if the r1 overflowed while shifting. @ This means that r3 has the high-order bit set. @ Restore lr and subtract from r3. mov r4, r4, lsl #4 mov lr, lr, lsr #1 add lr, r4, lr sub r5, r5, #1 b Ldo_single_div Lnot_too_big: 3: cmp lr, r3 bcc 2b@ beq Ldo_single_div /* NB: these are commented out in the V8-Sparc manual as well */ /* (I do not understand this) */ @ lr > r3: went too far: back up 1 step @ srl lr, 1, lr @ dec r5 @ do single-bit divide steps @ @ We have to be careful here. We know that r3 >= lr, so we can do the @ first divide step without thinking. BUT, the others are conditional, @ and are only done if r3 >= 0. Because both r3 and lr may have the high- @ order bit set in the first step, just falling into the regular @ division loop will mess up the first time around. @ So we unroll slightly... Ldo_single_div: subs r5, r5, #1 blt Lend_regular_divide sub r3, r3, lr mov r2, #1 b Lend_single_divloop Lsingle_divloop: cmp r3, #0 mov r2, r2, lsl #1 mov lr, lr, lsr #1 @ r3 >= 0 subpl r3, r3, lr addpl r2, r2, #1 @ r3 < 0 addmi r3, r3, lr submi r2, r2, #1 Lend_single_divloop: subs r5, r5, #1 bge Lsingle_divloop b Lend_regular_divide1: add ip, ip, #1Lnot_really_big: mov lr, lr, lsl #4 cmp lr, r3 bls 1b @ @ HOW CAN ip EVER BE -1 HERE ????? @ cmn ip, #1 beq Lgot_resultLdivloop: cmp r3, #0 @ set up for initial iteration mov r2, r2, lsl #4 @ depth 1, accumulated bits 0 mov lr, lr, lsr #1 blt L.1.1015 @ remainder is positive subs r3, r3, lr @ depth 2, accumulated bits 1 mov lr, lr, lsr #1 blt L.2.1016 @ remainder is positive subs r3, r3, lr @ depth 3, accumulated bits 3 mov lr, lr, lsr #1 blt L.3.1018 @ remainder is positive subs r3, r3, lr @ depth 4, accumulated bits 7 mov lr, lr, lsr #1 blt L.4.1022 @ remainder is positive subs r3, r3, lr add r2, r2, #15 b 9f L.4.1022: @ remainder is negative adds r3, r3, lr add r2, r2, #13 b 9f L.3.1018: @ remainder is negative adds r3, r3, lr @ depth 4, accumulated bits 5 mov lr, lr, lsr #1 blt L.4.1020 @ remainder is positive subs r3, r3, lr add r2, r2, #11 b 9f L.4.1020: @ remainder is negative adds r3, r3, lr add r2, r2, #9 b 9f L.2.1016: @ remainder is negative adds r3, r3, lr @ depth 3, accumulated bits 1 mov lr, lr, lsr #1 blt L.3.1016 @ remainder is positive subs r3, r3, lr @ depth 4, accumulated bits 3 mov lr, lr, lsr #1 blt L.4.1018 @ remainder is positive subs r3, r3, lr add r2, r2, #7 b 9f L.4.1018: @ remainder is negative adds r3, r3, lr add r2, r2, #5 b 9f L.3.1016: @ remainder is negative adds r3, r3, lr @ depth 4, accumulated bits 1 mov lr, lr, lsr #1 blt L.4.1016 @ remainder is positive subs r3, r3, lr add r2, r2, #3 b 9f L.4.1016: @ remainder is negative adds r3, r3, lr add r2, r2, #1 b 9f L.1.1015: @ remainder is negative adds r3, r3, lr @ depth 2, accumulated bits -1 mov lr, lr, lsr #1 blt L.2.1014 @ remainder is positive subs r3, r3, lr @ depth 3, accumulated bits -1 mov lr, lr, lsr #1 blt L.3.1014 @ remainder is positive subs r3, r3, lr @ depth 4, accumulated bits -1 mov lr, lr, lsr #1 blt L.4.1014 @ remainder is positive subs r3, r3, lr sub r2, r2, #1 b 9f L.4.1014: @ remainder is negative adds r3, r3, lr sub r2, r2, #3 b 9f L.3.1014: @ remainder is negative adds r3, r3, lr @ depth 4, accumulated bits -3 mov lr, lr, lsr #1 blt L.4.1012 @ remainder is positive subs r3, r3, lr sub r2, r2, #5 b 9f L.4.1012: @ remainder is negative adds r3, r3, lr sub r2, r2, #7 b 9f L.2.1014: @ remainder is negative adds r3, r3, lr @ depth 3, accumulated bits -3 mov lr, lr, lsr #1 blt L.3.1012 @ remainder is positive subs r3, r3, lr @ depth 4, accumulated bits -5 mov lr, lr, lsr #1 blt L.4.1010 @ remainder is positive subs r3, r3, lr sub r2, r2, #9 b 9f L.4.1010: @ remainder is negative adds r3, r3, lr sub r2, r2, #11 b 9f L.3.1012: @ remainder is negative adds r3, r3, lr @ depth 4, accumulated bits -7 mov lr, lr, lsr #1 blt L.4.1008 @ remainder is positive subs r3, r3, lr sub r2, r2, #13 b 9f L.4.1008: @ remainder is negative adds r3, r3, lr sub r2, r2, #15 b 9f 9:Lend_regular_divide: subs ip, ip, #1 bge Ldivloop cmp r3, #0 @ non-restoring fixup here (one instruction only!) sublt r2, r2, #1Lgot_result: @ check to see if answer should be < 0 cmp r6, #0 rsbmi r2, r2, #0 mov r0, r2 ldmia sp!, {r4, r5, r6, pc}Ldiv_zero: @ Divide by zero trap. If it returns, return 0 (about as @ wrong as possible, but that is what SunOS does...). bl ___div0 mov r0, #0 ldmia sp!, {r4, r5, r6, pc}#endif /* L_divsi3 */#ifdef L_umodsi3ip .req r12sp .req r13lr .req r14pc .req r15.text .globl ___umodsi3 .align 0___umodsi3: stmdb sp!, {r4, r5, lr} @ Ready to divide. Compute size of quotient; scale comparand. movs lr, r1 mov r3, r0 beq Ldiv_zero cmp r3, lr @ if r1 exceeds r0, done mov r2, #0 bcc Lgot_result @ (and algorithm fails otherwise) mov r4, #(1 << (32 - 4 - 1)) cmp r3, r4 mov ip, #0 bcc Lnot_really_big @ Here the dividend is >= 2^(31-N) or so. We must be careful here, @ as our usual N-at-a-shot divide step will cause overflow and havoc. @ The number of bits in the result here is N*ITER+SC, where SC <= N. @ Compute ITER in an unorthodox manner: know we need to shift V into @ the top decade: so do not even bother to compare to R. mov r5, #1 1: cmp lr, r4 bcs 3f mov lr, lr, lsl #4 add ip, ip, #1 b 1b @ Now compute r5. 2: adds lr, lr, lr add r5, r5, #1 bcc Lnot_too_big @ We get here if the r1 overflowed while shifting. @ This means that r3 has the high-order bit set. @ Restore lr and subtract from r3. mov r4, r4, lsl #4 mov lr, lr, lsr #1 add lr, r4, lr sub r5, r5, #1 b Ldo_single_div Lnot_too_big: 3: cmp lr, r3 bcc 2b@ beq Ldo_single_div /* NB: these are commented out in the V8-Sparc manual as well */ /* (I do not understand this) */ @ lr > r3: went too far: back up 1 step @ srl lr, 1, lr @ dec r5 @ do single-bit divide steps @ @ We have to be careful here. We know that r3 >= lr, so we can do the @ first divide step without thinking. BUT, the others are conditional, @ and are only done if r3 >= 0. Because both r3 and lr may have the high- @ order bit set in the first step, just falling into the regular @ division loop will mess up the first time around. @ So we unroll slightly... Ldo_single_div: subs r5, r5, #1 blt Lend_regular_divide sub r3, r3, lr mov r2, #1 b Lend_single_divloop Lsingle_divloop: cmp r3, #0 mov r2, r2, lsl #1 mov lr, lr, lsr #1 @ r3 >= 0 subpl r3, r3, lr addpl r2, r2, #1 @ r3 < 0 addmi r3, r3, lr submi r2, r2, #1 Lend_single_divloop: subs r5, r5, #1 bge Lsingle_divloop b Lend_regular_divide1: add ip, ip, #1Lnot_really_big: mov lr, lr, lsl #4 cmp lr, r3 bls 1b @ @ HOW CAN ip EVER BE -1 HERE ????? @ cmn ip, #1 beq Lgot_resultLdivloop: cmp r3, #0 @ set up for initial iteration mov r2, r2, lsl #4 @ depth 1, accumulated bits 0 mov lr, lr, lsr #1 blt L.1.1015 @ remainder is positive subs r3, r3, lr @ depth 2, accumulated bits 1 mov lr, lr, lsr #1 blt L.2.1016 @ remainder is positive subs r3, r3, lr @ depth 3, accumulated bits 3 mov lr, lr, lsr #1 blt L.3.1018 @ remainder is positive subs r3, r3, lr @ depth 4, accumulated bits 7 mov lr, lr, lsr #1 blt L.4.1022 @ remainder is positive subs r3, r3, lr add r2, r2, #15 b 9f L.4.1022: @ remainder is negative adds r3, r3, lr add r2, r2, #13 b 9f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -