// Copyright 2016 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 (
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"fmt"
	"sort"
)

// AlgKind describes the kind of algorithms used for comparing and
// hashing a Type.
type AlgKind int

//go:generate stringer -type AlgKind -trimprefix A

const (
	// These values are known by runtime.
	ANOEQ AlgKind = iota
	AMEM0
	AMEM8
	AMEM16
	AMEM32
	AMEM64
	AMEM128
	ASTRING
	AINTER
	ANILINTER
	AFLOAT32
	AFLOAT64
	ACPLX64
	ACPLX128

	// Type can be compared/hashed as regular memory.
	AMEM AlgKind = 100

	// Type needs special comparison/hashing functions.
	ASPECIAL AlgKind = -1
)

// IsComparable reports whether t is a comparable type.
func IsComparable(t *types.Type) bool {
	a, _ := algtype1(t)
	return a != ANOEQ
}

// IsRegularMemory reports whether t can be compared/hashed as regular memory.
func IsRegularMemory(t *types.Type) bool {
	a, _ := algtype1(t)
	return a == AMEM
}

// IncomparableField returns an incomparable Field of struct Type t, if any.
func IncomparableField(t *types.Type) *types.Field {
	for _, f := range t.FieldSlice() {
		if !IsComparable(f.Type) {
			return f
		}
	}
	return nil
}

// EqCanPanic reports whether == on type t could panic (has an interface somewhere).
// t must be comparable.
func EqCanPanic(t *types.Type) bool {
	switch t.Etype {
	default:
		return false
	case TINTER:
		return true
	case TARRAY:
		return EqCanPanic(t.Elem())
	case TSTRUCT:
		for _, f := range t.FieldSlice() {
			if !f.Sym.IsBlank() && EqCanPanic(f.Type) {
				return true
			}
		}
		return false
	}
}

// algtype is like algtype1, except it returns the fixed-width AMEMxx variants
// instead of the general AMEM kind when possible.
func algtype(t *types.Type) AlgKind {
	a, _ := algtype1(t)
	if a == AMEM {
		switch t.Width {
		case 0:
			return AMEM0
		case 1:
			return AMEM8
		case 2:
			return AMEM16
		case 4:
			return AMEM32
		case 8:
			return AMEM64
		case 16:
			return AMEM128
		}
	}

	return a
}

// algtype1 returns the AlgKind used for comparing and hashing Type t.
// If it returns ANOEQ, it also returns the component type of t that
// makes it incomparable.
func algtype1(t *types.Type) (AlgKind, *types.Type) {
	if t.Broke() {
		return AMEM, nil
	}
	if t.Noalg() {
		return ANOEQ, t
	}

	switch t.Etype {
	case TANY, TFORW:
		// will be defined later.
		return ANOEQ, t

	case TINT8, TUINT8, TINT16, TUINT16,
		TINT32, TUINT32, TINT64, TUINT64,
		TINT, TUINT, TUINTPTR,
		TBOOL, TPTR,
		TCHAN, TUNSAFEPTR:
		return AMEM, nil

	case TFUNC, TMAP:
		return ANOEQ, t

	case TFLOAT32:
		return AFLOAT32, nil

	case TFLOAT64:
		return AFLOAT64, nil

	case TCOMPLEX64:
		return ACPLX64, nil

	case TCOMPLEX128:
		return ACPLX128, nil

	case TSTRING:
		return ASTRING, nil

	case TINTER:
		if t.IsEmptyInterface() {
			return ANILINTER, nil
		}
		return AINTER, nil

	case TSLICE:
		return ANOEQ, t

	case TARRAY:
		a, bad := algtype1(t.Elem())
		switch a {
		case AMEM:
			return AMEM, nil
		case ANOEQ:
			return ANOEQ, bad
		}

		switch t.NumElem() {
		case 0:
			// We checked above that the element type is comparable.
			return AMEM, nil
		case 1:
			// Single-element array is same as its lone element.
			return a, nil
		}

		return ASPECIAL, nil

	case TSTRUCT:
		fields := t.FieldSlice()

		// One-field struct is same as that one field alone.
		if len(fields) == 1 && !fields[0].Sym.IsBlank() {
			return algtype1(fields[0].Type)
		}

		ret := AMEM
		for i, f := range fields {
			// All fields must be comparable.
			a, bad := algtype1(f.Type)
			if a == ANOEQ {
				return ANOEQ, bad
			}

			// Blank fields, padded fields, fields with non-memory
			// equality need special compare.
			if a != AMEM || f.Sym.IsBlank() || ispaddedfield(t, i) {
				ret = ASPECIAL
			}
		}

		return ret, nil
	}

	Fatalf("algtype1: unexpected type %v", t)
	return 0, nil
}

