// 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 (
	"cmd/internal/obj"
	"fmt"
	"strings"
)

var mpzero Mpint

// The constant is known to runtime.
const (
	tmpstringbufsize = 32
)

func walk(fn *Node) {
	Curfn = fn

	if Debug['W'] != 0 {
		s := fmt.Sprintf("\nbefore %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Nbody)
	}

	lno := int(lineno)

	// Final typecheck for any unused variables.
	// It's hard to be on the heap when not-used, but best to be consistent about &~PHEAP here and below.
	for l := fn.Func.Dcl; l != nil; l = l.Next {
		if l.N.Op == ONAME && l.N.Class&^PHEAP == PAUTO {
			typecheck(&l.N, Erv|Easgn)
		}
	}

	// Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
	for l := fn.Func.Dcl; l != nil; l = l.Next {
		if l.N.Op == ONAME && l.N.Class&^PHEAP == PAUTO && l.N.Name.Defn != nil && l.N.Name.Defn.Op == OTYPESW && l.N.Used {
			l.N.Name.Defn.Left.Used = true
		}
	}

	for l := fn.Func.Dcl; l != nil; l = l.Next {
		if l.N.Op != ONAME || l.N.Class&^PHEAP != PAUTO || l.N.Sym.Name[0] == '&' || l.N.Used {
			continue
		}
		if defn := l.N.Name.Defn; defn != nil && defn.Op == OTYPESW {
			if defn.Left.Used {
				continue
			}
			lineno = defn.Left.Lineno
			Yyerror("%v declared and not used", l.N.Sym)
			defn.Left.Used = true // suppress repeats
		} else {
			lineno = l.N.Lineno
			Yyerror("%v declared and not used", l.N.Sym)
		}
	}

	lineno = int32(lno)
	if nerrors != 0 {
		return
	}
	walkstmtlist(Curfn.Nbody)
	if Debug['W'] != 0 {
		s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Nbody)
	}

	heapmoves()
	if Debug['W'] != 0 && Curfn.Func.Enter != nil {
		s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Func.Enter)
	}
}

func walkstmtlist(l *NodeList) {
	for ; l != nil; l = l.Next {
		walkstmt(&l.N)
	}
}

func samelist(a *NodeList, b *NodeList) bool {
	for ; a != nil && b != nil; a, b = a.Next, b.Next {
		if a.N != b.N {
			return false
		}
	}
	return a == b
}

func paramoutheap(fn *Node) bool {
	for l := fn.Func.Dcl; l != nil; l = l.Next {
		switch l.N.Class {
		case PPARAMOUT,
			PPARAMOUT | PHEAP:
			return l.N.Addrtaken

			// stop early - parameters are over
		case PAUTO,
			PAUTO | PHEAP:
			return false
		}
	}

	return false
}

// adds "adjust" to all the argument locations for the call n.
// n must be a defer or go node that has already been walked.
func adjustargs(n *Node, adjust int) {
	var arg *Node
	var lhs *Node

	callfunc := n.Left
	for args := callfunc.List; args != nil; args = args.Next {
		arg = args.N
		if arg.Op != OAS {
			Yyerror("call arg not assignment")
		}
		lhs = arg.Left
		if lhs.Op == ONAME {
			// This is a temporary introduced by reorder1.
			// The real store to the stack appears later in the arg list.
			continue
		}

		if lhs.Op != OINDREG {
			Yyerror("call argument store does not use OINDREG")
		}

		// can't really check this in machine-indep code.
		//if(lhs->val.u.reg != D_SP)
		//      yyerror("call arg assign not indreg(SP)");
		lhs.Xoffset += int64(adjust)
	}
}

func walkstmt(np **Node) {
	n := *np
	if n == nil {
		return
	}
	if n.Dodata == 2 { // don't walk, generated by anylit.
		return
	}

	setlineno(n)

	walkstmtlist(n.Ninit)

	switch n.Op {
	default:
		if n.Op == ONAME {
			Yyerror("%v is not a top level statement", n.Sym)
		} else {
			Yyerror("%v is not a top level statement", Oconv(int(n.Op), 0))
		}
		Dump("nottop", n)

	case OAS,
		OASOP,
		OAS2,
		OAS2DOTTYPE,
		OAS2RECV,
		OAS2FUNC,
		OAS2MAPR,
		OCLOSE,
		OCOPY,
		OCALLMETH,
		OCALLINTER,
		OCALL,
		OCALLFUNC,
		ODELETE,
		OSEND,
		OPRINT,
		OPRINTN,
		OPANIC,
		OEMPTY,
		ORECOVER,
		OGETG:
		if n.Typecheck == 0 {
			Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign))
		}
		init := n.Ninit
		n.Ninit = nil
		walkexpr(&n, &init)
		addinit(&n, init)
		if (*np).Op == OCOPY && n.Op == OCONVNOP {
			n.Op = OEMPTY // don't leave plain values as statements.
		}

		// special case for a receive where we throw away
	// the value received.
	case ORECV:
		if n.Typecheck == 0 {
			Fatalf("missing typecheck: %v", Nconv(n, obj.FmtSign))
		}
		init := n.Ninit
		n.Ninit = nil

		walkexpr(&n.Left, &init)
		n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, typename(n.Left.Type), n.Left, nodnil())
		walkexpr(&n, &init)

		addinit(&n, init)

	case OBREAK,
		ODCL,
		OCONTINUE,
		OFALL,
		OGOTO,
		OLABEL,
		ODCLCONST,
		ODCLTYPE,
		OCHECKNIL,
		OVARKILL:
		break

	case OBLOCK:
		walkstmtlist(n.List)

	case OXCASE:
		Yyerror("case statement out of place")
		n.Op = OCASE
		fallthrough

	case OCASE:
		walkstmt(&n.Right)

	case ODEFER:
		hasdefer = true
		switch n.Left.Op {
		case OPRINT, OPRINTN:
			walkprintfunc(&n.Left, &n.Ninit)

		case OCOPY:
			n.Left = copyany(n.Left, &n.Ninit, 1)

		default:
			walkexpr(&n.Left, &n.Ninit)
		}

		// make room for size & fn arguments.
		adjustargs(n, 2*Widthptr)

	case OFOR:
		if n.Left != nil {
			walkstmtlist(n.Left.Ninit)
			init := n.Left.Ninit
			n.Left.Ninit = nil
			walkexpr(&n.Left, &init)
			addinit(&n.Left, init)
		}

		walkstmt(&n.Right)
		walkstmtlist(n.Nbody)

	case OIF:
		walkexpr(&n.Left, &n.Ninit)
		walkstmtlist(n.Nbody)
		walkstmtlist(n.Rlist)

	case OPROC:
		switch n.Left.Op {
		case OPRINT, OPRINTN:
			walkprintfunc(&n.Left, &n.Ninit)

		case OCOPY:
			n.Left = copyany(n.Left, &n.Ninit, 1)

		default:
			walkexpr(&n.Left, &n.Ninit)
		}

		// make room for size & fn arguments.
		adjustargs(n, 2*Widthptr)

	case ORETURN:
		walkexprlist(n.List, &n.Ninit)
		if n.List == nil {
			break
		}
		if (Curfn.Type.Outnamed && count(n.List) > 1) || paramoutheap(Curfn) {
			// assign to the function out parameters,
			// so that reorder3 can fix up conflicts
			var rl *NodeList

			var cl uint8
			for ll := Curfn.Func.Dcl; ll != nil; ll = ll.Next {
				cl = ll.N.Class &^ PHEAP
				if cl == PAUTO {
					break
				}
				if cl == PPARAMOUT {
					rl = list(rl, ll.N)
				}
			}

			if samelist(rl, n.List) {
				// special return in disguise
				n.List = nil

				break
			}

			if count(n.List) == 1 && count(rl) > 1 {
				// OAS2FUNC in disguise
				f := n.List.N

				if f.Op != OCALLFUNC && f.Op != OCALLMETH && f.Op != OCALLINTER {
					Fatalf("expected return of call, have %v", f)
				}
				n.List = concat(list1(f), ascompatet(int(n.Op), rl, &f.Type, 0, &n.Ninit))
				break
			}

			// move function calls out, to make reorder3's job easier.
			walkexprlistsafe(n.List, &n.Ninit)

			ll := ascompatee(int(n.Op), rl, n.List, &n.Ninit)
			n.List = reorder3(ll)
			break
		}

		ll := ascompatte(int(n.Op), nil, false, Getoutarg(Curfn.Type), n.List, 1, &n.Ninit)
		n.List = ll

	case ORETJMP:
		break

	case OSELECT:
		walkselect(n)

	case OSWITCH:
		walkswitch(n)

	case ORANGE:
		walkrange(n)

	case OXFALL:
		Yyerror("fallthrough statement out of place")
		n.Op = OFALL
	}

	if n.Op == ONAME {
		Fatalf("walkstmt ended up with name: %v", Nconv(n, obj.FmtSign))
	}

	*np = n
}

func isSmallMakeSlice(n *Node) bool {
	if n.Op != OMAKESLICE {
		return false
	}
	l := n.Left
	r := n.Right
	if r == nil {
		r = l
	}
	t := n.Type

	return Smallintconst(l) && Smallintconst(r) && (t.Type.Width == 0 || Mpgetfix(r.Val().U.(*Mpint)) < (1<<16)/t.Type.Width)
}

/*
 * walk the whole tree of the body of an
 * expression or simple statement.
 * the types expressions are calculated.
 * compile-time constants are evaluated.
 * complex side effects like statements are appended to init
 */
func walkexprlist(l *NodeList, init **NodeList) {
	for ; l != nil; l = l.Next {
		walkexpr(&l.N, init)
	}
}

func walkexprlistsafe(l *NodeList, init **NodeList) {
	for ; l != nil; l = l.Next {
		l.N = safeexpr(l.N, init)
		walkexpr(&l.N, init)
	}
}

func walkexprlistcheap(l *NodeList, init **NodeList) {
	for ; l != nil; l = l.Next {
		l.N = cheapexpr(l.N, init)
		walkexpr(&l.N, init)
	}
}

