// Copyright 2015 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 rewritegeneric

import (
	"fmt"
	"math"
	"math/bits"
	"strings"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/reflectdata"
	"cmd/compile/internal/rttype"
	"cmd/compile/internal/ssa"
	"cmd/compile/internal/ssa/ssaop"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/objabi"
)

func addToSub(op ssaop.Op) ssaop.Op {
	switch op {
	case ssaop.OpAdd64:
		return ssaop.OpSub64
	case ssaop.OpAdd32:
		return ssaop.OpSub32
	case ssaop.OpAdd16:
		return ssaop.OpSub16
	case ssaop.OpAdd8:
		return ssaop.OpSub8
	default:
		panic(fmt.Sprintf("unexpected op %v", op))
	}
}

func bitsAdd64(x, y, carry int64) (r struct{ sum, carry int64 }) {
	s, c := bits.Add64(uint64(x), uint64(y), uint64(carry))
	r.sum, r.carry = int64(s), int64(c)
	return
}

func bitsMulU32(x, y int32) (r struct{ hi, lo int32 }) {
	hi, lo := bits.Mul32(uint32(x), uint32(y))
	r.hi, r.lo = int32(hi), int32(lo)
	return
}

func bitsMulU64(x, y int64) (r struct{ hi, lo int64 }) {
	hi, lo := bits.Mul64(uint64(x), uint64(y))
	r.hi, r.lo = int64(hi), int64(lo)
	return
}

func bitsDiv128u(hi, lo, y int64) (r struct{ quo, rem int64 }) {
	q, rem := bits.Div64(uint64(hi), uint64(lo), uint64(y))
	r.quo, r.rem = int64(q), int64(rem)
	return
}

// bool2int converts bool to int: true to 1, false to 0
func bool2int(x bool) int {
	var b int
	if x {
		b = 1
	}
	return b
}

// canLoadUnaligned reports if the architecture supports unaligned load operations.
func canLoadUnaligned(c *ssa.Config) bool {
	return c.Ctxt.Arch.Alignment == 1
}

// canRotate reports whether the architecture supports
// rotates of integer registers with the given number of bits.
func canRotate(c *ssa.Config, bits int64) bool {
	if bits > c.PtrSize*8 {
		// Don't rewrite to rotates bigger than the machine word.
		return false
	}
	switch c.Arch {
	case "386", "amd64", "arm64", "loong64", "riscv64":
		return true
	case "arm", "s390x", "ppc64", "ppc64le", "wasm":
		return bits >= 32
	default:
		return false
	}
}

func copyCompatibleType(t1, t2 *types.Type) bool {
	if t1.Size() != t2.Size() {
		return false
	}
	if t1.IsInteger() {
		return t2.IsInteger()
	}
	if ssa.IsPtr(t1) {
		return ssa.IsPtr(t2)
	}
	return t1.Compare(t2) == types.CMPeq
}

func devirtLECall(v *ssa.Value, sym *obj.LSym) *ssa.Value {
	v.Op = ssaop.OpStaticLECall
	auxcall := v.Aux.(*ssa.AuxCall)
	auxcall.Fn = sym
	// Remove first arg
	v.Args[0].Uses--
	copy(v.Args[0:], v.Args[1:])
	v.Args[len(v.Args)-1] = nil // aid GC
	v.Args = v.Args[:len(v.Args)-1]
	if f := v.Block.Func; f.Pass.Debug > 0 {
		f.Warnl(v.Pos, "de-virtualizing call")
	}
	return v
}

// hasSmallRotate reports whether the architecture has rotate instructions
// for sizes < 32-bit.  This is used to decide whether to promote some rotations.
func hasSmallRotate(c *ssa.Config) bool {
	switch c.Arch {
	case "amd64", "386":
		return true
	default:
		return false
	}
}