// genhash returns a symbol which is the closure used to compute
// the hash of a value of type t.
// Note: the generated function must match runtime.typehash exactly.
func genhash(t *types.Type) *obj.LSym {
	switch algtype(t) {
	default:
		// genhash is only called for types that have equality
		Fatalf("genhash %v", t)
	case AMEM0:
		return sysClosure("memhash0")
	case AMEM8:
		return sysClosure("memhash8")
	case AMEM16:
		return sysClosure("memhash16")
	case AMEM32:
		return sysClosure("memhash32")
	case AMEM64:
		return sysClosure("memhash64")
	case AMEM128:
		return sysClosure("memhash128")
	case ASTRING:
		return sysClosure("strhash")
	case AINTER:
		return sysClosure("interhash")
	case ANILINTER:
		return sysClosure("nilinterhash")
	case AFLOAT32:
		return sysClosure("f32hash")
	case AFLOAT64:
		return sysClosure("f64hash")
	case ACPLX64:
		return sysClosure("c64hash")
	case ACPLX128:
		return sysClosure("c128hash")
	case AMEM:
		// For other sizes of plain memory, we build a closure
		// that calls memhash_varlen. The size of the memory is
		// encoded in the first slot of the closure.
		closure := typeLookup(fmt.Sprintf(".hashfunc%d", t.Width)).Linksym()
		if len(closure.P) > 0 { // already generated
			return closure
		}
		if memhashvarlen == nil {
			memhashvarlen = sysfunc("memhash_varlen")
		}
		ot := 0
		ot = dsymptr(closure, ot, memhashvarlen, 0)
		ot = duintptr(closure, ot, uint64(t.Width)) // size encoded in closure
		ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
		return closure
	case ASPECIAL:
		break
	}

	closure := typesymprefix(".hashfunc", t).Linksym()
	if len(closure.P) > 0 { // already generated
		return closure
	}

	// Generate hash functions for subtypes.
	// There are cases where we might not use these hashes,
	// but in that case they will get dead-code eliminated.
	// (And the closure generated by genhash will also get
	// dead-code eliminated, as we call the subtype hashers
	// directly.)
	switch t.Etype {
	case types.TARRAY:
		genhash(t.Elem())
	case types.TSTRUCT:
		for _, f := range t.FieldSlice() {
			genhash(f.Type)
		}
	}

	sym := typesymprefix(".hash", t)
	if Debug['r'] != 0 {
		fmt.Printf("genhash %v %v %v\n", closure, sym, t)
	}

	lineno = autogeneratedPos // less confusing than end of input
	dclcontext = PEXTERN

	// func sym(p *T, h uintptr) uintptr
	tfn := nod(OTFUNC, nil, nil)
	tfn.List.Set2(
		namedfield("p", types.NewPtr(t)),
		namedfield("h", types.Types[TUINTPTR]),
	)
	tfn.Rlist.Set1(anonfield(types.Types[TUINTPTR]))

	fn := dclfunc(sym, tfn)
	np := asNode(tfn.Type.Params().Field(0).Nname)
	nh := asNode(tfn.Type.Params().Field(1).Nname)

	switch t.Etype {
	case types.TARRAY:
		// An array of pure memory would be handled by the
		// standard algorithm, so the element type must not be
		// pure memory.
		hashel := hashfor(t.Elem())

		n := nod(ORANGE, nil, nod(ODEREF, np, nil))
		ni := newname(lookup("i"))
		ni.Type = types.Types[TINT]
		n.List.Set1(ni)
		n.SetColas(true)
		colasdefn(n.List.Slice(), n)
		ni = n.List.First()

		// h = hashel(&p[i], h)
		call := nod(OCALL, hashel, nil)

		nx := nod(OINDEX, np, ni)
		nx.SetBounded(true)
		na := nod(OADDR, nx, nil)
		call.List.Append(na)
		call.List.Append(nh)
		n.Nbody.Append(nod(OAS, nh, call))

		fn.Nbody.Append(n)

	case types.TSTRUCT:
		// Walk the struct using memhash for runs of AMEM
		// and calling specific hash functions for the others.
		for i, fields := 0, t.FieldSlice(); i < len(fields); {
			f := fields[i]

			// Skip blank fields.
			if f.Sym.IsBlank() {
				i++
				continue
			}

			// Hash non-memory fields with appropriate hash function.
			if !IsRegularMemory(f.Type) {
				hashel := hashfor(f.Type)
				call := nod(OCALL, hashel, nil)
				nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
				na := nod(OADDR, nx, nil)
				call.List.Append(na)
				call.List.Append(nh)
				fn.Nbody.Append(nod(OAS, nh, call))
				i++
				continue
			}

			// Otherwise, hash a maximal length run of raw memory.
			size, next := memrun(t, i)

			// h = hashel(&p.first, size, h)
			hashel := hashmem(f.Type)
			call := nod(OCALL, hashel, nil)
			nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
			na := nod(OADDR, nx, nil)
			call.List.Append(na)
			call.List.Append(nh)
			call.List.Append(nodintconst(size))
			fn.Nbody.Append(nod(OAS, nh, call))

			i = next
		}
	}

	r := nod(ORETURN, nil, nil)
	r.List.Append(nh)
	fn.Nbody.Append(r)

	if Debug['r'] != 0 {
		dumplist("genhash body", fn.Nbody)
	}

	funcbody()

	fn.Func.SetDupok(true)
	fn = typecheck(fn, ctxStmt)

	Curfn = fn
	typecheckslice(fn.Nbody.Slice(), ctxStmt)
	Curfn = nil

	if debug_dclstack != 0 {
		testdclstack()
	}

	fn.Func.SetNilCheckDisabled(true)
	xtop = append(xtop, fn)

	// Build closure. It doesn't close over any variables, so
	// it contains just the function pointer.
	dsymptr(closure, 0, sym.Linksym(), 0)
	ggloblsym(closure, int32(Widthptr), obj.DUPOK|obj.RODATA)

	return closure
}