func walkexpr(np **Node, init **NodeList) {
	n := *np

	if n == nil {
		return
	}

	if init == &n.Ninit {
		// not okay to use n->ninit when walking n,
		// because we might replace n with some other node
		// and would lose the init list.
		Fatalf("walkexpr init == &n->ninit")
	}

	if n.Ninit != nil {
		walkstmtlist(n.Ninit)
		*init = concat(*init, n.Ninit)
		n.Ninit = nil
	}

	// annoying case - not typechecked
	if n.Op == OKEY {
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		return
	}

	lno := setlineno(n)

	if Debug['w'] > 1 {
		Dump("walk-before", n)
	}

	if n.Typecheck != 1 {
		Fatalf("missed typecheck: %v\n", Nconv(n, obj.FmtSign))
	}

	switch n.Op {
	default:
		Dump("walk", n)
		Fatalf("walkexpr: switch 1 unknown op %v", Nconv(n, obj.FmtShort|obj.FmtSign))

	case OTYPE,
		ONONAME,
		OINDREG,
		OEMPTY,
		OPARAM,
		OGETG:
		goto ret

	case ONOT,
		OMINUS,
		OPLUS,
		OCOM,
		OREAL,
		OIMAG,
		ODOTMETH,
		ODOTINTER:
		walkexpr(&n.Left, init)
		goto ret

	case OIND:
		walkexpr(&n.Left, init)
		goto ret

	case ODOT:
		usefield(n)
		walkexpr(&n.Left, init)
		goto ret

	case ODOTPTR:
		usefield(n)
		if n.Op == ODOTPTR && n.Left.Type.Type.Width == 0 {
			// No actual copy will be generated, so emit an explicit nil check.
			n.Left = cheapexpr(n.Left, init)

			checknil(n.Left, init)
		}

		walkexpr(&n.Left, init)
		goto ret

	case OEFACE:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		goto ret

	case OSPTR, OITAB:
		walkexpr(&n.Left, init)
		goto ret

	case OLEN, OCAP:
		walkexpr(&n.Left, init)

		// replace len(*[10]int) with 10.
		// delayed until now to preserve side effects.
		t := n.Left.Type

		if Isptr[t.Etype] {
			t = t.Type
		}
		if Isfixedarray(t) {
			safeexpr(n.Left, init)
			Nodconst(n, n.Type, t.Bound)
			n.Typecheck = 1
		}

		goto ret

	case OLSH, ORSH:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		t := n.Left.Type
		n.Bounded = bounded(n.Right, 8*t.Width)
		if Debug['m'] != 0 && n.Etype != 0 && !Isconst(n.Right, CTINT) {
			Warn("shift bounds check elided")
		}
		goto ret

		// Use results from call expression as arguments for complex.
	case OAND,
		OSUB,
		OHMUL,
		OLT,
		OLE,
		OGE,
		OGT,
		OADD,
		OCOMPLEX,
		OLROT:
		if n.Op == OCOMPLEX && n.Left == nil && n.Right == nil {
			n.Left = n.List.N
			n.Right = n.List.Next.N
		}

		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		goto ret

	case OOR, OXOR:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		walkrotate(&n)
		goto ret

	case OEQ, ONE:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)

		// Disable safemode while compiling this code: the code we
		// generate internally can refer to unsafe.Pointer.
		// In this case it can happen if we need to generate an ==
		// for a struct containing a reflect.Value, which itself has
		// an unexported field of type unsafe.Pointer.
		old_safemode := safemode

		safemode = 0
		walkcompare(&n, init)
		safemode = old_safemode
		goto ret

	case OANDAND, OOROR:
		walkexpr(&n.Left, init)

		// cannot put side effects from n.Right on init,
		// because they cannot run before n.Left is checked.
		// save elsewhere and store on the eventual n.Right.
		var ll *NodeList

		walkexpr(&n.Right, &ll)
		addinit(&n.Right, ll)
		goto ret

	case OPRINT, OPRINTN:
		walkexprlist(n.List, init)
		n = walkprint(n, init)
		goto ret

	case OPANIC:
		n = mkcall("gopanic", nil, init, n.Left)
		goto ret

	case ORECOVER:
		n = mkcall("gorecover", n.Type, init, Nod(OADDR, nodfp, nil))
		goto ret

	case OLITERAL:
		n.Addable = true
		goto ret

	case OCLOSUREVAR, OCFUNC:
		n.Addable = true
		goto ret

	case ONAME:
		if n.Class&PHEAP == 0 && n.Class != PPARAMREF {
			n.Addable = true
		}
		goto ret

	case OCALLINTER:
		t := n.Left.Type
		if n.List != nil && n.List.N.Op == OAS {
			goto ret
		}
		walkexpr(&n.Left, init)
		walkexprlist(n.List, init)
		ll := ascompatte(int(n.Op), n, n.Isddd, getinarg(t), n.List, 0, init)
		n.List = reorder1(ll)
		goto ret

	case OCALLFUNC:
		if n.Left.Op == OCLOSURE {
			// Transform direct call of a closure to call of a normal function.
			// transformclosure already did all preparation work.

			// Prepend captured variables to argument list.
			n.List = concat(n.Left.Func.Enter, n.List)

			n.Left.Func.Enter = nil

			// Replace OCLOSURE with ONAME/PFUNC.
			n.Left = n.Left.Func.Closure.Func.Nname

			// Update type of OCALLFUNC node.
			// Output arguments had not changed, but their offsets could.
			if n.Left.Type.Outtuple == 1 {
				t := getoutargx(n.Left.Type).Type
				if t.Etype == TFIELD {
					t = t.Type
				}
				n.Type = t
			} else {
				n.Type = getoutargx(n.Left.Type)
			}
		}

		t := n.Left.Type
		if n.List != nil && n.List.N.Op == OAS {
			goto ret
		}

		walkexpr(&n.Left, init)
		walkexprlist(n.List, init)

		if n.Left.Op == ONAME && n.Left.Sym.Name == "Sqrt" && n.Left.Sym.Pkg.Path == "math" {
			switch Thearch.Thechar {
			case '5', '6', '7':
				n.Op = OSQRT
				n.Left = n.List.N
				n.List = nil
				goto ret
			}
		}

		ll := ascompatte(int(n.Op), n, n.Isddd, getinarg(t), n.List, 0, init)
		n.List = reorder1(ll)
		goto ret

	case OCALLMETH:
		t := n.Left.Type
		if n.List != nil && n.List.N.Op == OAS {
			goto ret
		}
		walkexpr(&n.Left, init)
		walkexprlist(n.List, init)
		ll := ascompatte(int(n.Op), n, false, getthis(t), list1(n.Left.Left), 0, init)
		lr := ascompatte(int(n.Op), n, n.Isddd, getinarg(t), n.List, 0, init)
		ll = concat(ll, lr)
		n.Left.Left = nil
		ullmancalc(n.Left)
		n.List = reorder1(ll)
		goto ret

	case OAS:
		*init = concat(*init, n.Ninit)
		n.Ninit = nil

		walkexpr(&n.Left, init)
		n.Left = safeexpr(n.Left, init)

		if oaslit(n, init) {
			goto ret
		}

		if n.Right == nil || iszero(n.Right) && flag_race == 0 {
			goto ret
		}

		switch n.Right.Op {
		default:
			walkexpr(&n.Right, init)

		case ODOTTYPE:
			// TODO(rsc): The Isfat is for consistency with componentgen and orderexpr.
			// It needs to be removed in all three places.
			// That would allow inlining x.(struct{*int}) the same as x.(*int).
			if isdirectiface(n.Right.Type) && !Isfat(n.Right.Type) && flag_race == 0 {
				// handled directly during cgen
				walkexpr(&n.Right, init)
				break
			}

			// x = i.(T); n.Left is x, n.Right.Left is i.
			// orderstmt made sure x is addressable.
			walkexpr(&n.Right.Left, init)

			n1 := Nod(OADDR, n.Left, nil)
			r := n.Right // i.(T)

			if Debug_typeassert > 0 {
				Warn("type assertion not inlined")
			}

			buf := "assert" + type2IET(r.Left.Type) + "2" + type2IET(r.Type)
			fn := syslook(buf, 1)
			substArgTypes(fn, r.Left.Type, r.Type)

			n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1)
			walkexpr(&n, init)
			goto ret

		case ORECV:
			// x = <-c; n.Left is x, n.Right.Left is c.
			// orderstmt made sure x is addressable.
			walkexpr(&n.Right.Left, init)

			n1 := Nod(OADDR, n.Left, nil)
			r := n.Right.Left // the channel
			n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, typename(r.Type), r, n1)
			walkexpr(&n, init)
			goto ret

		case OAPPEND:
			// x = append(...)
			r := n.Right
			if r.Isddd {
				r = appendslice(r, init) // also works for append(slice, string).
			} else {
				r = walkappend(r, init, n)
			}
			n.Right = r
			if r.Op == OAPPEND {
				// Left in place for back end.
				// Do not add a new write barrier.
				goto ret
			}
			// Otherwise, lowered for race detector.
			// Treat as ordinary assignment.
		}

		if n.Left != nil && n.Right != nil {
			r := convas(Nod(OAS, n.Left, n.Right), init)
			r.Dodata = n.Dodata
			n = r
			n = applywritebarrier(n, init)
		}

		goto ret

	case OAS2:
		*init = concat(*init, n.Ninit)
		n.Ninit = nil
		walkexprlistsafe(n.List, init)
		walkexprlistsafe(n.Rlist, init)
		ll := ascompatee(OAS, n.List, n.Rlist, init)
		ll = reorder3(ll)
		for lr := ll; lr != nil; lr = lr.Next {
			lr.N = applywritebarrier(lr.N, init)
		}
		n = liststmt(ll)
		goto ret

		// a,b,... = fn()
	case OAS2FUNC:
		*init = concat(*init, n.Ninit)

		n.Ninit = nil
		r := n.Rlist.N
		walkexprlistsafe(n.List, init)
		walkexpr(&r, init)

		ll := ascompatet(int(n.Op), n.List, &r.Type, 0, init)
		for lr := ll; lr != nil; lr = lr.Next {
			lr.N = applywritebarrier(lr.N, init)
		}
		n = liststmt(concat(list1(r), ll))
		goto ret

		// x, y = <-c
	// orderstmt made sure x is addressable.
	case OAS2RECV:
		*init = concat(*init, n.Ninit)

		n.Ninit = nil
		r := n.Rlist.N
		walkexprlistsafe(n.List, init)
		walkexpr(&r.Left, init)
		var n1 *Node
		if isblank(n.List.N) {
			n1 = nodnil()
		} else {
			n1 = Nod(OADDR, n.List.N, nil)
		}
		n1.Etype = 1 // addr does not escape
		fn := chanfn("chanrecv2", 2, r.Left.Type)
		r = mkcall1(fn, n.List.Next.N.Type, init, typename(r.Left.Type), r.Left, n1)
		n = Nod(OAS, n.List.Next.N, r)
		typecheck(&n, Etop)
		goto ret

		// a,b = m[i];
	case OAS2MAPR:
		*init = concat(*init, n.Ninit)

		n.Ninit = nil
		r := n.Rlist.N
		walkexprlistsafe(n.List, init)
		walkexpr(&r.Left, init)
		walkexpr(&r.Right, init)
		t := r.Left.Type
		p := ""
		if t.Type.Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing.
			switch Simsimtype(t.Down) {
			case TINT32, TUINT32:
				p = "mapaccess2_fast32"

			case TINT64, TUINT64:
				p = "mapaccess2_fast64"

			case TSTRING:
				p = "mapaccess2_faststr"
			}
		}

		var key *Node
		if p != "" {
			// fast versions take key by value
			key = r.Right
		} else {
			// standard version takes key by reference
			// orderexpr made sure key is addressable.
			key = Nod(OADDR, r.Right, nil)

			p = "mapaccess2"
		}

		// from:
		//   a,b = m[i]
		// to:
		//   var,b = mapaccess2*(t, m, i)
		//   a = *var
		a := n.List.N

		fn := mapfn(p, t)
		r = mkcall1(fn, getoutargx(fn.Type), init, typename(t), r.Left, key)

		// mapaccess2* returns a typed bool, but due to spec changes,
		// the boolean result of i.(T) is now untyped so we make it the
		// same type as the variable on the lhs.
		if !isblank(n.List.Next.N) {
			r.Type.Type.Down.Type = n.List.Next.N.Type
		}
		n.Rlist = list1(r)
		n.Op = OAS2FUNC

		// don't generate a = *var if a is _
		if !isblank(a) {
			var_ := temp(Ptrto(t.Type))
			var_.Typecheck = 1
			n.List.N = var_
			walkexpr(&n, init)
			*init = list(*init, n)
			n = Nod(OAS, a, Nod(OIND, var_, nil))
		}

		typecheck(&n, Etop)
		walkexpr(&n, init)

		// TODO: ptr is always non-nil, so disable nil check for this OIND op.
		goto ret

	case ODELETE:
		*init = concat(*init, n.Ninit)
		n.Ninit = nil
		map_ := n.List.N
		key := n.List.Next.N
		walkexpr(&map_, init)
		walkexpr(&key, init)

		// orderstmt made sure key is addressable.
		key = Nod(OADDR, key, nil)

		t := map_.Type
		n = mkcall1(mapfndel("mapdelete", t), nil, init, typename(t), map_, key)
		goto ret

	case OAS2DOTTYPE:
		e := n.Rlist.N // i.(T)
		// TODO(rsc): The Isfat is for consistency with componentgen and orderexpr.
		// It needs to be removed in all three places.
		// That would allow inlining x.(struct{*int}) the same as x.(*int).
		if isdirectiface(e.Type) && !Isfat(e.Type) && flag_race == 0 {
			// handled directly during gen.
			walkexprlistsafe(n.List, init)
			walkexpr(&e.Left, init)
			goto ret
		}

		// res, ok = i.(T)
		// orderstmt made sure a is addressable.
		*init = concat(*init, n.Ninit)
		n.Ninit = nil

		walkexprlistsafe(n.List, init)
		walkexpr(&e.Left, init)
		t := e.Type    // T
		from := e.Left // i

		oktype := Types[TBOOL]
		ok := n.List.Next.N
		if !isblank(ok) {
			oktype = ok.Type
		}

		fromKind := type2IET(from.Type)
		toKind := type2IET(t)

		// Avoid runtime calls in a few cases of the form _, ok := i.(T).
		// This is faster and shorter and allows the corresponding assertX2X2
		// routines to skip nil checks on their last argument.
		if isblank(n.List.N) {
			var fast *Node
			switch {
			case fromKind == "E" && toKind == "T":
				tab := Nod(OITAB, from, nil) // type:eface::tab:iface
				typ := Nod(OCONVNOP, typename(t), nil)
				typ.Type = Ptrto(Types[TUINTPTR])
				fast = Nod(OEQ, tab, typ)
			case fromKind == "I" && toKind == "E",
				fromKind == "E" && toKind == "E":
				tab := Nod(OITAB, from, nil)
				fast = Nod(ONE, nodnil(), tab)
			}
			if fast != nil {
				if Debug_typeassert > 0 {
					Warn("type assertion (ok only) inlined")
				}
				n = Nod(OAS, ok, fast)
				typecheck(&n, Etop)
				goto ret
			}
		}

		var resptr *Node // &res
		if isblank(n.List.N) {
			resptr = nodnil()
		} else {
			resptr = Nod(OADDR, n.List.N, nil)
		}
		resptr.Etype = 1 // addr does not escape

		if Debug_typeassert > 0 {
			Warn("type assertion not inlined")
		}
		buf := "assert" + fromKind + "2" + toKind + "2"
		fn := syslook(buf, 1)
		substArgTypes(fn, from.Type, t)
		call := mkcall1(fn, oktype, init, typename(t), from, resptr)
		n = Nod(OAS, ok, call)
		typecheck(&n, Etop)
		goto ret

	case ODOTTYPE, ODOTTYPE2:
		if !isdirectiface(n.Type) || Isfat(n.Type) {
			Fatalf("walkexpr ODOTTYPE") // should see inside OAS only
		}
		walkexpr(&n.Left, init)
		goto ret

	case OCONVIFACE:
		walkexpr(&n.Left, init)

		// Optimize convT2E as a two-word copy when T is pointer-shaped.
		if isnilinter(n.Type) && isdirectiface(n.Left.Type) {
			l := Nod(OEFACE, typename(n.Left.Type), n.Left)
			l.Type = n.Type
			l.Typecheck = n.Typecheck
			n = l
			goto ret
		}

		// Build name of function: convI2E etc.
		// Not all names are possible
		// (e.g., we'll never generate convE2E or convE2I).
		buf := "conv" + type2IET(n.Left.Type) + "2" + type2IET(n.Type)
		fn := syslook(buf, 1)
		var ll *NodeList
		if !Isinter(n.Left.Type) {
			ll = list(ll, typename(n.Left.Type))
		}
		if !isnilinter(n.Type) {
			ll = list(ll, typename(n.Type))
		}
		if !Isinter(n.Left.Type) && !isnilinter(n.Type) {
			sym := Pkglookup(Tconv(n.Left.Type, obj.FmtLeft)+"."+Tconv(n.Type, obj.FmtLeft), itabpkg)
			if sym.Def == nil {
				l := Nod(ONAME, nil, nil)
				l.Sym = sym
				l.Type = Ptrto(Types[TUINT8])
				l.Addable = true
				l.Class = PEXTERN
				l.Xoffset = 0
				sym.Def = l
				ggloblsym(sym, int32(Widthptr), obj.DUPOK|obj.NOPTR)
			}

			l := Nod(OADDR, sym.Def, nil)
			l.Addable = true
			ll = list(ll, l)

			if isdirectiface(n.Left.Type) {
				/* For pointer types, we can make a special form of optimization
				 *
				 * These statements are put onto the expression init list:
				 * 	Itab *tab = atomicloadtype(&cache);
				 * 	if(tab == nil)
				 * 		tab = typ2Itab(type, itype, &cache);
				 *
				 * The CONVIFACE expression is replaced with this:
				 * 	OEFACE{tab, ptr};
				 */
				l := temp(Ptrto(Types[TUINT8]))

				n1 := Nod(OAS, l, sym.Def)
				typecheck(&n1, Etop)
				*init = list(*init, n1)

				fn := syslook("typ2Itab", 1)
				n1 = Nod(OCALL, fn, nil)
				n1.List = ll
				typecheck(&n1, Erv)
				walkexpr(&n1, init)

				n2 := Nod(OIF, nil, nil)
				n2.Left = Nod(OEQ, l, nodnil())
				n2.Nbody = list1(Nod(OAS, l, n1))
				n2.Likely = -1
				typecheck(&n2, Etop)
				*init = list(*init, n2)

				l = Nod(OEFACE, l, n.Left)
				l.Typecheck = n.Typecheck
				l.Type = n.Type
				n = l
				goto ret
			}
		}

		if Isinter(n.Left.Type) {
			ll = list(ll, n.Left)
		} else {
			// regular types are passed by reference to avoid C vararg calls
			// orderexpr arranged for n.Left to be a temporary for all
			// the conversions it could see. comparison of an interface
			// with a non-interface, especially in a switch on interface value
			// with non-interface cases, is not visible to orderstmt, so we
			// have to fall back on allocating a temp here.
			if islvalue(n.Left) {
				ll = list(ll, Nod(OADDR, n.Left, nil))
			} else {
				ll = list(ll, Nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil))
			}
			dowidth(n.Left.Type)
			r := nodnil()
			if n.Esc == EscNone && n.Left.Type.Width <= 1024 {
				// Allocate stack buffer for value stored in interface.
				r = temp(n.Left.Type)
				r = Nod(OAS, r, nil) // zero temp
				typecheck(&r, Etop)
				*init = list(*init, r)
				r = Nod(OADDR, r.Left, nil)
				typecheck(&r, Erv)
			}
			ll = list(ll, r)
		}

		if !Isinter(n.Left.Type) {
			substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
		} else {
			substArgTypes(fn, n.Left.Type, n.Type)
		}
		dowidth(fn.Type)
		n = Nod(OCALL, fn, nil)
		n.List = ll
		typecheck(&n, Erv)
		walkexpr(&n, init)
		goto ret

	case OCONV, OCONVNOP:
		if Thearch.Thechar == '5' {
			if Isfloat[n.Left.Type.Etype] {
				if n.Type.Etype == TINT64 {
					n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
					goto ret
				}

				if n.Type.Etype == TUINT64 {
					n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
					goto ret
				}
			}

			if Isfloat[n.Type.Etype] {
				if n.Left.Type.Etype == TINT64 {
					n = mkcall("int64tofloat64", n.Type, init, conv(n.Left, Types[TINT64]))
					goto ret
				}

				if n.Left.Type.Etype == TUINT64 {
					n = mkcall("uint64tofloat64", n.Type, init, conv(n.Left, Types[TUINT64]))
					goto ret
				}
			}
		}

		walkexpr(&n.Left, init)
		goto ret

	case OANDNOT:
		walkexpr(&n.Left, init)
		n.Op = OAND
		n.Right = Nod(OCOM, n.Right, nil)
		typecheck(&n.Right, Erv)
		walkexpr(&n.Right, init)
		goto ret

	case OMUL:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)
		walkmul(&n, init)
		goto ret

	case ODIV, OMOD:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)

		/*
		 * rewrite complex div into function call.
		 */
		et := int(n.Left.Type.Etype)

		if Iscomplex[et] && n.Op == ODIV {
			t := n.Type
			n = mkcall("complex128div", Types[TCOMPLEX128], init, conv(n.Left, Types[TCOMPLEX128]), conv(n.Right, Types[TCOMPLEX128]))
			n = conv(n, t)
			goto ret
		}

		// Nothing to do for float divisions.
		if Isfloat[et] {
			goto ret
		}

		// Try rewriting as shifts or magic multiplies.
		walkdiv(&n, init)

		/*
		 * rewrite 64-bit div and mod into function calls
		 * on 32-bit architectures.
		 */
		switch n.Op {
		case OMOD, ODIV:
			if Widthreg >= 8 || (et != TUINT64 && et != TINT64) {
				goto ret
			}
			var fn string
			if et == TINT64 {
				fn = "int64"
			} else {
				fn = "uint64"
			}
			if n.Op == ODIV {
				fn += "div"
			} else {
				fn += "mod"
			}
			n = mkcall(fn, n.Type, init, conv(n.Left, Types[et]), conv(n.Right, Types[et]))

		default:
			break
		}

		goto ret

	case OINDEX:
		walkexpr(&n.Left, init)

		// save the original node for bounds checking elision.
		// If it was a ODIV/OMOD walk might rewrite it.
		r := n.Right

		walkexpr(&n.Right, init)

		// if range of type cannot exceed static array bound,
		// disable bounds check.
		if n.Bounded {
			goto ret
		}
		t := n.Left.Type
		if t != nil && Isptr[t.Etype] {
			t = t.Type
		}
		if Isfixedarray(t) {
			n.Bounded = bounded(r, t.Bound)
			if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) {
				Warn("index bounds check elided")
			}
			if Smallintconst(n.Right) && !n.Bounded {
				Yyerror("index out of bounds")
			}
		} else if Isconst(n.Left, CTSTR) {
			n.Bounded = bounded(r, int64(len(n.Left.Val().U.(string))))
			if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) {
				Warn("index bounds check elided")
			}
			if Smallintconst(n.Right) {
				if !n.Bounded {
					Yyerror("index out of bounds")
				} else {
					// replace "abc"[1] with 'b'.
					// delayed until now because "abc"[1] is not
					// an ideal constant.
					v := Mpgetfix(n.Right.Val().U.(*Mpint))

					Nodconst(n, n.Type, int64(n.Left.Val().U.(string)[v]))
					n.Typecheck = 1
				}
			}
		}

		if Isconst(n.Right, CTINT) {
			if Mpcmpfixfix(n.Right.Val().U.(*Mpint), &mpzero) < 0 || Mpcmpfixfix(n.Right.Val().U.(*Mpint), Maxintval[TINT]) > 0 {
				Yyerror("index out of bounds")
			}
		}
		goto ret

	case OINDEXMAP:
		if n.Etype == 1 {
			goto ret
		}
		walkexpr(&n.Left, init)
		walkexpr(&n.Right, init)

		t := n.Left.Type
		p := ""
		if t.Type.Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing.
			switch Simsimtype(t.Down) {
			case TINT32, TUINT32:
				p = "mapaccess1_fast32"

			case TINT64, TUINT64:
				p = "mapaccess1_fast64"

			case TSTRING:
				p = "mapaccess1_faststr"
			}
		}

		var key *Node
		if p != "" {
			// fast versions take key by value
			key = n.Right
		} else {
			// standard version takes key by reference.
			// orderexpr made sure key is addressable.
			key = Nod(OADDR, n.Right, nil)

			p = "mapaccess1"
		}

		n = mkcall1(mapfn(p, t), Ptrto(t.Type), init, typename(t), n.Left, key)
		n = Nod(OIND, n, nil)
		n.Type = t.Type
		n.Typecheck = 1

		goto ret

	case ORECV:
		Fatalf("walkexpr ORECV") // should see inside OAS only

	case OSLICE, OSLICEARR, OSLICESTR:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right.Left, init)
		if n.Right.Left != nil && iszero(n.Right.Left) {
			// Reduce x[0:j] to x[:j].
			n.Right.Left = nil
		}
		walkexpr(&n.Right.Right, init)
		n = reduceSlice(n)
		goto ret

	case OSLICE3, OSLICE3ARR:
		walkexpr(&n.Left, init)
		walkexpr(&n.Right.Left, init)
		if n.Right.Left != nil && iszero(n.Right.Left) {
			// Reduce x[0:j:k] to x[:j:k].
			n.Right.Left = nil
		}
		walkexpr(&n.Right.Right.Left, init)
		walkexpr(&n.Right.Right.Right, init)

		r := n.Right.Right.Right
		if r != nil && r.Op == OCAP && samesafeexpr(n.Left, r.Left) {
			// Reduce x[i:j:cap(x)] to x[i:j].
			n.Right.Right = n.Right.Right.Left
			if n.Op == OSLICE3 {
				n.Op = OSLICE
			} else {
				n.Op = OSLICEARR
			}
			n = reduceSlice(n)
			goto ret
		}
		goto ret

	case OADDR:
		walkexpr(&n.Left, init)
		goto ret

	case ONEW:
		if n.Esc == EscNone {
			if n.Type.Type.Width >= 1<<16 {
				Fatalf("large ONEW with EscNone: %v", n)
			}
			r := temp(n.Type.Type)
			r = Nod(OAS, r, nil) // zero temp
			typecheck(&r, Etop)
			*init = list(*init, r)
			r = Nod(OADDR, r.Left, nil)
			typecheck(&r, Erv)
			n = r
		} else {
			n = callnew(n.Type.Type)
		}

		goto ret

		// If one argument to the comparison is an empty string,
	// comparing the lengths instead will yield the same result
	// without the function call.
	case OCMPSTR:
		if (Isconst(n.Left, CTSTR) && len(n.Left.Val().U.(string)) == 0) || (Isconst(n.Right, CTSTR) && len(n.Right.Val().U.(string)) == 0) {
			r := Nod(int(n.Etype), Nod(OLEN, n.Left, nil), Nod(OLEN, n.Right, nil))
			typecheck(&r, Erv)
			walkexpr(&r, init)
			r.Type = n.Type
			n = r
			goto ret
		}

		// s + "badgerbadgerbadger" == "badgerbadgerbadger"
		if (n.Etype == OEQ || n.Etype == ONE) && Isconst(n.Right, CTSTR) && n.Left.Op == OADDSTR && count(n.Left.List) == 2 && Isconst(n.Left.List.Next.N, CTSTR) && cmpslit(n.Right, n.Left.List.Next.N) == 0 {
			r := Nod(int(n.Etype), Nod(OLEN, n.Left.List.N, nil), Nodintconst(0))
			typecheck(&r, Erv)
			walkexpr(&r, init)
			r.Type = n.Type
			n = r
			goto ret
		}

		var r *Node
		if n.Etype == OEQ || n.Etype == ONE {
			// prepare for rewrite below
			n.Left = cheapexpr(n.Left, init)

			n.Right = cheapexpr(n.Right, init)

			r = mkcall("eqstring", Types[TBOOL], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING]))

			// quick check of len before full compare for == or !=
			// eqstring assumes that the lengths are equal
			if n.Etype == OEQ {
				// len(left) == len(right) && eqstring(left, right)
				r = Nod(OANDAND, Nod(OEQ, Nod(OLEN, n.Left, nil), Nod(OLEN, n.Right, nil)), r)
			} else {
				// len(left) != len(right) || !eqstring(left, right)
				r = Nod(ONOT, r, nil)

				r = Nod(OOROR, Nod(ONE, Nod(OLEN, n.Left, nil), Nod(OLEN, n.Right, nil)), r)
			}

			typecheck(&r, Erv)
			walkexpr(&r, nil)
		} else {
			// sys_cmpstring(s1, s2) :: 0
			r = mkcall("cmpstring", Types[TINT], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING]))

			r = Nod(int(n.Etype), r, Nodintconst(0))
		}

		typecheck(&r, Erv)
		if n.Type.Etype != TBOOL {
			Fatalf("cmp %v", n.Type)
		}
		r.Type = n.Type
		n = r
		goto ret

	case OADDSTR:
		n = addstr(n, init)
		goto ret

	case OAPPEND:
		// order should make sure we only see OAS(node, OAPPEND), which we handle above.
		Fatalf("append outside assignment")

	case OCOPY:
		n = copyany(n, init, flag_race)
		goto ret

		// cannot use chanfn - closechan takes any, not chan any
	case OCLOSE:
		fn := syslook("closechan", 1)

		substArgTypes(fn, n.Left.Type)
		n = mkcall1(fn, nil, init, n.Left)
		goto ret

	case OMAKECHAN:
		n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]))
		goto ret

	case OMAKEMAP:
		t := n.Type

		fn := syslook("makemap", 1)

		a := nodnil() // hmap buffer
		r := nodnil() // bucket buffer
		if n.Esc == EscNone {
			// Allocate hmap buffer on stack.
			var_ := temp(hmap(t))

			a = Nod(OAS, var_, nil) // zero temp
			typecheck(&a, Etop)
			*init = list(*init, a)
			a = Nod(OADDR, var_, nil)

			// Allocate one bucket on stack.
			// Maximum key/value size is 128 bytes, larger objects
			// are stored with an indirection. So max bucket size is 2048+eps.
			var_ = temp(mapbucket(t))

			r = Nod(OAS, var_, nil) // zero temp
			typecheck(&r, Etop)
			*init = list(*init, r)
			r = Nod(OADDR, var_, nil)
		}

		substArgTypes(fn, hmap(t), mapbucket(t), t.Down, t.Type)
		n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
		goto ret

	case OMAKESLICE:
		l := n.Left
		r := n.Right
		if r == nil {
			r = safeexpr(l, init)
			l = r
		}
		t := n.Type
		if n.Esc == EscNone {
			if !isSmallMakeSlice(n) {
				Fatalf("non-small OMAKESLICE with EscNone: %v", n)
			}
			// var arr [r]T
			// n = arr[:l]
			t = aindex(r, t.Type) // [r]T
			var_ := temp(t)
			a := Nod(OAS, var_, nil) // zero temp
			typecheck(&a, Etop)
			*init = list(*init, a)
			r := Nod(OSLICE, var_, Nod(OKEY, nil, l)) // arr[:l]
			r = conv(r, n.Type)                       // in case n.Type is named.
			typecheck(&r, Erv)
			walkexpr(&r, init)
			n = r
		} else {
			// makeslice(t *Type, nel int64, max int64) (ary []any)
			fn := syslook("makeslice", 1)

			substArgTypes(fn, t.Type) // any-1
			n = mkcall1(fn, n.Type, init, typename(n.Type), conv(l, Types[TINT64]), conv(r, Types[TINT64]))
		}

		goto ret

	case ORUNESTR:
		a := nodnil()
		if n.Esc == EscNone {
			t := aindex(Nodintconst(4), Types[TUINT8])
			var_ := temp(t)
			a = Nod(OADDR, var_, nil)
		}

		// intstring(*[4]byte, rune)
		n = mkcall("intstring", n.Type, init, a, conv(n.Left, Types[TINT64]))

		goto ret

	case OARRAYBYTESTR:
		a := nodnil()
		if n.Esc == EscNone {
			// Create temporary buffer for string on stack.
			t := aindex(Nodintconst(tmpstringbufsize), Types[TUINT8])

			a = Nod(OADDR, temp(t), nil)
		}

		// slicebytetostring(*[32]byte, []byte) string;
		n = mkcall("slicebytetostring", n.Type, init, a, n.Left)

		goto ret

		// slicebytetostringtmp([]byte) string;
	case OARRAYBYTESTRTMP:
		n = mkcall("slicebytetostringtmp", n.Type, init, n.Left)

		goto ret

		// slicerunetostring(*[32]byte, []rune) string;
	case OARRAYRUNESTR:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for string on stack.
			t := aindex(Nodintconst(tmpstringbufsize), Types[TUINT8])

			a = Nod(OADDR, temp(t), nil)
		}

		n = mkcall("slicerunetostring", n.Type, init, a, n.Left)
		goto ret

		// stringtoslicebyte(*32[byte], string) []byte;
	case OSTRARRAYBYTE:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for slice on stack.
			t := aindex(Nodintconst(tmpstringbufsize), Types[TUINT8])

			a = Nod(OADDR, temp(t), nil)
		}

		n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING]))
		goto ret

		// stringtoslicebytetmp(string) []byte;
	case OSTRARRAYBYTETMP:
		n = mkcall("stringtoslicebytetmp", n.Type, init, conv(n.Left, Types[TSTRING]))

		goto ret

		// stringtoslicerune(*[32]rune, string) []rune
	case OSTRARRAYRUNE:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for slice on stack.
			t := aindex(Nodintconst(tmpstringbufsize), Types[TINT32])

			a = Nod(OADDR, temp(t), nil)
		}

		n = mkcall("stringtoslicerune", n.Type, init, a, n.Left)
		goto ret

		// ifaceeq(i1 any-1, i2 any-2) (ret bool);
	case OCMPIFACE:
		if !Eqtype(n.Left.Type, n.Right.Type) {
			Fatalf("ifaceeq %v %v %v", Oconv(int(n.Op), 0), n.Left.Type, n.Right.Type)
		}
		var fn *Node
		if isnilinter(n.Left.Type) {
			fn = syslook("efaceeq", 1)
		} else {
			fn = syslook("ifaceeq", 1)
		}

		n.Right = cheapexpr(n.Right, init)
		n.Left = cheapexpr(n.Left, init)
		substArgTypes(fn, n.Right.Type, n.Left.Type)
		r := mkcall1(fn, n.Type, init, n.Left, n.Right)
		if n.Etype == ONE {
			r = Nod(ONOT, r, nil)
		}

		// check itable/type before full compare.
		if n.Etype == OEQ {
			r = Nod(OANDAND, Nod(OEQ, Nod(OITAB, n.Left, nil), Nod(OITAB, n.Right, nil)), r)
		} else {
			r = Nod(OOROR, Nod(ONE, Nod(OITAB, n.Left, nil), Nod(OITAB, n.Right, nil)), r)
		}
		typecheck(&r, Erv)
		walkexpr(&r, init)
		r.Type = n.Type
		n = r
		goto ret

	case OARRAYLIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
		var_ := temp(n.Type)
		anylit(0, n, var_, init)
		n = var_
		goto ret

	case OSEND:
		n1 := n.Right
		n1 = assignconv(n1, n.Left.Type.Type, "chan send")
		walkexpr(&n1, init)
		n1 = Nod(OADDR, n1, nil)
		n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, typename(n.Left.Type), n.Left, n1)
		goto ret

	case OCLOSURE:
		n = walkclosure(n, init)
		goto ret

	case OCALLPART:
		n = walkpartialcall(n, init)
		goto ret
	}

	Fatalf("missing switch %v", Oconv(int(n.Op), 0))

	// Expressions that are constant at run time but not
	// considered const by the language spec are not turned into
	// constants until walk. For example, if n is y%1 == 0, the
	// walk of y%1 may have replaced it by 0.
	// Check whether n with its updated args is itself now a constant.
