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  }