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