_udivsi3.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. .globl __aeabi_uidiv
  16. .type __aeabi_uidiv ,function
  17. .align 0
  18. __udivsi3:
  19. __aeabi_uidiv:
  20. cmp divisor, #0
  21. beq Ldiv0
  22. mov curbit, #1
  23. mov result, #0
  24. cmp dividend, divisor
  25. bcc Lgot_result
  26. Loop1:
  27. @ Unless the divisor is very big, shift it up in multiples of
  28. @ four bits, since this is the amount of unwinding in the main
  29. @ division loop. Continue shifting until the divisor is
  30. @ larger than the dividend.
  31. cmp divisor, #0x10000000
  32. cmpcc divisor, dividend
  33. movcc divisor, divisor, lsl #4
  34. movcc curbit, curbit, lsl #4
  35. bcc Loop1
  36. Lbignum:
  37. @ For very big divisors, we must shift it a bit at a time, or
  38. @ we will be in danger of overflowing.
  39. cmp divisor, #0x80000000
  40. cmpcc divisor, dividend
  41. movcc divisor, divisor, lsl #1
  42. movcc curbit, curbit, lsl #1
  43. bcc Lbignum
  44. Loop3:
  45. @ Test for possible subtractions, and note which bits
  46. @ are done in the result. On the final pass, this may subtract
  47. @ too much from the dividend, but the result will be ok, since the
  48. @ "bit" will have been shifted out at the bottom.
  49. cmp dividend, divisor
  50. subcs dividend, dividend, divisor
  51. orrcs result, result, curbit
  52. cmp dividend, divisor, lsr #1
  53. subcs dividend, dividend, divisor, lsr #1
  54. orrcs result, result, curbit, lsr #1
  55. cmp dividend, divisor, lsr #2
  56. subcs dividend, dividend, divisor, lsr #2
  57. orrcs result, result, curbit, lsr #2
  58. cmp dividend, divisor, lsr #3
  59. subcs dividend, dividend, divisor, lsr #3
  60. orrcs result, result, curbit, lsr #3
  61. cmp dividend, #0 @ Early termination?
  62. movnes curbit, curbit, lsr #4 @ No, any more bits to do?
  63. movne divisor, divisor, lsr #4
  64. bne Loop3
  65. Lgot_result:
  66. mov r0, result
  67. mov pc, lr
  68. Ldiv0:
  69. str lr, [sp, #-4]!
  70. bl __div0 (PLT)
  71. mov r0, #0 @ about as wrong as it could be
  72. ldmia sp!, {pc}
  73. .size __udivsi3 , . - __udivsi3
  74. .globl __aeabi_uidivmod
  75. __aeabi_uidivmod:
  76. stmfd sp!, {r0, r1, ip, lr}
  77. bl __aeabi_uidiv
  78. ldmfd sp!, {r1, r2, ip, lr}
  79. mul r3, r0, r2
  80. sub r1, r1, r3
  81. mov pc, lr
  82. .globl __aeabi_idivmod
  83. __aeabi_idivmod:
  84. stmfd sp!, {r0, r1, ip, lr}
  85. bl __aeabi_idiv
  86. ldmfd sp!, {r1, r2, ip, lr}
  87. mul r3, r0, r2
  88. sub r1, r1, r3
  89. mov pc, lr