_udivsi3.S 2.4 KB

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