func hashfor(t *types.Type) *Node {
	var sym *types.Sym

	switch a, _ := algtype1(t); a {
	case AMEM:
		Fatalf("hashfor with AMEM type")
	case AINTER:
		sym = Runtimepkg.Lookup("interhash")
	case ANILINTER:
		sym = Runtimepkg.Lookup("nilinterhash")
	case ASTRING:
		sym = Runtimepkg.Lookup("strhash")
	case AFLOAT32:
		sym = Runtimepkg.Lookup("f32hash")
	case AFLOAT64:
		sym = Runtimepkg.Lookup("f64hash")
	case ACPLX64:
		sym = Runtimepkg.Lookup("c64hash")
	case ACPLX128:
		sym = Runtimepkg.Lookup("c128hash")
	default:
		// Note: the caller of hashfor ensured that this symbol
		// exists and has a body by calling genhash for t.
		sym = typesymprefix(".hash", t)
	}

	n := newname(sym)
	setNodeNameFunc(n)
	n.Type = functype(nil, []*Node{
		anonfield(types.NewPtr(t)),
		anonfield(types.Types[TUINTPTR]),
	}, []*Node{
		anonfield(types.Types[TUINTPTR]),
	})
	return n
}

// sysClosure returns a closure which will call the
// given runtime function (with no closed-over variables).
func sysClosure(name string) *obj.LSym {
	s := sysvar(name + "·f")
	if len(s.P) == 0 {
		f := sysfunc(name)
		dsymptr(s, 0, f, 0)
		ggloblsym(s, int32(Widthptr), obj.DUPOK|obj.RODATA)
	}
	return s
}

