libgcc2.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (C) 1989-2013 Free Software Foundation, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include "libgcc2.h"
  7. DWtype
  8. __ashldi3(DWtype u, shift_count_type b)
  9. {
  10. if (b == 0)
  11. return u;
  12. const DWunion uu = {.ll = u};
  13. const shift_count_type bm = W_TYPE_SIZE - b;
  14. DWunion w;
  15. if (bm <= 0) {
  16. w.s.low = 0;
  17. w.s.high = (UWtype)uu.s.low << -bm;
  18. } else {
  19. const UWtype carries = (UWtype) uu.s.low >> bm;
  20. w.s.low = (UWtype)uu.s.low << b;
  21. w.s.high = ((UWtype)uu.s.high << b) | carries;
  22. }
  23. return w.ll;
  24. }
  25. DWtype
  26. __ashrdi3(DWtype u, shift_count_type b)
  27. {
  28. if (b == 0)
  29. return u;
  30. const DWunion uu = {.ll = u};
  31. const shift_count_type bm = W_TYPE_SIZE - b;
  32. DWunion w;
  33. if (bm <= 0) {
  34. /* w.s.high = 1..1 or 0..0 */
  35. w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
  36. w.s.low = uu.s.high >> -bm;
  37. } else {
  38. const UWtype carries = (UWtype) uu.s.high << bm;
  39. w.s.high = uu.s.high >> b;
  40. w.s.low = ((UWtype)uu.s.low >> b) | carries;
  41. }
  42. return w.ll;
  43. }
  44. DWtype
  45. __lshrdi3(DWtype u, shift_count_type b)
  46. {
  47. if (b == 0)
  48. return u;
  49. const DWunion uu = {.ll = u};
  50. const shift_count_type bm = W_TYPE_SIZE - b;
  51. DWunion w;
  52. if (bm <= 0) {
  53. w.s.high = 0;
  54. w.s.low = (UWtype)uu.s.high >> -bm;
  55. } else {
  56. const UWtype carries = (UWtype)uu.s.high << bm;
  57. w.s.high = (UWtype)uu.s.high >> b;
  58. w.s.low = ((UWtype)uu.s.low >> b) | carries;
  59. }
  60. return w.ll;
  61. }
  62. unsigned long
  63. udivmodsi4(unsigned long num, unsigned long den, int modwanted)
  64. {
  65. unsigned long bit = 1;
  66. unsigned long res = 0;
  67. while (den < num && bit && !(den & (1L<<31))) {
  68. den <<= 1;
  69. bit <<= 1;
  70. }
  71. while (bit) {
  72. if (num >= den) {
  73. num -= den;
  74. res |= bit;
  75. }
  76. bit >>= 1;
  77. den >>= 1;
  78. }
  79. if (modwanted)
  80. return num;
  81. return res;
  82. }
  83. long
  84. __divsi3(long a, long b)
  85. {
  86. int neg = 0;
  87. long res;
  88. if (a < 0) {
  89. a = -a;
  90. neg = !neg;
  91. }
  92. if (b < 0) {
  93. b = -b;
  94. neg = !neg;
  95. }
  96. res = udivmodsi4(a, b, 0);
  97. if (neg)
  98. res = -res;
  99. return res;
  100. }
  101. long
  102. __modsi3(long a, long b)
  103. {
  104. int neg = 0;
  105. long res;
  106. if (a < 0) {
  107. a = -a;
  108. neg = 1;
  109. }
  110. if (b < 0)
  111. b = -b;
  112. res = udivmodsi4(a, b, 1);
  113. if (neg)
  114. res = -res;
  115. return res;
  116. }
  117. long
  118. __udivsi3(long a, long b)
  119. {
  120. return udivmodsi4(a, b, 0);
  121. }
  122. long
  123. __umodsi3(long a, long b)
  124. {
  125. return udivmodsi4(a, b, 1);
  126. }