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