// geneq returns a symbol which is the closure used to compute
// equality for two objects of type t.
func geneq(t *types.Type) *obj.LSym {
	switch algtype(t) {
	case ANOEQ:
		// The runtime will panic if it tries to compare
		// a type with a nil equality function.
		return nil
	case AMEM0:
		return sysClosure("memequal0")
	case AMEM8:
		return sysClosure("memequal8")
	case AMEM16:
		return sysClosure("memequal16")
	case AMEM32:
		return sysClosure("memequal32")
	case AMEM64:
		return sysClosure("memequal64")
	case AMEM128:
		return sysClosure("memequal128")
	case ASTRING:
		return sysClosure("strequal")
	case AINTER:
		return sysClosure("interequal")
	case ANILINTER:
		return sysClosure("nilinterequal")
	case AFLOAT32:
		return sysClosure("f32equal")
	case AFLOAT64:
		return sysClosure("f64equal")
	case ACPLX64:
		return sysClosure("c64equal")
	case ACPLX128:
		return sysClosure("c128equal")
	case AMEM:
		// make equality closure. The size of the type
		// is encoded in the closure.
		closure := typeLookup(fmt.Sprintf(".eqfunc%d", t.Width)).Linksym()
		if len(closure.P) != 0 {
			return closure
		}
		if memequalvarlen == nil {
			memequalvarlen = sysvar("memequal_varlen") // asm func
		}
		ot := 0
		ot = dsymptr(closure, ot, memequalvarlen, 0)
		ot = duintptr(closure, ot, uint64(t.Width))
		ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
		return closure
	case ASPECIAL:
		break
	}

	closure := typesymprefix(".eqfunc", t).Linksym()
	if len(closure.P) > 0 { // already generated
		return closure
	}
	sym := typesymprefix(".eq", t)
	if Debug['r'] != 0 {
		fmt.Printf("geneq %v\n", t)
	}

	// Autogenerate code for equality of structs and arrays.

	lineno = autogeneratedPos // less confusing than end of input
	dclcontext = PEXTERN

	// func sym(p, q *T) bool
	tfn := nod(OTFUNC, nil, nil)
	tfn.List.Set2(
		namedfield("p", types.NewPtr(t)),
		namedfield("q", types.NewPtr(t)),
	)
	tfn.Rlist.Set1(namedfield("r", types.Types[TBOOL]))

	fn := dclfunc(sym, tfn)
	np := asNode(tfn.Type.Params().Field(0).Nname)
	nq := asNode(tfn.Type.Params().Field(1).Nname)

	// We reach here only for types that have equality but
	// cannot be handled by the standard algorithms,
	// so t must be either an array or a struct.
	switch t.Etype {
	default:
		Fatalf("geneq %v", t)

	case TARRAY:
		nelem := t.NumElem()

		// checkAll generates code to check the equality of all array elements.
		// If unroll is greater than nelem, checkAll generates:
		//
		// if eq(p[0], q[0]) && eq(p[1], q[1]) && ... {
		// } else {
		//   return
		// }
		//
		// And so on.
		//
		// Otherwise it generates:
		//
		// for i := 0; i < nelem; i++ {
		//   if eq(p[i], q[i]) {
		//   } else {
		//     return
		//   }
		// }
		//
		// TODO(josharian): consider doing some loop unrolling
		// for larger nelem as well, processing a few elements at a time in a loop.
		checkAll := func(unroll int64, eq func(pi, qi *Node) *Node) {
			// checkIdx generates a node to check for equality at index i.
			checkIdx := func(i *Node) *Node {
				// pi := p[i]
				pi := nod(OINDEX, np, i)
				pi.SetBounded(true)
				pi.Type = t.Elem()
				// qi := q[i]
				qi := nod(OINDEX, nq, i)
				qi.SetBounded(true)
				qi.Type = t.Elem()
				return eq(pi, qi)
			}

			if nelem <= unroll {
				// Generate a series of checks.
				var cond *Node
				for i := int64(0); i < nelem; i++ {
					c := nodintconst(i)
					check := checkIdx(c)
					if cond == nil {
						cond = check
						continue
					}
					cond = nod(OANDAND, cond, check)
				}
				nif := nod(OIF, cond, nil)
				nif.Rlist.Append(nod(ORETURN, nil, nil))
				fn.Nbody.Append(nif)
				return
			}

			// Generate a for loop.
			// for i := 0; i < nelem; i++
			i := temp(types.Types[TINT])
			init := nod(OAS, i, nodintconst(0))
			cond := nod(OLT, i, nodintconst(nelem))
			post := nod(OAS, i, nod(OADD, i, nodintconst(1)))
			loop := nod(OFOR, cond, post)
			loop.Ninit.Append(init)
			// if eq(pi, qi) {} else { return }
			check := checkIdx(i)
			nif := nod(OIF, check, nil)
			nif.Rlist.Append(nod(ORETURN, nil, nil))
			loop.Nbody.Append(nif)
			fn.Nbody.Append(loop)
		}

		switch t.Elem().Etype {
		case TSTRING:
			// Do two loops. First, check that all the lengths match (cheap).
			// Second, check that all the contents match (expensive).
			// TODO: when the array size is small, unroll the length match checks.
			checkAll(3, func(pi, qi *Node) *Node {
				// Compare lengths.
				eqlen, _ := eqstring(pi, qi)
				return eqlen
			})
			checkAll(1, func(pi, qi *Node) *Node {
				// Compare contents.
				_, eqmem := eqstring(pi, qi)
				return eqmem
			})
		case TFLOAT32, TFLOAT64:
			checkAll(2, func(pi, qi *Node) *Node {
				// p[i] == q[i]
				return nod(OEQ, pi, qi)
			})
		// TODO: pick apart structs, do them piecemeal too
		default:
			checkAll(1, func(pi, qi *Node) *Node {
				// p[i] == q[i]
				return nod(OEQ, pi, qi)
			})
		}
		// return true
		ret := nod(ORETURN, nil, nil)
		ret.List.Append(nodbool(true))
		fn.Nbody.Append(ret)

	case TSTRUCT:
		// Build a list of conditions to satisfy.
		// The conditions are a list-of-lists. Conditions are reorderable
		// within each inner list. The outer lists must be evaluated in order.
		var conds [][]*Node
		conds = append(conds, []*Node{})
		and := func(n *Node) {
			i := len(conds) - 1
			conds[i] = append(conds[i], n)
		}

		// Walk the struct using memequal for runs of AMEM
		// and calling specific equality tests for the others.
		for i, fields := 0, t.FieldSlice(); i < len(fields); {
			f := fields[i]

			// Skip blank-named fields.
			if f.Sym.IsBlank() {
				i++
				continue
			}

			// Compare non-memory fields with field equality.
			if !IsRegularMemory(f.Type) {
				if EqCanPanic(f.Type) {
					// Enforce ordering by starting a new set of reorderable conditions.
					conds = append(conds, []*Node{})
				}
				p := nodSym(OXDOT, np, f.Sym)
				q := nodSym(OXDOT, nq, f.Sym)
				switch {
				case f.Type.IsString():
					eqlen, eqmem := eqstring(p, q)
					and(eqlen)
					and(eqmem)
				default:
					and(nod(OEQ, p, q))
				}
				if EqCanPanic(f.Type) {
					// Also enforce ordering after something that can panic.
					conds = append(conds, []*Node{})
				}
				i++
				continue
			}

			// Find maximal length run of memory-only fields.
			size, next := memrun(t, i)

			// TODO(rsc): All the calls to newname are wrong for
			// cross-package unexported fields.
			if s := fields[i:next]; len(s) <= 2 {
				// Two or fewer fields: use plain field equality.
				for _, f := range s {
					and(eqfield(np, nq, f.Sym))
				}
			} else {
				// More than two fields: use memequal.
				and(eqmem(np, nq, f.Sym, size))
			}
			i = next
		}

		// Sort conditions to put runtime calls last.
		// Preserve the rest of the ordering.
		var flatConds []*Node
		for _, c := range conds {
			isCall := func(n *Node) bool {
				return n.Op == OCALL || n.Op == OCALLFUNC
			}
			sort.SliceStable(c, func(i, j int) bool {
				return !isCall(c[i]) && isCall(c[j])
			})
			flatConds = append(flatConds, c...)
		}

		var cond *Node
		if len(flatConds) == 0 {
			cond = nodbool(true)
		} else {
			cond = flatConds[0]
			for _, c := range flatConds[1:] {
				cond = nod(OANDAND, cond, c)
			}
		}

		ret := nod(ORETURN, nil, nil)
		ret.List.Append(cond)
		fn.Nbody.Append(ret)
	}

	if Debug['r'] != 0 {
		dumplist("geneq body", fn.Nbody)
	}

	funcbody()

	fn.Func.SetDupok(true)
	fn = typecheck(fn, ctxStmt)

	Curfn = fn
	typecheckslice(fn.Nbody.Slice(), ctxStmt)
	Curfn = nil

	if debug_dclstack != 0 {
		testdclstack()
	}

	// Disable checknils while compiling this code.
	// We are comparing a struct or an array,
	// neither of which can be nil, and our comparisons
	// are shallow.
	fn.Func.SetNilCheckDisabled(true)
	xtop = append(xtop, fn)

	// Generate a closure which points at the function we just generated.
	dsymptr(closure, 0, sym.Linksym(), 0)
	ggloblsym(closure, int32(Widthptr), obj.DUPOK|obj.RODATA)
	return closure
}

