_udivsi3.S 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* # 1 "libgcc1.S" */
  2. @ libgcc1 routines for ARM cpu.
  3. @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
  4. dividend .req r0
  5. divisor .req r1
  6. result .req r2
  7. curbit .req r3
  8. /* ip .req r12 */
  9. /* sp .req r13 */
  10. /* lr .req r14 */
  11. /* pc .req r15 */
  12. .text
  13. .globl __udivsi3
  14. .type __udivsi3 ,function
  15. .align 0
  16. __udivsi3 :
  17. cmp divisor, #0
  18. beq Ldiv0
  19. mov curbit, #1
  20. mov result, #0
  21. cmp dividend, divisor
  22. bcc Lgot_result
  23. Loop1:
  24. @ Unless the divisor is very big, shift it up in multiples of
  25. @ four bits, since this is the amount of unwinding in the main
  26. @ division loop. Continue shifting until the divisor is
  27. @ larger than the dividend.
  28. cmp divisor, #0x10000000
  29. cmpcc divisor, dividend
  30. movcc divisor, divisor, lsl #4
  31. movcc curbit, curbit, lsl #4
  32. bcc Loop1
  33. Lbignum:
  34. @ For very big divisors, we must shift it a bit at a time, or
  35. @ we will be in danger of overflowing.
  36. cmp divisor, #0x80000000
  37. cmpcc divisor, dividend
  38. movcc divisor, divisor, lsl #1
  39. movcc curbit, curbit, lsl #1
  40. bcc Lbignum
  41. Loop3:
  42. @ Test for possible subtractions, and note which bits
  43. @ are done in the result. On the final pass, this may subtract
  44. @ too much from the dividend, but the result will be ok, since the
  45. @ "bit" will have been shifted out at the bottom.
  46. cmp dividend, divisor
  47. subcs dividend, dividend, divisor
  48. orrcs result, result, curbit
  49. cmp dividend, divisor, lsr #1
  50. subcs dividend, dividend, divisor, lsr #1
  51. orrcs result, result, curbit, lsr #1
  52. cmp dividend, divisor, lsr #2
  53. subcs dividend, dividend, divisor, lsr #2
  54. orrcs result, result, curbit, lsr #2
  55. cmp dividend, divisor, lsr #3
  56. subcs dividend, dividend, divisor, lsr #3
  57. orrcs result, result, curbit, lsr #3
  58. cmp dividend, #0 @ Early termination?
  59. movnes curbit, curbit, lsr #4 @ No, any more bits to do?
  60. movne divisor, divisor, lsr #4
  61. bne Loop3
  62. Lgot_result:
  63. mov r0, result
  64. mov pc, lr
  65. Ldiv0:
  66. str lr, [sp, #-4]!
  67. bl __div0 (PLT)
  68. mov r0, #0 @ about as wrong as it could be
  69. ldmia sp!, {pc}
  70. .size __udivsi3 , . - __udivsi3
  71. /* # 235 "libgcc1.S" */
  72. /* # 320 "libgcc1.S" */
  73. /* # 421 "libgcc1.S" */
  74. /* # 433 "libgcc1.S" */
  75. /* # 456 "libgcc1.S" */
  76. /* # 500 "libgcc1.S" */
  77. /* # 580 "libgcc1.S" */