ret:
	t := n.Type

	evconst(n)
	n.Type = t
	if n.Op == OLITERAL {
		typecheck(&n, Erv)
	}

	ullmancalc(n)

	if Debug['w'] != 0 && n != nil {
		Dump("walk", n)
	}

	lineno = lno
	*np = n
}

func reduceSlice(n *Node) *Node {
	r := n.Right.Right
	if r != nil && r.Op == OLEN && samesafeexpr(n.Left, r.Left) {
		// Reduce x[i:len(x)] to x[i:].
		n.Right.Right = nil
	}
	if (n.Op == OSLICE || n.Op == OSLICESTR) && n.Right.Left == nil && n.Right.Right == nil {
		// Reduce x[:] to x.
		if Debug_slice > 0 {
			Warn("slice: omit slice operation")
		}
		return n.Left
	}
	return n
}

func ascompatee1(op int, l *Node, r *Node, init **NodeList) *Node {
	// convas will turn map assigns into function calls,
	// making it impossible for reorder3 to work.
	n := Nod(OAS, l, r)

	if l.Op == OINDEXMAP {
		return n
	}

	return convas(n, init)
}

func ascompatee(op int, nl *NodeList, nr *NodeList, init **NodeList) *NodeList {
	/*
	 * check assign expression list to
	 * a expression list. called in
	 *	expr-list = expr-list
	 */

	// ensure order of evaluation for function calls
	for ll := nl; ll != nil; ll = ll.Next {
		ll.N = safeexpr(ll.N, init)
	}
	for lr := nr; lr != nil; lr = lr.Next {
		lr.N = safeexpr(lr.N, init)
	}

	var nn *NodeList
	ll := nl
	lr := nr
	for ; ll != nil && lr != nil; ll, lr = ll.Next, lr.Next {
		// Do not generate 'x = x' during return. See issue 4014.
		if op == ORETURN && ll.N == lr.N {
			continue
		}
		nn = list(nn, ascompatee1(op, ll.N, lr.N, init))
	}

	// cannot happen: caller checked that lists had same length
	if ll != nil || lr != nil {
		Yyerror("error in shape across %v %v %v / %d %d [%s]", Hconv(nl, obj.FmtSign), Oconv(int(op), 0), Hconv(nr, obj.FmtSign), count(nl), count(nr), Curfn.Func.Nname.Sym.Name)
	}
	return nn
}