func invertibleBool(op ssaop.Op) bool {
	switch op {
	case ssaop.OpLess64, ssaop.OpLess32, ssaop.OpLess16, ssaop.OpLess8,
		ssaop.OpLeq64, ssaop.OpLeq32, ssaop.OpLeq16, ssaop.OpLeq8,
		ssaop.OpLess64U, ssaop.OpLess32U, ssaop.OpLess16U, ssaop.OpLess8U,
		ssaop.OpLeq64U, ssaop.OpLeq32U, ssaop.OpLeq16U, ssaop.OpLeq8U,
		ssaop.OpEq64, ssaop.OpEq32, ssaop.OpEq16, ssaop.OpEq8,
		ssaop.OpNeq64, ssaop.OpNeq32, ssaop.OpNeq16, ssaop.OpNeq8,
		ssaop.OpNot:
		return true
	default:
		return false
	}
}

func isDictArgSym(sym ssa.Sym) bool {
	return sym.(*ir.Name).Sym().Name == typecheck.LocalDictName
}

// isDirectAndComparableIface reports whether v represents an itab
// (a *runtime._itab) for a type whose value is stored directly
// in an interface (i.e., is pointer or pointer-like) and is comparable.
func isDirectAndComparableIface(v *ssa.Value) bool {
	return isDirectAndComparableIface1(v, 9)
}

// v is an itab
func isDirectAndComparableIface1(v *ssa.Value, depth int) bool {
	if depth == 0 {
		return false
	}
	switch v.Op {
	case ssaop.OpITab:
		return isDirectAndComparableIface2(v.Args[0], depth-1)
	case ssaop.OpAddr:
		lsym := v.Aux.(*obj.LSym)
		if ii := lsym.ItabInfo(); ii != nil {
			t := ii.Type.(*types.Type)
			return types.IsDirectIface(t) && types.IsComparable(t)
		}
	case ssaop.OpConstNil:
		// We can treat this as direct, because if the itab is
		// nil, the data field must be nil also.
		return true
	}
	return false
}

// v is an interface
func isDirectAndComparableIface2(v *ssa.Value, depth int) bool {
	if depth == 0 {
		return false
	}
	switch v.Op {
	case ssaop.OpIMake:
		return isDirectAndComparableIface1(v.Args[0], depth-1)
	case ssaop.OpPhi:
		for _, a := range v.Args {
			if !isDirectAndComparableIface2(a, depth-1) {
				return false
			}
		}
		return true
	}
	return false
}

// isDirectAndComparableType reports whether v represents a type
// (a *runtime._type) whose value is stored directly in an
// interface (i.e., is pointer or pointer-like) and is comparable.
func isDirectAndComparableType(v *ssa.Value) bool {
	return isDirectAndComparableType1(v)
}

// v is a type
func isDirectAndComparableType1(v *ssa.Value) bool {
	switch v.Op {
	case ssaop.OpITab:
		return isDirectAndComparableType2(v.Args[0])
	case ssaop.OpAddr:
		lsym := v.Aux.(*obj.LSym)
		if ti := lsym.TypeInfo(); ti != nil {
			t := ti.Type.(*types.Type)
			return types.IsDirectIface(t) && types.IsComparable(t)
		}
	}
	return false
}

// v is an empty interface
func isDirectAndComparableType2(v *ssa.Value) bool {
	switch v.Op {
	case ssaop.OpIMake:
		return isDirectAndComparableType1(v.Args[0])
	}
	return false
}

// isFixedLoad returns true if the load can be resolved to fixed address or constant,
// and can be rewritten by rewriteFixedLoad.
func isFixedLoad(v *ssa.Value, sym ssa.Sym, off int64) bool {
	lsym := sym.(*obj.LSym)
	if (v.Type.IsPtrShaped() || v.Type.IsUintptr()) && lsym.Type == objabi.SRODATA {
		for _, r := range lsym.R {
			if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off && r.Add == 0 {
				return true
			}
		}
		return false
	}

	if ti := lsym.TypeInfo(); ti != nil {
		// Type symbols do not contain information about their fields, unlike the cases above.
		// Hand-implement field accesses.
		// TODO: can this be replaced with reflectdata.writeType and just use the code above?

		t := ti.Type.(*types.Type)

		for _, f := range rttype.Type.Fields() {
			if f.Offset == off && copyCompatibleType(v.Type, f.Type) {
				switch f.Sym.Name {
				case "Size_", "PtrBytes", "Hash", "Kind_", "GCData", "TFlag":
					return true
				default:
					// fmt.Println("unknown field", f.Sym.Name)
					return false
				}
			}
		}

		if t.IsPtr() && off == rttype.PtrType.OffsetOf("Elem") {
			return true
		}

		return false
	}

	return false
}

