// 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) {
	var s string
	var l *NodeList
	var lno int

	Curfn = fn

	if Debug['W'] != 0 {
		s = fmt.Sprintf("\nbefore %v", Sconv(Curfn.Nname.Sym, 0))
		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.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.Dcl; l != nil; l = l.Next {
		if l.N.Op == ONAME && l.N.Class&^PHEAP == PAUTO && l.N.Defn != nil && l.N.Defn.Op == OTYPESW && l.N.Used != 0 {
			l.N.Defn.Left.Used++
		}
	}

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

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

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

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

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

func paramoutheap(fn *Node) int {
	var l *NodeList

	for l = fn.Dcl; l != nil; l = l.Next {
		switch l.N.Class {
		case PPARAMOUT,
			PPARAMOUT | PHEAP:
			return int(l.N.Addrtaken)

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

	return 0
}

// 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 callfunc *Node
	var arg *Node
	var lhs *Node
	var args *NodeList

	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) {
	var init *NodeList
	var ll *NodeList
	var rl *NodeList
	var cl int
	var n *Node
	var f *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", Sconv(n.Sym, 0))
		} 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:
		if n.Typecheck == 0 {
			Fatal("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 {
			Fatal("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 = 1
		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.Ntest != nil {
			walkstmtlist(n.Ntest.Ninit)
			init = n.Ntest.Ninit
			n.Ntest.Ninit = nil
			walkexpr(&n.Ntest, &init)
			addinit(&n.Ntest, init)
		}

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

	case OIF:
		walkexpr(&n.Ntest, &n.Ninit)
		walkstmtlist(n.Nbody)
		walkstmtlist(n.Nelse)

	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 != 0 && count(n.List) > 1) || paramoutheap(Curfn) != 0 {
			// assign to the function out parameters,
			// so that reorder3 can fix up conflicts
			rl = nil

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

			if samelist(rl, n.List) != 0 {
				// 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 {
					Fatal("expected return of call, have %v", Nconv(f, 0))
				}
				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, 0, 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 {
		Fatal("walkstmt ended up with name: %v", Nconv(n, obj.FmtSign))
	}

	*np = n
}

/*
 * 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) {
	var r *Node
	var l *Node
	var var_ *Node
	var a *Node
	var ok *Node
	var map_ *Node
	var key *Node
	var ll *NodeList
	var lr *NodeList
	var t *Type
	var et int
	var old_safemode int
	var v int64
	var lno int32
	var n *Node
	var fn *Node
	var n1 *Node
	var n2 *Node
	var sym *Sym
	var buf string
	var p string
	var from string
	var to string

	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.
		Fatal("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 {
		Fatal("missed typecheck: %v\n", Nconv(n, obj.FmtSign))
	}

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

	case OTYPE,
		ONONAME,
		OINDREG,
		OEMPTY,
		OPARAM:
		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] != 0 {
			t = t.Type
		}
		if Isfixedarray(t) != 0 {
			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 = uint8(bounded(n.Right, 8*t.Width))
		if Debug['m'] != 0 && n.Etype != 0 && !(Isconst(n.Right, CTINT) != 0) {
			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.
		ll = nil

		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 = 1
		goto ret

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

	case ONAME:
		if !(n.Class&PHEAP != 0) && n.Class != PPARAMREF {
			n.Addable = 1
		}
		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, int(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.

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

			n.Left.Enter = nil

			// Replace OCLOSURE with ONAME/PFUNC.
			n.Left = n.Left.Closure.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)

		ll = ascompatte(int(n.Op), n, int(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, 0, getthis(t), list1(n.Left.Left), 0, init)
		lr = ascompatte(int(n.Op), n, int(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) != 0 {
			goto ret
		}

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

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

			// x = i.(T); n->left is x, n->right->left is i.
		// orderstmt made sure x is addressable.
		case ODOTTYPE:
			walkexpr(&n.Right.Left, init)

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

			from = "I"

			to = "T"
			if isnilinter(r.Left.Type) != 0 {
				from = "E"
			}
			if isnilinter(r.Type) != 0 {
				to = "E"
			} else if Isinter(r.Type) != 0 {
				to = "I"
			}

			buf = fmt.Sprintf("assert%s2%s", from, to)

			fn = syslook(buf, 1)
			argtype(fn, r.Left.Type)
			argtype(fn, r.Type)

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

			// x = <-c; n->left is x, n->right->left is c.
		// orderstmt made sure x is addressable.
		case ORECV:
			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
		}

		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)
		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"
			}
		}

		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)

		// mapaccess needs a zero value to be at least this big.
		if zerosize < t.Type.Width {
			zerosize = t.Type.Width
		}

		// 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

		// a,b = i.(T)
	// orderstmt made sure a is addressable.
	case OAS2DOTTYPE:
		*init = concat(*init, n.Ninit)

		n.Ninit = nil
		r = n.Rlist.N
		walkexprlistsafe(n.List, init)
		walkexpr(&r.Left, init)
		if isblank(n.List.N) {
			n1 = nodnil()
		} else {
			n1 = Nod(OADDR, n.List.N, nil)
		}
		n1.Etype = 1 // addr does not escape

		from = "I"

		to = "T"
		if isnilinter(r.Left.Type) != 0 {
			from = "E"
		}
		if isnilinter(r.Type) != 0 {
			to = "E"
		} else if Isinter(r.Type) != 0 {
			to = "I"
		}
		buf = fmt.Sprintf("assert%s2%s2", from, to)

		fn = syslook(buf, 1)
		argtype(fn, r.Left.Type)
		argtype(fn, r.Type)

		t = Types[TBOOL]
		ok = n.List.Next.N
		if !isblank(ok) {
			t = ok.Type
		}
		r = mkcall1(fn, t, init, typename(r.Type), r.Left, n1)
		n = Nod(OAS, ok, r)
		typecheck(&n, Etop)
		goto ret

	case ODOTTYPE,
		ODOTTYPE2:
		Fatal("walkexpr ODOTTYPE") // should see inside OAS or OAS2 only
		fallthrough

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

		// Optimize convT2E as a two-word copy when T is pointer-shaped.
		if isnilinter(n.Type) != 0 && isdirectiface(n.Left.Type) != 0 {
			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).
		from = "T"

		to = "I"
		if isnilinter(n.Left.Type) != 0 {
			from = "E"
		} else if Isinter(n.Left.Type) != 0 {
			from = "I"
		}
		if isnilinter(n.Type) != 0 {
			to = "E"
		}
		buf = fmt.Sprintf("conv%s2%s", from, to)

		fn = syslook(buf, 1)
		ll = nil
		if !(Isinter(n.Left.Type) != 0) {
			ll = list(ll, typename(n.Left.Type))
		}
		if !(isnilinter(n.Type) != 0) {
			ll = list(ll, typename(n.Type))
		}
		if !(Isinter(n.Left.Type) != 0) && !(isnilinter(n.Type) != 0) {
			sym = Pkglookup(fmt.Sprintf("%v.%v", 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 = 1
				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 = 1
			ll = list(ll, l)

			if isdirectiface(n.Left.Type) != 0 {
				/* 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.Ntest = 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) != 0 {
			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) != 0 {
				ll = list(ll, Nod(OADDR, n.Left, nil))
			} else {
				ll = list(ll, Nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil))
			}
		}

		argtype(fn, n.Left.Type)
		argtype(fn, 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] != 0 {
				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] != 0 {
				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] != 0 && 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] != 0 {
			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
			}
			if et == TINT64 {
				namebuf = "int64"
			} else {
				namebuf = "uint64"
			}
			if n.Op == ODIV {
				namebuf += "div"
			} else {
				namebuf += "mod"
			}
			n = mkcall(namebuf, 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 != 0 {
			goto ret
		}
		t = n.Left.Type
		if t != nil && Isptr[t.Etype] != 0 {
			t = t.Type
		}
		if Isfixedarray(t) != 0 {
			n.Bounded = uint8(bounded(r, t.Bound))
			if Debug['m'] != 0 && n.Bounded != 0 && !(Isconst(n.Right, CTINT) != 0) {
				Warn("index bounds check elided")
			}
			if Smallintconst(n.Right) != 0 && !(n.Bounded != 0) {
				Yyerror("index out of bounds")
			}
		} else if Isconst(n.Left, CTSTR) != 0 {
			n.Bounded = uint8(bounded(r, int64(len(n.Left.Val.U.Sval.S))))
			if Debug['m'] != 0 && n.Bounded != 0 && !(Isconst(n.Right, CTINT) != 0) {
				Warn("index bounds check elided")
			}
			if Smallintconst(n.Right) != 0 {
				if !(n.Bounded != 0) {
					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.Xval)

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

		if Isconst(n.Right, CTINT) != 0 {
			if Mpcmpfixfix(n.Right.Val.U.Xval, &mpzero) < 0 || Mpcmpfixfix(n.Right.Val.U.Xval, 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"
			}
		}

		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

		// mapaccess needs a zero value to be at least this big.
		if zerosize < t.Type.Width {
			zerosize = t.Type.Width
		}
		goto ret

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

	case OSLICE:
		if n.Right != nil && n.Right.Left == nil && n.Right.Right == nil { // noop
			walkexpr(&n.Left, init)
			n = n.Left
			goto ret
		}
		fallthrough

		// fallthrough
	case OSLICEARR,
		OSLICESTR:
		if n.Right == nil { // already processed
			goto ret
		}

		walkexpr(&n.Left, init)

		// cgen_slice can't handle string literals as source
		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
		if (n.Op == OSLICESTR && n.Left.Op == OLITERAL) || (n.Left.Op == OINDEX) {
			n.Left = copyexpr(n.Left, n.Left.Type, init)
		} else {
			n.Left = safeexpr(n.Left, init)
		}
		walkexpr(&n.Right.Left, init)
		n.Right.Left = safeexpr(n.Right.Left, init)
		walkexpr(&n.Right.Right, init)
		n.Right.Right = safeexpr(n.Right.Right, init)
		n = sliceany(n, init) // chops n->right, sets n->list
		goto ret

	case OSLICE3,
		OSLICE3ARR:
		if n.Right == nil { // already processed
			goto ret
		}

		walkexpr(&n.Left, init)

		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
		// TODO the comment on the previous line was copied from case OSLICE. it might not even be true.
		if n.Left.Op == OINDEX {
			n.Left = copyexpr(n.Left, n.Left.Type, init)
		} else {
			n.Left = safeexpr(n.Left, init)
		}
		walkexpr(&n.Right.Left, init)
		n.Right.Left = safeexpr(n.Right.Left, init)
		walkexpr(&n.Right.Right.Left, init)
		n.Right.Right.Left = safeexpr(n.Right.Right.Left, init)
		walkexpr(&n.Right.Right.Right, init)
		n.Right.Right.Right = safeexpr(n.Right.Right.Right, init)
		n = sliceany(n, init) // chops n->right, sets n->list
		goto ret

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

	case ONEW:
		if n.Esc == EscNone && n.Type.Type.Width < 1<<16 {
			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) != 0 && len(n.Left.Val.U.Sval.S) == 0) || (Isconst(n.Right, CTSTR) != 0 && len(n.Right.Val.U.Sval.S) == 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) != 0 && n.Left.Op == OADDSTR && count(n.Left.List) == 2 && Isconst(n.Left.List.Next.N, CTSTR) != 0 && 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
		}

		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 {
			Fatal("cmp %v", Tconv(n.Type, 0))
		}
		r.Type = n.Type
		n = r
		goto ret

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

	case OAPPEND:
		if n.Isddd != 0 {
			n = appendslice(n, init) // also works for append(slice, string).
		} else {
			n = walkappend(n, init)
		}
		goto ret

	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)

		argtype(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)
		}

		argtype(fn, hmap(t))      // hmap buffer
		argtype(fn, mapbucket(t)) // bucket buffer
		argtype(fn, t.Down)       // key type
		argtype(fn, t.Type)       // value 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 && Smallintconst(l) != 0 && Smallintconst(r) != 0 && (t.Type.Width == 0 || Mpgetfix(r.Val.U.Xval) < (1<<16)/t.Type.Width) {
			// 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)

			argtype(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) {
			Fatal("ifaceeq %v %v %v", Oconv(int(n.Op), 0), Tconv(n.Left.Type, 0), Tconv(n.Right.Type, 0))
		}
		if isnilinter(n.Left.Type) != 0 {
			fn = syslook("efaceeq", 1)
		} else {
			fn = syslook("ifaceeq", 1)
		}

		n.Right = cheapexpr(n.Right, init)
		n.Left = cheapexpr(n.Left, init)
		argtype(fn, n.Right.Type)
		argtype(fn, 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
	}

	Fatal("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 ascompatee1(op int, l *Node, r *Node, init **NodeList) *Node {
	var n *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 {
	var ll *NodeList
	var lr *NodeList
	var nn *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)
	}

	nn = nil
	ll = nl
	lr = nr
	for ; ll != nil && lr != nil; (func() { ll = ll.Next; lr = 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.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) int {
	var r Node

	if l.Ullman >= UINF || l.Op == OINDEXMAP {
		return 1
	}
	r = Node{}
	if needwritebarrier(l, &r) != 0 {
		return 1
	}
	if Eqtype(l.Type, rt) {
		return 0
	}
	return 1
}

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 r *Type
	var saver Iter
	var ucount int
	var nn *NodeList
	var mm *NodeList

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

	nn = nil
	mm = nil
	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) != 0 {
			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 {
		Fatal("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 {
	var a *Node
	var n *Node
	var tslice *Type
	var esc int

	esc = EscUnknown
	if ddd != nil {
		esc = int(ddd.Esc)
	}

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

	if count(lr0) == 0 {
		n = nodnil()
		n.Type = tslice
	} else {
		n = Nod(OCOMPLIT, nil, typenod(tslice))
		if ddd != nil {
			n.Alloc = ddd.Alloc // temporary to use
		}
		n.List = lr0
		n.Esc = uint(esc)
		typecheck(&n, Erv)
		if n.Type == nil {
			Fatal("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 first int
	var l *Type
	var savel Iter
	var fmt_ string

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

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

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

	fmt_ = ""
	fmt_ += fmt.Sprintf("\t")
	first = 1
	for ; l != nil; l = l.Next {
		r = l.N
		if first != 0 {
			first = 0
		} else {
			fmt_ += fmt.Sprintf(", ")
		}
		fmt_ += fmt.Sprintf("%v", 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 int, nl **Type, lr *NodeList, fp int, init **NodeList) *NodeList {
	var l *Type
	var ll *Type
	var r *Node
	var a *Node
	var nn *NodeList
	var lr0 *NodeList
	var alist *NodeList
	var savel Iter
	var l1 string
	var l2 string

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

	// f(g()) where g has multiple return values
	if r != nil && lr.Next == nil && r.Type.Etype == TSTRUCT && r.Type.Funarg != 0 {
		// optimization - can do block copy
		if eqtypenoname(r.Type, *nl) != 0 {
			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.
		alist = nil

		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 != 0 {
		// 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 != 0 && 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 l *NodeList
	var all *NodeList
	var on *Node
	var t *Type
	var notfirst int
	var et int
	var op int
	var calls *NodeList

	op = int(nn.Op)
	all = nn.List
	calls = nil
	notfirst = 0

	// 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 != 0 {
			calls = list(calls, mkcall("printsp", nil, init))
		}

		notfirst = bool2int(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) != 0 {
			if isnilinter(n.Type) != 0 {
				on = syslook("printeface", 1)
			} else {
				on = syslook("printiface", 1)
			}
			argtype(on, n.Type) // any-1
		} else if Isptr[et] != 0 || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
			on = syslook("printpointer", 1)
			argtype(on, n.Type) // any-1
		} else if Isslice(n.Type) != 0 {
			on = syslook("printslice", 1)
			argtype(on, n.Type) // any-1
		} else if Isint[et] != 0 {
			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] != 0 {
			on = syslook("printfloat", 0)
		} else if Iscomplex[et] != 0 {
			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 {
	var fn *Node

	dowidth(t)
	fn = syslook("newobject", 1)
	argtype(fn, t)
	return mkcall1(fn, Ptrto(t), nil, typename(t))
}

func isstack(n *Node) int {
	var defn *Node

	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.Defn
		if defn != nil && defn.Op == OAS && defn.Right.Op == OADDR {
			n = defn.Right.Left
		}
	}

	switch n.Op {
	// OINDREG only ends up in walk if it's indirect of SP.
	case OINDREG:
		return 1

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

	return 0
}

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

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

	return 0
}

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

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

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

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

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

	// No write barrier for implicit or explicit zeroing.
	if r == nil || iszero(r) != 0 {
		return 0
	}

	// No write barrier for initialization to constant.
	if r.Op == OLITERAL {
		return 0
	}

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

	// 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) != 0 {
		return 0
	}

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

	// No write barrier for reslice: x = x[0:y] or x = append(x, ...).
	// Both are compiled to modify x directly.
	// In the case of append, a write barrier may still be needed
	// if the underlying array grows, but the append code can
	// generate the write barrier directly in that case.
	// (It does not yet, but the cost of the write barrier will be
	// small compared to the cost of the allocation.)
	if r.Reslice != 0 {
		switch r.Op {
		case OSLICE,
			OSLICE3,
			OSLICESTR,
			OAPPEND:
			break

		default:
			Dump("bad reslice-l", l)
			Dump("bad reslice-r", r)
		}

		return 0
	}

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

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

var applywritebarrier_bv *Bvec

func applywritebarrier(n *Node, init **NodeList) *Node {
	var l *Node
	var r *Node
	var t *Type
	var x int64
	var name string

	if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) != 0 {
		if Curfn != nil && Curfn.Nowritebarrier {
			Yyerror("write barrier prohibited")
		}
		t = n.Left.Type
		l = Nod(OADDR, n.Left, nil)
		l.Etype = 1 // addr does not escape
		if t.Width == int64(Widthptr) {
			n = mkcall1(writebarrierfn("writebarrierptr", t, n.Right.Type), nil, init, l, n.Right)
		} else if t.Etype == TSTRING {
			n = mkcall1(writebarrierfn("writebarrierstring", t, n.Right.Type), nil, init, l, n.Right)
		} else if Isslice(t) != 0 {
			n = mkcall1(writebarrierfn("writebarrierslice", t, n.Right.Type), nil, init, l, n.Right)
		} else if Isinter(t) != 0 {
			n = mkcall1(writebarrierfn("writebarrieriface", t, n.Right.Type), nil, init, l, n.Right)
		} else if t.Width <= int64(4*Widthptr) {
			x = 0
			if applywritebarrier_bv == nil {
				applywritebarrier_bv = bvalloc(obj.BitsPerPointer * 4)
			}
			bvresetall(applywritebarrier_bv)
			twobitwalktype1(t, &x, applywritebarrier_bv)
			const (
				PtrBit = 1
			)
			// The bvgets are looking for BitsPointer in successive slots.
			if obj.BitsPointer != 1<<PtrBit {
				Fatal("wrong PtrBit")
			}
			switch t.Width / int64(Widthptr) {
			default:
				Fatal("found writebarrierfat for %d-byte object of type %v", int(t.Width), Tconv(t, 0))
				fallthrough

			case 2:
				name = fmt.Sprintf("writebarrierfat%d%d", bvget(applywritebarrier_bv, PtrBit), bvget(applywritebarrier_bv, obj.BitsPerPointer+PtrBit))

			case 3:
				name = fmt.Sprintf("writebarrierfat%d%d%d", bvget(applywritebarrier_bv, PtrBit), bvget(applywritebarrier_bv, obj.BitsPerPointer+PtrBit), bvget(applywritebarrier_bv, 2*obj.BitsPerPointer+PtrBit))

			case 4:
				name = fmt.Sprintf("writebarrierfat%d%d%d%d", bvget(applywritebarrier_bv, PtrBit), bvget(applywritebarrier_bv, obj.BitsPerPointer+PtrBit), bvget(applywritebarrier_bv, 2*obj.BitsPerPointer+PtrBit), bvget(applywritebarrier_bv, 3*obj.BitsPerPointer+PtrBit))
			}

			n = mkcall1(writebarrierfn(name, t, n.Right.Type), nil, init, l, nodnil(), n.Right)
		} else {
			r = n.Right
			for r.Op == OCONVNOP {
				r = r.Left
			}
			r = Nod(OADDR, r, nil)
			r.Etype = 1 // addr does not escape

			//warnl(n->lineno, "typedmemmove %T %N", t, r);
			n = mkcall1(writebarrierfn("typedmemmove", t, r.Left.Type), nil, init, typename(t), l, r)
		}
	}

	return n
}

func convas(n *Node, init **NodeList) *Node {
	var lt *Type
	var rt *Type
	var map_ *Node
	var key *Node
	var val *Node

	if n.Op != OAS {
		Fatal("convas: not OAS %v", Oconv(int(n.Op), 0))
	}

	n.Typecheck = 1

	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 f *Node
	var a *Node
	var n *Node
	var l *NodeList
	var r *NodeList
	var g *NodeList
	var c int
	var d int
	var t int

	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
	}

	g = nil // fncalls assigned to tempnames
	f = nil // last fncall assigned to stack
	r = nil // non fncalls and tempnames assigned to stack
	d = 0
	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 list *NodeList
	var early *NodeList
	var mapinit *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.
	early = nil

	mapinit = nil
	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) != 0 {
				reorder3save(&l.Right, all, list, &early)
				l = l.Left
				continue
			}

			break
		}

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

		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) {
	var n *Node
	var q *Node

	n = *np
	if !(aliased(n, all, stop) != 0) {
		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 {
			Fatal("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) != 0 {
			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) int {
	var memwrite int
	var varwrite int
	var a *Node
	var l *NodeList

	if n == nil {
		return 0
	}

	// 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
	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 != 0 {
				varwrite = 1
				continue
			}

			if vmatch2(a, n) != 0 {
				// Direct hit.
				return 1
			}
		}
	}

	// 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 0
	}

	// 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) != 0 {
		return 0
	}

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

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

	switch n.Op {
	case OLITERAL:
		return 1

	case ONAME:
		switch n.Class {
		case PAUTO,
			PPARAM,
			PPARAMOUT:
			if !(n.Addrtaken != 0) {
				return 1
			}
		}

		return 0

	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 bool2int(varexpr(n.Left) != 0 && varexpr(n.Right) != 0)
	}

	// Be conservative.
	return 0
}

/*
 * is the name l mentioned in r?
 */
func vmatch2(l *Node, r *Node) int {
	var ll *NodeList

	if r == nil {
		return 0
	}
	switch r.Op {
	// match each right given left
	case ONAME:
		return bool2int(l == r)

	case OLITERAL:
		return 0
	}

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

/*
 * is any name mentioned in l also mentioned in r?
 * called by sinit.c
 */
func vmatch1(l *Node, r *Node) int {
	var ll *NodeList

	/*
	 * isolate all left sides
	 */
	if l == nil || r == nil {
		return 0
	}
	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 1
			}
		}

		return vmatch2(l, r)

	case OLITERAL:
		return 0
	}

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

/*
 * 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 t *Type
	var savet Iter
	var v *Node
	var as *Node
	var nn *NodeList

	nn = nil
	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.", Nconv(v, 0))
		}
		if v.Alloc == nil {
			v.Alloc = callnew(v.Type)
		}
		nn = list(nn, Nod(OAS, v.Heapaddr, v.Alloc))
		if v.Class&^PHEAP != PPARAMOUT {
			as = Nod(OAS, v, v.Stackparam)
			v.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 t *Type
	var savet Iter
	var v *Node
	var nn *NodeList

	nn = nil
	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.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() {
	var nn *NodeList
	var lno int32

	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.Enter = concat(Curfn.Enter, nn)
	lineno = Curfn.Endlineno
	Curfn.Exit = returnsfromheap(Getoutarg(Curfn.Type))
	lineno = lno
}

func vmkcall(fn *Node, t *Type, init **NodeList, va []*Node) *Node {
	var i int
	var n int
	var r *Node
	var args *NodeList

	if fn.Type == nil || fn.Type.Etype != TFUNC {
		Fatal("mkcall %v %v", Nconv(fn, 0), Tconv(fn.Type, 0))
	}

	args = nil
	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 {
	var fn *Node
	var i int

	if t.Etype != TCHAN {
		Fatal("chanfn %v", Tconv(t, 0))
	}
	fn = syslook(name, 1)
	for i = 0; i < n; i++ {
		argtype(fn, t.Type)
	}
	return fn
}

func mapfn(name string, t *Type) *Node {
	var fn *Node

	if t.Etype != TMAP {
		Fatal("mapfn %v", Tconv(t, 0))
	}
	fn = syslook(name, 1)
	argtype(fn, t.Down)
	argtype(fn, t.Type)
	argtype(fn, t.Down)
	argtype(fn, t.Type)
	return fn
}

func mapfndel(name string, t *Type) *Node {
	var fn *Node

	if t.Etype != TMAP {
		Fatal("mapfn %v", Tconv(t, 0))
	}
	fn = syslook(name, 1)
	argtype(fn, t.Down)
	argtype(fn, t.Type)
	argtype(fn, t.Down)
	return fn
}

func writebarrierfn(name string, l *Type, r *Type) *Node {
	var fn *Node

	fn = syslook(name, 1)
	argtype(fn, l)
	argtype(fn, r)
	return fn
}

func addstr(n *Node, init **NodeList) *Node {
	var r *Node
	var cat *Node
	var slice *Node
	var buf *Node
	var args *NodeList
	var l *NodeList
	var c int
	var sz int64
	var t *Type

	// 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 = 0
		for l = n.List; l != nil; l = l.Next {
			if n.Op == OLITERAL {
				sz += int64(len(n.Val.U.Sval.S))
			}
		}

		// 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]))
	}

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

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

	cat = syslook(namebuf, 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(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 {
	var l *NodeList
	var l1 *Node
	var l2 *Node
	var nt *Node
	var nif *Node
	var fn *Node
	var nptr1 *Node
	var nptr2 *Node
	var nwid *Node
	var s *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
	l = nil
	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.Ntest = Nod(OGT, nt, Nodintconst(0))

	// instantiate growslice(Type*, []any, int64) []any
	fn = syslook("growslice", 1)

	argtype(fn, s.Type.Type)
	argtype(fn, s.Type.Type)

	// s = growslice(T, s, n)
	nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, conv(nt, Types[TINT64]))))

	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)
		argtype(fn, l1.Type)
		argtype(fn, 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
		if l2.Type.Etype == TSTRING {
			fn = syslook("slicestringcopy", 1)
		} else {
			fn = syslook("slicecopy", 1)
		}
		argtype(fn, l1.Type)
		argtype(fn, 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 = 1
		nptr1 = Nod(OADDR, nptr1, nil)

		nptr2 = Nod(OSPTR, l2, nil)

		fn = syslook("memmove", 1)
		argtype(fn, s.Type.Type) // 1 old []any
		argtype(fn, s.Type.Type) // 2 ret []any

		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
}

// expand append(src, a [, b]* ) to
//
//   init {
//     s := src
//     const argc = len(args) - 1
//     if cap(s) - len(s) < argc {
//	    s = growslice(s, argc)
//     }
//     n := len(s)
//     s = s[:n+argc]
//     s[n] = a
//     s[n+1] = b
//     ...
//   }
//   s
func walkappend(n *Node, init **NodeList) *Node {
	var l *NodeList
	var a *NodeList
	var nsrc *Node
	var ns *Node
	var nn *Node
	var na *Node
	var nx *Node
	var fn *Node
	var argc int

	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)
	}

	nsrc = n.List.N

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

	l = nil

	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.Ntest = Nod(OLT, Nod(OSUB, Nod(OCAP, ns, nil), Nod(OLEN, ns, nil)), na)

	fn = syslook("growslice", 1) //   growslice(<type>, old []T, n int64) (ret []T)
	argtype(fn, ns.Type.Type)    // 1 old []any
	argtype(fn, ns.Type.Type)    // 2 ret []any

	nx.Nbody = list1(Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, conv(na, Types[TINT64]))))

	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 = 1
		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 {
	var nl *Node
	var nr *Node
	var nfrm *Node
	var nto *Node
	var nif *Node
	var nlen *Node
	var nwid *Node
	var fn *Node
	var l *NodeList

	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 {
		if n.Right.Type.Etype == TSTRING {
			fn = syslook("slicestringcopy", 1)
		} else {
			fn = syslook("slicecopy", 1)
		}
		argtype(fn, n.Left.Type)
		argtype(fn, 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)
	l = nil
	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.Ntest = 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)

	argtype(fn, nl.Type.Type)
	argtype(fn, 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
}

// Generate frontend part for OSLICE[3][ARR|STR]
//
func sliceany(n *Node, init **NodeList) *Node {
	var bounded int
	var slice3 int
	var src *Node
	var lb *Node
	var hb *Node
	var cb *Node
	var bound *Node
	var chk *Node
	var chk0 *Node
	var chk1 *Node
	var chk2 *Node
	var lbv int64
	var hbv int64
	var cbv int64
	var bv int64
	var w int64
	var bt *Type

	//	print("before sliceany: %+N\n", n);

	src = n.Left

	lb = n.Right.Left
	slice3 = bool2int(n.Op == OSLICE3 || n.Op == OSLICE3ARR)
	if slice3 != 0 {
		hb = n.Right.Right.Left
		cb = n.Right.Right.Right
	} else {
		hb = n.Right.Right
		cb = nil
	}

	bounded = int(n.Etype)

	if n.Op == OSLICESTR {
		bound = Nod(OLEN, src, nil)
	} else {
		bound = Nod(OCAP, src, nil)
	}

	typecheck(&bound, Erv)
	walkexpr(&bound, init) // if src is an array, bound will be a const now.

	// static checks if possible
	bv = 1 << 50

	if Isconst(bound, CTINT) != 0 {
		if !(Smallintconst(bound) != 0) {
			Yyerror("array len too large")
		} else {
			bv = Mpgetfix(bound.Val.U.Xval)
		}
	}

	if Isconst(cb, CTINT) != 0 {
		cbv = Mpgetfix(cb.Val.U.Xval)
		if cbv < 0 || cbv > bv {
			Yyerror("slice index out of bounds")
		}
	}

	if Isconst(hb, CTINT) != 0 {
		hbv = Mpgetfix(hb.Val.U.Xval)
		if hbv < 0 || hbv > bv {
			Yyerror("slice index out of bounds")
		}
	}

	if Isconst(lb, CTINT) != 0 {
		lbv = Mpgetfix(lb.Val.U.Xval)
		if lbv < 0 || lbv > bv {
			Yyerror("slice index out of bounds")
			lbv = -1
		}

		if lbv == 0 {
			lb = nil
		}
	}

	// Checking src[lb:hb:cb] or src[lb:hb].
	// if chk0 || chk1 || chk2 { panicslice() }
	chk = nil

	chk0 = nil // cap(src) < cb
	chk1 = nil // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
	chk2 = nil // hb < lb

	// All comparisons are unsigned to avoid testing < 0.
	bt = Types[Simtype[TUINT]]

	if cb != nil && cb.Type.Width > 4 {
		bt = Types[TUINT64]
	}
	if hb != nil && hb.Type.Width > 4 {
		bt = Types[TUINT64]
	}
	if lb != nil && lb.Type.Width > 4 {
		bt = Types[TUINT64]
	}

	bound = cheapexpr(conv(bound, bt), init)

	if cb != nil {
		cb = cheapexpr(conv(cb, bt), init)
		if !(bounded != 0) {
			chk0 = Nod(OLT, bound, cb)
		}
	} else if slice3 != 0 {
		// When we figure out what this means, implement it.
		Fatal("slice3 with cb == N") // rejected by parser
	}

	if hb != nil {
		hb = cheapexpr(conv(hb, bt), init)
		if !(bounded != 0) {
			if cb != nil {
				chk1 = Nod(OLT, cb, hb)
			} else {
				chk1 = Nod(OLT, bound, hb)
			}
		}
	} else if slice3 != 0 {
		// When we figure out what this means, implement it.
		Fatal("slice3 with hb == N") // rejected by parser
	} else if n.Op == OSLICEARR {
		hb = bound
	} else {
		hb = Nod(OLEN, src, nil)
		typecheck(&hb, Erv)
		walkexpr(&hb, init)
		hb = cheapexpr(conv(hb, bt), init)
	}

	if lb != nil {
		lb = cheapexpr(conv(lb, bt), init)
		if !(bounded != 0) {
			chk2 = Nod(OLT, hb, lb)
		}
	}

	if chk0 != nil || chk1 != nil || chk2 != nil {
		chk = Nod(OIF, nil, nil)
		chk.Nbody = list1(mkcall("panicslice", nil, init))
		chk.Likely = -1
		if chk0 != nil {
			chk.Ntest = chk0
		}
		if chk1 != nil {
			if chk.Ntest == nil {
				chk.Ntest = chk1
			} else {
				chk.Ntest = Nod(OOROR, chk.Ntest, chk1)
			}
		}

		if chk2 != nil {
			if chk.Ntest == nil {
				chk.Ntest = chk2
			} else {
				chk.Ntest = Nod(OOROR, chk.Ntest, chk2)
			}
		}

		typecheck(&chk, Etop)
		walkstmt(&chk)
		*init = concat(*init, chk.Ninit)
		chk.Ninit = nil
		*init = list(*init, chk)
	}

	// prepare new cap, len and offs for backend cgen_slice
	// cap = bound [ - lo ]
	n.Right = nil

	n.List = nil
	if !(slice3 != 0) {
		cb = bound
	}
	if lb == nil {
		bound = conv(cb, Types[Simtype[TUINT]])
	} else {
		bound = Nod(OSUB, conv(cb, Types[Simtype[TUINT]]), conv(lb, Types[Simtype[TUINT]]))
	}
	typecheck(&bound, Erv)
	walkexpr(&bound, init)
	n.List = list(n.List, bound)

	// len = hi [ - lo]
	if lb == nil {
		hb = conv(hb, Types[Simtype[TUINT]])
	} else {
		hb = Nod(OSUB, conv(hb, Types[Simtype[TUINT]]), conv(lb, Types[Simtype[TUINT]]))
	}
	typecheck(&hb, Erv)
	walkexpr(&hb, init)
	n.List = list(n.List, hb)

	// offs = [width *] lo, but omit if zero
	if lb != nil {
		if n.Op == OSLICESTR {
			w = 1
		} else {
			w = n.Type.Type.Width
		}
		lb = conv(lb, Types[TUINTPTR])
		if w > 1 {
			lb = Nod(OMUL, Nodintconst(w), lb)
		}
		typecheck(&lb, Erv)
		walkexpr(&lb, init)
		n.List = list(n.List, lb)
	}

	//	print("after sliceany: %+N\n", n);

	return n
}

func eqfor(t *Type, needsize *int) *Node {
	var a int
	var n *Node
	var ntype *Node
	var sym *Sym

	// 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 {
		Fatal("eqfor %v", Tconv(t, 0))
	}

	if a == AMEM {
		n = syslook("memequal", 1)
		argtype(n, t)
		argtype(n, 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 {
	var t1 *Type
	var n int

	n = 0
	for t1 = t.Type; t1 != nil; t1 = t1.Down {
		n++
	}
	return n
}

func walkcompare(np **Node, init **NodeList) {
	var n *Node
	var l *Node
	var r *Node
	var call *Node
	var a *Node
	var li *Node
	var ri *Node
	var expr *Node
	var cmpl *Node
	var cmpr *Node
	var x *Node
	var ok *Node
	var andor int
	var i int
	var needsize int
	var t *Type
	var t1 *Type

	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.
	l = nil

	r = nil
	if Isinter(n.Left.Type) != 0 && !(Isinter(n.Right.Type) != 0) {
		l = n.Left
		r = n.Right
	} else if !(Isinter(n.Left.Type) != 0) && Isinter(n.Right.Type) != 0 {
		l = n.Right
		r = n.Left
	}

	if l != nil {
		x = temp(r.Type)
		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)
		goto ret
	}

	// 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) != 0 {
			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) != 0) || !(islvalue(cmpr) != 0) {
		Fatal("arguments of comparison must be lvalues - %v %v", Nconv(cmpl, 0), Nconv(cmpr, 0))
	}

	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)

	expr = nil
	andor = OANDAND
	if n.Op == ONE {
		andor = OOROR
	}

	if t.Etype == TARRAY && t.Bound <= 4 && issimple[t.Type.Etype] != 0 {
		// Four or fewer elements of a basic type.
		// Unroll comparisons.
		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(bool2int(n.Op == OEQ))
		}
		r = expr
		goto ret
	}

	if t.Etype == TSTRUCT && countfield(t) <= 4 {
		// Struct of four or fewer fields.
		// Inline comparisons.
		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(bool2int(n.Op == OEQ))
		}
		r = expr
		goto ret
	}

	// Chose not to inline.  Call equality function directly.
	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)
	}
	goto ret

ret:
	typecheck(&r, Erv)
	walkexpr(&r, init)
	if r.Type != n.Type {
		r = Nod(OCONVNOP, r, nil)
		r.Type = n.Type
		r.Typecheck = 1
	}

	*np = r
	return
}

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

		case ONAME:
			return bool2int(a == b)

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

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

		a = a.Left
		b = b.Left
	}

	return 0
}

func walkrotate(np **Node) {
	var w int
	var sl int
	var sr int
	var s int
	var l *Node
	var r *Node
	var n *Node

	if 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] != 0 || l.Op == r.Op {
		return
	}

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

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

	if Smallintconst(l.Right) != 0 && Smallintconst(r.Right) != 0 {
		sl = int(Mpgetfix(l.Right.Val.U.Xval))
		if sl >= 0 {
			sr = int(Mpgetfix(r.Right.Val.U.Xval))
			if sr >= 0 && sl+sr == w {
				goto yes
			}
		}
		return
	}

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

	// Rewrite left shift half to left rotate.
yes:
	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.Xval))

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

	*np = n
	return
}

/*
 * walkmul rewrites integer multiplication by powers of two as shifts.
 */
func walkmul(np **Node, init **NodeList) {
	var n *Node
	var nl *Node
	var nr *Node
	var pow int
	var neg int
	var w int

	n = *np
	if !(Isint[n.Type.Etype] != 0) {
		return
	}

	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).
	if Mpgetfix(nr.Val.U.Xval) == 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) {
	var n *Node
	var nl *Node
	var nr *Node
	// if >= 0, nr is 1<<pow // 1 if nr is negative.
	var nc *Node
	var n1 *Node
	var n2 *Node
	var n3 *Node
	var n4 *Node
	var pow int
	var s int
	var w int
	var twide *Type
	var m Magic

	// TODO(minux)
	if 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
	pow = powtwo(nr)
	if pow >= 1000 {
		// negative power of 2
		s = 1

		pow -= 1000
	}

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

	if pow < 0 {
		goto divbymul
	}

	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] != 0 {
			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.Xval)-1)
		} else {
			// n = nl >> pow
			n.Op = ORSH

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

		n.Typecheck = 0
		n.Right = nc
	}

	goto ret

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

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

	if m.Bad != 0 {
		return
	}

	// We have a quick division method so use it
	// for modulo too.
	if n.Op == OMOD {
		goto longmod
	}

	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(OMUL, nl, nc)
		typecheck(&n1, Erv)
		n1.Op = OHMUL
		if m.Ua != 0 {
			// Select a Go type with (at least) twice the width.
			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(OMUL, nl, nc)
		typecheck(&n1, Erv)
		n1.Op = OHMUL
		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

	// rewrite as A%B = A - (A/B*B).
longmod:
	n1 = Nod(ODIV, nl, nr)

	n2 = Nod(OMUL, n1, nr)
	n = Nod(OSUB, nl, n2)
	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) int {
	var v int64
	var bits int32
	var sign int

	if n.Type == nil || !(Isint[n.Type.Etype] != 0) {
		return 0
	}

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

	if Smallintconst(n) != 0 {
		v = Mpgetfix(n.Val.U.Xval)
		return bool2int(0 <= v && v < max)
	}

	switch n.Op {
	case OAND:
		v = -1
		if Smallintconst(n.Left) != 0 {
			v = Mpgetfix(n.Left.Val.U.Xval)
		} else if Smallintconst(n.Right) != 0 {
			v = Mpgetfix(n.Right.Val.U.Xval)
		}

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

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

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

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

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

	return 0
}

func usefield(n *Node) {
	var field *Type
	var l *Type

	if !(obj.Fieldtrack_enabled != 0) {
		return
	}

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

	case ODOT,
		ODOTPTR:
		break
	}

	field = n.Paramfld
	if field == nil {
		Fatal("usefield %v %v without paramfld", Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, 0))
	}
	if field.Note == nil || !strings.Contains(field.Note.S, "go:\"track\"") {
		return
	}

	// dedup on list
	if field.Lastfn == Curfn {
		return
	}
	field.Lastfn = Curfn
	field.Outer = n.Left.Type
	if Isptr[field.Outer.Etype] != 0 {
		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)")
	}

	l = typ(0)
	l.Type = field
	l.Down = Curfn.Paramfld
	Curfn.Paramfld = l
}