/*
 * l is an lv and rt is the type of an rv
 * return 1 if this implies a function call
 * evaluating the lv or a function call
 * in the conversion of the types
 */
func fncall(l *Node, rt *Type) bool {
	if l.Ullman >= UINF || l.Op == OINDEXMAP {
		return true
	}
	var r Node
	if needwritebarrier(l, &r) {
		return true
	}
	if Eqtype(l.Type, rt) {
		return false
	}
	return true
}

func ascompatet(op int, nl *NodeList, nr **Type, fp int, init **NodeList) *NodeList {
	var l *Node
	var tmp *Node
	var a *Node
	var ll *NodeList
	var saver Iter

	/*
	 * check assign type list to
	 * a expression list. called in
	 *	expr-list = func()
	 */
	r := Structfirst(&saver, nr)

	var nn *NodeList
	var mm *NodeList
	ucount := 0
	for ll = nl; ll != nil; ll = ll.Next {
		if r == nil {
			break
		}
		l = ll.N
		if isblank(l) {
			r = structnext(&saver)
			continue
		}

		// any lv that causes a fn call must be
		// deferred until all the return arguments
		// have been pulled from the output arguments
		if fncall(l, r.Type) {
			tmp = temp(r.Type)
			typecheck(&tmp, Erv)
			a = Nod(OAS, l, tmp)
			a = convas(a, init)
			mm = list(mm, a)
			l = tmp
		}

		a = Nod(OAS, l, nodarg(r, fp))
		a = convas(a, init)
		ullmancalc(a)
		if a.Ullman >= UINF {
			Dump("ascompatet ucount", a)
			ucount++
		}

		nn = list(nn, a)
		r = structnext(&saver)
	}

	if ll != nil || r != nil {
		Yyerror("ascompatet: assignment count mismatch: %d = %d", count(nl), structcount(*nr))
	}

	if ucount != 0 {
		Fatalf("ascompatet: too many function calls evaluating parameters")
	}
	return concat(nn, mm)
}

/*
* package all the arguments that match a ... T parameter into a []T.
 */
func mkdotargslice(lr0 *NodeList, nn *NodeList, l *Type, fp int, init **NodeList, ddd *Node) *NodeList {
	esc := uint16(EscUnknown)
	if ddd != nil {
		esc = ddd.Esc
	}

	tslice := typ(TARRAY)
	tslice.Type = l.Type.Type
	tslice.Bound = -1

	var n *Node
	if count(lr0) == 0 {
		n = nodnil()
		n.Type = tslice
	} else {
		n = Nod(OCOMPLIT, nil, typenod(tslice))
		if ddd != nil && prealloc[ddd] != nil {
			prealloc[n] = prealloc[ddd] // temporary to use
		}
		n.List = lr0
		n.Esc = esc
		typecheck(&n, Erv)
		if n.Type == nil {
			Fatalf("mkdotargslice: typecheck failed")
		}
		walkexpr(&n, init)
	}

	a := Nod(OAS, nodarg(l, fp), n)
	nn = list(nn, convas(a, init))
	return nn
}

/*
 * helpers for shape errors
 */
func dumptypes(nl **Type, what string) string {
	var savel Iter

	fmt_ := ""
	fmt_ += "\t"
	first := 1
	for l := Structfirst(&savel, nl); l != nil; l = structnext(&savel) {
		if first != 0 {
			first = 0
		} else {
			fmt_ += ", "
		}
		fmt_ += Tconv(l, 0)
	}

	if first != 0 {
		fmt_ += fmt.Sprintf("[no arguments %s]", what)
	}
	return fmt_
}

func dumpnodetypes(l *NodeList, what string) string {
	var r *Node

	fmt_ := ""
	fmt_ += "\t"
	first := 1
	for ; l != nil; l = l.Next {
		r = l.N
		if first != 0 {
			first = 0
		} else {
			fmt_ += ", "
		}
		fmt_ += Tconv(r.Type, 0)
	}

	if first != 0 {
		fmt_ += fmt.Sprintf("[no arguments %s]", what)
	}
	return fmt_
}

/*
 * check assign expression list to
 * a type list. called in
 *	return expr-list
 *	func(expr-list)
 */
func ascompatte(op int, call *Node, isddd bool, nl **Type, lr *NodeList, fp int, init **NodeList) *NodeList {
	var savel Iter

	lr0 := lr
	l := Structfirst(&savel, nl)
	var r *Node
	if lr != nil {
		r = lr.N
	}
	var nn *NodeList

	// f(g()) where g has multiple return values
	var a *Node
	var l2 string
	var ll *Type
	var l1 string
	if r != nil && lr.Next == nil && r.Type.Etype == TSTRUCT && r.Type.Funarg {
		// optimization - can do block copy
		if eqtypenoname(r.Type, *nl) {
			a := nodarg(*nl, fp)
			r = Nod(OCONVNOP, r, nil)
			r.Type = a.Type
			nn = list1(convas(Nod(OAS, a, r), init))
			goto ret
		}

		// conversions involved.
		// copy into temporaries.
		var alist *NodeList

		for l := Structfirst(&savel, &r.Type); l != nil; l = structnext(&savel) {
			a = temp(l.Type)
			alist = list(alist, a)
		}

		a = Nod(OAS2, nil, nil)
		a.List = alist
		a.Rlist = lr
		typecheck(&a, Etop)
		walkstmt(&a)
		*init = list(*init, a)
		lr = alist
		r = lr.N
		l = Structfirst(&savel, nl)
	}

loop:
	if l != nil && l.Isddd {
		// the ddd parameter must be last
		ll = structnext(&savel)

		if ll != nil {
			Yyerror("... must be last argument")
		}

		// special case --
		// only if we are assigning a single ddd
		// argument to a ddd parameter then it is
		// passed thru unencapsulated
		if r != nil && lr.Next == nil && isddd && Eqtype(l.Type, r.Type) {
			a = Nod(OAS, nodarg(l, fp), r)
			a = convas(a, init)
			nn = list(nn, a)
			goto ret
		}

		// normal case -- make a slice of all
		// remaining arguments and pass it to
		// the ddd parameter.
		nn = mkdotargslice(lr, nn, l, fp, init, call.Right)

		goto ret
	}

	if l == nil || r == nil {
		if l != nil || r != nil {
			l1 = dumptypes(nl, "expected")
			l2 = dumpnodetypes(lr0, "given")
			if l != nil {
				Yyerror("not enough arguments to %v\n%s\n%s", Oconv(int(op), 0), l1, l2)
			} else {
				Yyerror("too many arguments to %v\n%s\n%s", Oconv(int(op), 0), l1, l2)
			}
		}

		goto ret
	}

	a = Nod(OAS, nodarg(l, fp), r)
	a = convas(a, init)
	nn = list(nn, a)

	l = structnext(&savel)
	r = nil
	lr = lr.Next
	if lr != nil {
		r = lr.N
	}
	goto loop

ret:
	for lr = nn; lr != nil; lr = lr.Next {
		lr.N.Typecheck = 1
	}
	return nn
}

