libgcc2.c 2.2 KB

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