divmodsi4.S 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===//
  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 __divmodsi4 (32-bit signed integer divide and
  10. // modulus) function for the ARM architecture. A naive digit-by-digit
  11. // computation is employed for simplicity.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "../assembly.h"
  15. #define ESTABLISH_FRAME \
  16. push {r4-r7, lr} ;\
  17. add r7, sp, #12
  18. #define CLEAR_FRAME_AND_RETURN \
  19. pop {r4-r7, pc}
  20. .syntax unified
  21. .text
  22. DEFINE_CODE_STATE
  23. @ int __divmodsi4(int divident, int divisor, int *remainder)
  24. @ Calculate the quotient and remainder of the (signed) division. The return
  25. @ value is the quotient, the remainder is placed in the variable.
  26. .p2align 3
  27. DEFINE_COMPILERRT_FUNCTION(__divmodsi4)
  28. #if __ARM_ARCH_EXT_IDIV__
  29. tst r1, r1
  30. beq LOCAL_LABEL(divzero)
  31. mov r3, r0
  32. sdiv r0, r3, r1
  33. mls r1, r0, r1, r3
  34. str r1, [r2]
  35. bx lr
  36. LOCAL_LABEL(divzero):
  37. mov r0, #0
  38. bx lr
  39. #else
  40. ESTABLISH_FRAME
  41. // Set aside the sign of the quotient and modulus, and the address for the
  42. // modulus.
  43. eor r4, r0, r1
  44. mov r5, r0
  45. mov r6, r2
  46. // Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
  47. eor ip, r0, r0, asr #31
  48. eor lr, r1, r1, asr #31
  49. sub r0, ip, r0, asr #31
  50. sub r1, lr, r1, asr #31
  51. // Unsigned divmod:
  52. bl SYMBOL_NAME(__udivmodsi4)
  53. // Apply the sign of quotient and modulus
  54. ldr r1, [r6]
  55. eor r0, r0, r4, asr #31
  56. eor r1, r1, r5, asr #31
  57. sub r0, r0, r4, asr #31
  58. sub r1, r1, r5, asr #31
  59. str r1, [r6]
  60. CLEAR_FRAME_AND_RETURN
  61. #endif
  62. END_COMPILERRT_FUNCTION(__divmodsi4)
  63. NO_EXEC_STACK_DIRECTIVE