// generate code for print
func walkprint(nn *Node, init **NodeList) *Node {
	var r *Node
	var n *Node
	var on *Node
	var t *Type
	var et int

	op := int(nn.Op)
	all := nn.List
	var calls *NodeList
	notfirst := false

	// Hoist all the argument evaluation up before the lock.
	walkexprlistcheap(all, init)

	calls = list(calls, mkcall("printlock", nil, init))

	for l := all; l != nil; l = l.Next {
		if notfirst {
			calls = list(calls, mkcall("printsp", nil, init))
		}

		notfirst = op == OPRINTN

		n = l.N
		if n.Op == OLITERAL {
			switch n.Val().Ctype() {
			case CTRUNE:
				defaultlit(&n, runetype)

			case CTINT:
				defaultlit(&n, Types[TINT64])

			case CTFLT:
				defaultlit(&n, Types[TFLOAT64])
			}
		}

		if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL {
			defaultlit(&n, Types[TINT64])
		}
		defaultlit(&n, nil)
		l.N = n
		if n.Type == nil || n.Type.Etype == TFORW {
			continue
		}

		t = n.Type
		et = int(n.Type.Etype)
		if Isinter(n.Type) {
			if isnilinter(n.Type) {
				on = syslook("printeface", 1)
			} else {
				on = syslook("printiface", 1)
			}
			substArgTypes(on, n.Type) // any-1
		} else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
			on = syslook("printpointer", 1)
			substArgTypes(on, n.Type) // any-1
		} else if Isslice(n.Type) {
			on = syslook("printslice", 1)
			substArgTypes(on, n.Type) // any-1
		} else if Isint[et] {
			if et == TUINT64 {
				if (t.Sym.Pkg == Runtimepkg || compiling_runtime != 0) && t.Sym.Name == "hex" {
					on = syslook("printhex", 0)
				} else {
					on = syslook("printuint", 0)
				}
			} else {
				on = syslook("printint", 0)
			}
		} else if Isfloat[et] {
			on = syslook("printfloat", 0)
		} else if Iscomplex[et] {
			on = syslook("printcomplex", 0)
		} else if et == TBOOL {
			on = syslook("printbool", 0)
		} else if et == TSTRING {
			on = syslook("printstring", 0)
		} else {
			badtype(OPRINT, n.Type, nil)
			continue
		}

		t = *getinarg(on.Type)
		if t != nil {
			t = t.Type
		}
		if t != nil {
			t = t.Type
		}

		if !Eqtype(t, n.Type) {
			n = Nod(OCONV, n, nil)
			n.Type = t
		}

		r = Nod(OCALL, on, nil)
		r.List = list1(n)
		calls = list(calls, r)
	}

	if op == OPRINTN {
		calls = list(calls, mkcall("printnl", nil, nil))
	}

	calls = list(calls, mkcall("printunlock", nil, init))

	typechecklist(calls, Etop)
	walkexprlist(calls, init)

	r = Nod(OEMPTY, nil, nil)
	typecheck(&r, Etop)
	walkexpr(&r, init)
	r.Ninit = calls
	return r
}

func callnew(t *Type) *Node {
	dowidth(t)
	fn := syslook("newobject", 1)
	substArgTypes(fn, t)
	return mkcall1(fn, Ptrto(t), nil, typename(t))
}

func iscallret(n *Node) bool {
	n = outervalue(n)
	return n.Op == OINDREG && n.Reg == int16(Thearch.REGSP)
}

func isstack(n *Node) bool {
	n = outervalue(n)

	// If n is *autotmp and autotmp = &foo, replace n with foo.
	// We introduce such temps when initializing struct literals.
	if n.Op == OIND && n.Left.Op == ONAME && strings.HasPrefix(n.Left.Sym.Name, "autotmp_") {
		defn := n.Left.Name.Defn
		if defn != nil && defn.Op == OAS && defn.Right.Op == OADDR {
			n = defn.Right.Left
		}
	}

	switch n.Op {
	case OINDREG:
		return n.Reg == int16(Thearch.REGSP)

	case ONAME:
		switch n.Class {
		case PAUTO, PPARAM, PPARAMOUT:
			return true
		}
	}

	return false
}

func isglobal(n *Node) bool {
	n = outervalue(n)

	switch n.Op {
	case ONAME:
		switch n.Class {
		case PEXTERN:
			return true
		}
	}

	return false
}

// Do we need a write barrier for the assignment l = r?
func needwritebarrier(l *Node, r *Node) bool {
	if use_writebarrier == 0 {
		return false
	}

	if l == nil || isblank(l) {
		return false
	}

	// No write barrier for write of non-pointers.
	dowidth(l.Type)

	if !haspointers(l.Type) {
		return false
	}

	// No write barrier for write to stack.
	if isstack(l) {
		return false
	}

	// No write barrier for implicit zeroing.
	if r == nil {
		return false
	}

	// Ignore no-op conversions when making decision.
	// Ensures that xp = unsafe.Pointer(&x) is treated
	// the same as xp = &x.
	for r.Op == OCONVNOP {
		r = r.Left
	}

	// No write barrier for zeroing or initialization to constant.
	if iszero(r) || r.Op == OLITERAL {
		return false
	}

	// No write barrier for storing static (read-only) data.
	if r.Op == ONAME && strings.HasPrefix(r.Sym.Name, "statictmp_") {
		return false
	}

	// No write barrier for storing address of stack values,
	// which are guaranteed only to be written to the stack.
	if r.Op == OADDR && isstack(r.Left) {
		return false
	}

	// No write barrier for storing address of global, which
	// is live no matter what.
	if r.Op == OADDR && isglobal(r.Left) {
		return false
	}

	// Otherwise, be conservative and use write barrier.
	return true
}

// TODO(rsc): Perhaps componentgen should run before this.

var applywritebarrier_bv Bvec

func applywritebarrier(n *Node, init **NodeList) *Node {
	if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) {
		if Debug_wb > 1 {
			Warnl(int(n.Lineno), "marking %v for barrier", Nconv(n.Left, 0))
		}
		n.Op = OASWB
		return n
	}
	return n
}

func convas(n *Node, init **NodeList) *Node {
	if n.Op != OAS {
		Fatalf("convas: not OAS %v", Oconv(int(n.Op), 0))
	}

	n.Typecheck = 1

	var lt *Type
	var rt *Type
	if n.Left == nil || n.Right == nil {
		goto out
	}

	lt = n.Left.Type
	rt = n.Right.Type
	if lt == nil || rt == nil {
		goto out
	}

	if isblank(n.Left) {
		defaultlit(&n.Right, nil)
		goto out
	}

	if n.Left.Op == OINDEXMAP {
		map_ := n.Left.Left
		key := n.Left.Right
		val := n.Right
		walkexpr(&map_, init)
		walkexpr(&key, init)
		walkexpr(&val, init)

		// orderexpr made sure key and val are addressable.
		key = Nod(OADDR, key, nil)

		val = Nod(OADDR, val, nil)
		n = mkcall1(mapfn("mapassign1", map_.Type), nil, init, typename(map_.Type), map_, key, val)
		goto out
	}

	if !Eqtype(lt, rt) {
		n.Right = assignconv(n.Right, lt, "assignment")
		walkexpr(&n.Right, init)
	}

out:
	ullmancalc(n)
	return n
}

/*
 * from ascompat[te]
 * evaluating actual function arguments.
 *	f(a,b)
 * if there is exactly one function expr,
 * then it is done first. otherwise must
 * make temp variables
 */
func reorder1(all *NodeList) *NodeList {
	var n *Node

	c := 0 // function calls
	t := 0 // total parameters

	for l := all; l != nil; l = l.Next {
		n = l.N
		t++
		ullmancalc(n)
		if n.Ullman >= UINF {
			c++
		}
	}

	if c == 0 || t == 1 {
		return all
	}

	var g *NodeList // fncalls assigned to tempnames
	var f *Node     // last fncall assigned to stack
	var r *NodeList // non fncalls and tempnames assigned to stack
	d := 0
	var a *Node
	for l := all; l != nil; l = l.Next {
		n = l.N
		if n.Ullman < UINF {
			r = list(r, n)
			continue
		}

		d++
		if d == c {
			f = n
			continue
		}

		// make assignment of fncall to tempname
		a = temp(n.Right.Type)

		a = Nod(OAS, a, n.Right)
		g = list(g, a)

		// put normal arg assignment on list
		// with fncall replaced by tempname
		n.Right = a.Left

		r = list(r, n)
	}

	if f != nil {
		g = list(g, f)
	}
	return concat(g, r)
}

/*
 * from ascompat[ee]
 *	a,b = c,d
 * simultaneous assignment. there cannot
 * be later use of an earlier lvalue.
 *
 * function calls have been removed.
 */
func reorder3(all *NodeList) *NodeList {
	var l *Node

	// If a needed expression may be affected by an
	// earlier assignment, make an early copy of that
	// expression and use the copy instead.
	var early *NodeList

	var mapinit *NodeList
	for list := all; list != nil; list = list.Next {
		l = list.N.Left

		// Save subexpressions needed on left side.
		// Drill through non-dereferences.
		for {
			if l.Op == ODOT || l.Op == OPAREN {
				l = l.Left
				continue
			}

			if l.Op == OINDEX && Isfixedarray(l.Left.Type) {
				reorder3save(&l.Right, all, list, &early)
				l = l.Left
				continue
			}

			break
		}

		switch l.Op {
		default:
			Fatalf("reorder3 unexpected lvalue %v", Oconv(int(l.Op), obj.FmtSharp))

		case ONAME:
			break

		case OINDEX, OINDEXMAP:
			reorder3save(&l.Left, all, list, &early)
			reorder3save(&l.Right, all, list, &early)
			if l.Op == OINDEXMAP {
				list.N = convas(list.N, &mapinit)
			}

		case OIND, ODOTPTR:
			reorder3save(&l.Left, all, list, &early)
		}

		// Save expression on right side.
		reorder3save(&list.N.Right, all, list, &early)
	}

	early = concat(mapinit, early)
	return concat(early, all)
}

/*
 * if the evaluation of *np would be affected by the
 * assignments in all up to but not including stop,
 * copy into a temporary during *early and
 * replace *np with that temp.
 */
func reorder3save(np **Node, all *NodeList, stop *NodeList, early **NodeList) {
	n := *np
	if !aliased(n, all, stop) {
		return
	}

	q := temp(n.Type)
	q = Nod(OAS, q, n)
	typecheck(&q, Etop)
	*early = list(*early, q)
	*np = q.Left
}

/*
 * what's the outer value that a write to n affects?
 * outer value means containing struct or array.
 */
func outervalue(n *Node) *Node {
	for {
		if n.Op == OXDOT {
			Fatalf("OXDOT in walk")
		}
		if n.Op == ODOT || n.Op == OPAREN || n.Op == OCONVNOP {
			n = n.Left
			continue
		}

		if n.Op == OINDEX && Isfixedarray(n.Left.Type) {
			n = n.Left
			continue
		}

		break
	}

	return n
}

/*
 * Is it possible that the computation of n might be
 * affected by writes in as up to but not including stop?
 */
func aliased(n *Node, all *NodeList, stop *NodeList) bool {
	if n == nil {
		return false
	}

	// Look for obvious aliasing: a variable being assigned
	// during the all list and appearing in n.
	// Also record whether there are any writes to main memory.
	// Also record whether there are any writes to variables
	// whose addresses have been taken.
	memwrite := 0

	varwrite := 0
	var a *Node
	for l := all; l != stop; l = l.Next {
		a = outervalue(l.N.Left)
		if a.Op != ONAME {
			memwrite = 1
			continue
		}

		switch n.Class {
		default:
			varwrite = 1
			continue

		case PAUTO, PPARAM, PPARAMOUT:
			if n.Addrtaken {
				varwrite = 1
				continue
			}

			if vmatch2(a, n) {
				// Direct hit.
				return true
			}
		}
	}

	// The variables being written do not appear in n.
	// However, n might refer to computed addresses
	// that are being written.

	// If no computed addresses are affected by the writes, no aliasing.
	if memwrite == 0 && varwrite == 0 {
		return false
	}

	// If n does not refer to computed addresses
	// (that is, if n only refers to variables whose addresses
	// have not been taken), no aliasing.
	if varexpr(n) {
		return false
	}

	// Otherwise, both the writes and n refer to computed memory addresses.
	// Assume that they might conflict.
	return true
}

/*
 * does the evaluation of n only refer to variables
 * whose addresses have not been taken?
 * (and no other memory)
 */