// eqfield returns the node
// 	p.field == q.field
func eqfield(p *Node, q *Node, field *types.Sym) *Node {
	nx := nodSym(OXDOT, p, field)
	ny := nodSym(OXDOT, q, field)
	ne := nod(OEQ, nx, ny)
	return ne
}

// eqstring returns the nodes
//   len(s) == len(t)
// and
//   memequal(s.ptr, t.ptr, len(s))
// which can be used to construct string equality comparison.
// eqlen must be evaluated before eqmem, and shortcircuiting is required.
func eqstring(s, t *Node) (eqlen, eqmem *Node) {
	s = conv(s, types.Types[TSTRING])
	t = conv(t, types.Types[TSTRING])
	sptr := nod(OSPTR, s, nil)
	tptr := nod(OSPTR, t, nil)
	slen := conv(nod(OLEN, s, nil), types.Types[TUINTPTR])
	tlen := conv(nod(OLEN, t, nil), types.Types[TUINTPTR])

	fn := syslook("memequal")
	fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
	call := nod(OCALL, fn, nil)
	call.List.Append(sptr, tptr, slen.copy())
	call = typecheck(call, ctxExpr|ctxMultiOK)

	cmp := nod(OEQ, slen, tlen)
	cmp = typecheck(cmp, ctxExpr)
	cmp.Type = types.Types[TBOOL]
	return cmp, call
}

