udivsi3.S 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <linux/linkage.h>
  2. /*
  3. * Unsigned divide operation.
  4. * Input : Divisor in Reg r5
  5. * Dividend in Reg r6
  6. * Output: Result in Reg r3
  7. */
  8. .text
  9. .globl __udivsi3
  10. .type __udivsi3, @function
  11. .ent __udivsi3
  12. __udivsi3:
  13. .frame r1, 0, r15
  14. addik r1, r1, -12
  15. swi r29, r1, 0
  16. swi r30, r1, 4
  17. swi r31, r1, 8
  18. beqi r6, div_by_zero /* div_by_zero /* division error */
  19. beqid r5, result_is_zero /* result is zero */
  20. addik r30, r0, 0 /* clear mod */
  21. addik r29, r0, 32 /* initialize the loop count */
  22. /* check if r6 and r5 are equal - if yes, return 1 */
  23. rsub r18, r5, r6
  24. beqid r18, return_here
  25. addik r3, r0, 1
  26. /* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
  27. xor r18, r5, r6
  28. bgeid r18, 16
  29. add r3, r0, r0 /* we would anyways clear r3 */
  30. blti r6, return_here /* r6[bit 31 = 1] hence is greater */
  31. bri checkr6
  32. rsub r18, r6, r5 /* microblazecmp */
  33. blti r18, return_here
  34. /* if r6 [bit 31] is set, then return result as 1 */
  35. checkr6:
  36. bgti r6, div0
  37. brid return_here
  38. addik r3, r0, 1
  39. /* first part try to find the first '1' in the r5 */
  40. div0:
  41. blti r5, div2
  42. div1:
  43. add r5, r5, r5 /* left shift logical r5 */
  44. bgtid r5, div1
  45. addik r29, r29, -1
  46. div2:
  47. /* left shift logical r5 get the '1' into the carry */
  48. add r5, r5, r5
  49. addc r30, r30, r30 /* move that bit into the mod register */
  50. rsub r31, r6, r30 /* try to subtract (r30 a r6) */
  51. blti r31, mod_too_small
  52. /* move the r31 to mod since the result was positive */
  53. or r30, r0, r31
  54. addik r3, r3, 1
  55. mod_too_small:
  56. addik r29, r29, -1
  57. beqi r29, loop_end
  58. add r3, r3, r3 /* shift in the '1' into div */
  59. bri div2 /* div2 */
  60. loop_end:
  61. bri return_here
  62. div_by_zero:
  63. result_is_zero:
  64. or r3, r0, r0 /* set result to 0 */
  65. return_here:
  66. /* restore values of csrs and that of r3 and the divisor and the dividend */
  67. lwi r29, r1, 0
  68. lwi r30, r1, 4
  69. lwi r31, r1, 8
  70. rtsd r15, 8
  71. addik r1, r1, 12
  72. .size __udivsi3, . - __udivsi3
  73. .end __udivsi3