func varexpr(n *Node) bool {
	if n == nil {
		return true
	}

	switch n.Op {
	case OLITERAL:
		return true

	case ONAME:
		switch n.Class {
		case PAUTO, PPARAM, PPARAMOUT:
			if !n.Addrtaken {
				return true
			}
		}

		return false

	case OADD,
		OSUB,
		OOR,
		OXOR,
		OMUL,
		ODIV,
		OMOD,
		OLSH,
		ORSH,
		OAND,
		OANDNOT,
		OPLUS,
		OMINUS,
		OCOM,
		OPAREN,
		OANDAND,
		OOROR,
		ODOT, // but not ODOTPTR
		OCONV,
		OCONVNOP,
		OCONVIFACE,
		ODOTTYPE:
		return varexpr(n.Left) && varexpr(n.Right)
	}

	// Be conservative.
	return false
}

/*
 * is the name l mentioned in r?
 */
func vmatch2(l *Node, r *Node) bool {
	if r == nil {
		return false
	}
	switch r.Op {
	// match each right given left
	case ONAME:
		return l == r

	case OLITERAL:
		return false
	}

	if vmatch2(l, r.Left) {
		return true
	}
	if vmatch2(l, r.Right) {
		return true
	}
	for ll := r.List; ll != nil; ll = ll.Next {
		if vmatch2(l, ll.N) {
			return true
		}
	}
	return false
}

/*
 * is any name mentioned in l also mentioned in r?
 * called by sinit.go
 */
func vmatch1(l *Node, r *Node) bool {
	/*
	 * isolate all left sides
	 */
	if l == nil || r == nil {
		return false
	}
	switch l.Op {
	case ONAME:
		switch l.Class {
		case PPARAM, PPARAMREF, PAUTO:
			break

			// assignment to non-stack variable
		// must be delayed if right has function calls.
		default:
			if r.Ullman >= UINF {
				return true
			}
		}

		return vmatch2(l, r)

	case OLITERAL:
		return false
	}

	if vmatch1(l.Left, r) {
		return true
	}
	if vmatch1(l.Right, r) {
		return true
	}
	for ll := l.List; ll != nil; ll = ll.Next {
		if vmatch1(ll.N, r) {
			return true
		}
	}
	return false
}

/*
 * walk through argin parameters.
 * generate and return code to allocate
 * copies of escaped parameters to the heap.
 */
func paramstoheap(argin **Type, out int) *NodeList {
	var savet Iter
	var v *Node
	var as *Node

	var nn *NodeList
	for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
		v = t.Nname
		if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result
			v = nil
		}

		// For precise stacks, the garbage collector assumes results
		// are always live, so zero them always.
		if out != 0 {
			// Defer might stop a panic and show the
			// return values as they exist at the time of panic.
			// Make sure to zero them on entry to the function.
			nn = list(nn, Nod(OAS, nodarg(t, 1), nil))
		}

		if v == nil || v.Class&PHEAP == 0 {
			continue
		}

		// generate allocation & copying code
		if compiling_runtime != 0 {
			Yyerror("%v escapes to heap, not allowed in runtime.", v)
		}
		if prealloc[v] == nil {
			prealloc[v] = callnew(v.Type)
		}
		nn = list(nn, Nod(OAS, v.Name.Heapaddr, prealloc[v]))
		if v.Class&^PHEAP != PPARAMOUT {
			as = Nod(OAS, v, v.Name.Param.Stackparam)
			v.Name.Param.Stackparam.Typecheck = 1
			typecheck(&as, Etop)
			as = applywritebarrier(as, &nn)
			nn = list(nn, as)
		}
	}

	return nn
}

/*
 * walk through argout parameters copying back to stack
 */
func returnsfromheap(argin **Type) *NodeList {
	var savet Iter
	var v *Node

	var nn *NodeList
	for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
		v = t.Nname
		if v == nil || v.Class != PHEAP|PPARAMOUT {
			continue
		}
		nn = list(nn, Nod(OAS, v.Name.Param.Stackparam, v))
	}

	return nn
}

/*
 * take care of migrating any function in/out args
 * between the stack and the heap.  adds code to
 * curfn's before and after lists.
 */
func heapmoves() {
	lno := lineno
	lineno = Curfn.Lineno
	nn := paramstoheap(getthis(Curfn.Type), 0)
	nn = concat(nn, paramstoheap(getinarg(Curfn.Type), 0))
	nn = concat(nn, paramstoheap(Getoutarg(Curfn.Type), 1))
	Curfn.Func.Enter = concat(Curfn.Func.Enter, nn)
	lineno = Curfn.Func.Endlineno
	Curfn.Func.Exit = returnsfromheap(Getoutarg(Curfn.Type))
	lineno = lno
}

func vmkcall(fn *Node, t *Type, init **NodeList, va []*Node) *Node {
	if fn.Type == nil || fn.Type.Etype != TFUNC {
		Fatalf("mkcall %v %v", fn, fn.Type)
	}

	var args *NodeList
	n := fn.Type.Intuple
	for i := 0; i < n; i++ {
		args = list(args, va[i])
	}

	r := Nod(OCALL, fn, nil)
	r.List = args
	if fn.Type.Outtuple > 0 {
		typecheck(&r, Erv|Efnstruct)
	} else {
		typecheck(&r, Etop)
	}
	walkexpr(&r, init)
	r.Type = t
	return r
}

func mkcall(name string, t *Type, init **NodeList, args ...*Node) *Node {
	return vmkcall(syslook(name, 0), t, init, args)
}

func mkcall1(fn *Node, t *Type, init **NodeList, args ...*Node) *Node {
	return vmkcall(fn, t, init, args)
}

func conv(n *Node, t *Type) *Node {
	if Eqtype(n.Type, t) {
		return n
	}
	n = Nod(OCONV, n, nil)
	n.Type = t
	typecheck(&n, Erv)
	return n
}

func chanfn(name string, n int, t *Type) *Node {
	if t.Etype != TCHAN {
		Fatalf("chanfn %v", t)
	}
	fn := syslook(name, 1)
	switch n {
	default:
		Fatalf("chanfn %d", n)
	case 1:
		substArgTypes(fn, t.Type)
	case 2:
		substArgTypes(fn, t.Type, t.Type)
	}
	return fn
}

func mapfn(name string, t *Type) *Node {
	if t.Etype != TMAP {
		Fatalf("mapfn %v", t)
	}
	fn := syslook(name, 1)
	substArgTypes(fn, t.Down, t.Type, t.Down, t.Type)
	return fn
}

func mapfndel(name string, t *Type) *Node {
	if t.Etype != TMAP {
		Fatalf("mapfn %v", t)
	}
	fn := syslook(name, 1)
	substArgTypes(fn, t.Down, t.Type, t.Down)
	return fn
}

func writebarrierfn(name string, l *Type, r *Type) *Node {
	fn := syslook(name, 1)
	substArgTypes(fn, l, r)
	return fn
}

func addstr(n *Node, init **NodeList) *Node {
	// orderexpr rewrote OADDSTR to have a list of strings.
	c := count(n.List)

	if c < 2 {
		Yyerror("addstr count %d too small", c)
	}

	buf := nodnil()
	if n.Esc == EscNone {
		sz := int64(0)
		for l := n.List; l != nil; l = l.Next {
			if n.Op == OLITERAL {
				sz += int64(len(n.Val().U.(string)))
			}
		}

		// Don't allocate the buffer if the result won't fit.
		if sz < tmpstringbufsize {
			// Create temporary buffer for result string on stack.
			t := aindex(Nodintconst(tmpstringbufsize), Types[TUINT8])

			buf = Nod(OADDR, temp(t), nil)
		}
	}

	// build list of string arguments
	args := list1(buf)

	for l := n.List; l != nil; l = l.Next {
		args = list(args, conv(l.N, Types[TSTRING]))
	}

	var fn string
	if c <= 5 {
		// small numbers of strings use direct runtime helpers.
		// note: orderexpr knows this cutoff too.
		fn = fmt.Sprintf("concatstring%d", c)
	} else {
		// large numbers of strings are passed to the runtime as a slice.
		fn = "concatstrings"

		t := typ(TARRAY)
		t.Type = Types[TSTRING]
		t.Bound = -1
		slice := Nod(OCOMPLIT, nil, typenod(t))
		if prealloc[n] != nil {
			prealloc[slice] = prealloc[n]
		}
		slice.List = args.Next // skip buf arg
		args = list1(buf)
		args = list(args, slice)
		slice.Esc = EscNone
	}

	cat := syslook(fn, 1)
	r := Nod(OCALL, cat, nil)
	r.List = args
	typecheck(&r, Erv)
	walkexpr(&r, init)
	r.Type = n.Type

	return r
}

// expand append(l1, l2...) to
//   init {
//     s := l1
//     if n := len(l1) + len(l2) - cap(s); n > 0 {
//       s = growslice_n(s, n)
//     }
//     s = s[:len(l1)+len(l2)]
//     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
//   }
//   s
//
// l2 is allowed to be a string.
func appendslice(n *Node, init **NodeList) *Node {
	walkexprlistsafe(n.List, init)

	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
	// and n are name or literal, but those may index the slice we're
	// modifying here.  Fix explicitly.
	for l := n.List; l != nil; l = l.Next {
		l.N = cheapexpr(l.N, init)
	}

	l1 := n.List.N
	l2 := n.List.Next.N

	s := temp(l1.Type) // var s []T
	var l *NodeList
	l = list(l, Nod(OAS, s, l1)) // s = l1

	nt := temp(Types[TINT])

	nif := Nod(OIF, nil, nil)

	// n := len(s) + len(l2) - cap(s)
	nif.Ninit = list1(Nod(OAS, nt, Nod(OSUB, Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil)), Nod(OCAP, s, nil))))

	nif.Left = Nod(OGT, nt, Nodintconst(0))

	// instantiate growslice_n(Type*, []any, int) []any
	fn := syslook("growslice_n", 1) //   growslice_n(<type>, old []T, n int64) (ret []T)
	substArgTypes(fn, s.Type.Type, s.Type.Type)

	// s = growslice_n(T, s, n)
	nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt)))

	l = list(l, nif)

	if haspointers(l1.Type.Type) {
		// copy(s[len(l1):len(l1)+len(l2)], l2)
		nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))))

		nptr1.Etype = 1
		nptr2 := l2
		fn := syslook("typedslicecopy", 1)
		substArgTypes(fn, l1.Type, l2.Type)
		nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2)
		l = list(l, nt)
	} else if flag_race != 0 {
		// rely on runtime to instrument copy.
		// copy(s[len(l1):len(l1)+len(l2)], l2)
		nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))))

		nptr1.Etype = 1
		nptr2 := l2
		var fn *Node
		if l2.Type.Etype == TSTRING {
			fn = syslook("slicestringcopy", 1)
		} else {
			fn = syslook("slicecopy", 1)
		}
		substArgTypes(fn, l1.Type, l2.Type)
		nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width))
		l = list(l, nt)
	} else {
		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
		nptr1 := Nod(OINDEX, s, Nod(OLEN, l1, nil))

		nptr1.Bounded = true
		nptr1 = Nod(OADDR, nptr1, nil)

		nptr2 := Nod(OSPTR, l2, nil)

		fn := syslook("memmove", 1)
		substArgTypes(fn, s.Type.Type, s.Type.Type)

		nwid := cheapexpr(conv(Nod(OLEN, l2, nil), Types[TUINTPTR]), &l)

		nwid = Nod(OMUL, nwid, Nodintconst(s.Type.Type.Width))
		nt := mkcall1(fn, nil, &l, nptr1, nptr2, nwid)
		l = list(l, nt)
	}

	// s = s[:len(l1)+len(l2)]
	nt = Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))

	nt = Nod(OSLICE, s, Nod(OKEY, nil, nt))
	nt.Etype = 1
	l = list(l, Nod(OAS, s, nt))

	typechecklist(l, Etop)
	walkstmtlist(l)
	*init = concat(*init, l)
	return s
}

// Rewrite append(src, x, y, z) so that any side effects in
// x, y, z (including runtime panics) are evaluated in
// initialization statements before the append.
// For normal code generation, stop there and leave the
// rest to cgen_append.
//
// For race detector, expand append(src, a [, b]* ) to
//
//   init {
//     s := src
//     const argc = len(args) - 1
//     if cap(s) - len(s) < argc {
//	    s = growslice(s, len(s)+argc)
//     }
//     n := len(s)
//     s = s[:n+argc]
//     s[n] = a
//     s[n+1] = b
//     ...
//   }
//   s
func walkappend(n *Node, init **NodeList, dst *Node) *Node {
	if !samesafeexpr(dst, n.List.N) {
		l := n.List
		l.N = safeexpr(l.N, init)
		walkexpr(&l.N, init)
	}
	walkexprlistsafe(n.List.Next, init)

	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
	// and n are name or literal, but those may index the slice we're
	// modifying here.  Fix explicitly.
	// Using cheapexpr also makes sure that the evaluation
	// of all arguments (and especially any panics) happen
	// before we begin to modify the slice in a visible way.
	for l := n.List.Next; l != nil; l = l.Next {
		l.N = cheapexpr(l.N, init)
	}

	nsrc := n.List.N

	// Resolve slice type of multi-valued return.
	if Istype(nsrc.Type, TSTRUCT) {
		nsrc.Type = nsrc.Type.Type.Type
	}
	argc := count(n.List) - 1
	if argc < 1 {
		return nsrc
	}

	// General case, with no function calls left as arguments.
	// Leave for gen, except that race detector requires old form
	if flag_race == 0 {
		return n
	}

	var l *NodeList

	ns := temp(nsrc.Type)
	l = list(l, Nod(OAS, ns, nsrc)) // s = src

	na := Nodintconst(int64(argc)) // const argc
	nx := Nod(OIF, nil, nil)       // if cap(s) - len(s) < argc
	nx.Left = Nod(OLT, Nod(OSUB, Nod(OCAP, ns, nil), Nod(OLEN, ns, nil)), na)

	fn := syslook("growslice", 1) //   growslice(<type>, old []T, mincap int) (ret []T)
	substArgTypes(fn, ns.Type.Type, ns.Type.Type)

	nx.Nbody = list1(Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, Nod(OADD, Nod(OLEN, ns, nil), na))))

	l = list(l, nx)

	nn := temp(Types[TINT])
	l = list(l, Nod(OAS, nn, Nod(OLEN, ns, nil))) // n = len(s)

	nx = Nod(OSLICE, ns, Nod(OKEY, nil, Nod(OADD, nn, na))) // ...s[:n+argc]
	nx.Etype = 1
	l = list(l, Nod(OAS, ns, nx)) // s = s[:n+argc]

	for a := n.List.Next; a != nil; a = a.Next {
		nx = Nod(OINDEX, ns, nn) // s[n] ...
		nx.Bounded = true
		l = list(l, Nod(OAS, nx, a.N)) // s[n] = arg
		if a.Next != nil {
			l = list(l, Nod(OAS, nn, Nod(OADD, nn, Nodintconst(1)))) // n = n + 1
		}
	}

	typechecklist(l, Etop)
	walkstmtlist(l)
	*init = concat(*init, l)
	return ns
}

