udivsi3_i4i-Os.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0
  2. *
  3. * Copyright (C) 2006 Free Software Foundation, Inc.
  4. */
  5. /* Moderately Space-optimized libgcc routines for the Renesas SH /
  6. STMicroelectronics ST40 CPUs.
  7. Contributed by J"orn Rennecke joern.rennecke@st.com. */
  8. /* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i
  9. sh4-200 run times:
  10. udiv small divisor: 55 cycles
  11. udiv large divisor: 52 cycles
  12. sdiv small divisor, positive result: 59 cycles
  13. sdiv large divisor, positive result: 56 cycles
  14. sdiv small divisor, negative result: 65 cycles (*)
  15. sdiv large divisor, negative result: 62 cycles (*)
  16. (*): r2 is restored in the rts delay slot and has a lingering latency
  17. of two more cycles. */
  18. .balign 4
  19. .global __udivsi3_i4i
  20. .global __udivsi3_i4
  21. .set __udivsi3_i4, __udivsi3_i4i
  22. .type __udivsi3_i4i, @function
  23. .type __sdivsi3_i4i, @function
  24. __udivsi3_i4i:
  25. sts pr,r1
  26. mov.l r4,@-r15
  27. extu.w r5,r0
  28. cmp/eq r5,r0
  29. swap.w r4,r0
  30. shlr16 r4
  31. bf/s large_divisor
  32. div0u
  33. mov.l r5,@-r15
  34. shll16 r5
  35. sdiv_small_divisor:
  36. div1 r5,r4
  37. bsr div6
  38. div1 r5,r4
  39. div1 r5,r4
  40. bsr div6
  41. div1 r5,r4
  42. xtrct r4,r0
  43. xtrct r0,r4
  44. bsr div7
  45. swap.w r4,r4
  46. div1 r5,r4
  47. bsr div7
  48. div1 r5,r4
  49. xtrct r4,r0
  50. mov.l @r15+,r5
  51. swap.w r0,r0
  52. mov.l @r15+,r4
  53. jmp @r1
  54. rotcl r0
  55. div7:
  56. div1 r5,r4
  57. div6:
  58. div1 r5,r4; div1 r5,r4; div1 r5,r4
  59. div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
  60. divx3:
  61. rotcl r0
  62. div1 r5,r4
  63. rotcl r0
  64. div1 r5,r4
  65. rotcl r0
  66. rts
  67. div1 r5,r4
  68. large_divisor:
  69. mov.l r5,@-r15
  70. sdiv_large_divisor:
  71. xor r4,r0
  72. .rept 4
  73. rotcl r0
  74. bsr divx3
  75. div1 r5,r4
  76. .endr
  77. mov.l @r15+,r5
  78. mov.l @r15+,r4
  79. jmp @r1
  80. rotcl r0
  81. .global __sdivsi3_i4i
  82. .global __sdivsi3_i4
  83. .global __sdivsi3
  84. .set __sdivsi3_i4, __sdivsi3_i4i
  85. .set __sdivsi3, __sdivsi3_i4i
  86. __sdivsi3_i4i:
  87. mov.l r4,@-r15
  88. cmp/pz r5
  89. mov.l r5,@-r15
  90. bt/s pos_divisor
  91. cmp/pz r4
  92. neg r5,r5
  93. extu.w r5,r0
  94. bt/s neg_result
  95. cmp/eq r5,r0
  96. neg r4,r4
  97. pos_result:
  98. swap.w r4,r0
  99. bra sdiv_check_divisor
  100. sts pr,r1
  101. pos_divisor:
  102. extu.w r5,r0
  103. bt/s pos_result
  104. cmp/eq r5,r0
  105. neg r4,r4
  106. neg_result:
  107. mova negate_result,r0
  108. ;
  109. mov r0,r1
  110. swap.w r4,r0
  111. lds r2,macl
  112. sts pr,r2
  113. sdiv_check_divisor:
  114. shlr16 r4
  115. bf/s sdiv_large_divisor
  116. div0u
  117. bra sdiv_small_divisor
  118. shll16 r5
  119. .balign 4
  120. negate_result:
  121. neg r0,r0
  122. jmp @r2
  123. sts macl,r2