...
Source file src/pkg/cmd/compile/internal/gc/mpint.go
1
2
3
4
5 package gc
6
7 import (
8 "fmt"
9 "math/big"
10 )
11
12
13
14
15 type Mpint struct {
16 Val big.Int
17 Ovf bool
18 Rune bool
19 }
20
21 func (a *Mpint) SetOverflow() {
22 a.Val.SetUint64(1)
23 a.Ovf = true
24 }
25
26 func (a *Mpint) checkOverflow(extra int) bool {
27
28
29 if a.Val.BitLen()+extra > Mpprec {
30 a.SetOverflow()
31 }
32 return a.Ovf
33 }
34
35 func (a *Mpint) Set(b *Mpint) {
36 a.Val.Set(&b.Val)
37 }
38
39 func (a *Mpint) SetFloat(b *Mpflt) bool {
40
41
42 if b.Val.MantExp(nil) > 2*Mpprec {
43 a.SetOverflow()
44 return false
45 }
46
47 if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
48 return true
49 }
50
51 const delta = 16
52 var t big.Float
53 t.SetPrec(Mpprec - delta)
54
55
56 t.SetMode(big.ToZero)
57 t.Set(&b.Val)
58 if _, acc := t.Int(&a.Val); acc == big.Exact {
59 return true
60 }
61
62
63 t.SetMode(big.AwayFromZero)
64 t.Set(&b.Val)
65 if _, acc := t.Int(&a.Val); acc == big.Exact {
66 return true
67 }
68
69 a.Ovf = false
70 return false
71 }
72
73 func (a *Mpint) Add(b *Mpint) {
74 if a.Ovf || b.Ovf {
75 if nsavederrors+nerrors == 0 {
76 Fatalf("ovf in Mpint Add")
77 }
78 a.SetOverflow()
79 return
80 }
81
82 a.Val.Add(&a.Val, &b.Val)
83
84 if a.checkOverflow(0) {
85 yyerror("constant addition overflow")
86 }
87 }
88
89 func (a *Mpint) Sub(b *Mpint) {
90 if a.Ovf || b.Ovf {
91 if nsavederrors+nerrors == 0 {
92 Fatalf("ovf in Mpint Sub")
93 }
94 a.SetOverflow()
95 return
96 }
97
98 a.Val.Sub(&a.Val, &b.Val)
99
100 if a.checkOverflow(0) {
101 yyerror("constant subtraction overflow")
102 }
103 }
104
105 func (a *Mpint) Mul(b *Mpint) {
106 if a.Ovf || b.Ovf {
107 if nsavederrors+nerrors == 0 {
108 Fatalf("ovf in Mpint Mul")
109 }
110 a.SetOverflow()
111 return
112 }
113
114 a.Val.Mul(&a.Val, &b.Val)
115
116 if a.checkOverflow(0) {
117 yyerror("constant multiplication overflow")
118 }
119 }
120
121 func (a *Mpint) Quo(b *Mpint) {
122 if a.Ovf || b.Ovf {
123 if nsavederrors+nerrors == 0 {
124 Fatalf("ovf in Mpint Quo")
125 }
126 a.SetOverflow()
127 return
128 }
129
130 a.Val.Quo(&a.Val, &b.Val)
131
132 if a.checkOverflow(0) {
133
134 yyerror("constant division overflow")
135 }
136 }
137
138 func (a *Mpint) Rem(b *Mpint) {
139 if a.Ovf || b.Ovf {
140 if nsavederrors+nerrors == 0 {
141 Fatalf("ovf in Mpint Rem")
142 }
143 a.SetOverflow()
144 return
145 }
146
147 a.Val.Rem(&a.Val, &b.Val)
148
149 if a.checkOverflow(0) {
150
151 yyerror("constant modulo overflow")
152 }
153 }
154
155 func (a *Mpint) Or(b *Mpint) {
156 if a.Ovf || b.Ovf {
157 if nsavederrors+nerrors == 0 {
158 Fatalf("ovf in Mpint Or")
159 }
160 a.SetOverflow()
161 return
162 }
163
164 a.Val.Or(&a.Val, &b.Val)
165 }
166
167 func (a *Mpint) And(b *Mpint) {
168 if a.Ovf || b.Ovf {
169 if nsavederrors+nerrors == 0 {
170 Fatalf("ovf in Mpint And")
171 }
172 a.SetOverflow()
173 return
174 }
175
176 a.Val.And(&a.Val, &b.Val)
177 }
178
179 func (a *Mpint) AndNot(b *Mpint) {
180 if a.Ovf || b.Ovf {
181 if nsavederrors+nerrors == 0 {
182 Fatalf("ovf in Mpint AndNot")
183 }
184 a.SetOverflow()
185 return
186 }
187
188 a.Val.AndNot(&a.Val, &b.Val)
189 }
190
191 func (a *Mpint) Xor(b *Mpint) {
192 if a.Ovf || b.Ovf {
193 if nsavederrors+nerrors == 0 {
194 Fatalf("ovf in Mpint Xor")
195 }
196 a.SetOverflow()
197 return
198 }
199
200 a.Val.Xor(&a.Val, &b.Val)
201 }
202
203 func (a *Mpint) Lsh(b *Mpint) {
204 if a.Ovf || b.Ovf {
205 if nsavederrors+nerrors == 0 {
206 Fatalf("ovf in Mpint Lsh")
207 }
208 a.SetOverflow()
209 return
210 }
211
212 s := b.Int64()
213 if s < 0 || s >= Mpprec {
214 msg := "shift count too large"
215 if s < 0 {
216 msg = "invalid negative shift count"
217 }
218 yyerror("%s: %d", msg, s)
219 a.SetInt64(0)
220 return
221 }
222
223 if a.checkOverflow(int(s)) {
224 yyerror("constant shift overflow")
225 return
226 }
227 a.Val.Lsh(&a.Val, uint(s))
228 }
229
230 func (a *Mpint) Rsh(b *Mpint) {
231 if a.Ovf || b.Ovf {
232 if nsavederrors+nerrors == 0 {
233 Fatalf("ovf in Mpint Rsh")
234 }
235 a.SetOverflow()
236 return
237 }
238
239 s := b.Int64()
240 if s < 0 {
241 yyerror("invalid negative shift count: %d", s)
242 if a.Val.Sign() < 0 {
243 a.SetInt64(-1)
244 } else {
245 a.SetInt64(0)
246 }
247 return
248 }
249
250 a.Val.Rsh(&a.Val, uint(s))
251 }
252
253 func (a *Mpint) Cmp(b *Mpint) int {
254 return a.Val.Cmp(&b.Val)
255 }
256
257 func (a *Mpint) CmpInt64(c int64) int {
258 if c == 0 {
259 return a.Val.Sign()
260 }
261 return a.Val.Cmp(big.NewInt(c))
262 }
263
264 func (a *Mpint) Neg() {
265 a.Val.Neg(&a.Val)
266 }
267
268 func (a *Mpint) Int64() int64 {
269 if a.Ovf {
270 if nsavederrors+nerrors == 0 {
271 Fatalf("constant overflow")
272 }
273 return 0
274 }
275
276 return a.Val.Int64()
277 }
278
279 func (a *Mpint) SetInt64(c int64) {
280 a.Val.SetInt64(c)
281 }
282
283 func (a *Mpint) SetString(as string) {
284 _, ok := a.Val.SetString(as, 0)
285 if !ok {
286
287
288
289
290 Fatalf("malformed integer constant: %s", as)
291 return
292 }
293 if a.checkOverflow(0) {
294 yyerror("constant too large: %s", as)
295 }
296 }
297
298 func (a *Mpint) GoString() string {
299 return a.Val.String()
300 }
301
302 func (a *Mpint) String() string {
303 return fmt.Sprintf("%#x", &a.Val)
304 }
305
View as plain text