divsi3.S 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===-- divsi3.S - 32-bit signed integer divide ---------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the __divsi3 (32-bit signed integer divide) function
  10. // for the ARM architecture as a wrapper around the unsigned routine.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "../assembly.h"
  14. #define ESTABLISH_FRAME \
  15. push {r4, r7, lr} ;\
  16. add r7, sp, #4
  17. #define CLEAR_FRAME_AND_RETURN \
  18. pop {r4, r7, pc}
  19. .syntax unified
  20. .text
  21. DEFINE_CODE_STATE
  22. .p2align 3
  23. // Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
  24. DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)
  25. @ int __divsi3(int divident, int divisor)
  26. @ Calculate and return the quotient of the (signed) division.
  27. DEFINE_COMPILERRT_FUNCTION(__divsi3)
  28. #if __ARM_ARCH_EXT_IDIV__
  29. tst r1,r1
  30. beq LOCAL_LABEL(divzero)
  31. sdiv r0, r0, r1
  32. bx lr
  33. LOCAL_LABEL(divzero):
  34. // Use movs for compatibility with v8-m.base.
  35. movs r0,#0
  36. bx lr
  37. #else
  38. ESTABLISH_FRAME
  39. // Set aside the sign of the quotient.
  40. # if defined(USE_THUMB_1)
  41. movs r4, r0
  42. eors r4, r1
  43. # else
  44. eor r4, r0, r1
  45. # endif
  46. // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
  47. # if defined(USE_THUMB_1)
  48. asrs r2, r0, #31
  49. asrs r3, r1, #31
  50. eors r0, r2
  51. eors r1, r3
  52. subs r0, r0, r2
  53. subs r1, r1, r3
  54. # else
  55. eor r2, r0, r0, asr #31
  56. eor r3, r1, r1, asr #31
  57. sub r0, r2, r0, asr #31
  58. sub r1, r3, r1, asr #31
  59. # endif
  60. // abs(a) / abs(b)
  61. bl SYMBOL_NAME(__udivsi3)
  62. // Apply sign of quotient to result and return.
  63. # if defined(USE_THUMB_1)
  64. asrs r4, #31
  65. eors r0, r4
  66. subs r0, r0, r4
  67. # else
  68. eor r0, r0, r4, asr #31
  69. sub r0, r0, r4, asr #31
  70. # endif
  71. CLEAR_FRAME_AND_RETURN
  72. #endif
  73. END_COMPILERRT_FUNCTION(__divsi3)
  74. NO_EXEC_STACK_DIRECTIVE