func isInlinableMemclr(c *ssa.Config, sz int64) bool {
	if sz < 0 {
		return false
	}
	// TODO: expand this check to allow other architectures
	// see CL 454255 and issue 56997
	switch c.Arch {
	case "amd64", "arm64":
		return true
	case "ppc64le", "ppc64", "loong64":
		return sz < 512
	}
	return false
}

func isMalloc(aux ssa.Aux) bool {
	return ssa.IsNewObjectCall(aux) || ssa.IsSpecializedMalloc(aux)
}

// isNonNegative reports whether v is known to be greater or equal to zero.
// Note that this is pretty simplistic. The prove pass generates more detailed
// nonnegative information about values.
func isNonNegative(v *ssa.Value) bool {
	if !v.Type.IsInteger() {
		v.Fatalf("isNonNegative bad type: %v", v.Type)
	}
	// TODO: return true if !v.Type.IsSigned()
	// SSA isn't type-safe enough to do that now (issue 37753).
	// The checks below depend only on the pattern of bits.

	switch v.Op {
	case ssaop.OpConst64:
		return v.AuxInt >= 0

	case ssaop.OpConst32:
		return int32(v.AuxInt) >= 0

	case ssaop.OpConst16:
		return int16(v.AuxInt) >= 0

	case ssaop.OpConst8:
		return int8(v.AuxInt) >= 0

	case ssaop.OpStringLen, ssaop.OpSliceLen, ssaop.OpSliceCap,
		ssaop.OpZeroExt8to64, ssaop.OpZeroExt16to64, ssaop.OpZeroExt32to64,
		ssaop.OpZeroExt8to32, ssaop.OpZeroExt16to32, ssaop.OpZeroExt8to16,
		ssaop.OpCtz64, ssaop.OpCtz32, ssaop.OpCtz16, ssaop.OpCtz8,
		ssaop.OpCtz64NonZero, ssaop.OpCtz32NonZero, ssaop.OpCtz16NonZero, ssaop.OpCtz8NonZero,
		ssaop.OpBitLen64, ssaop.OpBitLen32, ssaop.OpBitLen16, ssaop.OpBitLen8:
		return true

	case ssaop.OpRsh64Ux64, ssaop.OpRsh32Ux64:
		by := v.Args[1]
		return by.Op == ssaop.OpConst64 && by.AuxInt > 0

	case ssaop.OpRsh64x64, ssaop.OpRsh32x64, ssaop.OpRsh8x64, ssaop.OpRsh16x64, ssaop.OpRsh32x32, ssaop.OpRsh64x32,
		ssaop.OpSignExt32to64, ssaop.OpSignExt16to64, ssaop.OpSignExt8to64, ssaop.OpSignExt16to32, ssaop.OpSignExt8to32:
		return isNonNegative(v.Args[0])

	case ssaop.OpAnd64, ssaop.OpAnd32, ssaop.OpAnd16, ssaop.OpAnd8:
		return isNonNegative(v.Args[0]) || isNonNegative(v.Args[1])

	case ssaop.OpMod64, ssaop.OpMod32, ssaop.OpMod16, ssaop.OpMod8,
		ssaop.OpDiv64, ssaop.OpDiv32, ssaop.OpDiv16, ssaop.OpDiv8,
		ssaop.OpOr64, ssaop.OpOr32, ssaop.OpOr16, ssaop.OpOr8,
		ssaop.OpXor64, ssaop.OpXor32, ssaop.OpXor16, ssaop.OpXor8:
		return isNonNegative(v.Args[0]) && isNonNegative(v.Args[1])

		// We could handle OpPhi here, but the improvements from doing
		// so are very minor, and it is neither simple nor cheap.
	}
	return false
}

