div_32.s 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. .text
  2. .align 4
  3. .code 32
  4. .global div_32
  5. .type div_32, %function
  6. div_32:
  7. STMFD sp!,{r4 - r5}
  8. MOV R2,R1
  9. MOV R1,R0
  10. @*check for divide by zero!
  11. CMP R2, #0
  12. BEQ divide_end
  13. MOV R0,#0 @*clear R0 to accumulate result
  14. MOV R3,#1 @*set bit 0 in R3, which will be
  15. @*shifted left then right
  16. start:
  17. CMP R2,R1
  18. MOVLS R2,R2,LSL#1
  19. MOVLS R3,R3,LSL#1
  20. BLS start
  21. @*shift R2 left until it is about to
  22. @*be bigger than R1
  23. @*shift R3 left in parallel in order
  24. @*to flag how far we have to go
  25. next:
  26. CMP R1,R2 @*carry set if R1>R2 (don't ask why)
  27. SUBCS R1,R1,R2 @*subtract R2 from R1 if this would
  28. @*give a positive answer
  29. ADDCS R0,R0,R3 @*and add the current bit in R3 to
  30. @*the accumulating answer in R0
  31. MOVS R3,R3,LSR#1 @*Shift R3 right into carry flag
  32. MOVCC R2,R2,LSR#1 @*and if bit 0 of R3 was zero, also
  33. @*shift R2 right
  34. BCC next @*If carry not clear, R3 has shifted
  35. @*back to where it started, and we
  36. @*can end
  37. divide_end:
  38. @*At the end of the routine, R1 holds the remainder,
  39. @*if any, R2 has returned to the value it held on entry to the routine,
  40. @*R0 holds the result and R3 holds zero.
  41. @*Both zero and carry flags are set
  42. LDMFD sp!,{r4 - r5}
  43. BX lr
  44. @ clz_divide:
  45. @ MOV r2,#0
  46. @ CMP r0,#0
  47. @ BLT .END
  48. @ CMP r0,r1
  49. @ BGT .END
  50. @ MOVWEQ r2,#0x7FFF
  51. @ BEQ .END
  52. @
  53. @ LSL r0,r0,#15
  54. @
  55. @ clz r3, r0 /* r3 ← CLZ(r0) Count leading zeroes of N */
  56. @ clz r2, r1 /* r2 ← CLZ(r1) Count leading zeroes of D */
  57. @ sub r3, r2, r3 /* r3 ← r2 - r3.
  58. @ This is the difference of zeroes
  59. @ between D and N.
  60. @ Note that N >= D implies CLZ(N) <= CLZ(D)*/
  61. @ add r3, r3, #1 /* Loop below needs an extra iteration count */
  62. @
  63. @ mov r2, #0 /* r2 ← 0 */
  64. @ b .Lloop_check4
  65. @ .Lloop4:
  66. @ cmp r0, r1, lsl r3 /* Compute r0 - (r1 << r3) and update cpsr */
  67. @ adc r2, r2, r2 /* r2 ← r2 + r2 + C.
  68. @ Note that if r0 >= (r1 << r3) then C=1, C=0 otherwise */
  69. @ subcs r0, r0, r1, lsl r3 /* r0 ← r0 - (r1 << r3) if C = 1 (this is, only if r0 >= (r1 << r3) ) */
  70. @ .Lloop_check4:
  71. @ subs r3, r3, #1 /* r3 ← r3 - 1 */
  72. @ bpl .Lloop4 /* if r3 >= 0 (N=0) then branch to .Lloop1 */
  73. @ .END:
  74. @ mov r0, r2
  75. @ bx lr