_divsi3.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <linux/linkage.h>
  2. .macro ARM_DIV_BODY dividend, divisor, result, curbit
  3. #if __LINUX_ARM_ARCH__ >= 5
  4. clz \curbit, \divisor
  5. clz \result, \dividend
  6. sub \result, \curbit, \result
  7. mov \curbit, #1
  8. mov \divisor, \divisor, lsl \result
  9. mov \curbit, \curbit, lsl \result
  10. mov \result, #0
  11. #else
  12. @ Initially shift the divisor left 3 bits if possible,
  13. @ set curbit accordingly. This allows for curbit to be located
  14. @ at the left end of each 4 bit nibbles in the division loop
  15. @ to save one loop in most cases.
  16. tst \divisor, #0xe0000000
  17. moveq \divisor, \divisor, lsl #3
  18. moveq \curbit, #8
  19. movne \curbit, #1
  20. @ Unless the divisor is very big, shift it up in multiples of
  21. @ four bits, since this is the amount of unwinding in the main
  22. @ division loop. Continue shifting until the divisor is
  23. @ larger than the dividend.
  24. 1: cmp \divisor, #0x10000000
  25. cmplo \divisor, \dividend
  26. movlo \divisor, \divisor, lsl #4
  27. movlo \curbit, \curbit, lsl #4
  28. blo 1b
  29. @ For very big divisors, we must shift it a bit at a time, or
  30. @ we will be in danger of overflowing.
  31. 1: cmp \divisor, #0x80000000
  32. cmplo \divisor, \dividend
  33. movlo \divisor, \divisor, lsl #1
  34. movlo \curbit, \curbit, lsl #1
  35. blo 1b
  36. mov \result, #0
  37. #endif
  38. @ Division loop
  39. 1: cmp \dividend, \divisor
  40. subhs \dividend, \dividend, \divisor
  41. orrhs \result, \result, \curbit
  42. cmp \dividend, \divisor, lsr #1
  43. subhs \dividend, \dividend, \divisor, lsr #1
  44. orrhs \result, \result, \curbit, lsr #1
  45. cmp \dividend, \divisor, lsr #2
  46. subhs \dividend, \dividend, \divisor, lsr #2
  47. orrhs \result, \result, \curbit, lsr #2
  48. cmp \dividend, \divisor, lsr #3
  49. subhs \dividend, \dividend, \divisor, lsr #3
  50. orrhs \result, \result, \curbit, lsr #3
  51. cmp \dividend, #0 @ Early termination?
  52. movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
  53. movne \divisor, \divisor, lsr #4
  54. bne 1b
  55. .endm
  56. .macro ARM_DIV2_ORDER divisor, order
  57. #if __LINUX_ARM_ARCH__ >= 5
  58. clz \order, \divisor
  59. rsb \order, \order, #31
  60. #else
  61. cmp \divisor, #(1 << 16)
  62. movhs \divisor, \divisor, lsr #16
  63. movhs \order, #16
  64. movlo \order, #0
  65. cmp \divisor, #(1 << 8)
  66. movhs \divisor, \divisor, lsr #8
  67. addhs \order, \order, #8
  68. cmp \divisor, #(1 << 4)
  69. movhs \divisor, \divisor, lsr #4
  70. addhs \order, \order, #4
  71. cmp \divisor, #(1 << 2)
  72. addhi \order, \order, #3
  73. addls \order, \order, \divisor, lsr #1
  74. #endif
  75. .endm
  76. .align 5
  77. .globl __divsi3
  78. __divsi3:
  79. ENTRY(__aeabi_idiv)
  80. cmp r1, #0
  81. eor ip, r0, r1 @ save the sign of the result.
  82. beq Ldiv0
  83. rsbmi r1, r1, #0 @ loops below use unsigned.
  84. subs r2, r1, #1 @ division by 1 or -1 ?
  85. beq 10f
  86. movs r3, r0
  87. rsbmi r3, r0, #0 @ positive dividend value
  88. cmp r3, r1
  89. bls 11f
  90. tst r1, r2 @ divisor is power of 2 ?
  91. beq 12f
  92. ARM_DIV_BODY r3, r1, r0, r2
  93. cmp ip, #0
  94. rsbmi r0, r0, #0
  95. mov pc, lr
  96. 10: teq ip, r0 @ same sign ?
  97. rsbmi r0, r0, #0
  98. mov pc, lr
  99. 11: movlo r0, #0
  100. moveq r0, ip, asr #31
  101. orreq r0, r0, #1
  102. mov pc, lr
  103. 12: ARM_DIV2_ORDER r1, r2
  104. cmp ip, #0
  105. mov r0, r3, lsr r2
  106. rsbmi r0, r0, #0
  107. mov pc, lr
  108. Ldiv0:
  109. str lr, [sp, #-4]!
  110. bl __div0
  111. mov r0, #0 @ About as wrong as it could be.
  112. ldr pc, [sp], #4
  113. ENDPROC(__aeabi_idiv)