func isStackPtr(v *ssa.Value) bool {
	for v.Op == ssaop.OpOffPtr || v.Op == ssaop.OpAddPtr {
		v = v.Args[0]
	}
	return v.Op == ssaop.OpSP || v.Op == ssaop.OpLocalAddr
}

// needRaceCleanup reports whether this call to racefuncenter/exit isn't needed.
func needRaceCleanup(sym *ssa.AuxCall, v *ssa.Value) bool {
	f := v.Block.Func
	if !f.Config.Race {
		return false
	}
	if !ssa.IsSameCall(sym, "runtime.racefuncenter") && !ssa.IsSameCall(sym, "runtime.racefuncexit") {
		return false
	}
	for _, b := range f.Blocks {
		for _, v := range b.Values {
			switch v.Op {
			case ssaop.OpStaticCall, ssaop.OpStaticLECall:
				// Check for racefuncenter will encounter racefuncexit and vice versa.
				// Allow calls to panic*
				s := v.Aux.(*ssa.AuxCall).Fn.String()
				switch s {
				case "runtime.racefuncenter", "runtime.racefuncexit",
					"runtime.panicdivide", "runtime.panicwrap",
					"runtime.panicshift":
					continue
				}
				// If we encountered any call, we need to keep racefunc*,
				// for accurate stacktraces.
				return false
			case ssaop.OpPanicBounds, ssaop.OpPanicExtend:
				// Note: these are panic generators that are ok (like the static calls above).
			case ssaop.OpClosureCall, ssaop.OpInterCall, ssaop.OpClosureLECall, ssaop.OpInterLECall:
				// We must keep the race functions if there are any other call types.
				return false
			}
		}
	}
	if ssa.IsSameCall(sym, "runtime.racefuncenter") {
		// TODO REGISTER ABI this needs to be cleaned up.
		// If we're removing racefuncenter, remove its argument as well.
		if v.Args[0].Op != ssaop.OpStore {
			if v.Op == ssaop.OpStaticLECall {
				// there is no store, yet.
				return true
			}
			return false
		}
		mem := v.Args[0].Args[2]
		v.Args[0].Reset(ssaop.OpCopy)
		v.Args[0].AddArg(mem)
	}
	return true
}

func nlz16(x int16) int { return bits.LeadingZeros16(uint16(x)) }

func nlz32(x int32) int { return bits.LeadingZeros32(uint32(x)) }

// nlzX returns the number of leading zeros.
func nlz64(x int64) int { return bits.LeadingZeros64(uint64(x)) }

func nlz8(x int8) int { return bits.LeadingZeros8(uint8(x)) }

func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }

func ntz32(x int32) int { return bits.TrailingZeros32(uint32(x)) }

func ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) }

// reciprocalExact32 reports whether 1/c is exactly representable.
func reciprocalExact32(c float32) bool {
	b := math.Float32bits(c)
	man := b & (1<<23 - 1)
	if man != 0 {
		return false // not a power of 2, denormal, or NaN
	}
	exp := b >> 23 & (1<<8 - 1)
	// exponent bias is 0x7f.  So taking the reciprocal of a number
	// changes the exponent to 0xfe-exp.
	switch exp {
	case 0:
		return false // ±0
	case 0xff:
		return false // ±inf
	case 0xfe:
		return false // exponent is not representable
	default:
		return true
	}
}

// reciprocalExact64 reports whether 1/c is exactly representable.
func reciprocalExact64(c float64) bool {
	b := math.Float64bits(c)
	man := b & (1<<52 - 1)
	if man != 0 {
		return false // not a power of 2, denormal, or NaN
	}
	exp := b >> 52 & (1<<11 - 1)
	// exponent bias is 0x3ff.  So taking the reciprocal of a number
	// changes the exponent to 0x7fe-exp.
	switch exp {
	case 0:
		return false // ±0
	case 0x7ff:
		return false // ±inf
	case 0x7fe:
		return false // exponent is not representable
	default:
		return true
	}
}