// eqinterface returns the nodes
//   s.tab == t.tab (or s.typ == t.typ, as appropriate)
// and
//   ifaceeq(s.tab, s.data, t.data) (or efaceeq(s.typ, s.data, t.data), as appropriate)
// which can be used to construct interface equality comparison.
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
func eqinterface(s, t *Node) (eqtab, eqdata *Node) {
	if !types.Identical(s.Type, t.Type) {
		Fatalf("eqinterface %v %v", s.Type, t.Type)
	}
	// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
	// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
	var fn *Node
	if s.Type.IsEmptyInterface() {
		fn = syslook("efaceeq")
	} else {
		fn = syslook("ifaceeq")
	}

	stab := nod(OITAB, s, nil)
	ttab := nod(OITAB, t, nil)
	sdata := nod(OIDATA, s, nil)
	tdata := nod(OIDATA, t, nil)
	sdata.Type = types.Types[TUNSAFEPTR]
	tdata.Type = types.Types[TUNSAFEPTR]
	sdata.SetTypecheck(1)
	tdata.SetTypecheck(1)

	call := nod(OCALL, fn, nil)
	call.List.Append(stab, sdata, tdata)
	call = typecheck(call, ctxExpr|ctxMultiOK)

	cmp := nod(OEQ, stab, ttab)
	cmp = typecheck(cmp, ctxExpr)
	cmp.Type = types.Types[TBOOL]
	return cmp, call
}

// eqmem returns the node
// 	memequal(&p.field, &q.field [, size])
func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
	nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
	ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
	nx = typecheck(nx, ctxExpr)
	ny = typecheck(ny, ctxExpr)

	fn, needsize := eqmemfunc(size, nx.Type.Elem())
	call := nod(OCALL, fn, nil)
	call.List.Append(nx)
	call.List.Append(ny)
	if needsize {
		call.List.Append(nodintconst(size))
	}

	return call
}

func eqmemfunc(size int64, t *types.Type) (fn *Node, needsize bool) {
	switch size {
	default:
		fn = syslook("memequal")
		needsize = true
	case 1, 2, 4, 8, 16:
		buf := fmt.Sprintf("memequal%d", int(size)*8)
		fn = syslook(buf)
	}

	fn = substArgTypes(fn, t, t)
	return fn, needsize
}

// memrun finds runs of struct fields for which memory-only algs are appropriate.
// t is the parent struct type, and start is the field index at which to start the run.
// size is the length in bytes of the memory included in the run.
// next is the index just after the end of the memory run.
func memrun(t *types.Type, start int) (size int64, next int) {
	next = start
	for {
		next++
		if next == t.NumFields() {
			break
		}
		// Stop run after a padded field.
		if ispaddedfield(t, next-1) {
			break
		}
		// Also, stop before a blank or non-memory field.
		if f := t.Field(next); f.Sym.IsBlank() || !IsRegularMemory(f.Type) {
			break
		}
	}
	return t.Field(next-1).End() - t.Field(start).Offset, next
}

// ispaddedfield reports whether the i'th field of struct type t is followed
// by padding.
func ispaddedfield(t *types.Type, i int) bool {
	if !t.IsStruct() {
		Fatalf("ispaddedfield called non-struct %v", t)
	}
	end := t.Width
	if i+1 < t.NumFields() {
		end = t.Field(i + 1).Offset
	}
	return t.Field(i).End() != end
}
