// Do not edit. Bootstrap copy of /tmp/go/src/cmd/compile/internal/gc/mparith2.go

//line /tmp/go/src/cmd/compile/internal/gc/mparith2.go:1
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"bootstrap/compile/internal/big"
	"bootstrap/internal/obj"
	"fmt"
)

/// implements fix arithmetic

func mpsetovf(a *Mpint) {
	a.Val.SetUint64(1) // avoid spurious div-zero errors
	a.Ovf = true
}

func mptestovf(a *Mpint, extra int) bool {
	// We don't need to be precise here, any reasonable upper limit would do.
	// For now, use existing limit so we pass all the tests unchanged.
	if a.Val.BitLen()+extra > Mpprec {
		mpsetovf(a)
	}
	return a.Ovf
}

func mpmovefixfix(a, b *Mpint) {
	a.Val.Set(&b.Val)
}

func mpmovefltfix(a *Mpint, b *Mpflt) int {
	if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
		return 0
	}

	const delta = 16 // a reasonably small number of bits > 0
	var t big.Float
	t.SetPrec(Mpprec - delta)

	// try rounding down a little
	t.SetMode(big.ToZero)
	t.Set(&b.Val)
	if _, acc := t.Int(&a.Val); acc == big.Exact {
		return 0
	}

	// try rounding up a little
	t.SetMode(big.AwayFromZero)
	t.Set(&b.Val)
	if _, acc := t.Int(&a.Val); acc == big.Exact {
		return 0
	}

	return -1
}

func mpaddfixfix(a, b *Mpint, quiet int) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpaddfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Add(&a.Val, &b.Val)

	if mptestovf(a, 0) && quiet == 0 {
		Yyerror("constant addition overflow")
	}
}

func mpsubfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpsubfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Sub(&a.Val, &b.Val)

	if mptestovf(a, 0) {
		Yyerror("constant subtraction overflow")
	}
}

func mpmulfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpmulfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Mul(&a.Val, &b.Val)

	if mptestovf(a, 0) {
		Yyerror("constant multiplication overflow")
	}
}

func mpdivfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpdivfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Quo(&a.Val, &b.Val)

	if mptestovf(a, 0) {
		// can only happen for div-0 which should be checked elsewhere
		Yyerror("constant division overflow")
	}
}

func mpmodfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpmodfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Rem(&a.Val, &b.Val)

	if mptestovf(a, 0) {
		// should never happen
		Yyerror("constant modulo overflow")
	}
}

func mporfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mporfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Or(&a.Val, &b.Val)
}

func mpandfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpandfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.And(&a.Val, &b.Val)
}

func mpandnotfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpandnotfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.AndNot(&a.Val, &b.Val)
}

func mpxorfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mpxorfixfix")
		}
		mpsetovf(a)
		return
	}

	a.Val.Xor(&a.Val, &b.Val)
}

// shift left by s (or right by -s)
func Mpshiftfix(a *Mpint, s int) {
	switch {
	case s > 0:
		if mptestovf(a, s) {
			Yyerror("constant shift overflow")
			return
		}
		a.Val.Lsh(&a.Val, uint(s))
	case s < 0:
		a.Val.Rsh(&a.Val, uint(-s))
	}
}

func mplshfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mplshfixfix")
		}
		mpsetovf(a)
		return
	}

	s := Mpgetfix(b)
	if s < 0 || s >= Mpprec {
		Yyerror("stupid shift: %d", s)
		Mpmovecfix(a, 0)
		return
	}

	Mpshiftfix(a, int(s))
}

func mprshfixfix(a, b *Mpint) {
	if a.Ovf || b.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("ovf in mprshfixfix")
		}
		mpsetovf(a)
		return
	}

	s := Mpgetfix(b)
	if s < 0 || s >= Mpprec {
		Yyerror("stupid shift: %d", s)
		if a.Val.Sign() < 0 {
			Mpmovecfix(a, -1)
		} else {
			Mpmovecfix(a, 0)
		}
		return
	}

	Mpshiftfix(a, int(-s))
}

func Mpcmpfixfix(a, b *Mpint) int {
	return a.Val.Cmp(&b.Val)
}

func mpcmpfixc(b *Mpint, c int64) int {
	return b.Val.Cmp(big.NewInt(c))
}

func mpnegfix(a *Mpint) {
	a.Val.Neg(&a.Val)
}

func Mpgetfix(a *Mpint) int64 {
	if a.Ovf {
		if nsavederrors+nerrors == 0 {
			Yyerror("constant overflow")
		}
		return 0
	}

	return a.Val.Int64()
}

func Mpmovecfix(a *Mpint, c int64) {
	a.Val.SetInt64(c)
}

func mpatofix(a *Mpint, as string) {
	_, ok := a.Val.SetString(as, 0)
	if !ok {
		// required syntax is [+-][0[x]]d*
		// At the moment we lose precise error cause;
		// the old code distinguished between:
		// - malformed hex constant
		// - malformed octal constant
		// - malformed decimal constant
		// TODO(gri) use different conversion function
		Yyerror("malformed integer constant: %s", as)
		a.Val.SetUint64(0)
		return
	}
	if mptestovf(a, 0) {
		Yyerror("constant too large: %s", as)
	}
}

func (x *Mpint) String() string {
	return Bconv(x, 0)
}

func Bconv(xval *Mpint, flag int) string {
	if flag&obj.FmtSharp != 0 {
		return fmt.Sprintf("%#x", &xval.Val)
	}
	return xval.Val.String()
}