// registerizable reports whether t is a primitive type that fits in
// a register. It assumes float64 values will always fit into registers
// even if that isn't strictly true.
func registerizable(b *ssa.Block, typ *types.Type) bool {
	if typ.IsPtrShaped() || typ.IsFloat() || typ.IsBoolean() {
		return true
	}
	if typ.IsInteger() {
		return typ.Size() <= b.Func.Config.RegSize
	}
	return false
}

// resetCopy resets v to be a copy of arg.
// Always returns true.
func resetCopy(v *ssa.Value, arg *ssa.Value) bool {
	v.Reset(ssaop.OpCopy)
	v.AddArg(arg)
	return true
}

// rewriteCondSelectIntoMath reports whether x OP (y * constant) should be used instead of a CondSelect.
// x arbitrary, y in [0,1]
func rewriteCondSelectIntoMath(config *ssa.Config, op ssaop.Op, constant int64) bool {
	// at worst this becomes a left shift by a constant which has asymmetric latency (1:3 vs 2:2)
	// but performs better in accumulation chains.
	// Various arches do strictly superior for specific cases, but this is a good general default.
	// FIXME: optimize more constants in arches where this is possible.
	switch config.Arch {
	case "arm64":
		switch op {
		case ssaop.OpAdd64, ssaop.OpAdd32, ssaop.OpAdd16, ssaop.OpAdd8:
			if constant == 1 {
				return false // better done as CSINC
			}
			fallthrough
		default:
			// add sub or xor & and are implemented using inline LSL
			// the rest becomes the default LSL
			return ssa.IsPowerOfTwo(uint64(constant))
		}
	default:
		return ssa.IsPowerOfTwo(uint64(constant))
	}
}

// rewriteFixedLoad rewrites a load to a fixed address or constant, if isFixedLoad returns true.
func rewriteFixedLoad(v *ssa.Value, sym ssa.Sym, sb *ssa.Value, off int64) *ssa.Value {
	b := v.Block
	f := b.Func

	lsym := sym.(*obj.LSym)
	if (v.Type.IsPtrShaped() || v.Type.IsUintptr()) && lsym.Type == objabi.SRODATA {
		for _, r := range lsym.R {
			if (r.Type == objabi.R_ADDR || r.Type == objabi.R_WEAKADDR) && int64(r.Off) == off && r.Add == 0 {
				if strings.HasPrefix(r.Sym.Name, "type:") {
					// In case we're loading a type out of a dictionary, we need to record
					// that the containing function might put that type in an interface.
					// That information is currently recorded in relocations in the dictionary,
					// but if we perform this load at compile time then the dictionary
					// might be dead.
					reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.Fe.Func().Linksym())
				} else if strings.HasPrefix(r.Sym.Name, "go:itab") {
					// Same, but if we're using an itab we need to record that the
					// itab._type might be put in an interface.
					reflectdata.MarkTypeSymUsedInInterface(r.Sym, f.Fe.Func().Linksym())
				}
				v.Reset(ssaop.OpAddr)
				v.Aux = ssa.SymToAux(r.Sym)
				v.AddArg(sb)
				return v
			}
		}
		base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
	}

	if ti := lsym.TypeInfo(); ti != nil {
		// Type symbols do not contain information about their fields, unlike the cases above.
		// Hand-implement field accesses.
		// TODO: can this be replaced with reflectdata.writeType and just use the code above?

		t := ti.Type.(*types.Type)

		ptrSizedOpConst := ssaop.OpConst64
		if f.Config.PtrSize == 4 {
			ptrSizedOpConst = ssaop.OpConst32
		}

		for _, f := range rttype.Type.Fields() {
			if f.Offset == off && copyCompatibleType(v.Type, f.Type) {
				switch f.Sym.Name {
				case "Size_":
					v.Reset(ptrSizedOpConst)
					v.AuxInt = t.Size()
					return v
				case "PtrBytes":
					v.Reset(ptrSizedOpConst)
					v.AuxInt = types.PtrDataSize(t)
					return v
				case "Hash":
					v.Reset(ssaop.OpConst32)
					v.AuxInt = int64(int32(types.TypeHash(t)))
					return v
				case "TFlag":
					v.Reset(ssaop.OpConst8)
					v.AuxInt = int64(t.TFlag())
					return v
				case "Kind_":
					v.Reset(ssaop.OpConst8)
					v.AuxInt = int64(int8(reflectdata.ABIKindOfType(t)))
					return v
				case "GCData":
					gcdata, _ := reflectdata.GCSym(t, true)
					v.Reset(ssaop.OpAddr)
					v.Aux = ssa.SymToAux(gcdata)
					v.AddArg(sb)
					return v
				default:
					base.Fatalf("unknown field %s for fixedLoad of %s at offset %d", f.Sym.Name, lsym.Name, off)
				}
			}
		}

		if t.IsPtr() && off == rttype.PtrType.OffsetOf("Elem") {
			elemSym := reflectdata.TypeLinksym(t.Elem())
			reflectdata.MarkTypeSymUsedInInterface(elemSym, f.Fe.Func().Linksym())
			v.Reset(ssaop.OpAddr)
			v.Aux = ssa.SymToAux(elemSym)
			v.AddArg(sb)
			return v
		}

		base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
	}

	base.Fatalf("fixedLoad data not known for %s:%d", sym, off)
	return nil
}