func candiscardlist(l *NodeList) int {
	for ; l != nil; l = l.Next {
		if !(candiscard(l.N) != 0) {
			return 0
		}
	}
	return 1
}

func candiscard(n *Node) int {
	if n == nil {
		return 1
	}

	switch n.Op {
	default:
		return 0

		// 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) != 0 && mpcmpfixc(n.Right.Val.U.Xval, 0) != 0 {
			break
		}
		if Isconst(n.Right, CTFLT) != 0 && mpcmpfltc(n.Right.Val.U.Fval, 0) != 0 {
			break
		}
		return 0

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

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

	if !(candiscard(n.Left) != 0) || !(candiscard(n.Right) != 0) || !(candiscard(n.Ntest) != 0) || !(candiscard(n.Nincr) != 0) || !(candiscardlist(n.Ninit) != 0) || !(candiscardlist(n.Nbody) != 0) || !(candiscardlist(n.Nelse) != 0) || !(candiscardlist(n.List) != 0) || !(candiscardlist(n.Rlist) != 0) {
		return 0
	}

	return 1
}

// 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) {
	var n *Node
	var a *Node
	var fn *Node
	var t *Node
	var oldfn *Node
	var l *NodeList
	var printargs *NodeList
	var num int
	var buf string

	n = *np

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

	t = Nod(OTFUNC, nil, nil)
	num = 0
	printargs = nil
	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.Nname = newname(Lookup(buf))
	fn.Nname.Defn = fn
	fn.Nname.Ntype = t
	declare(fn.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.Nname
	a.List = n.List
	typecheck(&a, Etop)
	walkexpr(&a, init)
	*np = a
}