// Lower copy(a, b) to a memmove call or a runtime call.
//
// init {
//   n := len(a)
//   if n > len(b) { n = len(b) }
//   memmove(a.ptr, b.ptr, n*sizeof(elem(a)))
// }
// n;
//
// Also works if b is a string.
//
func copyany(n *Node, init **NodeList, runtimecall int) *Node {
	if haspointers(n.Left.Type.Type) {
		fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
		return mkcall1(fn, n.Type, init, typename(n.Left.Type.Type), n.Left, n.Right)
	}

	if runtimecall != 0 {
		var fn *Node
		if n.Right.Type.Etype == TSTRING {
			fn = syslook("slicestringcopy", 1)
		} else {
			fn = syslook("slicecopy", 1)
		}
		substArgTypes(fn, n.Left.Type, n.Right.Type)
		return mkcall1(fn, n.Type, init, n.Left, n.Right, Nodintconst(n.Left.Type.Type.Width))
	}

	walkexpr(&n.Left, init)
	walkexpr(&n.Right, init)
	nl := temp(n.Left.Type)
	nr := temp(n.Right.Type)
	var l *NodeList
	l = list(l, Nod(OAS, nl, n.Left))
	l = list(l, Nod(OAS, nr, n.Right))

	nfrm := Nod(OSPTR, nr, nil)
	nto := Nod(OSPTR, nl, nil)

	nlen := temp(Types[TINT])

	// n = len(to)
	l = list(l, Nod(OAS, nlen, Nod(OLEN, nl, nil)))

	// if n > len(frm) { n = len(frm) }
	nif := Nod(OIF, nil, nil)

	nif.Left = Nod(OGT, nlen, Nod(OLEN, nr, nil))
	nif.Nbody = list(nif.Nbody, Nod(OAS, nlen, Nod(OLEN, nr, nil)))
	l = list(l, nif)

	// Call memmove.
	fn := syslook("memmove", 1)

	substArgTypes(fn, nl.Type.Type, nl.Type.Type)
	nwid := temp(Types[TUINTPTR])
	l = list(l, Nod(OAS, nwid, conv(nlen, Types[TUINTPTR])))
	nwid = Nod(OMUL, nwid, Nodintconst(nl.Type.Type.Width))
	l = list(l, mkcall1(fn, nil, init, nto, nfrm, nwid))

	typechecklist(l, Etop)
	walkstmtlist(l)
	*init = concat(*init, l)
	return nlen
}

func eqfor(t *Type, needsize *int) *Node {
	// Should only arrive here with large memory or
	// a struct/array containing a non-memory field/element.
	// Small memory is handled inline, and single non-memory
	// is handled during type check (OCMPSTR etc).
	a := algtype1(t, nil)

	if a != AMEM && a != -1 {
		Fatalf("eqfor %v", t)
	}

	if a == AMEM {
		n := syslook("memequal", 1)
		substArgTypes(n, t, t)
		*needsize = 1
		return n
	}

	sym := typesymprefix(".eq", t)
	n := newname(sym)
	n.Class = PFUNC
	ntype := Nod(OTFUNC, nil, nil)
	ntype.List = list(ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
	ntype.List = list(ntype.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
	ntype.Rlist = list(ntype.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
	typecheck(&ntype, Etype)
	n.Type = ntype.Type
	*needsize = 0
	return n
}

func countfield(t *Type) int {
	n := 0
	for t1 := t.Type; t1 != nil; t1 = t1.Down {
		n++
	}
	return n
}

func walkcompare(np **Node, init **NodeList) {
	n := *np

	// Given interface value l and concrete value r, rewrite
	//   l == r
	// to
	//   x, ok := l.(type(r)); ok && x == r
	// Handle != similarly.
	// This avoids the allocation that would be required
	// to convert r to l for comparison.
	var l *Node

	var r *Node
	if Isinter(n.Left.Type) && !Isinter(n.Right.Type) {
		l = n.Left
		r = n.Right
	} else if !Isinter(n.Left.Type) && Isinter(n.Right.Type) {
		l = n.Right
		r = n.Left
	}

	if l != nil {
		x := temp(r.Type)
		if haspointers(r.Type) {
			a := Nod(OAS, x, nil)
			typecheck(&a, Etop)
			*init = list(*init, a)
		}
		ok := temp(Types[TBOOL])

		// l.(type(r))
		a := Nod(ODOTTYPE, l, nil)

		a.Type = r.Type

		// x, ok := l.(type(r))
		expr := Nod(OAS2, nil, nil)

		expr.List = list1(x)
		expr.List = list(expr.List, ok)
		expr.Rlist = list1(a)
		typecheck(&expr, Etop)
		walkexpr(&expr, init)

		if n.Op == OEQ {
			r = Nod(OANDAND, ok, Nod(OEQ, x, r))
		} else {
			r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r))
		}
		*init = list(*init, expr)
		finishcompare(np, n, r, init)
		return
	}

	// Must be comparison of array or struct.
	// Otherwise back end handles it.
	t := n.Left.Type

	switch t.Etype {
	default:
		return

	case TARRAY:
		if Isslice(t) {
			return
		}

	case TSTRUCT:
		break
	}

	cmpl := n.Left
	for cmpl != nil && cmpl.Op == OCONVNOP {
		cmpl = cmpl.Left
	}
	cmpr := n.Right
	for cmpr != nil && cmpr.Op == OCONVNOP {
		cmpr = cmpr.Left
	}

	if !islvalue(cmpl) || !islvalue(cmpr) {
		Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
	}

	l = temp(Ptrto(t))
	a := Nod(OAS, l, Nod(OADDR, cmpl, nil))
	a.Right.Etype = 1 // addr does not escape
	typecheck(&a, Etop)
	*init = list(*init, a)

	r = temp(Ptrto(t))
	a = Nod(OAS, r, Nod(OADDR, cmpr, nil))
	a.Right.Etype = 1 // addr does not escape
	typecheck(&a, Etop)
	*init = list(*init, a)

	andor := OANDAND
	if n.Op == ONE {
		andor = OOROR
	}

	var expr *Node
	if t.Etype == TARRAY && t.Bound <= 4 && issimple[t.Type.Etype] {
		// Four or fewer elements of a basic type.
		// Unroll comparisons.
		var li *Node
		var ri *Node
		for i := 0; int64(i) < t.Bound; i++ {
			li = Nod(OINDEX, l, Nodintconst(int64(i)))
			ri = Nod(OINDEX, r, Nodintconst(int64(i)))
			a = Nod(int(n.Op), li, ri)
			if expr == nil {
				expr = a
			} else {
				expr = Nod(andor, expr, a)
			}
		}

		if expr == nil {
			expr = Nodbool(n.Op == OEQ)
		}
		finishcompare(np, n, expr, init)
		return
	}

	if t.Etype == TSTRUCT && countfield(t) <= 4 {
		// Struct of four or fewer fields.
		// Inline comparisons.
		var li *Node
		var ri *Node
		for t1 := t.Type; t1 != nil; t1 = t1.Down {
			if isblanksym(t1.Sym) {
				continue
			}
			li = Nod(OXDOT, l, newname(t1.Sym))
			ri = Nod(OXDOT, r, newname(t1.Sym))
			a = Nod(int(n.Op), li, ri)
			if expr == nil {
				expr = a
			} else {
				expr = Nod(andor, expr, a)
			}
		}

		if expr == nil {
			expr = Nodbool(n.Op == OEQ)
		}
		finishcompare(np, n, expr, init)
		return
	}

	// Chose not to inline.  Call equality function directly.
	var needsize int
	call := Nod(OCALL, eqfor(t, &needsize), nil)

	call.List = list(call.List, l)
	call.List = list(call.List, r)
	if needsize != 0 {
		call.List = list(call.List, Nodintconst(t.Width))
	}
	r = call
	if n.Op != OEQ {
		r = Nod(ONOT, r, nil)
	}

	finishcompare(np, n, r, init)
	return
}

func finishcompare(np **Node, n, r *Node, init **NodeList) {
	// Using np here to avoid passing &r to typecheck.
	*np = r
	typecheck(np, Erv)
	walkexpr(np, init)
	r = *np
	if r.Type != n.Type {
		r = Nod(OCONVNOP, r, nil)
		r.Type = n.Type
		r.Typecheck = 1
		*np = r
	}
}

func samecheap(a *Node, b *Node) bool {
	var ar *Node
	var br *Node
	for a != nil && b != nil && a.Op == b.Op {
		switch a.Op {
		default:
			return false

		case ONAME:
			return a == b

		case ODOT, ODOTPTR:
			ar = a.Right
			br = b.Right
			if ar.Op != ONAME || br.Op != ONAME || ar.Sym != br.Sym {
				return false
			}

		case OINDEX:
			ar = a.Right
			br = b.Right
			if !Isconst(ar, CTINT) || !Isconst(br, CTINT) || Mpcmpfixfix(ar.Val().U.(*Mpint), br.Val().U.(*Mpint)) != 0 {
				return false
			}
		}

		a = a.Left
		b = b.Left
	}

	return false
}

func walkrotate(np **Node) {
	if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
		return
	}

	n := *np

	// Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
	l := n.Left

	r := n.Right
	if (n.Op != OOR && n.Op != OXOR) || (l.Op != OLSH && l.Op != ORSH) || (r.Op != OLSH && r.Op != ORSH) || n.Type == nil || Issigned[n.Type.Etype] || l.Op == r.Op {
		return
	}

	// Want same, side effect-free expression on lhs of both shifts.
	if !samecheap(l.Left, r.Left) {
		return
	}

	// Constants adding to width?
	w := int(l.Type.Width * 8)

	if Smallintconst(l.Right) && Smallintconst(r.Right) {
		sl := int(Mpgetfix(l.Right.Val().U.(*Mpint)))
		if sl >= 0 {
			sr := int(Mpgetfix(r.Right.Val().U.(*Mpint)))
			if sr >= 0 && sl+sr == w {
				// Rewrite left shift half to left rotate.
				if l.Op == OLSH {
					n = l
				} else {
					n = r
				}
				n.Op = OLROT

				// Remove rotate 0 and rotate w.
				s := int(Mpgetfix(n.Right.Val().U.(*Mpint)))

				if s == 0 || s == w {
					n = n.Left
				}

				*np = n
				return
			}
		}
		return
	}

	// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
	return
}

/*
 * walkmul rewrites integer multiplication by powers of two as shifts.
 */
func walkmul(np **Node, init **NodeList) {
	n := *np
	if !Isint[n.Type.Etype] {
		return
	}

	var nr *Node
	var nl *Node
	if n.Right.Op == OLITERAL {
		nl = n.Left
		nr = n.Right
	} else if n.Left.Op == OLITERAL {
		nl = n.Right
		nr = n.Left
	} else {
		return
	}

	neg := 0

	// x*0 is 0 (and side effects of x).
	var pow int
	var w int
	if Mpgetfix(nr.Val().U.(*Mpint)) == 0 {
		cheapexpr(nl, init)
		Nodconst(n, n.Type, 0)
		goto ret
	}

	// nr is a constant.
	pow = powtwo(nr)

	if pow < 0 {
		return
	}
	if pow >= 1000 {
		// negative power of 2, like -16
		neg = 1

		pow -= 1000
	}

	w = int(nl.Type.Width * 8)
	if pow+1 >= w { // too big, shouldn't happen
		return
	}

	nl = cheapexpr(nl, init)

	if pow == 0 {
		// x*1 is x
		n = nl

		goto ret
	}

	n = Nod(OLSH, nl, Nodintconst(int64(pow)))

ret:
	if neg != 0 {
		n = Nod(OMINUS, n, nil)
	}

	typecheck(&n, Erv)
	walkexpr(&n, init)
	*np = n
}

/*
 * walkdiv rewrites division by a constant as less expensive
 * operations.
 */