func rewriteStructLoad(v *ssa.Value) *ssa.Value {
	b := v.Block
	ptr := v.Args[0]
	mem := v.Args[1]

	t := v.Type
	args := make([]*ssa.Value, t.NumFields())
	for i := range args {
		ft := t.FieldType(i)
		addr := b.NewValue1I(v.Pos, ssaop.OpOffPtr, ft.PtrTo(), t.FieldOff(i), ptr)
		args[i] = b.NewValue2(v.Pos, ssaop.OpLoad, ft, addr, mem)
	}

	v.Reset(ssaop.OpStructMake)
	v.AddArgs(args...)
	return v
}

// symIsROZero reports whether sym is a read-only global whose data contains all zeros.
func symIsROZero(sym ssa.Sym) bool {
	lsym := sym.(*obj.LSym)
	if lsym.Type != objabi.SRODATA || len(lsym.R) != 0 {
		return false
	}
	for _, b := range lsym.P {
		if b != 0 {
			return false
		}
	}
	return true
}

// uaddOvf reports whether unsigned a+b would overflow.
func uaddOvf(a, b int64) bool {
	return uint64(a)+uint64(b) < uint64(a)
}

// warnRule generates compiler debug output with string s when
// v is not in autogenerated code, cond is true and the rule has fired.
func warnRule(cond bool, v *ssa.Value, s string) bool {
	if pos := v.Pos; pos.Line() > 1 && cond {
		v.Block.Func.Warnl(pos, s)
	}
	return true
}

func bitsSub64(x, y, borrow int64) (r struct{ diff, borrow int64 }) {
	d, b := bits.Sub64(uint64(x), uint64(y), uint64(borrow))
	r.diff, r.borrow = int64(d), int64(b)
	return
}

func modularMultiplicativeInverse(x uint64) (y uint64) {
	if x%2 != 1 {
		panic("even numbers in a power-of-two modulus do not have a multiplicative inverse")
	}
	// we start with 3 bits of precision because each odd number is its own multiplicative inverse mod 8
	y = x // 3 bits

	// now use the Newton-Raphson method to double the number of correct bits in each iteration.
	y *= 2 - x*y // 6 bits
	y *= 2 - x*y // 12 bits
	y *= 2 - x*y // 24 bits
	y *= 2 - x*y // 48 bits
	y *= 2 - x*y // 96 bits; good enough
	return
}
