blob: d5ad327f655dd2675be568b0c24acb68809448e4 [file] [log] [blame]
Alexey Brodkin93206d22015-02-03 13:58:20 +03001/*
2 * Copyright (C) 1989-2013 Free Software Foundation, Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include "libgcc2.h"
8
9DWtype
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
32DWtype
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
56DWtype
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
79unsigned long
80udivmodsi4(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
105long
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
129long
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
151long
152__udivsi3(long a, long b)
153{
154 return udivmodsi4(a, b, 0);
155}
156
157long
158__umodsi3(long a, long b)
159{
160 return udivmodsi4(a, b, 1);
161}