func walkdiv(np **Node, init **NodeList) {
	// if >= 0, nr is 1<<pow // 1 if nr is negative.

	// TODO(minux)
	if Thearch.Thechar == '7' || Thearch.Thechar == '9' {
		return
	}

	n := *np
	if n.Right.Op != OLITERAL {
		return
	}

	// nr is a constant.
	nl := cheapexpr(n.Left, init)

	nr := n.Right

	// special cases of mod/div
	// by a constant
	w := int(nl.Type.Width * 8)

	s := 0            // 1 if nr is negative.
	pow := powtwo(nr) // if >= 0, nr is 1<<pow
	if pow >= 1000 {
		// negative power of 2
		s = 1

		pow -= 1000
	}

	if pow+1 >= w {
		// divisor too large.
		return
	}

	if pow < 0 {
		// try to do division by multiply by (2^w)/d
		// see hacker's delight chapter 10
		// TODO: support 64-bit magic multiply here.
		var m Magic
		m.W = w

		if Issigned[nl.Type.Etype] {
			m.Sd = Mpgetfix(nr.Val().U.(*Mpint))
			Smagic(&m)
		} else {
			m.Ud = uint64(Mpgetfix(nr.Val().U.(*Mpint)))
			Umagic(&m)
		}

		if m.Bad != 0 {
			return
		}

		// We have a quick division method so use it
		// for modulo too.
		if n.Op == OMOD {
			// rewrite as A%B = A - (A/B*B).
			n1 := Nod(ODIV, nl, nr)

			n2 := Nod(OMUL, n1, nr)
			n = Nod(OSUB, nl, n2)
			goto ret
		}

		switch Simtype[nl.Type.Etype] {
		default:
			return

			// n1 = nl * magic >> w (HMUL)
		case TUINT8, TUINT16, TUINT32:
			nc := Nod(OXXX, nil, nil)

			Nodconst(nc, nl.Type, int64(m.Um))
			n1 := Nod(OHMUL, nl, nc)
			typecheck(&n1, Erv)
			if m.Ua != 0 {
				// Select a Go type with (at least) twice the width.
				var twide *Type
				switch Simtype[nl.Type.Etype] {
				default:
					return

				case TUINT8, TUINT16:
					twide = Types[TUINT32]

				case TUINT32:
					twide = Types[TUINT64]

				case TINT8, TINT16:
					twide = Types[TINT32]

				case TINT32:
					twide = Types[TINT64]
				}

				// add numerator (might overflow).
				// n2 = (n1 + nl)
				n2 := Nod(OADD, conv(n1, twide), conv(nl, twide))

				// shift by m.s
				nc := Nod(OXXX, nil, nil)

				Nodconst(nc, Types[TUINT], int64(m.S))
				n = conv(Nod(ORSH, n2, nc), nl.Type)
			} else {
				// n = n1 >> m.s
				nc := Nod(OXXX, nil, nil)

				Nodconst(nc, Types[TUINT], int64(m.S))
				n = Nod(ORSH, n1, nc)
			}

			// n1 = nl * magic >> w
		case TINT8, TINT16, TINT32:
			nc := Nod(OXXX, nil, nil)

			Nodconst(nc, nl.Type, m.Sm)
			n1 := Nod(OHMUL, nl, nc)
			typecheck(&n1, Erv)
			if m.Sm < 0 {
				// add the numerator.
				n1 = Nod(OADD, n1, nl)
			}

			// shift by m.s
			nc = Nod(OXXX, nil, nil)

			Nodconst(nc, Types[TUINT], int64(m.S))
			n2 := conv(Nod(ORSH, n1, nc), nl.Type)

			// add 1 iff n1 is negative.
			nc = Nod(OXXX, nil, nil)

			Nodconst(nc, Types[TUINT], int64(w)-1)
			n3 := Nod(ORSH, nl, nc) // n4 = -1 iff n1 is negative.
			n = Nod(OSUB, n2, n3)

			// apply sign.
			if m.Sd < 0 {
				n = Nod(OMINUS, n, nil)
			}
		}

		goto ret
	}

	switch pow {
	case 0:
		if n.Op == OMOD {
			// nl % 1 is zero.
			Nodconst(n, n.Type, 0)
		} else if s != 0 {
			// divide by -1
			n.Op = OMINUS

			n.Right = nil
		} else {
			// divide by 1
			n = nl
		}

	default:
		if Issigned[n.Type.Etype] {
			if n.Op == OMOD {
				// signed modulo 2^pow is like ANDing
				// with the last pow bits, but if nl < 0,
				// nl & (2^pow-1) is (nl+1)%2^pow - 1.
				nc := Nod(OXXX, nil, nil)

				Nodconst(nc, Types[Simtype[TUINT]], int64(w)-1)
				n1 := Nod(ORSH, nl, nc) // n1 = -1 iff nl < 0.
				if pow == 1 {
					typecheck(&n1, Erv)
					n1 = cheapexpr(n1, init)

					// n = (nl+ε)&1 -ε where ε=1 iff nl<0.
					n2 := Nod(OSUB, nl, n1)

					nc := Nod(OXXX, nil, nil)
					Nodconst(nc, nl.Type, 1)
					n3 := Nod(OAND, n2, nc)
					n = Nod(OADD, n3, n1)
				} else {
					// n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0.
					nc := Nod(OXXX, nil, nil)

					Nodconst(nc, nl.Type, (1<<uint(pow))-1)
					n2 := Nod(OAND, n1, nc) // n2 = 2^pow-1 iff nl<0.
					typecheck(&n2, Erv)
					n2 = cheapexpr(n2, init)

					n3 := Nod(OADD, nl, n2)
					n4 := Nod(OAND, n3, nc)
					n = Nod(OSUB, n4, n2)
				}

				break
			} else {
				// arithmetic right shift does not give the correct rounding.
				// if nl >= 0, nl >> n == nl / nr
				// if nl < 0, we want to add 2^n-1 first.
				nc := Nod(OXXX, nil, nil)

				Nodconst(nc, Types[Simtype[TUINT]], int64(w)-1)
				n1 := Nod(ORSH, nl, nc) // n1 = -1 iff nl < 0.
				if pow == 1 {
					// nl+1 is nl-(-1)
					n.Left = Nod(OSUB, nl, n1)
				} else {
					// Do a logical right right on -1 to keep pow bits.
					nc := Nod(OXXX, nil, nil)

					Nodconst(nc, Types[Simtype[TUINT]], int64(w)-int64(pow))
					n2 := Nod(ORSH, conv(n1, tounsigned(nl.Type)), nc)
					n.Left = Nod(OADD, nl, conv(n2, nl.Type))
				}

				// n = (nl + 2^pow-1) >> pow
				n.Op = ORSH

				nc = Nod(OXXX, nil, nil)
				Nodconst(nc, Types[Simtype[TUINT]], int64(pow))
				n.Right = nc
				n.Typecheck = 0
			}

			if s != 0 {
				n = Nod(OMINUS, n, nil)
			}
			break
		}

		nc := Nod(OXXX, nil, nil)
		if n.Op == OMOD {
			// n = nl & (nr-1)
			n.Op = OAND

			Nodconst(nc, nl.Type, Mpgetfix(nr.Val().U.(*Mpint))-1)
		} else {
			// n = nl >> pow
			n.Op = ORSH

			Nodconst(nc, Types[Simtype[TUINT]], int64(pow))
		}

		n.Typecheck = 0
		n.Right = nc
	}

	goto ret

ret:
	typecheck(&n, Erv)
	walkexpr(&n, init)
	*np = n
}

// return 1 if integer n must be in range [0, max), 0 otherwise
func bounded(n *Node, max int64) bool {
	if n.Type == nil || !Isint[n.Type.Etype] {
		return false
	}

	sign := Issigned[n.Type.Etype]
	bits := int32(8 * n.Type.Width)

	if Smallintconst(n) {
		v := Mpgetfix(n.Val().U.(*Mpint))
		return 0 <= v && v < max
	}

	switch n.Op {
	case OAND:
		v := int64(-1)
		if Smallintconst(n.Left) {
			v = Mpgetfix(n.Left.Val().U.(*Mpint))
		} else if Smallintconst(n.Right) {
			v = Mpgetfix(n.Right.Val().U.(*Mpint))
		}

		if 0 <= v && v < max {
			return true
		}

	case OMOD:
		if !sign && Smallintconst(n.Right) {
			v := Mpgetfix(n.Right.Val().U.(*Mpint))
			if 0 <= v && v <= max {
				return true
			}
		}

	case ODIV:
		if !sign && Smallintconst(n.Right) {
			v := Mpgetfix(n.Right.Val().U.(*Mpint))
			for bits > 0 && v >= 2 {
				bits--
				v >>= 1
			}
		}

	case ORSH:
		if !sign && Smallintconst(n.Right) {
			v := Mpgetfix(n.Right.Val().U.(*Mpint))
			if v > int64(bits) {
				return true
			}
			bits -= int32(v)
		}
	}

	if !sign && bits <= 62 && 1<<uint(bits) <= max {
		return true
	}

	return false
}

func usefield(n *Node) {
	if obj.Fieldtrack_enabled == 0 {
		return
	}

	switch n.Op {
	default:
		Fatalf("usefield %v", Oconv(int(n.Op), 0))

	case ODOT, ODOTPTR:
		break
	}

	t := n.Left.Type
	if Isptr[t.Etype] {
		t = t.Type
	}
	field := dotField[typeSym{t.Orig, n.Right.Sym}]
	if field == nil {
		Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Right.Sym)
	}
	if field.Note == nil || !strings.Contains(*field.Note, "go:\"track\"") {
		return
	}

	// dedup on list
	if field.Lastfn == Curfn {
		return
	}
	field.Lastfn = Curfn
	field.Outer = n.Left.Type
	if Isptr[field.Outer.Etype] {
		field.Outer = field.Outer.Type
	}
	if field.Outer.Sym == nil {
		Yyerror("tracked field must be in named struct type")
	}
	if !exportname(field.Sym.Name) {
		Yyerror("tracked field must be exported (upper case)")
	}

	Curfn.Func.Fieldtrack = append(Curfn.Func.Fieldtrack, field)
}

func candiscardlist(l *NodeList) bool {
	for ; l != nil; l = l.Next {
		if !candiscard(l.N) {
			return false
		}
	}
	return true
}

func candiscard(n *Node) bool {
	if n == nil {
		return true
	}

	switch n.Op {
	default:
		return false

		// Discardable as long as the subpieces are.
	case ONAME,
		ONONAME,
		OTYPE,
		OPACK,
		OLITERAL,
		OADD,
		OSUB,
		OOR,
		OXOR,
		OADDSTR,
		OADDR,
		OANDAND,
		OARRAYBYTESTR,
		OARRAYRUNESTR,
		OSTRARRAYBYTE,
		OSTRARRAYRUNE,
		OCAP,
		OCMPIFACE,
		OCMPSTR,
		OCOMPLIT,
		OMAPLIT,
		OSTRUCTLIT,
		OARRAYLIT,
		OPTRLIT,
		OCONV,
		OCONVIFACE,
		OCONVNOP,
		ODOT,
		OEQ,
		ONE,
		OLT,
		OLE,
		OGT,
		OGE,
		OKEY,
		OLEN,
		OMUL,
		OLSH,
		ORSH,
		OAND,
		OANDNOT,
		ONEW,
		ONOT,
		OCOM,
		OPLUS,
		OMINUS,
		OOROR,
		OPAREN,
		ORUNESTR,
		OREAL,
		OIMAG,
		OCOMPLEX:
		break

		// Discardable as long as we know it's not division by zero.
	case ODIV, OMOD:
		if Isconst(n.Right, CTINT) && mpcmpfixc(n.Right.Val().U.(*Mpint), 0) != 0 {
			break
		}
		if Isconst(n.Right, CTFLT) && mpcmpfltc(n.Right.Val().U.(*Mpflt), 0) != 0 {
			break
		}
		return false

		// Discardable as long as we know it won't fail because of a bad size.
	case OMAKECHAN, OMAKEMAP:
		if Isconst(n.Left, CTINT) && mpcmpfixc(n.Left.Val().U.(*Mpint), 0) == 0 {
			break
		}
		return false

		// Difficult to tell what sizes are okay.
	case OMAKESLICE:
		return false
	}

	if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
		return false
	}

	return true
}

// rewrite
//	print(x, y, z)
// into
//	func(a1, a2, a3) {
//		print(a1, a2, a3)
//	}(x, y, z)
// and same for println.

var walkprintfunc_prgen int

func walkprintfunc(np **Node, init **NodeList) {
	n := *np

	if n.Ninit != nil {
		walkstmtlist(n.Ninit)
		*init = concat(*init, n.Ninit)
		n.Ninit = nil
	}

	t := Nod(OTFUNC, nil, nil)
	num := 0
	var printargs *NodeList
	var a *Node
	var buf string
	for l := n.List; l != nil; l = l.Next {
		buf = fmt.Sprintf("a%d", num)
		num++
		a = Nod(ODCLFIELD, newname(Lookup(buf)), typenod(l.N.Type))
		t.List = list(t.List, a)
		printargs = list(printargs, a.Left)
	}

	fn := Nod(ODCLFUNC, nil, nil)
	walkprintfunc_prgen++
	buf = fmt.Sprintf("print·%d", walkprintfunc_prgen)
	fn.Func.Nname = newname(Lookup(buf))
	fn.Func.Nname.Name.Defn = fn
	fn.Func.Nname.Name.Param.Ntype = t
	declare(fn.Func.Nname, PFUNC)

	oldfn := Curfn
	Curfn = nil
	funchdr(fn)

	a = Nod(int(n.Op), nil, nil)
	a.List = printargs
	typecheck(&a, Etop)
	walkstmt(&a)

	fn.Nbody = list1(a)

	funcbody(fn)

	typecheck(&fn, Etop)
	typechecklist(fn.Nbody, Etop)
	xtop = list(xtop, fn)
	Curfn = oldfn

	a = Nod(OCALL, nil, nil)
	a.Left = fn.Func.Nname
	a.List = n.List
	typecheck(&a, Etop)
	walkexpr(&a, init)
	*np = a
}
