github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/mparith2.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/mparith2.go 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package gc 8 9 import ( 10 "rsc.io/tmp/bootstrap/internal/gc/big" 11 "rsc.io/tmp/bootstrap/internal/obj" 12 "fmt" 13 ) 14 15 /// implements fix arithmetic 16 17 func mpsetovf(a *Mpint) { 18 a.Val.SetUint64(0) 19 a.Ovf = true 20 } 21 22 func mptestovf(a *Mpint, extra int) bool { 23 // We don't need to be precise here, any reasonable upper limit would do. 24 // For now, use existing limit so we pass all the tests unchanged. 25 if a.Val.BitLen()+extra > Mpprec { 26 mpsetovf(a) 27 } 28 return a.Ovf 29 } 30 31 func mpmovefixfix(a, b *Mpint) { 32 a.Val.Set(&b.Val) 33 } 34 35 func mpmovefltfix(a *Mpint, b *Mpflt) int { 36 if _, acc := b.Val.Int(&a.Val); acc == big.Exact { 37 return 0 38 } 39 40 const delta = 16 // a reasonably small number of bits > 0 41 var t big.Float 42 t.SetPrec(Mpprec - delta) 43 44 // try rounding down a little 45 t.SetMode(big.ToZero) 46 t.Set(&b.Val) 47 if _, acc := t.Int(&a.Val); acc == big.Exact { 48 return 0 49 } 50 51 // try rounding up a little 52 t.SetMode(big.AwayFromZero) 53 t.Set(&b.Val) 54 if _, acc := t.Int(&a.Val); acc == big.Exact { 55 return 0 56 } 57 58 return -1 59 } 60 61 func mpaddfixfix(a, b *Mpint, quiet int) { 62 if a.Ovf || b.Ovf { 63 if nsavederrors+nerrors == 0 { 64 Yyerror("ovf in mpaddfixfix") 65 } 66 mpsetovf(a) 67 return 68 } 69 70 a.Val.Add(&a.Val, &b.Val) 71 72 if mptestovf(a, 0) && quiet == 0 { 73 Yyerror("constant addition overflow") 74 } 75 } 76 77 func mpsubfixfix(a, b *Mpint) { 78 if a.Ovf || b.Ovf { 79 if nsavederrors+nerrors == 0 { 80 Yyerror("ovf in mpsubfixfix") 81 } 82 mpsetovf(a) 83 return 84 } 85 86 a.Val.Sub(&a.Val, &b.Val) 87 88 if mptestovf(a, 0) { 89 Yyerror("constant subtraction overflow") 90 } 91 } 92 93 func mpmulfixfix(a, b *Mpint) { 94 if a.Ovf || b.Ovf { 95 if nsavederrors+nerrors == 0 { 96 Yyerror("ovf in mpmulfixfix") 97 } 98 mpsetovf(a) 99 return 100 } 101 102 a.Val.Mul(&a.Val, &b.Val) 103 104 if mptestovf(a, 0) { 105 Yyerror("constant multiplication overflow") 106 } 107 } 108 109 func mpdivfixfix(a, b *Mpint) { 110 if a.Ovf || b.Ovf { 111 if nsavederrors+nerrors == 0 { 112 Yyerror("ovf in mpdivfixfix") 113 } 114 mpsetovf(a) 115 return 116 } 117 118 a.Val.Quo(&a.Val, &b.Val) 119 120 if mptestovf(a, 0) { 121 // can only happen for div-0 which should be checked elsewhere 122 Yyerror("constant division overflow") 123 } 124 } 125 126 func mpmodfixfix(a, b *Mpint) { 127 if a.Ovf || b.Ovf { 128 if nsavederrors+nerrors == 0 { 129 Yyerror("ovf in mpmodfixfix") 130 } 131 mpsetovf(a) 132 return 133 } 134 135 a.Val.Rem(&a.Val, &b.Val) 136 137 if mptestovf(a, 0) { 138 // should never happen 139 Yyerror("constant modulo overflow") 140 } 141 } 142 143 func mporfixfix(a, b *Mpint) { 144 if a.Ovf || b.Ovf { 145 if nsavederrors+nerrors == 0 { 146 Yyerror("ovf in mporfixfix") 147 } 148 mpsetovf(a) 149 return 150 } 151 152 a.Val.Or(&a.Val, &b.Val) 153 } 154 155 func mpandfixfix(a, b *Mpint) { 156 if a.Ovf || b.Ovf { 157 if nsavederrors+nerrors == 0 { 158 Yyerror("ovf in mpandfixfix") 159 } 160 mpsetovf(a) 161 return 162 } 163 164 a.Val.And(&a.Val, &b.Val) 165 } 166 167 func mpandnotfixfix(a, b *Mpint) { 168 if a.Ovf || b.Ovf { 169 if nsavederrors+nerrors == 0 { 170 Yyerror("ovf in mpandnotfixfix") 171 } 172 mpsetovf(a) 173 return 174 } 175 176 a.Val.AndNot(&a.Val, &b.Val) 177 } 178 179 func mpxorfixfix(a, b *Mpint) { 180 if a.Ovf || b.Ovf { 181 if nsavederrors+nerrors == 0 { 182 Yyerror("ovf in mpxorfixfix") 183 } 184 mpsetovf(a) 185 return 186 } 187 188 a.Val.Xor(&a.Val, &b.Val) 189 } 190 191 // shift left by s (or right by -s) 192 func Mpshiftfix(a *Mpint, s int) { 193 switch { 194 case s > 0: 195 if mptestovf(a, s) { 196 Yyerror("constant shift overflow") 197 return 198 } 199 a.Val.Lsh(&a.Val, uint(s)) 200 case s < 0: 201 a.Val.Rsh(&a.Val, uint(-s)) 202 } 203 } 204 205 func mplshfixfix(a, b *Mpint) { 206 if a.Ovf || b.Ovf { 207 if nsavederrors+nerrors == 0 { 208 Yyerror("ovf in mplshfixfix") 209 } 210 mpsetovf(a) 211 return 212 } 213 214 s := Mpgetfix(b) 215 if s < 0 || s >= Mpprec { 216 Yyerror("stupid shift: %d", s) 217 Mpmovecfix(a, 0) 218 return 219 } 220 221 Mpshiftfix(a, int(s)) 222 } 223 224 func mprshfixfix(a, b *Mpint) { 225 if a.Ovf || b.Ovf { 226 if nsavederrors+nerrors == 0 { 227 Yyerror("ovf in mprshfixfix") 228 } 229 mpsetovf(a) 230 return 231 } 232 233 s := Mpgetfix(b) 234 if s < 0 || s >= Mpprec { 235 Yyerror("stupid shift: %d", s) 236 if a.Val.Sign() < 0 { 237 Mpmovecfix(a, -1) 238 } else { 239 Mpmovecfix(a, 0) 240 } 241 return 242 } 243 244 Mpshiftfix(a, int(-s)) 245 } 246 247 func Mpcmpfixfix(a, b *Mpint) int { 248 return a.Val.Cmp(&b.Val) 249 } 250 251 func mpcmpfixc(b *Mpint, c int64) int { 252 return b.Val.Cmp(big.NewInt(c)) 253 } 254 255 func mpnegfix(a *Mpint) { 256 a.Val.Neg(&a.Val) 257 } 258 259 func Mpgetfix(a *Mpint) int64 { 260 if a.Ovf { 261 if nsavederrors+nerrors == 0 { 262 Yyerror("constant overflow") 263 } 264 return 0 265 } 266 267 return a.Val.Int64() 268 } 269 270 func Mpmovecfix(a *Mpint, c int64) { 271 a.Val.SetInt64(c) 272 } 273 274 func mpatofix(a *Mpint, as string) { 275 _, ok := a.Val.SetString(as, 0) 276 if !ok { 277 // required syntax is [+-][0[x]]d* 278 // At the moment we lose precise error cause; 279 // the old code distinguished between: 280 // - malformed hex constant 281 // - malformed octal constant 282 // - malformed decimal constant 283 // TODO(gri) use different conversion function 284 Yyerror("malformed integer constant: %s", as) 285 a.Val.SetUint64(0) 286 return 287 } 288 if mptestovf(a, 0) { 289 Yyerror("constant too large: %s", as) 290 } 291 } 292 293 func (x *Mpint) String() string { 294 return Bconv(x, 0) 295 } 296 297 func Bconv(xval *Mpint, flag int) string { 298 if flag&obj.FmtSharp != 0 { 299 return fmt.Sprintf("%#x", &xval.Val) 300 } 301 return xval.Val.String() 302 }