diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile
new file mode 100644
index 0000000..58e25fa
--- /dev/null
+++ b/src/cmd/gc/Makefile
@@ -0,0 +1,17 @@
+# Copyright 2012 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.
+
+include ../../Make.dist
+
+install: y.tab.h builtin.c
+
+y.tab.h: go.y go.errors bisonerrors
+	bison -v -y -d go.y
+	# make yystate global, yytname mutable
+	cat y.tab.c | sed '/ int yystate;/d; s/int yychar;/int yychar, yystate;/; s/static const char \*const yytname/const char *yytname/; s/char const \*yymsgp/char *yymsgp/' >y1.tab.c
+	mv y1.tab.c y.tab.c
+	awk -f bisonerrors y.output go.errors >yerr.h
+
+builtin.c: runtime.go unsafe.go
+	./mkbuiltin
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
new file mode 100644
index 0000000..63ed2e5
--- /dev/null
+++ b/src/cmd/gc/align.c
@@ -0,0 +1,680 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+/*
+ * machine size and rounding
+ * alignment is dictated around
+ * the size of a pointer, set in betypeinit
+ * (see ../6g/galign.c).
+ */
+
+static int defercalc;
+
+vlong
+rnd(vlong o, vlong r)
+{
+	if(r < 1 || r > 8 || (r&(r-1)) != 0)
+		fatal("rnd");
+	return (o+r-1)&~(r-1);
+}
+
+static void
+offmod(Type *t)
+{
+	Type *f;
+	int32 o;
+
+	o = 0;
+	for(f=t->type; f!=T; f=f->down) {
+		if(f->etype != TFIELD)
+			fatal("offmod: not TFIELD: %lT", f);
+		f->width = o;
+		o += widthptr;
+		if(o >= MAXWIDTH) {
+			yyerror("interface too large");
+			o = widthptr;
+		}
+	}
+}
+
+static vlong
+widstruct(Type *errtype, Type *t, vlong o, int flag)
+{
+	Type *f;
+	int64 w;
+	int32 maxalign;
+	
+	maxalign = flag;
+	if(maxalign < 1)
+		maxalign = 1;
+	for(f=t->type; f!=T; f=f->down) {
+		if(f->etype != TFIELD)
+			fatal("widstruct: not TFIELD: %lT", f);
+		if(f->type == T) {
+			// broken field, just skip it so that other valid fields
+			// get a width.
+			continue;
+		}
+		dowidth(f->type);
+		if(f->type->align > maxalign)
+			maxalign = f->type->align;
+		if(f->type->width < 0)
+			fatal("invalid width %lld", f->type->width);
+		w = f->type->width;
+		if(f->type->align > 0)
+			o = rnd(o, f->type->align);
+		f->width = o;	// really offset for TFIELD
+		if(f->nname != N) {
+			// this same stackparam logic is in addrescapes
+			// in typecheck.c.  usually addrescapes runs after
+			// widstruct, in which case we could drop this,
+			// but function closure functions are the exception.
+			if(f->nname->stackparam) {
+				f->nname->stackparam->xoffset = o;
+				f->nname->xoffset = 0;
+			} else
+				f->nname->xoffset = o;
+		}
+		o += w;
+		if(o >= MAXWIDTH) {
+			yyerror("type %lT too large", errtype);
+			o = 8;  // small but nonzero
+		}
+	}
+	// final width is rounded
+	if(flag)
+		o = rnd(o, maxalign);
+	t->align = maxalign;
+
+	// type width only includes back to first field's offset
+	if(t->type == T)
+		t->width = 0;
+	else
+		t->width = o - t->type->width;
+	return o;
+}
+
+void
+dowidth(Type *t)
+{
+	int32 et;
+	int64 w;
+	int lno;
+	Type *t1;
+
+	if(widthptr == 0)
+		fatal("dowidth without betypeinit");
+
+	if(t == T)
+		return;
+
+	if(t->width > 0)
+		return;
+
+	if(t->width == -2) {
+		lno = lineno;
+		lineno = t->lineno;
+		if(!t->broke) {
+			t->broke = 1;
+			yyerror("invalid recursive type %T", t);
+		}
+		t->width = 0;
+		lineno = lno;
+		return;
+	}
+
+	// break infinite recursion if the broken recursive type
+	// is referenced again
+	if(t->broke && t->width == 0)
+		return;
+
+	// defer checkwidth calls until after we're done
+	defercalc++;
+
+	lno = lineno;
+	lineno = t->lineno;
+	t->width = -2;
+	t->align = 0;
+
+	et = t->etype;
+	switch(et) {
+	case TFUNC:
+	case TCHAN:
+	case TMAP:
+	case TSTRING:
+		break;
+
+	default:
+		/* simtype == 0 during bootstrap */
+		if(simtype[t->etype] != 0)
+			et = simtype[t->etype];
+		break;
+	}
+
+	w = 0;
+	switch(et) {
+	default:
+		fatal("dowidth: unknown type: %T", t);
+		break;
+
+	/* compiler-specific stuff */
+	case TINT8:
+	case TUINT8:
+	case TBOOL:		// bool is int8
+		w = 1;
+		break;
+	case TINT16:
+	case TUINT16:
+		w = 2;
+		break;
+	case TINT32:
+	case TUINT32:
+	case TFLOAT32:
+		w = 4;
+		break;
+	case TINT64:
+	case TUINT64:
+	case TFLOAT64:
+	case TCOMPLEX64:
+		w = 8;
+		t->align = widthreg;
+		break;
+	case TCOMPLEX128:
+		w = 16;
+		t->align = widthreg;
+		break;
+	case TPTR32:
+		w = 4;
+		checkwidth(t->type);
+		break;
+	case TPTR64:
+		w = 8;
+		checkwidth(t->type);
+		break;
+	case TUNSAFEPTR:
+		w = widthptr;
+		break;
+	case TINTER:		// implemented as 2 pointers
+		w = 2*widthptr;
+		t->align = widthptr;
+		offmod(t);
+		break;
+	case TCHAN:		// implemented as pointer
+		w = widthptr;
+		checkwidth(t->type);
+
+		// make fake type to check later to
+		// trigger channel argument check.
+		t1 = typ(TCHANARGS);
+		t1->type = t;
+		checkwidth(t1);
+		break;
+	case TCHANARGS:
+		t1 = t->type;
+		dowidth(t->type);	// just in case
+		if(t1->type->width >= (1<<16))
+			yyerror("channel element type too large (>64kB)");
+		t->width = 1;
+		break;
+	case TMAP:		// implemented as pointer
+		w = widthptr;
+		checkwidth(t->type);
+		checkwidth(t->down);
+		break;
+	case TFORW:		// should have been filled in
+		if(!t->broke)
+			yyerror("invalid recursive type %T", t);
+		w = 1;	// anything will do
+		break;
+	case TANY:
+		// dummy type; should be replaced before use.
+		if(!debug['A'])
+			fatal("dowidth any");
+		w = 1;	// anything will do
+		break;
+	case TSTRING:
+		if(sizeof_String == 0)
+			fatal("early dowidth string");
+		w = sizeof_String;
+		t->align = widthptr;
+		break;
+	case TARRAY:
+		if(t->type == T)
+			break;
+		if(t->bound >= 0) {
+			uint64 cap;
+
+			dowidth(t->type);
+			if(t->type->width != 0) {
+				cap = (MAXWIDTH-1) / t->type->width;
+				if(t->bound > cap)
+					yyerror("type %lT larger than address space", t);
+			}
+			w = t->bound * t->type->width;
+			t->align = t->type->align;
+		}
+		else if(t->bound == -1) {
+			w = sizeof_Array;
+			checkwidth(t->type);
+			t->align = widthptr;
+		}
+		else if(t->bound == -100) {
+			if(!t->broke) {
+				yyerror("use of [...] array outside of array literal");
+				t->broke = 1;
+			}
+		}
+		else
+			fatal("dowidth %T", t);	// probably [...]T
+		break;
+
+	case TSTRUCT:
+		if(t->funarg)
+			fatal("dowidth fn struct %T", t);
+		w = widstruct(t, t, 0, 1);
+		break;
+
+	case TFUNC:
+		// make fake type to check later to
+		// trigger function argument computation.
+		t1 = typ(TFUNCARGS);
+		t1->type = t;
+		checkwidth(t1);
+
+		// width of func type is pointer
+		w = widthptr;
+		break;
+
+	case TFUNCARGS:
+		// function is 3 cated structures;
+		// compute their widths as side-effect.
+		t1 = t->type;
+		w = widstruct(t->type, *getthis(t1), 0, 0);
+		w = widstruct(t->type, *getinarg(t1), w, widthreg);
+		w = widstruct(t->type, *getoutarg(t1), w, widthreg);
+		t1->argwid = w;
+		if(w%widthreg)
+			warn("bad type %T %d\n", t1, w);
+		t->align = 1;
+		break;
+	}
+
+	if(widthptr == 4 && w != (int32)w)
+		yyerror("type %T too large", t);
+
+	t->width = w;
+	if(t->align == 0) {
+		if(w > 8 || (w&(w-1)) != 0)
+			fatal("invalid alignment for %T", t);
+		t->align = w;
+	}
+	lineno = lno;
+
+	if(defercalc == 1)
+		resumecheckwidth();
+	else
+		--defercalc;
+}
+
+/*
+ * when a type's width should be known, we call checkwidth
+ * to compute it.  during a declaration like
+ *
+ *	type T *struct { next T }
+ *
+ * it is necessary to defer the calculation of the struct width
+ * until after T has been initialized to be a pointer to that struct.
+ * similarly, during import processing structs may be used
+ * before their definition.  in those situations, calling
+ * defercheckwidth() stops width calculations until
+ * resumecheckwidth() is called, at which point all the
+ * checkwidths that were deferred are executed.
+ * dowidth should only be called when the type's size
+ * is needed immediately.  checkwidth makes sure the
+ * size is evaluated eventually.
+ */
+typedef struct TypeList TypeList;
+struct TypeList {
+	Type *t;
+	TypeList *next;
+};
+
+static TypeList *tlfree;
+static TypeList *tlq;
+
+void
+checkwidth(Type *t)
+{
+	TypeList *l;
+
+	if(t == T)
+		return;
+
+	// function arg structs should not be checked
+	// outside of the enclosing function.
+	if(t->funarg)
+		fatal("checkwidth %T", t);
+
+	if(!defercalc) {
+		dowidth(t);
+		return;
+	}
+	if(t->deferwidth)
+		return;
+	t->deferwidth = 1;
+
+	l = tlfree;
+	if(l != nil)
+		tlfree = l->next;
+	else
+		l = mal(sizeof *l);
+
+	l->t = t;
+	l->next = tlq;
+	tlq = l;
+}
+
+void
+defercheckwidth(void)
+{
+	// we get out of sync on syntax errors, so don't be pedantic.
+	if(defercalc && nerrors == 0)
+		fatal("defercheckwidth");
+	defercalc = 1;
+}
+
+void
+resumecheckwidth(void)
+{
+	TypeList *l;
+
+	if(!defercalc)
+		fatal("resumecheckwidth");
+	for(l = tlq; l != nil; l = tlq) {
+		l->t->deferwidth = 0;
+		tlq = l->next;
+		dowidth(l->t);
+		l->next = tlfree;
+		tlfree = l;
+	}
+	defercalc = 0;
+}
+
+void
+typeinit(void)
+{
+	int i, etype, sameas;
+	Type *t;
+	Sym *s, *s1;
+
+	if(widthptr == 0)
+		fatal("typeinit before betypeinit");
+
+	for(i=0; i<NTYPE; i++)
+		simtype[i] = i;
+
+	types[TPTR32] = typ(TPTR32);
+	dowidth(types[TPTR32]);
+
+	types[TPTR64] = typ(TPTR64);
+	dowidth(types[TPTR64]);
+	
+	t = typ(TUNSAFEPTR);
+	types[TUNSAFEPTR] = t;
+	t->sym = pkglookup("Pointer", unsafepkg);
+	t->sym->def = typenod(t);
+	
+	dowidth(types[TUNSAFEPTR]);
+
+	tptr = TPTR32;
+	if(widthptr == 8)
+		tptr = TPTR64;
+
+	for(i=TINT8; i<=TUINT64; i++)
+		isint[i] = 1;
+	isint[TINT] = 1;
+	isint[TUINT] = 1;
+	isint[TUINTPTR] = 1;
+
+	isfloat[TFLOAT32] = 1;
+	isfloat[TFLOAT64] = 1;
+
+	iscomplex[TCOMPLEX64] = 1;
+	iscomplex[TCOMPLEX128] = 1;
+
+	isptr[TPTR32] = 1;
+	isptr[TPTR64] = 1;
+
+	isforw[TFORW] = 1;
+
+	issigned[TINT] = 1;
+	issigned[TINT8] = 1;
+	issigned[TINT16] = 1;
+	issigned[TINT32] = 1;
+	issigned[TINT64] = 1;
+
+	/*
+	 * initialize okfor
+	 */
+	for(i=0; i<NTYPE; i++) {
+		if(isint[i] || i == TIDEAL) {
+			okforeq[i] = 1;
+			okforcmp[i] = 1;
+			okforarith[i] = 1;
+			okforadd[i] = 1;
+			okforand[i] = 1;
+			okforconst[i] = 1;
+			issimple[i] = 1;
+			minintval[i] = mal(sizeof(*minintval[i]));
+			maxintval[i] = mal(sizeof(*maxintval[i]));
+		}
+		if(isfloat[i]) {
+			okforeq[i] = 1;
+			okforcmp[i] = 1;
+			okforadd[i] = 1;
+			okforarith[i] = 1;
+			okforconst[i] = 1;
+			issimple[i] = 1;
+			minfltval[i] = mal(sizeof(*minfltval[i]));
+			maxfltval[i] = mal(sizeof(*maxfltval[i]));
+		}
+		if(iscomplex[i]) {
+			okforeq[i] = 1;
+			okforadd[i] = 1;
+			okforarith[i] = 1;
+			okforconst[i] = 1;
+			issimple[i] = 1;
+		}
+	}
+
+	issimple[TBOOL] = 1;
+
+	okforadd[TSTRING] = 1;
+
+	okforbool[TBOOL] = 1;
+
+	okforcap[TARRAY] = 1;
+	okforcap[TCHAN] = 1;
+
+	okforconst[TBOOL] = 1;
+	okforconst[TSTRING] = 1;
+
+	okforlen[TARRAY] = 1;
+	okforlen[TCHAN] = 1;
+	okforlen[TMAP] = 1;
+	okforlen[TSTRING] = 1;
+
+	okforeq[TPTR32] = 1;
+	okforeq[TPTR64] = 1;
+	okforeq[TUNSAFEPTR] = 1;
+	okforeq[TINTER] = 1;
+	okforeq[TCHAN] = 1;
+	okforeq[TSTRING] = 1;
+	okforeq[TBOOL] = 1;
+	okforeq[TMAP] = 1;	// nil only; refined in typecheck
+	okforeq[TFUNC] = 1;	// nil only; refined in typecheck
+	okforeq[TARRAY] = 1;	// nil slice only; refined in typecheck
+	okforeq[TSTRUCT] = 1;	// it's complicated; refined in typecheck
+
+	okforcmp[TSTRING] = 1;
+
+	for(i=0; i<nelem(okfor); i++)
+		okfor[i] = okfornone;
+
+	// binary
+	okfor[OADD] = okforadd;
+	okfor[OAND] = okforand;
+	okfor[OANDAND] = okforbool;
+	okfor[OANDNOT] = okforand;
+	okfor[ODIV] = okforarith;
+	okfor[OEQ] = okforeq;
+	okfor[OGE] = okforcmp;
+	okfor[OGT] = okforcmp;
+	okfor[OLE] = okforcmp;
+	okfor[OLT] = okforcmp;
+	okfor[OMOD] = okforand;
+	okfor[OMUL] = okforarith;
+	okfor[ONE] = okforeq;
+	okfor[OOR] = okforand;
+	okfor[OOROR] = okforbool;
+	okfor[OSUB] = okforarith;
+	okfor[OXOR] = okforand;
+	okfor[OLSH] = okforand;
+	okfor[ORSH] = okforand;
+
+	// unary
+	okfor[OCOM] = okforand;
+	okfor[OMINUS] = okforarith;
+	okfor[ONOT] = okforbool;
+	okfor[OPLUS] = okforarith;
+
+	// special
+	okfor[OCAP] = okforcap;
+	okfor[OLEN] = okforlen;
+
+	// comparison
+	iscmp[OLT] = 1;
+	iscmp[OGT] = 1;
+	iscmp[OGE] = 1;
+	iscmp[OLE] = 1;
+	iscmp[OEQ] = 1;
+	iscmp[ONE] = 1;
+
+	mpatofix(maxintval[TINT8], "0x7f");
+	mpatofix(minintval[TINT8], "-0x80");
+	mpatofix(maxintval[TINT16], "0x7fff");
+	mpatofix(minintval[TINT16], "-0x8000");
+	mpatofix(maxintval[TINT32], "0x7fffffff");
+	mpatofix(minintval[TINT32], "-0x80000000");
+	mpatofix(maxintval[TINT64], "0x7fffffffffffffff");
+	mpatofix(minintval[TINT64], "-0x8000000000000000");
+
+	mpatofix(maxintval[TUINT8], "0xff");
+	mpatofix(maxintval[TUINT16], "0xffff");
+	mpatofix(maxintval[TUINT32], "0xffffffff");
+	mpatofix(maxintval[TUINT64], "0xffffffffffffffff");
+
+	/* f is valid float if min < f < max.  (min and max are not themselves valid.) */
+	mpatoflt(maxfltval[TFLOAT32], "33554431p103");	/* 2^24-1 p (127-23) + 1/2 ulp*/
+	mpatoflt(minfltval[TFLOAT32], "-33554431p103");
+	mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970");	/* 2^53-1 p (1023-52) + 1/2 ulp */
+	mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970");
+
+	maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32];
+	minfltval[TCOMPLEX64] = minfltval[TFLOAT32];
+	maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64];
+	minfltval[TCOMPLEX128] = minfltval[TFLOAT64];
+
+	/* for walk to use in error messages */
+	types[TFUNC] = functype(N, nil, nil);
+
+	/* types used in front end */
+	// types[TNIL] got set early in lexinit
+	types[TIDEAL] = typ(TIDEAL);
+	types[TINTER] = typ(TINTER);
+
+	/* simple aliases */
+	simtype[TMAP] = tptr;
+	simtype[TCHAN] = tptr;
+	simtype[TFUNC] = tptr;
+	simtype[TUNSAFEPTR] = tptr;
+
+	/* pick up the backend typedefs */
+	for(i=0; typedefs[i].name; i++) {
+		s = lookup(typedefs[i].name);
+		s1 = pkglookup(typedefs[i].name, builtinpkg);
+
+		etype = typedefs[i].etype;
+		if(etype < 0 || etype >= nelem(types))
+			fatal("typeinit: %s bad etype", s->name);
+		sameas = typedefs[i].sameas;
+		if(sameas < 0 || sameas >= nelem(types))
+			fatal("typeinit: %s bad sameas", s->name);
+		simtype[etype] = sameas;
+		minfltval[etype] = minfltval[sameas];
+		maxfltval[etype] = maxfltval[sameas];
+		minintval[etype] = minintval[sameas];
+		maxintval[etype] = maxintval[sameas];
+
+		t = types[etype];
+		if(t != T)
+			fatal("typeinit: %s already defined", s->name);
+
+		t = typ(etype);
+		t->sym = s1;
+
+		dowidth(t);
+		types[etype] = t;
+		s1->def = typenod(t);
+	}
+
+	Array_array = rnd(0, widthptr);
+	Array_nel = rnd(Array_array+widthptr, widthint);
+	Array_cap = rnd(Array_nel+widthint, widthint);
+	sizeof_Array = rnd(Array_cap+widthint, widthptr);
+
+	// string is same as slice wo the cap
+	sizeof_String = rnd(Array_nel+widthint, widthptr);
+
+	dowidth(types[TSTRING]);
+	dowidth(idealstring);
+}
+
+/*
+ * compute total size of f's in/out arguments.
+ */
+int
+argsize(Type *t)
+{
+	Iter save;
+	Type *fp;
+	int64 w, x;
+
+	w = 0;
+
+	fp = structfirst(&save, getoutarg(t));
+	while(fp != T) {
+		x = fp->width + fp->type->width;
+		if(x > w)
+			w = x;
+		fp = structnext(&save);
+	}
+
+	fp = funcfirst(&save, t);
+	while(fp != T) {
+		x = fp->width + fp->type->width;
+		if(x > w)
+			w = x;
+		fp = funcnext(&save);
+	}
+
+	w = (w+widthptr-1) & ~(widthptr-1);
+	if((int)w != w)
+		fatal("argsize too big");
+	return w;
+}
diff --git a/src/cmd/gc/array.c b/src/cmd/gc/array.c
new file mode 100644
index 0000000..611fc9f
--- /dev/null
+++ b/src/cmd/gc/array.c
@@ -0,0 +1,115 @@
+// Copyright 2013 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+enum {
+	DEFAULTCAPACITY = 16,
+};
+
+struct Array
+{
+	int32	length;  // number of elements
+	int32	size;  // element size
+	int32	capacity;  // size of data in elements
+	char	*data;  // element storage
+};
+
+Array*
+arraynew(int32 capacity, int32 size)
+{
+	Array *result;
+
+	if(capacity < 0)
+		fatal("arraynew: capacity %d is not positive", capacity);
+	if(size < 0)
+		fatal("arraynew: size %d is not positive\n", size);
+	result = malloc(sizeof(*result));
+	if(result == nil)
+		fatal("arraynew: malloc failed\n");
+	result->length = 0;
+	result->size = size;
+	result->capacity = capacity == 0 ? DEFAULTCAPACITY : capacity;
+	result->data = malloc(result->capacity * result->size);
+	if(result->data == nil)
+		fatal("arraynew: malloc failed\n");
+	return result;
+}
+
+void
+arrayfree(Array *array)
+{
+	if(array == nil)
+		return;
+	free(array->data);
+	free(array);
+}
+
+int32
+arraylength(Array *array)
+{
+	return array->length;
+}
+
+void*
+arrayget(Array *array, int32 index)
+{
+	if(array == nil)
+		fatal("arrayget: array is nil\n");
+	if(index < 0 || index >= array->length)
+		fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length);
+	return array->data + index * array->size;
+}
+
+void
+arrayset(Array *array, int32 index, void *element)
+{
+	if(array == nil)
+		fatal("arrayset: array is nil\n");
+	if(element == nil)
+		fatal("arrayset: element is nil\n");
+	if(index < 0 || index >= array->length)
+		fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length);
+	memmove(array->data + index * array->size, element, array->size);
+}
+
+static void
+ensurecapacity(Array *array, int32 capacity)
+{
+	int32 newcapacity;
+	char *newdata;
+
+	if(array == nil)
+		fatal("ensurecapacity: array is nil\n");
+	if(capacity < 0)
+		fatal("ensurecapacity: capacity %d is not positive", capacity);
+	if(capacity >= array->capacity) {
+		newcapacity = capacity + (capacity >> 1);
+		newdata = realloc(array->data, newcapacity * array->size);
+		if(newdata == nil)
+			fatal("ensurecapacity: realloc failed\n");
+		array->capacity = newcapacity;
+		array->data = newdata;
+	}
+}
+
+void
+arrayadd(Array *array, void *element)
+{
+	if(array == nil)
+		fatal("arrayset: array is nil\n");
+	if(element == nil)
+		fatal("arrayset: element is nil\n");
+	ensurecapacity(array, array->length + 1);
+	array->length++;
+	arrayset(array, array->length - 1, element);
+}
+
+void
+arraysort(Array *array, int (*cmp)(const void*, const void*))
+{
+	qsort(array->data, array->length, array->size, cmp);
+}
diff --git a/src/cmd/gc/bisonerrors b/src/cmd/gc/bisonerrors
new file mode 100755
index 0000000..fa74c67
--- /dev/null
+++ b/src/cmd/gc/bisonerrors
@@ -0,0 +1,156 @@
+#!/usr/bin/awk -f
+# Copyright 2010 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.
+
+# This program implements the core idea from
+#
+#	Clinton L. Jeffery, Generating LR syntax error messages from examples,
+#	ACM TOPLAS 25(5) (September 2003).  http://doi.acm.org/10.1145/937563.937566
+# 
+# It reads Bison's summary of a grammar followed by a file
+# like go.errors, replacing lines beginning with % by the 
+# yystate and yychar that will be active when an error happens
+# while parsing that line.  
+#
+# Unlike the system described in the paper, the lines in go.errors
+# give grammar symbol name lists, not actual program fragments.
+# This is a little less programmer-friendly but doesn't require being
+# able to run the text through lex.c.
+
+BEGIN{
+	bison = 1
+	grammar = 0
+	states = 0
+	open = 0
+}
+
+# In Grammar section of y.output,
+# record lhs and length of rhs for each rule.
+bison && /^Grammar/ { grammar = 1 }
+bison && /^(Terminals|state 0)/ { grammar = 0 }
+grammar && NF>0 {
+	if($2 != "|") {
+		r = $2
+		sub(/:$/, "", r)
+	}
+	rulelhs[$1] = r
+	rulesize[$1] = NF-2
+	if(rulesize[$1] == 1 && $3 == "%empty") {
+		rulesize[$1] = 0
+	}
+	if(rulesize[$1] == 3 && $3 $4 $5 == "/*empty*/") {
+		rulesize[$1] = 0
+	}
+}
+
+# In state dumps, record shift/reduce actions.
+bison && /^[Ss]tate 0/ { grammar = 0; states = 1 }
+
+states && /^[Ss]tate / { state = $2 }
+states { statetext[state] = statetext[state] $0 "\n" }
+
+states && / shift/ {
+	n = nshift[state]++
+	if($0 ~ /and go to/)
+		shift[state,n] = $7 # GNU Bison
+	else
+		shift[state,n] = $3 # Plan 9 Yacc
+	shifttoken[state,n] = $1
+	next
+}
+states && / (go to|goto)/ {
+	n = nshift[state]++
+	if($0 ~ /go to/)
+		shift[state,n] = $5 # GNU Bison
+	else
+		shift[state,n] = $3 # Plan 9 Yacc
+	shifttoken[state,n] = $1
+	next
+}
+states && / reduce/ {
+	n = nreduce[state]++
+	if($0 ~ /reduce using rule/)
+		reduce[state,n] = $5 # GNU Bison
+	else
+		reduce[state,n] = $3 # Plan 9 yacc
+	reducetoken[state,n] = $1
+	next
+}
+
+# Skip over the summary information printed by Plan 9 yacc.
+/nonterminals$/,/^maximum spread/ { next }
+
+# First // comment marks the beginning of the pattern file.
+/^\/\// { bison = 0; grammar = 0; state = 0 }
+bison { next }
+
+# Treat % as first field on line as introducing a pattern (token sequence).
+# Run it through the LR machine and print the induced "yystate, yychar,"
+# at the point where the error happens.
+$1 == "%" {
+	nstack = 0
+	state = 0
+	f = 2
+	tok = ""
+	for(;;) {
+		if(tok == "" && f <= NF) {
+			tok = $f
+			f++
+		}
+		found = 0
+		for(j=0; j<nshift[state]; j++) {
+			if(shifttoken[state,j] == tok) {
+				# print "SHIFT " tok " " state " -> " shift[state,j]
+				stack[nstack++] = state
+				state = shift[state,j]
+				found = 1
+				tok = ""
+				break
+			}
+		}
+		if(found)
+			continue
+		for(j=0; j<nreduce[state]; j++) {
+			t = reducetoken[state,j]
+			if(t == tok || t == "$default" || t == ".") {
+				stack[nstack++] = state
+				rule = reduce[state,j]
+				nstack -= rulesize[rule]
+				state = stack[--nstack]
+				lhs = rulelhs[rule]
+				if(tok != "")
+					--f
+				tok = rulelhs[rule]
+				# print "REDUCE " nstack " " state " " tok " rule " rule " size " rulesize[rule]
+				found = 1
+				break
+			}
+		}
+		if(found)
+			continue
+
+		# No shift or reduce applied - found the error.
+		printf("\t{%s, %s,\n", state, tok);
+		open = 1;
+		break
+	}
+	next
+}
+
+# Print other lines verbatim.
+open && /,$/ {
+	s = $0;
+	sub(",", "},", s)
+	print s
+	open = 0
+	next
+}
+
+open && /"$/ {
+	print $0 "}"
+	open = 0
+	next
+}
+
+{print}
diff --git a/src/cmd/gc/bits.c b/src/cmd/gc/bits.c
new file mode 100644
index 0000000..2e79f6f
--- /dev/null
+++ b/src/cmd/gc/bits.c
@@ -0,0 +1,163 @@
+// Inferno utils/cc/bits.c
+// http://code.google.com/p/inferno-os/source/browse/utils/cc/bits.c
+//
+//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//	Portions Copyright © 1997-1999 Vita Nuova Limited
+//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//	Portions Copyright © 2004,2006 Bruce Ellis
+//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+/*
+Bits
+bor(Bits a, Bits b)
+{
+	Bits c;
+	int i;
+
+	for(i=0; i<BITS; i++)
+		c.b[i] = a.b[i] | b.b[i];
+	return c;
+}
+
+Bits
+band(Bits a, Bits b)
+{
+	Bits c;
+	int i;
+
+	for(i=0; i<BITS; i++)
+		c.b[i] = a.b[i] & b.b[i];
+	return c;
+}
+
+Bits
+bnot(Bits a)
+{
+	Bits c;
+	int i;
+
+	for(i=0; i<BITS; i++)
+		c.b[i] = ~a.b[i];
+	return c;
+}
+*/
+
+int
+bany(Bits *a)
+{
+	int i;
+
+	for(i=0; i<BITS; i++)
+		if(a->b[i])
+			return 1;
+	return 0;
+}
+
+/*
+int
+beq(Bits a, Bits b)
+{
+	int i;
+
+	for(i=0; i<BITS; i++)
+		if(a.b[i] != b.b[i])
+			return 0;
+	return 1;
+}
+*/
+
+int
+bnum(Bits a)
+{
+	int i;
+	int32 b;
+
+	for(i=0; i<BITS; i++)
+		if(b = a.b[i])
+			return 32*i + bitno(b);
+	fatal("bad in bnum");
+	return 0;
+}
+
+Bits
+blsh(uint n)
+{
+	Bits c;
+
+	c = zbits;
+	c.b[n/32] = 1L << (n%32);
+	return c;
+}
+
+/*
+int
+bset(Bits a, uint n)
+{
+	if(a.b[n/32] & (1L << (n%32)))
+		return 1;
+	return 0;
+}
+*/
+
+int
+bitno(int32 b)
+{
+	int i;
+
+	for(i=0; i<32; i++)
+		if(b & (1L<<i))
+			return i;
+	fatal("bad in bitno");
+	return 0;
+}
+
+int
+Qconv(Fmt *fp)
+{
+	Bits bits;
+	int i, first;
+
+	first = 1;
+	bits = va_arg(fp->args, Bits);
+	while(bany(&bits)) {
+		i = bnum(bits);
+		if(first)
+			first = 0;
+		else
+			fmtprint(fp, " ");
+		if(var[i].node == N || var[i].node->sym == S)
+			fmtprint(fp, "$%d", i);
+		else {
+			fmtprint(fp, "%s(%d)", var[i].node->sym->name, i);
+			if(var[i].offset != 0)
+				fmtprint(fp, "%+lld", (vlong)var[i].offset);
+		}
+		bits.b[i/32] &= ~(1L << (i%32));
+	}
+	return 0;
+}
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
new file mode 100644
index 0000000..fbca4ee
--- /dev/null
+++ b/src/cmd/gc/builtin.c
@@ -0,0 +1,137 @@
+// AUTO-GENERATED by mkbuiltin; DO NOT EDIT
+char *runtimeimport =
+	"package runtime\n"
+	"import runtime \"runtime\"\n"
+	"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n"
+	"func @\"\".panicindex ()\n"
+	"func @\"\".panicslice ()\n"
+	"func @\"\".panicdivide ()\n"
+	"func @\"\".throwreturn ()\n"
+	"func @\"\".throwinit ()\n"
+	"func @\"\".panicwrap (? string, ? string, ? string)\n"
+	"func @\"\".gopanic (? interface {})\n"
+	"func @\"\".gorecover (? *int32) (? interface {})\n"
+	"func @\"\".printbool (? bool)\n"
+	"func @\"\".printfloat (? float64)\n"
+	"func @\"\".printint (? int64)\n"
+	"func @\"\".printhex (? uint64)\n"
+	"func @\"\".printuint (? uint64)\n"
+	"func @\"\".printcomplex (? complex128)\n"
+	"func @\"\".printstring (? string)\n"
+	"func @\"\".printpointer (? any)\n"
+	"func @\"\".printiface (? any)\n"
+	"func @\"\".printeface (? any)\n"
+	"func @\"\".printslice (? any)\n"
+	"func @\"\".printnl ()\n"
+	"func @\"\".printsp ()\n"
+	"func @\"\".concatstring2 (? string, ? string) (? string)\n"
+	"func @\"\".concatstring3 (? string, ? string, ? string) (? string)\n"
+	"func @\"\".concatstring4 (? string, ? string, ? string, ? string) (? string)\n"
+	"func @\"\".concatstring5 (? string, ? string, ? string, ? string, ? string) (? string)\n"
+	"func @\"\".concatstrings (? []string) (? string)\n"
+	"func @\"\".cmpstring (? string, ? string) (? int)\n"
+	"func @\"\".eqstring (? string, ? string) (? bool)\n"
+	"func @\"\".intstring (? int64) (? string)\n"
+	"func @\"\".slicebytetostring (? []byte) (? string)\n"
+	"func @\"\".slicebytetostringtmp (? []byte) (? string)\n"
+	"func @\"\".slicerunetostring (? []rune) (? string)\n"
+	"func @\"\".stringtoslicebyte (? string) (? []byte)\n"
+	"func @\"\".stringtoslicerune (? string) (? []rune)\n"
+	"func @\"\".stringiter (? string, ? int) (? int)\n"
+	"func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n"
+	"func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n"
+	"func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n"
+	"func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n"
+	"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n"
+	"func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 *any) (@\"\".ret·1 any)\n"
+	"func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 *any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertE2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertE2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertE2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertE2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertE2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertE2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertI2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertI2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertI2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertI2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertI2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
+	"func @\"\".assertI2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
+	"func @\"\".assertI2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n"
+	"func @\"\".assertE2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n"
+	"func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n"
+	"func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n"
+	"func @\"\".ifacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
+	"func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
+	"func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64) (@\"\".hmap·1 map[any]any)\n"
+	"func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n"
+	"func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
+	"func @\"\".mapaccess1_fast64 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
+	"func @\"\".mapaccess1_faststr (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
+	"func @\"\".mapaccess2 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 *any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+	"func @\"\".mapaccess2_fast32 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+	"func @\"\".mapaccess2_fast64 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+	"func @\"\".mapaccess2_faststr (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
+	"func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any, @\"\".val·4 *any)\n"
+	"func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n"
+	"func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any)\n"
+	"func @\"\".mapiternext (@\"\".hiter·1 *any)\n"
+	"func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n"
+	"func @\"\".chanrecv1 (@\"\".chanType·1 *byte, @\"\".hchan·2 <-chan any, @\"\".elem·3 *any)\n"
+	"func @\"\".chanrecv2 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (? bool)\n"
+	"func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 *any)\n"
+	"func @\"\".closechan (@\"\".hchan·1 any)\n"
+	"func @\"\".writebarrierptr (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+	"func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+	"func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+	"func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+	"func @\"\".writebarrierfat2 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat3 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat4 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n"
+	"func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n"
+	"func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
+	"func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n"
+	"func @\"\".newselect (@\"\".sel·1 *byte, @\"\".selsize·2 int64, @\"\".size·3 int32)\n"
+	"func @\"\".selectsend (@\"\".sel·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
+	"func @\"\".selectrecv (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
+	"func @\"\".selectrecv2 (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any, @\"\".received·5 *bool) (@\"\".selected·1 bool)\n"
+	"func @\"\".selectdefault (@\"\".sel·2 *byte) (@\"\".selected·1 bool)\n"
+	"func @\"\".selectgo (@\"\".sel·1 *byte)\n"
+	"func @\"\".block ()\n"
+	"func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n"
+	"func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int64) (@\"\".ary·1 []any)\n"
+	"func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr)\n"
+	"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal8 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal16 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal32 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal64 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal128 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".int64div (? int64, ? int64) (? int64)\n"
+	"func @\"\".uint64div (? uint64, ? uint64) (? uint64)\n"
+	"func @\"\".int64mod (? int64, ? int64) (? int64)\n"
+	"func @\"\".uint64mod (? uint64, ? uint64) (? uint64)\n"
+	"func @\"\".float64toint64 (? float64) (? int64)\n"
+	"func @\"\".float64touint64 (? float64) (? uint64)\n"
+	"func @\"\".int64tofloat64 (? int64) (? float64)\n"
+	"func @\"\".uint64tofloat64 (? uint64) (? float64)\n"
+	"func @\"\".complex128div (@\"\".num·2 complex128, @\"\".den·3 complex128) (@\"\".quo·1 complex128)\n"
+	"func @\"\".racefuncenter (? uintptr)\n"
+	"func @\"\".racefuncexit ()\n"
+	"func @\"\".raceread (? uintptr)\n"
+	"func @\"\".racewrite (? uintptr)\n"
+	"func @\"\".racereadrange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n"
+	"func @\"\".racewriterange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n"
+	"\n"
+	"$$\n";
+char *unsafeimport =
+	"package unsafe\n"
+	"import runtime \"runtime\"\n"
+	"type @\"\".Pointer uintptr\n"
+	"func @\"\".Offsetof (? any) (? uintptr)\n"
+	"func @\"\".Sizeof (? any) (? uintptr)\n"
+	"func @\"\".Alignof (? any) (? uintptr)\n"
+	"\n"
+	"$$\n";
diff --git a/src/cmd/gc/bv.c b/src/cmd/gc/bv.c
new file mode 100644
index 0000000..cfd1cd2
--- /dev/null
+++ b/src/cmd/gc/bv.c
@@ -0,0 +1,213 @@
+// Copyright 2013 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+enum {
+	WORDSIZE = sizeof(uint32),
+	WORDBITS = 32,
+	WORDMASK = WORDBITS - 1,
+	WORDSHIFT = 5,
+};
+
+static uintptr
+bvsize(uintptr n)
+{
+	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE;
+}
+
+int32
+bvbits(Bvec *bv)
+{
+	return bv->n;
+}
+
+int32
+bvwords(Bvec *bv)
+{
+	return (bv->n + WORDBITS - 1) / WORDBITS;
+}
+
+Bvec*
+bvalloc(int32 n)
+{
+	Bvec *bv;
+	uintptr nbytes;
+
+	if(n < 0)
+		fatal("bvalloc: initial size is negative\n");
+	nbytes = sizeof(Bvec) + bvsize(n);
+	bv = malloc(nbytes);
+	if(bv == nil)
+		fatal("bvalloc: malloc failed\n");
+	memset(bv, 0, nbytes);
+	bv->n = n;
+	return bv;
+}
+
+/* difference */
+void
+bvandnot(Bvec *dst, Bvec *src1, Bvec *src2)
+{
+	int32 i, w;
+
+	if(dst->n != src1->n || dst->n != src2->n)
+		fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+		dst->b[w] = src1->b[w] & ~src2->b[w];
+}
+
+int
+bvcmp(Bvec *bv1, Bvec *bv2)
+{
+	uintptr nbytes;
+
+	if(bv1->n != bv2->n)
+		fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n);
+	nbytes = bvsize(bv1->n);
+	return memcmp(bv1->b, bv2->b, nbytes);
+}
+
+void
+bvcopy(Bvec *dst, Bvec *src)
+{
+	memmove(dst->b, src->b, bvsize(dst->n));
+}
+
+Bvec*
+bvconcat(Bvec *src1, Bvec *src2)
+{
+	Bvec *dst;
+	int32 i;
+
+	dst = bvalloc(src1->n + src2->n);
+	for(i = 0; i < src1->n; i++)
+		if(bvget(src1, i))
+			bvset(dst, i);
+	for(i = 0; i < src2->n; i++)
+		if(bvget(src2, i))
+			bvset(dst, i + src1->n);
+	return dst;
+}
+
+int
+bvget(Bvec *bv, int32 i)
+{
+	if(i < 0 || i >= bv->n)
+		fatal("bvget: index %d is out of bounds with length %d\n", i, bv->n);
+	return (bv->b[i>>WORDSHIFT] >> (i&WORDMASK)) & 1;
+}
+
+// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
+// If there is no such index, bvnext returns -1.
+int
+bvnext(Bvec *bv, int32 i)
+{
+	uint32 w;
+
+	if(i >= bv->n)
+		return -1;
+
+	// Jump i ahead to next word with bits.
+	if((bv->b[i>>WORDSHIFT]>>(i&WORDMASK)) == 0) {
+		i &= ~WORDMASK;
+		i += WORDBITS;
+		while(i < bv->n && bv->b[i>>WORDSHIFT] == 0)
+			i += WORDBITS;
+	}
+	if(i >= bv->n)
+		return -1;
+
+	// Find 1 bit.
+	w = bv->b[i>>WORDSHIFT]>>(i&WORDMASK);
+	while((w&1) == 0) {
+		w>>=1;
+		i++;
+	}
+	return i;
+}
+
+int
+bvisempty(Bvec *bv)
+{
+	int32 i;
+
+	for(i = 0; i < bv->n; i += WORDBITS)
+		if(bv->b[i>>WORDSHIFT] != 0)
+			return 0;
+	return 1;
+}
+
+void
+bvnot(Bvec *bv)
+{
+	int32 i, w;
+
+	for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++)
+		bv->b[w] = ~bv->b[w];
+}
+
+/* union */
+void
+bvor(Bvec *dst, Bvec *src1, Bvec *src2)
+{
+	int32 i, w;
+
+	if(dst->n != src1->n || dst->n != src2->n)
+		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+		dst->b[w] = src1->b[w] | src2->b[w];
+}
+
+/* intersection */
+void
+bvand(Bvec *dst, Bvec *src1, Bvec *src2)
+{
+	int32 i, w;
+
+	if(dst->n != src1->n || dst->n != src2->n)
+		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+		dst->b[w] = src1->b[w] & src2->b[w];
+}
+
+void
+bvprint(Bvec *bv)
+{
+	int32 i;
+
+	print("#*");
+	for(i = 0; i < bv->n; i++)
+		print("%d", bvget(bv, i));
+}
+
+void
+bvreset(Bvec *bv, int32 i)
+{
+	uint32 mask;
+
+	if(i < 0 || i >= bv->n)
+		fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n);
+	mask = ~(1 << (i % WORDBITS));
+	bv->b[i / WORDBITS] &= mask;
+}
+
+void
+bvresetall(Bvec *bv)
+{
+	memset(bv->b, 0x00, bvsize(bv->n));
+}
+
+void
+bvset(Bvec *bv, int32 i)
+{
+	uint32 mask;
+
+	if(i < 0 || i >= bv->n)
+		fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n);
+	mask = 1U << (i % WORDBITS);
+	bv->b[i / WORDBITS] |= mask;
+}
diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c
new file mode 100644
index 0000000..ad4e5bd
--- /dev/null
+++ b/src/cmd/gc/closure.c
@@ -0,0 +1,467 @@
+// 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.
+
+/*
+ * function literals aka closures
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+void
+closurehdr(Node *ntype)
+{
+	Node *n, *name, *a;
+	NodeList *l;
+
+	n = nod(OCLOSURE, N, N);
+	n->ntype = ntype;
+	n->funcdepth = funcdepth;
+
+	funchdr(n);
+
+	// steal ntype's argument names and
+	// leave a fresh copy in their place.
+	// references to these variables need to
+	// refer to the variables in the external
+	// function declared below; see walkclosure.
+	n->list = ntype->list;
+	n->rlist = ntype->rlist;
+	ntype->list = nil;
+	ntype->rlist = nil;
+	for(l=n->list; l; l=l->next) {
+		name = l->n->left;
+		if(name)
+			name = newname(name->sym);
+		a = nod(ODCLFIELD, name, l->n->right);
+		a->isddd = l->n->isddd;
+		if(name)
+			name->isddd = a->isddd;
+		ntype->list = list(ntype->list, a);
+	}
+	for(l=n->rlist; l; l=l->next) {
+		name = l->n->left;
+		if(name)
+			name = newname(name->sym);
+		ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, name, l->n->right));
+	}
+}
+
+Node*
+closurebody(NodeList *body)
+{
+	Node *func, *v;
+	NodeList *l;
+
+	if(body == nil)
+		body = list1(nod(OEMPTY, N, N));
+
+	func = curfn;
+	func->nbody = body;
+	func->endlineno = lineno;
+	funcbody(func);
+
+	// closure-specific variables are hanging off the
+	// ordinary ones in the symbol table; see oldname.
+	// unhook them.
+	// make the list of pointers for the closure call.
+	for(l=func->cvars; l; l=l->next) {
+		v = l->n;
+		v->closure->closure = v->outer;
+		v->heapaddr = nod(OADDR, oldname(v->sym), N);
+	}
+
+	return func;
+}
+
+static Node* makeclosure(Node *func);
+
+void
+typecheckclosure(Node *func, int top)
+{
+	Node *oldfn;
+	NodeList *l;
+	Node *v;
+
+	oldfn = curfn;
+	typecheck(&func->ntype, Etype);
+	func->type = func->ntype->type;
+	
+	// Type check the body now, but only if we're inside a function.
+	// At top level (in a variable initialization: curfn==nil) we're not
+	// ready to type check code yet; we'll check it later, because the
+	// underlying closure function we create is added to xtop.
+	if(curfn && func->type != T) {
+		curfn = func;
+		typechecklist(func->nbody, Etop);
+		curfn = oldfn;
+	}
+
+	// type check the & of closed variables outside the closure,
+	// so that the outer frame also grabs them and knows they
+	// escape.
+	func->enter = nil;
+	for(l=func->cvars; l; l=l->next) {
+		v = l->n;
+		if(v->type == T) {
+			// if v->type is nil, it means v looked like it was
+			// going to be used in the closure but wasn't.
+			// this happens because when parsing a, b, c := f()
+			// the a, b, c gets parsed as references to older
+			// a, b, c before the parser figures out this is a
+			// declaration.
+			v->op = 0;
+			continue;
+		}
+		// For a closure that is called in place, but not
+		// inside a go statement, avoid moving variables to the heap.
+		if ((top & (Ecall|Eproc)) == Ecall)
+			v->heapaddr->etype = 1;
+		typecheck(&v->heapaddr, Erv);
+		func->enter = list(func->enter, v->heapaddr);
+		v->heapaddr = N;
+	}
+
+	// Create top-level function 
+	xtop = list(xtop, makeclosure(func));
+}
+
+static Node*
+makeclosure(Node *func)
+{
+	Node *xtype, *v, *addr, *xfunc, *cv;
+	NodeList *l, *body;
+	static int closgen;
+	char *p;
+	vlong offset;
+
+	/*
+	 * wrap body in external function
+	 * that begins by reading closure parameters.
+	 */
+	xtype = nod(OTFUNC, N, N);
+	xtype->list = func->list;
+	xtype->rlist = func->rlist;
+
+	// create the function
+	xfunc = nod(ODCLFUNC, N, N);
+	snprint(namebuf, sizeof namebuf, "func·%.3d", ++closgen);
+	xfunc->nname = newname(lookup(namebuf));
+	xfunc->nname->sym->flags |= SymExported; // disable export
+	xfunc->nname->ntype = xtype;
+	xfunc->nname->defn = xfunc;
+	declare(xfunc->nname, PFUNC);
+	xfunc->nname->funcdepth = func->funcdepth;
+	xfunc->funcdepth = func->funcdepth;
+	xfunc->endlineno = func->endlineno;
+	
+	// declare variables holding addresses taken from closure
+	// and initialize in entry prologue.
+	body = nil;
+	offset = widthptr;
+	xfunc->needctxt = func->cvars != nil;
+	for(l=func->cvars; l; l=l->next) {
+		v = l->n;
+		if(v->op == 0)
+			continue;
+		addr = nod(ONAME, N, N);
+		p = smprint("&%s", v->sym->name);
+		addr->sym = lookup(p);
+		free(p);
+		addr->ntype = nod(OIND, typenod(v->type), N);
+		addr->class = PAUTO;
+		addr->addable = 1;
+		addr->ullman = 1;
+		addr->used = 1;
+		addr->curfn = xfunc;
+		xfunc->dcl = list(xfunc->dcl, addr);
+		v->heapaddr = addr;
+		cv = nod(OCLOSUREVAR, N, N);
+		cv->type = ptrto(v->type);
+		cv->xoffset = offset;
+		body = list(body, nod(OAS, addr, cv));
+		offset += widthptr;
+	}
+	typechecklist(body, Etop);
+	walkstmtlist(body);
+	xfunc->enter = body;
+
+	xfunc->nbody = func->nbody;
+	xfunc->dcl = concat(func->dcl, xfunc->dcl);
+	if(xfunc->nbody == nil)
+		fatal("empty body - won't generate any code");
+	typecheck(&xfunc, Etop);
+
+	xfunc->closure = func;
+	func->closure = xfunc;
+	
+	func->nbody = nil;
+	func->list = nil;
+	func->rlist = nil;
+
+	return xfunc;
+}
+
+Node*
+walkclosure(Node *func, NodeList **init)
+{
+	Node *clos, *typ;
+	NodeList *l;
+	char buf[20];
+	int narg;
+
+	// If no closure vars, don't bother wrapping.
+	if(func->cvars == nil)
+		return func->closure->nname;
+
+	// Create closure in the form of a composite literal.
+	// supposing the closure captures an int i and a string s
+	// and has one float64 argument and no results,
+	// the generated code looks like:
+	//
+	//	clos = &struct{F uintptr; A0 *int; A1 *string}{func·001, &i, &s}
+	//
+	// The use of the struct provides type information to the garbage
+	// collector so that it can walk the closure. We could use (in this case)
+	// [3]unsafe.Pointer instead, but that would leave the gc in the dark.
+	// The information appears in the binary in the form of type descriptors;
+	// the struct is unnamed so that closures in multiple packages with the
+	// same struct type can share the descriptor.
+
+	narg = 0;
+	typ = nod(OTSTRUCT, N, N);
+	typ->list = list1(nod(ODCLFIELD, newname(lookup("F")), typenod(types[TUINTPTR])));
+	for(l=func->cvars; l; l=l->next) {
+		if(l->n->op == 0)
+			continue;
+		snprint(buf, sizeof buf, "A%d", narg++);
+		typ->list = list(typ->list, nod(ODCLFIELD, newname(lookup(buf)), l->n->heapaddr->ntype));
+	}
+
+	clos = nod(OCOMPLIT, N, nod(OIND, typ, N));
+	clos->esc = func->esc;
+	clos->right->implicit = 1;
+	clos->list = concat(list1(nod(OCFUNC, func->closure->nname, N)), func->enter);
+
+	// Force type conversion from *struct to the func type.
+	clos = nod(OCONVNOP, clos, N);
+	clos->type = func->type;
+
+	typecheck(&clos, Erv);
+	// typecheck will insert a PTRLIT node under CONVNOP,
+	// tag it with escape analysis result.
+	clos->left->esc = func->esc;
+	// non-escaping temp to use, if any.
+	// orderexpr did not compute the type; fill it in now.
+	if(func->alloc != N) {
+		func->alloc->type = clos->left->left->type;
+		func->alloc->orig->type = func->alloc->type;
+		clos->left->right = func->alloc;
+		func->alloc = N;
+	}
+	walkexpr(&clos, init);
+
+	return clos;
+}
+
+static Node *makepartialcall(Node*, Type*, Node*);
+
+void
+typecheckpartialcall(Node *fn, Node *sym)
+{
+	switch(fn->op) {
+	case ODOTINTER:
+	case ODOTMETH:
+		break;
+	default:
+		fatal("invalid typecheckpartialcall");
+	}
+
+	// Create top-level function.
+	fn->nname = makepartialcall(fn, fn->type, sym);
+	fn->right = sym;
+	fn->op = OCALLPART;
+	fn->type = fn->nname->type;
+}
+
+static Node*
+makepartialcall(Node *fn, Type *t0, Node *meth)
+{
+	Node *ptr, *n, *fld, *call, *xtype, *xfunc, *cv, *savecurfn;
+	Type *rcvrtype, *basetype, *t;
+	NodeList *body, *l, *callargs, *retargs;
+	char *p;
+	Sym *sym;
+	Pkg *spkg;
+	static Pkg* gopkg;
+	int i, ddd;
+
+	// TODO: names are not right
+	rcvrtype = fn->left->type;
+	if(exportname(meth->sym->name))
+		p = smprint("%-hT.%s·fm", rcvrtype, meth->sym->name);
+	else
+		p = smprint("%-hT.(%-S)·fm", rcvrtype, meth->sym);
+	basetype = rcvrtype;
+	if(isptr[rcvrtype->etype])
+		basetype = basetype->type;
+	if(basetype->etype != TINTER && basetype->sym == S)
+		fatal("missing base type for %T", rcvrtype);
+
+	spkg = nil;
+	if(basetype->sym != S)
+		spkg = basetype->sym->pkg;
+	if(spkg == nil) {
+		if(gopkg == nil)
+			gopkg = mkpkg(strlit("go"));
+		spkg = gopkg;
+	}
+	sym = pkglookup(p, spkg);
+	free(p);
+	if(sym->flags & SymUniq)
+		return sym->def;
+	sym->flags |= SymUniq;
+	
+	savecurfn = curfn;
+	curfn = N;
+
+	xtype = nod(OTFUNC, N, N);
+	i = 0;
+	l = nil;
+	callargs = nil;
+	ddd = 0;
+	xfunc = nod(ODCLFUNC, N, N);
+	curfn = xfunc;
+	for(t = getinargx(t0)->type; t; t = t->down) {
+		snprint(namebuf, sizeof namebuf, "a%d", i++);
+		n = newname(lookup(namebuf));
+		n->class = PPARAM;
+		xfunc->dcl = list(xfunc->dcl, n);
+		callargs = list(callargs, n);
+		fld = nod(ODCLFIELD, n, typenod(t->type));
+		if(t->isddd) {
+			fld->isddd = 1;
+			ddd = 1;
+		}
+		l = list(l, fld);
+	}
+	xtype->list = l;
+	i = 0;
+	l = nil;
+	retargs = nil;
+	for(t = getoutargx(t0)->type; t; t = t->down) {
+		snprint(namebuf, sizeof namebuf, "r%d", i++);
+		n = newname(lookup(namebuf));
+		n->class = PPARAMOUT;
+		xfunc->dcl = list(xfunc->dcl, n);
+		retargs = list(retargs, n);
+		l = list(l, nod(ODCLFIELD, n, typenod(t->type)));
+	}
+	xtype->rlist = l;
+
+	xfunc->dupok = 1;
+	xfunc->nname = newname(sym);
+	xfunc->nname->sym->flags |= SymExported; // disable export
+	xfunc->nname->ntype = xtype;
+	xfunc->nname->defn = xfunc;
+	declare(xfunc->nname, PFUNC);
+
+	// Declare and initialize variable holding receiver.
+	body = nil;
+	xfunc->needctxt = 1;
+	cv = nod(OCLOSUREVAR, N, N);
+	cv->xoffset = widthptr;
+	cv->type = rcvrtype;
+	if(cv->type->align > widthptr)
+		cv->xoffset = cv->type->align;
+	ptr = nod(ONAME, N, N);
+	ptr->sym = lookup("rcvr");
+	ptr->class = PAUTO;
+	ptr->addable = 1;
+	ptr->ullman = 1;
+	ptr->used = 1;
+	ptr->curfn = xfunc;
+	xfunc->dcl = list(xfunc->dcl, ptr);
+	if(isptr[rcvrtype->etype] || isinter(rcvrtype)) {
+		ptr->ntype = typenod(rcvrtype);
+		body = list(body, nod(OAS, ptr, cv));
+	} else {
+		ptr->ntype = typenod(ptrto(rcvrtype));
+		body = list(body, nod(OAS, ptr, nod(OADDR, cv, N)));
+	}
+
+	call = nod(OCALL, nod(OXDOT, ptr, meth), N);
+	call->list = callargs;
+	call->isddd = ddd;
+	if(t0->outtuple == 0) {
+		body = list(body, call);
+	} else {
+		n = nod(OAS2, N, N);
+		n->list = retargs;
+		n->rlist = list1(call);
+		body = list(body, n);
+		n = nod(ORETURN, N, N);
+		body = list(body, n);
+	}
+
+	xfunc->nbody = body;
+
+	typecheck(&xfunc, Etop);
+	sym->def = xfunc;
+	xtop = list(xtop, xfunc);
+	curfn = savecurfn;
+
+	return xfunc;
+}
+
+Node*
+walkpartialcall(Node *n, NodeList **init)
+{
+	Node *clos, *typ;
+
+	// Create closure in the form of a composite literal.
+	// For x.M with receiver (x) type T, the generated code looks like:
+	//
+	//	clos = &struct{F uintptr; R T}{M.T·f, x}
+	//
+	// Like walkclosure above.
+
+	if(isinter(n->left->type)) {
+		// Trigger panic for method on nil interface now.
+		// Otherwise it happens in the wrapper and is confusing.
+		n->left = cheapexpr(n->left, init);
+		checknil(n->left, init);
+	}
+
+	typ = nod(OTSTRUCT, N, N);
+	typ->list = list1(nod(ODCLFIELD, newname(lookup("F")), typenod(types[TUINTPTR])));
+	typ->list = list(typ->list, nod(ODCLFIELD, newname(lookup("R")), typenod(n->left->type)));
+
+	clos = nod(OCOMPLIT, N, nod(OIND, typ, N));
+	clos->esc = n->esc;
+	clos->right->implicit = 1;
+	clos->list = list1(nod(OCFUNC, n->nname->nname, N));
+	clos->list = list(clos->list, n->left);
+
+	// Force type conversion from *struct to the func type.
+	clos = nod(OCONVNOP, clos, N);
+	clos->type = n->type;
+
+	typecheck(&clos, Erv);
+	// typecheck will insert a PTRLIT node under CONVNOP,
+	// tag it with escape analysis result.
+	clos->left->esc = n->esc;
+	// non-escaping temp to use, if any.
+	// orderexpr did not compute the type; fill it in now.
+	if(n->alloc != N) {
+		n->alloc->type = clos->left->left->type;
+		n->alloc->orig->type = n->alloc->type;
+		clos->left->right = n->alloc;
+		n->alloc = N;
+	}
+	walkexpr(&clos, init);
+
+	return clos;
+}
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
new file mode 100644
index 0000000..e418b9c
--- /dev/null
+++ b/src/cmd/gc/const.c
@@ -0,0 +1,1674 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#define	TUP(x,y)	(((x)<<16)|(y))
+/*c2go int TUP(int, int); */
+
+static	Val	tocplx(Val);
+static	Val	toflt(Val);
+static	Val	tostr(Val);
+static	Val	copyval(Val);
+static	void	cmplxmpy(Mpcplx*, Mpcplx*);
+static	void	cmplxdiv(Mpcplx*, Mpcplx*);
+
+/*
+ * truncate float literal fv to 32-bit or 64-bit precision
+ * according to type; return truncated value.
+ */
+Mpflt*
+truncfltlit(Mpflt *oldv, Type *t)
+{
+	double d;
+	Mpflt *fv;
+	Val v;
+
+	if(t == T)
+		return oldv;
+
+	memset(&v, 0, sizeof v);
+	v.ctype = CTFLT;
+	v.u.fval = oldv;
+	overflow(v, t);
+
+	fv = mal(sizeof *fv);
+	*fv = *oldv;
+
+	// convert large precision literal floating
+	// into limited precision (float64 or float32)
+	switch(t->etype) {
+	case TFLOAT64:
+		d = mpgetflt(fv);
+		mpmovecflt(fv, d);
+		break;
+
+	case TFLOAT32:
+		d = mpgetflt32(fv);
+		mpmovecflt(fv, d);
+
+		break;
+	}
+	return fv;
+}
+
+/*
+ * convert n, if literal, to type t.
+ * implicit conversion.
+ */
+void
+convlit(Node **np, Type *t)
+{
+	convlit1(np, t, 0);
+}
+
+/*
+ * convert n, if literal, to type t.
+ * return a new node if necessary
+ * (if n is a named constant, can't edit n->type directly).
+ */
+void
+convlit1(Node **np, Type *t, int explicit)
+{
+	int ct, et;
+	Node *n, *nn;
+
+	n = *np;
+	if(n == N || t == T || n->type == T || isideal(t) || n->type == t)
+		return;
+	if(!explicit && !isideal(n->type))
+		return;
+
+	if(n->op == OLITERAL) {
+		nn = nod(OXXX, N, N);
+		*nn = *n;
+		n = nn;
+		*np = n;
+	}
+
+	switch(n->op) {
+	default:
+		if(n->type == idealbool) {
+			if(t->etype == TBOOL)
+				n->type = t;
+			else
+				n->type = types[TBOOL];
+		}
+		if(n->type->etype == TIDEAL) {
+			convlit(&n->left, t);
+			convlit(&n->right, t);
+			n->type = t;
+		}
+		return;
+	case OLITERAL:
+		// target is invalid type for a constant?  leave alone.
+		if(!okforconst[t->etype] && n->type->etype != TNIL) {
+			defaultlit(&n, T);
+			*np = n;
+			return;
+		}
+		break;
+	case OLSH:
+	case ORSH:
+		convlit1(&n->left, t, explicit && isideal(n->left->type));
+		t = n->left->type;
+		if(t != T && t->etype == TIDEAL && n->val.ctype != CTINT)
+			n->val = toint(n->val);
+		if(t != T && !isint[t->etype]) {
+			yyerror("invalid operation: %N (shift of type %T)", n, t);
+			t = T;
+		}
+		n->type = t;
+		return;
+	case OCOMPLEX:
+		if(n->type->etype == TIDEAL) {
+			switch(t->etype) {
+			default:
+				// If trying to convert to non-complex type,
+				// leave as complex128 and let typechecker complain.
+				t = types[TCOMPLEX128];
+				//fallthrough
+			case TCOMPLEX128:
+				n->type = t;
+				convlit(&n->left, types[TFLOAT64]);
+				convlit(&n->right, types[TFLOAT64]);
+				break;
+			case TCOMPLEX64:
+				n->type = t;
+				convlit(&n->left, types[TFLOAT32]);
+				convlit(&n->right, types[TFLOAT32]);
+				break;
+			}
+		}
+		return;
+	}
+
+	// avoided repeated calculations, errors
+	if(eqtype(n->type, t))
+		return;
+
+	ct = consttype(n);
+	if(ct < 0)
+		goto bad;
+
+	et = t->etype;
+	if(et == TINTER) {
+		if(ct == CTNIL && n->type == types[TNIL]) {
+			n->type = t;
+			return;
+		}
+		defaultlit(np, T);
+		return;
+	}
+
+	switch(ct) {
+	default:
+		goto bad;
+
+	case CTNIL:
+		switch(et) {
+		default:
+			n->type = T;
+			goto bad;
+
+		case TSTRING:
+			// let normal conversion code handle it
+			return;
+
+		case TARRAY:
+			if(!isslice(t))
+				goto bad;
+			break;
+
+		case TPTR32:
+		case TPTR64:
+		case TINTER:
+		case TMAP:
+		case TCHAN:
+		case TFUNC:
+		case TUNSAFEPTR:
+			break;
+
+		case TUINTPTR:
+			// A nil literal may be converted to uintptr
+			// if it is an unsafe.Pointer
+			if(n->type->etype == TUNSAFEPTR) {
+				n->val.u.xval = mal(sizeof(*n->val.u.xval));
+				mpmovecfix(n->val.u.xval, 0);
+				n->val.ctype = CTINT;
+			} else
+				goto bad;
+		}
+		break;
+
+	case CTSTR:
+	case CTBOOL:
+		if(et != n->type->etype)
+			goto bad;
+		break;
+
+	case CTINT:
+	case CTRUNE:
+	case CTFLT:
+	case CTCPLX:
+		ct = n->val.ctype;
+		if(isint[et]) {
+			switch(ct) {
+			default:
+				goto bad;
+			case CTCPLX:
+			case CTFLT:
+			case CTRUNE:
+				n->val = toint(n->val);
+				// flowthrough
+			case CTINT:
+				overflow(n->val, t);
+				break;
+			}
+		} else
+		if(isfloat[et]) {
+			switch(ct) {
+			default:
+				goto bad;
+			case CTCPLX:
+			case CTINT:
+			case CTRUNE:
+				n->val = toflt(n->val);
+				// flowthrough
+			case CTFLT:
+				n->val.u.fval = truncfltlit(n->val.u.fval, t);
+				break;
+			}
+		} else
+		if(iscomplex[et]) {
+			switch(ct) {
+			default:
+				goto bad;
+			case CTFLT:
+			case CTINT:
+			case CTRUNE:
+				n->val = tocplx(n->val);
+				break;
+			case CTCPLX:
+				overflow(n->val, t);
+				break;
+			}
+		} else
+		if(et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit)
+			n->val = tostr(n->val);
+		else
+			goto bad;
+		break;
+	}
+	n->type = t;
+	return;
+
+bad:
+	if(!n->diag) {
+		if(!t->broke)
+			yyerror("cannot convert %N to type %T", n, t);
+		n->diag = 1;
+	}
+	if(isideal(n->type)) {
+		defaultlit(&n, T);
+		*np = n;
+	}
+	return;
+}
+
+static Val
+copyval(Val v)
+{
+	Mpint *i;
+	Mpflt *f;
+	Mpcplx *c;
+
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		i = mal(sizeof(*i));
+		mpmovefixfix(i, v.u.xval);
+		v.u.xval = i;
+		break;
+	case CTFLT:
+		f = mal(sizeof(*f));
+		mpmovefltflt(f, v.u.fval);
+		v.u.fval = f;
+		break;
+	case CTCPLX:
+		c = mal(sizeof(*c));
+		mpmovefltflt(&c->real, &v.u.cval->real);
+		mpmovefltflt(&c->imag, &v.u.cval->imag);
+		v.u.cval = c;
+		break;
+	}
+	return v;
+}
+
+static Val
+tocplx(Val v)
+{
+	Mpcplx *c;
+
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		c = mal(sizeof(*c));
+		mpmovefixflt(&c->real, v.u.xval);
+		mpmovecflt(&c->imag, 0.0);
+		v.ctype = CTCPLX;
+		v.u.cval = c;
+		break;
+	case CTFLT:
+		c = mal(sizeof(*c));
+		mpmovefltflt(&c->real, v.u.fval);
+		mpmovecflt(&c->imag, 0.0);
+		v.ctype = CTCPLX;
+		v.u.cval = c;
+		break;
+	}
+	return v;
+}
+
+static Val
+toflt(Val v)
+{
+	Mpflt *f;
+
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		f = mal(sizeof(*f));
+		mpmovefixflt(f, v.u.xval);
+		v.ctype = CTFLT;
+		v.u.fval = f;
+		break;
+	case CTCPLX:
+		f = mal(sizeof(*f));
+		mpmovefltflt(f, &v.u.cval->real);
+		if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
+			yyerror("constant %#F%+#Fi truncated to real", &v.u.cval->real, &v.u.cval->imag);
+		v.ctype = CTFLT;
+		v.u.fval = f;
+		break;
+	}
+	return v;
+}
+
+Val
+toint(Val v)
+{
+	Mpint *i;
+
+	switch(v.ctype) {
+	case CTRUNE:
+		v.ctype = CTINT;
+		break;
+	case CTFLT:
+		i = mal(sizeof(*i));
+		if(mpmovefltfix(i, v.u.fval) < 0)
+			yyerror("constant %#F truncated to integer", v.u.fval);
+		v.ctype = CTINT;
+		v.u.xval = i;
+		break;
+	case CTCPLX:
+		i = mal(sizeof(*i));
+		if(mpmovefltfix(i, &v.u.cval->real) < 0)
+			yyerror("constant %#F%+#Fi truncated to integer", &v.u.cval->real, &v.u.cval->imag);
+		if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
+			yyerror("constant %#F%+#Fi truncated to real", &v.u.cval->real, &v.u.cval->imag);
+		v.ctype = CTINT;
+		v.u.xval = i;
+		break;
+	}
+	return v;
+}
+
+int
+doesoverflow(Val v, Type *t)
+{
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		if(!isint[t->etype])
+			fatal("overflow: %T integer constant", t);
+		if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 ||
+		   mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
+			return 1;
+		break;
+	case CTFLT:
+		if(!isfloat[t->etype])
+			fatal("overflow: %T floating-point constant", t);
+		if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0 ||
+		   mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
+			return 1;
+		break;
+	case CTCPLX:
+		if(!iscomplex[t->etype])
+			fatal("overflow: %T complex constant", t);
+		if(mpcmpfltflt(&v.u.cval->real, minfltval[t->etype]) <= 0 ||
+		   mpcmpfltflt(&v.u.cval->real, maxfltval[t->etype]) >= 0 ||
+		   mpcmpfltflt(&v.u.cval->imag, minfltval[t->etype]) <= 0 ||
+		   mpcmpfltflt(&v.u.cval->imag, maxfltval[t->etype]) >= 0)
+			return 1;
+		break;
+	}
+	return 0;
+}
+
+void
+overflow(Val v, Type *t)
+{
+	// v has already been converted
+	// to appropriate form for t.
+	if(t == T || t->etype == TIDEAL)
+		return;
+
+	if(!doesoverflow(v, t))
+		return;
+
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		yyerror("constant %B overflows %T", v.u.xval, t);
+		break;
+	case CTFLT:
+		yyerror("constant %#F overflows %T", v.u.fval, t);
+		break;
+	case CTCPLX:
+		yyerror("constant %#F overflows %T", v.u.fval, t);
+		break;
+	}
+}
+
+static Val
+tostr(Val v)
+{
+	Rune rune;
+	int l;
+	Strlit *s;
+
+	switch(v.ctype) {
+	case CTINT:
+	case CTRUNE:
+		if(mpcmpfixfix(v.u.xval, minintval[TINT]) < 0 ||
+		   mpcmpfixfix(v.u.xval, maxintval[TINT]) > 0)
+			yyerror("overflow in int -> string");
+		rune = mpgetfix(v.u.xval);
+		l = runelen(rune);
+		s = mal(sizeof(*s)+l);
+		s->len = l;
+		runetochar((char*)s->s, &rune);
+		memset(&v, 0, sizeof v);
+		v.ctype = CTSTR;
+		v.u.sval = s;
+		break;
+
+	case CTFLT:
+		yyerror("no float -> string");
+
+	case CTNIL:
+		memset(&v, 0, sizeof v);
+		v.ctype = CTSTR;
+		v.u.sval = mal(sizeof *s);
+		break;
+	}
+	return v;
+}
+
+int
+consttype(Node *n)
+{
+	if(n == N || n->op != OLITERAL)
+		return -1;
+	return n->val.ctype;
+}
+
+int
+isconst(Node *n, int ct)
+{
+	int t;
+	
+	t = consttype(n);
+	// If the caller is asking for CTINT, allow CTRUNE too.
+	// Makes life easier for back ends.
+	return t == ct || (ct == CTINT && t == CTRUNE);
+}
+
+static Node*
+saveorig(Node *n)
+{
+	Node *n1;
+
+	if(n == n->orig) {
+		// duplicate node for n->orig.
+		n1 = nod(OLITERAL, N, N);
+		n->orig = n1;
+		*n1 = *n;
+	}
+	return n->orig;
+}
+
+/*
+ * if n is constant, rewrite as OLITERAL node.
+ */
+void
+evconst(Node *n)
+{
+	Node *nl, *nr, *norig;
+	int32 len;
+	Strlit *str;
+	int wl, wr, lno, et;
+	Val v, rv;
+	Mpint b;
+	NodeList *l1, *l2;
+
+	// pick off just the opcodes that can be
+	// constant evaluated.
+	switch(n->op) {
+	default:
+		return;
+	case OADD:
+	case OAND:
+	case OANDAND:
+	case OANDNOT:
+	case OARRAYBYTESTR:
+	case OCOM:
+	case ODIV:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLSH:
+	case OLT:
+	case OMINUS:
+	case OMOD:
+	case OMUL:
+	case ONE:
+	case ONOT:
+	case OOR:
+	case OOROR:
+	case OPLUS:
+	case ORSH:
+	case OSUB:
+	case OXOR:
+		break;
+	case OCONV:
+		if(n->type == T)
+			return;
+		if(!okforconst[n->type->etype] && n->type->etype != TNIL)
+			return;
+		break;
+	
+	case OADDSTR:
+		// merge adjacent constants in the argument list.
+		for(l1=n->list; l1 != nil; l1= l1->next) {
+			if(isconst(l1->n, CTSTR) && l1->next != nil && isconst(l1->next->n, CTSTR)) {
+				l2 = l1;
+				len = 0;
+				while(l2 != nil && isconst(l2->n, CTSTR)) {
+					nr = l2->n;
+					len += nr->val.u.sval->len;
+					l2 = l2->next;
+				}
+				// merge from l1 up to but not including l2
+				str = mal(sizeof(*str) + len);
+				str->len = len;
+				len = 0;
+				l2 = l1;
+				while(l2 != nil && isconst(l2->n, CTSTR)) {
+					nr = l2->n;
+					memmove(str->s+len, nr->val.u.sval->s, nr->val.u.sval->len);
+					len += nr->val.u.sval->len;
+					l2 = l2->next;
+				}
+				nl = nod(OXXX, N, N);
+				*nl = *l1->n;
+				nl->orig = nl;
+				nl->val.ctype = CTSTR;
+				nl->val.u.sval = str;
+				l1->n = nl;
+				l1->next = l2;
+			}
+		}
+		// fix list end pointer.
+		for(l2=n->list; l2 != nil; l2=l2->next)
+			n->list->end = l2;
+		// collapse single-constant list to single constant.
+		if(count(n->list) == 1 && isconst(n->list->n, CTSTR)) {
+			n->op = OLITERAL;
+			n->val = n->list->n->val;
+		}
+		return;
+	}
+
+	nl = n->left;
+	if(nl == N || nl->type == T)
+		return;
+	if(consttype(nl) < 0)
+		return;
+	wl = nl->type->etype;
+	if(isint[wl] || isfloat[wl] || iscomplex[wl])
+		wl = TIDEAL;
+
+	nr = n->right;
+	if(nr == N)
+		goto unary;
+	if(nr->type == T)
+		return;
+	if(consttype(nr) < 0)
+		return;
+	wr = nr->type->etype;
+	if(isint[wr] || isfloat[wr] || iscomplex[wr])
+		wr = TIDEAL;
+
+	// check for compatible general types (numeric, string, etc)
+	if(wl != wr)
+		goto illegal;
+
+	// check for compatible types.
+	switch(n->op) {
+	default:
+		// ideal const mixes with anything but otherwise must match.
+		if(nl->type->etype != TIDEAL) {
+			defaultlit(&nr, nl->type);
+			n->right = nr;
+		}
+		if(nr->type->etype != TIDEAL) {
+			defaultlit(&nl, nr->type);
+			n->left = nl;
+		}
+		if(nl->type->etype != nr->type->etype)
+			goto illegal;
+		break;
+
+	case OLSH:
+	case ORSH:
+		// right must be unsigned.
+		// left can be ideal.
+		defaultlit(&nr, types[TUINT]);
+		n->right = nr;
+		if(nr->type && (issigned[nr->type->etype] || !isint[nr->type->etype]))
+			goto illegal;
+		if(nl->val.ctype != CTRUNE)
+			nl->val = toint(nl->val);
+		nr->val = toint(nr->val);
+		break;
+	}
+
+	// copy numeric value to avoid modifying
+	// n->left, in case someone still refers to it (e.g. iota).
+	v = nl->val;
+	if(wl == TIDEAL)
+		v = copyval(v);
+
+	rv = nr->val;
+
+	// convert to common ideal
+	if(v.ctype == CTCPLX || rv.ctype == CTCPLX) {
+		v = tocplx(v);
+		rv = tocplx(rv);
+	}
+	if(v.ctype == CTFLT || rv.ctype == CTFLT) {
+		v = toflt(v);
+		rv = toflt(rv);
+	}
+
+	// Rune and int turns into rune.
+	if(v.ctype == CTRUNE && rv.ctype == CTINT)
+		rv.ctype = CTRUNE;
+	if(v.ctype == CTINT && rv.ctype == CTRUNE) {
+		if(n->op == OLSH || n->op == ORSH)
+			rv.ctype = CTINT;
+		else
+			v.ctype = CTRUNE;
+	}
+
+	if(v.ctype != rv.ctype) {
+		// Use of undefined name as constant?
+		if((v.ctype == 0 || rv.ctype == 0) && nerrors > 0)
+			return;
+		fatal("constant type mismatch %T(%d) %T(%d)", nl->type, v.ctype, nr->type, rv.ctype);
+	}
+
+	// run op
+	switch(TUP(n->op, v.ctype)) {
+	default:
+	illegal:
+		if(!n->diag) {
+			yyerror("illegal constant expression: %T %O %T",
+				nl->type, n->op, nr->type);
+			n->diag = 1;
+		}
+		return;
+
+	case TUP(OADD, CTINT):
+	case TUP(OADD, CTRUNE):
+		mpaddfixfix(v.u.xval, rv.u.xval, 0);
+		break;
+	case TUP(OSUB, CTINT):
+	case TUP(OSUB, CTRUNE):
+		mpsubfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OMUL, CTINT):
+	case TUP(OMUL, CTRUNE):
+		mpmulfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(ODIV, CTINT):
+	case TUP(ODIV, CTRUNE):
+		if(mpcmpfixc(rv.u.xval, 0) == 0) {
+			yyerror("division by zero");
+			mpmovecfix(v.u.xval, 1);
+			break;
+		}
+		mpdivfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OMOD, CTINT):
+	case TUP(OMOD, CTRUNE):
+		if(mpcmpfixc(rv.u.xval, 0) == 0) {
+			yyerror("division by zero");
+			mpmovecfix(v.u.xval, 1);
+			break;
+		}
+		mpmodfixfix(v.u.xval, rv.u.xval);
+		break;
+
+	case TUP(OLSH, CTINT):
+	case TUP(OLSH, CTRUNE):
+		mplshfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(ORSH, CTINT):
+	case TUP(ORSH, CTRUNE):
+		mprshfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OOR, CTINT):
+	case TUP(OOR, CTRUNE):
+		mporfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OAND, CTINT):
+	case TUP(OAND, CTRUNE):
+		mpandfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OANDNOT, CTINT):
+	case TUP(OANDNOT, CTRUNE):
+		mpandnotfixfix(v.u.xval, rv.u.xval);
+		break;
+	case TUP(OXOR, CTINT):
+	case TUP(OXOR, CTRUNE):
+		mpxorfixfix(v.u.xval, rv.u.xval);
+		break;
+
+	case TUP(OADD, CTFLT):
+		mpaddfltflt(v.u.fval, rv.u.fval);
+		break;
+	case TUP(OSUB, CTFLT):
+		mpsubfltflt(v.u.fval, rv.u.fval);
+		break;
+	case TUP(OMUL, CTFLT):
+		mpmulfltflt(v.u.fval, rv.u.fval);
+		break;
+	case TUP(ODIV, CTFLT):
+		if(mpcmpfltc(rv.u.fval, 0) == 0) {
+			yyerror("division by zero");
+			mpmovecflt(v.u.fval, 1.0);
+			break;
+		}
+		mpdivfltflt(v.u.fval, rv.u.fval);
+		break;
+	case TUP(OMOD, CTFLT):
+		// The default case above would print 'ideal % ideal',
+		// which is not quite an ideal error.
+		if(!n->diag) {
+			yyerror("illegal constant expression: floating-point %% operation");
+			n->diag = 1;
+		}
+		return;
+
+	case TUP(OADD, CTCPLX):
+		mpaddfltflt(&v.u.cval->real, &rv.u.cval->real);
+		mpaddfltflt(&v.u.cval->imag, &rv.u.cval->imag);
+		break;
+	case TUP(OSUB, CTCPLX):
+		mpsubfltflt(&v.u.cval->real, &rv.u.cval->real);
+		mpsubfltflt(&v.u.cval->imag, &rv.u.cval->imag);
+		break;
+	case TUP(OMUL, CTCPLX):
+		cmplxmpy(v.u.cval, rv.u.cval);
+		break;
+	case TUP(ODIV, CTCPLX):
+		if(mpcmpfltc(&rv.u.cval->real, 0) == 0 &&
+		   mpcmpfltc(&rv.u.cval->imag, 0) == 0) {
+			yyerror("complex division by zero");
+			mpmovecflt(&rv.u.cval->real, 1.0);
+			mpmovecflt(&rv.u.cval->imag, 0.0);
+			break;
+		}
+		cmplxdiv(v.u.cval, rv.u.cval);
+		break;
+
+	case TUP(OEQ, CTNIL):
+		goto settrue;
+	case TUP(ONE, CTNIL):
+		goto setfalse;
+
+	case TUP(OEQ, CTINT):
+	case TUP(OEQ, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) == 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(ONE, CTINT):
+	case TUP(ONE, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) != 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLT, CTINT):
+	case TUP(OLT, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) < 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLE, CTINT):
+	case TUP(OLE, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) <= 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGE, CTINT):
+	case TUP(OGE, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) >= 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGT, CTINT):
+	case TUP(OGT, CTRUNE):
+		if(mpcmpfixfix(v.u.xval, rv.u.xval) > 0)
+			goto settrue;
+		goto setfalse;
+
+	case TUP(OEQ, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) == 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(ONE, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) != 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLT, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) < 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLE, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) <= 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGE, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) >= 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGT, CTFLT):
+		if(mpcmpfltflt(v.u.fval, rv.u.fval) > 0)
+			goto settrue;
+		goto setfalse;
+
+	case TUP(OEQ, CTCPLX):
+		if(mpcmpfltflt(&v.u.cval->real, &rv.u.cval->real) == 0 &&
+		   mpcmpfltflt(&v.u.cval->imag, &rv.u.cval->imag) == 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(ONE, CTCPLX):
+		if(mpcmpfltflt(&v.u.cval->real, &rv.u.cval->real) != 0 ||
+		   mpcmpfltflt(&v.u.cval->imag, &rv.u.cval->imag) != 0)
+			goto settrue;
+		goto setfalse;
+
+	case TUP(OEQ, CTSTR):
+		if(cmpslit(nl, nr) == 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(ONE, CTSTR):
+		if(cmpslit(nl, nr) != 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLT, CTSTR):
+		if(cmpslit(nl, nr) < 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OLE, CTSTR):
+		if(cmpslit(nl, nr) <= 0)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGE, CTSTR):
+		if(cmpslit(nl, nr) >= 0l)
+			goto settrue;
+		goto setfalse;
+	case TUP(OGT, CTSTR):
+		if(cmpslit(nl, nr) > 0)
+			goto settrue;
+		goto setfalse;
+
+	case TUP(OOROR, CTBOOL):
+		if(v.u.bval || rv.u.bval)
+			goto settrue;
+		goto setfalse;
+	case TUP(OANDAND, CTBOOL):
+		if(v.u.bval && rv.u.bval)
+			goto settrue;
+		goto setfalse;
+	case TUP(OEQ, CTBOOL):
+		if(v.u.bval == rv.u.bval)
+			goto settrue;
+		goto setfalse;
+	case TUP(ONE, CTBOOL):
+		if(v.u.bval != rv.u.bval)
+			goto settrue;
+		goto setfalse;
+	}
+	goto ret;
+
+unary:
+	// copy numeric value to avoid modifying
+	// nl, in case someone still refers to it (e.g. iota).
+	v = nl->val;
+	if(wl == TIDEAL)
+		v = copyval(v);
+
+	switch(TUP(n->op, v.ctype)) {
+	default:
+		if(!n->diag) {
+			yyerror("illegal constant expression %O %T", n->op, nl->type);
+			n->diag = 1;
+		}
+		return;
+
+	case TUP(OCONV, CTNIL):
+	case TUP(OARRAYBYTESTR, CTNIL):
+		if(n->type->etype == TSTRING) {
+			v = tostr(v);
+			nl->type = n->type;
+			break;
+		}
+		// fall through
+	case TUP(OCONV, CTINT):
+	case TUP(OCONV, CTRUNE):
+	case TUP(OCONV, CTFLT):
+	case TUP(OCONV, CTSTR):
+		convlit1(&nl, n->type, 1);
+		v = nl->val;
+		break;
+
+	case TUP(OPLUS, CTINT):
+	case TUP(OPLUS, CTRUNE):
+		break;
+	case TUP(OMINUS, CTINT):
+	case TUP(OMINUS, CTRUNE):
+		mpnegfix(v.u.xval);
+		break;
+	case TUP(OCOM, CTINT):
+	case TUP(OCOM, CTRUNE):
+		et = Txxx;
+		if(nl->type != T)
+			et = nl->type->etype;
+
+		// calculate the mask in b
+		// result will be (a ^ mask)
+		switch(et) {
+		default:
+			// signed guys change sign
+			mpmovecfix(&b, -1);
+			break;
+
+		case TUINT8:
+		case TUINT16:
+		case TUINT32:
+		case TUINT64:
+		case TUINT:
+		case TUINTPTR:
+			// unsigned guys invert their bits
+			mpmovefixfix(&b, maxintval[et]);
+			break;
+		}
+		mpxorfixfix(v.u.xval, &b);
+		break;
+
+	case TUP(OPLUS, CTFLT):
+		break;
+	case TUP(OMINUS, CTFLT):
+		mpnegflt(v.u.fval);
+		break;
+
+	case TUP(OPLUS, CTCPLX):
+		break;
+	case TUP(OMINUS, CTCPLX):
+		mpnegflt(&v.u.cval->real);
+		mpnegflt(&v.u.cval->imag);
+		break;
+
+	case TUP(ONOT, CTBOOL):
+		if(!v.u.bval)
+			goto settrue;
+		goto setfalse;
+	}
+
+ret:
+	norig = saveorig(n);
+	*n = *nl;
+	// restore value of n->orig.
+	n->orig = norig;
+	n->val = v;
+
+	// check range.
+	lno = setlineno(n);
+	overflow(v, n->type);
+	lineno = lno;
+
+	// truncate precision for non-ideal float.
+	if(v.ctype == CTFLT && n->type->etype != TIDEAL)
+		n->val.u.fval = truncfltlit(v.u.fval, n->type);
+	return;
+
+settrue:
+	norig = saveorig(n);
+	*n = *nodbool(1);
+	n->orig = norig;
+	return;
+
+setfalse:
+	norig = saveorig(n);
+	*n = *nodbool(0);
+	n->orig = norig;
+	return;
+}
+
+Node*
+nodlit(Val v)
+{
+	Node *n;
+
+	n = nod(OLITERAL, N, N);
+	n->val = v;
+	switch(v.ctype) {
+	default:
+		fatal("nodlit ctype %d", v.ctype);
+	case CTSTR:
+		n->type = idealstring;
+		break;
+	case CTBOOL:
+		n->type = idealbool;
+		break;
+	case CTINT:
+	case CTRUNE:
+	case CTFLT:
+	case CTCPLX:
+		n->type = types[TIDEAL];
+		break;
+	case CTNIL:
+		n->type = types[TNIL];
+		break;
+	}
+	return n;
+}
+
+Node*
+nodcplxlit(Val r, Val i)
+{
+	Node *n;
+	Mpcplx *c;
+
+	r = toflt(r);
+	i = toflt(i);
+
+	c = mal(sizeof(*c));
+	n = nod(OLITERAL, N, N);
+	n->type = types[TIDEAL];
+	n->val.u.cval = c;
+	n->val.ctype = CTCPLX;
+
+	if(r.ctype != CTFLT || i.ctype != CTFLT)
+		fatal("nodcplxlit ctype %d/%d", r.ctype, i.ctype);
+
+	mpmovefltflt(&c->real, r.u.fval);
+	mpmovefltflt(&c->imag, i.u.fval);
+	return n;
+}
+
+// idealkind returns a constant kind like consttype
+// but for an arbitrary "ideal" (untyped constant) expression.
+static int
+idealkind(Node *n)
+{
+	int k1, k2;
+
+	if(n == N || !isideal(n->type))
+		return CTxxx;
+
+	switch(n->op) {
+	default:
+		return CTxxx;
+	case OLITERAL:
+		return n->val.ctype;
+	case OADD:
+	case OAND:
+	case OANDNOT:
+	case OCOM:
+	case ODIV:
+	case OMINUS:
+	case OMOD:
+	case OMUL:
+	case OSUB:
+	case OXOR:
+	case OOR:
+	case OPLUS:
+		// numeric kinds.
+		k1 = idealkind(n->left);
+		k2 = idealkind(n->right);
+		if(k1 > k2)
+			return k1;
+		else
+			return k2;
+	case OREAL:
+	case OIMAG:
+		return CTFLT;
+	case OCOMPLEX:
+		return CTCPLX;
+	case OADDSTR:
+		return CTSTR;
+	case OANDAND:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLT:
+	case ONE:
+	case ONOT:
+	case OOROR:
+	case OCMPSTR:
+	case OCMPIFACE:
+		return CTBOOL;
+	case OLSH:
+	case ORSH:
+		// shifts (beware!).
+		return idealkind(n->left);
+	}
+}
+
+void
+defaultlit(Node **np, Type *t)
+{
+	int lno;
+	int ctype;
+	Node *n, *nn;
+	Type *t1;
+
+	n = *np;
+	if(n == N || !isideal(n->type))
+		return;
+
+	if(n->op == OLITERAL) {
+		nn = nod(OXXX, N, N);
+		*nn = *n;
+		n = nn;
+		*np = n;
+	}
+
+	lno = setlineno(n);
+	ctype = idealkind(n);
+	switch(ctype) {
+	default:
+		if(t != T) {
+			convlit(np, t);
+			return;
+		}
+		if(n->val.ctype == CTNIL) {
+			lineno = lno;
+			if(!n->diag) {
+				yyerror("use of untyped nil");
+				n->diag = 1;
+			}
+			n->type = T;
+			break;
+		}
+		if(n->val.ctype == CTSTR) {
+			t1 = types[TSTRING];
+			convlit(np, t1);
+			break;
+		}
+		yyerror("defaultlit: unknown literal: %N", n);
+		break;
+	case CTxxx:
+		fatal("defaultlit: idealkind is CTxxx: %+N", n);
+		break;
+	case CTBOOL:
+		t1 = types[TBOOL];
+		if(t != T && t->etype == TBOOL)
+			t1 = t;
+		convlit(np, t1);
+		break;
+	case CTINT:
+		t1 = types[TINT];
+		goto num;
+	case CTRUNE:
+		t1 = runetype;
+		goto num;
+	case CTFLT:
+		t1 = types[TFLOAT64];
+		goto num;
+	case CTCPLX:
+		t1 = types[TCOMPLEX128];
+		goto num;
+	num:
+		if(t != T) {
+			if(isint[t->etype]) {
+				t1 = t;
+				n->val = toint(n->val);
+			}
+			else
+			if(isfloat[t->etype]) {
+				t1 = t;
+				n->val = toflt(n->val);
+			}
+			else
+			if(iscomplex[t->etype]) {
+				t1 = t;
+				n->val = tocplx(n->val);
+			}
+		}
+		overflow(n->val, t1);
+		convlit(np, t1);
+		break;
+	}
+	lineno = lno;
+}
+
+/*
+ * defaultlit on both nodes simultaneously;
+ * if they're both ideal going in they better
+ * get the same type going out.
+ * force means must assign concrete (non-ideal) type.
+ */
+void
+defaultlit2(Node **lp, Node **rp, int force)
+{
+	Node *l, *r;
+	int lkind, rkind;
+
+	l = *lp;
+	r = *rp;
+	if(l->type == T || r->type == T)
+		return;
+	if(!isideal(l->type)) {
+		convlit(rp, l->type);
+		return;
+	}
+	if(!isideal(r->type)) {
+		convlit(lp, r->type);
+		return;
+	}
+	if(!force)
+		return;
+	if(l->type->etype == TBOOL) {
+		convlit(lp, types[TBOOL]);
+		convlit(rp, types[TBOOL]);
+	}
+	lkind = idealkind(l);
+	rkind = idealkind(r);
+	if(lkind == CTCPLX || rkind == CTCPLX) {
+		convlit(lp, types[TCOMPLEX128]);
+		convlit(rp, types[TCOMPLEX128]);
+		return;
+	}
+	if(lkind == CTFLT || rkind == CTFLT) {
+		convlit(lp, types[TFLOAT64]);
+		convlit(rp, types[TFLOAT64]);
+		return;
+	}
+
+	if(lkind == CTRUNE || rkind == CTRUNE) {
+		convlit(lp, runetype);
+		convlit(rp, runetype);
+		return;
+	}
+
+	convlit(lp, types[TINT]);
+	convlit(rp, types[TINT]);
+}
+
+int
+cmpslit(Node *l, Node *r)
+{
+	int32 l1, l2, i, m;
+	uchar *s1, *s2;
+
+	l1 = l->val.u.sval->len;
+	l2 = r->val.u.sval->len;
+	s1 = (uchar*)l->val.u.sval->s;
+	s2 = (uchar*)r->val.u.sval->s;
+
+	m = l1;
+	if(l2 < m)
+		m = l2;
+
+	for(i=0; i<m; i++) {
+		if(s1[i] == s2[i])
+			continue;
+		if(s1[i] > s2[i])
+			return +1;
+		return -1;
+	}
+	if(l1 == l2)
+		return 0;
+	if(l1 > l2)
+		return +1;
+	return -1;
+}
+
+int
+smallintconst(Node *n)
+{
+	if(n->op == OLITERAL && isconst(n, CTINT) && n->type != T)
+	switch(simtype[n->type->etype]) {
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TBOOL:
+	case TPTR32:
+		return 1;
+	case TIDEAL:
+	case TINT64:
+	case TUINT64:
+	case TPTR64:
+		if(mpcmpfixfix(n->val.u.xval, minintval[TINT32]) < 0
+		|| mpcmpfixfix(n->val.u.xval, maxintval[TINT32]) > 0)
+			break;
+		return 1;
+	}
+	return 0;
+}
+
+long
+nonnegconst(Node *n)
+{
+	if(n->op == OLITERAL && n->type != T)
+	switch(simtype[n->type->etype]) {
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TIDEAL:
+		// check negative and 2^31
+		if(mpcmpfixfix(n->val.u.xval, minintval[TUINT32]) < 0
+		|| mpcmpfixfix(n->val.u.xval, maxintval[TINT32]) > 0)
+			break;
+		return mpgetfix(n->val.u.xval);
+	}
+	return -1;
+}
+
+/*
+ * convert x to type et and back to int64
+ * for sign extension and truncation.
+ */
+static int64
+iconv(int64 x, int et)
+{
+	switch(et) {
+	case TINT8:
+		x = (int8)x;
+		break;
+	case TUINT8:
+		x = (uint8)x;
+		break;
+	case TINT16:
+		x = (int16)x;
+		break;
+	case TUINT16:
+		x = (uint64)x;
+		break;
+	case TINT32:
+		x = (int32)x;
+		break;
+	case TUINT32:
+		x = (uint32)x;
+		break;
+	case TINT64:
+	case TUINT64:
+		break;
+	}
+	return x;
+}
+
+/*
+ * convert constant val to type t; leave in con.
+ * for back end.
+ */
+void
+convconst(Node *con, Type *t, Val *val)
+{
+	int64 i;
+	int tt;
+
+	tt = simsimtype(t);
+
+	// copy the constant for conversion
+	nodconst(con, types[TINT8], 0);
+	con->type = t;
+	con->val = *val;
+
+	if(isint[tt]) {
+		con->val.ctype = CTINT;
+		con->val.u.xval = mal(sizeof *con->val.u.xval);
+		switch(val->ctype) {
+		default:
+			fatal("convconst ctype=%d %lT", val->ctype, t);
+		case CTINT:
+		case CTRUNE:
+			i = mpgetfix(val->u.xval);
+			break;
+		case CTBOOL:
+			i = val->u.bval;
+			break;
+		case CTNIL:
+			i = 0;
+			break;
+		}
+		i = iconv(i, tt);
+		mpmovecfix(con->val.u.xval, i);
+		return;
+	}
+
+	if(isfloat[tt]) {
+		con->val = toflt(con->val);
+		if(con->val.ctype != CTFLT)
+			fatal("convconst ctype=%d %T", con->val.ctype, t);
+		if(tt == TFLOAT32)
+			con->val.u.fval = truncfltlit(con->val.u.fval, t);
+		return;
+	}
+
+	if(iscomplex[tt]) {
+		con->val = tocplx(con->val);
+		if(tt == TCOMPLEX64) {
+			con->val.u.cval->real = *truncfltlit(&con->val.u.cval->real, types[TFLOAT32]);
+			con->val.u.cval->imag = *truncfltlit(&con->val.u.cval->imag, types[TFLOAT32]);
+		}
+		return;
+	}
+
+	fatal("convconst %lT constant", t);
+
+}
+
+// complex multiply v *= rv
+//	(a, b) * (c, d) = (a*c - b*d, b*c + a*d)
+static void
+cmplxmpy(Mpcplx *v, Mpcplx *rv)
+{
+	Mpflt ac, bd, bc, ad;
+
+	mpmovefltflt(&ac, &v->real);
+	mpmulfltflt(&ac, &rv->real);	// ac
+
+	mpmovefltflt(&bd, &v->imag);
+	mpmulfltflt(&bd, &rv->imag);	// bd
+
+	mpmovefltflt(&bc, &v->imag);
+	mpmulfltflt(&bc, &rv->real);	// bc
+
+	mpmovefltflt(&ad, &v->real);
+	mpmulfltflt(&ad, &rv->imag);	// ad
+
+	mpmovefltflt(&v->real, &ac);
+	mpsubfltflt(&v->real, &bd);	// ac-bd
+
+	mpmovefltflt(&v->imag, &bc);
+	mpaddfltflt(&v->imag, &ad);	// bc+ad
+}
+
+// complex divide v /= rv
+//	(a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d)
+static void
+cmplxdiv(Mpcplx *v, Mpcplx *rv)
+{
+	Mpflt ac, bd, bc, ad, cc_plus_dd;
+
+	mpmovefltflt(&cc_plus_dd, &rv->real);
+	mpmulfltflt(&cc_plus_dd, &rv->real);	// cc
+
+	mpmovefltflt(&ac, &rv->imag);
+	mpmulfltflt(&ac, &rv->imag);		// dd
+
+	mpaddfltflt(&cc_plus_dd, &ac);		// cc+dd
+
+	mpmovefltflt(&ac, &v->real);
+	mpmulfltflt(&ac, &rv->real);		// ac
+
+	mpmovefltflt(&bd, &v->imag);
+	mpmulfltflt(&bd, &rv->imag);		// bd
+
+	mpmovefltflt(&bc, &v->imag);
+	mpmulfltflt(&bc, &rv->real);		// bc
+
+	mpmovefltflt(&ad, &v->real);
+	mpmulfltflt(&ad, &rv->imag);		// ad
+
+	mpmovefltflt(&v->real, &ac);
+	mpaddfltflt(&v->real, &bd);		// ac+bd
+	mpdivfltflt(&v->real, &cc_plus_dd);	// (ac+bd)/(cc+dd)
+
+	mpmovefltflt(&v->imag, &bc);
+	mpsubfltflt(&v->imag, &ad);		// bc-ad
+	mpdivfltflt(&v->imag, &cc_plus_dd);	// (bc+ad)/(cc+dd)
+}
+
+static int hascallchan(Node*);
+
+// Is n a Go language constant (as opposed to a compile-time constant)?
+// Expressions derived from nil, like string([]byte(nil)), while they
+// may be known at compile time, are not Go language constants.
+// Only called for expressions known to evaluated to compile-time
+// constants.
+int
+isgoconst(Node *n)
+{
+	Node *l;
+	Type *t;
+
+	if(n->orig != N)
+		n = n->orig;
+
+	switch(n->op) {
+	case OADD:
+	case OADDSTR:
+	case OAND:
+	case OANDAND:
+	case OANDNOT:
+	case OCOM:
+	case ODIV:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLSH:
+	case OLT:
+	case OMINUS:
+	case OMOD:
+	case OMUL:
+	case ONE:
+	case ONOT:
+	case OOR:
+	case OOROR:
+	case OPLUS:
+	case ORSH:
+	case OSUB:
+	case OXOR:
+	case OIOTA:
+	case OCOMPLEX:
+	case OREAL:
+	case OIMAG:
+		if(isgoconst(n->left) && (n->right == N || isgoconst(n->right)))
+			return 1;
+		break;
+
+	case OCONV:
+		if(okforconst[n->type->etype] && isgoconst(n->left))
+			return 1;
+		break;
+
+	case OLEN:
+	case OCAP:
+		l = n->left;
+		if(isgoconst(l))
+			return 1;
+		// Special case: len/cap is constant when applied to array or
+		// pointer to array when the expression does not contain
+		// function calls or channel receive operations.
+		t = l->type;
+		if(t != T && isptr[t->etype])
+			t = t->type;
+		if(isfixedarray(t) && !hascallchan(l))
+			return 1;
+		break;
+
+	case OLITERAL:
+		if(n->val.ctype != CTNIL)
+			return 1;
+		break;
+
+	case ONAME:
+		l = n->sym->def;
+		if(l && l->op == OLITERAL && n->val.ctype != CTNIL)
+			return 1;
+		break;
+	
+	case ONONAME:
+		if(n->sym->def != N && n->sym->def->op == OIOTA)
+			return 1;
+		break;
+	
+	case OCALL:
+		// Only constant calls are unsafe.Alignof, Offsetof, and Sizeof.
+		l = n->left;
+		while(l->op == OPAREN)
+			l = l->left;
+		if(l->op != ONAME || l->sym->pkg != unsafepkg)
+			break;
+		if(strcmp(l->sym->name, "Alignof") == 0 ||
+		   strcmp(l->sym->name, "Offsetof") == 0 ||
+		   strcmp(l->sym->name, "Sizeof") == 0)
+			return 1;
+		break;		
+	}
+
+	//dump("nonconst", n);
+	return 0;
+}
+
+static int
+hascallchan(Node *n)
+{
+	NodeList *l;
+
+	if(n == N)
+		return 0;
+	switch(n->op) {
+	case OAPPEND:
+	case OCALL:
+	case OCALLFUNC:
+	case OCALLINTER:
+	case OCALLMETH:
+	case OCAP:
+	case OCLOSE:
+	case OCOMPLEX:
+	case OCOPY:
+	case ODELETE:
+	case OIMAG:
+	case OLEN:
+	case OMAKE:
+	case ONEW:
+	case OPANIC:
+	case OPRINT:
+	case OPRINTN:
+	case OREAL:
+	case ORECOVER:
+	case ORECV:
+		return 1;
+	}
+	
+	if(hascallchan(n->left) ||
+	   hascallchan(n->right))
+		return 1;
+	
+	for(l=n->list; l; l=l->next)
+		if(hascallchan(l->n))
+			return 1;
+	for(l=n->rlist; l; l=l->next)
+		if(hascallchan(l->n))
+			return 1;
+
+	return 0;
+}
diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c
new file mode 100644
index 0000000..c9bab7a
--- /dev/null
+++ b/src/cmd/gc/cplx.c
@@ -0,0 +1,486 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+
+static	void	subnode(Node *nr, Node *ni, Node *nc);
+static	void	minus(Node *nl, Node *res);
+	void	complexminus(Node*, Node*);
+	void	complexadd(int op, Node*, Node*, Node*);
+	void	complexmul(Node*, Node*, Node*);
+
+#define	CASE(a,b)	(((a)<<16)|((b)<<0))
+
+static int
+overlap(Node *f, Node *t)
+{
+	// check whether f and t could be overlapping stack references.
+	// not exact, because it's hard to check for the stack register
+	// in portable code.  close enough: worst case we will allocate
+	// an extra temporary and the registerizer will clean it up.
+	return f->op == OINDREG &&
+		t->op == OINDREG &&
+		f->xoffset+f->type->width >= t->xoffset &&
+		t->xoffset+t->type->width >= f->xoffset;
+}
+
+/*
+ * generate:
+ *	res = n;
+ * simplifies and calls gmove.
+ */
+void
+complexmove(Node *f, Node *t)
+{
+	int ft, tt;
+	Node n1, n2, n3, n4, tmp;
+
+	if(debug['g']) {
+		dump("\ncomplexmove-f", f);
+		dump("complexmove-t", t);
+	}
+
+	if(!t->addable)
+		fatal("complexmove: to not addable");
+
+	ft = simsimtype(f->type);
+	tt = simsimtype(t->type);
+	switch(CASE(ft,tt)) {
+
+	default:
+		fatal("complexmove: unknown conversion: %T -> %T\n",
+			f->type, t->type);
+
+	case CASE(TCOMPLEX64,TCOMPLEX64):
+	case CASE(TCOMPLEX64,TCOMPLEX128):
+	case CASE(TCOMPLEX128,TCOMPLEX64):
+	case CASE(TCOMPLEX128,TCOMPLEX128):
+		// complex to complex move/convert.
+		// make f addable.
+		// also use temporary if possible stack overlap.
+		if(!f->addable || overlap(f, t)) {
+			tempname(&tmp, f->type);
+			complexmove(f, &tmp);
+			f = &tmp;
+		}
+
+		subnode(&n1, &n2, f);
+		subnode(&n3, &n4, t);
+
+		cgen(&n1, &n3);
+		cgen(&n2, &n4);
+		break;
+	}
+}
+
+int
+complexop(Node *n, Node *res)
+{
+	if(n != N && n->type != T)
+	if(iscomplex[n->type->etype]) {
+		goto maybe;
+	}
+	if(res != N && res->type != T)
+	if(iscomplex[res->type->etype]) {
+		goto maybe;
+	}
+
+	if(n->op == OREAL || n->op == OIMAG)
+		goto yes;
+
+	goto no;
+
+maybe:
+	switch(n->op) {
+	case OCONV:	// implemented ops
+	case OADD:
+	case OSUB:
+	case OMUL:
+	case OMINUS:
+	case OCOMPLEX:
+	case OREAL:
+	case OIMAG:
+		goto yes;
+
+	case ODOT:
+	case ODOTPTR:
+	case OINDEX:
+	case OIND:
+	case ONAME:
+		goto yes;
+	}
+
+no:
+//dump("\ncomplex-no", n);
+	return 0;
+yes:
+//dump("\ncomplex-yes", n);
+	return 1;
+}
+
+void
+complexgen(Node *n, Node *res)
+{
+	Node *nl, *nr;
+	Node tnl, tnr;
+	Node n1, n2, tmp;
+	int tl, tr;
+
+	if(debug['g']) {
+		dump("\ncomplexgen-n", n);
+		dump("complexgen-res", res);
+	}
+	
+	while(n->op == OCONVNOP)
+		n = n->left;
+
+	// pick off float/complex opcodes
+	switch(n->op) {
+	case OCOMPLEX:
+		if(res->addable) {
+			subnode(&n1, &n2, res);
+			tempname(&tmp, n1.type);
+			cgen(n->left, &tmp);
+			cgen(n->right, &n2);
+			cgen(&tmp, &n1);
+			return;
+		}
+		break;
+
+	case OREAL:
+	case OIMAG:
+		nl = n->left;
+		if(!nl->addable) {
+			tempname(&tmp, nl->type);
+			complexgen(nl, &tmp);
+			nl = &tmp;
+		}
+		subnode(&n1, &n2, nl);
+		if(n->op == OREAL) {
+			cgen(&n1, res);
+			return;
+		}
+		cgen(&n2, res);
+		return;
+	}
+
+	// perform conversion from n to res
+	tl = simsimtype(res->type);
+	tl = cplxsubtype(tl);
+	tr = simsimtype(n->type);
+	tr = cplxsubtype(tr);
+	if(tl != tr) {
+		if(!n->addable) {
+			tempname(&n1, n->type);
+			complexmove(n, &n1);
+			n = &n1;
+		}
+		complexmove(n, res);
+		return;
+	}
+
+	if(!res->addable) {
+		igen(res, &n1, N);
+		cgen(n, &n1);
+		regfree(&n1);
+		return;
+	}
+	if(n->addable) {
+		complexmove(n, res);
+		return;
+	}
+
+	switch(n->op) {
+	default:
+		dump("complexgen: unknown op", n);
+		fatal("complexgen: unknown op %O", n->op);
+
+	case ODOT:
+	case ODOTPTR:
+	case OINDEX:
+	case OIND:
+	case ONAME:	// PHEAP or PPARAMREF var
+	case OCALLFUNC:
+	case OCALLMETH:
+	case OCALLINTER:
+		igen(n, &n1, res);
+		complexmove(&n1, res);
+		regfree(&n1);
+		return;
+
+	case OCONV:
+	case OADD:
+	case OSUB:
+	case OMUL:
+	case OMINUS:
+	case OCOMPLEX:
+	case OREAL:
+	case OIMAG:
+		break;
+	}
+
+	nl = n->left;
+	if(nl == N)
+		return;
+	nr = n->right;
+
+	// make both sides addable in ullman order
+	if(nr != N) {
+		if(nl->ullman > nr->ullman && !nl->addable) {
+			tempname(&tnl, nl->type);
+			cgen(nl, &tnl);
+			nl = &tnl;
+		}
+		if(!nr->addable) {
+			tempname(&tnr, nr->type);
+			cgen(nr, &tnr);
+			nr = &tnr;
+		}
+	}
+	if(!nl->addable) {
+		tempname(&tnl, nl->type);
+		cgen(nl, &tnl);
+		nl = &tnl;
+	}
+
+	switch(n->op) {
+	default:
+		fatal("complexgen: unknown op %O", n->op);
+		break;
+
+	case OCONV:
+		complexmove(nl, res);
+		break;
+
+	case OMINUS:
+		complexminus(nl, res);
+		break;
+
+	case OADD:
+	case OSUB:
+		complexadd(n->op, nl, nr, res);
+		break;
+
+	case OMUL:
+		complexmul(nl, nr, res);
+		break;
+	}
+}
+
+void
+complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to)
+{
+	Node tnl, tnr;
+	Node n1, n2, n3, n4;
+	Node na, nb, nc;
+
+	// make both sides addable in ullman order
+	if(nr != N) {
+		if(nl->ullman > nr->ullman && !nl->addable) {
+			tempname(&tnl, nl->type);
+			cgen(nl, &tnl);
+			nl = &tnl;
+		}
+		if(!nr->addable) {
+			tempname(&tnr, nr->type);
+			cgen(nr, &tnr);
+			nr = &tnr;
+		}
+	}
+	if(!nl->addable) {
+		tempname(&tnl, nl->type);
+		cgen(nl, &tnl);
+		nl = &tnl;
+	}
+
+	// build tree
+	// real(l) == real(r) && imag(l) == imag(r)
+
+	subnode(&n1, &n2, nl);
+	subnode(&n3, &n4, nr);
+
+	memset(&na, 0, sizeof(na));
+	na.op = OANDAND;
+	na.left = &nb;
+	na.right = &nc;
+	na.type = types[TBOOL];
+
+	memset(&nb, 0, sizeof(na));
+	nb.op = OEQ;
+	nb.left = &n1;
+	nb.right = &n3;
+	nb.type = types[TBOOL];
+
+	memset(&nc, 0, sizeof(na));
+	nc.op = OEQ;
+	nc.left = &n2;
+	nc.right = &n4;
+	nc.type = types[TBOOL];
+
+	if(op == ONE)
+		true = !true;
+
+	bgen(&na, true, likely, to);
+}
+
+void
+nodfconst(Node *n, Type *t, Mpflt* fval)
+{
+	memset(n, 0, sizeof(*n));
+	n->op = OLITERAL;
+	n->addable = 1;
+	ullmancalc(n);
+	n->val.u.fval = fval;
+	n->val.ctype = CTFLT;
+	n->type = t;
+
+	if(!isfloat[t->etype])
+		fatal("nodfconst: bad type %T", t);
+}
+
+// break addable nc-complex into nr-real and ni-imaginary
+static void
+subnode(Node *nr, Node *ni, Node *nc)
+{
+	int tc;
+	Type *t;
+
+	if(!nc->addable)
+		fatal("subnode not addable");
+
+	tc = simsimtype(nc->type);
+	tc = cplxsubtype(tc);
+	t = types[tc];
+
+	if(nc->op == OLITERAL) {
+		nodfconst(nr, t, &nc->val.u.cval->real);
+		nodfconst(ni, t, &nc->val.u.cval->imag);
+		return;
+	}
+
+	*nr = *nc;
+	nr->type = t;
+
+	*ni = *nc;
+	ni->type = t;
+	ni->xoffset += t->width;
+}
+
+// generate code res = -nl
+static void
+minus(Node *nl, Node *res)
+{
+	Node ra;
+
+	memset(&ra, 0, sizeof(ra));
+	ra.op = OMINUS;
+	ra.left = nl;
+	ra.type = nl->type;
+	cgen(&ra, res);
+}
+
+// build and execute tree
+//	real(res) = -real(nl)
+//	imag(res) = -imag(nl)
+void
+complexminus(Node *nl, Node *res)
+{
+	Node n1, n2, n5, n6;
+
+	subnode(&n1, &n2, nl);
+	subnode(&n5, &n6, res);
+
+	minus(&n1, &n5);
+	minus(&n2, &n6);
+}
+
+
+// build and execute tree
+//	real(res) = real(nl) op real(nr)
+//	imag(res) = imag(nl) op imag(nr)
+void
+complexadd(int op, Node *nl, Node *nr, Node *res)
+{
+	Node n1, n2, n3, n4, n5, n6;
+	Node ra;
+
+	subnode(&n1, &n2, nl);
+	subnode(&n3, &n4, nr);
+	subnode(&n5, &n6, res);
+
+	memset(&ra, 0, sizeof(ra));
+	ra.op = op;
+	ra.left = &n1;
+	ra.right = &n3;
+	ra.type = n1.type;
+	cgen(&ra, &n5);
+
+	memset(&ra, 0, sizeof(ra));
+	ra.op = op;
+	ra.left = &n2;
+	ra.right = &n4;
+	ra.type = n2.type;
+	cgen(&ra, &n6);
+}
+
+// build and execute tree
+//	tmp       = real(nl)*real(nr) - imag(nl)*imag(nr)
+//	imag(res) = real(nl)*imag(nr) + imag(nl)*real(nr)
+//	real(res) = tmp
+void
+complexmul(Node *nl, Node *nr, Node *res)
+{
+	Node n1, n2, n3, n4, n5, n6;
+	Node rm1, rm2, ra, tmp;
+
+	subnode(&n1, &n2, nl);
+	subnode(&n3, &n4, nr);
+	subnode(&n5, &n6, res);
+	tempname(&tmp, n5.type);
+
+	// real part -> tmp
+	memset(&rm1, 0, sizeof(ra));
+	rm1.op = OMUL;
+	rm1.left = &n1;
+	rm1.right = &n3;
+	rm1.type = n1.type;
+
+	memset(&rm2, 0, sizeof(ra));
+	rm2.op = OMUL;
+	rm2.left = &n2;
+	rm2.right = &n4;
+	rm2.type = n2.type;
+
+	memset(&ra, 0, sizeof(ra));
+	ra.op = OSUB;
+	ra.left = &rm1;
+	ra.right = &rm2;
+	ra.type = rm1.type;
+	cgen(&ra, &tmp);
+
+	// imag part
+	memset(&rm1, 0, sizeof(ra));
+	rm1.op = OMUL;
+	rm1.left = &n1;
+	rm1.right = &n4;
+	rm1.type = n1.type;
+
+	memset(&rm2, 0, sizeof(ra));
+	rm2.op = OMUL;
+	rm2.left = &n2;
+	rm2.right = &n3;
+	rm2.type = n2.type;
+
+	memset(&ra, 0, sizeof(ra));
+	ra.op = OADD;
+	ra.left = &rm1;
+	ra.right = &rm2;
+	ra.type = rm1.type;
+	cgen(&ra, &n6);
+
+	// tmp ->real part
+	cgen(&tmp, &n5);
+}
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
new file mode 100644
index 0000000..dfcf475
--- /dev/null
+++ b/src/cmd/gc/dcl.c
@@ -0,0 +1,1494 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"y.tab.h"
+
+static	void	funcargs(Node*);
+static	void	funcargs2(Type*);
+
+static int
+dflag(void)
+{
+	if(!debug['d'])
+		return 0;
+	if(debug['y'])
+		return 1;
+	if(incannedimport)
+		return 0;
+	return 1;
+}
+
+/*
+ * declaration stack & operations
+ */
+
+static void
+dcopy(Sym *a, Sym *b)
+{
+	a->pkg = b->pkg;
+	a->name = b->name;
+	a->def = b->def;
+	a->block = b->block;
+	a->lastlineno = b->lastlineno;
+}
+
+static Sym*
+push(void)
+{
+	Sym *d;
+
+	d = mal(sizeof(*d));
+	d->lastlineno = lineno;
+	d->link = dclstack;
+	dclstack = d;
+	return d;
+}
+
+static Sym*
+pushdcl(Sym *s)
+{
+	Sym *d;
+
+	d = push();
+	dcopy(d, s);
+	if(dflag())
+		print("\t%L push %S %p\n", lineno, s, s->def);
+	return d;
+}
+
+void
+popdcl(void)
+{
+	Sym *d, *s;
+	int lno;
+
+//	if(dflag())
+//		print("revert\n");
+
+	for(d=dclstack; d!=S; d=d->link) {
+		if(d->name == nil)
+			break;
+		s = pkglookup(d->name, d->pkg);
+		lno = s->lastlineno;
+		dcopy(s, d);
+		d->lastlineno = lno;
+		if(dflag())
+			print("\t%L pop %S %p\n", lineno, s, s->def);
+	}
+	if(d == S)
+		fatal("popdcl: no mark");
+	dclstack = d->link;
+	block = d->block;
+}
+
+void
+poptodcl(void)
+{
+	// pop the old marker and push a new one
+	// (cannot reuse the existing one)
+	// because we use the markers to identify blocks
+	// for the goto restriction checks.
+	popdcl();
+	markdcl();
+}
+
+void
+markdcl(void)
+{
+	Sym *d;
+
+	d = push();
+	d->name = nil;		// used as a mark in fifo
+	d->block = block;
+
+	blockgen++;
+	block = blockgen;
+
+//	if(dflag())
+//		print("markdcl\n");
+}
+
+void
+dumpdcl(char *st)
+{
+	Sym *s, *d;
+	int i;
+
+	USED(st);
+
+	i = 0;
+	for(d=dclstack; d!=S; d=d->link) {
+		i++;
+		print("    %.2d %p", i, d);
+		if(d->name == nil) {
+			print("\n");
+			continue;
+		}
+		print(" '%s'", d->name);
+		s = pkglookup(d->name, d->pkg);
+		print(" %S\n", s);
+	}
+}
+
+void
+testdclstack(void)
+{
+	Sym *d;
+
+	for(d=dclstack; d!=S; d=d->link) {
+		if(d->name == nil) {
+			if(nerrors != 0)
+				errorexit();
+			yyerror("mark left on the stack");
+			continue;
+		}
+	}
+}
+
+void
+redeclare(Sym *s, char *where)
+{
+	Strlit *pkgstr;
+	int line1, line2;
+
+	if(s->lastlineno == 0) {
+		pkgstr = s->origpkg ? s->origpkg->path : s->pkg->path;
+		yyerror("%S redeclared %s\n"
+			"\tprevious declaration during import \"%Z\"",
+			s, where, pkgstr);
+	} else {
+		line1 = parserline();
+		line2 = s->lastlineno;
+		
+		// When an import and a declaration collide in separate files,
+		// present the import as the "redeclared", because the declaration
+		// is visible where the import is, but not vice versa.
+		// See issue 4510.
+		if(s->def == N) {
+			line2 = line1;
+			line1 = s->lastlineno;
+		}
+
+		yyerrorl(line1, "%S redeclared %s\n"
+			"\tprevious declaration at %L",
+			s, where, line2);
+	}
+}
+
+static int vargen;
+
+/*
+ * declare individual names - var, typ, const
+ */
+void
+declare(Node *n, int ctxt)
+{
+	Sym *s;
+	int gen;
+	static int typegen;
+	
+	if(ctxt == PDISCARD)
+		return;
+
+	if(isblank(n))
+		return;
+
+	n->lineno = parserline();
+	s = n->sym;
+
+	// kludgy: typecheckok means we're past parsing.  Eg genwrapper may declare out of package names later.
+	if(importpkg == nil && !typecheckok && s->pkg != localpkg)
+		yyerror("cannot declare name %S", s);
+
+	if(ctxt == PEXTERN && strcmp(s->name, "init") == 0)
+		yyerror("cannot declare init - must be func", s);
+
+	gen = 0;
+	if(ctxt == PEXTERN) {
+		externdcl = list(externdcl, n);
+		if(dflag())
+			print("\t%L global decl %S %p\n", lineno, s, n);
+	} else {
+		if(curfn == nil && ctxt == PAUTO)
+			fatal("automatic outside function");
+		if(curfn != nil)
+			curfn->dcl = list(curfn->dcl, n);
+		if(n->op == OTYPE)
+			gen = ++typegen;
+		else if(n->op == ONAME && ctxt == PAUTO && strstr(s->name, "·") == nil)
+			gen = ++vargen;
+		pushdcl(s);
+		n->curfn = curfn;
+	}
+	if(ctxt == PAUTO)
+		n->xoffset = 0;
+
+	if(s->block == block) {
+		// functype will print errors about duplicate function arguments.
+		// Don't repeat the error here.
+		if(ctxt != PPARAM && ctxt != PPARAMOUT)
+			redeclare(s, "in this block");
+	}
+
+	s->block = block;
+	s->lastlineno = parserline();
+	s->def = n;
+	n->vargen = gen;
+	n->funcdepth = funcdepth;
+	n->class = ctxt;
+
+	autoexport(n, ctxt);
+}
+
+void
+addvar(Node *n, Type *t, int ctxt)
+{
+	if(n==N || n->sym == S || (n->op != ONAME && n->op != ONONAME) || t == T)
+		fatal("addvar: n=%N t=%T nil", n, t);
+
+	n->op = ONAME;
+	declare(n, ctxt);
+	n->type = t;
+}
+
+/*
+ * declare variables from grammar
+ * new_name_list (type | [type] = expr_list)
+ */
+NodeList*
+variter(NodeList *vl, Node *t, NodeList *el)
+{
+	int doexpr;
+	Node *v, *e, *as2;
+	NodeList *init;
+
+	init = nil;
+	doexpr = el != nil;
+
+	if(count(el) == 1 && count(vl) > 1) {
+		e = el->n;
+		as2 = nod(OAS2, N, N);
+		as2->list = vl;
+		as2->rlist = list1(e);
+		for(; vl; vl=vl->next) {
+			v = vl->n;
+			v->op = ONAME;
+			declare(v, dclcontext);
+			v->ntype = t;
+			v->defn = as2;
+			if(funcdepth > 0)
+				init = list(init, nod(ODCL, v, N));
+		}
+		return list(init, as2);
+	}
+	
+	for(; vl; vl=vl->next) {
+		if(doexpr) {
+			if(el == nil) {
+				yyerror("missing expression in var declaration");
+				break;
+			}
+			e = el->n;
+			el = el->next;
+		} else
+			e = N;
+
+		v = vl->n;
+		v->op = ONAME;
+		declare(v, dclcontext);
+		v->ntype = t;
+
+		if(e != N || funcdepth > 0 || isblank(v)) {
+			if(funcdepth > 0)
+				init = list(init, nod(ODCL, v, N));
+			e = nod(OAS, v, e);
+			init = list(init, e);
+			if(e->right != N)
+				v->defn = e;
+		}
+	}
+	if(el != nil)
+		yyerror("extra expression in var declaration");
+	return init;
+}
+
+/*
+ * declare constants from grammar
+ * new_name_list [[type] = expr_list]
+ */
+NodeList*
+constiter(NodeList *vl, Node *t, NodeList *cl)
+{
+	Node *v, *c;
+	NodeList *vv;
+
+	vv = nil;
+	if(cl == nil) {
+		if(t != N)
+			yyerror("const declaration cannot have type without expression");
+		cl = lastconst;
+		t = lasttype;
+	} else {
+		lastconst = cl;
+		lasttype = t;
+	}
+	cl = listtreecopy(cl);
+
+	for(; vl; vl=vl->next) {
+		if(cl == nil) {
+			yyerror("missing value in const declaration");
+			break;
+		}
+		c = cl->n;
+		cl = cl->next;
+
+		v = vl->n;
+		v->op = OLITERAL;
+		declare(v, dclcontext);
+
+		v->ntype = t;
+		v->defn = c;
+
+		vv = list(vv, nod(ODCLCONST, v, N));
+	}
+	if(cl != nil)
+		yyerror("extra expression in const declaration");
+	iota += 1;
+	return vv;
+}
+
+/*
+ * this generates a new name node,
+ * typically for labels or other one-off names.
+ */
+Node*
+newname(Sym *s)
+{
+	Node *n;
+
+	if(s == S)
+		fatal("newname nil");
+
+	n = nod(ONAME, N, N);
+	n->sym = s;
+	n->type = T;
+	n->addable = 1;
+	n->ullman = 1;
+	n->xoffset = 0;
+	return n;
+}
+
+/*
+ * this generates a new name node for a name
+ * being declared.
+ */
+Node*
+dclname(Sym *s)
+{
+	Node *n;
+
+	n = newname(s);
+	n->op = ONONAME;	// caller will correct it
+	return n;
+}
+
+Node*
+typenod(Type *t)
+{
+	// if we copied another type with *t = *u
+	// then t->nod might be out of date, so
+	// check t->nod->type too
+	if(t->nod == N || t->nod->type != t) {
+		t->nod = nod(OTYPE, N, N);
+		t->nod->type = t;
+		t->nod->sym = t->sym;
+	}
+	return t->nod;
+}
+
+
+/*
+ * this will return an old name
+ * that has already been pushed on the
+ * declaration list. a diagnostic is
+ * generated if no name has been defined.
+ */
+Node*
+oldname(Sym *s)
+{
+	Node *n;
+	Node *c;
+
+	n = s->def;
+	if(n == N) {
+		// maybe a top-level name will come along
+		// to give this a definition later.
+		// walkdef will check s->def again once
+		// all the input source has been processed.
+		n = newname(s);
+		n->op = ONONAME;
+		n->iota = iota;	// save current iota value in const declarations
+	}
+	if(curfn != nil && n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
+		// inner func is referring to var in outer func.
+		//
+		// TODO(rsc): If there is an outer variable x and we
+		// are parsing x := 5 inside the closure, until we get to
+		// the := it looks like a reference to the outer x so we'll
+		// make x a closure variable unnecessarily.
+		if(n->closure == N || n->closure->funcdepth != funcdepth) {
+			// create new closure var.
+			c = nod(ONAME, N, N);
+			c->sym = s;
+			c->class = PPARAMREF;
+			c->isddd = n->isddd;
+			c->defn = n;
+			c->addable = 0;
+			c->ullman = 2;
+			c->funcdepth = funcdepth;
+			c->outer = n->closure;
+			n->closure = c;
+			n->addrtaken = 1;
+			c->closure = n;
+			c->xoffset = 0;
+			curfn->cvars = list(curfn->cvars, c);
+		}
+		// return ref to closure var, not original
+		return n->closure;
+	}
+	return n;
+}
+
+/*
+ * := declarations
+ */
+
+static int
+colasname(Node *n)
+{
+	switch(n->op) {
+	case ONAME:
+	case ONONAME:
+	case OPACK:
+	case OTYPE:
+	case OLITERAL:
+		return n->sym != S;
+	}
+	return 0;
+}
+
+void
+colasdefn(NodeList *left, Node *defn)
+{
+	int nnew, nerr;
+	NodeList *l;
+	Node *n;
+
+	for(l=left; l; l=l->next)
+		if(l->n->sym != S)
+			l->n->sym->flags |= SymUniq;
+
+	nnew = 0;
+	nerr = 0;
+	for(l=left; l; l=l->next) {
+		n = l->n;
+		if(isblank(n))
+			continue;
+		if(!colasname(n)) {
+			yyerrorl(defn->lineno, "non-name %N on left side of :=", n);
+			nerr++;
+			continue;
+		}
+		if((n->sym->flags & SymUniq) == 0) {
+			yyerrorl(defn->lineno, "%S repeated on left side of :=", n->sym);
+			n->diag++;
+			nerr++;
+			continue;
+		}
+		n->sym->flags &= ~SymUniq;
+		if(n->sym->block == block)
+			continue;
+
+		nnew++;
+		n = newname(n->sym);
+		declare(n, dclcontext);
+		n->defn = defn;
+		defn->ninit = list(defn->ninit, nod(ODCL, n, N));
+		l->n = n;
+	}
+	if(nnew == 0 && nerr == 0)
+		yyerrorl(defn->lineno, "no new variables on left side of :=");
+}
+
+Node*
+colas(NodeList *left, NodeList *right, int32 lno)
+{
+	Node *as;
+
+	as = nod(OAS2, N, N);
+	as->list = left;
+	as->rlist = right;
+	as->colas = 1;
+	as->lineno = lno;
+	colasdefn(left, as);
+
+	// make the tree prettier; not necessary
+	if(count(left) == 1 && count(right) == 1) {
+		as->left = as->list->n;
+		as->right = as->rlist->n;
+		as->list = nil;
+		as->rlist = nil;
+		as->op = OAS;
+	}
+
+	return as;
+}
+
+/*
+ * declare the arguments in an
+ * interface field declaration.
+ */
+void
+ifacedcl(Node *n)
+{
+	if(n->op != ODCLFIELD || n->right == N)
+		fatal("ifacedcl");
+
+	if(isblank(n->left))
+		yyerror("methods must have a unique non-blank name");
+
+	dclcontext = PPARAM;
+	markdcl();
+	funcdepth++;
+	n->outer = curfn;
+	curfn = n;
+	funcargs(n->right);
+
+	// funcbody is normally called after the parser has
+	// seen the body of a function but since an interface
+	// field declaration does not have a body, we must
+	// call it now to pop the current declaration context.
+	dclcontext = PAUTO;
+	funcbody(n);
+}
+
+/*
+ * declare the function proper
+ * and declare the arguments.
+ * called in extern-declaration context
+ * returns in auto-declaration context.
+ */
+void
+funchdr(Node *n)
+{
+	// change the declaration context from extern to auto
+	if(funcdepth == 0 && dclcontext != PEXTERN)
+		fatal("funchdr: dclcontext");
+
+	dclcontext = PAUTO;
+	markdcl();
+	funcdepth++;
+
+	n->outer = curfn;
+	curfn = n;
+
+	if(n->nname)
+		funcargs(n->nname->ntype);
+	else if (n->ntype)
+		funcargs(n->ntype);
+	else
+		funcargs2(n->type);
+}
+
+static void
+funcargs(Node *nt)
+{
+	Node *n, *nn;
+	NodeList *l;
+	int gen;
+
+	if(nt->op != OTFUNC)
+		fatal("funcargs %O", nt->op);
+
+	// re-start the variable generation number
+	// we want to use small numbers for the return variables,
+	// so let them have the chunk starting at 1.
+	vargen = count(nt->rlist);
+
+	// declare the receiver and in arguments.
+	// no n->defn because type checking of func header
+	// will not fill in the types until later
+	if(nt->left != N) {
+		n = nt->left;
+		if(n->op != ODCLFIELD)
+			fatal("funcargs receiver %O", n->op);
+		if(n->left != N) {
+			n->left->op = ONAME;
+			n->left->ntype = n->right;
+			declare(n->left, PPARAM);
+			if(dclcontext == PAUTO)
+				n->left->vargen = ++vargen;
+		}
+	}
+	for(l=nt->list; l; l=l->next) {
+		n = l->n;
+		if(n->op != ODCLFIELD)
+			fatal("funcargs in %O", n->op);
+		if(n->left != N) {
+			n->left->op = ONAME;
+			n->left->ntype = n->right;
+			declare(n->left, PPARAM);
+			if(dclcontext == PAUTO)
+				n->left->vargen = ++vargen;
+		}
+	}
+
+	// declare the out arguments.
+	gen = count(nt->list);
+	int i = 0;
+	for(l=nt->rlist; l; l=l->next) {
+		n = l->n;
+
+		if(n->op != ODCLFIELD)
+			fatal("funcargs out %O", n->op);
+
+		if(n->left == N) {
+			// Name so that escape analysis can track it. ~r stands for 'result'.
+			snprint(namebuf, sizeof(namebuf), "~r%d", gen++);
+			n->left = newname(lookup(namebuf));
+			// TODO: n->left->missing = 1;
+		} 
+
+		n->left->op = ONAME;
+
+		if(isblank(n->left)) {
+			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
+			// The name must be different from ~r above because if you have
+			//	func f() (_ int)
+			//	func g() int
+			// f is allowed to use a plain 'return' with no arguments, while g is not.
+			// So the two cases must be distinguished.
+			// We do not record a pointer to the original node (n->orig).
+			// Having multiple names causes too much confusion in later passes.
+			nn = nod(OXXX, N, N);
+			*nn = *n->left;
+			nn->orig = nn;
+			snprint(namebuf, sizeof(namebuf), "~b%d", gen++);
+			nn->sym = lookup(namebuf);
+			n->left = nn;
+		}
+
+		n->left->ntype = n->right;
+		declare(n->left, PPARAMOUT);
+		if(dclcontext == PAUTO)
+			n->left->vargen = ++i;
+	}
+}
+
+/*
+ * Same as funcargs, except run over an already constructed TFUNC.
+ * This happens during import, where the hidden_fndcl rule has
+ * used functype directly to parse the function's type.
+ */
+static void
+funcargs2(Type *t)
+{
+	Type *ft;
+	Node *n;
+
+	if(t->etype != TFUNC)
+		fatal("funcargs2 %T", t);
+	
+	if(t->thistuple)
+		for(ft=getthisx(t)->type; ft; ft=ft->down) {
+			if(!ft->nname || !ft->nname->sym)
+				continue;
+			n = ft->nname;  // no need for newname(ft->nname->sym)
+			n->type = ft->type;
+			declare(n, PPARAM);
+		}
+
+	if(t->intuple)
+		for(ft=getinargx(t)->type; ft; ft=ft->down) {
+			if(!ft->nname || !ft->nname->sym)
+				continue;
+			n = ft->nname;
+			n->type = ft->type;
+			declare(n, PPARAM);
+		}
+
+	if(t->outtuple)
+		for(ft=getoutargx(t)->type; ft; ft=ft->down) {
+			if(!ft->nname || !ft->nname->sym)
+				continue;
+			n = ft->nname;
+			n->type = ft->type;
+			declare(n, PPARAMOUT);
+		}
+}
+
+/*
+ * finish the body.
+ * called in auto-declaration context.
+ * returns in extern-declaration context.
+ */
+void
+funcbody(Node *n)
+{
+	// change the declaration context from auto to extern
+	if(dclcontext != PAUTO)
+		fatal("funcbody: dclcontext");
+	popdcl();
+	funcdepth--;
+	curfn = n->outer;
+	n->outer = N;
+	if(funcdepth == 0)
+		dclcontext = PEXTERN;
+}
+
+/*
+ * new type being defined with name s.
+ */
+Node*
+typedcl0(Sym *s)
+{
+	Node *n;
+
+	n = newname(s);
+	n->op = OTYPE;
+	declare(n, dclcontext);
+	return n;
+}
+
+/*
+ * node n, which was returned by typedcl0
+ * is being declared to have uncompiled type t.
+ * return the ODCLTYPE node to use.
+ */
+Node*
+typedcl1(Node *n, Node *t, int local)
+{
+	n->ntype = t;
+	n->local = local;
+	return nod(ODCLTYPE, n, N);
+}
+
+/*
+ * structs, functions, and methods.
+ * they don't belong here, but where do they belong?
+ */
+
+static void
+checkembeddedtype(Type *t)
+{
+	if (t == T)
+		return;
+
+	if(t->sym == S && isptr[t->etype]) {
+		t = t->type;
+		if(t->etype == TINTER)
+			yyerror("embedded type cannot be a pointer to interface");
+	}
+	if(isptr[t->etype])
+		yyerror("embedded type cannot be a pointer");
+	else if(t->etype == TFORW && t->embedlineno == 0)
+		t->embedlineno = lineno;
+}
+
+static Type*
+structfield(Node *n)
+{
+	Type *f;
+	int lno;
+
+	lno = lineno;
+	lineno = n->lineno;
+
+	if(n->op != ODCLFIELD)
+		fatal("structfield: oops %N\n", n);
+
+	f = typ(TFIELD);
+	f->isddd = n->isddd;
+
+	if(n->right != N) {
+		typecheck(&n->right, Etype);
+		n->type = n->right->type;
+		if(n->left != N)
+			n->left->type = n->type;
+		if(n->embedded)
+			checkembeddedtype(n->type);
+	}
+	n->right = N;
+		
+	f->type = n->type;
+	if(f->type == T)
+		f->broke = 1;
+
+	switch(n->val.ctype) {
+	case CTSTR:
+		f->note = n->val.u.sval;
+		break;
+	default:
+		yyerror("field annotation must be string");
+		// fallthrough
+	case CTxxx:
+		f->note = nil;
+		break;
+	}
+
+	if(n->left && n->left->op == ONAME) {
+		f->nname = n->left;
+		f->embedded = n->embedded;
+		f->sym = f->nname->sym;
+	}
+
+	lineno = lno;
+	return f;
+}
+
+static uint32 uniqgen;
+
+static void
+checkdupfields(Type *t, char* what)
+{
+	int lno;
+
+	lno = lineno;
+
+	for( ; t; t=t->down) {
+		if(t->sym && t->nname && !isblank(t->nname)) {
+			if(t->sym->uniqgen == uniqgen) {
+				lineno = t->nname->lineno;
+				yyerror("duplicate %s %s", what, t->sym->name);
+			} else
+				t->sym->uniqgen = uniqgen;
+		}
+	}
+
+	lineno = lno;
+}
+
+/*
+ * convert a parsed id/type list into
+ * a type for struct/interface/arglist
+ */
+Type*
+tostruct(NodeList *l)
+{
+	Type *t, *f, **tp;
+	t = typ(TSTRUCT);
+
+	for(tp = &t->type; l; l=l->next) {
+		f = structfield(l->n);
+
+		*tp = f;
+		tp = &f->down;
+	}
+
+	for(f=t->type; f && !t->broke; f=f->down)
+		if(f->broke)
+			t->broke = 1;
+
+	uniqgen++;
+	checkdupfields(t->type, "field");
+
+	if (!t->broke)
+		checkwidth(t);
+
+	return t;
+}
+
+static Type*
+tofunargs(NodeList *l)
+{
+	Type *t, *f, **tp;
+
+	t = typ(TSTRUCT);
+	t->funarg = 1;
+
+	for(tp = &t->type; l; l=l->next) {
+		f = structfield(l->n);
+		f->funarg = 1;
+
+		// esc.c needs to find f given a PPARAM to add the tag.
+		if(l->n->left && l->n->left->class == PPARAM)
+			l->n->left->paramfld = f;
+
+		*tp = f;
+		tp = &f->down;
+	}
+
+	for(f=t->type; f && !t->broke; f=f->down)
+		if(f->broke)
+			t->broke = 1;
+
+	return t;
+}
+
+static Type*
+interfacefield(Node *n)
+{
+	Type *f;
+	int lno;
+
+	lno = lineno;
+	lineno = n->lineno;
+
+	if(n->op != ODCLFIELD)
+		fatal("interfacefield: oops %N\n", n);
+
+	if (n->val.ctype != CTxxx)
+		yyerror("interface method cannot have annotation");
+
+	f = typ(TFIELD);
+	f->isddd = n->isddd;
+	
+	if(n->right != N) {
+		if(n->left != N) {
+			// queue resolution of method type for later.
+			// right now all we need is the name list.
+			// avoids cycles for recursive interface types.
+			n->type = typ(TINTERMETH);
+			n->type->nname = n->right;
+			n->left->type = n->type;
+			queuemethod(n);
+
+			if(n->left->op == ONAME) {
+				f->nname = n->left;
+				f->embedded = n->embedded;
+				f->sym = f->nname->sym;
+			}
+
+		} else {
+
+			typecheck(&n->right, Etype);
+			n->type = n->right->type;
+
+			if(n->embedded)
+				checkembeddedtype(n->type);
+
+			if(n->type)
+				switch(n->type->etype) {
+				case TINTER:
+					break;
+				case TFORW:
+					yyerror("interface type loop involving %T", n->type);
+					f->broke = 1;
+					break;
+				default:
+					yyerror("interface contains embedded non-interface %T", n->type);
+					f->broke = 1;
+					break;
+				}
+		}
+	}
+
+	n->right = N;
+	
+	f->type = n->type;
+	if(f->type == T)
+		f->broke = 1;
+	
+	lineno = lno;
+	return f;
+}
+
+Type*
+tointerface(NodeList *l)
+{
+	Type *t, *f, **tp, *t1;
+
+	t = typ(TINTER);
+
+	tp = &t->type;
+	for(; l; l=l->next) {
+		f = interfacefield(l->n);
+
+		if (l->n->left == N && f->type->etype == TINTER) {
+			// embedded interface, inline methods
+			for(t1=f->type->type; t1; t1=t1->down) {
+				f = typ(TFIELD);
+				f->type = t1->type;
+				f->broke = t1->broke;
+				f->sym = t1->sym;
+				if(f->sym)
+					f->nname = newname(f->sym);
+				*tp = f;
+				tp = &f->down;
+			}
+		} else {
+			*tp = f;
+			tp = &f->down;
+		}
+	}
+
+	for(f=t->type; f && !t->broke; f=f->down)
+		if(f->broke)
+			t->broke = 1;
+
+	uniqgen++;
+	checkdupfields(t->type, "method");
+	t = sortinter(t);
+	checkwidth(t);
+
+	return t;
+}
+
+Node*
+embedded(Sym *s, Pkg *pkg)
+{
+	Node *n;
+	char *name;
+
+	// Names sometimes have disambiguation junk
+	// appended after a center dot.  Discard it when
+	// making the name for the embedded struct field.
+	enum { CenterDot = 0xB7 };
+	name = s->name;
+	if(utfrune(s->name, CenterDot)) {
+		name = strdup(s->name);
+		*utfrune(name, CenterDot) = 0;
+	}
+
+	if(exportname(name))
+		n = newname(lookup(name));
+	else if(s->pkg == builtinpkg)
+		// The name of embedded builtins belongs to pkg.
+		n = newname(pkglookup(name, pkg));
+	else
+		n = newname(pkglookup(name, s->pkg));
+	n = nod(ODCLFIELD, n, oldname(s));
+	n->embedded = 1;
+	return n;
+}
+
+/*
+ * check that the list of declarations is either all anonymous or all named
+ */
+
+static Node*
+findtype(NodeList *l)
+{
+	for(; l; l=l->next)
+		if(l->n->op == OKEY)
+			return l->n->right;
+	return N;
+}
+
+NodeList*
+checkarglist(NodeList *all, int input)
+{
+	int named;
+	Node *n, *t, *nextt;
+	NodeList *l;
+
+	named = 0;
+	for(l=all; l; l=l->next) {
+		if(l->n->op == OKEY) {
+			named = 1;
+			break;
+		}
+	}
+	if(named) {
+		n = N;
+		for(l=all; l; l=l->next) {
+			n = l->n;
+			if(n->op != OKEY && n->sym == S) {
+				yyerror("mixed named and unnamed function parameters");
+				break;
+			}
+		}
+		if(l == nil && n != N && n->op != OKEY)
+			yyerror("final function parameter must have type");
+	}
+
+	nextt = nil;
+	for(l=all; l; l=l->next) {
+		// can cache result from findtype to avoid
+		// quadratic behavior here, but unlikely to matter.
+		n = l->n;
+		if(named) {
+			if(n->op == OKEY) {
+				t = n->right;
+				n = n->left;
+				nextt = nil;
+			} else {
+				if(nextt == nil)
+					nextt = findtype(l);
+				t = nextt;
+			}
+		} else {
+			t = n;
+			n = N;
+		}
+
+		// during import l->n->op is OKEY, but l->n->left->sym == S
+		// means it was a '?', not that it was
+		// a lone type This doesn't matter for the exported
+		// declarations, which are parsed by rules that don't
+		// use checkargs, but can happen for func literals in
+		// the inline bodies.
+		// TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ?
+		if(importpkg && n->sym == S)
+			n = N;
+
+		if(n != N && n->sym == S) {
+			t = n;
+			n = N;
+		}
+		if(n != N)
+			n = newname(n->sym);
+		n = nod(ODCLFIELD, n, t);
+		if(n->right != N && n->right->op == ODDD) {
+			if(!input)
+				yyerror("cannot use ... in output argument list");
+			else if(l->next != nil)
+				yyerror("can only use ... as final argument in list");
+			n->right->op = OTARRAY;
+			n->right->right = n->right->left;
+			n->right->left = N;
+			n->isddd = 1;
+			if(n->left != N)
+				n->left->isddd = 1;
+		}
+		l->n = n;
+	}
+	return all;
+}
+
+
+Node*
+fakethis(void)
+{
+	Node *n;
+
+	n = nod(ODCLFIELD, N, typenod(ptrto(typ(TSTRUCT))));
+	return n;
+}
+
+/*
+ * Is this field a method on an interface?
+ * Those methods have an anonymous
+ * *struct{} as the receiver.
+ * (See fakethis above.)
+ */
+int
+isifacemethod(Type *f)
+{
+	Type *rcvr;
+	Type *t;
+
+	rcvr = getthisx(f)->type;
+	if(rcvr->sym != S)
+		return 0;
+	t = rcvr->type;
+	if(!isptr[t->etype])
+		return 0;
+	t = t->type;
+	if(t->sym != S || t->etype != TSTRUCT || t->type != T)
+		return 0;
+	return 1;
+}
+
+/*
+ * turn a parsed function declaration
+ * into a type
+ */
+Type*
+functype(Node *this, NodeList *in, NodeList *out)
+{
+	Type *t;
+	NodeList *rcvr;
+	Sym *s;
+
+	t = typ(TFUNC);
+
+	rcvr = nil;
+	if(this)
+		rcvr = list1(this);
+	t->type = tofunargs(rcvr);
+	t->type->down = tofunargs(out);
+	t->type->down->down = tofunargs(in);
+
+	uniqgen++;
+	checkdupfields(t->type->type, "argument");
+	checkdupfields(t->type->down->type, "argument");
+	checkdupfields(t->type->down->down->type, "argument");
+
+	if (t->type->broke || t->type->down->broke || t->type->down->down->broke)
+		t->broke = 1;
+
+	if(this)
+		t->thistuple = 1;
+	t->outtuple = count(out);
+	t->intuple = count(in);
+	t->outnamed = 0;
+	if(t->outtuple > 0 && out->n->left != N && out->n->left->orig != N) {
+		s = out->n->left->orig->sym;
+		if(s != S && (s->name[0] != '~' || s->name[1] != 'r')) // ~r%d is the name invented for an unnamed result
+			t->outnamed = 1;
+	}
+
+	return t;
+}
+
+Sym*
+methodsym(Sym *nsym, Type *t0, int iface)
+{
+	Sym *s;
+	char *p;
+	Type *t;
+	char *suffix;
+	Pkg *spkg;
+	static Pkg *toppkg;
+
+	t = t0;
+	if(t == T)
+		goto bad;
+	s = t->sym;
+	if(s == S && isptr[t->etype]) {
+		t = t->type;
+		if(t == T)
+			goto bad;
+		s = t->sym;
+	}
+	spkg = nil;
+	if(s != S)
+		spkg = s->pkg;
+
+	// if t0 == *t and t0 has a sym,
+	// we want to see *t, not t0, in the method name.
+	if(t != t0 && t0->sym)
+		t0 = ptrto(t);
+
+	suffix = "";
+	if(iface) {
+		dowidth(t0);
+		if(t0->width < types[tptr]->width)
+			suffix = "·i";
+	}
+	if((spkg == nil || nsym->pkg != spkg) && !exportname(nsym->name)) {
+		if(t0->sym == S && isptr[t0->etype])
+			p = smprint("(%-hT).%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix);
+		else
+			p = smprint("%-hT.%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix);
+	} else {
+		if(t0->sym == S && isptr[t0->etype])
+			p = smprint("(%-hT).%s%s", t0, nsym->name, suffix);
+		else
+			p = smprint("%-hT.%s%s", t0, nsym->name, suffix);
+	}
+	if(spkg == nil) {
+		if(toppkg == nil)
+			toppkg = mkpkg(strlit("go"));
+		spkg = toppkg;
+	}
+	s = pkglookup(p, spkg);
+	free(p);
+	return s;
+
+bad:
+	yyerror("illegal receiver type: %T", t0);
+	return S;
+}
+
+Node*
+methodname(Node *n, Type *t)
+{
+	Sym *s;
+
+	s = methodsym(n->sym, t, 0);
+	if(s == S)
+		return n;
+	return newname(s);
+}
+
+Node*
+methodname1(Node *n, Node *t)
+{
+	char *star;
+	char *p;
+
+	star = nil;
+	if(t->op == OIND) {
+		star = "*";
+		t = t->left;
+	}
+	if(t->sym == S || isblank(n))
+		return newname(n->sym);
+
+	if(star)
+		p = smprint("(%s%S).%S", star, t->sym, n->sym);
+	else
+		p = smprint("%S.%S", t->sym, n->sym);
+
+	if(exportname(t->sym->name))
+		n = newname(lookup(p));
+	else
+		n = newname(pkglookup(p, t->sym->pkg));
+	free(p);
+	return n;
+}
+
+/*
+ * add a method, declared as a function,
+ * n is fieldname, pa is base type, t is function type
+ */
+void
+addmethod(Sym *sf, Type *t, int local, int nointerface)
+{
+	Type *f, *d, *pa;
+	Node *n;
+
+	// get field sym
+	if(sf == S)
+		fatal("no method symbol");
+
+	// get parent type sym
+	pa = getthisx(t)->type;	// ptr to this structure
+	if(pa == T) {
+		yyerror("missing receiver");
+		return;
+	}
+
+	pa = pa->type;
+	f = methtype(pa, 1);
+	if(f == T) {
+		t = pa;
+		if(t == T) // rely on typecheck having complained before
+			return;
+		if(t != T) {
+			if(isptr[t->etype]) {
+				if(t->sym != S) {
+					yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+					return;
+				}
+				t = t->type;
+			}
+			if(t->broke) // rely on typecheck having complained before
+				return;
+			if(t->sym == S) {
+				yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
+				return;
+			}
+			if(isptr[t->etype]) {
+				yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+				return;
+			}
+			if(t->etype == TINTER) {
+				yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
+				return;
+			}
+		}
+		// Should have picked off all the reasons above,
+		// but just in case, fall back to generic error.
+		yyerror("invalid receiver type %T (%lT / %lT)", pa, pa, t);
+		return;
+	}
+
+	pa = f;
+	if(pa->etype == TSTRUCT) {
+		for(f=pa->type; f; f=f->down) {
+			if(f->sym == sf) {
+				yyerror("type %T has both field and method named %S", pa, sf);
+				return;
+			}
+		}
+	}
+
+	if(local && !pa->local) {
+		// defining method on non-local type.
+		yyerror("cannot define new methods on non-local type %T", pa);
+		return;
+	}
+
+	n = nod(ODCLFIELD, newname(sf), N);
+	n->type = t;
+
+	d = T;	// last found
+	for(f=pa->method; f!=T; f=f->down) {
+		d = f;
+		if(f->etype != TFIELD)
+			fatal("addmethod: not TFIELD: %N", f);
+		if(strcmp(sf->name, f->sym->name) != 0)
+			continue;
+		if(!eqtype(t, f->type))
+			yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
+		return;
+	}
+
+	f = structfield(n);
+	f->nointerface = nointerface;
+
+	// during import unexported method names should be in the type's package
+	if(importpkg && f->sym && !exportname(f->sym->name) && f->sym->pkg != structpkg)
+		fatal("imported method name %+S in wrong package %s\n", f->sym, structpkg->name);
+
+	if(d == T)
+		pa->method = f;
+	else
+		d->down = f;
+	return;
+}
+
+void
+funccompile(Node *n, int isclosure)
+{
+	stksize = BADWIDTH;
+	maxarg = 0;
+
+	if(n->type == T) {
+		if(nerrors == 0)
+			fatal("funccompile missing type");
+		return;
+	}
+
+	// assign parameter offsets
+	checkwidth(n->type);
+	
+	// record offset to actual frame pointer.
+	// for closure, have to skip over leading pointers and PC slot.
+	// TODO(rsc): this is the old jit closure handling code.
+	// with the new closures, isclosure is always 0; delete this block.
+	nodfp->xoffset = 0;
+	if(isclosure) {
+		NodeList *l;
+		for(l=n->nname->ntype->list; l; l=l->next) {
+			nodfp->xoffset += widthptr;
+			if(l->n->left == N)	// found slot for PC
+				break;
+		}
+	}
+
+	if(curfn)
+		fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
+
+	stksize = 0;
+	dclcontext = PAUTO;
+	funcdepth = n->funcdepth + 1;
+	compile(n);
+	curfn = nil;
+	funcdepth = 0;
+	dclcontext = PEXTERN;
+}
+
+Sym*
+funcsym(Sym *s)
+{
+	char *p;
+	Sym *s1;
+	
+	p = smprint("%s·f", s->name);
+	s1 = pkglookup(p, s->pkg);
+	free(p);
+	if(s1->def == N) {
+		s1->def = newname(s1);
+		s1->def->shortname = newname(s);
+		funcsyms = list(funcsyms, s1->def);
+	}
+	return s1;
+}
diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go
new file mode 100644
index 0000000..03df93a
--- /dev/null
+++ b/src/cmd/gc/doc.go
@@ -0,0 +1,95 @@
+// 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.
+
+// +build ignore
+
+/*
+
+Gc is the generic label for the family of Go compilers
+that function as part of the (modified) Plan 9 tool chain.  The C compiler
+documentation at
+
+	http://plan9.bell-labs.com/sys/doc/comp.pdf     (Tools overview)
+	http://plan9.bell-labs.com/sys/doc/compiler.pdf (C compiler architecture)
+
+gives the overall design of the tool chain.  Aside from a few adapted pieces,
+such as the optimizer, the Go compilers are wholly new programs.
+
+The compiler reads in a set of Go files, typically suffixed ".go".  They
+must all be part of one package.  The output is a single intermediate file
+representing the "binary assembly" of the compiled package, ready as input
+for the linker (6l, etc.).
+
+The generated files contain type information about the symbols exported by
+the package and about types used by symbols imported by the package from
+other packages. It is therefore not necessary when compiling client C of
+package P to read the files of P's dependencies, only the compiled output
+of P.
+
+Command Line
+
+Usage:
+	go tool 6g [flags] file...
+The specified files must be Go source files and all part of the same package.
+Substitute 6g with 8g or 5g where appropriate.
+
+Flags:
+	-o file
+		output file, default file.6 for 6g, etc.
+	-pack
+		write an archive file rather than an object file
+	-e
+		normally the compiler quits after 10 errors; -e prints all errors
+	-p path
+		assume that path is the eventual import path for this code,
+		and diagnose any attempt to import a package that depends on it.
+	-D path
+		treat a relative import as relative to path
+	-L
+		show entire file path when printing line numbers in errors
+	-I dir1 -I dir2
+		add dir1 and dir2 to the list of paths to check for imported packages
+	-N
+		disable optimizations
+	-nolocalimports
+		disallow local (relative) imports
+	-S
+		write assembly language text to standard output (code only)
+	-S -S
+		write assembly language text to standard output (code and data)
+	-u
+		disallow importing packages not marked as safe; implies -nolocalimports
+	-V
+		print the compiler version
+	-race
+		compile with race detection enabled
+
+There are also a number of debugging flags; run the command with no arguments
+to get a usage message.
+
+Compiler Directives
+
+The compiler accepts two compiler directives in the form of // comments at the
+beginning of a line. To distinguish them from non-directive comments, the directives
+require no space between the slashes and the name of the directive. However, since
+they are comments, tools unaware of the directive convention or of a particular
+directive can skip over a directive like any other comment.
+
+    //line path/to/file:linenumber
+
+The //line directive specifies that the source line that follows should be recorded
+as having come from the given file path and line number. Successive lines are
+recorded using increasing line numbers, until the next directive. This directive
+typically appears in machine-generated code, so that compilers and debuggers
+will show lines in the original input to the generator.
+
+    //go:noescape
+
+The //go:noescape directive specifies that the next declaration in the file, which
+must be a func without a body (meaning that it has an implementation not written
+in Go) does not allow any of the pointers passed as arguments to escape into the
+heap or into the values returned from the function. This information can be used as
+during the compiler's escape analysis of Go code calling the function.
+*/
+package main
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
new file mode 100644
index 0000000..324f24f
--- /dev/null
+++ b/src/cmd/gc/esc.c
@@ -0,0 +1,1281 @@
+// Copyright 2011 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.
+
+// Escape analysis.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+// Run analysis on minimal sets of mutually recursive functions
+// or single non-recursive functions, bottom up.
+//
+// Finding these sets is finding strongly connected components
+// in the static call graph.  The algorithm for doing that is taken
+// from Sedgewick, Algorithms, Second Edition, p. 482, with two
+// adaptations.
+//
+// First, a hidden closure function (n->curfn != N) cannot be the
+// root of a connected component. Refusing to use it as a root
+// forces it into the component of the function in which it appears.
+// The analysis assumes that closures and the functions in which they
+// appear are analyzed together, so that the aliasing between their
+// variables can be modeled more precisely.
+//
+// Second, each function becomes two virtual nodes in the graph,
+// with numbers n and n+1. We record the function's node number as n
+// but search from node n+1. If the search tells us that the component
+// number (min) is n+1, we know that this is a trivial component: one function
+// plus its closures. If the search tells us that the component number is
+// n, then there was a path from node n+1 back to node n, meaning that
+// the function set is mutually recursive. The escape analysis can be
+// more precise when analyzing a single non-recursive function than
+// when analyzing a set of mutually recursive functions.
+
+static NodeList *stack;
+static uint32 visitgen;
+static uint32 visit(Node*);
+static uint32 visitcode(Node*, uint32);
+static uint32 visitcodelist(NodeList*, uint32);
+
+static void analyze(NodeList*, int);
+
+enum
+{
+	EscFuncUnknown = 0,
+	EscFuncPlanned,
+	EscFuncStarted,
+	EscFuncTagged,
+};
+
+void
+escapes(NodeList *all)
+{
+	NodeList *l;
+
+	for(l=all; l; l=l->next)
+		l->n->walkgen = 0;
+
+	visitgen = 0;
+	for(l=all; l; l=l->next)
+		if(l->n->op == ODCLFUNC && l->n->curfn == N)
+			visit(l->n);
+
+	for(l=all; l; l=l->next)
+		l->n->walkgen = 0;
+}
+
+static uint32
+visit(Node *n)
+{
+	uint32 min, recursive;
+	NodeList *l, *block;
+
+	if(n->walkgen > 0) {
+		// already visited
+		return n->walkgen;
+	}
+	
+	visitgen++;
+	n->walkgen = visitgen;
+	visitgen++;
+	min = visitgen;
+
+	l = mal(sizeof *l);
+	l->next = stack;
+	l->n = n;
+	stack = l;
+	min = visitcodelist(n->nbody, min);
+	if((min == n->walkgen || min == n->walkgen+1) && n->curfn == N) {
+		// This node is the root of a strongly connected component.
+
+		// The original min passed to visitcodelist was n->walkgen+1.
+		// If visitcodelist found its way back to n->walkgen, then this
+		// block is a set of mutually recursive functions.
+		// Otherwise it's just a lone function that does not recurse.
+		recursive = min == n->walkgen;
+
+		// Remove connected component from stack.
+		// Mark walkgen so that future visits return a large number
+		// so as not to affect the caller's min.
+		block = stack;
+		for(l=stack; l->n != n; l=l->next)
+			l->n->walkgen = (uint32)~0U;
+		n->walkgen = (uint32)~0U;
+		stack = l->next;
+		l->next = nil;
+
+		// Run escape analysis on this set of functions.
+		analyze(block, recursive);
+	}
+
+	return min;
+}
+
+static uint32
+visitcodelist(NodeList *l, uint32 min)
+{
+	for(; l; l=l->next)
+		min = visitcode(l->n, min);
+	return min;
+}
+
+static uint32
+visitcode(Node *n, uint32 min)
+{
+	Node *fn;
+	uint32 m;
+
+	if(n == N)
+		return min;
+
+	min = visitcodelist(n->ninit, min);
+	min = visitcode(n->left, min);
+	min = visitcode(n->right, min);
+	min = visitcodelist(n->list, min);
+	min = visitcode(n->ntest, min);
+	min = visitcode(n->nincr, min);
+	min = visitcodelist(n->nbody, min);
+	min = visitcodelist(n->nelse, min);
+	min = visitcodelist(n->rlist, min);
+	
+	if(n->op == OCALLFUNC || n->op == OCALLMETH) {
+		fn = n->left;
+		if(n->op == OCALLMETH)
+			fn = n->left->right->sym->def;
+		if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn)
+			if((m = visit(fn->defn)) < min)
+				min = m;
+	}
+	
+	if(n->op == OCLOSURE)
+		if((m = visit(n->closure)) < min)
+			min = m;
+
+	return min;
+}
+
+// An escape analysis pass for a set of functions.
+//
+// First escfunc, esc and escassign recurse over the ast of each
+// function to dig out flow(dst,src) edges between any
+// pointer-containing nodes and store them in dst->escflowsrc.  For
+// variables assigned to a variable in an outer scope or used as a
+// return value, they store a flow(theSink, src) edge to a fake node
+// 'the Sink'.  For variables referenced in closures, an edge
+// flow(closure, &var) is recorded and the flow of a closure itself to
+// an outer scope is tracked the same way as other variables.
+//
+// Then escflood walks the graph starting at theSink and tags all
+// variables of it can reach an & node as escaping and all function
+// parameters it can reach as leaking.
+//
+// If a value's address is taken but the address does not escape,
+// then the value can stay on the stack.  If the value new(T) does
+// not escape, then new(T) can be rewritten into a stack allocation.
+// The same is true of slice literals.
+//
+// If optimizations are disabled (-N), this code is not used.
+// Instead, the compiler assumes that any value whose address
+// is taken without being immediately dereferenced
+// needs to be moved to the heap, and new(T) and slice
+// literals are always real allocations.
+
+typedef struct EscState EscState;
+
+static void escfunc(EscState*, Node *func);
+static void esclist(EscState*, NodeList *l, Node *up);
+static void esc(EscState*, Node *n, Node *up);
+static void escloopdepthlist(EscState*, NodeList *l);
+static void escloopdepth(EscState*, Node *n);
+static void escassign(EscState*, Node *dst, Node *src);
+static void esccall(EscState*, Node*, Node *up);
+static void escflows(EscState*, Node *dst, Node *src);
+static void escflood(EscState*, Node *dst);
+static void escwalk(EscState*, int level, Node *dst, Node *src);
+static void esctag(EscState*, Node *func);
+
+struct EscState {
+	// Fake node that all
+	//   - return values and output variables
+	//   - parameters on imported functions not marked 'safe'
+	//   - assignments to global variables
+	// flow to.
+	Node	theSink;
+	
+	// If an analyzed function is recorded to return
+	// pieces obtained via indirection from a parameter,
+	// and later there is a call f(x) to that function,
+	// we create a link funcParam <- x to record that fact.
+	// The funcParam node is handled specially in escflood.
+	Node	funcParam;	
+	
+	NodeList*	dsts;		// all dst nodes
+	int	loopdepth;	// for detecting nested loop scopes
+	int	pdepth;		// for debug printing in recursions.
+	int	dstcount, edgecount;	// diagnostic
+	NodeList*	noesc;	// list of possible non-escaping nodes, for printing
+	int	recursive;	// recursive function or group of mutually recursive functions.
+};
+
+static Strlit *tags[16];
+
+static Strlit*
+mktag(int mask)
+{
+	Strlit *s;
+	char buf[40];
+
+	switch(mask&EscMask) {
+	case EscNone:
+	case EscReturn:
+		break;
+	default:
+		fatal("escape mktag");
+	}
+
+	mask >>= EscBits;
+
+	if(mask < nelem(tags) && tags[mask] != nil)
+		return tags[mask];
+
+	snprint(buf, sizeof buf, "esc:0x%x", mask);
+	s = strlit(buf);
+	if(mask < nelem(tags))
+		tags[mask] = s;
+	return s;
+}
+
+static int
+parsetag(Strlit *note)
+{
+	int em;
+
+	if(note == nil)
+		return EscUnknown;
+	if(strncmp(note->s, "esc:", 4) != 0)
+		return EscUnknown;
+	em = atoi(note->s + 4);
+	if (em == 0)
+		return EscNone;
+	return EscReturn | (em << EscBits);
+}
+
+static void
+analyze(NodeList *all, int recursive)
+{
+	NodeList *l;
+	EscState es, *e;
+	
+	memset(&es, 0, sizeof es);
+	e = &es;
+	e->theSink.op = ONAME;
+	e->theSink.orig = &e->theSink;
+	e->theSink.class = PEXTERN;
+	e->theSink.sym = lookup(".sink");
+	e->theSink.escloopdepth = -1;
+	e->recursive = recursive;
+	
+	e->funcParam.op = ONAME;
+	e->funcParam.orig = &e->funcParam;
+	e->funcParam.class = PAUTO;
+	e->funcParam.sym = lookup(".param");
+	e->funcParam.escloopdepth = 10000000;
+	
+	for(l=all; l; l=l->next)
+		if(l->n->op == ODCLFUNC)
+			l->n->esc = EscFuncPlanned;
+
+	// flow-analyze functions
+	for(l=all; l; l=l->next)
+		if(l->n->op == ODCLFUNC)
+			escfunc(e, l->n);
+
+	// print("escapes: %d e->dsts, %d edges\n", e->dstcount, e->edgecount);
+
+	// visit the upstream of each dst, mark address nodes with
+	// addrescapes, mark parameters unsafe
+	for(l = e->dsts; l; l=l->next)
+		escflood(e, l->n);
+
+	// for all top level functions, tag the typenodes corresponding to the param nodes
+	for(l=all; l; l=l->next)
+		if(l->n->op == ODCLFUNC)
+			esctag(e, l->n);
+
+	if(debug['m']) {
+		for(l=e->noesc; l; l=l->next)
+			if(l->n->esc == EscNone)
+				warnl(l->n->lineno, "%S %hN does not escape",
+					(l->n->curfn && l->n->curfn->nname) ? l->n->curfn->nname->sym : S,
+					l->n);
+	}
+}
+
+
+static void
+escfunc(EscState *e, Node *func)
+{
+	Node *savefn;
+	NodeList *ll;
+	int saveld;
+
+//	print("escfunc %N %s\n", func->nname, e->recursive?"(recursive)":"");
+
+	if(func->esc != 1)
+		fatal("repeat escfunc %N", func->nname);
+	func->esc = EscFuncStarted;
+
+	saveld = e->loopdepth;
+	e->loopdepth = 1;
+	savefn = curfn;
+	curfn = func;
+
+	for(ll=curfn->dcl; ll; ll=ll->next) {
+		if(ll->n->op != ONAME)
+			continue;
+		switch (ll->n->class) {
+		case PPARAMOUT:
+			// out params are in a loopdepth between the sink and all local variables
+			ll->n->escloopdepth = 0;
+			break;
+		case PPARAM:
+			ll->n->escloopdepth = 1; 
+			if(ll->n->type && !haspointers(ll->n->type))
+				break;
+			if(curfn->nbody == nil && !curfn->noescape)
+				ll->n->esc = EscHeap;
+			else
+				ll->n->esc = EscNone;	// prime for escflood later
+			e->noesc = list(e->noesc, ll->n);
+			break;
+		}
+	}
+
+	// in a mutually recursive group we lose track of the return values
+	if(e->recursive)
+		for(ll=curfn->dcl; ll; ll=ll->next)
+			if(ll->n->op == ONAME && ll->n->class == PPARAMOUT)
+				escflows(e, &e->theSink, ll->n);
+
+	escloopdepthlist(e, curfn->nbody);
+	esclist(e, curfn->nbody, curfn);
+	curfn = savefn;
+	e->loopdepth = saveld;
+}
+
+// Mark labels that have no backjumps to them as not increasing e->loopdepth.
+// Walk hasn't generated (goto|label)->left->sym->label yet, so we'll cheat
+// and set it to one of the following two.  Then in esc we'll clear it again.
+static Label looping;
+static Label nonlooping;
+
+static void
+escloopdepthlist(EscState *e, NodeList *l)
+{
+	for(; l; l=l->next)
+		escloopdepth(e, l->n);
+}
+
+static void
+escloopdepth(EscState *e, Node *n)
+{
+	if(n == N)
+		return;
+
+	escloopdepthlist(e, n->ninit);
+
+	switch(n->op) {
+	case OLABEL:
+		if(!n->left || !n->left->sym)
+			fatal("esc:label without label: %+N", n);
+		// Walk will complain about this label being already defined, but that's not until
+		// after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
+		// if(n->left->sym->label != nil)
+		//	fatal("escape analysis messed up analyzing label: %+N", n);
+		n->left->sym->label = &nonlooping;
+		break;
+	case OGOTO:
+		if(!n->left || !n->left->sym)
+			fatal("esc:goto without label: %+N", n);
+		// If we come past one that's uninitialized, this must be a (harmless) forward jump
+		// but if it's set to nonlooping the label must have preceded this goto.
+		if(n->left->sym->label == &nonlooping)
+			n->left->sym->label = &looping;
+		break;
+	}
+
+	escloopdepth(e, n->left);
+	escloopdepth(e, n->right);
+	escloopdepthlist(e, n->list);
+	escloopdepth(e, n->ntest);
+	escloopdepth(e, n->nincr);
+	escloopdepthlist(e, n->nbody);
+	escloopdepthlist(e, n->nelse);
+	escloopdepthlist(e, n->rlist);
+
+}
+
+static void
+esclist(EscState *e, NodeList *l, Node *up)
+{
+	for(; l; l=l->next)
+		esc(e, l->n, up);
+}
+
+static void
+esc(EscState *e, Node *n, Node *up)
+{
+	int lno;
+	NodeList *ll, *lr;
+	Node *a;
+
+	if(n == N)
+		return;
+
+	lno = setlineno(n);
+
+	// ninit logically runs at a different loopdepth than the rest of the for loop.
+	esclist(e, n->ninit, n);
+
+	if(n->op == OFOR || n->op == ORANGE)
+		e->loopdepth++;
+
+	// type switch variables have no ODCL.
+	// process type switch as declaration.
+	// must happen before processing of switch body,
+	// so before recursion.
+	if(n->op == OSWITCH && n->ntest && n->ntest->op == OTYPESW) {
+		for(ll=n->list; ll; ll=ll->next) {  // cases
+			// ll->n->nname is the variable per case
+			if(ll->n->nname)
+				ll->n->nname->escloopdepth = e->loopdepth;
+		}
+	}
+
+	esc(e, n->left, n);
+	esc(e, n->right, n);
+	esc(e, n->ntest, n);
+	esc(e, n->nincr, n);
+	esclist(e, n->nbody, n);
+	esclist(e, n->nelse, n);
+	esclist(e, n->list, n);
+	esclist(e, n->rlist, n);
+
+	if(n->op == OFOR || n->op == ORANGE)
+		e->loopdepth--;
+
+	if(debug['m'] > 1)
+		print("%L:[%d] %S esc: %N\n", lineno, e->loopdepth,
+		      (curfn && curfn->nname) ? curfn->nname->sym : S, n);
+
+	switch(n->op) {
+	case ODCL:
+		// Record loop depth at declaration.
+		if(n->left)
+			n->left->escloopdepth = e->loopdepth;
+		break;
+
+	case OLABEL:
+		if(n->left->sym->label == &nonlooping) {
+			if(debug['m'] > 1)
+				print("%L:%N non-looping label\n", lineno, n);
+		} else if(n->left->sym->label == &looping) {
+			if(debug['m'] > 1)
+				print("%L: %N looping label\n", lineno, n);
+			e->loopdepth++;
+		}
+		// See case OLABEL in escloopdepth above
+		// else if(n->left->sym->label == nil)
+		//	fatal("escape analysis missed or messed up a label: %+N", n);
+
+		n->left->sym->label = nil;
+		break;
+
+	case ORANGE:
+		// Everything but fixed array is a dereference.
+		if(isfixedarray(n->type) && n->list && n->list->next)
+			escassign(e, n->list->next->n, n->right);
+		break;
+
+	case OSWITCH:
+		if(n->ntest && n->ntest->op == OTYPESW) {
+			for(ll=n->list; ll; ll=ll->next) {  // cases
+				// ntest->right is the argument of the .(type),
+				// ll->n->nname is the variable per case
+				escassign(e, ll->n->nname, n->ntest->right);
+			}
+		}
+		break;
+
+	case OAS:
+	case OASOP:
+		escassign(e, n->left, n->right);
+		break;
+
+	case OAS2:	// x,y = a,b
+		if(count(n->list) == count(n->rlist))
+			for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next)
+				escassign(e, ll->n, lr->n);
+		break;
+
+	case OAS2RECV:		// v, ok = <-ch
+	case OAS2MAPR:		// v, ok = m[k]
+	case OAS2DOTTYPE:	// v, ok = x.(type)
+		escassign(e, n->list->n, n->rlist->n);
+		break;
+
+	case OSEND:		// ch <- x
+		escassign(e, &e->theSink, n->right);
+		break;
+
+	case ODEFER:
+		if(e->loopdepth == 1)  // top level
+			break;
+		// arguments leak out of scope
+		// TODO: leak to a dummy node instead
+		// fallthrough
+	case OPROC:
+		// go f(x) - f and x escape
+		escassign(e, &e->theSink, n->left->left);
+		escassign(e, &e->theSink, n->left->right);  // ODDDARG for call
+		for(ll=n->left->list; ll; ll=ll->next)
+			escassign(e, &e->theSink, ll->n);
+		break;
+
+	case OCALLMETH:
+	case OCALLFUNC:
+	case OCALLINTER:
+		esccall(e, n, up);
+		break;
+
+	case OAS2FUNC:	// x,y = f()
+		// esccall already done on n->rlist->n. tie it's escretval to n->list
+		lr=n->rlist->n->escretval;
+		for(ll=n->list; lr && ll; lr=lr->next, ll=ll->next)
+			escassign(e, ll->n, lr->n);
+		if(lr || ll)
+			fatal("esc oas2func");
+		break;
+
+	case ORETURN:
+		ll=n->list;
+		if(count(n->list) == 1 && curfn->type->outtuple > 1) {
+			// OAS2FUNC in disguise
+			// esccall already done on n->list->n
+			// tie n->list->n->escretval to curfn->dcl PPARAMOUT's
+			ll = n->list->n->escretval;
+		}
+
+		for(lr = curfn->dcl; lr && ll; lr=lr->next) {
+			if (lr->n->op != ONAME || lr->n->class != PPARAMOUT)
+				continue;
+			escassign(e, lr->n, ll->n);
+			ll = ll->next;
+		}
+		if (ll != nil)
+			fatal("esc return list");
+		break;
+
+	case OPANIC:
+		// Argument could leak through recover.
+		escassign(e, &e->theSink, n->left);
+		break;
+
+	case OAPPEND:
+		if(!n->isddd)
+			for(ll=n->list->next; ll; ll=ll->next)
+				escassign(e, &e->theSink, ll->n);  // lose track of assign to dereference
+		break;
+
+	case OCONV:
+	case OCONVNOP:
+	case OCONVIFACE:
+		escassign(e, n, n->left);
+		break;
+
+	case OARRAYLIT:
+		if(isslice(n->type)) {
+			n->esc = EscNone;  // until proven otherwise
+			e->noesc = list(e->noesc, n);
+			n->escloopdepth = e->loopdepth;
+			// Values make it to memory, lose track.
+			for(ll=n->list; ll; ll=ll->next)
+				escassign(e, &e->theSink, ll->n->right);
+		} else {
+			// Link values to array.
+			for(ll=n->list; ll; ll=ll->next)
+				escassign(e, n, ll->n->right);
+		}
+		break;
+
+	case OSTRUCTLIT:
+		// Link values to struct.
+		for(ll=n->list; ll; ll=ll->next)
+			escassign(e, n, ll->n->right);
+		break;
+	
+	case OPTRLIT:
+		n->esc = EscNone;  // until proven otherwise
+		e->noesc = list(e->noesc, n);
+		n->escloopdepth = e->loopdepth;
+		// Contents make it to memory, lose track.
+		escassign(e, &e->theSink, n->left);
+		break;
+	
+	case OCALLPART:
+		n->esc = EscNone; // until proven otherwise
+		e->noesc = list(e->noesc, n);
+		n->escloopdepth = e->loopdepth;
+		// Contents make it to memory, lose track.
+		escassign(e, &e->theSink, n->left);
+		break;
+
+	case OMAPLIT:
+		n->esc = EscNone;  // until proven otherwise
+		e->noesc = list(e->noesc, n);
+		n->escloopdepth = e->loopdepth;
+		// Keys and values make it to memory, lose track.
+		for(ll=n->list; ll; ll=ll->next) {
+			escassign(e, &e->theSink, ll->n->left);
+			escassign(e, &e->theSink, ll->n->right);
+		}
+		break;
+	
+	case OCLOSURE:
+		// Link addresses of captured variables to closure.
+		for(ll=n->cvars; ll; ll=ll->next) {
+			if(ll->n->op == OXXX)  // unnamed out argument; see dcl.c:/^funcargs
+				continue;
+			a = nod(OADDR, ll->n->closure, N);
+			a->lineno = ll->n->lineno;
+			a->escloopdepth = e->loopdepth;
+			typecheck(&a, Erv);
+			escassign(e, n, a);
+		}
+		// fallthrough
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case ONEW:
+		n->escloopdepth = e->loopdepth;
+		n->esc = EscNone;  // until proven otherwise
+		e->noesc = list(e->noesc, n);
+		break;
+
+	case OADDR:
+		n->esc = EscNone;  // until proven otherwise
+		e->noesc = list(e->noesc, n);
+		// current loop depth is an upper bound on actual loop depth
+		// of addressed value.
+		n->escloopdepth = e->loopdepth;
+		// for &x, use loop depth of x if known.
+		// it should always be known, but if not, be conservative
+		// and keep the current loop depth.
+		if(n->left->op == ONAME) {
+			switch(n->left->class) {
+			case PAUTO:
+				if(n->left->escloopdepth != 0)
+					n->escloopdepth = n->left->escloopdepth;
+				break;
+			case PPARAM:
+			case PPARAMOUT:
+				// PPARAM is loop depth 1 always.
+				// PPARAMOUT is loop depth 0 for writes
+				// but considered loop depth 1 for address-of,
+				// so that writing the address of one result
+				// to another (or the same) result makes the
+				// first result move to the heap.
+				n->escloopdepth = 1;
+				break;
+			}
+		}
+		break;
+	}
+
+	lineno = lno;
+}
+
+// Assert that expr somehow gets assigned to dst, if non nil.  for
+// dst==nil, any name node expr still must be marked as being
+// evaluated in curfn.	For expr==nil, dst must still be examined for
+// evaluations inside it (e.g *f(x) = y)
+static void
+escassign(EscState *e, Node *dst, Node *src)
+{
+	int lno;
+	NodeList *ll;
+
+	if(isblank(dst) || dst == N || src == N || src->op == ONONAME || src->op == OXXX)
+		return;
+
+	if(debug['m'] > 1)
+		print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, e->loopdepth,
+		      (curfn && curfn->nname) ? curfn->nname->sym : S, dst, dst, src, src);
+
+	setlineno(dst);
+	
+	// Analyze lhs of assignment.
+	// Replace dst with e->theSink if we can't track it.
+	switch(dst->op) {
+	default:
+		dump("dst", dst);
+		fatal("escassign: unexpected dst");
+
+	case OARRAYLIT:
+	case OCLOSURE:
+	case OCONV:
+	case OCONVIFACE:
+	case OCONVNOP:
+	case OMAPLIT:
+	case OSTRUCTLIT:
+	case OCALLPART:
+		break;
+
+	case ONAME:
+		if(dst->class == PEXTERN)
+			dst = &e->theSink;
+		break;
+	case ODOT:	      // treat "dst.x  = src" as "dst = src"
+		escassign(e, dst->left, src);
+		return;
+	case OINDEX:
+		if(isfixedarray(dst->left->type)) {
+			escassign(e, dst->left, src);
+			return;
+		}
+		dst = &e->theSink;  // lose track of dereference
+		break;
+	case OIND:
+	case ODOTPTR:
+		dst = &e->theSink;  // lose track of dereference
+		break;
+	case OINDEXMAP:
+		// lose track of key and value
+		escassign(e, &e->theSink, dst->right);
+		dst = &e->theSink;
+		break;
+	}
+
+	lno = setlineno(src);
+	e->pdepth++;
+
+	switch(src->op) {
+	case OADDR:	// dst = &x
+	case OIND:	// dst = *x
+	case ODOTPTR:	// dst = (*x).f
+	case ONAME:
+	case OPARAM:
+	case ODDDARG:
+	case OPTRLIT:
+	case OARRAYLIT:
+	case OMAPLIT:
+	case OSTRUCTLIT:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case ONEW:
+	case OCLOSURE:
+	case OCALLPART:
+		escflows(e, dst, src);
+		break;
+
+	case OCALLMETH:
+	case OCALLFUNC:
+	case OCALLINTER:
+		// Flowing multiple returns to a single dst happens when
+		// analyzing "go f(g())": here g() flows to sink (issue 4529).
+		for(ll=src->escretval; ll; ll=ll->next)
+			escflows(e, dst, ll->n);
+		break;
+
+	case ODOT:
+		// A non-pointer escaping from a struct does not concern us.
+		if(src->type && !haspointers(src->type))
+			break;
+		// fallthrough
+	case OCONV:
+	case OCONVIFACE:
+	case OCONVNOP:
+	case ODOTMETH:	// treat recv.meth as a value with recv in it, only happens in ODEFER and OPROC
+			// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
+	case ODOTTYPE:
+	case ODOTTYPE2:
+	case OSLICE:
+	case OSLICE3:
+	case OSLICEARR:
+	case OSLICE3ARR:
+		// Conversions, field access, slice all preserve the input value.
+		escassign(e, dst, src->left);
+		break;
+
+	case OAPPEND:
+		// Append returns first argument.
+		escassign(e, dst, src->list->n);
+		break;
+	
+	case OINDEX:
+		// Index of array preserves input value.
+		if(isfixedarray(src->left->type))
+			escassign(e, dst, src->left);
+		break;
+
+	case OADD:
+	case OSUB:
+	case OOR:
+	case OXOR:
+	case OMUL:
+	case ODIV:
+	case OMOD:
+	case OLSH:
+	case ORSH:
+	case OAND:
+	case OANDNOT:
+	case OPLUS:
+	case OMINUS:
+	case OCOM:
+		// Might be pointer arithmetic, in which case
+		// the operands flow into the result.
+		// TODO(rsc): Decide what the story is here.  This is unsettling.
+		escassign(e, dst, src->left);
+		escassign(e, dst, src->right);
+		break;
+	}
+
+	e->pdepth--;
+	lineno = lno;
+}
+
+static int
+escassignfromtag(EscState *e, Strlit *note, NodeList *dsts, Node *src)
+{
+	int em, em0;
+	
+	em = parsetag(note);
+
+	if(em == EscUnknown) {
+		escassign(e, &e->theSink, src);
+		return em;
+	}
+
+	if(em == EscNone)
+		return em;
+	
+	// If content inside parameter (reached via indirection)
+	// escapes back to results, mark as such.
+	if(em & EscContentEscapes)
+		escassign(e, &e->funcParam, src);
+
+	em0 = em;
+	for(em >>= EscReturnBits; em && dsts; em >>= 1, dsts=dsts->next)
+		if(em & 1)
+			escassign(e, dsts->n, src);
+
+	if (em != 0 && dsts == nil)
+		fatal("corrupt esc tag %Z or messed up escretval list\n", note);
+	return em0;
+}
+
+// This is a bit messier than fortunate, pulled out of esc's big
+// switch for clarity.	We either have the paramnodes, which may be
+// connected to other things through flows or we have the parameter type
+// nodes, which may be marked "noescape". Navigating the ast is slightly
+// different for methods vs plain functions and for imported vs
+// this-package
+static void
+esccall(EscState *e, Node *n, Node *up)
+{
+	NodeList *ll, *lr;
+	Node *a, *fn, *src;
+	Type *t, *fntype;
+	char buf[40];
+	int i;
+
+	fn = N;
+	switch(n->op) {
+	default:
+		fatal("esccall");
+
+	case OCALLFUNC:
+		fn = n->left;
+		fntype = fn->type;
+		break;
+
+	case OCALLMETH:
+		fn = n->left->right->sym->def;
+		if(fn)
+			fntype = fn->type;
+		else
+			fntype = n->left->type;
+		break;
+
+	case OCALLINTER:
+		fntype = n->left->type;
+		break;
+	}
+
+	ll = n->list;
+	if(n->list != nil && n->list->next == nil) {
+		a = n->list->n;
+		if(a->type->etype == TSTRUCT && a->type->funarg) // f(g()).
+			ll = a->escretval;
+	}
+
+	if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype && fn->defn->esc < EscFuncTagged) {
+		// function in same mutually recursive group.  Incorporate into flow graph.
+//		print("esc local fn: %N\n", fn->ntype);
+		if(fn->defn->esc == EscFuncUnknown || n->escretval != nil)
+			fatal("graph inconsistency");
+
+		// set up out list on this call node
+		for(lr=fn->ntype->rlist; lr; lr=lr->next)
+			n->escretval = list(n->escretval, lr->n->left);  // type.rlist ->  dclfield -> ONAME (PPARAMOUT)
+
+		// Receiver.
+		if(n->op != OCALLFUNC)
+			escassign(e, fn->ntype->left->left, n->left->left);
+
+		for(lr=fn->ntype->list; ll && lr; ll=ll->next, lr=lr->next) {
+			src = ll->n;
+			if(lr->n->isddd && !n->isddd) {
+				// Introduce ODDDARG node to represent ... allocation.
+				src = nod(ODDDARG, N, N);
+				src->type = typ(TARRAY);
+				src->type->type = lr->n->type->type;
+				src->type->bound = count(ll);
+				src->type = ptrto(src->type); // make pointer so it will be tracked
+				src->escloopdepth = e->loopdepth;
+				src->lineno = n->lineno;
+				src->esc = EscNone;  // until we find otherwise
+				e->noesc = list(e->noesc, src);
+				n->right = src;
+			}
+			if(lr->n->left != N)
+				escassign(e, lr->n->left, src);
+			if(src != ll->n)
+				break;
+		}
+		// "..." arguments are untracked
+		for(; ll; ll=ll->next)
+			escassign(e, &e->theSink, ll->n);
+
+		return;
+	}
+
+	// Imported or completely analyzed function.  Use the escape tags.
+	if(n->escretval != nil)
+		fatal("esc already decorated call %+N\n", n);
+
+	// set up out list on this call node with dummy auto ONAMES in the current (calling) function.
+	i = 0;
+	for(t=getoutargx(fntype)->type; t; t=t->down) {
+		src = nod(ONAME, N, N);
+		snprint(buf, sizeof buf, ".dum%d", i++);
+		src->sym = lookup(buf);
+		src->type = t->type;
+		src->class = PAUTO;
+		src->curfn = curfn;
+		src->escloopdepth = e->loopdepth;
+		src->used = 1;
+		src->lineno = n->lineno;
+		n->escretval = list(n->escretval, src); 
+	}
+
+//	print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, n->escretval);
+
+	// Receiver.
+	if(n->op != OCALLFUNC) {
+		t = getthisx(fntype)->type;
+		src = n->left->left;
+		if(haspointers(t->type))
+			escassignfromtag(e, t->note, n->escretval, src);
+	}
+	
+	for(t=getinargx(fntype)->type; ll; ll=ll->next) {
+		src = ll->n;
+		if(t->isddd && !n->isddd) {
+			// Introduce ODDDARG node to represent ... allocation.
+			src = nod(ODDDARG, N, N);
+			src->escloopdepth = e->loopdepth;
+			src->lineno = n->lineno;
+			src->type = typ(TARRAY);
+			src->type->type = t->type->type;
+			src->type->bound = count(ll);
+			src->type = ptrto(src->type); // make pointer so it will be tracked
+			src->esc = EscNone;  // until we find otherwise
+			e->noesc = list(e->noesc, src);
+			n->right = src;
+		}
+		if(haspointers(t->type)) {
+			if(escassignfromtag(e, t->note, n->escretval, src) == EscNone && up->op != ODEFER && up->op != OPROC) {
+				a = src;
+				while(a->op == OCONVNOP)
+					a = a->left;
+				switch(a->op) {
+				case OCALLPART:
+				case OCLOSURE:
+				case ODDDARG:
+				case OARRAYLIT:
+				case OPTRLIT:
+				case OSTRUCTLIT:
+					// The callee has already been analyzed, so its arguments have esc tags.
+					// The argument is marked as not escaping at all.
+					// Record that fact so that any temporary used for
+					// synthesizing this expression can be reclaimed when
+					// the function returns.
+					// This 'noescape' is even stronger than the usual esc == EscNone.
+					// src->esc == EscNone means that src does not escape the current function.
+					// src->noescape = 1 here means that src does not escape this statement
+					// in the current function.
+					a->noescape = 1;
+					break;
+				}
+			}
+		}
+		if(src != ll->n)
+			break;
+		t = t->down;
+	}
+	// "..." arguments are untracked
+	for(; ll; ll=ll->next)
+		escassign(e, &e->theSink, ll->n);
+}
+
+// Store the link src->dst in dst, throwing out some quick wins.
+static void
+escflows(EscState *e, Node *dst, Node *src)
+{
+	if(dst == nil || src == nil || dst == src)
+		return;
+
+	// Don't bother building a graph for scalars.
+	if(src->type && !haspointers(src->type))
+		return;
+
+	if(debug['m']>2)
+		print("%L::flows:: %hN <- %hN\n", lineno, dst, src);
+
+	if(dst->escflowsrc == nil) {
+		e->dsts = list(e->dsts, dst);
+		e->dstcount++;
+	}
+	e->edgecount++;
+
+	dst->escflowsrc = list(dst->escflowsrc, src);
+}
+
+// Whenever we hit a reference node, the level goes up by one, and whenever
+// we hit an OADDR, the level goes down by one. as long as we're on a level > 0
+// finding an OADDR just means we're following the upstream of a dereference,
+// so this address doesn't leak (yet).
+// If level == 0, it means the /value/ of this node can reach the root of this flood.
+// so if this node is an OADDR, it's argument should be marked as escaping iff
+// it's currfn/e->loopdepth are different from the flood's root.
+// Once an object has been moved to the heap, all of it's upstream should be considered
+// escaping to the global scope.
+static void
+escflood(EscState *e, Node *dst)
+{
+	NodeList *l;
+
+	switch(dst->op) {
+	case ONAME:
+	case OCLOSURE:
+		break;
+	default:
+		return;
+	}
+
+	if(debug['m']>1)
+		print("\nescflood:%d: dst %hN scope:%S[%d]\n", walkgen, dst,
+		      (dst->curfn && dst->curfn->nname) ? dst->curfn->nname->sym : S,
+		      dst->escloopdepth);
+
+	for(l = dst->escflowsrc; l; l=l->next) {
+		walkgen++;
+		escwalk(e, 0, dst, l->n);
+	}
+}
+
+// There appear to be some loops in the escape graph, causing
+// arbitrary recursion into deeper and deeper levels.
+// Cut this off safely by making minLevel sticky: once you
+// get that deep, you cannot go down any further but you also
+// cannot go up any further. This is a conservative fix.
+// Making minLevel smaller (more negative) would handle more
+// complex chains of indirections followed by address-of operations,
+// at the cost of repeating the traversal once for each additional
+// allowed level when a loop is encountered. Using -2 suffices to
+// pass all the tests we have written so far, which we assume matches
+// the level of complexity we want the escape analysis code to handle.
+#define MinLevel (-2)
+/*c2go enum { MinLevel = -2 };*/
+
+static void
+escwalk(EscState *e, int level, Node *dst, Node *src)
+{
+	NodeList *ll;
+	int leaks, newlevel;
+
+	if(src->walkgen == walkgen && src->esclevel <= level)
+		return;
+	src->walkgen = walkgen;
+	src->esclevel = level;
+
+	if(debug['m']>1)
+		print("escwalk: level:%d depth:%d %.*s %hN(%hJ) scope:%S[%d]\n",
+		      level, e->pdepth, e->pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src,
+		      (src->curfn && src->curfn->nname) ? src->curfn->nname->sym : S, src->escloopdepth);
+
+	e->pdepth++;
+
+	// Input parameter flowing to output parameter?
+	if(dst->op == ONAME && dst->class == PPARAMOUT && dst->vargen <= 20) {
+		if(src->op == ONAME && src->class == PPARAM && src->curfn == dst->curfn && src->esc != EscScope && src->esc != EscHeap) {
+			if(level == 0) {
+				if(debug['m'])
+					warnl(src->lineno, "leaking param: %hN to result %S", src, dst->sym);
+				if((src->esc&EscMask) != EscReturn)
+					src->esc = EscReturn;
+				src->esc |= 1<<((dst->vargen-1) + EscReturnBits);
+				goto recurse;
+			} else if(level > 0) {
+				if(debug['m'])
+					warnl(src->lineno, "%N leaking param %hN content to result %S", src->curfn->nname, src, dst->sym);
+				if((src->esc&EscMask) != EscReturn)
+					src->esc = EscReturn;
+				src->esc |= EscContentEscapes;
+				goto recurse;
+			}
+		}
+	}
+
+	// The second clause is for values pointed at by an object passed to a call
+	// that returns something reached via indirect from the object.
+	// We don't know which result it is or how many indirects, so we treat it as leaking.
+	leaks = level <= 0 && dst->escloopdepth < src->escloopdepth ||
+		level < 0 && dst == &e->funcParam && haspointers(src->type);
+
+	switch(src->op) {
+	case ONAME:
+		if(src->class == PPARAM && (leaks || dst->escloopdepth < 0) && src->esc != EscHeap) {
+			src->esc = EscScope;
+			if(debug['m'])
+				warnl(src->lineno, "leaking param: %hN", src);
+		}
+
+		// Treat a PPARAMREF closure variable as equivalent to the
+		// original variable.
+		if(src->class == PPARAMREF) {
+			if(leaks && debug['m'])
+				warnl(src->lineno, "leaking closure reference %hN", src);
+			escwalk(e, level, dst, src->closure);
+		}
+		break;
+
+	case OPTRLIT:
+	case OADDR:
+		if(leaks) {
+			src->esc = EscHeap;
+			addrescapes(src->left);
+			if(debug['m'])
+				warnl(src->lineno, "%hN escapes to heap", src);
+		}
+		newlevel = level;
+		if(level > MinLevel)
+			newlevel--;
+		escwalk(e, newlevel, dst, src->left);
+		break;
+
+	case OARRAYLIT:
+		if(isfixedarray(src->type))
+			break;
+		// fall through
+	case ODDDARG:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case OMAPLIT:
+	case ONEW:
+	case OCLOSURE:
+	case OCALLPART:
+		if(leaks) {
+			src->esc = EscHeap;
+			if(debug['m'])
+				warnl(src->lineno, "%hN escapes to heap", src);
+		}
+		break;
+
+	case ODOT:
+	case OSLICE:
+	case OSLICEARR:
+	case OSLICE3:
+	case OSLICE3ARR:
+		escwalk(e, level, dst, src->left);
+		break;
+
+	case OINDEX:
+		if(isfixedarray(src->left->type)) {
+			escwalk(e, level, dst, src->left);
+			break;
+		}
+		// fall through
+	case ODOTPTR:
+	case OINDEXMAP:
+	case OIND:
+		newlevel = level;
+		if(level > MinLevel)
+			newlevel++;
+		escwalk(e, newlevel, dst, src->left);
+	}
+
+recurse:
+	for(ll=src->escflowsrc; ll; ll=ll->next)
+		escwalk(e, level, dst, ll->n);
+
+	e->pdepth--;
+}
+
+static void
+esctag(EscState *e, Node *func)
+{
+	Node *savefn;
+	NodeList *ll;
+	Type *t;
+
+	USED(e);
+	func->esc = EscFuncTagged;
+	
+	// External functions are assumed unsafe,
+	// unless //go:noescape is given before the declaration.
+	if(func->nbody == nil) {
+		if(func->noescape) {
+			for(t=getinargx(func->type)->type; t; t=t->down)
+				if(haspointers(t->type))
+					t->note = mktag(EscNone);
+		}
+		return;
+	}
+
+	savefn = curfn;
+	curfn = func;
+
+	for(ll=curfn->dcl; ll; ll=ll->next) {
+		if(ll->n->op != ONAME || ll->n->class != PPARAM)
+			continue;
+
+		switch (ll->n->esc&EscMask) {
+		case EscNone:	// not touched by escflood
+		case EscReturn:	
+			if(haspointers(ll->n->type)) // don't bother tagging for scalars
+				ll->n->paramfld->note = mktag(ll->n->esc);
+			break;
+		case EscHeap:	// touched by escflood, moved to heap
+		case EscScope:	// touched by escflood, value leaves scope
+			break;
+		}
+	}
+
+	curfn = savefn;
+}
diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c
new file mode 100644
index 0000000..da5984c
--- /dev/null
+++ b/src/cmd/gc/export.c
@@ -0,0 +1,521 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"y.tab.h"
+
+static void	dumpexporttype(Type *t);
+
+// Mark n's symbol as exported
+void
+exportsym(Node *n)
+{
+	if(n == N || n->sym == S)
+		return;
+	if(n->sym->flags & (SymExport|SymPackage)) {
+		if(n->sym->flags & SymPackage)
+			yyerror("export/package mismatch: %S", n->sym);
+		return;
+	}
+	n->sym->flags |= SymExport;
+
+	if(debug['E'])
+		print("export symbol %S\n", n->sym);
+	exportlist = list(exportlist, n);
+}
+
+int
+exportname(char *s)
+{
+	Rune r;
+
+	if((uchar)s[0] < Runeself)
+		return 'A' <= s[0] && s[0] <= 'Z';
+	chartorune(&r, s);
+	return isupperrune(r);
+}
+
+static int
+initname(char *s)
+{
+	return strcmp(s, "init") == 0;
+}
+
+// exportedsym reports whether a symbol will be visible
+// to files that import our package.
+static int
+exportedsym(Sym *sym)
+{
+	// Builtins are visible everywhere.
+	if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg)
+		return 1;
+
+	return sym->pkg == localpkg && exportname(sym->name);
+}
+
+void
+autoexport(Node *n, int ctxt)
+{
+	if(n == N || n->sym == S)
+		return;
+	if((ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN)
+		return;
+	if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left)	// method
+		return;
+	// -A is for cmd/gc/mkbuiltin script, so export everything
+	if(debug['A'] || exportname(n->sym->name) || initname(n->sym->name))
+		exportsym(n);
+}
+
+static void
+dumppkg(Pkg *p)
+{
+	char *suffix;
+
+	if(p == nil || p == localpkg || p->exported || p == builtinpkg)
+		return;
+	p->exported = 1;
+	suffix = "";
+	if(!p->direct)
+		suffix = " // indirect";
+	Bprint(bout, "\timport %s \"%Z\"%s\n", p->name, p->path, suffix);
+}
+
+// Look for anything we need for the inline body
+static void reexportdep(Node *n);
+static void
+reexportdeplist(NodeList *ll)
+{
+	for(; ll ;ll=ll->next)
+		reexportdep(ll->n);
+}
+
+static void
+reexportdep(Node *n)
+{
+	Type *t;
+
+	if(!n)
+		return;
+
+	//print("reexportdep %+hN\n", n);
+	switch(n->op) {
+	case ONAME:
+		switch(n->class&~PHEAP) {
+		case PFUNC:
+			// methods will be printed along with their type
+			// nodes for T.Method expressions
+			if(n->left && n->left->op == OTYPE)
+				break;
+			// nodes for method calls.
+			if(!n->type || n->type->thistuple > 0)
+				break;
+			// fallthrough
+		case PEXTERN:
+			if(n->sym && !exportedsym(n->sym)) {
+				if(debug['E'])
+					print("reexport name %S\n", n->sym);
+				exportlist = list(exportlist, n);
+			}
+		}
+		break;
+
+	case ODCL:
+		// Local variables in the bodies need their type.
+		t = n->left->type;
+		if(t != types[t->etype] && t != idealbool && t != idealstring) {
+			if(isptr[t->etype])
+				t = t->type;
+			if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+				if(debug['E'])
+					print("reexport type %S from declaration\n", t->sym);
+				exportlist = list(exportlist, t->sym->def);
+			}
+		}
+		break;
+
+	case OLITERAL:
+		t = n->type;
+		if(t != types[n->type->etype] && t != idealbool && t != idealstring) {
+			if(isptr[t->etype])
+				t = t->type;
+			if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+				if(debug['E'])
+					print("reexport literal type %S\n", t->sym);
+				exportlist = list(exportlist, t->sym->def);
+			}
+		}
+		// fallthrough
+	case OTYPE:
+		if(n->sym && !exportedsym(n->sym)) {
+			if(debug['E'])
+				print("reexport literal/type %S\n", n->sym);
+			exportlist = list(exportlist, n);
+		}
+		break;
+
+	// for operations that need a type when rendered, put the type on the export list.
+	case OCONV:
+	case OCONVIFACE:
+	case OCONVNOP:
+	case ORUNESTR:
+	case OARRAYBYTESTR:
+	case OARRAYRUNESTR:
+	case OSTRARRAYBYTE:
+	case OSTRARRAYRUNE:
+	case ODOTTYPE:
+	case ODOTTYPE2:
+	case OSTRUCTLIT:
+	case OARRAYLIT:
+	case OPTRLIT:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case OMAKECHAN:
+		t = n->type;
+		if(!t->sym && t->type)
+			t = t->type;
+		if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+			if(debug['E'])
+				print("reexport type for expression %S\n", t->sym);
+			exportlist = list(exportlist, t->sym->def);
+		}
+		break;
+	}
+
+	reexportdep(n->left);
+	reexportdep(n->right);
+	reexportdeplist(n->list);
+	reexportdeplist(n->rlist);
+	reexportdeplist(n->ninit);
+	reexportdep(n->ntest);
+	reexportdep(n->nincr);
+	reexportdeplist(n->nbody);
+	reexportdeplist(n->nelse);
+}
+
+
+static void
+dumpexportconst(Sym *s)
+{
+	Node *n;
+	Type *t;
+
+	n = s->def;
+	typecheck(&n, Erv);
+	if(n == N || n->op != OLITERAL)
+		fatal("dumpexportconst: oconst nil: %S", s);
+
+	t = n->type;	// may or may not be specified
+	dumpexporttype(t);
+
+	if(t != T && !isideal(t))
+		Bprint(bout, "\tconst %#S %#T = %#V\n", s, t, &n->val);
+	else
+		Bprint(bout, "\tconst %#S = %#V\n", s, &n->val);
+}
+
+static void
+dumpexportvar(Sym *s)
+{
+	Node *n;
+	Type *t;
+
+	n = s->def;
+	typecheck(&n, Erv|Ecall);
+	if(n == N || n->type == T) {
+		yyerror("variable exported but not defined: %S", s);
+		return;
+	}
+
+	t = n->type;
+	dumpexporttype(t);
+
+	if(t->etype == TFUNC && n->class == PFUNC) {
+		if (n->inl) {
+			// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
+			// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
+			if(debug['l'] < 2)
+				typecheckinl(n);
+			// NOTE: The space after %#S here is necessary for ld's export data parser.
+			Bprint(bout, "\tfunc %#S %#hT { %#H }\n", s, t, n->inl);
+			reexportdeplist(n->inl);
+		} else
+			Bprint(bout, "\tfunc %#S %#hT\n", s, t);
+	} else
+		Bprint(bout, "\tvar %#S %#T\n", s, t);
+}
+
+static int
+methcmp(const void *va, const void *vb)
+{
+	Type *a, *b;
+	
+	a = *(Type**)va;
+	b = *(Type**)vb;
+	return strcmp(a->sym->name, b->sym->name);
+}
+
+static void
+dumpexporttype(Type *t)
+{
+	Type *f;
+	Type **m;
+	int i, n;
+
+	if(t == T)
+		return;
+	if(t->printed || t == types[t->etype] || t == bytetype || t == runetype || t == errortype)
+		return;
+	t->printed = 1;
+
+	if(t->sym != S && t->etype != TFIELD)
+		dumppkg(t->sym->pkg);
+
+	dumpexporttype(t->type);
+	dumpexporttype(t->down);
+
+	if (t->sym == S || t->etype == TFIELD)
+		return;
+
+	n = 0;
+	for(f=t->method; f!=T; f=f->down) {	
+		dumpexporttype(f);
+		n++;
+	}
+
+	m = mal(n*sizeof m[0]);
+	i = 0;
+	for(f=t->method; f!=T; f=f->down)
+		m[i++] = f;
+	qsort(m, n, sizeof m[0], methcmp);
+
+	Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
+	for(i=0; i<n; i++) {
+		f = m[i];
+		if(f->nointerface)
+			Bprint(bout, "\t//go:nointerface\n");
+		if (f->type->nname && f->type->nname->inl) { // nname was set by caninl
+			// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
+			// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
+			if(debug['l'] < 2)
+				typecheckinl(f->type->nname);
+			Bprint(bout, "\tfunc (%#T) %#hhS %#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
+			reexportdeplist(f->type->nname->inl);
+		} else
+			Bprint(bout, "\tfunc (%#T) %#hhS %#hT\n", getthisx(f->type)->type, f->sym, f->type);
+	}
+}
+
+static void
+dumpsym(Sym *s)
+{
+	if(s->flags & SymExported)
+		return;
+	s->flags |= SymExported;
+
+	if(s->def == N) {
+		yyerror("unknown export symbol: %S", s);
+		return;
+	}
+//	print("dumpsym %O %+S\n", s->def->op, s);
+	dumppkg(s->pkg);
+
+	switch(s->def->op) {
+	default:
+		yyerror("unexpected export symbol: %O %S", s->def->op, s);
+		break;
+
+	case OLITERAL:
+		dumpexportconst(s);
+		break;
+
+	case OTYPE:
+		if(s->def->type->etype == TFORW)
+			yyerror("export of incomplete type %S", s);
+		else
+			dumpexporttype(s->def->type);
+		break;
+
+	case ONAME:
+		dumpexportvar(s);
+		break;
+	}
+}
+
+void
+dumpexport(void)
+{
+	NodeList *l;
+	int32 i, lno;
+	Pkg *p;
+
+	lno = lineno;
+
+	Bprint(bout, "\n$$\npackage %s", localpkg->name);
+	if(safemode)
+		Bprint(bout, " safe");
+	Bprint(bout, "\n");
+
+	for(i=0; i<nelem(phash); i++)
+		for(p=phash[i]; p; p=p->link)
+			if(p->direct)
+				dumppkg(p);
+
+	for(l=exportlist; l; l=l->next) {
+		lineno = l->n->lineno;
+		dumpsym(l->n->sym);
+	}
+
+	Bprint(bout, "\n$$\n");
+	lineno = lno;
+}
+
+/*
+ * import
+ */
+
+/*
+ * return the sym for ss, which should match lexical
+ */
+Sym*
+importsym(Sym *s, int op)
+{
+	char *pkgstr;
+
+	if(s->def != N && s->def->op != op) {
+		pkgstr = smprint("during import \"%Z\"", importpkg->path);
+		redeclare(s, pkgstr);
+	}
+
+	// mark the symbol so it is not reexported
+	if(s->def == N) {
+		if(exportname(s->name) || initname(s->name))
+			s->flags |= SymExport;
+		else
+			s->flags |= SymPackage;	// package scope
+	}
+	return s;
+}
+
+/*
+ * return the type pkg.name, forward declaring if needed
+ */
+Type*
+pkgtype(Sym *s)
+{
+	Type *t;
+
+	importsym(s, OTYPE);
+	if(s->def == N || s->def->op != OTYPE) {
+		t = typ(TFORW);
+		t->sym = s;
+		s->def = typenod(t);
+	}
+	if(s->def->type == T)
+		yyerror("pkgtype %S", s);
+	return s->def->type;
+}
+
+void
+importimport(Sym *s, Strlit *z)
+{
+	// Informational: record package name
+	// associated with import path, for use in
+	// human-readable messages.
+	Pkg *p;
+
+	if(isbadimport(z))
+		errorexit();
+	p = mkpkg(z);
+	if(p->name == nil) {
+		p->name = s->name;
+		pkglookup(s->name, nil)->npkg++;
+	} else if(strcmp(p->name, s->name) != 0)
+		yyerror("conflicting names %s and %s for package \"%Z\"", p->name, s->name, p->path);
+	
+	if(!incannedimport && myimportpath != nil && strcmp(z->s, myimportpath) == 0) {
+		yyerror("import \"%Z\": package depends on \"%Z\" (import cycle)", importpkg->path, z);
+		errorexit();
+	}
+}
+
+void
+importconst(Sym *s, Type *t, Node *n)
+{
+	Node *n1;
+
+	importsym(s, OLITERAL);
+	convlit(&n, t);
+
+	if(s->def != N)	 // TODO: check if already the same.
+		return;
+
+	if(n->op != OLITERAL) {
+		yyerror("expression must be a constant");
+		return;
+	}
+
+	if(n->sym != S) {
+		n1 = nod(OXXX, N, N);
+		*n1 = *n;
+		n = n1;
+	}
+	n->orig = newname(s);
+	n->sym = s;
+	declare(n, PEXTERN);
+
+	if(debug['E'])
+		print("import const %S\n", s);
+}
+
+void
+importvar(Sym *s, Type *t)
+{
+	Node *n;
+
+	importsym(s, ONAME);
+	if(s->def != N && s->def->op == ONAME) {
+		if(eqtype(t, s->def->type))
+			return;
+		yyerror("inconsistent definition for var %S during import\n\t%T (in \"%Z\")\n\t%T (in \"%Z\")", s, s->def->type, s->importdef->path, t, importpkg->path);
+	}
+	n = newname(s);
+	s->importdef = importpkg;
+	n->type = t;
+	declare(n, PEXTERN);
+
+	if(debug['E'])
+		print("import var %S %lT\n", s, t);
+}
+
+void
+importtype(Type *pt, Type *t)
+{
+	Node *n;
+
+	// override declaration in unsafe.go for Pointer.
+	// there is no way in Go code to define unsafe.Pointer
+	// so we have to supply it.
+	if(incannedimport &&
+	   strcmp(importpkg->name, "unsafe") == 0 &&
+	   strcmp(pt->nod->sym->name, "Pointer") == 0) {
+		t = types[TUNSAFEPTR];
+	}
+
+	if(pt->etype == TFORW) {
+		n = pt->nod;
+		copytype(pt->nod, t);
+		pt->nod = n;		// unzero nod
+		pt->sym->importdef = importpkg;
+		pt->sym->lastlineno = parserline();
+		declare(n, PEXTERN);
+		checkwidth(pt);
+	} else if(!eqtype(pt->orig, t))
+		yyerror("inconsistent definition for type %S during import\n\t%lT (in \"%Z\")\n\t%lT (in \"%Z\")", pt->sym, pt, pt->sym->importdef->path, t, importpkg->path);
+
+	if(debug['E'])
+		print("import type %T %lT\n", pt, t);
+}
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
new file mode 100644
index 0000000..89d2a14
--- /dev/null
+++ b/src/cmd/gc/fmt.c
@@ -0,0 +1,1691 @@
+// Copyright 2011 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"opnames.h"
+
+//
+// Format conversions
+//	%L int		Line numbers
+//
+//	%E int		etype values (aka 'Kind')
+//
+//	%O int		Node Opcodes
+//		Flags: "%#O": print go syntax. (automatic unless fmtmode == FDbg)
+//
+//	%J Node*	Node details
+//		Flags: "%hJ" suppresses things not relevant until walk.
+//
+//	%V Val*		Constant values
+//
+//	%S Sym*		Symbols
+//		Flags: +,- #: mode (see below)
+//			"%hS"	unqualified identifier in any mode
+//			"%hhS"  in export mode: unqualified identifier if exported, qualified if not
+//
+//	%T Type*	Types
+//		Flags: +,- #: mode (see below)
+//			'l' definition instead of name.
+//			'h' omit "func" and receiver in function types
+//			'u' (only in -/Sym mode) print type identifiers wit package name instead of prefix.
+//
+//	%N Node*	Nodes
+//		Flags: +,- #: mode (see below)
+//			'h' (only in +/debug mode) suppress recursion
+//			'l' (only in Error mode) print "foo (type Bar)"
+//
+//	%H NodeList*	NodeLists
+//		Flags: those of %N
+//			','  separate items with ',' instead of ';'
+//
+//	%Z Strlit*	String literals
+//
+//   In mparith1.c:
+//      %B Mpint*	Big integers
+//	%F Mpflt*	Big floats
+//
+//   %S, %T and %N obey use the following flags to set the format mode:
+enum {
+	FErr,	//     error mode (default)
+	FDbg,	//     "%+N" debug mode
+	FExp,	//     "%#N" export mode
+	FTypeId,  //   "%-N" turning-types-into-symbols-mode: identical types give identical strings
+};
+static int fmtmode;
+static int fmtpkgpfx;	// %uT stickyness
+//
+// E.g. for %S:	%+S %#S %-S	print an identifier properly qualified for debug/export/internal mode.
+//
+// The mode flags  +, - and # are sticky, meaning they persist through
+// recursions of %N, %T and %S, but not the h and l flags.  The u flag is
+// sticky only on %T recursions and only used in %-/Sym mode.
+
+//
+// Useful format combinations:
+//
+//	%+N   %+H	multiline recursive debug dump of node/nodelist
+//	%+hN  %+hH	non recursive debug dump
+//
+//	%#N   %#T	export format
+//	%#lT		type definition instead of name
+//	%#hT		omit"func" and receiver in function signature
+//
+//	%lN		"foo (type Bar)" for error messages
+//
+//	%-T		type identifiers
+//	%-hT		type identifiers without "func" and arg names in type signatures (methodsym)
+//	%-uT		type identifiers with package name instead of prefix (typesym, dcommontype, typehash)
+//
+
+
+static int
+setfmode(unsigned long *flags)
+{
+	int fm;
+
+	fm = fmtmode;
+	if(*flags & FmtSign)
+		fmtmode = FDbg;
+	else if(*flags & FmtSharp)
+		fmtmode = FExp;
+	else if(*flags & FmtLeft)
+		fmtmode = FTypeId;
+
+	*flags &= ~(FmtSharp|FmtLeft|FmtSign);
+	return fm;
+}
+
+// Fmt "%L": Linenumbers
+static int
+Lconv(Fmt *fp)
+{
+	return linklinefmt(ctxt, fp);
+}
+
+static char*
+goopnames[] =
+{
+	[OADDR]		= "&",
+	[OADD]		= "+",
+	[OADDSTR]	= "+",
+	[OANDAND]	= "&&",
+	[OANDNOT]	= "&^",
+	[OAND]		= "&",
+	[OAPPEND]	= "append",
+	[OAS]		= "=",
+	[OAS2]		= "=",
+	[OBREAK]	= "break",
+	[OCALL]		= "function call",	// not actual syntax
+	[OCAP]		= "cap",
+	[OCASE]		= "case",
+	[OCLOSE]	= "close",
+	[OCOMPLEX]	= "complex",
+	[OCOM]		= "^",
+	[OCONTINUE]	= "continue",
+	[OCOPY]		= "copy",
+	[ODEC]		= "--",
+	[ODELETE]	= "delete",
+	[ODEFER]	= "defer",
+	[ODIV]		= "/",
+	[OEQ]		= "==",
+	[OFALL]		= "fallthrough",
+	[OFOR]		= "for",
+	[OGE]		= ">=",
+	[OGOTO]		= "goto",
+	[OGT]		= ">",
+	[OIF]		= "if",
+	[OIMAG]		= "imag",
+	[OINC]		= "++",
+	[OIND]		= "*",
+	[OLEN]		= "len",
+	[OLE]		= "<=",
+	[OLSH]		= "<<",
+	[OLT]		= "<",
+	[OMAKE]		= "make",
+	[OMINUS]	= "-",
+	[OMOD]		= "%",
+	[OMUL]		= "*",
+	[ONEW]		= "new",
+	[ONE]		= "!=",
+	[ONOT]		= "!",
+	[OOROR]		= "||",
+	[OOR]		= "|",
+	[OPANIC]	= "panic",
+	[OPLUS]		= "+",
+	[OPRINTN]	= "println",
+	[OPRINT]	= "print",
+	[ORANGE]	= "range",
+	[OREAL]		= "real",
+	[ORECV]		= "<-",
+	[ORECOVER]	= "recover",
+	[ORETURN]	= "return",
+	[ORSH]		= ">>",
+	[OSELECT]	= "select",
+	[OSEND]		= "<-",
+	[OSUB]		= "-",
+	[OSWITCH]	= "switch",
+	[OXOR]		= "^",
+};
+
+// Fmt "%O":  Node opcodes
+static int
+Oconv(Fmt *fp)
+{
+	int o;
+
+	o = va_arg(fp->args, int);
+	if((fp->flags & FmtSharp) || fmtmode != FDbg)
+		if(o >= 0 && o < nelem(goopnames) && goopnames[o] != nil)
+			return fmtstrcpy(fp, goopnames[o]);
+
+	if(o >= 0 && o < nelem(opnames) && opnames[o] != nil)
+		return fmtstrcpy(fp, opnames[o]);
+
+	return fmtprint(fp, "O-%d", o);
+}
+
+static const char* classnames[] = {
+	"Pxxx",
+	"PEXTERN",
+	"PAUTO",
+	"PPARAM",
+	"PPARAMOUT",
+	"PPARAMREF",
+	"PFUNC",
+};
+
+// Fmt "%J": Node details.
+static int
+Jconv(Fmt *fp)
+{
+	Node *n;
+	char *s;
+	int c;
+
+	n = va_arg(fp->args, Node*);
+
+	c = fp->flags&FmtShort;
+
+	if(!c && n->ullman != 0)
+		fmtprint(fp, " u(%d)", n->ullman);
+
+	if(!c && n->addable != 0)
+		fmtprint(fp, " a(%d)", n->addable);
+
+	if(!c && n->vargen != 0)
+		fmtprint(fp, " g(%d)", n->vargen);
+
+	if(n->lineno != 0)
+		fmtprint(fp, " l(%d)", n->lineno);
+
+	if(!c && n->xoffset != BADWIDTH)
+		fmtprint(fp, " x(%lld%+lld)", n->xoffset, n->stkdelta);
+
+	if(n->class != 0) {
+		s = "";
+		if(n->class & PHEAP) s = ",heap";
+		if((n->class & ~PHEAP) < nelem(classnames))
+			fmtprint(fp, " class(%s%s)", classnames[n->class&~PHEAP], s);
+		else
+			fmtprint(fp, " class(%d?%s)", n->class&~PHEAP, s);
+	}
+
+	if(n->colas != 0)
+		fmtprint(fp, " colas(%d)", n->colas);
+
+	if(n->funcdepth != 0)
+		fmtprint(fp, " f(%d)", n->funcdepth);
+
+	switch(n->esc) {
+	case EscUnknown:
+		break;
+	case EscHeap:
+		fmtprint(fp, " esc(h)");
+		break;
+	case EscScope:
+		fmtprint(fp, " esc(s)");
+		break;
+	case EscNone:
+		fmtprint(fp, " esc(no)");
+		break;
+	case EscNever:
+		if(!c)
+			fmtprint(fp, " esc(N)");
+		break;
+	default:
+		fmtprint(fp, " esc(%d)", n->esc);
+		break;
+	}
+
+	if(n->escloopdepth)
+		fmtprint(fp, " ld(%d)", n->escloopdepth);
+
+	if(!c && n->typecheck != 0)
+		fmtprint(fp, " tc(%d)", n->typecheck);
+
+	if(!c && n->dodata != 0)
+		fmtprint(fp, " dd(%d)", n->dodata);
+
+	if(n->isddd != 0)
+		fmtprint(fp, " isddd(%d)", n->isddd);
+
+	if(n->implicit != 0)
+		fmtprint(fp, " implicit(%d)", n->implicit);
+
+	if(n->embedded != 0)
+		fmtprint(fp, " embedded(%d)", n->embedded);
+
+	if(!c && n->used != 0)
+		fmtprint(fp, " used(%d)", n->used);
+	return 0;
+}
+
+// Fmt "%V": Values
+static int
+Vconv(Fmt *fp)
+{
+	Val *v;
+	vlong x;
+
+	v = va_arg(fp->args, Val*);
+
+	switch(v->ctype) {
+	case CTINT:
+		if((fp->flags & FmtSharp) || fmtmode == FExp)
+			return fmtprint(fp, "%#B", v->u.xval);
+		return fmtprint(fp, "%B", v->u.xval);
+	case CTRUNE:
+		x = mpgetfix(v->u.xval);
+		if(' ' <= x && x < 0x80 && x != '\\' && x != '\'')
+			return fmtprint(fp, "'%c'", (int)x);
+		if(0 <= x && x < (1<<16))
+			return fmtprint(fp, "'\\u%04ux'", (int)x);
+		if(0 <= x && x <= Runemax)
+			return fmtprint(fp, "'\\U%08llux'", x);
+		return fmtprint(fp, "('\\x00' + %B)", v->u.xval);
+	case CTFLT:
+		if((fp->flags & FmtSharp) || fmtmode == FExp)
+			return fmtprint(fp, "%F", v->u.fval);
+		return fmtprint(fp, "%#F", v->u.fval);
+	case CTCPLX:
+		if((fp->flags & FmtSharp) || fmtmode == FExp)
+			return fmtprint(fp, "(%F+%Fi)", &v->u.cval->real, &v->u.cval->imag);
+		if(mpcmpfltc(&v->u.cval->real, 0) == 0)
+			return fmtprint(fp, "%#Fi", &v->u.cval->imag);
+		if(mpcmpfltc(&v->u.cval->imag, 0) == 0)
+			return fmtprint(fp, "%#F", &v->u.cval->real);
+		if(mpcmpfltc(&v->u.cval->imag, 0) < 0)
+			return fmtprint(fp, "(%#F%#Fi)", &v->u.cval->real, &v->u.cval->imag);
+		return fmtprint(fp, "(%#F+%#Fi)", &v->u.cval->real, &v->u.cval->imag);
+	case CTSTR:
+		return fmtprint(fp, "\"%Z\"", v->u.sval);
+	case CTBOOL:
+		if( v->u.bval)
+			return fmtstrcpy(fp, "true");
+		return fmtstrcpy(fp, "false");
+	case CTNIL:
+		return fmtstrcpy(fp, "nil");
+	}
+	return fmtprint(fp, "<ctype=%d>", v->ctype);
+}
+
+// Fmt "%Z": escaped string literals
+static int
+Zconv(Fmt *fp)
+{
+	Rune r;
+	Strlit *sp;
+	char *s, *se;
+	int n;
+
+	sp = va_arg(fp->args, Strlit*);
+	if(sp == nil)
+		return fmtstrcpy(fp, "<nil>");
+
+	s = sp->s;
+	se = s + sp->len;
+
+	// NOTE: Keep in sync with ../ld/go.c:/^Zconv.
+	while(s < se) {
+		n = chartorune(&r, s);
+		s += n;
+		switch(r) {
+		case Runeerror:
+			if(n == 1) {
+				fmtprint(fp, "\\x%02x", (uchar)*(s-1));
+				break;
+			}
+			// fall through
+		default:
+			if(r < ' ') {
+				fmtprint(fp, "\\x%02x", r);
+				break;
+			}
+			fmtrune(fp, r);
+			break;
+		case '\t':
+			fmtstrcpy(fp, "\\t");
+			break;
+		case '\n':
+			fmtstrcpy(fp, "\\n");
+			break;
+		case '\"':
+		case '\\':
+			fmtrune(fp, '\\');
+			fmtrune(fp, r);
+			break;
+		case 0xFEFF: // BOM, basically disallowed in source code
+			fmtstrcpy(fp, "\\uFEFF");
+			break;
+		}
+	}
+	return 0;
+}
+
+/*
+s%,%,\n%g
+s%\n+%\n%g
+s%^[	]*T%%g
+s%,.*%%g
+s%.+%	[T&]		= "&",%g
+s%^	........*\]%&~%g
+s%~	%%g
+*/
+
+static char*
+etnames[] =
+{
+	[TINT]		= "INT",
+	[TUINT]		= "UINT",
+	[TINT8]		= "INT8",
+	[TUINT8]	= "UINT8",
+	[TINT16]	= "INT16",
+	[TUINT16]	= "UINT16",
+	[TINT32]	= "INT32",
+	[TUINT32]	= "UINT32",
+	[TINT64]	= "INT64",
+	[TUINT64]	= "UINT64",
+	[TUINTPTR]	= "UINTPTR",
+	[TFLOAT32]	= "FLOAT32",
+	[TFLOAT64]	= "FLOAT64",
+	[TCOMPLEX64]	= "COMPLEX64",
+	[TCOMPLEX128]	= "COMPLEX128",
+	[TBOOL]		= "BOOL",
+	[TPTR32]	= "PTR32",
+	[TPTR64]	= "PTR64",
+	[TFUNC]		= "FUNC",
+	[TARRAY]	= "ARRAY",
+	[TSTRUCT]	= "STRUCT",
+	[TCHAN]		= "CHAN",
+	[TMAP]		= "MAP",
+	[TINTER]	= "INTER",
+	[TFORW]		= "FORW",
+	[TFIELD]	= "FIELD",
+	[TSTRING]	= "STRING",
+	[TANY]		= "ANY",
+};
+
+// Fmt "%E": etype
+static int
+Econv(Fmt *fp)
+{
+	int et;
+
+	et = va_arg(fp->args, int);
+	if(et >= 0 && et < nelem(etnames) && etnames[et] != nil)
+		return fmtstrcpy(fp, etnames[et]);
+	return fmtprint(fp, "E-%d", et);
+}
+
+// Fmt "%S": syms
+static int
+symfmt(Fmt *fp, Sym *s)
+{
+	char *p;
+
+	if(s->pkg && !(fp->flags&FmtShort)) {
+		switch(fmtmode) {
+		case FErr:	// This is for the user
+			if(s->pkg == localpkg)
+				return fmtstrcpy(fp, s->name);
+			// If the name was used by multiple packages, display the full path,
+			if(s->pkg->name && pkglookup(s->pkg->name, nil)->npkg > 1)
+				return fmtprint(fp, "\"%Z\".%s", s->pkg->path, s->name);
+			return fmtprint(fp, "%s.%s", s->pkg->name, s->name);
+		case FDbg:
+			return fmtprint(fp, "%s.%s", s->pkg->name, s->name);
+		case FTypeId:
+			if(fp->flags&FmtUnsigned)
+				return fmtprint(fp, "%s.%s", s->pkg->name, s->name);	// dcommontype, typehash
+			return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name);	// (methodsym), typesym, weaksym
+		case FExp:
+			if(s->name && s->name[0] == '.')
+				fatal("exporting synthetic symbol %s", s->name);
+			if(s->pkg != builtinpkg)
+				return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name);
+		}
+	}
+
+	if(fp->flags&FmtByte) {  // FmtByte (hh) implies FmtShort (h)
+		// skip leading "type." in method name
+		p = utfrrune(s->name, '.');
+		if(p)
+			p++;
+		else
+			p = s->name;
+
+		// exportname needs to see the name without the prefix too.
+		if((fmtmode == FExp && !exportname(p)) || fmtmode == FDbg)
+			return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, p);
+
+		return fmtstrcpy(fp, p);
+	}
+
+	return fmtstrcpy(fp, s->name);
+}
+
+static char*
+basicnames[] =
+{
+	[TINT]		= "int",
+	[TUINT]		= "uint",
+	[TINT8]		= "int8",
+	[TUINT8]	= "uint8",
+	[TINT16]	= "int16",
+	[TUINT16]	= "uint16",
+	[TINT32]	= "int32",
+	[TUINT32]	= "uint32",
+	[TINT64]	= "int64",
+	[TUINT64]	= "uint64",
+	[TUINTPTR]	= "uintptr",
+	[TFLOAT32]	= "float32",
+	[TFLOAT64]	= "float64",
+	[TCOMPLEX64]	= "complex64",
+	[TCOMPLEX128]	= "complex128",
+	[TBOOL]		= "bool",
+	[TANY]		= "any",
+	[TSTRING]	= "string",
+	[TNIL]		= "nil",
+	[TIDEAL]	= "untyped number",
+	[TBLANK]	= "blank",
+};
+
+static int
+typefmt(Fmt *fp, Type *t)
+{
+	Type *t1;
+	Sym *s;
+
+	if(t == T)
+		return fmtstrcpy(fp, "<T>");
+
+	if (t == bytetype || t == runetype) {
+		// in %-T mode collapse rune and byte with their originals.
+		if(fmtmode != FTypeId)
+			return fmtprint(fp, "%hS", t->sym);
+		t = types[t->etype];
+	}
+
+	if(t == errortype)
+		return fmtstrcpy(fp, "error");
+
+	// Unless the 'l' flag was specified, if the type has a name, just print that name.
+	if(!(fp->flags&FmtLong) && t->sym && t->etype != TFIELD && t != types[t->etype]) {
+		switch(fmtmode) {
+		case FTypeId:
+			if(fp->flags&FmtShort) {
+				if(t->vargen)
+					return fmtprint(fp, "%hS·%d", t->sym, t->vargen);
+				return fmtprint(fp, "%hS", t->sym);
+			}
+			if(fp->flags&FmtUnsigned)
+				return fmtprint(fp, "%uS", t->sym);
+			// fallthrough
+		case FExp:
+			if(t->sym->pkg == localpkg && t->vargen)
+				return fmtprint(fp, "%S·%d", t->sym, t->vargen);
+			break;
+		}
+		return fmtprint(fp, "%S", t->sym);
+	}
+
+	if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) {
+		if(fmtmode == FErr && (t == idealbool || t == idealstring))
+			fmtstrcpy(fp, "untyped ");
+		return fmtstrcpy(fp, basicnames[t->etype]);
+	}
+
+	if(fmtmode == FDbg)
+		fmtprint(fp, "%E-", t->etype);
+
+	switch(t->etype) {
+	case TPTR32:
+	case TPTR64:
+		if(fmtmode == FTypeId && (fp->flags&FmtShort))
+			return fmtprint(fp, "*%hT", t->type);
+		return fmtprint(fp, "*%T", t->type);
+
+	case TARRAY:
+		if(t->bound >= 0)
+			return fmtprint(fp, "[%lld]%T", t->bound, t->type);
+		if(t->bound == -100)
+			return fmtprint(fp, "[...]%T", t->type);
+		return fmtprint(fp, "[]%T", t->type);
+
+	case TCHAN:
+		switch(t->chan) {
+		case Crecv:
+			return fmtprint(fp, "<-chan %T", t->type);
+		case Csend:
+			return fmtprint(fp, "chan<- %T", t->type);
+		}
+
+		if(t->type != T && t->type->etype == TCHAN && t->type->sym == S && t->type->chan == Crecv)
+			return fmtprint(fp, "chan (%T)", t->type);
+		return fmtprint(fp, "chan %T", t->type);
+
+	case TMAP:
+		return fmtprint(fp, "map[%T]%T", t->down, t->type);
+
+	case TINTER:
+		fmtstrcpy(fp, "interface {");
+		for(t1=t->type; t1!=T; t1=t1->down)
+			if(exportname(t1->sym->name)) {
+				if(t1->down)
+					fmtprint(fp, " %hS%hT;", t1->sym, t1->type);
+				else
+					fmtprint(fp, " %hS%hT ", t1->sym, t1->type);
+			} else {
+				// non-exported method names must be qualified
+				if(t1->down)
+					fmtprint(fp, " %uS%hT;", t1->sym, t1->type);
+				else
+					fmtprint(fp, " %uS%hT ", t1->sym, t1->type);
+			}
+		fmtstrcpy(fp, "}");
+		return 0;
+
+	case TFUNC:
+		if(fp->flags & FmtShort) {
+			fmtprint(fp, "%T", getinargx(t));
+		} else {
+			if(t->thistuple)
+				fmtprint(fp, "method%T func%T", getthisx(t), getinargx(t));
+			else
+				fmtprint(fp, "func%T", getinargx(t));
+		}
+		switch(t->outtuple) {
+		case 0:
+			break;
+		case 1:
+			if(fmtmode != FExp) {
+				fmtprint(fp, " %T", getoutargx(t)->type->type);	 // struct->field->field's type
+				break;
+			}
+		default:
+			fmtprint(fp, " %T", getoutargx(t));
+			break;
+		}
+		return 0;
+
+	case TSTRUCT:
+		// Format the bucket struct for map[x]y as map.bucket[x]y.
+		// This avoids a recursive print that generates very long names.
+		if(t->map != T) {
+			if(t->map->bucket == t) {
+				return fmtprint(fp, "map.bucket[%T]%T", t->map->down, t->map->type);
+			}
+			if(t->map->hmap == t) {
+				return fmtprint(fp, "map.hdr[%T]%T", t->map->down, t->map->type);
+			}
+			if(t->map->hiter == t) {
+				return fmtprint(fp, "map.iter[%T]%T", t->map->down, t->map->type);
+			}
+			yyerror("unknown internal map type");
+		}
+
+		if(t->funarg) {
+			fmtstrcpy(fp, "(");
+			if(fmtmode == FTypeId || fmtmode == FErr) {	// no argument names on function signature, and no "noescape"/"nosplit" tags
+				for(t1=t->type; t1!=T; t1=t1->down)
+					if(t1->down)
+						fmtprint(fp, "%hT, ", t1);
+					else
+						fmtprint(fp, "%hT", t1);
+			} else {
+				for(t1=t->type; t1!=T; t1=t1->down)
+					if(t1->down)
+						fmtprint(fp, "%T, ", t1);
+					else
+						fmtprint(fp, "%T", t1);
+			}
+			fmtstrcpy(fp, ")");
+		} else {
+			fmtstrcpy(fp, "struct {");
+			for(t1=t->type; t1!=T; t1=t1->down)
+				if(t1->down)
+					fmtprint(fp, " %lT;", t1);
+				else
+					fmtprint(fp, " %lT ", t1);
+			fmtstrcpy(fp, "}");
+		}
+		return 0;
+
+	case TFIELD:
+		if(!(fp->flags&FmtShort)) {
+			s = t->sym;
+
+			// Take the name from the original, lest we substituted it with ~r%d or ~b%d.
+			// ~r%d is a (formerly) unnamed result.
+			if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) {
+				if(t->nname->orig != N) {
+					s = t->nname->orig->sym;
+					if(s != S && s->name[0] == '~') {
+						if(s->name[1] == 'r') // originally an unnamed result
+							s = S;
+						else if(s->name[1] == 'b') // originally the blank identifier _
+							s = lookup("_");
+					}
+				} else 
+					s = S;
+			}
+			
+			if(s != S && !t->embedded) {
+				if(t->funarg)
+					fmtprint(fp, "%N ", t->nname);
+				else if(fp->flags&FmtLong)
+					fmtprint(fp, "%hhS ", s);  // qualify non-exported names (used on structs, not on funarg)
+				else 
+					fmtprint(fp, "%S ", s);
+			} else if(fmtmode == FExp) {
+				// TODO(rsc) this breaks on the eliding of unused arguments in the backend
+				// when this is fixed, the special case in dcl.c checkarglist can go.
+				//if(t->funarg)
+				//	fmtstrcpy(fp, "_ ");
+				//else
+				if(t->embedded && s->pkg != nil && s->pkg->path->len > 0)
+					fmtprint(fp, "@\"%Z\".? ", s->pkg->path);
+				else
+					fmtstrcpy(fp, "? ");
+			}
+		}
+
+		if(t->isddd)
+			fmtprint(fp, "...%T", t->type->type);
+		else
+			fmtprint(fp, "%T", t->type);
+
+		if(!(fp->flags&FmtShort) && t->note)
+			fmtprint(fp, " \"%Z\"", t->note);
+		return 0;
+
+	case TFORW:
+		if(t->sym)
+			return fmtprint(fp, "undefined %S", t->sym);
+		return fmtstrcpy(fp, "undefined");
+
+	case TUNSAFEPTR:
+		if(fmtmode == FExp)
+			return fmtprint(fp, "@\"unsafe\".Pointer");
+		return fmtprint(fp, "unsafe.Pointer");
+	}
+
+	if(fmtmode == FExp)
+		fatal("missing %E case during export", t->etype);
+	// Don't know how to handle - fall back to detailed prints.
+	return fmtprint(fp, "%E <%S> %T", t->etype, t->sym, t->type);
+}
+
+// Statements which may be rendered with a simplestmt as init.
+static int
+stmtwithinit(int op)
+{
+	switch(op) {
+	case OIF:
+	case OFOR:
+	case OSWITCH:
+		return 1;
+	}
+	return 0;
+}
+
+static int
+stmtfmt(Fmt *f, Node *n)
+{
+	int complexinit, simpleinit, extrablock;
+
+	// some statements allow for an init, but at most one,
+	// but we may have an arbitrary number added, eg by typecheck
+	// and inlining.  If it doesn't fit the syntax, emit an enclosing
+	// block starting with the init statements.
+
+	// if we can just say "for" n->ninit; ... then do so
+	simpleinit = n->ninit && !n->ninit->next && !n->ninit->n->ninit && stmtwithinit(n->op);
+	// otherwise, print the inits as separate statements
+	complexinit = n->ninit && !simpleinit && (fmtmode != FErr);
+	// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
+	extrablock = complexinit && stmtwithinit(n->op);
+
+	if(extrablock)
+		fmtstrcpy(f, "{");
+
+	if(complexinit)
+		fmtprint(f, " %H; ", n->ninit);
+
+	switch(n->op){
+	case ODCL:
+		if(fmtmode == FExp) {
+			switch(n->left->class&~PHEAP) {
+			case PPARAM:
+			case PPARAMOUT:
+			case PAUTO:
+				fmtprint(f, "var %N %T", n->left, n->left->type);
+				goto ret;
+			}
+		}			
+		fmtprint(f, "var %S %T", n->left->sym, n->left->type);
+		break;
+
+	case ODCLFIELD:
+		if(n->left)
+			fmtprint(f, "%N %N", n->left, n->right);
+		else
+			fmtprint(f, "%N", n->right);
+		break;
+
+	case OAS:
+		// Don't export "v = <N>" initializing statements, hope they're always 
+		// preceded by the DCL which will be re-parsed and typecheck to reproduce
+		// the "v = <N>" again.
+		if(fmtmode == FExp && n->right == N)
+			break;
+
+		if(n->colas && !complexinit)
+			fmtprint(f, "%N := %N", n->left, n->right);
+		else
+			fmtprint(f, "%N = %N", n->left, n->right);
+		break;
+
+	case OASOP:
+		if(n->implicit) {
+			if(n->etype == OADD)
+				fmtprint(f, "%N++", n->left);
+			else
+				fmtprint(f, "%N--", n->left);
+			break;
+		}
+		fmtprint(f, "%N %#O= %N", n->left, n->etype, n->right);
+		break;
+
+	case OAS2:
+		if(n->colas && !complexinit) {
+			fmtprint(f, "%,H := %,H", n->list, n->rlist);
+			break;
+		}
+		// fallthrough
+	case OAS2DOTTYPE:
+	case OAS2FUNC:
+	case OAS2MAPR:
+	case OAS2RECV:
+		fmtprint(f, "%,H = %,H", n->list, n->rlist);
+		break;
+
+	case ORETURN:
+		fmtprint(f, "return %,H", n->list);
+		break;
+
+	case ORETJMP:
+		fmtprint(f, "retjmp %S", n->sym);
+		break;
+	
+	case OPROC:
+		fmtprint(f, "go %N", n->left);
+		break;
+
+	case ODEFER:
+		fmtprint(f, "defer %N", n->left);
+		break;
+
+	case OIF:
+		if(simpleinit)
+			fmtprint(f, "if %N; %N { %H }", n->ninit->n, n->ntest, n->nbody);
+		else
+			fmtprint(f, "if %N { %H }", n->ntest, n->nbody);
+		if(n->nelse)
+			fmtprint(f, " else { %H }", n->nelse);
+		break;
+
+	case OFOR:
+		if(fmtmode == FErr) {	// TODO maybe only if FmtShort, same below
+			fmtstrcpy(f, "for loop");
+			break;
+		}
+
+		fmtstrcpy(f, "for");
+		if(simpleinit)
+			fmtprint(f, " %N;", n->ninit->n);
+		else if(n->nincr)
+			fmtstrcpy(f, " ;");
+
+		if(n->ntest)
+			fmtprint(f, " %N", n->ntest);
+
+		if(n->nincr)
+			fmtprint(f, "; %N", n->nincr);
+		else if(simpleinit)
+			fmtstrcpy(f, ";");
+
+
+		fmtprint(f, " { %H }", n->nbody);
+		break;
+
+	case ORANGE:
+		if(fmtmode == FErr) {
+			fmtstrcpy(f, "for loop");
+			break;
+		}
+		
+		if(n->list == nil) {
+			fmtprint(f, "for range %N { %H }", n->right, n->nbody);
+			break;
+		}
+		fmtprint(f, "for %,H = range %N { %H }", n->list, n->right, n->nbody);
+		break;
+
+	case OSELECT:
+	case OSWITCH:
+		if(fmtmode == FErr) {
+			fmtprint(f, "%O statement", n->op);
+			break;
+		}
+
+		fmtprint(f, "%#O", n->op);
+		if(simpleinit)
+			fmtprint(f, " %N;", n->ninit->n);
+		if(n->ntest)
+			fmtprint(f, "%N", n->ntest);
+
+		fmtprint(f, " { %H }", n->list);
+		break;
+
+	case OCASE:
+	case OXCASE:
+		if(n->list)
+			fmtprint(f, "case %,H: %H", n->list, n->nbody);
+		else
+			fmtprint(f, "default: %H", n->nbody);
+		break;
+
+	case OBREAK:
+	case OCONTINUE:
+	case OGOTO:
+	case OFALL:
+	case OXFALL:
+		if(n->left)
+			fmtprint(f, "%#O %N", n->op, n->left);
+		else
+			fmtprint(f, "%#O", n->op);
+		break;
+
+	case OEMPTY:
+		break;
+
+	case OLABEL:
+		fmtprint(f, "%N: ", n->left);
+		break;
+	  
+	}
+ret:
+
+	if(extrablock)
+		fmtstrcpy(f, "}");
+
+	return 0;
+}
+
+
+static int opprec[] = {
+	[OAPPEND] = 8,
+	[OARRAYBYTESTR] = 8,
+	[OARRAYLIT] = 8,
+	[OARRAYRUNESTR] = 8,
+	[OCALLFUNC] = 8,
+	[OCALLINTER] = 8,
+	[OCALLMETH] = 8,
+	[OCALL] = 8,
+	[OCAP] = 8,
+	[OCLOSE] = 8,
+	[OCONVIFACE] = 8,
+	[OCONVNOP] = 8,
+	[OCONV] = 8,
+	[OCOPY] = 8,
+	[ODELETE] = 8,
+	[OLEN] = 8,
+	[OLITERAL] = 8,
+	[OMAKESLICE] = 8,
+	[OMAKE] = 8,
+	[OMAPLIT] = 8,
+	[ONAME] = 8,
+	[ONEW] = 8,
+	[ONONAME] = 8,
+	[OPACK] = 8,
+	[OPANIC] = 8,
+	[OPAREN] = 8,
+	[OPRINTN] = 8,
+	[OPRINT] = 8,
+	[ORUNESTR] = 8,
+	[OSTRARRAYBYTE] = 8,
+	[OSTRARRAYRUNE] = 8,
+	[OSTRUCTLIT] = 8,
+	[OTARRAY] = 8,
+	[OTCHAN] = 8,
+	[OTFUNC] = 8,
+	[OTINTER] = 8,
+	[OTMAP] = 8,
+	[OTSTRUCT] = 8,
+
+	[OINDEXMAP] = 8,
+	[OINDEX] = 8,
+	[OSLICE] = 8,
+	[OSLICESTR] = 8,
+	[OSLICEARR] = 8,
+	[OSLICE3] = 8,
+	[OSLICE3ARR] = 8,
+	[ODOTINTER] = 8,
+	[ODOTMETH] = 8,
+	[ODOTPTR] = 8,
+	[ODOTTYPE2] = 8,
+	[ODOTTYPE] = 8,
+	[ODOT] = 8,
+	[OXDOT] = 8,
+	[OCALLPART] = 8,
+
+	[OPLUS] = 7,
+	[ONOT] = 7,
+	[OCOM] = 7,
+	[OMINUS] = 7,
+	[OADDR] = 7,
+	[OIND] = 7,
+	[ORECV] = 7,
+
+	[OMUL] = 6,
+	[ODIV] = 6,
+	[OMOD] = 6,
+	[OLSH] = 6,
+	[ORSH] = 6,
+	[OAND] = 6,
+	[OANDNOT] = 6,
+
+	[OADD] = 5,
+	[OSUB] = 5,
+	[OOR] = 5,
+	[OXOR] = 5,
+
+	[OEQ] = 4,
+	[OLT] = 4,
+	[OLE] = 4,
+	[OGE] = 4,
+	[OGT] = 4,
+	[ONE] = 4,
+	[OCMPSTR] = 4,
+	[OCMPIFACE] = 4,
+
+	[OSEND] = 3,
+	[OANDAND] = 2,
+	[OOROR] = 1,
+
+	// Statements handled by stmtfmt
+	[OAS] = -1,
+	[OAS2] = -1,
+	[OAS2DOTTYPE] = -1,
+	[OAS2FUNC] = -1,
+	[OAS2MAPR] = -1,
+	[OAS2RECV] = -1,
+	[OASOP] = -1,
+	[OBREAK] = -1,
+	[OCASE] = -1,
+	[OCONTINUE] = -1,
+	[ODCL] = -1,
+	[ODCLFIELD] = -1,
+	[ODEFER] = -1,
+	[OEMPTY] = -1,
+	[OFALL] = -1,
+	[OFOR] = -1,
+	[OGOTO] = -1,
+	[OIF] = -1,
+	[OLABEL] = -1,
+	[OPROC] = -1,
+	[ORANGE] = -1,
+	[ORETURN] = -1,
+	[OSELECT] = -1,
+	[OSWITCH] = -1,
+	[OXCASE] = -1,
+	[OXFALL] = -1,
+
+	[OEND] = 0
+};
+
+static int
+exprfmt(Fmt *f, Node *n, int prec)
+{
+	int nprec;
+	int ptrlit;
+	NodeList *l;
+
+	while(n && n->implicit && (n->op == OIND || n->op == OADDR))
+		n = n->left;
+
+	if(n == N)
+		return fmtstrcpy(f, "<N>");
+
+	nprec = opprec[n->op];
+	if(n->op == OTYPE && n->sym != S)
+		nprec = 8;
+
+	if(prec > nprec)
+		return fmtprint(f, "(%N)", n);
+
+	switch(n->op) {
+	case OPAREN:
+		return fmtprint(f, "(%N)", n->left);
+
+	case ODDDARG:
+		return fmtprint(f, "... argument");
+
+	case OREGISTER:
+		return fmtprint(f, "%R", n->val.u.reg);
+
+	case OLITERAL:  // this is a bit of a mess
+		if(fmtmode == FErr && n->sym != S)
+			return fmtprint(f, "%S", n->sym);
+		if(n->val.ctype == CTNIL && n->orig != N && n->orig != n)
+			return exprfmt(f, n->orig, prec);
+		if(n->type != T && n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) {
+			// Need parens when type begins with what might
+			// be misinterpreted as a unary operator: * or <-.
+			if(isptr[n->type->etype] || (n->type->etype == TCHAN && n->type->chan == Crecv))
+				return fmtprint(f, "(%T)(%V)", n->type, &n->val);
+			else 
+				return fmtprint(f, "%T(%V)", n->type, &n->val);
+		}
+		return fmtprint(f, "%V", &n->val);
+
+	case ONAME:
+		// Special case: name used as local variable in export.
+		// _ becomes ~b%d internally; print as _ for export
+		if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b')
+			return fmtprint(f, "_");
+		if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0)
+			return fmtprint(f, "%S·%d", n->sym, n->vargen);
+
+		// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
+		// but for export, this should be rendered as (*pkg.T).meth.
+		// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
+		if(fmtmode == FExp && n->left && n->left->op == OTYPE && n->right && n->right->op == ONAME) {
+			if(isptr[n->left->type->etype])
+				return fmtprint(f, "(%T).%hhS", n->left->type, n->right->sym);
+			else
+				return fmtprint(f, "%T.%hhS", n->left->type, n->right->sym);
+		}
+		//fallthrough
+	case OPACK:
+	case ONONAME:
+		return fmtprint(f, "%S", n->sym);
+
+	case OTYPE:
+		if(n->type == T && n->sym != S)
+			return fmtprint(f, "%S", n->sym);
+		return fmtprint(f, "%T", n->type);
+
+	case OTARRAY:
+		if(n->left)
+			return fmtprint(f, "[]%N", n->left);
+		return fmtprint(f, "[]%N", n->right);  // happens before typecheck
+
+	case OTMAP:
+		return fmtprint(f, "map[%N]%N", n->left, n->right);
+
+	case OTCHAN:
+		switch(n->etype) {
+		case Crecv:
+			return fmtprint(f, "<-chan %N", n->left);
+		case Csend:
+			return fmtprint(f, "chan<- %N", n->left);
+		default:
+			if(n->left != N && n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv)
+				return fmtprint(f, "chan (%N)", n->left);
+			else
+				return fmtprint(f, "chan %N", n->left);
+		}
+
+	case OTSTRUCT:
+		return fmtprint(f, "<struct>");
+
+	case OTINTER:
+		return fmtprint(f, "<inter>");
+
+	case OTFUNC:
+		return fmtprint(f, "<func>");
+
+	case OCLOSURE:
+		if(fmtmode == FErr)
+			return fmtstrcpy(f, "func literal");
+		if(n->nbody)
+			return fmtprint(f, "%T { %H }", n->type, n->nbody);
+		return fmtprint(f, "%T { %H }", n->type, n->closure->nbody);
+
+	case OCOMPLIT:
+		ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype];
+		if(fmtmode == FErr) {
+			if(n->right != N && n->right->type != T && !n->implicit) {
+				if(ptrlit)
+					return fmtprint(f, "&%T literal", n->right->type->type);
+				else
+					return fmtprint(f, "%T literal", n->right->type);
+			}
+			return fmtstrcpy(f, "composite literal");
+		}
+		if(fmtmode == FExp && ptrlit)
+			// typecheck has overwritten OIND by OTYPE with pointer type.
+			return fmtprint(f, "(&%T{ %,H })", n->right->type->type, n->list);
+		return fmtprint(f, "(%N{ %,H })", n->right, n->list);
+
+	case OPTRLIT:
+		if(fmtmode == FExp && n->left->implicit)
+			return fmtprint(f, "%N", n->left);
+		return fmtprint(f, "&%N", n->left);
+
+	case OSTRUCTLIT:
+		if(fmtmode == FExp) {   // requires special handling of field names
+			if(n->implicit)
+				fmtstrcpy(f, "{");
+			else
+				fmtprint(f, "(%T{", n->type);
+			for(l=n->list; l; l=l->next) {
+				fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right);
+
+				if(l->next)
+					fmtstrcpy(f, ",");
+				else
+					fmtstrcpy(f, " ");
+			}
+			if(!n->implicit)
+				return fmtstrcpy(f, "})");
+			return fmtstrcpy(f, "}");
+		}
+		// fallthrough
+
+	case OARRAYLIT:
+	case OMAPLIT:
+		if(fmtmode == FErr)
+			return fmtprint(f, "%T literal", n->type);
+		if(fmtmode == FExp && n->implicit)
+			return fmtprint(f, "{ %,H }", n->list);
+		return fmtprint(f, "(%T{ %,H })", n->type, n->list);
+
+	case OKEY:
+		if(n->left && n->right) {
+			if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) {
+				// requires special handling of field names
+				return fmtprint(f, "%hhS:%N", n->left->sym, n->right);
+			} else
+				return fmtprint(f, "%N:%N", n->left, n->right);
+		}
+		if(!n->left && n->right)
+			return fmtprint(f, ":%N", n->right);
+		if(n->left && !n->right)
+			return fmtprint(f, "%N:", n->left);
+		return fmtstrcpy(f, ":");
+
+	case OXDOT:
+	case ODOT:
+	case ODOTPTR:
+	case ODOTINTER:
+	case ODOTMETH:
+	case OCALLPART:
+		exprfmt(f, n->left, nprec);
+		if(n->right == N || n->right->sym == S)
+			return fmtstrcpy(f, ".<nil>");
+		return fmtprint(f, ".%hhS", n->right->sym);
+
+	case ODOTTYPE:
+	case ODOTTYPE2:
+		exprfmt(f, n->left, nprec);
+		if(n->right != N)
+			return fmtprint(f, ".(%N)", n->right);
+		return fmtprint(f, ".(%T)", n->type);
+
+	case OINDEX:
+	case OINDEXMAP:
+	case OSLICE:
+	case OSLICESTR:
+	case OSLICEARR:
+	case OSLICE3:
+	case OSLICE3ARR:
+		exprfmt(f, n->left, nprec);
+		return fmtprint(f, "[%N]", n->right);
+
+	case OCOPY:
+	case OCOMPLEX:
+		return fmtprint(f, "%#O(%N, %N)", n->op, n->left, n->right);
+
+	case OCONV:
+	case OCONVIFACE:
+	case OCONVNOP:
+	case OARRAYBYTESTR:
+	case OARRAYRUNESTR:
+	case OSTRARRAYBYTE:
+	case OSTRARRAYRUNE:
+	case ORUNESTR:
+		if(n->type == T || n->type->sym == S)
+			return fmtprint(f, "(%T)(%N)", n->type, n->left);
+		if(n->left)
+			return fmtprint(f, "%T(%N)", n->type, n->left);
+		return fmtprint(f, "%T(%,H)", n->type, n->list);
+
+	case OREAL:
+	case OIMAG:
+	case OAPPEND:
+	case OCAP:
+	case OCLOSE:
+	case ODELETE:
+	case OLEN:
+	case OMAKE:
+	case ONEW:
+	case OPANIC:
+	case ORECOVER:
+	case OPRINT:
+	case OPRINTN:
+		if(n->left)
+			return fmtprint(f, "%#O(%N)", n->op, n->left);
+		if(n->isddd)
+			return fmtprint(f, "%#O(%,H...)", n->op, n->list);
+		return fmtprint(f, "%#O(%,H)", n->op, n->list);
+
+	case OCALL:
+	case OCALLFUNC:
+	case OCALLINTER:
+	case OCALLMETH:
+		exprfmt(f, n->left, nprec);
+		if(n->isddd)
+			return fmtprint(f, "(%,H...)", n->list);
+		return fmtprint(f, "(%,H)", n->list);
+
+	case OMAKEMAP:
+	case OMAKECHAN:
+	case OMAKESLICE:
+		if(n->list) // pre-typecheck
+			return fmtprint(f, "make(%T, %,H)", n->type, n->list);
+		if(n->right)
+			return fmtprint(f, "make(%T, %N, %N)", n->type, n->left, n->right);
+		if(n->left)
+			return fmtprint(f, "make(%T, %N)", n->type, n->left);
+		return fmtprint(f, "make(%T)", n->type);
+
+	// Unary
+	case OPLUS:
+	case OMINUS:
+	case OADDR:
+	case OCOM:
+	case OIND:
+	case ONOT:
+	case ORECV:
+		if(n->left->op == n->op)
+			fmtprint(f, "%#O ", n->op);
+		else
+			fmtprint(f, "%#O", n->op);
+		return exprfmt(f, n->left, nprec+1);
+
+	// Binary
+	case OADD:
+	case OAND:
+	case OANDAND:
+	case OANDNOT:
+	case ODIV:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLT:
+	case OLSH:
+	case OMOD:
+	case OMUL:
+	case ONE:
+	case OOR:
+	case OOROR:
+	case ORSH:
+	case OSEND:
+	case OSUB:
+	case OXOR:
+		exprfmt(f, n->left, nprec);
+		fmtprint(f, " %#O ", n->op);
+		exprfmt(f, n->right, nprec+1);
+		return 0;
+
+	case OADDSTR:
+		for(l=n->list; l; l=l->next) {
+			if(l != n->list)
+				fmtprint(f, " + ");
+			exprfmt(f, l->n, nprec);
+		}
+		return 0;
+
+	case OCMPSTR:
+	case OCMPIFACE:
+		exprfmt(f, n->left, nprec);
+		fmtprint(f, " %#O ", n->etype);
+		exprfmt(f, n->right, nprec+1);
+		return 0;
+	}
+
+	return fmtprint(f, "<node %O>", n->op);
+}
+
+static int
+nodefmt(Fmt *f, Node *n)
+{
+	Type *t;
+
+	t = n->type;
+
+	// we almost always want the original, except in export mode for literals
+	// this saves the importer some work, and avoids us having to redo some
+	// special casing for package unsafe
+	if((fmtmode != FExp || n->op != OLITERAL) && n->orig != N)
+		n = n->orig;
+
+	if(f->flags&FmtLong && t != T) {
+		if(t->etype == TNIL)
+			return fmtprint(f, "nil");
+		else
+			return fmtprint(f, "%N (type %T)", n, t);
+	}
+
+	// TODO inlining produces expressions with ninits. we can't print these yet.
+
+	if(opprec[n->op] < 0)
+		return stmtfmt(f, n);
+
+	return exprfmt(f, n, 0);
+}
+
+static int dumpdepth;
+
+static void
+indent(Fmt *fp)
+{
+	int i;
+
+	fmtstrcpy(fp, "\n");
+	for(i = 0; i < dumpdepth; ++i)
+		fmtstrcpy(fp, ".   ");
+}
+
+static int
+nodedump(Fmt *fp, Node *n)
+{
+	int recur;
+
+	if(n == N)
+		return 0;
+
+	recur = !(fp->flags&FmtShort);
+
+	if(recur) {
+		indent(fp);
+		if(dumpdepth > 10)
+			return fmtstrcpy(fp, "...");
+
+		if(n->ninit != nil) {
+			fmtprint(fp, "%O-init%H", n->op, n->ninit);
+			indent(fp);
+		}
+	}
+
+//	fmtprint(fp, "[%p]", n);
+
+	switch(n->op) {
+	default:
+		fmtprint(fp, "%O%J", n->op, n);
+		break;
+	case OREGISTER:
+	case OINDREG:
+		fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n);
+		break;
+	case OLITERAL:
+		fmtprint(fp, "%O-%V%J", n->op, &n->val, n);
+		break;
+	case ONAME:
+	case ONONAME:
+		if(n->sym != S)
+			fmtprint(fp, "%O-%S%J", n->op, n->sym, n);
+		else
+			fmtprint(fp, "%O%J", n->op, n);
+		if(recur && n->type == T && n->ntype) {
+			indent(fp);
+			fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
+		}
+		break;
+	case OASOP:
+		fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
+		break;
+	case OTYPE:
+		fmtprint(fp, "%O %S%J type=%T", n->op, n->sym, n, n->type);
+		if(recur && n->type == T && n->ntype) {
+			indent(fp);
+			fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
+		}
+		break;
+	}
+
+	if(n->sym != S && n->op != ONAME)
+		fmtprint(fp, " %S G%d", n->sym, n->vargen);
+
+	if(n->type != T)
+		fmtprint(fp, " %T", n->type);
+
+	if(recur) {
+		if(n->left)
+			fmtprint(fp, "%N", n->left);
+		if(n->right)
+			fmtprint(fp, "%N", n->right);
+		if(n->list) {
+			indent(fp);
+			fmtprint(fp, "%O-list%H", n->op, n->list);
+		}
+		if(n->rlist) {
+			indent(fp);
+			fmtprint(fp, "%O-rlist%H", n->op, n->rlist);
+		}
+		if(n->ntest) {
+			indent(fp);
+			fmtprint(fp, "%O-test%N", n->op, n->ntest);
+		}
+		if(n->nbody) {
+			indent(fp);
+			fmtprint(fp, "%O-body%H", n->op, n->nbody);
+		}
+		if(n->nelse) {
+			indent(fp);
+			fmtprint(fp, "%O-else%H", n->op, n->nelse);
+		}
+		if(n->nincr) {
+			indent(fp);
+			fmtprint(fp, "%O-incr%N", n->op, n->nincr);
+		}
+	}
+
+	return 0;
+}
+
+// Fmt "%S": syms
+// Flags:  "%hS" suppresses qualifying with package
+static int
+Sconv(Fmt *fp)
+{
+	Sym *s;
+	int r, sm;
+	unsigned long sf;
+
+	if(fp->flags&FmtLong)
+		return linksymfmt(fp);
+
+	s = va_arg(fp->args, Sym*);
+	if(s == S)
+		return fmtstrcpy(fp, "<S>");
+
+	if(s->name && s->name[0] == '_' && s->name[1] == '\0')
+		return fmtstrcpy(fp, "_");
+
+	sf = fp->flags;
+	sm = setfmode(&fp->flags);
+	r = symfmt(fp, s);
+	fp->flags = sf;
+	fmtmode = sm;
+	return r;
+}
+
+// Fmt "%T": types.
+// Flags: 'l' print definition, not name
+//	  'h' omit 'func' and receiver from function types, short type names
+//	  'u' package name, not prefix (FTypeId mode, sticky)
+static int
+Tconv(Fmt *fp)
+{
+	Type *t;
+	int r, sm;
+	unsigned long sf;
+
+	t = va_arg(fp->args, Type*);
+	if(t == T)
+		return fmtstrcpy(fp, "<T>");
+
+	if(t->trecur > 4)
+		return fmtstrcpy(fp, "<...>");
+
+	t->trecur++;
+	sf = fp->flags;
+	sm = setfmode(&fp->flags);
+
+	if(fmtmode == FTypeId && (sf&FmtUnsigned))
+		fmtpkgpfx++;
+	if(fmtpkgpfx)
+		fp->flags |= FmtUnsigned;
+
+	r = typefmt(fp, t);
+
+	if(fmtmode == FTypeId && (sf&FmtUnsigned))
+		fmtpkgpfx--;
+
+	fp->flags = sf;
+	fmtmode = sm;
+	t->trecur--;
+	return r;
+}
+
+// Fmt '%N': Nodes.
+// Flags: 'l' suffix with "(type %T)" where possible
+//	  '+h' in debug mode, don't recurse, no multiline output
+static int
+Nconv(Fmt *fp)
+{
+	Node *n;
+	int r, sm;
+	unsigned long sf;
+
+	n = va_arg(fp->args, Node*);
+	if(n == N)
+		return fmtstrcpy(fp, "<N>");
+	sf = fp->flags;
+	sm = setfmode(&fp->flags);
+
+	r = -1;
+	switch(fmtmode) {
+	case FErr:
+	case FExp:
+		r = nodefmt(fp, n);
+		break;
+	case FDbg:
+		dumpdepth++;
+		r = nodedump(fp, n);
+		dumpdepth--;
+		break;
+	default:
+		fatal("unhandled %%N mode");
+	}
+
+	fp->flags = sf;
+	fmtmode = sm;
+	return r;
+}
+
+// Fmt '%H': NodeList.
+// Flags: all those of %N plus ',': separate with comma's instead of semicolons.
+static int
+Hconv(Fmt *fp)
+{
+	NodeList *l;
+	int r, sm;
+	unsigned long sf;
+	char *sep;
+
+	l = va_arg(fp->args, NodeList*);
+
+	if(l == nil && fmtmode == FDbg)
+		return fmtstrcpy(fp, "<nil>");
+
+	sf = fp->flags;
+	sm = setfmode(&fp->flags);
+	r = 0;
+	sep = "; ";
+	if(fmtmode == FDbg)
+		sep = "\n";
+	else if(fp->flags & FmtComma)
+		sep = ", ";
+
+	for(;l; l=l->next) {
+		r += fmtprint(fp, "%N", l->n);
+		if(l->next)
+			r += fmtstrcpy(fp, sep);
+	}
+
+	fp->flags = sf;
+	fmtmode = sm;
+	return r;
+}
+
+void
+fmtinstallgo(void)
+{
+	fmtmode = FErr;
+	fmtinstall('E', Econv);		// etype opcodes
+	fmtinstall('J', Jconv);		// all the node flags
+	fmtinstall('H', Hconv);		// node lists
+	fmtinstall('L', Lconv);		// line number
+	fmtinstall('N', Nconv);		// node pointer
+	fmtinstall('O', Oconv);		// node opcodes
+	fmtinstall('S', Sconv);		// sym pointer
+	fmtinstall('T', Tconv);		// type pointer
+	fmtinstall('V', Vconv);		// val pointer
+	fmtinstall('Z', Zconv);		// escaped string
+
+	// These are in mparith1.c
+	fmtinstall('B', Bconv);	// big numbers
+	fmtinstall('F', Fconv);	// big float numbers
+
+}
+
+void
+dumplist(char *s, NodeList *l)
+{
+	print("%s%+H\n", s, l);
+}
+
+void
+dump(char *s, Node *n)
+{
+	print("%s [%p]%+N\n", s, n, n);
+}
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
new file mode 100644
index 0000000..c7c9fcd
--- /dev/null
+++ b/src/cmd/gc/gen.c
@@ -0,0 +1,991 @@
+// 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.
+
+/*
+ * portable half of code generator.
+ * mainly statements and control flow.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+static void	cgen_dcl(Node *n);
+static void	cgen_proc(Node *n, int proc);
+static void	checkgoto(Node*, Node*);
+
+static Label *labellist;
+static Label *lastlabel;
+
+Node*
+sysfunc(char *name)
+{
+	Node *n;
+
+	n = newname(pkglookup(name, runtimepkg));
+	n->class = PFUNC;
+	return n;
+}
+
+/*
+ * the address of n has been taken and might be used after
+ * the current function returns.  mark any local vars
+ * as needing to move to the heap.
+ */
+void
+addrescapes(Node *n)
+{
+	char buf[100];
+	Node *oldfn;
+
+	switch(n->op) {
+	default:
+		// probably a type error already.
+		// dump("addrescapes", n);
+		break;
+
+	case ONAME:
+		if(n == nodfp)
+			break;
+
+		// if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
+		// on PPARAM it means something different.
+		if(n->class == PAUTO && n->esc == EscNever)
+			break;
+
+		switch(n->class) {
+		case PPARAMREF:
+			addrescapes(n->defn);
+			break;
+		case PPARAM:
+		case PPARAMOUT:
+			// if func param, need separate temporary
+			// to hold heap pointer.
+			// the function type has already been checked
+			// (we're in the function body)
+			// so the param already has a valid xoffset.
+
+			// expression to refer to stack copy
+			n->stackparam = nod(OPARAM, n, N);
+			n->stackparam->type = n->type;
+			n->stackparam->addable = 1;
+			if(n->xoffset == BADWIDTH)
+				fatal("addrescapes before param assignment");
+			n->stackparam->xoffset = n->xoffset;
+			// fallthrough
+
+		case PAUTO:
+			n->class |= PHEAP;
+			n->addable = 0;
+			n->ullman = 2;
+			n->xoffset = 0;
+
+			// create stack variable to hold pointer to heap
+			oldfn = curfn;
+			curfn = n->curfn;
+			n->heapaddr = temp(ptrto(n->type));
+			snprint(buf, sizeof buf, "&%S", n->sym);
+			n->heapaddr->sym = lookup(buf);
+			n->heapaddr->orig->sym = n->heapaddr->sym;
+			n->esc = EscHeap;
+			if(debug['m'])
+				print("%L: moved to heap: %N\n", n->lineno, n);
+			curfn = oldfn;
+			break;
+		}
+		break;
+
+	case OIND:
+	case ODOTPTR:
+		break;
+
+	case ODOT:
+	case OINDEX:
+		// ODOTPTR has already been introduced,
+		// so these are the non-pointer ODOT and OINDEX.
+		// In &x[0], if x is a slice, then x does not
+		// escape--the pointer inside x does, but that
+		// is always a heap pointer anyway.
+		if(!isslice(n->left->type))
+			addrescapes(n->left);
+		break;
+	}
+}
+
+void
+clearlabels(void)
+{
+	Label *l;
+
+	for(l=labellist; l!=L; l=l->link)
+		l->sym->label = L;
+	
+	labellist = L;
+	lastlabel = L;
+}
+
+static Label*
+newlab(Node *n)
+{
+	Sym *s;
+	Label *lab;
+	
+	s = n->left->sym;
+	if((lab = s->label) == L) {
+		lab = mal(sizeof(*lab));
+		if(lastlabel == nil)
+			labellist = lab;
+		else
+			lastlabel->link = lab;
+		lastlabel = lab;
+		lab->sym = s;
+		s->label = lab;
+	}
+	
+	if(n->op == OLABEL) {
+		if(lab->def != N)
+			yyerror("label %S already defined at %L", s, lab->def->lineno);
+		else
+			lab->def = n;
+	} else
+		lab->use = list(lab->use, n);
+
+	return lab;
+}
+
+void
+checklabels(void)
+{
+	Label *lab;
+	NodeList *l;
+
+	for(lab=labellist; lab!=L; lab=lab->link) {
+		if(lab->def == N) {
+			for(l=lab->use; l; l=l->next)
+				yyerrorl(l->n->lineno, "label %S not defined", lab->sym);
+			continue;
+		}
+		if(lab->use == nil && !lab->used) {
+			yyerrorl(lab->def->lineno, "label %S defined and not used", lab->sym);
+			continue;
+		}
+		if(lab->gotopc != P)
+			fatal("label %S never resolved", lab->sym);
+		for(l=lab->use; l; l=l->next)
+			checkgoto(l->n, lab->def);
+	}
+}
+
+static void
+checkgoto(Node *from, Node *to)
+{
+	int nf, nt;
+	Sym *block, *dcl, *fs, *ts;
+	int lno;
+
+	if(from->sym == to->sym)
+		return;
+
+	nf = 0;
+	for(fs=from->sym; fs; fs=fs->link)
+		nf++;
+	nt = 0;
+	for(fs=to->sym; fs; fs=fs->link)
+		nt++;
+	fs = from->sym;
+	for(; nf > nt; nf--)
+		fs = fs->link;
+	if(fs != to->sym) {
+		lno = lineno;
+		setlineno(from);
+
+		// decide what to complain about.
+		// prefer to complain about 'into block' over declarations,
+		// so scan backward to find most recent block or else dcl.
+		block = S;
+		dcl = S;
+		ts = to->sym;
+		for(; nt > nf; nt--) {
+			if(ts->pkg == nil)
+				block = ts;
+			else
+				dcl = ts;
+			ts = ts->link;
+		}
+		while(ts != fs) {
+			if(ts->pkg == nil)
+				block = ts;
+			else
+				dcl = ts;
+			ts = ts->link;
+			fs = fs->link;
+		}
+
+		if(block)
+			yyerror("goto %S jumps into block starting at %L", from->left->sym, block->lastlineno);
+		else
+			yyerror("goto %S jumps over declaration of %S at %L", from->left->sym, dcl, dcl->lastlineno);
+		lineno = lno;
+	}
+}
+
+static Label*
+stmtlabel(Node *n)
+{
+	Label *lab;
+
+	if(n->sym != S)
+	if((lab = n->sym->label) != L)
+	if(lab->def != N)
+	if(lab->def->defn == n)
+		return lab;
+	return L;
+}
+
+/*
+ * compile statements
+ */
+void
+genlist(NodeList *l)
+{
+	for(; l; l=l->next)
+		gen(l->n);
+}
+
+void
+gen(Node *n)
+{
+	int32 lno;
+	Prog *scontin, *sbreak;
+	Prog *p1, *p2, *p3;
+	Label *lab;
+	int32 wasregalloc;
+
+//dump("gen", n);
+
+	lno = setlineno(n);
+	wasregalloc = anyregalloc();
+
+	if(n == N)
+		goto ret;
+
+	if(n->ninit)
+		genlist(n->ninit);
+
+	setlineno(n);
+
+	switch(n->op) {
+	default:
+		fatal("gen: unknown op %+hN", n);
+		break;
+
+	case OCASE:
+	case OFALL:
+	case OXCASE:
+	case OXFALL:
+	case ODCLCONST:
+	case ODCLFUNC:
+	case ODCLTYPE:
+		break;
+
+	case OEMPTY:
+		break;
+
+	case OBLOCK:
+		genlist(n->list);
+		break;
+
+	case OLABEL:
+		if(isblanksym(n->left->sym))
+			break;
+		
+		lab = newlab(n);
+
+		// if there are pending gotos, resolve them all to the current pc.
+		for(p1=lab->gotopc; p1; p1=p2) {
+			p2 = unpatch(p1);
+			patch(p1, pc);
+		}
+		lab->gotopc = P;
+		if(lab->labelpc == P)
+			lab->labelpc = pc;
+
+		if(n->defn) {
+			switch(n->defn->op) {
+			case OFOR:
+			case OSWITCH:
+			case OSELECT:
+				// so stmtlabel can find the label
+				n->defn->sym = lab->sym;
+			}
+		}
+		break;
+
+	case OGOTO:
+		// if label is defined, emit jump to it.
+		// otherwise save list of pending gotos in lab->gotopc.
+		// the list is linked through the normal jump target field
+		// to avoid a second list.  (the jumps are actually still
+		// valid code, since they're just going to another goto
+		// to the same label.  we'll unwind it when we learn the pc
+		// of the label in the OLABEL case above.)
+		lab = newlab(n);
+		if(lab->labelpc != P)
+			gjmp(lab->labelpc);
+		else
+			lab->gotopc = gjmp(lab->gotopc);
+		break;
+
+	case OBREAK:
+		if(n->left != N) {
+			lab = n->left->sym->label;
+			if(lab == L) {
+				yyerror("break label not defined: %S", n->left->sym);
+				break;
+			}
+			lab->used = 1;
+			if(lab->breakpc == P) {
+				yyerror("invalid break label %S", n->left->sym);
+				break;
+			}
+			gjmp(lab->breakpc);
+			break;
+		}
+		if(breakpc == P) {
+			yyerror("break is not in a loop");
+			break;
+		}
+		gjmp(breakpc);
+		break;
+
+	case OCONTINUE:
+		if(n->left != N) {
+			lab = n->left->sym->label;
+			if(lab == L) {
+				yyerror("continue label not defined: %S", n->left->sym);
+				break;
+			}
+			lab->used = 1;
+			if(lab->continpc == P) {
+				yyerror("invalid continue label %S", n->left->sym);
+				break;
+			}
+			gjmp(lab->continpc);
+			break;
+		}
+		if(continpc == P) {
+			yyerror("continue is not in a loop");
+			break;
+		}
+		gjmp(continpc);
+		break;
+
+	case OFOR:
+		sbreak = breakpc;
+		p1 = gjmp(P);			//		goto test
+		breakpc = gjmp(P);		// break:	goto done
+		scontin = continpc;
+		continpc = pc;
+
+		// define break and continue labels
+		if((lab = stmtlabel(n)) != L) {
+			lab->breakpc = breakpc;
+			lab->continpc = continpc;
+		}
+		gen(n->nincr);				// contin:	incr
+		patch(p1, pc);				// test:
+		bgen(n->ntest, 0, -1, breakpc);		//		if(!test) goto break
+		genlist(n->nbody);				//		body
+		gjmp(continpc);
+		patch(breakpc, pc);			// done:
+		continpc = scontin;
+		breakpc = sbreak;
+		if(lab) {
+			lab->breakpc = P;
+			lab->continpc = P;
+		}
+		break;
+
+	case OIF:
+		p1 = gjmp(P);			//		goto test
+		p2 = gjmp(P);			// p2:		goto else
+		patch(p1, pc);				// test:
+		bgen(n->ntest, 0, -n->likely, p2);		//		if(!test) goto p2
+		genlist(n->nbody);				//		then
+		p3 = gjmp(P);			//		goto done
+		patch(p2, pc);				// else:
+		genlist(n->nelse);				//		else
+		patch(p3, pc);				// done:
+		break;
+
+	case OSWITCH:
+		sbreak = breakpc;
+		p1 = gjmp(P);			//		goto test
+		breakpc = gjmp(P);		// break:	goto done
+
+		// define break label
+		if((lab = stmtlabel(n)) != L)
+			lab->breakpc = breakpc;
+
+		patch(p1, pc);				// test:
+		genlist(n->nbody);				//		switch(test) body
+		patch(breakpc, pc);			// done:
+		breakpc = sbreak;
+		if(lab != L)
+			lab->breakpc = P;
+		break;
+
+	case OSELECT:
+		sbreak = breakpc;
+		p1 = gjmp(P);			//		goto test
+		breakpc = gjmp(P);		// break:	goto done
+
+		// define break label
+		if((lab = stmtlabel(n)) != L)
+			lab->breakpc = breakpc;
+
+		patch(p1, pc);				// test:
+		genlist(n->nbody);				//		select() body
+		patch(breakpc, pc);			// done:
+		breakpc = sbreak;
+		if(lab != L)
+			lab->breakpc = P;
+		break;
+
+	case OASOP:
+		cgen_asop(n);
+		break;
+
+	case ODCL:
+		cgen_dcl(n->left);
+		break;
+
+	case OAS:
+		if(gen_as_init(n))
+			break;
+		cgen_as(n->left, n->right);
+		break;
+
+	case OCALLMETH:
+		cgen_callmeth(n, 0);
+		break;
+
+	case OCALLINTER:
+		cgen_callinter(n, N, 0);
+		break;
+
+	case OCALLFUNC:
+		cgen_call(n, 0);
+		break;
+
+	case OPROC:
+		cgen_proc(n, 1);
+		break;
+
+	case ODEFER:
+		cgen_proc(n, 2);
+		break;
+
+	case ORETURN:
+	case ORETJMP:
+		cgen_ret(n);
+		break;
+	
+	case OCHECKNIL:
+		cgen_checknil(n->left);
+		break;
+	
+	case OVARKILL:
+		gvarkill(n->left);
+		break;
+	}
+
+ret:
+	if(anyregalloc() != wasregalloc) {
+		dump("node", n);
+		fatal("registers left allocated");
+	}
+
+	lineno = lno;
+}
+
+/*
+ * generate call to non-interface method
+ *	proc=0	normal call
+ *	proc=1	goroutine run in new proc
+ *	proc=2	defer call save away stack
+ */
+void
+cgen_callmeth(Node *n, int proc)
+{
+	Node n2;
+	Node *l;
+
+	// generate a rewrite in n2 for the method call
+	// (p.f)(...) goes to (f)(p,...)
+
+	l = n->left;
+	if(l->op != ODOTMETH)
+		fatal("cgen_callmeth: not dotmethod: %N");
+
+	n2 = *n;
+	n2.op = OCALLFUNC;
+	n2.left = l->right;
+	n2.left->type = l->type;
+
+	if(n2.left->op == ONAME)
+		n2.left->class = PFUNC;
+	cgen_call(&n2, proc);
+}
+
+/*
+ * generate code to start new proc running call n.
+ */
+static void
+cgen_proc(Node *n, int proc)
+{
+	switch(n->left->op) {
+	default:
+		fatal("cgen_proc: unknown call %O", n->left->op);
+
+	case OCALLMETH:
+		cgen_callmeth(n->left, proc);
+		break;
+
+	case OCALLINTER:
+		cgen_callinter(n->left, N, proc);
+		break;
+
+	case OCALLFUNC:
+		cgen_call(n->left, proc);
+		break;
+	}
+
+}
+
+/*
+ * generate declaration.
+ * have to allocate heap copy
+ * for escaped variables.
+ */
+static void
+cgen_dcl(Node *n)
+{
+	if(debug['g'])
+		dump("\ncgen-dcl", n);
+	if(n->op != ONAME) {
+		dump("cgen_dcl", n);
+		fatal("cgen_dcl");
+	}
+	if(!(n->class & PHEAP))
+		return;
+	if(compiling_runtime)
+		yyerror("%N escapes to heap, not allowed in runtime.", n);
+	if(n->alloc == nil)
+		n->alloc = callnew(n->type);
+	cgen_as(n->heapaddr, n->alloc);
+}
+
+/*
+ * generate discard of value
+ */
+static void
+cgen_discard(Node *nr)
+{
+	Node tmp;
+
+	if(nr == N)
+		return;
+
+	switch(nr->op) {
+	case ONAME:
+		if(!(nr->class & PHEAP) && nr->class != PEXTERN && nr->class != PFUNC && nr->class != PPARAMREF)
+			gused(nr);
+		break;
+
+	// unary
+	case OADD:
+	case OAND:
+	case ODIV:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLSH:
+	case OLT:
+	case OMOD:
+	case OMUL:
+	case ONE:
+	case OOR:
+	case ORSH:
+	case OSUB:
+	case OXOR:
+		cgen_discard(nr->left);
+		cgen_discard(nr->right);
+		break;
+
+	// binary
+	case OCAP:
+	case OCOM:
+	case OLEN:
+	case OMINUS:
+	case ONOT:
+	case OPLUS:
+		cgen_discard(nr->left);
+		break;
+	
+	case OIND:
+		cgen_checknil(nr->left);
+		break;
+
+	// special enough to just evaluate
+	default:
+		tempname(&tmp, nr->type);
+		cgen_as(&tmp, nr);
+		gused(&tmp);
+	}
+}
+
+/*
+ * clearslim generates code to zero a slim node.
+ */
+void
+clearslim(Node *n)
+{
+	Node z;
+	Mpflt zero;
+
+	memset(&z, 0, sizeof(z));
+	z.op = OLITERAL;
+	z.type = n->type;
+	z.addable = 1;
+
+	switch(simtype[n->type->etype]) {
+	case TCOMPLEX64:
+	case TCOMPLEX128:
+		z.val.u.cval = mal(sizeof(*z.val.u.cval));
+		mpmovecflt(&z.val.u.cval->real, 0.0);
+		mpmovecflt(&z.val.u.cval->imag, 0.0);
+		break;
+
+	case TFLOAT32:
+	case TFLOAT64:
+		mpmovecflt(&zero, 0.0);
+		z.val.ctype = CTFLT;
+		z.val.u.fval = &zero;
+		break;
+
+	case TPTR32:
+	case TPTR64:
+	case TCHAN:
+	case TMAP:
+		z.val.ctype = CTNIL;
+		break;
+
+	case TBOOL:
+		z.val.ctype = CTBOOL;
+		break;
+
+	case TINT8:
+	case TINT16:
+	case TINT32:
+	case TINT64:
+	case TUINT8:
+	case TUINT16:
+	case TUINT32:
+	case TUINT64:
+		z.val.ctype = CTINT;
+		z.val.u.xval = mal(sizeof(*z.val.u.xval));
+		mpmovecfix(z.val.u.xval, 0);
+		break;
+
+	default:
+		fatal("clearslim called on type %T", n->type);
+	}
+
+	ullmancalc(&z);
+	cgen(&z, n);
+}
+
+/*
+ * generate assignment:
+ *	nl = nr
+ * nr == N means zero nl.
+ */
+void
+cgen_as(Node *nl, Node *nr)
+{
+	Type *tl;
+
+	if(debug['g']) {
+		dump("cgen_as", nl);
+		dump("cgen_as = ", nr);
+	}
+
+	while(nr != N && nr->op == OCONVNOP)
+		nr = nr->left;
+
+	if(nl == N || isblank(nl)) {
+		cgen_discard(nr);
+		return;
+	}
+
+	if(nr == N || iszero(nr)) {
+		// heaps should already be clear
+		if(nr == N && (nl->class & PHEAP))
+			return;
+
+		tl = nl->type;
+		if(tl == T)
+			return;
+		if(isfat(tl)) {
+			if(nl->op == ONAME)
+				gvardef(nl);
+			clearfat(nl);
+			return;
+		}
+		clearslim(nl);
+		return;
+	}
+
+	tl = nl->type;
+	if(tl == T)
+		return;
+
+	cgen(nr, nl);
+}
+
+/*
+ * generate:
+ *	res = iface{typ, data}
+ * n->left is typ
+ * n->right is data
+ */
+void
+cgen_eface(Node *n, Node *res)
+{
+	/* 
+	 * the right node of an eface may contain function calls that uses res as an argument,
+	 * so it's important that it is done first
+	 */
+	Node dst;
+	Node *tmp;
+
+	tmp = temp(types[tptr]);
+	cgen(n->right, tmp);
+
+	gvardef(res);
+
+	dst = *res;
+	dst.type = types[tptr];
+	dst.xoffset += widthptr;
+	cgen(tmp, &dst);
+
+	dst.xoffset -= widthptr;
+	cgen(n->left, &dst);
+}
+
+/*
+ * generate:
+ *	res = s[lo, hi];
+ * n->left is s
+ * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)])
+ * caller (cgen) guarantees res is an addable ONAME.
+ *
+ * called for OSLICE, OSLICE3, OSLICEARR, OSLICE3ARR, OSLICESTR.
+ */
+void
+cgen_slice(Node *n, Node *res)
+{
+	Node src, dst, *cap, *len, *offs, *add, *base, *tmpcap, *tmplen, *cmp, con;
+	Prog *p1, *p2;
+
+	cap = n->list->n;
+	len = n->list->next->n;
+	offs = N;
+	if(n->list->next->next)
+		offs = n->list->next->next->n;
+
+	// evaluate base pointer first, because it is the only
+	// possibly complex expression. once that is evaluated
+	// and stored, updating the len and cap can be done
+	// without making any calls, so without doing anything that
+	// might cause preemption or garbage collection.
+	// this makes the whole slice update atomic as far as the
+	// garbage collector can see.
+	
+	base = temp(types[TUINTPTR]);
+	tmplen = temp(types[TINT]);
+	if(n->op != OSLICESTR)
+		tmpcap = temp(types[TINT]);
+	else
+		tmpcap = tmplen;
+
+	if(isnil(n->left)) {
+		tempname(&src, n->left->type);
+		cgen(n->left, &src);
+	} else
+		src = *n->left;
+	if(n->op == OSLICE || n->op == OSLICE3 || n->op == OSLICESTR)
+		src.xoffset += Array_array;
+
+	if(n->op == OSLICEARR || n->op == OSLICE3ARR) {
+		if(!isptr[n->left->type->etype])
+			fatal("slicearr is supposed to work on pointer: %+N\n", n);
+		cgen(&src, base);
+		cgen_checknil(base);
+	} else {
+		src.type = types[tptr];
+		cgen(&src, base);
+	}
+	
+	// committed to the update
+	gvardef(res);
+
+	// compute len and cap.
+	// len = n-i, cap = m-i, and offs = i*width.
+	// computing offs last lets the multiply overwrite i.
+	cgen(len, tmplen);
+	if(n->op != OSLICESTR)
+		cgen(cap, tmpcap);
+
+	// if new cap != 0 { base += add }
+	// This avoids advancing base past the end of the underlying array/string,
+	// so that it cannot point at the next object in memory.
+	// If cap == 0, the base doesn't matter except insofar as it is 0 or non-zero.
+	// In essence we are replacing x[i:j:k] where i == j == k
+	// or x[i:j] where i == j == cap(x) with x[0:0:0].
+	if(offs != N) {
+		p1 = gjmp(P);
+		p2 = gjmp(P);
+		patch(p1, pc);
+
+		nodconst(&con, tmpcap->type, 0);
+		cmp = nod(OEQ, tmpcap, &con);
+		typecheck(&cmp, Erv);
+		bgen(cmp, 1, -1, p2);
+
+		add = nod(OADD, base, offs);
+		typecheck(&add, Erv);
+		cgen(add, base);
+
+		patch(p2, pc);
+	}
+
+	// dst.array = src.array  [ + lo *width ]
+	dst = *res;
+	dst.xoffset += Array_array;
+	dst.type = types[tptr];
+	cgen(base, &dst);
+
+	// dst.len = hi [ - lo ]
+	dst = *res;
+	dst.xoffset += Array_nel;
+	dst.type = types[simtype[TUINT]];
+	cgen(tmplen, &dst);
+
+	if(n->op != OSLICESTR) {
+		// dst.cap = cap [ - lo ]
+		dst = *res;
+		dst.xoffset += Array_cap;
+		dst.type = types[simtype[TUINT]];
+		cgen(tmpcap, &dst);
+	}
+}
+
+/*
+ * gather series of offsets
+ * >=0 is direct addressed field
+ * <0 is pointer to next field (+1)
+ */
+int
+dotoffset(Node *n, int64 *oary, Node **nn)
+{
+	int i;
+
+	switch(n->op) {
+	case ODOT:
+		if(n->xoffset == BADWIDTH) {
+			dump("bad width in dotoffset", n);
+			fatal("bad width in dotoffset");
+		}
+		i = dotoffset(n->left, oary, nn);
+		if(i > 0) {
+			if(oary[i-1] >= 0)
+				oary[i-1] += n->xoffset;
+			else
+				oary[i-1] -= n->xoffset;
+			break;
+		}
+		if(i < 10)
+			oary[i++] = n->xoffset;
+		break;
+
+	case ODOTPTR:
+		if(n->xoffset == BADWIDTH) {
+			dump("bad width in dotoffset", n);
+			fatal("bad width in dotoffset");
+		}
+		i = dotoffset(n->left, oary, nn);
+		if(i < 10)
+			oary[i++] = -(n->xoffset+1);
+		break;
+
+	default:
+		*nn = n;
+		return 0;
+	}
+	if(i >= 10)
+		*nn = N;
+	return i;
+}
+
+/*
+ * make a new off the books
+ */
+void
+tempname(Node *nn, Type *t)
+{
+	Node *n;
+	Sym *s;
+
+	if(curfn == N)
+		fatal("no curfn for tempname");
+
+	if(t == T) {
+		yyerror("tempname called with nil type");
+		t = types[TINT32];
+	}
+
+	// give each tmp a different name so that there
+	// a chance to registerizer them
+	snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen);
+	statuniqgen++;
+	s = lookup(namebuf);
+	n = nod(ONAME, N, N);
+	n->sym = s;
+	s->def = n;
+	n->type = t;
+	n->class = PAUTO;
+	n->addable = 1;
+	n->ullman = 1;
+	n->esc = EscNever;
+	n->curfn = curfn;
+	curfn->dcl = list(curfn->dcl, n);
+
+	dowidth(t);
+	n->xoffset = 0;
+	*nn = *n;
+}
+
+Node*
+temp(Type *t)
+{
+	Node *n;
+	
+	n = nod(OXXX, N, N);
+	tempname(n, t);
+	n->sym->def->used = 1;
+	return n->orig;
+}
diff --git a/src/cmd/gc/go.errors b/src/cmd/gc/go.errors
new file mode 100644
index 0000000..f90d619
--- /dev/null
+++ b/src/cmd/gc/go.errors
@@ -0,0 +1,79 @@
+// Copyright 2010 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.
+
+// Example-based syntax error messages.
+// See bisonerrors, Makefile, go.y.
+
+static struct {
+	int yystate;
+	int yychar;
+	char *msg;
+} yymsg[] = {
+	// Each line of the form % token list
+	// is converted by bisonerrors into the yystate and yychar caused
+	// by that token list.
+
+	% loadsys package LIMPORT '(' LLITERAL import_package import_there ','
+	"unexpected comma during import block",
+
+	% loadsys package LIMPORT LNAME ';'
+	"missing import path; require quoted string",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header ';'
+	"missing { after if clause",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LSWITCH if_header ';'
+	"missing { after switch clause",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LFOR for_header ';'
+	"missing { after for clause",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LFOR ';' LBODY
+	"missing { after for clause",
+
+	% loadsys package imports LFUNC LNAME '(' ')' ';' '{'
+	"unexpected semicolon or newline before {",
+
+	% loadsys package imports LTYPE LNAME ';'
+	"unexpected semicolon or newline in type declaration",
+
+	% loadsys package imports LCHAN '}'
+	"unexpected } in channel type",
+	
+	% loadsys package imports LCHAN ')'
+	"unexpected ) in channel type",
+	
+	% loadsys package imports LCHAN ','
+	"unexpected comma in channel type",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' if_stmt ';' LELSE
+	"unexpected semicolon or newline before else",
+
+	% loadsys package imports LTYPE LNAME LINTERFACE '{' LNAME ',' LNAME
+	"name list not allowed in interface type",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LFOR LVAR LNAME '=' LNAME
+	"var declaration not allowed in for initializer",
+
+	% loadsys package imports LVAR LNAME '[' ']' LNAME '{'
+	"unexpected { at end of statement",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LVAR LNAME '[' ']' LNAME '{'
+	"unexpected { at end of statement",
+	
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LDEFER LNAME ';'
+	"argument to go/defer must be function call",
+	
+	% loadsys package imports LVAR LNAME '=' LNAME '{' LNAME ';'
+	"need trailing comma before newline in composite literal",
+	
+	% loadsys package imports LVAR LNAME '=' comptype '{' LNAME ';'
+	"need trailing comma before newline in composite literal",
+	
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LFUNC LNAME
+	"nested func not allowed",
+
+	% loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header loop_body LELSE ';'
+	"else must be followed by if or statement block"
+};
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
new file mode 100644
index 0000000..bbb8835
--- /dev/null
+++ b/src/cmd/gc/go.h
@@ -0,0 +1,1555 @@
+// 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.
+
+#include	<bio.h>
+#include	<link.h>
+
+#undef OAPPEND
+
+// avoid <ctype.h>
+#undef isblank
+#define isblank goisblank
+
+#ifndef	EXTERN
+#define	EXTERN	extern
+#endif
+
+#undef	BUFSIZ
+
+// The parser's maximum stack size.
+// We have to use a #define macro here since yacc
+// or bison will check for its definition and use
+// a potentially smaller value if it is undefined.
+#define YYMAXDEPTH 500
+
+enum
+{
+	NHUNK		= 50000,
+	BUFSIZ		= 8192,
+	NSYMB		= 500,
+	NHASH		= 1024,
+	STRINGSZ	= 200,
+	MAXALIGN	= 7,
+	UINF		= 100,
+
+	PRIME1		= 3,
+
+	AUNK		= 100,
+
+	// These values are known by runtime.
+	// The MEMx and NOEQx values must run in parallel.  See algtype.
+	AMEM		= 0,
+	AMEM0,
+	AMEM8,
+	AMEM16,
+	AMEM32,
+	AMEM64,
+	AMEM128,
+	ANOEQ,
+	ANOEQ0,
+	ANOEQ8,
+	ANOEQ16,
+	ANOEQ32,
+	ANOEQ64,
+	ANOEQ128,
+	ASTRING,
+	AINTER,
+	ANILINTER,
+	ASLICE,
+	AFLOAT32,
+	AFLOAT64,
+	ACPLX64,
+	ACPLX128,
+
+	BADWIDTH	= -1000000000,
+	
+	MaxStackVarSize = 10*1024*1024,
+};
+
+extern vlong	MAXWIDTH;
+
+/*
+ * note this is the representation
+ * of the compilers string literals,
+ * it is not the runtime representation
+ */
+typedef	struct	Strlit	Strlit;
+struct	Strlit
+{
+	int32	len;
+	char	s[1]; // variable
+};
+
+enum
+{
+	Mpscale	= 29,		// safely smaller than bits in a long
+	Mpprec	= 16,		// Mpscale*Mpprec is max number of bits
+	Mpnorm	= Mpprec - 1,	// significant words in a normalized float
+	Mpbase	= 1L << Mpscale,
+	Mpsign	= Mpbase >> 1,
+	Mpmask	= Mpbase - 1,
+	Mpdebug	= 0,
+};
+
+typedef	struct	Mpint	Mpint;
+struct	Mpint
+{
+	long	a[Mpprec];
+	uchar	neg;
+	uchar	ovf;
+};
+
+typedef	struct	Mpflt	Mpflt;
+struct	Mpflt
+{
+	Mpint	val;
+	short	exp;
+};
+
+typedef	struct	Mpcplx	Mpcplx;
+struct	Mpcplx
+{
+	Mpflt	real;
+	Mpflt	imag;
+};
+
+typedef	struct	Val	Val;
+struct	Val
+{
+	short	ctype;
+	union
+	{
+		short	reg;		// OREGISTER
+		short	bval;		// bool value CTBOOL
+		Mpint*	xval;		// int CTINT, rune CTRUNE
+		Mpflt*	fval;		// float CTFLT
+		Mpcplx*	cval;		// float CTCPLX
+		Strlit*	sval;		// string CTSTR
+	} u;
+};
+
+// prevent incompatible type signatures between libgc and 8g on Plan 9
+#pragma incomplete struct Array
+
+typedef	struct	Array	Array;
+typedef	struct	Bvec	Bvec;
+typedef	struct	Pkg Pkg;
+typedef	struct	Sym	Sym;
+typedef	struct	Node	Node;
+typedef	struct	NodeList	NodeList;
+typedef	struct	Type	Type;
+typedef	struct	Label	Label;
+
+struct	Type
+{
+	uchar	etype;
+	uchar	nointerface;
+	uchar	noalg;
+	uchar	chan;
+	uchar	trecur;		// to detect loops
+	uchar	printed;
+	uchar	embedded;	// TFIELD embedded type
+	uchar	siggen;
+	uchar	funarg;		// on TSTRUCT and TFIELD
+	uchar	copyany;
+	uchar	local;		// created in this file
+	uchar	deferwidth;
+	uchar	broke;  	// broken type definition.
+	uchar	isddd;		// TFIELD is ... argument
+	uchar	align;
+	uchar	haspointers;	// 0 unknown, 1 no, 2 yes
+
+	Node*	nod;		// canonical OTYPE node
+	Type*	orig;		// original type (type literal or predefined type)
+	int		lineno;
+
+	// TFUNC
+	int	thistuple;
+	int	outtuple;
+	int	intuple;
+	uchar	outnamed;
+
+	Type*	method;
+	Type*	xmethod;
+
+	Sym*	sym;
+	int32	vargen;		// unique name for OTYPE/ONAME
+
+	Node*	nname;
+	vlong	argwid;
+
+	// most nodes
+	Type*	type;   	// actual type for TFIELD, element type for TARRAY, TCHAN, TMAP, TPTRxx
+	vlong	width;  	// offset in TFIELD, width in all others
+
+	// TFIELD
+	Type*	down;		// next struct field, also key type in TMAP
+	Type*	outer;		// outer struct
+	Strlit*	note;		// literal string annotation
+
+	// TARRAY
+	vlong	bound;		// negative is dynamic array
+
+	// TMAP
+	Type*	bucket;		// internal type representing a hash bucket
+	Type*	hmap;		// internal type representing a Hmap (map header object)
+	Type*	hiter;		// internal type representing hash iterator state
+	Type*	map;		// link from the above 3 internal types back to the map type.
+
+	int32	maplineno;	// first use of TFORW as map key
+	int32	embedlineno;	// first use of TFORW as embedded type
+	
+	// for TFORW, where to copy the eventual value to
+	NodeList	*copyto;
+	
+	Node	*lastfn;	// for usefield
+};
+#define	T	((Type*)0)
+
+typedef struct InitEntry InitEntry;
+typedef struct InitPlan InitPlan;
+
+struct InitEntry
+{
+	vlong xoffset;  // struct, array only
+	Node *key;  // map only
+	Node *expr;
+};
+
+struct InitPlan
+{
+	vlong lit;  // bytes of initialized non-zero literals
+	vlong zero;  // bytes of zeros
+	vlong expr;  // bytes of run-time computed expressions
+
+	InitEntry *e;
+	int len;
+	int cap;
+};
+
+enum
+{
+	EscUnknown,
+	EscHeap,
+	EscScope,
+	EscNone,
+	EscReturn,
+	EscNever,
+	EscBits = 3,
+	EscMask = (1<<EscBits) - 1,
+	EscContentEscapes = 1<<EscBits, // value obtained by indirect of parameter escapes to some returned result
+	EscReturnBits = EscBits+1,
+};
+
+struct	Node
+{
+	// Tree structure.
+	// Generic recursive walks should follow these fields.
+	Node*	left;
+	Node*	right;
+	Node*	ntest;
+	Node*	nincr;
+	NodeList*	ninit;
+	NodeList*	nbody;
+	NodeList*	nelse;
+	NodeList*	list;
+	NodeList*	rlist;
+
+	uchar	op;
+	uchar	nointerface;
+	uchar	ullman;		// sethi/ullman number
+	uchar	addable;	// type of addressability - 0 is not addressable
+	uchar	trecur;		// to detect loops
+	uchar	etype;		// op for OASOP, etype for OTYPE, exclam for export
+	uchar	bounded;	// bounds check unnecessary
+	uchar	class;		// PPARAM, PAUTO, PEXTERN, etc
+	uchar	method;		// OCALLMETH name
+	uchar	embedded;	// ODCLFIELD embedded type
+	uchar	colas;		// OAS resulting from :=
+	uchar	diag;		// already printed error about this
+	uchar	noescape;	// func arguments do not escape
+	uchar	nosplit;	// func should not execute on separate stack
+	uchar	builtin;	// built-in name, like len or close
+	uchar	walkdef;
+	uchar	typecheck;
+	uchar	local;
+	uchar	dodata;
+	uchar	initorder;
+	uchar	used;
+	uchar	isddd;
+	uchar	readonly;
+	uchar	implicit;
+	uchar	addrtaken;	// address taken, even if not moved to heap
+	uchar	dupok;	// duplicate definitions ok (for func)
+	uchar	wrapper;	// is method wrapper (for func)
+	uchar	reslice;	// this is a reslice x = x[0:y] or x = append(x, ...)
+	schar	likely; // likeliness of if statement
+	uchar	hasbreak;	// has break statement
+	uchar	needzero; // if it contains pointers, needs to be zeroed on function entry
+	uchar	needctxt;	// function uses context register (has closure variables)
+	uint	esc;		// EscXXX
+	int	funcdepth;
+
+	// most nodes
+	Type*	type;
+	Node*	orig;		// original form, for printing, and tracking copies of ONAMEs
+
+	// func
+	Node*	nname;
+	Node*	shortname;
+	NodeList*	enter;
+	NodeList*	exit;
+	NodeList*	cvars;	// closure params
+	NodeList*	dcl;	// autodcl for this func/closure
+	NodeList*	inl;	// copy of the body for use in inlining
+	NodeList*	inldcl;	// copy of dcl for use in inlining
+
+	// OLITERAL/OREGISTER
+	Val	val;
+
+	// ONAME
+	Node*	ntype;
+	Node*	defn;	// ONAME: initializing assignment; OLABEL: labeled statement
+	Node*	pack;	// real package for import . names
+	Node*	curfn;	// function for local variables
+	Type*	paramfld; // TFIELD for this PPARAM; also for ODOT, curfn
+
+	// ONAME func param with PHEAP
+	Node*	heapaddr;	// temp holding heap address of param
+	Node*	stackparam;	// OPARAM node referring to stack copy of param
+	Node*	alloc;	// allocation call
+
+	// ONAME closure param with PPARAMREF
+	Node*	outer;	// outer PPARAMREF in nested closure
+	Node*	closure;	// ONAME/PHEAP <-> ONAME/PPARAMREF
+
+	// ONAME substitute while inlining
+	Node* inlvar;
+
+	// OPACK
+	Pkg*	pkg;
+	
+	// OARRAYLIT, OMAPLIT, OSTRUCTLIT.
+	InitPlan*	initplan;
+
+	// Escape analysis.
+	NodeList* escflowsrc;	// flow(this, src)
+	NodeList* escretval;	// on OCALLxxx, list of dummy return values
+	int	escloopdepth;	// -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
+
+	Sym*	sym;		// various
+	int32	vargen;		// unique name for OTYPE/ONAME
+	int32	lineno;
+	int32	endlineno;
+	vlong	xoffset;
+	vlong	stkdelta;	// offset added by stack frame compaction phase.
+	int32	ostk;
+	int32	iota;
+	uint32	walkgen;
+	int32	esclevel;
+	void*	opt;	// for optimization passes
+};
+#define	N	((Node*)0)
+
+/*
+ * Every node has a walkgen field.
+ * If you want to do a traversal of a node graph that
+ * might contain duplicates and want to avoid
+ * visiting the same nodes twice, increment walkgen
+ * before starting.  Then before processing a node, do
+ *
+ *	if(n->walkgen == walkgen)
+ *		return;
+ *	n->walkgen = walkgen;
+ *
+ * Such a walk cannot call another such walk recursively,
+ * because of the use of the global walkgen.
+ */
+EXTERN	uint32	walkgen;
+
+struct	NodeList
+{
+	Node*	n;
+	NodeList*	next;
+	NodeList*	end;
+};
+
+enum
+{
+	SymExport	= 1<<0,	// to be exported
+	SymPackage	= 1<<1,
+	SymExported	= 1<<2,	// already written out by export
+	SymUniq		= 1<<3,
+	SymSiggen	= 1<<4,
+};
+
+struct	Sym
+{
+	ushort	lexical;
+	uchar	flags;
+	uchar	sym;		// huffman encoding in object file
+	Sym*	link;
+	int32	npkg;	// number of imported packages with this name
+	uint32	uniqgen;
+	Pkg*	importdef;	// where imported definition was found
+
+	// saved and restored by dcopy
+	Pkg*	pkg;
+	char*	name;		// variable name
+	Node*	def;		// definition: ONAME OTYPE OPACK or OLITERAL
+	Label*	label;	// corresponding label (ephemeral)
+	int32	block;		// blocknumber to catch redeclaration
+	int32	lastlineno;	// last declaration for diagnostic
+	Pkg*	origpkg;	// original package for . import
+	LSym*	lsym;
+};
+#define	S	((Sym*)0)
+
+EXTERN	Sym*	dclstack;
+
+struct	Pkg
+{
+	char*	name;		// package name
+	Strlit*	path;		// string literal used in import statement
+	Sym*	pathsym;
+	char*	prefix;		// escaped path for use in symbol table
+	Pkg*	link;
+	uchar	imported;	// export data of this package was parsed
+	char	exported;	// import line written in export data
+	char	direct;	// imported directly
+	char	safe;	// whether the package is marked as safe
+};
+
+typedef	struct	Iter	Iter;
+struct	Iter
+{
+	int	done;
+	Type*	tfunc;
+	Type*	t;
+	Node**	an;
+	Node*	n;
+};
+
+// Node ops.
+enum
+{
+	OXXX,
+
+	// names
+	ONAME,	// var, const or func name
+	ONONAME,	// unnamed arg or return value: f(int, string) (int, error) { etc }
+	OTYPE,	// type name
+	OPACK,	// import
+	OLITERAL, // literal
+
+	// expressions
+	OADD,	// x + y
+	OSUB,	// x - y
+	OOR,	// x | y
+	OXOR,	// x ^ y
+	OADDSTR,	// s + "foo"
+	OADDR,	// &x
+	OANDAND,	// b0 && b1
+	OAPPEND,	// append
+	OARRAYBYTESTR,	// string(bytes)
+	OARRAYBYTESTRTMP, // string(bytes) ephemeral
+	OARRAYRUNESTR,	// string(runes)
+	OSTRARRAYBYTE,	// []byte(s)
+	OSTRARRAYRUNE,	// []rune(s)
+	OAS,	// x = y or x := y
+	OAS2,	// x, y, z = xx, yy, zz
+	OAS2FUNC,	// x, y = f()
+	OAS2RECV,	// x, ok = <-c
+	OAS2MAPR,	// x, ok = m["foo"]
+	OAS2DOTTYPE,	// x, ok = I.(int)
+	OASOP,	// x += y
+	OCALL,	// function call, method call or type conversion, possibly preceded by defer or go.
+	OCALLFUNC,	// f()
+	OCALLMETH,	// t.Method()
+	OCALLINTER,	// err.Error()
+	OCALLPART,	// t.Method (without ())
+	OCAP,	// cap
+	OCLOSE,	// close
+	OCLOSURE,	// f = func() { etc }
+	OCMPIFACE,	// err1 == err2
+	OCMPSTR,	// s1 == s2
+	OCOMPLIT,	// composite literal, typechecking may convert to a more specific OXXXLIT.
+	OMAPLIT,	// M{"foo":3, "bar":4}
+	OSTRUCTLIT,	// T{x:3, y:4}
+	OARRAYLIT,	// [2]int{3, 4}
+	OPTRLIT,	// &T{x:3, y:4}
+	OCONV,	// var i int; var u uint; i = int(u)
+	OCONVIFACE,	// I(t)
+	OCONVNOP,	// type Int int; var i int; var j Int; i = int(j)
+	OCOPY,	// copy
+	ODCL,	// var x int
+	ODCLFUNC,	// func f() or func (r) f()
+	ODCLFIELD,	// struct field, interface field, or func/method argument/return value.
+	ODCLCONST,	// const pi = 3.14
+	ODCLTYPE,	// type Int int
+	ODELETE,	// delete
+	ODOT,	// t.x
+	ODOTPTR,	// p.x that is implicitly (*p).x
+	ODOTMETH,	// t.Method
+	ODOTINTER,	// err.Error
+	OXDOT,	// t.x, typechecking may convert to a more specific ODOTXXX.
+	ODOTTYPE,	// e = err.(MyErr)
+	ODOTTYPE2,	// e, ok = err.(MyErr)
+	OEQ,	// x == y
+	ONE,	// x != y
+	OLT,	// x < y
+	OLE,	// x <= y
+	OGE,	// x >= y
+	OGT,	// x > y
+	OIND,	// *p
+	OINDEX,	// a[i]
+	OINDEXMAP,	// m[s]
+	OKEY,	// The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
+	OPARAM,	// The on-stack copy of a parameter or return value that escapes.
+	OLEN,	// len
+	OMAKE,	// make, typechecking may convert to a more specific OMAKEXXX.
+	OMAKECHAN,	// make(chan int)
+	OMAKEMAP,	// make(map[string]int)
+	OMAKESLICE,	// make([]int, 0)
+	OMUL,	// x * y
+	ODIV,	// x / y
+	OMOD,	// x % y
+	OLSH,	// x << u
+	ORSH,	// x >> u
+	OAND,	// x & y
+	OANDNOT,	// x &^ y
+	ONEW,	// new
+	ONOT,	// !b
+	OCOM,	// ^x
+	OPLUS,	// +x
+	OMINUS,	// -y
+	OOROR,	// b1 || b2
+	OPANIC,	// panic
+	OPRINT,	// print
+	OPRINTN,	// println
+	OPAREN,	// (x)
+	OSEND,	// c <- x
+	OSLICE,	// v[1:2], typechecking may convert to a more specific OSLICEXXX.
+	OSLICEARR,	// a[1:2]
+	OSLICESTR,	// s[1:2]
+	OSLICE3,	// v[1:2:3], typechecking may convert to OSLICE3ARR.
+	OSLICE3ARR,	// a[1:2:3]
+	ORECOVER,	// recover
+	ORECV,	// <-c
+	ORUNESTR,	// string(i)
+	OSELRECV,	// case x = <-c:
+	OSELRECV2,	// case x, ok = <-c:
+	OIOTA,	// iota
+	OREAL,	// real
+	OIMAG,	// imag
+	OCOMPLEX,	// complex
+
+	// statements
+	OBLOCK,	// block of code
+	OBREAK,	// break
+	OCASE,	// case, after being verified by swt.c's casebody.
+	OXCASE,	// case, before verification.
+	OCONTINUE,	// continue
+	ODEFER,	// defer
+	OEMPTY,	// no-op
+	OFALL,	// fallthrough, after being verified by swt.c's casebody.
+	OXFALL,	// fallthrough, before verification.
+	OFOR,	// for
+	OGOTO,	// goto
+	OIF,	// if
+	OLABEL,	// label:
+	OPROC,	// go
+	ORANGE,	// range
+	ORETURN,	// return
+	OSELECT,	// select
+	OSWITCH,	// switch x
+	OTYPESW,	// switch err.(type)
+
+	// types
+	OTCHAN,	// chan int
+	OTMAP,	// map[string]int
+	OTSTRUCT,	// struct{}
+	OTINTER,	// interface{}
+	OTFUNC,	// func()
+	OTARRAY,	// []int, [8]int, [N]int or [...]int
+
+	// misc
+	ODDD,	// func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
+	ODDDARG,	// func f(args ...int), introduced by escape analysis.
+	OINLCALL,	// intermediary representation of an inlined call.
+	OEFACE,	// itable and data words of an empty-interface value.
+	OITAB,	// itable word of an interface value.
+	OSPTR,  // base pointer of a slice or string.
+	OCLOSUREVAR, // variable reference at beginning of closure function
+	OCFUNC,	// reference to c function pointer (not go func value)
+	OCHECKNIL, // emit code to ensure pointer/interface not nil
+	OVARKILL, // variable is dead
+
+	// arch-specific registers
+	OREGISTER,	// a register, such as AX.
+	OINDREG,	// offset plus indirect of a register, such as 8(SP).
+
+	// 386/amd64-specific opcodes
+	OCMP,	// compare: ACMP.
+	ODEC,	// decrement: ADEC.
+	OINC,	// increment: AINC.
+	OEXTEND,	// extend: ACWD/ACDQ/ACQO.
+	OHMUL, // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
+	OLROT,	// left rotate: AROL.
+	ORROTC, // right rotate-carry: ARCR.
+	ORETJMP,	// return to other function
+
+	OEND,
+};
+
+enum
+{
+	Txxx,			// 0
+
+	TINT8,	TUINT8,		// 1
+	TINT16,	TUINT16,
+	TINT32,	TUINT32,
+	TINT64,	TUINT64,
+	TINT, TUINT, TUINTPTR,
+
+	TCOMPLEX64,		// 12
+	TCOMPLEX128,
+
+	TFLOAT32,		// 14
+	TFLOAT64,
+
+	TBOOL,			// 16
+
+	TPTR32, TPTR64,		// 17
+
+	TFUNC,			// 19
+	TARRAY,
+	T_old_DARRAY,
+	TSTRUCT,		// 22
+	TCHAN,
+	TMAP,
+	TINTER,			// 25
+	TFORW,
+	TFIELD,
+	TANY,
+	TSTRING,
+	TUNSAFEPTR,
+
+	// pseudo-types for literals
+	TIDEAL,			// 31
+	TNIL,
+	TBLANK,
+
+	// pseudo-type for frame layout
+	TFUNCARGS,
+	TCHANARGS,
+	TINTERMETH,
+
+	NTYPE,
+};
+
+enum
+{
+	CTxxx,
+
+	CTINT,
+	CTRUNE,
+	CTFLT,
+	CTCPLX,
+	CTSTR,
+	CTBOOL,
+	CTNIL,
+};
+
+enum
+{
+	/* types of channel */
+	/* must match ../../pkg/nreflect/type.go:/Chandir */
+	Cxxx,
+	Crecv = 1<<0,
+	Csend = 1<<1,
+	Cboth = Crecv | Csend,
+};
+
+// declaration context
+enum
+{
+	Pxxx,
+
+	PEXTERN,	// global variable
+	PAUTO,		// local variables
+	PPARAM,		// input arguments
+	PPARAMOUT,	// output results
+	PPARAMREF,	// closure variable reference
+	PFUNC,		// global function
+
+	PDISCARD,	// discard during parse of duplicate import
+
+	PHEAP = 1<<7,	// an extra bit to identify an escaped variable
+};
+
+enum
+{
+	Etop = 1<<1,		// evaluated at statement level
+	Erv = 1<<2,		// evaluated in value context
+	Etype = 1<<3,
+	Ecall = 1<<4,		// call-only expressions are ok
+	Efnstruct = 1<<5,	// multivalue function returns are ok
+	Eiota = 1<<6,		// iota is ok
+	Easgn = 1<<7,		// assigning to expression
+	Eindir = 1<<8,		// indirecting through expression
+	Eaddr = 1<<9,		// taking address of expression
+	Eproc = 1<<10,		// inside a go statement
+	Ecomplit = 1<<11,	// type in composite literal
+};
+
+#define	BITS	5
+#define	NVAR	(BITS*sizeof(uint32)*8)
+
+typedef	struct	Bits	Bits;
+struct	Bits
+{
+	uint32	b[BITS];
+};
+
+EXTERN	Bits	zbits;
+
+struct Bvec
+{
+	int32	n;	// number of bits
+	uint32	b[];
+};
+
+typedef	struct	Var	Var;
+struct	Var
+{
+	vlong	offset;
+	Node*	node;
+	Var*	nextinnode;
+	int	width;
+	char	name;
+	char	etype;
+	char	addr;
+};
+
+EXTERN	Var	var[NVAR];
+
+typedef	struct	Typedef	Typedef;
+struct	Typedef
+{
+	char*	name;
+	int	etype;
+	int	sameas;
+};
+
+extern	Typedef	typedefs[];
+
+typedef	struct	Sig	Sig;
+struct	Sig
+{
+	char*	name;
+	Pkg*	pkg;
+	Sym*	isym;
+	Sym*	tsym;
+	Type*	type;
+	Type*	mtype;
+	int32	offset;
+	Sig*	link;
+};
+
+typedef	struct	Io	Io;
+struct	Io
+{
+	char*	infile;
+	Biobuf*	bin;
+	int32	ilineno;
+	int	nlsemi;
+	int	eofnl;
+	int	last;
+	int	peekc;
+	int	peekc1;	// second peekc for ...
+	char*	cp;	// used for content when bin==nil
+	int	importsafe;
+};
+
+typedef	struct	Dlist	Dlist;
+struct	Dlist
+{
+	Type*	field;
+};
+
+typedef	struct	Idir	Idir;
+struct Idir
+{
+	Idir*	link;
+	char*	dir;
+};
+
+/*
+ * argument passing to/from
+ * smagic and umagic
+ */
+typedef	struct	Magic Magic;
+struct	Magic
+{
+	int	w;	// input for both - width
+	int	s;	// output for both - shift
+	int	bad;	// output for both - unexpected failure
+
+	// magic multiplier for signed literal divisors
+	int64	sd;	// input - literal divisor
+	int64	sm;	// output - multiplier
+
+	// magic multiplier for unsigned literal divisors
+	uint64	ud;	// input - literal divisor
+	uint64	um;	// output - multiplier
+	int	ua;	// output - adder
+};
+
+struct	Label
+{
+	uchar	used;
+	Sym*	sym;
+	Node*	def;
+	NodeList*	use;
+	Label*	link;
+	
+	// for use during gen
+	Prog*	gotopc;	// pointer to unresolved gotos
+	Prog*	labelpc;	// pointer to code
+	Prog*	breakpc;	// pointer to code
+	Prog*	continpc;	// pointer to code
+};
+#define	L	((Label*)0)
+
+/*
+ * note this is the runtime representation
+ * of the compilers arrays.
+ *
+ * typedef	struct
+ * {				// must not move anything
+ *	uchar	array[8];	// pointer to data
+ *	uchar	nel[4];		// number of elements
+ *	uchar	cap[4];		// allocated number of elements
+ * } Array;
+ */
+EXTERN	int	Array_array;	// runtime offsetof(Array,array) - same for String
+EXTERN	int	Array_nel;	// runtime offsetof(Array,nel) - same for String
+EXTERN	int	Array_cap;	// runtime offsetof(Array,cap)
+EXTERN	int	sizeof_Array;	// runtime sizeof(Array)
+
+
+/*
+ * note this is the runtime representation
+ * of the compilers strings.
+ *
+ * typedef	struct
+ * {				// must not move anything
+ *	uchar	array[8];	// pointer to data
+ *	uchar	nel[4];		// number of elements
+ * } String;
+ */
+EXTERN	int	sizeof_String;	// runtime sizeof(String)
+
+EXTERN	Dlist	dotlist[10];	// size is max depth of embeddeds
+
+EXTERN	Io	curio;
+EXTERN	Io	pushedio;
+EXTERN	int32	lexlineno;
+EXTERN	int32	lineno;
+EXTERN	int32	prevlineno;
+
+EXTERN	char*	infile;
+EXTERN	char*	outfile;
+EXTERN	Biobuf*	bout;
+EXTERN	int	nerrors;
+EXTERN	int	nsavederrors;
+EXTERN	int	nsyntaxerrors;
+EXTERN	int	safemode;
+EXTERN	int	nolocalimports;
+EXTERN	char	namebuf[NSYMB];
+EXTERN	char	lexbuf[NSYMB];
+EXTERN	char	litbuf[NSYMB];
+EXTERN	int	debug[256];
+EXTERN	char*	debugstr;
+EXTERN	int	debug_checknil;
+EXTERN	Sym*	hash[NHASH];
+EXTERN	Sym*	importmyname;	// my name for package
+EXTERN	Pkg*	localpkg;	// package being compiled
+EXTERN	Pkg*	importpkg;	// package being imported
+EXTERN	Pkg*	structpkg;	// package that declared struct, during import
+EXTERN	Pkg*	builtinpkg;	// fake package for builtins
+EXTERN	Pkg*	gostringpkg;	// fake pkg for Go strings
+EXTERN	Pkg*	itabpkg;	// fake pkg for itab cache
+EXTERN	Pkg*	runtimepkg;	// package runtime
+EXTERN	Pkg*	racepkg;	// package runtime/race
+EXTERN	Pkg*	stringpkg;	// fake package for C strings
+EXTERN	Pkg*	typepkg;	// fake package for runtime type info (headers)
+EXTERN	Pkg*	typelinkpkg;	// fake package for runtime type info (data)
+EXTERN	Pkg*	weaktypepkg;	// weak references to runtime type info
+EXTERN	Pkg*	unsafepkg;	// package unsafe
+EXTERN	Pkg*	trackpkg;	// fake package for field tracking
+EXTERN	Pkg*	phash[128];
+EXTERN	int	tptr;		// either TPTR32 or TPTR64
+extern	char*	runtimeimport;
+extern	char*	unsafeimport;
+EXTERN	char*	myimportpath;
+EXTERN	Idir*	idirs;
+EXTERN	char*	localimport;
+
+EXTERN	Type*	types[NTYPE];
+EXTERN	Type*	idealstring;
+EXTERN	Type*	idealbool;
+EXTERN	Type*	bytetype;
+EXTERN	Type*	runetype;
+EXTERN	Type*	errortype;
+EXTERN	uchar	simtype[NTYPE];
+EXTERN	uchar	isptr[NTYPE];
+EXTERN	uchar	isforw[NTYPE];
+EXTERN	uchar	isint[NTYPE];
+EXTERN	uchar	isfloat[NTYPE];
+EXTERN	uchar	iscomplex[NTYPE];
+EXTERN	uchar	issigned[NTYPE];
+EXTERN	uchar	issimple[NTYPE];
+
+EXTERN	uchar	okforeq[NTYPE];
+EXTERN	uchar	okforadd[NTYPE];
+EXTERN	uchar	okforand[NTYPE];
+EXTERN	uchar	okfornone[NTYPE];
+EXTERN	uchar	okforcmp[NTYPE];
+EXTERN	uchar	okforbool[NTYPE];
+EXTERN	uchar	okforcap[NTYPE];
+EXTERN	uchar	okforlen[NTYPE];
+EXTERN	uchar	okforarith[NTYPE];
+EXTERN	uchar	okforconst[NTYPE];
+EXTERN	uchar*	okfor[OEND];
+EXTERN	uchar	iscmp[OEND];
+
+EXTERN	Mpint*	minintval[NTYPE];
+EXTERN	Mpint*	maxintval[NTYPE];
+EXTERN	Mpflt*	minfltval[NTYPE];
+EXTERN	Mpflt*	maxfltval[NTYPE];
+
+EXTERN	NodeList*	xtop;
+EXTERN	NodeList*	externdcl;
+EXTERN	NodeList*	closures;
+EXTERN	NodeList*	exportlist;
+EXTERN	NodeList*	importlist;	// imported functions and methods with inlinable bodies
+EXTERN	NodeList*	funcsyms;
+EXTERN	int	dclcontext;		// PEXTERN/PAUTO
+EXTERN	int	incannedimport;
+EXTERN	int	statuniqgen;		// name generator for static temps
+EXTERN	int	loophack;
+
+EXTERN	int32	iota;
+EXTERN	NodeList*	lastconst;
+EXTERN	Node*	lasttype;
+EXTERN	vlong	maxarg;
+EXTERN	vlong	stksize;		// stack size for current frame
+EXTERN	vlong	stkptrsize;		// prefix of stack containing pointers
+EXTERN	int32	blockgen;		// max block number
+EXTERN	int32	block;			// current block number
+EXTERN	int	hasdefer;		// flag that curfn has defer statetment
+
+EXTERN	Node*	curfn;
+
+EXTERN	int	widthptr;
+EXTERN	int	widthint;
+EXTERN	int	widthreg;
+
+EXTERN	Node*	typesw;
+EXTERN	Node*	nblank;
+
+extern	int	thechar;
+extern	char*	thestring;
+extern	LinkArch*	thelinkarch;
+EXTERN	int  	use_sse;
+
+EXTERN	char*	hunk;
+EXTERN	int32	nhunk;
+EXTERN	int32	thunk;
+
+EXTERN	int	funcdepth;
+EXTERN	int	typecheckok;
+EXTERN	int	compiling_runtime;
+EXTERN	int	compiling_wrappers;
+EXTERN	int	inl_nonlocal;
+EXTERN	int	use_writebarrier;
+EXTERN	int	pure_go;
+EXTERN	char*	flag_installsuffix;
+EXTERN	int	flag_race;
+EXTERN	int	flag_largemodel;
+EXTERN	int	noescape;
+EXTERN	int	nosplit;
+EXTERN	int	debuglive;
+EXTERN	Link*	ctxt;
+
+EXTERN	int	nointerface;
+EXTERN	int	fieldtrack_enabled;
+EXTERN	int	precisestack_enabled;
+EXTERN	int	writearchive;
+
+EXTERN	Biobuf	bstdout;
+
+EXTERN	int	nacl;
+
+/*
+ *	y.tab.c
+ */
+int	yyparse(void);
+
+/*
+ *	align.c
+ */
+int	argsize(Type *t);
+void	checkwidth(Type *t);
+void	defercheckwidth(void);
+void	dowidth(Type *t);
+void	resumecheckwidth(void);
+vlong	rnd(vlong o, vlong r);
+void	typeinit(void);
+
+/*
+ *	array.c
+ */
+Array*	arraynew(int32 capacity, int32 size);
+void	arrayfree(Array *array);
+int32	arraylength(Array *array);
+void*	arrayget(Array *array, int32 index);
+void	arrayset(Array *array, int32 index, void *element);
+void	arrayadd(Array *array, void *element);
+void	arraysort(Array* array, int (*cmp)(const void*, const void*));
+
+/*
+ *	bits.c
+ */
+int	Qconv(Fmt *fp);
+Bits	band(Bits a, Bits b);
+int	bany(Bits *a);
+int	beq(Bits a, Bits b);
+int	bitno(int32 b);
+Bits	blsh(uint n);
+Bits	bnot(Bits a);
+int	bnum(Bits a);
+Bits	bor(Bits a, Bits b);
+int	bset(Bits a, uint n);
+
+/*
+ *	bv.c
+ */
+Bvec*	bvalloc(int32 n);
+void	bvandnot(Bvec *dst, Bvec *src1, Bvec *src2);
+int	bvcmp(Bvec *bv1, Bvec *bv2);
+void	bvcopy(Bvec *dst, Bvec *src);
+Bvec*	bvconcat(Bvec *src1, Bvec *src2);
+int	bvget(Bvec *bv, int32 i);
+int32	bvnext(Bvec *bv, int32 i);
+int	bvisempty(Bvec *bv);
+void	bvnot(Bvec *bv);
+void	bvor(Bvec *dst, Bvec *src1, Bvec *src2);
+void	bvand(Bvec *dst, Bvec *src1, Bvec *src2);
+void	bvprint(Bvec *bv);
+void	bvreset(Bvec *bv, int32 i);
+void	bvresetall(Bvec *bv);
+void	bvset(Bvec *bv, int32 i);
+
+/*
+ *	closure.c
+ */
+Node*	closurebody(NodeList *body);
+void	closurehdr(Node *ntype);
+void	typecheckclosure(Node *func, int top);
+Node*	walkclosure(Node *func, NodeList **init);
+void	typecheckpartialcall(Node*, Node*);
+Node*	walkpartialcall(Node*, NodeList**);
+
+/*
+ *	const.c
+ */
+int	cmpslit(Node *l, Node *r);
+int	consttype(Node *n);
+void	convconst(Node *con, Type *t, Val *val);
+void	convlit(Node **np, Type *t);
+void	convlit1(Node **np, Type *t, int explicit);
+void	defaultlit(Node **np, Type *t);
+void	defaultlit2(Node **lp, Node **rp, int force);
+void	evconst(Node *n);
+int	isconst(Node *n, int ct);
+int	isgoconst(Node *n);
+Node*	nodcplxlit(Val r, Val i);
+Node*	nodlit(Val v);
+long	nonnegconst(Node *n);
+int	doesoverflow(Val v, Type *t);
+void	overflow(Val v, Type *t);
+int	smallintconst(Node *n);
+Val	toint(Val v);
+Mpflt*	truncfltlit(Mpflt *oldv, Type *t);
+
+/*
+ *	cplx.c
+ */
+void	complexadd(int op, Node *nl, Node *nr, Node *res);
+void	complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to);
+void	complexgen(Node *n, Node *res);
+void	complexminus(Node *nl, Node *res);
+void	complexmove(Node *f, Node *t);
+void	complexmul(Node *nl, Node *nr, Node *res);
+int	complexop(Node *n, Node *res);
+void	nodfconst(Node *n, Type *t, Mpflt* fval);
+
+/*
+ *	dcl.c
+ */
+void	addmethod(Sym *sf, Type *t, int local, int nointerface);
+void	addvar(Node *n, Type *t, int ctxt);
+NodeList*	checkarglist(NodeList *all, int input);
+Node*	colas(NodeList *left, NodeList *right, int32 lno);
+void	colasdefn(NodeList *left, Node *defn);
+NodeList*	constiter(NodeList *vl, Node *t, NodeList *cl);
+Node*	dclname(Sym *s);
+void	declare(Node *n, int ctxt);
+void	dumpdcl(char *st);
+Node*	embedded(Sym *s, Pkg *pkg);
+Node*	fakethis(void);
+void	funcbody(Node *n);
+void	funccompile(Node *n, int isclosure);
+void	funchdr(Node *n);
+Type*	functype(Node *this, NodeList *in, NodeList *out);
+void	ifacedcl(Node *n);
+int	isifacemethod(Type *f);
+void	markdcl(void);
+Node*	methodname(Node *n, Type *t);
+Node*	methodname1(Node *n, Node *t);
+Sym*	methodsym(Sym *nsym, Type *t0, int iface);
+Node*	newname(Sym *s);
+Node*	oldname(Sym *s);
+void	popdcl(void);
+void	poptodcl(void);
+void	redeclare(Sym *s, char *where);
+void	testdclstack(void);
+Type*	tointerface(NodeList *l);
+Type*	tostruct(NodeList *l);
+Node*	typedcl0(Sym *s);
+Node*	typedcl1(Node *n, Node *t, int local);
+Node*	typenod(Type *t);
+NodeList*	variter(NodeList *vl, Node *t, NodeList *el);
+Sym*	funcsym(Sym*);
+
+/*
+ *	esc.c
+ */
+void	escapes(NodeList*);
+
+/*
+ *	export.c
+ */
+void	autoexport(Node *n, int ctxt);
+void	dumpexport(void);
+int	exportname(char *s);
+void	exportsym(Node *n);
+void    importconst(Sym *s, Type *t, Node *n);
+void	importimport(Sym *s, Strlit *z);
+Sym*    importsym(Sym *s, int op);
+void    importtype(Type *pt, Type *t);
+void    importvar(Sym *s, Type *t);
+Type*	pkgtype(Sym *s);
+
+/*
+ *	fmt.c
+ */
+void	fmtinstallgo(void);
+void	dump(char *s, Node *n);
+void	dumplist(char *s, NodeList *l);
+
+/*
+ *	gen.c
+ */
+void	addrescapes(Node *n);
+void	cgen_as(Node *nl, Node *nr);
+void	cgen_callmeth(Node *n, int proc);
+void	cgen_eface(Node* n, Node* res);
+void	cgen_slice(Node* n, Node* res);
+void	clearlabels(void);
+void	clearslim(Node*);
+void	checklabels(void);
+int	dotoffset(Node *n, int64 *oary, Node **nn);
+void	gen(Node *n);
+void	genlist(NodeList *l);
+Node*	sysfunc(char *name);
+void	tempname(Node *n, Type *t);
+Node*	temp(Type*);
+
+/*
+ *	init.c
+ */
+void	fninit(NodeList *n);
+Sym*	renameinit(void);
+
+/*
+ *	inl.c
+ */
+void	caninl(Node *fn);
+void	inlcalls(Node *fn);
+void	typecheckinl(Node *fn);
+
+/*
+ *	lex.c
+ */
+void	cannedimports(char *file, char *cp);
+void	importfile(Val *f, int line);
+char*	lexname(int lex);
+char*	expstring(void);
+void	mkpackage(char* pkgname);
+void	unimportfile(void);
+int32	yylex(void);
+extern	int	yylast;
+extern	int	yyprev;
+
+/*
+ *	mparith1.c
+ */
+int	Bconv(Fmt *fp);
+int	Fconv(Fmt *fp);
+void	mpaddcfix(Mpint *a, vlong c);
+void	mpaddcflt(Mpflt *a, double c);
+void	mpatofix(Mpint *a, char *as);
+void	mpatoflt(Mpflt *a, char *as);
+int	mpcmpfixc(Mpint *b, vlong c);
+int	mpcmpfixfix(Mpint *a, Mpint *b);
+int	mpcmpfixflt(Mpint *a, Mpflt *b);
+int	mpcmpfltc(Mpflt *b, double c);
+int	mpcmpfltfix(Mpflt *a, Mpint *b);
+int	mpcmpfltflt(Mpflt *a, Mpflt *b);
+void	mpcomfix(Mpint *a);
+void	mpdivfixfix(Mpint *a, Mpint *b);
+void	mpmodfixfix(Mpint *a, Mpint *b);
+void	mpmovefixfix(Mpint *a, Mpint *b);
+void	mpmovefixflt(Mpflt *a, Mpint *b);
+int	mpmovefltfix(Mpint *a, Mpflt *b);
+void	mpmovefltflt(Mpflt *a, Mpflt *b);
+void	mpmulcfix(Mpint *a, vlong c);
+void	mpmulcflt(Mpflt *a, double c);
+void	mpsubfixfix(Mpint *a, Mpint *b);
+void	mpsubfltflt(Mpflt *a, Mpflt *b);
+
+/*
+ *	mparith2.c
+ */
+void	mpaddfixfix(Mpint *a, Mpint *b, int);
+void	mpandfixfix(Mpint *a, Mpint *b);
+void	mpandnotfixfix(Mpint *a, Mpint *b);
+void	mpdivfract(Mpint *a, Mpint *b);
+void	mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d);
+vlong	mpgetfix(Mpint *a);
+void	mplshfixfix(Mpint *a, Mpint *b);
+void	mpmovecfix(Mpint *a, vlong c);
+void	mpmulfixfix(Mpint *a, Mpint *b);
+void	mpmulfract(Mpint *a, Mpint *b);
+void	mpnegfix(Mpint *a);
+void	mporfixfix(Mpint *a, Mpint *b);
+void	mprshfixfix(Mpint *a, Mpint *b);
+void	mpshiftfix(Mpint *a, int s);
+int	mptestfix(Mpint *a);
+void	mpxorfixfix(Mpint *a, Mpint *b);
+
+/*
+ *	mparith3.c
+ */
+void	mpaddfltflt(Mpflt *a, Mpflt *b);
+void	mpdivfltflt(Mpflt *a, Mpflt *b);
+double	mpgetflt(Mpflt *a);
+double	mpgetflt32(Mpflt *a);
+void	mpmovecflt(Mpflt *a, double c);
+void	mpmulfltflt(Mpflt *a, Mpflt *b);
+void	mpnegflt(Mpflt *a);
+void	mpnorm(Mpflt *a);
+void	mpsetexp(Mpflt *a, int exp);
+int	mptestflt(Mpflt *a);
+int	sigfig(Mpflt *a);
+
+/*
+ *	obj.c
+ */
+void	Bputname(Biobuf *b, LSym *s);
+int	duint16(Sym *s, int off, uint16 v);
+int	duint32(Sym *s, int off, uint32 v);
+int	duint64(Sym *s, int off, uint64 v);
+int	duint8(Sym *s, int off, uint8 v);
+int	duintptr(Sym *s, int off, uint64 v);
+int	dsname(Sym *s, int off, char *dat, int ndat);
+void	dumpobj(void);
+Sym*	stringsym(char*, int);
+void	slicebytes(Node*, char*, int);
+LSym*	linksym(Sym*);
+
+/*
+ *	order.c
+ */
+void	order(Node *fn);
+void	orderstmtinplace(Node **stmt);
+
+/*
+ *	range.c
+ */
+void	typecheckrange(Node *n);
+void	walkrange(Node *n);
+
+/*
+ *	reflect.c
+ */
+void	dumptypestructs(void);
+Type*	methodfunc(Type *f, Type*);
+Node*	typename(Type *t);
+Sym*	typesym(Type *t);
+Sym*	typenamesym(Type *t);
+Sym*	tracksym(Type *t);
+Sym*	typesymprefix(char *prefix, Type *t);
+int	haspointers(Type *t);
+Type*	hiter(Type* t);
+
+/*
+ *	select.c
+ */
+void	typecheckselect(Node *sel);
+void	walkselect(Node *sel);
+
+/*
+ *	sinit.c
+ */
+void	anylit(int, Node *n, Node *var, NodeList **init);
+int	gen_as_init(Node *n);
+NodeList*	initfix(NodeList *l);
+int	oaslit(Node *n, NodeList **init);
+int	stataddr(Node *nam, Node *n);
+
+/*
+ *	subr.c
+ */
+Node*	adddot(Node *n);
+int	adddot1(Sym *s, Type *t, int d, Type **save, int ignorecase);
+void	addinit(Node**, NodeList*);
+Type*	aindex(Node *b, Type *t);
+int	algtype(Type *t);
+int	algtype1(Type *t, Type **bad);
+void	argtype(Node *on, Type *t);
+Node*	assignconv(Node *n, Type *t, char *context);
+int	assignop(Type *src, Type *dst, char **why);
+void	badtype(int o, Type *tl, Type *tr);
+int	brcom(int a);
+int	brrev(int a);
+NodeList*	concat(NodeList *a, NodeList *b);
+int	convertop(Type *src, Type *dst, char **why);
+Node*	copyexpr(Node*, Type*, NodeList**);
+int	count(NodeList *l);
+int	cplxsubtype(int et);
+int	eqtype(Type *t1, Type *t2);
+int	eqtypenoname(Type *t1, Type *t2);
+void	errorexit(void);
+void	expandmeth(Type *t);
+void	fatal(char *fmt, ...);
+void	flusherrors(void);
+void	frame(int context);
+Type*	funcfirst(Iter *s, Type *t);
+Type*	funcnext(Iter *s);
+void	genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface);
+void	genhash(Sym *sym, Type *t);
+void	geneq(Sym *sym, Type *t);
+Type**	getinarg(Type *t);
+Type*	getinargx(Type *t);
+Type**	getoutarg(Type *t);
+Type*	getoutargx(Type *t);
+Type**	getthis(Type *t);
+Type*	getthisx(Type *t);
+int	implements(Type *t, Type *iface, Type **missing, Type **have, int *ptr);
+void	importdot(Pkg *opkg, Node *pack);
+int	is64(Type *t);
+int	isbadimport(Strlit *s);
+int	isblank(Node *n);
+int	isblanksym(Sym *s);
+int	isdirectiface(Type*);
+int	isfixedarray(Type *t);
+int	isideal(Type *t);
+int	isinter(Type *t);
+int	isnil(Node *n);
+int	isnilinter(Type *t);
+int	isptrto(Type *t, int et);
+int	isslice(Type *t);
+int	istype(Type *t, int et);
+int	iszero(Node *n);
+void	linehist(char *file, int32 off, int relative);
+NodeList*	list(NodeList *l, Node *n);
+NodeList*	list1(Node *n);
+void	listsort(NodeList**, int(*f)(Node*, Node*));
+Node*	liststmt(NodeList *l);
+NodeList*	listtreecopy(NodeList *l);
+Sym*	lookup(char *name);
+void*	mal(int32 n);
+Type*	maptype(Type *key, Type *val);
+Type*	methtype(Type *t, int mustname);
+Pkg*	mkpkg(Strlit *path);
+Sym*	ngotype(Node *n);
+int	noconv(Type *t1, Type *t2);
+Node*	nod(int op, Node *nleft, Node *nright);
+Node*	nodbool(int b);
+void	nodconst(Node *n, Type *t, int64 v);
+Node*	nodintconst(int64 v);
+Node*	nodfltconst(Mpflt *v);
+Node*	nodnil(void);
+int	parserline(void);
+Sym*	pkglookup(char *name, Pkg *pkg);
+int	powtwo(Node *n);
+Type*	ptrto(Type *t);
+void*	remal(void *p, int32 on, int32 n);
+Sym*	restrictlookup(char *name, Pkg *pkg);
+Node*	safeexpr(Node *n, NodeList **init);
+void	saveerrors(void);
+Node*	cheapexpr(Node *n, NodeList **init);
+Node*	localexpr(Node *n, Type *t, NodeList **init);
+void	saveorignode(Node *n);
+int32	setlineno(Node *n);
+void	setmaxarg(Type *t);
+Type*	shallow(Type *t);
+int	simsimtype(Type *t);
+void	smagic(Magic *m);
+Type*	sortinter(Type *t);
+uint32	stringhash(char *p);
+Strlit*	strlit(char *s);
+int	structcount(Type *t);
+Type*	structfirst(Iter *s, Type **nn);
+Type*	structnext(Iter *s);
+Node*	syslook(char *name, int copy);
+Type*	tounsigned(Type *t);
+Node*	treecopy(Node *n);
+Type*	typ(int et);
+uint32	typehash(Type *t);
+void	ullmancalc(Node *n);
+void	umagic(Magic *m);
+void	warn(char *fmt, ...);
+void	warnl(int line, char *fmt, ...);
+void	yyerror(char *fmt, ...);
+void	yyerrorl(int line, char *fmt, ...);
+
+/*
+ *	swt.c
+ */
+void	typecheckswitch(Node *n);
+void	walkswitch(Node *sw);
+
+/*
+ *	typecheck.c
+ */
+int	islvalue(Node *n);
+Node*	typecheck(Node **np, int top);
+void	typechecklist(NodeList *l, int top);
+Node*	typecheckdef(Node *n);
+void	copytype(Node *n, Type *t);
+void	checkreturn(Node*);
+void	queuemethod(Node *n);
+
+/*
+ *	unsafe.c
+ */
+int	isunsafebuiltin(Node *n);
+Node*	unsafenmagic(Node *n);
+
+/*
+ *	walk.c
+ */
+Node*	callnew(Type *t);
+Node*	chanfn(char *name, int n, Type *t);
+Node*	mkcall(char *name, Type *t, NodeList **init, ...);
+Node*	mkcall1(Node *fn, Type *t, NodeList **init, ...);
+int	vmatch1(Node *l, Node *r);
+void	walk(Node *fn);
+void	walkexpr(Node **np, NodeList **init);
+void	walkexprlist(NodeList *l, NodeList **init);
+void	walkexprlistsafe(NodeList *l, NodeList **init);
+void	walkstmt(Node **np);
+void	walkstmtlist(NodeList *l);
+Node*	conv(Node*, Type*);
+int	candiscard(Node*);
+int	needwritebarrier(Node*, Node*);
+Node*	outervalue(Node*);
+void	usefield(Node*);
+
+/*
+ *	arch-specific ggen.c/gsubr.c/gobj.c/pgen.c/plive.c
+ */
+#define	P	((Prog*)0)
+
+EXTERN	Prog*	continpc;
+EXTERN	Prog*	breakpc;
+EXTERN	Prog*	pc;
+EXTERN	Prog*	firstpc;
+
+EXTERN	Node*	nodfp;
+EXTERN	int	disable_checknil;
+EXTERN	vlong	zerosize;
+
+int	anyregalloc(void);
+void	betypeinit(void);
+void	bgen(Node *n, int true, int likely, Prog *to);
+void	checknil(Node*, NodeList**);
+void	expandchecks(Prog*);
+void	cgen(Node*, Node*);
+void	cgen_asop(Node *n);
+void	cgen_call(Node *n, int proc);
+void	cgen_callinter(Node *n, Node *res, int proc);
+void	cgen_checknil(Node*);
+void	cgen_ret(Node *n);
+void	clearfat(Node *n);
+void	compile(Node*);
+void	defframe(Prog*);
+int	dgostringptr(Sym*, int off, char *str);
+int	dgostrlitptr(Sym*, int off, Strlit*);
+int	dstringptr(Sym *s, int off, char *str);
+int	dsymptr(Sym *s, int off, Sym *x, int xoff);
+int	duintxx(Sym *s, int off, uint64 v, int wid);
+void	dumpdata(void);
+void	fixautoused(Prog*);
+void	gdata(Node*, Node*, int);
+void	gdatacomplex(Node*, Mpcplx*);
+void	gdatastring(Node*, Strlit*);
+void	ggloblnod(Node *nam);
+void	ggloblsym(Sym *s, int32 width, int8 flags);
+void	gvardef(Node*);
+void	gvarkill(Node*);
+Prog*	gjmp(Prog*);
+void	gused(Node*);
+void	movelarge(NodeList*);
+int	isfat(Type*);
+void	linkarchinit(void);
+void	liveness(Node*, Prog*, Sym*, Sym*);
+void	twobitwalktype1(Type*, vlong*, Bvec*);
+void	markautoused(Prog*);
+Plist*	newplist(void);
+Node*	nodarg(Type*, int);
+void	nopout(Prog*);
+void	patch(Prog*, Prog*);
+Prog*	unpatch(Prog*);
+
+#pragma	varargck	type	"B"	Mpint*
+#pragma	varargck	type	"E"	int
+#pragma	varargck	type	"E"	uint
+#pragma	varargck	type	"F"	Mpflt*
+#pragma	varargck	type	"H"	NodeList*
+#pragma	varargck	type	"J"	Node*
+#pragma	varargck	type	"lL"	int32
+#pragma	varargck	type	"L"	int32
+#pragma	varargck	type	"N"	Node*
+#pragma	varargck	type	"lN"	Node*
+#pragma	varargck	type	"O"	int
+#pragma	varargck	type	"O"	uint
+#pragma	varargck	type	"Q"	Bits
+#pragma	varargck	type	"S"	Sym*
+#pragma	varargck	type	"lS"	LSym*
+#pragma	varargck	type	"T"	Type*
+#pragma	varargck	type	"lT"	Type*
+#pragma	varargck	type	"V"	Val*
+#pragma	varargck	type	"Z"	Strlit*
+
+/*
+ *	racewalk.c
+ */
+void	racewalk(Node *fn);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
new file mode 100644
index 0000000..68fccc1
--- /dev/null
+++ b/src/cmd/gc/go.y
@@ -0,0 +1,2223 @@
+// 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.
+
+/*
+ * Go language grammar.
+ *
+ * The Go semicolon rules are:
+ *
+ *  1. all statements and declarations are terminated by semicolons.
+ *  2. semicolons can be omitted before a closing ) or }.
+ *  3. semicolons are inserted by the lexer before a newline
+ *      following a specific list of tokens.
+ *
+ * Rules #1 and #2 are accomplished by writing the lists as
+ * semicolon-separated lists with an optional trailing semicolon.
+ * Rule #3 is implemented in yylex.
+ */
+
+%{
+#include <u.h>
+#include <stdio.h>	/* if we don't, bison will, and go.h re-#defines getc */
+#include <libc.h>
+#include "go.h"
+
+static void fixlbrace(int);
+%}
+%union	{
+	Node*		node;
+	NodeList*		list;
+	Type*		type;
+	Sym*		sym;
+	struct	Val	val;
+	int		i;
+}
+
+// |sed 's/.*	//' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx		/'
+
+%token	<val>	LLITERAL
+%token	<i>	LASOP LCOLAS
+%token	<sym>	LBREAK LCASE LCHAN LCONST LCONTINUE LDDD
+%token	<sym>	LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
+%token	<sym>	LIF LIMPORT LINTERFACE LMAP LNAME
+%token	<sym>	LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
+%token	<sym>	LTYPE LVAR
+
+%token		LANDAND LANDNOT LBODY LCOMM LDEC LEQ LGE LGT
+%token		LIGNORE LINC LLE LLSH LLT LNE LOROR LRSH
+
+%type	<i>	lbrace import_here
+%type	<sym>	sym packname
+%type	<val>	oliteral
+
+%type	<node>	stmt ntype
+%type	<node>	arg_type
+%type	<node>	case caseblock
+%type	<node>	compound_stmt dotname embed expr complitexpr bare_complitexpr
+%type	<node>	expr_or_type
+%type	<node>	fndcl hidden_fndcl fnliteral
+%type	<node>	for_body for_header for_stmt if_header if_stmt non_dcl_stmt
+%type	<node>	interfacedcl keyval labelname name
+%type	<node>	name_or_type non_expr_type
+%type	<node>	new_name dcl_name oexpr typedclname
+%type	<node>	onew_name
+%type	<node>	osimple_stmt pexpr pexpr_no_paren
+%type	<node>	pseudocall range_stmt select_stmt
+%type	<node>	simple_stmt
+%type	<node>	switch_stmt uexpr
+%type	<node>	xfndcl typedcl start_complit
+
+%type	<list>	xdcl fnbody fnres loop_body dcl_name_list
+%type	<list>	new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
+%type	<list>	oexpr_list caseblock_list elseif elseif_list else stmt_list oarg_type_list_ocomma arg_type_list
+%type	<list>	interfacedcl_list vardcl vardcl_list structdcl structdcl_list
+%type	<list>	common_dcl constdcl constdcl1 constdcl_list typedcl_list
+
+%type	<node>	convtype comptype dotdotdot
+%type	<node>	indcl interfacetype structtype ptrtype
+%type	<node>	recvchantype non_recvchantype othertype fnret_type fntype
+
+%type	<sym>	hidden_importsym hidden_pkg_importsym
+
+%type	<node>	hidden_constant hidden_literal hidden_funarg
+%type	<node>	hidden_interfacedcl hidden_structdcl
+
+%type	<list>	hidden_funres
+%type	<list>	ohidden_funres
+%type	<list>	hidden_funarg_list ohidden_funarg_list
+%type	<list>	hidden_interfacedcl_list ohidden_interfacedcl_list
+%type	<list>	hidden_structdcl_list ohidden_structdcl_list
+
+%type	<type>	hidden_type hidden_type_misc hidden_pkgtype
+%type	<type>	hidden_type_func
+%type	<type>	hidden_type_recv_chan hidden_type_non_recv_chan
+
+%left		LCOMM	/* outside the usual hierarchy; here for good error messages */
+
+%left		LOROR
+%left		LANDAND
+%left		LEQ LNE LLE LGE LLT LGT
+%left		'+' '-' '|' '^'
+%left		'*' '/' '%' '&' LLSH LRSH LANDNOT
+
+/*
+ * manual override of shift/reduce conflicts.
+ * the general form is that we assign a precedence
+ * to the token being shifted and then introduce
+ * NotToken with lower precedence or PreferToToken with higher
+ * and annotate the reducing rule accordingly.
+ */
+%left		NotPackage
+%left		LPACKAGE
+
+%left		NotParen
+%left		'('
+
+%left		')'
+%left		PreferToRightParen
+
+%error-verbose
+
+%%
+file:
+	loadsys
+	package
+	imports
+	xdcl_list
+	{
+		xtop = concat(xtop, $4);
+	}
+
+package:
+	%prec NotPackage
+	{
+		prevlineno = lineno;
+		yyerror("package statement must be first");
+		errorexit();
+	}
+|	LPACKAGE sym ';'
+	{
+		mkpackage($2->name);
+	}
+
+/*
+ * this loads the definitions for the low-level runtime functions,
+ * so that the compiler can generate calls to them,
+ * but does not make the name "runtime" visible as a package.
+ */
+loadsys:
+	{
+		importpkg = runtimepkg;
+
+		if(debug['A'])
+			cannedimports("runtime.builtin", "package runtime\n\n$$\n\n");
+		else
+			cannedimports("runtime.builtin", runtimeimport);
+		curio.importsafe = 1;
+	}
+	import_package
+	import_there
+	{
+		importpkg = nil;
+	}
+
+imports:
+|	imports import ';'
+
+import:
+	LIMPORT import_stmt
+|	LIMPORT '(' import_stmt_list osemi ')'
+|	LIMPORT '(' ')'
+
+import_stmt:
+	import_here import_package import_there
+	{
+		Pkg *ipkg;
+		Sym *my;
+		Node *pack;
+		
+		ipkg = importpkg;
+		my = importmyname;
+		importpkg = nil;
+		importmyname = S;
+
+		if(my == nil)
+			my = lookup(ipkg->name);
+
+		pack = nod(OPACK, N, N);
+		pack->sym = my;
+		pack->pkg = ipkg;
+		pack->lineno = $1;
+
+		if(my->name[0] == '.') {
+			importdot(ipkg, pack);
+			break;
+		}
+		if(strcmp(my->name, "init") == 0) {
+			yyerror("cannot import package as init - init must be a func");
+			break;
+		}
+		if(my->name[0] == '_' && my->name[1] == '\0')
+			break;
+		if(my->def) {
+			lineno = $1;
+			redeclare(my, "as imported package name");
+		}
+		my->def = pack;
+		my->lastlineno = $1;
+		my->block = 1;	// at top level
+	}
+|	import_here import_there
+	{
+		// When an invalid import path is passed to importfile,
+		// it calls yyerror and then sets up a fake import with
+		// no package statement. This allows us to test more
+		// than one invalid import statement in a single file.
+		if(nerrors == 0)
+			fatal("phase error in import");
+	}
+
+import_stmt_list:
+	import_stmt
+|	import_stmt_list ';' import_stmt
+
+import_here:
+	LLITERAL
+	{
+		// import with original name
+		$$ = parserline();
+		importmyname = S;
+		importfile(&$1, $$);
+	}
+|	sym LLITERAL
+	{
+		// import with given name
+		$$ = parserline();
+		importmyname = $1;
+		importfile(&$2, $$);
+	}
+|	'.' LLITERAL
+	{
+		// import into my name space
+		$$ = parserline();
+		importmyname = lookup(".");
+		importfile(&$2, $$);
+	}
+
+import_package:
+	LPACKAGE LNAME import_safety ';'
+	{
+		if(importpkg->name == nil) {
+			importpkg->name = $2->name;
+			pkglookup($2->name, nil)->npkg++;
+		} else if(strcmp(importpkg->name, $2->name) != 0)
+			yyerror("conflicting names %s and %s for package \"%Z\"", importpkg->name, $2->name, importpkg->path);
+		importpkg->direct = 1;
+		importpkg->safe = curio.importsafe;
+
+		if(safemode && !curio.importsafe)
+			yyerror("cannot import unsafe package \"%Z\"", importpkg->path);
+	}
+
+import_safety:
+|	LNAME
+	{
+		if(strcmp($1->name, "safe") == 0)
+			curio.importsafe = 1;
+	}
+
+import_there:
+	{
+		defercheckwidth();
+	}
+	hidden_import_list '$' '$'
+	{
+		resumecheckwidth();
+		unimportfile();
+	}
+
+/*
+ * declarations
+ */
+xdcl:
+	{
+		yyerror("empty top-level declaration");
+		$$ = nil;
+	}
+|	common_dcl
+|	xfndcl
+	{
+		$$ = list1($1);
+	}
+|	non_dcl_stmt
+	{
+		yyerror("non-declaration statement outside function body");
+		$$ = nil;
+	}
+|	error
+	{
+		$$ = nil;
+	}
+
+common_dcl:
+	LVAR vardcl
+	{
+		$$ = $2;
+	}
+|	LVAR '(' vardcl_list osemi ')'
+	{
+		$$ = $3;
+	}
+|	LVAR '(' ')'
+	{
+		$$ = nil;
+	}
+|	lconst constdcl
+	{
+		$$ = $2;
+		iota = -100000;
+		lastconst = nil;
+	}
+|	lconst '(' constdcl osemi ')'
+	{
+		$$ = $3;
+		iota = -100000;
+		lastconst = nil;
+	}
+|	lconst '(' constdcl ';' constdcl_list osemi ')'
+	{
+		$$ = concat($3, $5);
+		iota = -100000;
+		lastconst = nil;
+	}
+|	lconst '(' ')'
+	{
+		$$ = nil;
+		iota = -100000;
+	}
+|	LTYPE typedcl
+	{
+		$$ = list1($2);
+	}
+|	LTYPE '(' typedcl_list osemi ')'
+	{
+		$$ = $3;
+	}
+|	LTYPE '(' ')'
+	{
+		$$ = nil;
+	}
+
+lconst:
+	LCONST
+	{
+		iota = 0;
+	}
+
+vardcl:
+	dcl_name_list ntype
+	{
+		$$ = variter($1, $2, nil);
+	}
+|	dcl_name_list ntype '=' expr_list
+	{
+		$$ = variter($1, $2, $4);
+	}
+|	dcl_name_list '=' expr_list
+	{
+		$$ = variter($1, nil, $3);
+	}
+
+constdcl:
+	dcl_name_list ntype '=' expr_list
+	{
+		$$ = constiter($1, $2, $4);
+	}
+|	dcl_name_list '=' expr_list
+	{
+		$$ = constiter($1, N, $3);
+	}
+
+constdcl1:
+	constdcl
+|	dcl_name_list ntype
+	{
+		$$ = constiter($1, $2, nil);
+	}
+|	dcl_name_list
+	{
+		$$ = constiter($1, N, nil);
+	}
+
+typedclname:
+	sym
+	{
+		// different from dclname because the name
+		// becomes visible right here, not at the end
+		// of the declaration.
+		$$ = typedcl0($1);
+	}
+
+typedcl:
+	typedclname ntype
+	{
+		$$ = typedcl1($1, $2, 1);
+	}
+
+simple_stmt:
+	expr
+	{
+		$$ = $1;
+
+		// These nodes do not carry line numbers.
+		// Since a bare name used as an expression is an error,
+		// introduce a wrapper node to give the correct line.
+		switch($$->op) {
+		case ONAME:
+		case ONONAME:
+		case OTYPE:
+		case OPACK:
+		case OLITERAL:
+			$$ = nod(OPAREN, $$, N);
+			$$->implicit = 1;
+			break;
+		}
+	}
+|	expr LASOP expr
+	{
+		$$ = nod(OASOP, $1, $3);
+		$$->etype = $2;			// rathole to pass opcode
+	}
+|	expr_list '=' expr_list
+	{
+		if($1->next == nil && $3->next == nil) {
+			// simple
+			$$ = nod(OAS, $1->n, $3->n);
+			break;
+		}
+		// multiple
+		$$ = nod(OAS2, N, N);
+		$$->list = $1;
+		$$->rlist = $3;
+	}
+|	expr_list LCOLAS expr_list
+	{
+		if($3->n->op == OTYPESW) {
+			$$ = nod(OTYPESW, N, $3->n->right);
+			if($3->next != nil)
+				yyerror("expr.(type) must be alone in list");
+			if($1->next != nil)
+				yyerror("argument count mismatch: %d = %d", count($1), 1);
+			else if(($1->n->op != ONAME && $1->n->op != OTYPE && $1->n->op != ONONAME) || isblank($1->n))
+				yyerror("invalid variable name %N in type switch", $1->n);
+			else
+				$$->left = dclname($1->n->sym);  // it's a colas, so must not re-use an oldname.
+			break;
+		}
+		$$ = colas($1, $3, $2);
+	}
+|	expr LINC
+	{
+		$$ = nod(OASOP, $1, nodintconst(1));
+		$$->implicit = 1;
+		$$->etype = OADD;
+	}
+|	expr LDEC
+	{
+		$$ = nod(OASOP, $1, nodintconst(1));
+		$$->implicit = 1;
+		$$->etype = OSUB;
+	}
+
+case:
+	LCASE expr_or_type_list ':'
+	{
+		Node *n, *nn;
+
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		$$ = nod(OXCASE, N, N);
+		$$->list = $2;
+		if(typesw != N && typesw->right != N && (n=typesw->right->left) != N) {
+			// type switch - declare variable
+			nn = newname(n->sym);
+			declare(nn, dclcontext);
+			$$->nname = nn;
+
+			// keep track of the instances for reporting unused
+			nn->defn = typesw->right;
+		}
+	}
+|	LCASE expr_or_type_list '=' expr ':'
+	{
+		Node *n;
+
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		$$ = nod(OXCASE, N, N);
+		if($2->next == nil)
+			n = nod(OAS, $2->n, $4);
+		else {
+			n = nod(OAS2, N, N);
+			n->list = $2;
+			n->rlist = list1($4);
+		}
+		$$->list = list1(n);
+	}
+|	LCASE expr_or_type_list LCOLAS expr ':'
+	{
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		$$ = nod(OXCASE, N, N);
+		$$->list = list1(colas($2, list1($4), $3));
+	}
+|	LDEFAULT ':'
+	{
+		Node *n, *nn;
+
+		markdcl();
+		$$ = nod(OXCASE, N, N);
+		if(typesw != N && typesw->right != N && (n=typesw->right->left) != N) {
+			// type switch - declare variable
+			nn = newname(n->sym);
+			declare(nn, dclcontext);
+			$$->nname = nn;
+
+			// keep track of the instances for reporting unused
+			nn->defn = typesw->right;
+		}
+	}
+
+compound_stmt:
+	'{'
+	{
+		markdcl();
+	}
+	stmt_list '}'
+	{
+		if($3 == nil)
+			$$ = nod(OEMPTY, N, N);
+		else
+			$$ = liststmt($3);
+		popdcl();
+	}
+
+caseblock:
+	case
+	{
+		// If the last token read by the lexer was consumed
+		// as part of the case, clear it (parser has cleared yychar).
+		// If the last token read by the lexer was the lookahead
+		// leave it alone (parser has it cached in yychar).
+		// This is so that the stmt_list action doesn't look at
+		// the case tokens if the stmt_list is empty.
+		yylast = yychar;
+		$1->xoffset = block;
+	}
+	stmt_list
+	{
+		int last;
+
+		// This is the only place in the language where a statement
+		// list is not allowed to drop the final semicolon, because
+		// it's the only place where a statement list is not followed 
+		// by a closing brace.  Handle the error for pedantry.
+
+		// Find the final token of the statement list.
+		// yylast is lookahead; yyprev is last of stmt_list
+		last = yyprev;
+
+		if(last > 0 && last != ';' && yychar != '}')
+			yyerror("missing statement after label");
+		$$ = $1;
+		$$->nbody = $3;
+		popdcl();
+	}
+
+caseblock_list:
+	{
+		$$ = nil;
+	}
+|	caseblock_list caseblock
+	{
+		$$ = list($1, $2);
+	}
+
+loop_body:
+	LBODY
+	{
+		markdcl();
+	}
+	stmt_list '}'
+	{
+		$$ = $3;
+		popdcl();
+	}
+
+range_stmt:
+	expr_list '=' LRANGE expr
+	{
+		$$ = nod(ORANGE, N, $4);
+		$$->list = $1;
+		$$->etype = 0;	// := flag
+	}
+|	expr_list LCOLAS LRANGE expr
+	{
+		$$ = nod(ORANGE, N, $4);
+		$$->list = $1;
+		$$->colas = 1;
+		colasdefn($1, $$);
+	}
+|	LRANGE expr
+	{
+		$$ = nod(ORANGE, N, $2);
+		$$->etype = 0; // := flag
+	}
+
+for_header:
+	osimple_stmt ';' osimple_stmt ';' osimple_stmt
+	{
+		// init ; test ; incr
+		if($5 != N && $5->colas != 0)
+			yyerror("cannot declare in the for-increment");
+		$$ = nod(OFOR, N, N);
+		if($1 != N)
+			$$->ninit = list1($1);
+		$$->ntest = $3;
+		$$->nincr = $5;
+	}
+|	osimple_stmt
+	{
+		// normal test
+		$$ = nod(OFOR, N, N);
+		$$->ntest = $1;
+	}
+|	range_stmt
+
+for_body:
+	for_header loop_body
+	{
+		$$ = $1;
+		$$->nbody = concat($$->nbody, $2);
+	}
+
+for_stmt:
+	LFOR
+	{
+		markdcl();
+	}
+	for_body
+	{
+		$$ = $3;
+		popdcl();
+	}
+
+if_header:
+	osimple_stmt
+	{
+		// test
+		$$ = nod(OIF, N, N);
+		$$->ntest = $1;
+	}
+|	osimple_stmt ';' osimple_stmt
+	{
+		// init ; test
+		$$ = nod(OIF, N, N);
+		if($1 != N)
+			$$->ninit = list1($1);
+		$$->ntest = $3;
+	}
+
+/* IF cond body (ELSE IF cond body)* (ELSE block)? */
+if_stmt:
+	LIF
+	{
+		markdcl();
+	}
+	if_header
+	{
+		if($3->ntest == N)
+			yyerror("missing condition in if statement");
+	}
+	loop_body
+	{
+		$3->nbody = $5;
+	}
+	elseif_list else
+	{
+		Node *n;
+		NodeList *nn;
+
+		$$ = $3;
+		n = $3;
+		popdcl();
+		for(nn = concat($7, $8); nn; nn = nn->next) {
+			if(nn->n->op == OIF)
+				popdcl();
+			n->nelse = list1(nn->n);
+			n = nn->n;
+		}
+	}
+
+elseif:
+	LELSE LIF 
+	{
+		markdcl();
+	}
+	if_header loop_body
+	{
+		if($4->ntest == N)
+			yyerror("missing condition in if statement");
+		$4->nbody = $5;
+		$$ = list1($4);
+	}
+
+elseif_list:
+	{
+		$$ = nil;
+	}
+|	elseif_list elseif
+	{
+		$$ = concat($1, $2);
+	}
+
+else:
+	{
+		$$ = nil;
+	}
+|	LELSE compound_stmt
+	{
+		NodeList *node;
+		
+		node = mal(sizeof *node);
+		node->n = $2;
+		node->end = node;
+		$$ = node;
+	}
+
+switch_stmt:
+	LSWITCH
+	{
+		markdcl();
+	}
+	if_header
+	{
+		Node *n;
+		n = $3->ntest;
+		if(n != N && n->op != OTYPESW)
+			n = N;
+		typesw = nod(OXXX, typesw, n);
+	}
+	LBODY caseblock_list '}'
+	{
+		$$ = $3;
+		$$->op = OSWITCH;
+		$$->list = $6;
+		typesw = typesw->left;
+		popdcl();
+	}
+
+select_stmt:
+	LSELECT
+	{
+		typesw = nod(OXXX, typesw, N);
+	}
+	LBODY caseblock_list '}'
+	{
+		$$ = nod(OSELECT, N, N);
+		$$->lineno = typesw->lineno;
+		$$->list = $4;
+		typesw = typesw->left;
+	}
+
+/*
+ * expressions
+ */
+expr:
+	uexpr
+|	expr LOROR expr
+	{
+		$$ = nod(OOROR, $1, $3);
+	}
+|	expr LANDAND expr
+	{
+		$$ = nod(OANDAND, $1, $3);
+	}
+|	expr LEQ expr
+	{
+		$$ = nod(OEQ, $1, $3);
+	}
+|	expr LNE expr
+	{
+		$$ = nod(ONE, $1, $3);
+	}
+|	expr LLT expr
+	{
+		$$ = nod(OLT, $1, $3);
+	}
+|	expr LLE expr
+	{
+		$$ = nod(OLE, $1, $3);
+	}
+|	expr LGE expr
+	{
+		$$ = nod(OGE, $1, $3);
+	}
+|	expr LGT expr
+	{
+		$$ = nod(OGT, $1, $3);
+	}
+|	expr '+' expr
+	{
+		$$ = nod(OADD, $1, $3);
+	}
+|	expr '-' expr
+	{
+		$$ = nod(OSUB, $1, $3);
+	}
+|	expr '|' expr
+	{
+		$$ = nod(OOR, $1, $3);
+	}
+|	expr '^' expr
+	{
+		$$ = nod(OXOR, $1, $3);
+	}
+|	expr '*' expr
+	{
+		$$ = nod(OMUL, $1, $3);
+	}
+|	expr '/' expr
+	{
+		$$ = nod(ODIV, $1, $3);
+	}
+|	expr '%' expr
+	{
+		$$ = nod(OMOD, $1, $3);
+	}
+|	expr '&' expr
+	{
+		$$ = nod(OAND, $1, $3);
+	}
+|	expr LANDNOT expr
+	{
+		$$ = nod(OANDNOT, $1, $3);
+	}
+|	expr LLSH expr
+	{
+		$$ = nod(OLSH, $1, $3);
+	}
+|	expr LRSH expr
+	{
+		$$ = nod(ORSH, $1, $3);
+	}
+	/* not an expression anymore, but left in so we can give a good error */
+|	expr LCOMM expr
+	{
+		$$ = nod(OSEND, $1, $3);
+	}
+
+uexpr:
+	pexpr
+|	'*' uexpr
+	{
+		$$ = nod(OIND, $2, N);
+	}
+|	'&' uexpr
+	{
+		if($2->op == OCOMPLIT) {
+			// Special case for &T{...}: turn into (*T){...}.
+			$$ = $2;
+			$$->right = nod(OIND, $$->right, N);
+			$$->right->implicit = 1;
+		} else {
+			$$ = nod(OADDR, $2, N);
+		}
+	}
+|	'+' uexpr
+	{
+		$$ = nod(OPLUS, $2, N);
+	}
+|	'-' uexpr
+	{
+		$$ = nod(OMINUS, $2, N);
+	}
+|	'!' uexpr
+	{
+		$$ = nod(ONOT, $2, N);
+	}
+|	'~' uexpr
+	{
+		yyerror("the bitwise complement operator is ^");
+		$$ = nod(OCOM, $2, N);
+	}
+|	'^' uexpr
+	{
+		$$ = nod(OCOM, $2, N);
+	}
+|	LCOMM uexpr
+	{
+		$$ = nod(ORECV, $2, N);
+	}
+
+/*
+ * call-like statements that
+ * can be preceded by 'defer' and 'go'
+ */
+pseudocall:
+	pexpr '(' ')'
+	{
+		$$ = nod(OCALL, $1, N);
+	}
+|	pexpr '(' expr_or_type_list ocomma ')'
+	{
+		$$ = nod(OCALL, $1, N);
+		$$->list = $3;
+	}
+|	pexpr '(' expr_or_type_list LDDD ocomma ')'
+	{
+		$$ = nod(OCALL, $1, N);
+		$$->list = $3;
+		$$->isddd = 1;
+	}
+
+pexpr_no_paren:
+	LLITERAL
+	{
+		$$ = nodlit($1);
+	}
+|	name
+|	pexpr '.' sym
+	{
+		if($1->op == OPACK) {
+			Sym *s;
+			s = restrictlookup($3->name, $1->pkg);
+			$1->used = 1;
+			$$ = oldname(s);
+			break;
+		}
+		$$ = nod(OXDOT, $1, newname($3));
+	}
+|	pexpr '.' '(' expr_or_type ')'
+	{
+		$$ = nod(ODOTTYPE, $1, $4);
+	}
+|	pexpr '.' '(' LTYPE ')'
+	{
+		$$ = nod(OTYPESW, N, $1);
+	}
+|	pexpr '[' expr ']'
+	{
+		$$ = nod(OINDEX, $1, $3);
+	}
+|	pexpr '[' oexpr ':' oexpr ']'
+	{
+		$$ = nod(OSLICE, $1, nod(OKEY, $3, $5));
+	}
+|	pexpr '[' oexpr ':' oexpr ':' oexpr ']'
+	{
+		if($5 == N)
+			yyerror("middle index required in 3-index slice");
+		if($7 == N)
+			yyerror("final index required in 3-index slice");
+		$$ = nod(OSLICE3, $1, nod(OKEY, $3, nod(OKEY, $5, $7)));
+	}
+|	pseudocall
+|	convtype '(' expr ocomma ')'
+	{
+		// conversion
+		$$ = nod(OCALL, $1, N);
+		$$->list = list1($3);
+	}
+|	comptype lbrace start_complit braced_keyval_list '}'
+	{
+		$$ = $3;
+		$$->right = $1;
+		$$->list = $4;
+		fixlbrace($2);
+	}
+|	pexpr_no_paren '{' start_complit braced_keyval_list '}'
+	{
+		$$ = $3;
+		$$->right = $1;
+		$$->list = $4;
+	}
+|	'(' expr_or_type ')' '{' start_complit braced_keyval_list '}'
+	{
+		yyerror("cannot parenthesize type in composite literal");
+		$$ = $5;
+		$$->right = $2;
+		$$->list = $6;
+	}
+|	fnliteral
+
+start_complit:
+	{
+		// composite expression.
+		// make node early so we get the right line number.
+		$$ = nod(OCOMPLIT, N, N);
+	}
+
+keyval:
+	expr ':' complitexpr
+	{
+		$$ = nod(OKEY, $1, $3);
+	}
+
+bare_complitexpr:
+	expr
+	{
+		// These nodes do not carry line numbers.
+		// Since a composite literal commonly spans several lines,
+		// the line number on errors may be misleading.
+		// Introduce a wrapper node to give the correct line.
+		$$ = $1;
+		switch($$->op) {
+		case ONAME:
+		case ONONAME:
+		case OTYPE:
+		case OPACK:
+		case OLITERAL:
+			$$ = nod(OPAREN, $$, N);
+			$$->implicit = 1;
+		}
+	}
+|	'{' start_complit braced_keyval_list '}'
+	{
+		$$ = $2;
+		$$->list = $3;
+	}
+
+complitexpr:
+	expr
+|	'{' start_complit braced_keyval_list '}'
+	{
+		$$ = $2;
+		$$->list = $3;
+	}
+
+pexpr:
+	pexpr_no_paren
+|	'(' expr_or_type ')'
+	{
+		$$ = $2;
+		
+		// Need to know on lhs of := whether there are ( ).
+		// Don't bother with the OPAREN in other cases:
+		// it's just a waste of memory and time.
+		switch($$->op) {
+		case ONAME:
+		case ONONAME:
+		case OPACK:
+		case OTYPE:
+		case OLITERAL:
+		case OTYPESW:
+			$$ = nod(OPAREN, $$, N);
+		}
+	}
+
+expr_or_type:
+	expr
+|	non_expr_type	%prec PreferToRightParen
+
+name_or_type:
+	ntype
+
+lbrace:
+	LBODY
+	{
+		$$ = LBODY;
+	}
+|	'{'
+	{
+		$$ = '{';
+	}
+
+/*
+ * names and types
+ *	newname is used before declared
+ *	oldname is used after declared
+ */
+new_name:
+	sym
+	{
+		if($1 == S)
+			$$ = N;
+		else
+			$$ = newname($1);
+	}
+
+dcl_name:
+	sym
+	{
+		$$ = dclname($1);
+	}
+
+onew_name:
+	{
+		$$ = N;
+	}
+|	new_name
+
+sym:
+	LNAME
+	{
+		$$ = $1;
+		// during imports, unqualified non-exported identifiers are from builtinpkg
+		if(importpkg != nil && !exportname($1->name))
+			$$ = pkglookup($1->name, builtinpkg);
+	}
+|	hidden_importsym
+|	'?'
+	{
+		$$ = S;
+	}
+
+hidden_importsym:
+	'@' LLITERAL '.' LNAME
+	{
+		Pkg *p;
+
+		if($2.u.sval->len == 0)
+			p = importpkg;
+		else {
+			if(isbadimport($2.u.sval))
+				errorexit();
+			p = mkpkg($2.u.sval);
+		}
+		$$ = pkglookup($4->name, p);
+	}
+|	'@' LLITERAL '.' '?'
+	{
+		Pkg *p;
+
+		if($2.u.sval->len == 0)
+			p = importpkg;
+		else {
+			if(isbadimport($2.u.sval))
+				errorexit();
+			p = mkpkg($2.u.sval);
+		}
+		$$ = pkglookup("?", p);
+	}
+
+name:
+	sym	%prec NotParen
+	{
+		$$ = oldname($1);
+		if($$->pack != N)
+			$$->pack->used = 1;
+	}
+
+labelname:
+	new_name
+
+/*
+ * to avoid parsing conflicts, type is split into
+ *	channel types
+ *	function types
+ *	parenthesized types
+ *	any other type
+ * the type system makes additional restrictions,
+ * but those are not implemented in the grammar.
+ */
+dotdotdot:
+	LDDD
+	{
+		yyerror("final argument in variadic function missing type");
+		$$ = nod(ODDD, typenod(typ(TINTER)), N);
+	}
+|	LDDD ntype
+	{
+		$$ = nod(ODDD, $2, N);
+	}
+
+ntype:
+	recvchantype
+|	fntype
+|	othertype
+|	ptrtype
+|	dotname
+|	'(' ntype ')'
+	{
+		$$ = $2;
+	}
+
+non_expr_type:
+	recvchantype
+|	fntype
+|	othertype
+|	'*' non_expr_type
+	{
+		$$ = nod(OIND, $2, N);
+	}
+
+non_recvchantype:
+	fntype
+|	othertype
+|	ptrtype
+|	dotname
+|	'(' ntype ')'
+	{
+		$$ = $2;
+	}
+
+convtype:
+	fntype
+|	othertype
+
+comptype:
+	othertype
+
+fnret_type:
+	recvchantype
+|	fntype
+|	othertype
+|	ptrtype
+|	dotname
+
+dotname:
+	name
+|	name '.' sym
+	{
+		if($1->op == OPACK) {
+			Sym *s;
+			s = restrictlookup($3->name, $1->pkg);
+			$1->used = 1;
+			$$ = oldname(s);
+			break;
+		}
+		$$ = nod(OXDOT, $1, newname($3));
+	}
+
+othertype:
+	'[' oexpr ']' ntype
+	{
+		$$ = nod(OTARRAY, $2, $4);
+	}
+|	'[' LDDD ']' ntype
+	{
+		// array literal of nelem
+		$$ = nod(OTARRAY, nod(ODDD, N, N), $4);
+	}
+|	LCHAN non_recvchantype
+	{
+		$$ = nod(OTCHAN, $2, N);
+		$$->etype = Cboth;
+	}
+|	LCHAN LCOMM ntype
+	{
+		$$ = nod(OTCHAN, $3, N);
+		$$->etype = Csend;
+	}
+|	LMAP '[' ntype ']' ntype
+	{
+		$$ = nod(OTMAP, $3, $5);
+	}
+|	structtype
+|	interfacetype
+
+ptrtype:
+	'*' ntype
+	{
+		$$ = nod(OIND, $2, N);
+	}
+
+recvchantype:
+	LCOMM LCHAN ntype
+	{
+		$$ = nod(OTCHAN, $3, N);
+		$$->etype = Crecv;
+	}
+
+structtype:
+	LSTRUCT lbrace structdcl_list osemi '}'
+	{
+		$$ = nod(OTSTRUCT, N, N);
+		$$->list = $3;
+		fixlbrace($2);
+	}
+|	LSTRUCT lbrace '}'
+	{
+		$$ = nod(OTSTRUCT, N, N);
+		fixlbrace($2);
+	}
+
+interfacetype:
+	LINTERFACE lbrace interfacedcl_list osemi '}'
+	{
+		$$ = nod(OTINTER, N, N);
+		$$->list = $3;
+		fixlbrace($2);
+	}
+|	LINTERFACE lbrace '}'
+	{
+		$$ = nod(OTINTER, N, N);
+		fixlbrace($2);
+	}
+
+/*
+ * function stuff
+ * all in one place to show how crappy it all is
+ */
+xfndcl:
+	LFUNC fndcl fnbody
+	{
+		$$ = $2;
+		if($$ == N)
+			break;
+		if(noescape && $3 != nil)
+			yyerror("can only use //go:noescape with external func implementations");
+		$$->nbody = $3;
+		$$->endlineno = lineno;
+		$$->noescape = noescape;
+		$$->nosplit = nosplit;
+		funcbody($$);
+	}
+
+fndcl:
+	sym '(' oarg_type_list_ocomma ')' fnres
+	{
+		Node *t;
+
+		$$ = N;
+		$3 = checkarglist($3, 1);
+
+		if(strcmp($1->name, "init") == 0) {
+			$1 = renameinit();
+			if($3 != nil || $5 != nil)
+				yyerror("func init must have no arguments and no return values");
+		}
+		if(strcmp(localpkg->name, "main") == 0 && strcmp($1->name, "main") == 0) {
+			if($3 != nil || $5 != nil)
+				yyerror("func main must have no arguments and no return values");
+		}
+
+		t = nod(OTFUNC, N, N);
+		t->list = $3;
+		t->rlist = $5;
+
+		$$ = nod(ODCLFUNC, N, N);
+		$$->nname = newname($1);
+		$$->nname->defn = $$;
+		$$->nname->ntype = t;		// TODO: check if nname already has an ntype
+		declare($$->nname, PFUNC);
+
+		funchdr($$);
+	}
+|	'(' oarg_type_list_ocomma ')' sym '(' oarg_type_list_ocomma ')' fnres
+	{
+		Node *rcvr, *t;
+
+		$$ = N;
+		$2 = checkarglist($2, 0);
+		$6 = checkarglist($6, 1);
+
+		if($2 == nil) {
+			yyerror("method has no receiver");
+			break;
+		}
+		if($2->next != nil) {
+			yyerror("method has multiple receivers");
+			break;
+		}
+		rcvr = $2->n;
+		if(rcvr->op != ODCLFIELD) {
+			yyerror("bad receiver in method");
+			break;
+		}
+
+		t = nod(OTFUNC, rcvr, N);
+		t->list = $6;
+		t->rlist = $8;
+
+		$$ = nod(ODCLFUNC, N, N);
+		$$->shortname = newname($4);
+		$$->nname = methodname1($$->shortname, rcvr->right);
+		$$->nname->defn = $$;
+		$$->nname->ntype = t;
+		$$->nname->nointerface = nointerface;
+		declare($$->nname, PFUNC);
+
+		funchdr($$);
+	}
+
+hidden_fndcl:
+	hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
+	{
+		Sym *s;
+		Type *t;
+
+		$$ = N;
+
+		s = $1;
+		t = functype(N, $3, $5);
+
+		importsym(s, ONAME);
+		if(s->def != N && s->def->op == ONAME) {
+			if(eqtype(t, s->def->type)) {
+				dclcontext = PDISCARD;  // since we skip funchdr below
+				break;
+			}
+			yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t);
+		}
+
+		$$ = newname(s);
+		$$->type = t;
+		declare($$, PFUNC);
+
+		funchdr($$);
+	}
+|	'(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres
+	{
+		$$ = methodname1(newname($4), $2->n->right); 
+		$$->type = functype($2->n, $6, $8);
+
+		checkwidth($$->type);
+		addmethod($4, $$->type, 0, nointerface);
+		nointerface = 0;
+		funchdr($$);
+		
+		// inl.c's inlnode in on a dotmeth node expects to find the inlineable body as
+		// (dotmeth's type)->nname->inl, and dotmeth's type has been pulled
+		// out by typecheck's lookdot as this $$->ttype.  So by providing
+		// this back link here we avoid special casing there.
+		$$->type->nname = $$;
+	}
+
+fntype:
+	LFUNC '(' oarg_type_list_ocomma ')' fnres
+	{
+		$3 = checkarglist($3, 1);
+		$$ = nod(OTFUNC, N, N);
+		$$->list = $3;
+		$$->rlist = $5;
+	}
+
+fnbody:
+	{
+		$$ = nil;
+	}
+|	'{' stmt_list '}'
+	{
+		$$ = $2;
+		if($$ == nil)
+			$$ = list1(nod(OEMPTY, N, N));
+	}
+
+fnres:
+	%prec NotParen
+	{
+		$$ = nil;
+	}
+|	fnret_type
+	{
+		$$ = list1(nod(ODCLFIELD, N, $1));
+	}
+|	'(' oarg_type_list_ocomma ')'
+	{
+		$2 = checkarglist($2, 0);
+		$$ = $2;
+	}
+
+fnlitdcl:
+	fntype
+	{
+		closurehdr($1);
+	}
+
+fnliteral:
+	fnlitdcl lbrace stmt_list '}'
+	{
+		$$ = closurebody($3);
+		fixlbrace($2);
+	}
+|	fnlitdcl error
+	{
+		$$ = closurebody(nil);
+	}
+
+/*
+ * lists of things
+ * note that they are left recursive
+ * to conserve yacc stack. they need to
+ * be reversed to interpret correctly
+ */
+xdcl_list:
+	{
+		$$ = nil;
+	}
+|	xdcl_list xdcl ';'
+	{
+		$$ = concat($1, $2);
+		if(nsyntaxerrors == 0)
+			testdclstack();
+		nointerface = 0;
+		noescape = 0;
+		nosplit = 0;
+	}
+
+vardcl_list:
+	vardcl
+|	vardcl_list ';' vardcl
+	{
+		$$ = concat($1, $3);
+	}
+
+constdcl_list:
+	constdcl1
+|	constdcl_list ';' constdcl1
+	{
+		$$ = concat($1, $3);
+	}
+
+typedcl_list:
+	typedcl
+	{
+		$$ = list1($1);
+	}
+|	typedcl_list ';' typedcl
+	{
+		$$ = list($1, $3);
+	}
+
+structdcl_list:
+	structdcl
+|	structdcl_list ';' structdcl
+	{
+		$$ = concat($1, $3);
+	}
+
+interfacedcl_list:
+	interfacedcl
+	{
+		$$ = list1($1);
+	}
+|	interfacedcl_list ';' interfacedcl
+	{
+		$$ = list($1, $3);
+	}
+
+structdcl:
+	new_name_list ntype oliteral
+	{
+		NodeList *l;
+
+		Node *n;
+		l = $1;
+		if(l == nil) {
+			// ? symbol, during import (list1(N) == nil)
+			n = $2;
+			if(n->op == OIND)
+				n = n->left;
+			n = embedded(n->sym, importpkg);
+			n->right = $2;
+			n->val = $3;
+			$$ = list1(n);
+			break;
+		}
+
+		for(l=$1; l; l=l->next) {
+			l->n = nod(ODCLFIELD, l->n, $2);
+			l->n->val = $3;
+		}
+	}
+|	embed oliteral
+	{
+		$1->val = $2;
+		$$ = list1($1);
+	}
+|	'(' embed ')' oliteral
+	{
+		$2->val = $4;
+		$$ = list1($2);
+		yyerror("cannot parenthesize embedded type");
+	}
+|	'*' embed oliteral
+	{
+		$2->right = nod(OIND, $2->right, N);
+		$2->val = $3;
+		$$ = list1($2);
+	}
+|	'(' '*' embed ')' oliteral
+	{
+		$3->right = nod(OIND, $3->right, N);
+		$3->val = $5;
+		$$ = list1($3);
+		yyerror("cannot parenthesize embedded type");
+	}
+|	'*' '(' embed ')' oliteral
+	{
+		$3->right = nod(OIND, $3->right, N);
+		$3->val = $5;
+		$$ = list1($3);
+		yyerror("cannot parenthesize embedded type");
+	}
+
+packname:
+	LNAME
+	{
+		Node *n;
+
+		$$ = $1;
+		n = oldname($1);
+		if(n->pack != N)
+			n->pack->used = 1;
+	}
+|	LNAME '.' sym
+	{
+		Pkg *pkg;
+
+		if($1->def == N || $1->def->op != OPACK) {
+			yyerror("%S is not a package", $1);
+			pkg = localpkg;
+		} else {
+			$1->def->used = 1;
+			pkg = $1->def->pkg;
+		}
+		$$ = restrictlookup($3->name, pkg);
+	}
+
+embed:
+	packname
+	{
+		$$ = embedded($1, localpkg);
+	}
+
+interfacedcl:
+	new_name indcl
+	{
+		$$ = nod(ODCLFIELD, $1, $2);
+		ifacedcl($$);
+	}
+|	packname
+	{
+		$$ = nod(ODCLFIELD, N, oldname($1));
+	}
+|	'(' packname ')'
+	{
+		$$ = nod(ODCLFIELD, N, oldname($2));
+		yyerror("cannot parenthesize embedded type");
+	}
+
+indcl:
+	'(' oarg_type_list_ocomma ')' fnres
+	{
+		// without func keyword
+		$2 = checkarglist($2, 1);
+		$$ = nod(OTFUNC, fakethis(), N);
+		$$->list = $2;
+		$$->rlist = $4;
+	}
+
+/*
+ * function arguments.
+ */
+arg_type:
+	name_or_type
+|	sym name_or_type
+	{
+		$$ = nod(ONONAME, N, N);
+		$$->sym = $1;
+		$$ = nod(OKEY, $$, $2);
+	}
+|	sym dotdotdot
+	{
+		$$ = nod(ONONAME, N, N);
+		$$->sym = $1;
+		$$ = nod(OKEY, $$, $2);
+	}
+|	dotdotdot
+
+arg_type_list:
+	arg_type
+	{
+		$$ = list1($1);
+	}
+|	arg_type_list ',' arg_type
+	{
+		$$ = list($1, $3);
+	}
+
+oarg_type_list_ocomma:
+	{
+		$$ = nil;
+	}
+|	arg_type_list ocomma
+	{
+		$$ = $1;
+	}
+
+/*
+ * statement
+ */
+stmt:
+	{
+		$$ = N;
+	}
+|	compound_stmt
+|	common_dcl
+	{
+		$$ = liststmt($1);
+	}
+|	non_dcl_stmt
+|	error
+	{
+		$$ = N;
+	}
+
+non_dcl_stmt:
+	simple_stmt
+|	for_stmt
+|	switch_stmt
+|	select_stmt
+|	if_stmt
+|	labelname ':'
+	{
+		$1 = nod(OLABEL, $1, N);
+		$1->sym = dclstack;  // context, for goto restrictions
+	}
+	stmt
+	{
+		NodeList *l;
+
+		$1->defn = $4;
+		l = list1($1);
+		if($4)
+			l = list(l, $4);
+		$$ = liststmt(l);
+	}
+|	LFALL
+	{
+		// will be converted to OFALL
+		$$ = nod(OXFALL, N, N);
+		$$->xoffset = block;
+	}
+|	LBREAK onew_name
+	{
+		$$ = nod(OBREAK, $2, N);
+	}
+|	LCONTINUE onew_name
+	{
+		$$ = nod(OCONTINUE, $2, N);
+	}
+|	LGO pseudocall
+	{
+		$$ = nod(OPROC, $2, N);
+	}
+|	LDEFER pseudocall
+	{
+		$$ = nod(ODEFER, $2, N);
+	}
+|	LGOTO new_name
+	{
+		$$ = nod(OGOTO, $2, N);
+		$$->sym = dclstack;  // context, for goto restrictions
+	}
+|	LRETURN oexpr_list
+	{
+		$$ = nod(ORETURN, N, N);
+		$$->list = $2;
+		if($$->list == nil && curfn != N) {
+			NodeList *l;
+
+			for(l=curfn->dcl; l; l=l->next) {
+				if(l->n->class == PPARAM)
+					continue;
+				if(l->n->class != PPARAMOUT)
+					break;
+				if(l->n->sym->def != l->n)
+					yyerror("%s is shadowed during return", l->n->sym->name);
+			}
+		}
+	}
+
+stmt_list:
+	stmt
+	{
+		$$ = nil;
+		if($1 != N)
+			$$ = list1($1);
+	}
+|	stmt_list ';' stmt
+	{
+		$$ = $1;
+		if($3 != N)
+			$$ = list($$, $3);
+	}
+
+new_name_list:
+	new_name
+	{
+		$$ = list1($1);
+	}
+|	new_name_list ',' new_name
+	{
+		$$ = list($1, $3);
+	}
+
+dcl_name_list:
+	dcl_name
+	{
+		$$ = list1($1);
+	}
+|	dcl_name_list ',' dcl_name
+	{
+		$$ = list($1, $3);
+	}
+
+expr_list:
+	expr
+	{
+		$$ = list1($1);
+	}
+|	expr_list ',' expr
+	{
+		$$ = list($1, $3);
+	}
+
+expr_or_type_list:
+	expr_or_type
+	{
+		$$ = list1($1);
+	}
+|	expr_or_type_list ',' expr_or_type
+	{
+		$$ = list($1, $3);
+	}
+
+/*
+ * list of combo of keyval and val
+ */
+keyval_list:
+	keyval
+	{
+		$$ = list1($1);
+	}
+|	bare_complitexpr
+	{
+		$$ = list1($1);
+	}
+|	keyval_list ',' keyval
+	{
+		$$ = list($1, $3);
+	}
+|	keyval_list ',' bare_complitexpr
+	{
+		$$ = list($1, $3);
+	}
+
+braced_keyval_list:
+	{
+		$$ = nil;
+	}
+|	keyval_list ocomma
+	{
+		$$ = $1;
+	}
+
+/*
+ * optional things
+ */
+osemi:
+|	';'
+
+ocomma:
+|	','
+
+oexpr:
+	{
+		$$ = N;
+	}
+|	expr
+
+oexpr_list:
+	{
+		$$ = nil;
+	}
+|	expr_list
+
+osimple_stmt:
+	{
+		$$ = N;
+	}
+|	simple_stmt
+
+ohidden_funarg_list:
+	{
+		$$ = nil;
+	}
+|	hidden_funarg_list
+
+ohidden_structdcl_list:
+	{
+		$$ = nil;
+	}
+|	hidden_structdcl_list
+
+ohidden_interfacedcl_list:
+	{
+		$$ = nil;
+	}
+|	hidden_interfacedcl_list
+
+oliteral:
+	{
+		$$.ctype = CTxxx;
+	}
+|	LLITERAL
+
+/*
+ * import syntax from package header
+ */
+hidden_import:
+	LIMPORT LNAME LLITERAL ';'
+	{
+		importimport($2, $3.u.sval);
+	}
+|	LVAR hidden_pkg_importsym hidden_type ';'
+	{
+		importvar($2, $3);
+	}
+|	LCONST hidden_pkg_importsym '=' hidden_constant ';'
+	{
+		importconst($2, types[TIDEAL], $4);
+	}
+|	LCONST hidden_pkg_importsym hidden_type '=' hidden_constant ';'
+	{
+		importconst($2, $3, $5);
+	}
+|	LTYPE hidden_pkgtype hidden_type ';'
+	{
+		importtype($2, $3);
+	}
+|	LFUNC hidden_fndcl fnbody ';'
+	{
+		if($2 == N) {
+			dclcontext = PEXTERN;  // since we skip the funcbody below
+			break;
+		}
+
+		$2->inl = $3;
+
+		funcbody($2);
+		importlist = list(importlist, $2);
+
+		if(debug['E']) {
+			print("import [%Z] func %lN \n", importpkg->path, $2);
+			if(debug['m'] > 2 && $2->inl)
+				print("inl body:%+H\n", $2->inl);
+		}
+	}
+
+hidden_pkg_importsym:
+	hidden_importsym
+	{
+		$$ = $1;
+		structpkg = $$->pkg;
+	}
+
+hidden_pkgtype:
+	hidden_pkg_importsym
+	{
+		$$ = pkgtype($1);
+		importsym($1, OTYPE);
+	}
+
+/*
+ *  importing types
+ */
+
+hidden_type:
+	hidden_type_misc
+|	hidden_type_recv_chan
+|	hidden_type_func
+
+hidden_type_non_recv_chan:
+	hidden_type_misc
+|	hidden_type_func
+
+hidden_type_misc:
+	hidden_importsym
+	{
+		$$ = pkgtype($1);
+	}
+|	LNAME
+	{
+		// predefined name like uint8
+		$1 = pkglookup($1->name, builtinpkg);
+		if($1->def == N || $1->def->op != OTYPE) {
+			yyerror("%s is not a type", $1->name);
+			$$ = T;
+		} else
+			$$ = $1->def->type;
+	}
+|	'[' ']' hidden_type
+	{
+		$$ = aindex(N, $3);
+	}
+|	'[' LLITERAL ']' hidden_type
+	{
+		$$ = aindex(nodlit($2), $4);
+	}
+|	LMAP '[' hidden_type ']' hidden_type
+	{
+		$$ = maptype($3, $5);
+	}
+|	LSTRUCT '{' ohidden_structdcl_list '}'
+	{
+		$$ = tostruct($3);
+	}
+|	LINTERFACE '{' ohidden_interfacedcl_list '}'
+	{
+		$$ = tointerface($3);
+	}
+|	'*' hidden_type
+	{
+		$$ = ptrto($2);
+	}
+|	LCHAN hidden_type_non_recv_chan
+	{
+		$$ = typ(TCHAN);
+		$$->type = $2;
+		$$->chan = Cboth;
+	}
+|	LCHAN '(' hidden_type_recv_chan ')'
+	{
+		$$ = typ(TCHAN);
+		$$->type = $3;
+		$$->chan = Cboth;
+	}
+|	LCHAN LCOMM hidden_type
+	{
+		$$ = typ(TCHAN);
+		$$->type = $3;
+		$$->chan = Csend;
+	}
+
+hidden_type_recv_chan:
+	LCOMM LCHAN hidden_type
+	{
+		$$ = typ(TCHAN);
+		$$->type = $3;
+		$$->chan = Crecv;
+	}
+
+hidden_type_func:
+	LFUNC '(' ohidden_funarg_list ')' ohidden_funres
+	{
+		$$ = functype(nil, $3, $5);
+	}
+
+hidden_funarg:
+	sym hidden_type oliteral
+	{
+		$$ = nod(ODCLFIELD, N, typenod($2));
+		if($1)
+			$$->left = newname($1);
+		$$->val = $3;
+	}
+|	sym LDDD hidden_type oliteral
+	{
+		Type *t;
+	
+		t = typ(TARRAY);
+		t->bound = -1;
+		t->type = $3;
+
+		$$ = nod(ODCLFIELD, N, typenod(t));
+		if($1)
+			$$->left = newname($1);
+		$$->isddd = 1;
+		$$->val = $4;
+	}
+
+hidden_structdcl:
+	sym hidden_type oliteral
+	{
+		Sym *s;
+		Pkg *p;
+
+		if($1 != S && strcmp($1->name, "?") != 0) {
+			$$ = nod(ODCLFIELD, newname($1), typenod($2));
+			$$->val = $3;
+		} else {
+			s = $2->sym;
+			if(s == S && isptr[$2->etype])
+				s = $2->type->sym;
+			p = importpkg;
+			if($1 != S)
+				p = $1->pkg;
+			$$ = embedded(s, p);
+			$$->right = typenod($2);
+			$$->val = $3;
+		}
+	}
+
+hidden_interfacedcl:
+	sym '(' ohidden_funarg_list ')' ohidden_funres
+	{
+		$$ = nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
+	}
+|	hidden_type
+	{
+		$$ = nod(ODCLFIELD, N, typenod($1));
+	}
+
+ohidden_funres:
+	{
+		$$ = nil;
+	}
+|	hidden_funres
+
+hidden_funres:
+	'(' ohidden_funarg_list ')'
+	{
+		$$ = $2;
+	}
+|	hidden_type
+	{
+		$$ = list1(nod(ODCLFIELD, N, typenod($1)));
+	}
+
+/*
+ *  importing constants
+ */
+
+hidden_literal:
+	LLITERAL
+	{
+		$$ = nodlit($1);
+	}
+|	'-' LLITERAL
+	{
+		$$ = nodlit($2);
+		switch($$->val.ctype){
+		case CTINT:
+		case CTRUNE:
+			mpnegfix($$->val.u.xval);
+			break;
+		case CTFLT:
+			mpnegflt($$->val.u.fval);
+			break;
+		case CTCPLX:
+			mpnegflt(&$$->val.u.cval->real);
+			mpnegflt(&$$->val.u.cval->imag);
+			break;
+		default:
+			yyerror("bad negated constant");
+		}
+	}
+|	sym
+	{
+		$$ = oldname(pkglookup($1->name, builtinpkg));
+		if($$->op != OLITERAL)
+			yyerror("bad constant %S", $$->sym);
+	}
+
+hidden_constant:
+	hidden_literal
+|	'(' hidden_literal '+' hidden_literal ')'
+	{
+		if($2->val.ctype == CTRUNE && $4->val.ctype == CTINT) {
+			$$ = $2;
+			mpaddfixfix($2->val.u.xval, $4->val.u.xval, 0);
+			break;
+		}
+		$4->val.u.cval->real = $4->val.u.cval->imag;
+		mpmovecflt(&$4->val.u.cval->imag, 0.0);
+		$$ = nodcplxlit($2->val, $4->val);
+	}
+
+hidden_import_list:
+|	hidden_import_list hidden_import
+
+hidden_funarg_list:
+	hidden_funarg
+	{
+		$$ = list1($1);
+	}
+|	hidden_funarg_list ',' hidden_funarg
+	{
+		$$ = list($1, $3);
+	}
+
+hidden_structdcl_list:
+	hidden_structdcl
+	{
+		$$ = list1($1);
+	}
+|	hidden_structdcl_list ';' hidden_structdcl
+	{
+		$$ = list($1, $3);
+	}
+
+hidden_interfacedcl_list:
+	hidden_interfacedcl
+	{
+		$$ = list1($1);
+	}
+|	hidden_interfacedcl_list ';' hidden_interfacedcl
+	{
+		$$ = list($1, $3);
+	}
+
+%%
+
+static void
+fixlbrace(int lbr)
+{
+	// If the opening brace was an LBODY,
+	// set up for another one now that we're done.
+	// See comment in lex.c about loophack.
+	if(lbr == LBODY)
+		loophack = 1;
+}
+
diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c
new file mode 100644
index 0000000..918d371
--- /dev/null
+++ b/src/cmd/gc/init.c
@@ -0,0 +1,195 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+/*
+ * a function named init is a special case.
+ * it is called by the initialization before
+ * main is run. to make it unique within a
+ * package and also uncallable, the name,
+ * normally "pkg.init", is altered to "pkg.init·1".
+ */
+Sym*
+renameinit(void)
+{
+	static int initgen;
+
+	snprint(namebuf, sizeof(namebuf), "init·%d", ++initgen);
+	return lookup(namebuf);
+}
+
+/*
+ * hand-craft the following initialization code
+ *	var initdone· uint8 				(1)
+ *	func init()					(2)
+ *		if initdone· != 0 {			(3)
+ *			if initdone· == 2		(4)
+ *				return
+ *			throw();			(5)
+ *		}
+ *		initdone· = 1;				(6)
+ *		// over all matching imported symbols
+ *			<pkg>.init()			(7)
+ *		{ <init stmts> }			(8)
+ *		init·<n>() // if any			(9)
+ *		initdone· = 2;				(10)
+ *		return					(11)
+ *	}
+ */
+static int
+anyinit(NodeList *n)
+{
+	uint32 h;
+	Sym *s;
+	NodeList *l;
+
+	// are there any interesting init statements
+	for(l=n; l; l=l->next) {
+		switch(l->n->op) {
+		case ODCLFUNC:
+		case ODCLCONST:
+		case ODCLTYPE:
+		case OEMPTY:
+			break;
+		case OAS:
+			if(isblank(l->n->left) && candiscard(l->n->right))
+				break;
+			// fall through
+		default:
+			return 1;
+		}
+	}
+
+	// is this main
+	if(strcmp(localpkg->name, "main") == 0)
+		return 1;
+
+	// is there an explicit init function
+	snprint(namebuf, sizeof(namebuf), "init·1");
+	s = lookup(namebuf);
+	if(s->def != N)
+		return 1;
+
+	// are there any imported init functions
+	for(h=0; h<NHASH; h++)
+	for(s = hash[h]; s != S; s = s->link) {
+		if(s->name[0] != 'i' || strcmp(s->name, "init") != 0)
+			continue;
+		if(s->def == N)
+			continue;
+		return 1;
+	}
+
+	// then none
+	return 0;
+}
+
+void
+fninit(NodeList *n)
+{
+	int i;
+	Node *gatevar;
+	Node *a, *b, *fn;
+	NodeList *r;
+	uint32 h;
+	Sym *s, *initsym;
+
+	if(debug['A']) {
+		// sys.go or unsafe.go during compiler build
+		return;
+	}
+
+	n = initfix(n);
+	if(!anyinit(n))
+		return;
+
+	r = nil;
+
+	// (1)
+	snprint(namebuf, sizeof(namebuf), "initdone·");
+	gatevar = newname(lookup(namebuf));
+	addvar(gatevar, types[TUINT8], PEXTERN);
+
+	// (2)
+	maxarg = 0;
+	snprint(namebuf, sizeof(namebuf), "init");
+
+	fn = nod(ODCLFUNC, N, N);
+	initsym = lookup(namebuf);
+	fn->nname = newname(initsym);
+	fn->nname->defn = fn;
+	fn->nname->ntype = nod(OTFUNC, N, N);
+	declare(fn->nname, PFUNC);
+	funchdr(fn);
+
+	// (3)
+	a = nod(OIF, N, N);
+	a->ntest = nod(ONE, gatevar, nodintconst(0));
+	r = list(r, a);
+
+	// (4)
+	b = nod(OIF, N, N);
+	b->ntest = nod(OEQ, gatevar, nodintconst(2));
+	b->nbody = list1(nod(ORETURN, N, N));
+	a->nbody = list1(b);
+
+	// (5)
+	b = syslook("throwinit", 0);
+	b = nod(OCALL, b, N);
+	a->nbody = list(a->nbody, b);
+
+	// (6)
+	a = nod(OAS, gatevar, nodintconst(1));
+	r = list(r, a);
+
+	// (7)
+	for(h=0; h<NHASH; h++)
+	for(s = hash[h]; s != S; s = s->link) {
+		if(s->name[0] != 'i' || strcmp(s->name, "init") != 0)
+			continue;
+		if(s->def == N)
+			continue;
+		if(s == initsym)
+			continue;
+
+		// could check that it is fn of no args/returns
+		a = nod(OCALL, s->def, N);
+		r = list(r, a);
+	}
+
+	// (8)
+	r = concat(r, n);
+
+	// (9)
+	// could check that it is fn of no args/returns
+	for(i=1;; i++) {
+		snprint(namebuf, sizeof(namebuf), "init·%d", i);
+		s = lookup(namebuf);
+		if(s->def == N)
+			break;
+		a = nod(OCALL, s->def, N);
+		r = list(r, a);
+	}
+
+	// (10)
+	a = nod(OAS, gatevar, nodintconst(2));
+	r = list(r, a);
+
+	// (11)
+	a = nod(ORETURN, N, N);
+	r = list(r, a);
+	exportsym(fn->nname);
+
+	fn->nbody = r;
+	funcbody(fn);
+
+	curfn = fn;
+	typecheck(&fn, Etop);
+	typechecklist(r, Etop);
+	curfn = nil;
+	funccompile(fn, 0);
+}
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
new file mode 100644
index 0000000..45e15bb
--- /dev/null
+++ b/src/cmd/gc/inl.c
@@ -0,0 +1,986 @@
+// Copyright 2011 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.
+//
+// The inlining facility makes 2 passes: first caninl determines which
+// functions are suitable for inlining, and for those that are it
+// saves a copy of the body. Then inlcalls walks each function body to
+// expand calls to inlinable functions.
+//
+// The debug['l'] flag controls the agressiveness. Note that main() swaps level 0 and 1,
+// making 1 the default and -l disable.  -ll and more is useful to flush out bugs.
+// These additional levels (beyond -l) may be buggy and are not supported.
+//      0: disabled
+//      1: 40-nodes leaf functions, oneliners, lazy typechecking (default)
+//      2: early typechecking of all imported bodies 
+//      3: allow variadic functions
+//      4: allow non-leaf functions , (breaks runtime.Caller)
+//      5: transitive inlining
+//
+//  At some point this may get another default and become switch-offable with -N.
+//
+//  The debug['m'] flag enables diagnostic output.  a single -m is useful for verifying
+//  which calls get inlined or not, more is for debugging, and may go away at any point.
+//
+// TODO:
+//   - inline functions with ... args
+//   - handle T.meth(f()) with func f() (t T, arg, arg, )
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+// Used by caninl.
+static Node*	inlcopy(Node *n);
+static NodeList* inlcopylist(NodeList *ll);
+static int	ishairy(Node *n, int *budget);
+static int	ishairylist(NodeList *ll, int *budget); 
+
+// Used by inlcalls
+static void	inlnodelist(NodeList *l);
+static void	inlnode(Node **np);
+static void	mkinlcall(Node **np, Node *fn, int isddd);
+static Node*	inlvar(Node *n);
+static Node*	retvar(Type *n, int i);
+static Node*	argvar(Type *n, int i);
+static Node*	newlabel(void);
+static Node*	inlsubst(Node *n);
+static NodeList* inlsubstlist(NodeList *l);
+
+static void	setlno(Node*, int);
+
+// Used during inlsubst[list]
+static Node *inlfn;		// function currently being inlined
+static Node *inlretlabel;	// target of the goto substituted in place of a return
+static NodeList *inlretvars;	// temp out variables
+
+// Get the function's package.  For ordinary functions it's on the ->sym, but for imported methods
+// the ->sym can be re-used in the local package, so peel it off the receiver's type.
+static Pkg*
+fnpkg(Node *fn)
+{
+	Type *rcvr;
+	
+	if(fn->type->thistuple) {
+		// method
+		rcvr = getthisx(fn->type)->type->type;
+		if(isptr[rcvr->etype])
+			rcvr = rcvr->type;
+		if(!rcvr->sym)
+			fatal("receiver with no sym: [%S] %lN  (%T)", fn->sym, fn, rcvr);
+		return rcvr->sym->pkg;
+	}
+	// non-method
+	return fn->sym->pkg;
+}
+
+// Lazy typechecking of imported bodies.  For local functions, caninl will set ->typecheck
+// because they're a copy of an already checked body. 
+void
+typecheckinl(Node *fn)
+{
+	Node *savefn;
+	Pkg *pkg;
+	int save_safemode, lno;
+
+	lno = setlineno(fn);
+
+	// typecheckinl is only for imported functions;
+	// their bodies may refer to unsafe as long as the package
+	// was marked safe during import (which was checked then).
+	// the ->inl of a local function has been typechecked before caninl copied it.
+	pkg = fnpkg(fn);
+	if (pkg == localpkg || pkg == nil)
+		return; // typecheckinl on local function
+
+	if (debug['m']>2)
+		print("typecheck import [%S] %lN { %#H }\n", fn->sym, fn, fn->inl);
+
+	save_safemode = safemode;
+	safemode = 0;
+
+	savefn = curfn;
+	curfn = fn;
+	typechecklist(fn->inl, Etop);
+	curfn = savefn;
+
+	safemode = save_safemode;
+
+	lineno = lno;
+}
+
+// Caninl determines whether fn is inlineable.
+// If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy.
+// fn and ->nbody will already have been typechecked.
+void
+caninl(Node *fn)
+{
+	Node *savefn;
+	Type *t;
+	int budget;
+
+	if(fn->op != ODCLFUNC)
+		fatal("caninl %N", fn);
+	if(!fn->nname)
+		fatal("caninl no nname %+N", fn);
+
+	// If fn has no body (is defined outside of Go), cannot inline it.
+	if(fn->nbody == nil)
+		return;
+
+	if(fn->typecheck == 0)
+		fatal("caninl on non-typechecked function %N", fn);
+
+	// can't handle ... args yet
+	if(debug['l'] < 3)
+		for(t=fn->type->type->down->down->type; t; t=t->down)
+			if(t->isddd)
+				return;
+
+	budget = 40;  // allowed hairyness
+	if(ishairylist(fn->nbody, &budget))
+		return;
+
+	savefn = curfn;
+	curfn = fn;
+
+	fn->nname->inl = fn->nbody;
+	fn->nbody = inlcopylist(fn->nname->inl);
+	fn->nname->inldcl = inlcopylist(fn->nname->defn->dcl);
+
+	// hack, TODO, check for better way to link method nodes back to the thing with the ->inl
+	// this is so export can find the body of a method
+	fn->type->nname = fn->nname;
+
+	if(debug['m'] > 1)
+		print("%L: can inline %#N as: %#T { %#H }\n", fn->lineno, fn->nname, fn->type, fn->nname->inl);
+	else if(debug['m'])
+		print("%L: can inline %N\n", fn->lineno, fn->nname);
+
+	curfn = savefn;
+}
+
+// Look for anything we want to punt on.
+static int
+ishairylist(NodeList *ll, int* budget)
+{
+	for(;ll;ll=ll->next)
+		if(ishairy(ll->n, budget))
+			return 1;
+	return 0;
+}
+
+static int
+ishairy(Node *n, int *budget)
+{
+	if(!n)
+		return 0;
+
+	// Things that are too hairy, irrespective of the budget
+	switch(n->op) {
+	case OCALL:
+	case OCALLFUNC:
+	case OCALLINTER:
+	case OCALLMETH:
+	case OPANIC:
+	case ORECOVER:
+		if(debug['l'] < 4)
+			return 1;
+		break;
+
+	case OCLOSURE:
+	case OCALLPART:
+	case ORANGE:
+	case OFOR:
+	case OSELECT:
+	case OSWITCH:
+	case OPROC:
+	case ODEFER:
+	case ODCLTYPE:  // can't print yet
+	case ODCLCONST:  // can't print yet
+	case ORETJMP:
+		return 1;
+
+		break;
+	}
+
+	(*budget)--;
+
+	return  *budget < 0 ||
+		ishairy(n->left, budget) ||
+		ishairy(n->right, budget) ||
+		ishairylist(n->list, budget) ||
+		ishairylist(n->rlist, budget) ||
+		ishairylist(n->ninit, budget) ||
+		ishairy(n->ntest, budget) ||
+		ishairy(n->nincr, budget) ||
+		ishairylist(n->nbody, budget) ||
+		ishairylist(n->nelse, budget);
+}
+
+// Inlcopy and inlcopylist recursively copy the body of a function.
+// Any name-like node of non-local class is marked for re-export by adding it to
+// the exportlist.
+static NodeList*
+inlcopylist(NodeList *ll)
+{
+	NodeList *l;
+
+	l = nil;
+	for(; ll; ll=ll->next)
+		l = list(l, inlcopy(ll->n));
+	return l;
+}
+
+static Node*
+inlcopy(Node *n)
+{
+	Node *m;
+
+	if(n == N)
+		return N;
+
+	switch(n->op) {
+	case ONAME:
+	case OTYPE:
+	case OLITERAL:
+		return n;
+	}
+
+	m = nod(OXXX, N, N);
+	*m = *n;
+	m->inl = nil;
+	m->left	  = inlcopy(n->left);
+	m->right  = inlcopy(n->right);
+	m->list   = inlcopylist(n->list);
+	m->rlist  = inlcopylist(n->rlist);
+	m->ninit  = inlcopylist(n->ninit);
+	m->ntest  = inlcopy(n->ntest);
+	m->nincr  = inlcopy(n->nincr);
+	m->nbody  = inlcopylist(n->nbody);
+	m->nelse  = inlcopylist(n->nelse);
+
+	return m;
+}
+
+
+// Inlcalls/nodelist/node walks fn's statements and expressions and substitutes any
+// calls made to inlineable functions.  This is the external entry point.
+void
+inlcalls(Node *fn)
+{
+	Node *savefn;
+
+	savefn = curfn;
+	curfn = fn;
+	inlnode(&fn);
+	if(fn != curfn)
+		fatal("inlnode replaced curfn");
+	curfn = savefn;
+}
+
+// Turn an OINLCALL into a statement.
+static void
+inlconv2stmt(Node *n)
+{
+	n->op = OBLOCK;
+	// n->ninit stays
+	n->list = n->nbody;
+	n->nbody = nil;
+	n->rlist = nil;
+}
+
+// Turn an OINLCALL into a single valued expression.
+static void
+inlconv2expr(Node **np)
+{
+	Node *n, *r;
+	n = *np;
+	r = n->rlist->n;
+	addinit(&r, concat(n->ninit, n->nbody));
+	*np = r;
+}
+
+// Turn the rlist (with the return values) of the OINLCALL in
+// n into an expression list lumping the ninit and body
+// containing the inlined statements on the first list element so
+// order will be preserved Used in return, oas2func and call
+// statements.
+static NodeList*
+inlconv2list(Node *n)
+{
+	NodeList *l;
+
+	if(n->op != OINLCALL || n->rlist == nil)
+		fatal("inlconv2list %+N\n", n);
+	
+	l = n->rlist;
+	addinit(&l->n, concat(n->ninit, n->nbody));
+	return l;
+} 
+ 
+static void
+inlnodelist(NodeList *l)
+{
+	for(; l; l=l->next)
+		inlnode(&l->n);
+}
+
+// inlnode recurses over the tree to find inlineable calls, which will
+// be turned into OINLCALLs by mkinlcall.  When the recursion comes
+// back up will examine left, right, list, rlist, ninit, ntest, nincr,
+// nbody and nelse and use one of the 4 inlconv/glue functions above
+// to turn the OINLCALL into an expression, a statement, or patch it
+// in to this nodes list or rlist as appropriate.
+// NOTE it makes no sense to pass the glue functions down the
+// recursion to the level where the OINLCALL gets created because they
+// have to edit /this/ n, so you'd have to push that one down as well,
+// but then you may as well do it here.  so this is cleaner and
+// shorter and less complicated.
+static void
+inlnode(Node **np)
+{
+	Node *n;
+	NodeList *l;
+	int lno;
+
+	if(*np == nil)
+		return;
+
+	n = *np;
+	
+	switch(n->op) {
+	case ODEFER:
+	case OPROC:
+		// inhibit inlining of their argument
+		switch(n->left->op) {
+		case OCALLFUNC:
+		case OCALLMETH:
+			n->left->etype = n->op;
+		}
+
+	case OCLOSURE:
+		// TODO do them here (or earlier),
+		// so escape analysis can avoid more heapmoves.
+		return;
+	}
+
+	lno = setlineno(n);
+
+	inlnodelist(n->ninit);
+	for(l=n->ninit; l; l=l->next)
+		if(l->n->op == OINLCALL)
+			inlconv2stmt(l->n);
+
+	inlnode(&n->left);
+	if(n->left && n->left->op == OINLCALL)
+		inlconv2expr(&n->left);
+
+	inlnode(&n->right);
+	if(n->right && n->right->op == OINLCALL)
+		inlconv2expr(&n->right);
+
+	inlnodelist(n->list);
+	switch(n->op) {
+	case OBLOCK:
+		for(l=n->list; l; l=l->next)
+			if(l->n->op == OINLCALL)
+				inlconv2stmt(l->n);
+		break;
+
+	case ORETURN:
+	case OCALLFUNC:
+	case OCALLMETH:
+	case OCALLINTER:
+	case OAPPEND:
+	case OCOMPLEX:
+		// if we just replaced arg in f(arg()) or return arg with an inlined call
+		// and arg returns multiple values, glue as list
+		if(count(n->list) == 1 && n->list->n->op == OINLCALL && count(n->list->n->rlist) > 1) {
+			n->list = inlconv2list(n->list->n);
+			break;
+		}
+
+		// fallthrough
+	default:
+		for(l=n->list; l; l=l->next)
+			if(l->n->op == OINLCALL)
+				inlconv2expr(&l->n);
+	}
+
+	inlnodelist(n->rlist);
+	switch(n->op) {
+	case OAS2FUNC:
+		if(n->rlist->n->op == OINLCALL) {
+			n->rlist = inlconv2list(n->rlist->n);
+			n->op = OAS2;
+			n->typecheck = 0;
+			typecheck(np, Etop);
+			break;
+		}
+
+		// fallthrough
+	default:
+		for(l=n->rlist; l; l=l->next)
+			if(l->n->op == OINLCALL)
+				inlconv2expr(&l->n);
+
+	}
+
+	inlnode(&n->ntest);
+	if(n->ntest && n->ntest->op == OINLCALL)
+		inlconv2expr(&n->ntest);
+
+	inlnode(&n->nincr);
+	if(n->nincr && n->nincr->op == OINLCALL)
+		inlconv2stmt(n->nincr);
+
+	inlnodelist(n->nbody);
+	for(l=n->nbody; l; l=l->next)
+		if(l->n->op == OINLCALL)
+			inlconv2stmt(l->n);
+
+	inlnodelist(n->nelse);
+	for(l=n->nelse; l; l=l->next)
+		if(l->n->op == OINLCALL)
+			inlconv2stmt(l->n);
+
+	// with all the branches out of the way, it is now time to
+	// transmogrify this node itself unless inhibited by the
+	// switch at the top of this function.
+	switch(n->op) {
+	case OCALLFUNC:
+	case OCALLMETH:
+		if (n->etype == OPROC || n->etype == ODEFER)
+			return;
+	}
+
+	switch(n->op) {
+	case OCALLFUNC:
+		if(debug['m']>3)
+			print("%L:call to func %+N\n", n->lineno, n->left);
+		if(n->left->inl)	// normal case
+			mkinlcall(np, n->left, n->isddd);
+		else if(n->left->op == ONAME && n->left->left && n->left->left->op == OTYPE && n->left->right &&  n->left->right->op == ONAME)  // methods called as functions
+			if(n->left->sym->def)
+				mkinlcall(np, n->left->sym->def, n->isddd);
+		break;
+
+	case OCALLMETH:
+		if(debug['m']>3)
+			print("%L:call to meth %lN\n", n->lineno, n->left->right);
+		// typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
+		if(n->left->type == T) 
+			fatal("no function type for [%p] %+N\n", n->left, n->left);
+
+		if(n->left->type->nname == N) 
+			fatal("no function definition for [%p] %+T\n", n->left->type, n->left->type);
+
+		mkinlcall(np, n->left->type->nname, n->isddd);
+
+		break;
+	}
+	
+	lineno = lno;
+}
+
+static void	mkinlcall1(Node **np, Node *fn, int isddd);
+
+static void
+mkinlcall(Node **np, Node *fn, int isddd)
+{
+	int save_safemode;
+	Pkg *pkg;
+
+	save_safemode = safemode;
+
+	// imported functions may refer to unsafe as long as the
+	// package was marked safe during import (already checked).
+	pkg = fnpkg(fn);
+	if(pkg != localpkg && pkg != nil)
+		safemode = 0;
+	mkinlcall1(np, fn, isddd);
+	safemode = save_safemode;
+}
+
+static Node*
+tinlvar(Type *t)
+{
+	if(t->nname && !isblank(t->nname)) {
+		if(!t->nname->inlvar)
+			fatal("missing inlvar for %N\n", t->nname);
+		return t->nname->inlvar;
+	}
+	typecheck(&nblank, Erv | Easgn);
+	return nblank;
+}
+
+static int inlgen;
+
+// if *np is a call, and fn is a function with an inlinable body, substitute *np with an OINLCALL.
+// On return ninit has the parameter assignments, the nbody is the
+// inlined function body and list, rlist contain the input, output
+// parameters.
+static void
+mkinlcall1(Node **np, Node *fn, int isddd)
+{
+	int i;
+	int chkargcount;
+	Node *n, *call, *saveinlfn, *as, *m;
+	NodeList *dcl, *ll, *ninit, *body;
+	Type *t;
+	// For variadic fn.
+	int variadic, varargcount, multiret;
+	Node *vararg;
+	NodeList *varargs;
+	Type *varargtype, *vararrtype;
+
+	if (fn->inl == nil)
+		return;
+
+	if (fn == curfn || fn->defn == curfn)
+		return;
+
+	if(debug['l']<2)
+		typecheckinl(fn);
+
+	n = *np;
+
+	// Bingo, we have a function node, and it has an inlineable body
+	if(debug['m']>1)
+		print("%L: inlining call to %S %#T { %#H }\n", n->lineno, fn->sym, fn->type, fn->inl);
+	else if(debug['m'])
+		print("%L: inlining call to %N\n", n->lineno, fn);
+
+	if(debug['m']>2)
+		print("%L: Before inlining: %+N\n", n->lineno, n);
+
+	saveinlfn = inlfn;
+	inlfn = fn;
+
+	ninit = n->ninit;
+
+//dumplist("ninit pre", ninit);
+
+	if(fn->defn) // local function
+		dcl = fn->inldcl;
+	else // imported function
+		dcl = fn->dcl;
+
+	inlretvars = nil;
+	i = 0;
+	// Make temp names to use instead of the originals
+	for(ll = dcl; ll; ll=ll->next) {
+		if(ll->n->class == PPARAMOUT)  // return values handled below.
+			continue;
+		if(ll->n->op == ONAME) {
+			ll->n->inlvar = inlvar(ll->n);
+			// Typecheck because inlvar is not necessarily a function parameter.
+			typecheck(&ll->n->inlvar, Erv);
+			if ((ll->n->class&~PHEAP) != PAUTO)
+				ninit = list(ninit, nod(ODCL, ll->n->inlvar, N));  // otherwise gen won't emit the allocations for heapallocs
+		}
+	}
+
+	// temporaries for return values.
+	for(t = getoutargx(fn->type)->type; t; t = t->down) {
+		if(t != T && t->nname != N && !isblank(t->nname)) {
+			m = inlvar(t->nname);
+			typecheck(&m, Erv);
+			t->nname->inlvar = m;
+		} else {
+			// anonymous return values, synthesize names for use in assignment that replaces return
+			m = retvar(t, i++);
+		}
+		ninit = list(ninit, nod(ODCL, m, N));
+		inlretvars = list(inlretvars, m);
+	}
+
+	// assign receiver.
+	if(fn->type->thistuple && n->left->op == ODOTMETH) {
+		// method call with a receiver.
+		t = getthisx(fn->type)->type;
+		if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar)
+			fatal("missing inlvar for %N\n", t->nname);
+		if(!n->left->left)
+			fatal("method call without receiver: %+N", n);
+		if(t == T)
+			fatal("method call unknown receiver type: %+N", n);
+		as = nod(OAS, tinlvar(t), n->left->left);
+		if(as != N) {
+			typecheck(&as, Etop);
+			ninit = list(ninit, as);
+		}
+	}
+
+	// check if inlined function is variadic.
+	variadic = 0;
+	varargtype = T;
+	varargcount = 0;
+	for(t=fn->type->type->down->down->type; t; t=t->down) {
+		if(t->isddd) {
+			variadic = 1;
+			varargtype = t->type;
+		}
+	}
+	// but if argument is dotted too forget about variadicity.
+	if(variadic && isddd)
+		variadic = 0;
+
+	// check if argument is actually a returned tuple from call.
+	multiret = 0;
+	if(n->list && !n->list->next) {
+		switch(n->list->n->op) {
+		case OCALL:
+		case OCALLFUNC:
+		case OCALLINTER:
+		case OCALLMETH:
+			if(n->list->n->left->type->outtuple > 1)
+				multiret = n->list->n->left->type->outtuple-1;
+		}
+	}
+
+	if(variadic) {
+		varargcount = count(n->list) + multiret;
+		if(n->left->op != ODOTMETH)
+			varargcount -= fn->type->thistuple;
+		varargcount -= fn->type->intuple - 1;
+	}
+
+	// assign arguments to the parameters' temp names
+	as = nod(OAS2, N, N);
+	as->rlist = n->list;
+	ll = n->list;
+
+	// TODO: if len(nlist) == 1 but multiple args, check that n->list->n is a call?
+	if(fn->type->thistuple && n->left->op != ODOTMETH) {
+		// non-method call to method
+		if(!n->list)
+			fatal("non-method call to method without first arg: %+N", n);
+		// append receiver inlvar to LHS.
+		t = getthisx(fn->type)->type;
+		if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar)
+			fatal("missing inlvar for %N\n", t->nname);
+		if(t == T)
+			fatal("method call unknown receiver type: %+N", n);
+		as->list = list(as->list, tinlvar(t));
+		ll = ll->next; // track argument count.
+	}
+
+	// append ordinary arguments to LHS.
+	chkargcount = n->list && n->list->next;
+	vararg = N;    // the slice argument to a variadic call
+	varargs = nil; // the list of LHS names to put in vararg.
+	if(!chkargcount) {
+		// 0 or 1 expression on RHS.
+		for(t = getinargx(fn->type)->type; t; t=t->down) {
+			if(variadic && t->isddd) {
+				vararg = tinlvar(t);
+				for(i=0; i<varargcount && ll; i++) {
+					m = argvar(varargtype, i);
+					varargs = list(varargs, m);
+					as->list = list(as->list, m);
+				}
+				break;
+			}
+			as->list = list(as->list, tinlvar(t));
+		}
+	} else {
+		// match arguments except final variadic (unless the call is dotted itself)
+		for(t = getinargx(fn->type)->type; t;) {
+			if(!ll)
+				break;
+			if(variadic && t->isddd)
+				break;
+			as->list = list(as->list, tinlvar(t));
+			t=t->down;
+			ll=ll->next;
+		}
+		// match varargcount arguments with variadic parameters.
+		if(variadic && t && t->isddd) {
+			vararg = tinlvar(t);
+			for(i=0; i<varargcount && ll; i++) {
+				m = argvar(varargtype, i);
+				varargs = list(varargs, m);
+				as->list = list(as->list, m);
+				ll=ll->next;
+			}
+			if(i==varargcount)
+				t=t->down;
+		}
+		if(ll || t)
+			fatal("arg count mismatch: %#T  vs %,H\n",  getinargx(fn->type), n->list);
+	}
+
+	if (as->rlist) {
+		typecheck(&as, Etop);
+		ninit = list(ninit, as);
+	}
+
+	// turn the variadic args into a slice.
+	if(variadic) {
+		as = nod(OAS, vararg, N);
+		if(!varargcount) {
+			as->right = nodnil();
+			as->right->type = varargtype;
+		} else {
+			vararrtype = typ(TARRAY);
+			vararrtype->type = varargtype->type;
+			vararrtype->bound = varargcount;
+
+			as->right = nod(OCOMPLIT, N, typenod(varargtype));
+			as->right->list = varargs;
+			as->right = nod(OSLICE, as->right, nod(OKEY, N, N));
+		}
+		typecheck(&as, Etop);
+		ninit = list(ninit, as);
+	}
+
+	// zero the outparams
+	for(ll = inlretvars; ll; ll=ll->next) {
+		as = nod(OAS, ll->n, N);
+		typecheck(&as, Etop);
+		ninit = list(ninit, as);
+	}
+
+	inlretlabel = newlabel();
+	inlgen++;
+	body = inlsubstlist(fn->inl);
+
+	body = list(body, nod(OGOTO, inlretlabel, N));	// avoid 'not used' when function doesnt have return
+	body = list(body, nod(OLABEL, inlretlabel, N));
+
+	typechecklist(body, Etop);
+//dumplist("ninit post", ninit);
+
+	call = nod(OINLCALL, N, N);
+	call->ninit = ninit;
+	call->nbody = body;
+	call->rlist = inlretvars;
+	call->type = n->type;
+	call->typecheck = 1;
+
+	setlno(call, n->lineno);
+//dumplist("call body", body);
+
+	*np = call;
+
+	inlfn =	saveinlfn;
+
+	// transitive inlining
+	// TODO do this pre-expansion on fn->inl directly.  requires
+	// either supporting exporting statemetns with complex ninits
+	// or saving inl and making inlinl
+	if(debug['l'] >= 5) {
+		body = fn->inl;
+		fn->inl = nil;	// prevent infinite recursion
+		inlnodelist(call->nbody);
+		for(ll=call->nbody; ll; ll=ll->next)
+			if(ll->n->op == OINLCALL)
+				inlconv2stmt(ll->n);
+		fn->inl = body;
+	}
+
+	if(debug['m']>2)
+		print("%L: After inlining %+N\n\n", n->lineno, *np);
+
+}
+
+// Every time we expand a function we generate a new set of tmpnames,
+// PAUTO's in the calling functions, and link them off of the
+// PPARAM's, PAUTOS and PPARAMOUTs of the called function. 
+static Node*
+inlvar(Node *var)
+{
+	Node *n;
+
+	if(debug['m']>3)
+		print("inlvar %+N\n", var);
+
+	n = newname(var->sym);
+	n->type = var->type;
+	n->class = PAUTO;
+	n->used = 1;
+	n->curfn = curfn;   // the calling function, not the called one
+	n->addrtaken = var->addrtaken;
+
+	// Esc pass wont run if we're inlining into a iface wrapper.
+	// Luckily, we can steal the results from the target func.
+	// If inlining a function defined in another package after
+	// escape analysis is done, treat all local vars as escaping.
+	// See issue 9537.
+	if(var->esc == EscHeap || (inl_nonlocal && var->op == ONAME))
+		addrescapes(n);
+
+	curfn->dcl = list(curfn->dcl, n);
+	return n;
+}
+
+// Synthesize a variable to store the inlined function's results in.
+static Node*
+retvar(Type *t, int i)
+{
+	Node *n;
+
+	snprint(namebuf, sizeof(namebuf), "~r%d", i);
+	n = newname(lookup(namebuf));
+	n->type = t->type;
+	n->class = PAUTO;
+	n->used = 1;
+	n->curfn = curfn;   // the calling function, not the called one
+	curfn->dcl = list(curfn->dcl, n);
+	return n;
+}
+
+// Synthesize a variable to store the inlined function's arguments
+// when they come from a multiple return call.
+static Node*
+argvar(Type *t, int i)
+{
+	Node *n;
+
+	snprint(namebuf, sizeof(namebuf), "~arg%d", i);
+	n = newname(lookup(namebuf));
+	n->type = t->type;
+	n->class = PAUTO;
+	n->used = 1;
+	n->curfn = curfn;   // the calling function, not the called one
+	curfn->dcl = list(curfn->dcl, n);
+	return n;
+}
+
+static Node*
+newlabel(void)
+{
+	Node *n;
+	static int label;
+	
+	label++;
+	snprint(namebuf, sizeof(namebuf), ".inlret%.6d", label);
+	n = newname(lookup(namebuf));
+	n->etype = 1;  // flag 'safe' for escape analysis (no backjumps)
+	return n;
+}
+
+// inlsubst and inlsubstlist recursively copy the body of the saved
+// pristine ->inl body of the function while substituting references
+// to input/output parameters with ones to the tmpnames, and
+// substituting returns with assignments to the output.
+static NodeList*
+inlsubstlist(NodeList *ll)
+{
+	NodeList *l;
+
+	l = nil;
+	for(; ll; ll=ll->next)
+		l = list(l, inlsubst(ll->n));
+	return l;
+}
+
+static Node*
+inlsubst(Node *n)
+{
+	char *p;
+	Node *m, *as;
+	NodeList *ll;
+
+	if(n == N)
+		return N;
+
+	switch(n->op) {
+	case ONAME:
+		if(n->inlvar) { // These will be set during inlnode
+			if (debug['m']>2)
+				print ("substituting name %+N  ->  %+N\n", n, n->inlvar);
+			return n->inlvar;
+		}
+		if (debug['m']>2)
+			print ("not substituting name %+N\n", n);
+		return n;
+
+	case OLITERAL:
+	case OTYPE:
+		return n;
+
+	case ORETURN:
+		// Since we don't handle bodies with closures, this return is guaranteed to belong to the current inlined function.
+
+//		dump("Return before substitution", n);
+		m = nod(OGOTO, inlretlabel, N);
+		m->ninit  = inlsubstlist(n->ninit);
+
+		if(inlretvars && n->list) {
+			as = nod(OAS2, N, N);
+			// shallow copy or OINLCALL->rlist will be the same list, and later walk and typecheck may clobber that.
+			for(ll=inlretvars; ll; ll=ll->next)
+				as->list = list(as->list, ll->n);
+			as->rlist = inlsubstlist(n->list);
+			typecheck(&as, Etop);
+			m->ninit = list(m->ninit, as);
+		}
+
+		typechecklist(m->ninit, Etop);
+		typecheck(&m, Etop);
+//		dump("Return after substitution", m);
+		return m;
+	
+	case OGOTO:
+	case OLABEL:
+		m = nod(OXXX, N, N);
+		*m = *n;
+		m->ninit = nil;
+		p = smprint("%s·%d", n->left->sym->name, inlgen);	
+		m->left = newname(lookup(p));
+		free(p);
+		return m;	
+	}
+
+
+	m = nod(OXXX, N, N);
+	*m = *n;
+	m->ninit = nil;
+	
+	if(n->op == OCLOSURE)
+		fatal("cannot inline function containing closure: %+N", n);
+
+	m->left	  = inlsubst(n->left);
+	m->right  = inlsubst(n->right);
+	m->list	  = inlsubstlist(n->list);
+	m->rlist  = inlsubstlist(n->rlist);
+	m->ninit  = concat(m->ninit, inlsubstlist(n->ninit));
+	m->ntest  = inlsubst(n->ntest);
+	m->nincr  = inlsubst(n->nincr);
+	m->nbody  = inlsubstlist(n->nbody);
+	m->nelse  = inlsubstlist(n->nelse);
+
+	return m;
+}
+
+// Plaster over linenumbers
+static void
+setlnolist(NodeList *ll, int lno)
+{
+	for(;ll;ll=ll->next)
+		setlno(ll->n, lno);
+}
+
+static void
+setlno(Node *n, int lno)
+{
+	if(!n)
+		return;
+
+	// don't clobber names, unless they're freshly synthesized
+	if(n->op != ONAME || n->lineno == 0)
+		n->lineno = lno;
+	
+	setlno(n->left, lno);
+	setlno(n->right, lno);
+	setlnolist(n->list, lno);
+	setlnolist(n->rlist, lno);
+	setlnolist(n->ninit, lno);
+	setlno(n->ntest, lno);
+	setlno(n->nincr, lno);
+	setlnolist(n->nbody, lno);
+	setlnolist(n->nelse, lno);
+}
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
new file mode 100644
index 0000000..523ba37
--- /dev/null
+++ b/src/cmd/gc/lex.c
@@ -0,0 +1,2414 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"y.tab.h"
+#include	<ar.h>
+
+#undef	getc
+#undef	ungetc
+#define	getc	ccgetc
+#define	ungetc	ccungetc
+
+extern int yychar;
+int yyprev;
+int yylast;
+
+static void	lexinit(void);
+static void	lexinit1(void);
+static void	lexfini(void);
+static void	yytinit(void);
+static int	getc(void);
+static void	ungetc(int);
+static int32	getr(void);
+static int	escchar(int, int*, vlong*);
+static void	addidir(char*);
+static int	getlinepragma(void);
+static char *goos, *goarch, *goroot;
+
+#define	BOM	0xFEFF
+
+// Compiler experiments.
+// These are controlled by the GOEXPERIMENT environment
+// variable recorded when the compiler is built.
+static struct {
+	char *name;
+	int *val;
+} exper[] = {
+//	{"rune32", &rune32},
+	{"fieldtrack", &fieldtrack_enabled},
+	{"precisestack", &precisestack_enabled},
+	{nil, nil},
+};
+
+// Debug arguments.
+// These can be specified with the -d flag, as in "-d nil"
+// to set the debug_checknil variable. In general the list passed
+// to -d can be comma-separated.
+static struct {
+	char *name;
+	int *val;
+} debugtab[] = {
+	{"nil", &debug_checknil},
+	{nil, nil},
+};
+
+static void
+addexp(char *s)
+{
+	int i;
+
+	for(i=0; exper[i].name != nil; i++) {
+		if(strcmp(exper[i].name, s) == 0) {
+			*exper[i].val = 1;
+			return;
+		}
+	}
+	
+	print("unknown experiment %s\n", s);
+	exits("unknown experiment");
+}
+
+static void
+setexp(void)
+{
+	char *f[20];
+	int i, nf;
+
+	precisestack_enabled = 1; // on by default
+
+	// cmd/dist #defines GOEXPERIMENT for us.
+	nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ",");
+	for(i=0; i<nf; i++)
+		addexp(f[i]);
+}
+
+char*
+expstring(void)
+{
+	int i;
+	static char buf[512];
+
+	strcpy(buf, "X");
+	for(i=0; exper[i].name != nil; i++)
+		if(*exper[i].val)
+			seprint(buf+strlen(buf), buf+sizeof buf, ",%s", exper[i].name);
+	if(strlen(buf) == 1)
+		strcpy(buf, "X,none");
+	buf[1] = ':';
+	return buf;
+}
+
+// Our own isdigit, isspace, isalpha, isalnum that take care 
+// of EOF and other out of range arguments.
+static int
+yy_isdigit(int c)
+{
+	return c >= 0 && c <= 0xFF && isdigit(c);
+}
+
+static int
+yy_isspace(int c)
+{
+	return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+}
+
+static int
+yy_isalpha(int c)
+{
+	return c >= 0 && c <= 0xFF && isalpha(c);
+}
+
+static int
+yy_isalnum(int c)
+{
+	return c >= 0 && c <= 0xFF && isalnum(c);
+}
+
+// Disallow use of isdigit etc.
+#undef isdigit
+#undef isspace
+#undef isalpha
+#undef isalnum
+#define isdigit use_yy_isdigit_instead_of_isdigit
+#define isspace use_yy_isspace_instead_of_isspace
+#define isalpha use_yy_isalpha_instead_of_isalpha
+#define isalnum use_yy_isalnum_instead_of_isalnum
+
+#define	DBG	if(!debug['x']){}else print
+/*c2go void DBG(char*, ...); */
+
+enum
+{
+	EOF		= -1,
+};
+
+void
+usage(void)
+{
+	print("usage: %cg [options] file.go...\n", thechar);
+	flagprint(1);
+	exits("usage");
+}
+
+void
+fault(int s)
+{
+	USED(s);
+
+	// If we've already complained about things
+	// in the program, don't bother complaining
+	// about the seg fault too; let the user clean up
+	// the code and try again.
+	if(nsavederrors + nerrors > 0)
+		errorexit();
+	fatal("fault");
+}
+
+#ifdef	PLAN9
+void
+catcher(void *v, char *s)
+{
+	USED(v);
+
+	if(strncmp(s, "sys: trap: fault read", 21) == 0) {
+		if(nsavederrors + nerrors > 0)
+			errorexit();
+		fatal("fault");
+	}
+	noted(NDFLT);
+}
+#endif
+
+void
+doversion(void)
+{
+	char *p;
+
+	p = expstring();
+	if(strcmp(p, "X:none") == 0)
+		p = "";
+	print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p);
+	exits(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int i;
+	NodeList *l;
+	char *p;
+
+#ifdef	SIGBUS	
+	signal(SIGBUS, fault);
+	signal(SIGSEGV, fault);
+#endif
+
+#ifdef	PLAN9
+	notify(catcher);
+	// Tell the FPU to handle all exceptions.
+	setfcr(FPPDBL|FPRNR);
+#endif
+	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
+	// but not other values.	
+	p = getgoarch();
+	if(strncmp(p, thestring, strlen(thestring)) != 0)
+		sysfatal("cannot use %cg with GOARCH=%s", thechar, p);
+	goarch = p;
+
+	linkarchinit();
+	ctxt = linknew(thelinkarch);
+	ctxt->diag = yyerror;
+	ctxt->bso = &bstdout;
+	Binit(&bstdout, 1, OWRITE);
+
+	localpkg = mkpkg(strlit(""));
+	localpkg->prefix = "\"\"";
+	
+	// pseudo-package, for scoping
+	builtinpkg = mkpkg(strlit("go.builtin"));
+
+	// pseudo-package, accessed by import "unsafe"
+	unsafepkg = mkpkg(strlit("unsafe"));
+	unsafepkg->name = "unsafe";
+
+	// real package, referred to by generated runtime calls
+	runtimepkg = mkpkg(strlit("runtime"));
+	runtimepkg->name = "runtime";
+
+	// pseudo-packages used in symbol tables
+	gostringpkg = mkpkg(strlit("go.string"));
+	gostringpkg->name = "go.string";
+	gostringpkg->prefix = "go.string";	// not go%2estring
+
+	itabpkg = mkpkg(strlit("go.itab"));
+	itabpkg->name = "go.itab";
+	itabpkg->prefix = "go.itab";	// not go%2eitab
+
+	weaktypepkg = mkpkg(strlit("go.weak.type"));
+	weaktypepkg->name = "go.weak.type";
+	weaktypepkg->prefix = "go.weak.type";  // not go%2eweak%2etype
+	
+	typelinkpkg = mkpkg(strlit("go.typelink"));
+	typelinkpkg->name = "go.typelink";
+	typelinkpkg->prefix = "go.typelink"; // not go%2etypelink
+
+	trackpkg = mkpkg(strlit("go.track"));
+	trackpkg->name = "go.track";
+	trackpkg->prefix = "go.track";  // not go%2etrack
+
+	typepkg = mkpkg(strlit("type"));
+	typepkg->name = "type";
+
+	goroot = getgoroot();
+	goos = getgoos();
+
+	nacl = strcmp(goos, "nacl") == 0;
+	if(nacl)
+		flag_largemodel = 1;
+
+	setexp();
+
+	outfile = nil;
+	flagcount("+", "compiling runtime", &compiling_runtime);
+	flagcount("%", "debug non-static initializers", &debug['%']);
+	flagcount("A", "for bootstrapping, allow 'any' type", &debug['A']);
+	flagcount("B", "disable bounds checking", &debug['B']);
+	flagstr("D", "path: set relative path for local imports", &localimport);
+	flagcount("E", "debug symbol export", &debug['E']);
+	flagfn1("I", "dir: add dir to import search path", addidir);
+	flagcount("K", "debug missing line numbers", &debug['K']);
+	flagcount("L", "use full (long) path in error messages", &debug['L']);
+	flagcount("M", "debug move generation", &debug['M']);
+	flagcount("N", "disable optimizations", &debug['N']);
+	flagcount("P", "debug peephole optimizer", &debug['P']);
+	flagcount("R", "debug register optimizer", &debug['R']);
+	flagcount("S", "print assembly listing", &debug['S']);
+	flagfn0("V", "print compiler version", doversion);
+	flagcount("W", "debug parse tree after type checking", &debug['W']);
+	flagcount("complete", "compiling complete package (no C or assembly)", &pure_go);
+	flagstr("d", "list: print debug information about items in list", &debugstr);
+	flagcount("e", "no limit on number of errors reported", &debug['e']);
+	flagcount("f", "debug stack frames", &debug['f']);
+	flagcount("g", "debug code generation", &debug['g']);
+	flagcount("h", "halt on error", &debug['h']);
+	flagcount("i", "debug line number stack", &debug['i']);
+	flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
+	flagcount("j", "debug runtime-initialized variables", &debug['j']);
+	flagcount("l", "disable inlining", &debug['l']);
+	flagcount("live", "debug liveness analysis", &debuglive);
+	flagcount("m", "print optimization decisions", &debug['m']);
+	flagcount("nolocalimports", "reject local (relative) imports", &nolocalimports);
+	flagstr("o", "obj: set output file", &outfile);
+	flagstr("p", "path: set expected package import path", &myimportpath);
+	flagcount("pack", "write package file instead of object file", &writearchive);
+	flagcount("r", "debug generated wrappers", &debug['r']);
+	flagcount("race", "enable race detector", &flag_race);
+	flagcount("s", "warn about composite literals that can be simplified", &debug['s']);
+	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
+	flagcount("u", "reject unsafe code", &safemode);
+	flagcount("v", "increase debug verbosity", &debug['v']);
+	flagcount("w", "debug type checking", &debug['w']);
+	use_writebarrier = 1;
+	flagcount("wb", "enable write barrier", &use_writebarrier);
+	flagcount("x", "debug lexer", &debug['x']);
+	flagcount("y", "debug declarations in canned imports (with -d)", &debug['y']);
+	if(thechar == '6')
+		flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
+
+	flagparse(&argc, &argv, usage);
+	ctxt->debugasm = debug['S'];
+	ctxt->debugvlog = debug['v'];
+
+	if(argc < 1)
+		usage();
+
+	if(flag_race) {
+		racepkg = mkpkg(strlit("runtime/race"));
+		racepkg->name = "race";
+	}
+	
+	// parse -d argument
+	if(debugstr) {
+		char *f[100];
+		int i, j, nf;
+		
+		nf = getfields(debugstr, f, nelem(f), 1, ",");
+		for(i=0; i<nf; i++) {
+			for(j=0; debugtab[j].name != nil; j++) {
+				if(strcmp(debugtab[j].name, f[i]) == 0) {
+					*debugtab[j].val = 1;
+					break;
+				}
+			}
+			if(debugtab[j].name == nil)
+				sysfatal("unknown debug information -d '%s'\n", f[i]);
+		}
+	}
+
+	// enable inlining.  for now:
+	//	default: inlining on.  (debug['l'] == 1)
+	//	-l: inlining off  (debug['l'] == 0)
+	//	-ll, -lll: inlining on again, with extra debugging (debug['l'] > 1)
+	if(debug['l'] <= 1)
+		debug['l'] = 1 - debug['l'];
+
+	if(thechar == '8') {
+		p = getgo386();
+		if(strcmp(p, "387") == 0)
+			use_sse = 0;
+		else if(strcmp(p, "sse2") == 0)
+			use_sse = 1;
+		else
+			sysfatal("unsupported setting GO386=%s", p);
+	}
+
+	fmtinstallgo();
+	betypeinit();
+	if(widthptr == 0)
+		fatal("betypeinit failed");
+
+	lexinit();
+	typeinit();
+	lexinit1();
+	yytinit();
+
+	blockgen = 1;
+	dclcontext = PEXTERN;
+	nerrors = 0;
+	lexlineno = 1;
+
+	for(i=0; i<argc; i++) {
+		infile = argv[i];
+		linehist(infile, 0, 0);
+
+		curio.infile = infile;
+		curio.bin = Bopen(infile, OREAD);
+		if(curio.bin == nil) {
+			print("open %s: %r\n", infile);
+			errorexit();
+		}
+		curio.peekc = 0;
+		curio.peekc1 = 0;
+		curio.nlsemi = 0;
+		curio.eofnl = 0;
+		curio.last = 0;
+
+		// Skip initial BOM if present.
+		if(Bgetrune(curio.bin) != BOM)
+			Bungetrune(curio.bin);
+
+		block = 1;
+		iota = -1000000;
+
+		yyparse();
+		if(nsyntaxerrors != 0)
+			errorexit();
+
+		linehist(nil, 0, 0);
+		if(curio.bin != nil)
+			Bterm(curio.bin);
+	}
+	testdclstack();
+	mkpackage(localpkg->name);	// final import not used checks
+	lexfini();
+
+	typecheckok = 1;
+	if(debug['f'])
+		frame(1);
+
+	// Process top-level declarations in phases.
+
+	// Phase 1: const, type, and names and types of funcs.
+	//   This will gather all the information about types
+	//   and methods but doesn't depend on any of it.
+	defercheckwidth();
+	for(l=xtop; l; l=l->next)
+		if(l->n->op != ODCL && l->n->op != OAS)
+			typecheck(&l->n, Etop);
+
+	// Phase 2: Variable assignments.
+	//   To check interface assignments, depends on phase 1.
+	for(l=xtop; l; l=l->next)
+		if(l->n->op == ODCL || l->n->op == OAS)
+			typecheck(&l->n, Etop);
+	resumecheckwidth();
+
+	// Phase 3: Type check function bodies.
+	for(l=xtop; l; l=l->next) {
+		if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE) {
+			curfn = l->n;
+			saveerrors();
+			typechecklist(l->n->nbody, Etop);
+			checkreturn(l->n);
+			if(nerrors != 0)
+				l->n->nbody = nil;  // type errors; do not compile
+		}
+	}
+
+	curfn = nil;
+	
+	if(nsavederrors+nerrors)
+		errorexit();
+
+	// Phase 4: Inlining
+	if(debug['l'] > 1) {
+		// Typecheck imported function bodies if debug['l'] > 1,
+		// otherwise lazily when used or re-exported.
+		for(l=importlist; l; l=l->next)
+			if (l->n->inl) {
+				saveerrors();
+				typecheckinl(l->n);
+			}
+		
+		if(nsavederrors+nerrors)
+			errorexit();
+	}
+
+	if(debug['l']) {
+		// Find functions that can be inlined and clone them before walk expands them.
+		for(l=xtop; l; l=l->next)
+			if(l->n->op == ODCLFUNC)
+				caninl(l->n);
+		
+		// Expand inlineable calls in all functions
+		for(l=xtop; l; l=l->next)
+			if(l->n->op == ODCLFUNC)
+				inlcalls(l->n);
+	}
+
+	// Phase 5: Escape analysis.
+	// Required for moving heap allocations onto stack,
+	// which in turn is required by the closure implementation,
+	// which stores the addresses of stack variables into the closure.
+	// If the closure does not escape, it needs to be on the stack
+	// or else the stack copier will not update it.
+	escapes(xtop);
+	
+	// Escape analysis moved escaped values off stack.
+	// Move large values off stack too.
+	movelarge(xtop);
+
+	// Phase 6: Compile top level functions.
+	for(l=xtop; l; l=l->next)
+		if(l->n->op == ODCLFUNC)
+			funccompile(l->n, 0);
+
+	if(nsavederrors+nerrors == 0)
+		fninit(xtop);
+
+	// Phase 7: Check external declarations.
+	for(l=externdcl; l; l=l->next)
+		if(l->n->op == ONAME)
+			typecheck(&l->n, Erv);
+
+	if(nerrors+nsavederrors)
+		errorexit();
+
+	dumpobj();
+
+	if(nerrors+nsavederrors)
+		errorexit();
+
+	flusherrors();
+	exits(0);
+	return 0;
+}
+
+void
+saveerrors(void)
+{
+	nsavederrors += nerrors;
+	nerrors = 0;
+}
+
+static int
+arsize(Biobuf *b, char *name)
+{
+	struct ar_hdr a;
+
+	if(Bread(b, a.name, sizeof(a.name)) != sizeof(a.name) ||
+	   Bread(b, a.date, sizeof(a.date)) != sizeof(a.date) ||
+	   Bread(b, a.uid, sizeof(a.uid)) != sizeof(a.uid) ||
+	   Bread(b, a.gid, sizeof(a.gid)) != sizeof(a.gid) ||
+	   Bread(b, a.mode, sizeof(a.mode)) != sizeof(a.mode) ||
+	   Bread(b, a.size, sizeof(a.size)) != sizeof(a.size) ||
+	   Bread(b, a.fmag, sizeof(a.fmag)) != sizeof(a.fmag))
+		return -1;
+
+	if(strncmp(a.name, name, strlen(name)) != 0)
+		return -1;
+
+	return atoi(a.size);
+}
+
+static int
+skiptopkgdef(Biobuf *b)
+{
+	char *p;
+	int sz;
+
+	/* archive header */
+	if((p = Brdline(b, '\n')) == nil)
+		return 0;
+	if(Blinelen(b) != 8)
+		return 0;
+	if(memcmp(p, "!<arch>\n", 8) != 0)
+		return 0;
+	/* symbol table may be first; skip it */
+	sz = arsize(b, "__.GOSYMDEF");
+	if(sz >= 0)
+		Bseek(b, sz, 1);
+	else
+		Bseek(b, 8, 0);
+	/* package export block is next */
+	sz = arsize(b, "__.PKGDEF");
+	if(sz <= 0)
+		return 0;
+	return 1;
+}
+
+static void
+addidir(char* dir)
+{
+	Idir** pp;
+
+	if(dir == nil)
+		return;
+
+	for(pp = &idirs; *pp != nil; pp = &(*pp)->link)
+		;
+	*pp = mal(sizeof(Idir));
+	(*pp)->link = nil;
+	(*pp)->dir = dir;
+}
+
+// is this path a local name?  begins with ./ or ../ or /
+static int
+islocalname(Strlit *name)
+{
+	if(name->len >= 1 && name->s[0] == '/')
+		return 1;
+	if(ctxt->windows && name->len >= 3 &&
+	   yy_isalpha(name->s[0]) && name->s[1] == ':' && name->s[2] == '/')
+	   	return 1;
+	if(name->len >= 2 && strncmp(name->s, "./", 2) == 0)
+		return 1;
+	if(name->len == 1 && strncmp(name->s, ".", 1) == 0)
+		return 1;
+	if(name->len >= 3 && strncmp(name->s, "../", 3) == 0)
+		return 1;
+	if(name->len == 2 && strncmp(name->s, "..", 2) == 0)
+		return 1;
+	return 0;
+}
+
+static int
+findpkg(Strlit *name)
+{
+	Idir *p;
+	char *q, *suffix, *suffixsep;
+
+	if(islocalname(name)) {
+		if(safemode || nolocalimports)
+			return 0;
+		// try .a before .6.  important for building libraries:
+		// if there is an array.6 in the array.a library,
+		// want to find all of array.a, not just array.6.
+		snprint(namebuf, sizeof(namebuf), "%Z.a", name);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+		snprint(namebuf, sizeof(namebuf), "%Z.%c", name, thechar);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+		return 0;
+	}
+
+	// local imports should be canonicalized already.
+	// don't want to see "encoding/../encoding/base64"
+	// as different from "encoding/base64".
+	q = mal(name->len+1);
+	memmove(q, name->s, name->len);
+	q[name->len] = '\0';
+	cleanname(q);
+	if(strlen(q) != name->len || memcmp(q, name->s, name->len) != 0) {
+		yyerror("non-canonical import path %Z (should be %s)", name, q);
+		return 0;
+	}
+
+	for(p = idirs; p != nil; p = p->link) {
+		snprint(namebuf, sizeof(namebuf), "%s/%Z.a", p->dir, name);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+		snprint(namebuf, sizeof(namebuf), "%s/%Z.%c", p->dir, name, thechar);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+	}
+	if(goroot != nil) {
+		suffix = "";
+		suffixsep = "";
+		if(flag_installsuffix != nil) {
+			suffixsep = "_";
+			suffix = flag_installsuffix;
+		} else if(flag_race) {
+			suffixsep = "_";
+			suffix = "race";
+		}
+		snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.a", goroot, goos, goarch, suffixsep, suffix, name);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+		snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.%c", goroot, goos, goarch, suffixsep, suffix, name, thechar);
+		if(access(namebuf, 0) >= 0)
+			return 1;
+	}
+	return 0;
+}
+
+static void
+fakeimport(void)
+{
+	importpkg = mkpkg(strlit("fake"));
+	cannedimports("fake.6", "$$\n");
+}
+
+void
+importfile(Val *f, int line)
+{
+	Biobuf *imp;
+	char *file, *p, *q, *tag;
+	int32 c;
+	int len;
+	Strlit *path;
+	char *cleanbuf, *prefix;
+
+	USED(line);
+
+	if(f->ctype != CTSTR) {
+		yyerror("import statement not a string");
+		fakeimport();
+		return;
+	}
+
+	if(f->u.sval->len == 0) {
+		yyerror("import path is empty");
+		fakeimport();
+		return;
+	}
+
+	if(isbadimport(f->u.sval)) {
+		fakeimport();
+		return;
+	}
+
+	// The package name main is no longer reserved,
+	// but we reserve the import path "main" to identify
+	// the main package, just as we reserve the import 
+	// path "math" to identify the standard math package.
+	if(strcmp(f->u.sval->s, "main") == 0) {
+		yyerror("cannot import \"main\"");
+		errorexit();
+	}
+
+	if(myimportpath != nil && strcmp(f->u.sval->s, myimportpath) == 0) {
+		yyerror("import \"%Z\" while compiling that package (import cycle)", f->u.sval);
+		errorexit();
+	}
+
+	if(strcmp(f->u.sval->s, "unsafe") == 0) {
+		if(safemode) {
+			yyerror("cannot import package unsafe");
+			errorexit();
+		}
+		importpkg = mkpkg(f->u.sval);
+		cannedimports("unsafe.6", unsafeimport);
+		return;
+	}
+	
+	path = f->u.sval;
+	if(islocalname(path)) {
+		if(path->s[0] == '/') {
+			yyerror("import path cannot be absolute path");
+			fakeimport();
+			return;
+		}
+		prefix = ctxt->pathname;
+		if(localimport != nil)
+			prefix = localimport;
+		cleanbuf = mal(strlen(prefix) + strlen(path->s) + 2);
+		strcpy(cleanbuf, prefix);
+		strcat(cleanbuf, "/");
+		strcat(cleanbuf, path->s);
+		cleanname(cleanbuf);
+		path = strlit(cleanbuf);
+		
+		if(isbadimport(path)) {
+			fakeimport();
+			return;
+		}
+	}
+
+	if(!findpkg(path)) {
+		yyerror("can't find import: \"%Z\"", f->u.sval);
+		errorexit();
+	}
+	importpkg = mkpkg(path);
+
+	// If we already saw that package, feed a dummy statement
+	// to the lexer to avoid parsing export data twice.
+	if(importpkg->imported) {
+		file = strdup(namebuf);
+		tag = "";
+		if(importpkg->safe) {
+			tag = "safe";
+		}
+		p = smprint("package %s %s\n$$\n", importpkg->name, tag);
+		cannedimports(file, p);
+		return;
+	}
+	importpkg->imported = 1;
+
+	imp = Bopen(namebuf, OREAD);
+	if(imp == nil) {
+		yyerror("can't open import: \"%Z\": %r", f->u.sval);
+		errorexit();
+	}
+	file = strdup(namebuf);
+
+	len = strlen(namebuf);
+	if(len > 2 && namebuf[len-2] == '.' && namebuf[len-1] == 'a') {
+		if(!skiptopkgdef(imp)) {
+			yyerror("import %s: not a package file", file);
+			errorexit();
+		}
+	}
+	
+	// check object header
+	p = Brdstr(imp, '\n', 1);
+	if(strcmp(p, "empty archive") != 0) {
+		if(strncmp(p, "go object ", 10) != 0) {
+			yyerror("import %s: not a go object file", file);
+			errorexit();
+		}
+		q = smprint("%s %s %s %s", getgoos(), getgoarch(), getgoversion(), expstring());
+		if(strcmp(p+10, q) != 0) {
+			yyerror("import %s: object is [%s] expected [%s]", file, p+10, q);
+			errorexit();
+		}
+		free(q);
+	}
+
+	// assume files move (get installed)
+	// so don't record the full path.
+	linehist(file + len - path->len - 2, -1, 1);	// acts as #pragma lib
+
+	/*
+	 * position the input right
+	 * after $$ and return
+	 */
+	pushedio = curio;
+	curio.bin = imp;
+	curio.peekc = 0;
+	curio.peekc1 = 0;
+	curio.infile = file;
+	curio.nlsemi = 0;
+	typecheckok = 1;
+
+	for(;;) {
+		c = getc();
+		if(c == EOF)
+			break;
+		if(c != '$')
+			continue;
+		c = getc();
+		if(c == EOF)
+			break;
+		if(c != '$')
+			continue;
+		return;
+	}
+	yyerror("no import in \"%Z\"", f->u.sval);
+	unimportfile();
+}
+
+void
+unimportfile(void)
+{
+	if(curio.bin != nil) {
+		Bterm(curio.bin);
+		curio.bin = nil;
+	} else
+		lexlineno--;	// re correct sys.6 line number
+
+	curio = pushedio;
+	pushedio.bin = nil;
+	incannedimport = 0;
+	typecheckok = 0;
+}
+
+void
+cannedimports(char *file, char *cp)
+{
+	lexlineno++;		// if sys.6 is included on line 1,
+
+	pushedio = curio;
+	curio.bin = nil;
+	curio.peekc = 0;
+	curio.peekc1 = 0;
+	curio.infile = file;
+	curio.cp = cp;
+	curio.nlsemi = 0;
+	curio.importsafe = 0;
+
+	typecheckok = 1;
+	incannedimport = 1;
+}
+
+static int
+isfrog(int c)
+{
+	// complain about possibly invisible control characters
+	if(c < ' ') {
+		return !yy_isspace(c);	// exclude good white space
+	}
+	if(0x7f <= c && c <= 0xa0)	// DEL, unicode block including unbreakable space.
+		return 1;
+	return 0;
+}
+
+typedef struct Loophack Loophack;
+struct Loophack {
+	int v;
+	Loophack *next;
+};
+
+static int32
+_yylex(void)
+{
+	int c, c1, clen, escflag, ncp;
+	vlong v;
+	char *cp, *ep;
+	Rune rune;
+	Sym *s;
+	static Loophack *lstk;
+	Loophack *h;
+
+	prevlineno = lineno;
+
+l0:
+	c = getc();
+	if(yy_isspace(c)) {
+		if(c == '\n' && curio.nlsemi) {
+			ungetc(c);
+			DBG("lex: implicit semi\n");
+			return ';';
+		}
+		goto l0;
+	}
+
+	lineno = lexlineno;	/* start of token */
+
+	if(c >= Runeself) {
+		/* all multibyte runes are alpha */
+		cp = lexbuf;
+		ep = lexbuf+sizeof lexbuf;
+		goto talph;
+	}
+
+	if(yy_isalpha(c)) {
+		cp = lexbuf;
+		ep = lexbuf+sizeof lexbuf;
+		goto talph;
+	}
+
+	if(yy_isdigit(c))
+		goto tnum;
+
+	switch(c) {
+	case EOF:
+		lineno = prevlineno;
+		ungetc(EOF);
+		return -1;
+
+	case '_':
+		cp = lexbuf;
+		ep = lexbuf+sizeof lexbuf;
+		goto talph;
+
+	case '.':
+		c1 = getc();
+		if(yy_isdigit(c1)) {
+			cp = lexbuf;
+			ep = lexbuf+sizeof lexbuf;
+			*cp++ = c;
+			c = c1;
+			goto casedot;
+		}
+		if(c1 == '.') {
+			c1 = getc();
+			if(c1 == '.') {
+				c = LDDD;
+				goto lx;
+			}
+			ungetc(c1);
+			c1 = '.';
+		}
+		break;
+
+	case '"':
+		/* "..." */
+		strcpy(lexbuf, "\"<string>\"");
+		cp = mal(8);
+		clen = sizeof(int32);
+		ncp = 8;
+
+		for(;;) {
+			if(clen+UTFmax > ncp) {
+				cp = remal(cp, ncp, ncp);
+				ncp += ncp;
+			}
+			if(escchar('"', &escflag, &v))
+				break;
+			if(v < Runeself || escflag) {
+				cp[clen++] = v;
+			} else {
+				rune = v;
+				c = runelen(rune);
+				runetochar(cp+clen, &rune);
+				clen += c;
+			}
+		}
+		goto strlit;
+	
+	case '`':
+		/* `...` */
+		strcpy(lexbuf, "`<string>`");
+		cp = mal(8);
+		clen = sizeof(int32);
+		ncp = 8;
+
+		for(;;) {
+			if(clen+UTFmax > ncp) {
+				cp = remal(cp, ncp, ncp);
+				ncp += ncp;
+			}
+			c = getr();
+			if(c == '\r')
+				continue;
+			if(c == EOF) {
+				yyerror("eof in string");
+				break;
+			}
+			if(c == '`')
+				break;
+			rune = c;
+			clen += runetochar(cp+clen, &rune);
+		}
+
+	strlit:
+		*(int32*)cp = clen-sizeof(int32);	// length
+		do {
+			cp[clen++] = 0;
+		} while(clen & MAXALIGN);
+		yylval.val.u.sval = (Strlit*)cp;
+		yylval.val.ctype = CTSTR;
+		DBG("lex: string literal\n");
+		strcpy(litbuf, "string literal");
+		return LLITERAL;
+
+	case '\'':
+		/* '.' */
+		if(escchar('\'', &escflag, &v)) {
+			yyerror("empty character literal or unescaped ' in character literal");
+			v = '\'';
+		}
+		if(!escchar('\'', &escflag, &v)) {
+			yyerror("missing '");
+			ungetc(v);
+		}
+		yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
+		mpmovecfix(yylval.val.u.xval, v);
+		yylval.val.ctype = CTRUNE;
+		DBG("lex: codepoint literal\n");
+		strcpy(litbuf, "string literal");
+		return LLITERAL;
+
+	case '/':
+		c1 = getc();
+		if(c1 == '*') {
+			int nl;
+			
+			nl = 0;
+			for(;;) {
+				c = getr();
+				if(c == '\n')
+					nl = 1;
+				while(c == '*') {
+					c = getr();
+					if(c == '/') {
+						if(nl)
+							ungetc('\n');
+						goto l0;
+					}
+					if(c == '\n')
+						nl = 1;
+				}
+				if(c == EOF) {
+					yyerror("eof in comment");
+					errorexit();
+				}
+			}
+		}
+		if(c1 == '/') {
+			c = getlinepragma();
+			for(;;) {
+				if(c == '\n' || c == EOF) {
+					ungetc(c);
+					goto l0;
+				}
+				c = getr();
+			}
+		}
+		if(c1 == '=') {
+			c = ODIV;
+			goto asop;
+		}
+		break;
+
+	case ':':
+		c1 = getc();
+		if(c1 == '=') {
+			c = LCOLAS;
+			yylval.i = lexlineno;
+			goto lx;
+		}
+		break;
+
+	case '*':
+		c1 = getc();
+		if(c1 == '=') {
+			c = OMUL;
+			goto asop;
+		}
+		break;
+
+	case '%':
+		c1 = getc();
+		if(c1 == '=') {
+			c = OMOD;
+			goto asop;
+		}
+		break;
+
+	case '+':
+		c1 = getc();
+		if(c1 == '+') {
+			c = LINC;
+			goto lx;
+		}
+		if(c1 == '=') {
+			c = OADD;
+			goto asop;
+		}
+		break;
+
+	case '-':
+		c1 = getc();
+		if(c1 == '-') {
+			c = LDEC;
+			goto lx;
+		}
+		if(c1 == '=') {
+			c = OSUB;
+			goto asop;
+		}
+		break;
+
+	case '>':
+		c1 = getc();
+		if(c1 == '>') {
+			c = LRSH;
+			c1 = getc();
+			if(c1 == '=') {
+				c = ORSH;
+				goto asop;
+			}
+			break;
+		}
+		if(c1 == '=') {
+			c = LGE;
+			goto lx;
+		}
+		c = LGT;
+		break;
+
+	case '<':
+		c1 = getc();
+		if(c1 == '<') {
+			c = LLSH;
+			c1 = getc();
+			if(c1 == '=') {
+				c = OLSH;
+				goto asop;
+			}
+			break;
+		}
+		if(c1 == '=') {
+			c = LLE;
+			goto lx;
+		}
+		if(c1 == '-') {
+			c = LCOMM;
+			goto lx;
+		}
+		c = LLT;
+		break;
+
+	case '=':
+		c1 = getc();
+		if(c1 == '=') {
+			c = LEQ;
+			goto lx;
+		}
+		break;
+
+	case '!':
+		c1 = getc();
+		if(c1 == '=') {
+			c = LNE;
+			goto lx;
+		}
+		break;
+
+	case '&':
+		c1 = getc();
+		if(c1 == '&') {
+			c = LANDAND;
+			goto lx;
+		}
+		if(c1 == '^') {
+			c = LANDNOT;
+			c1 = getc();
+			if(c1 == '=') {
+				c = OANDNOT;
+				goto asop;
+			}
+			break;
+		}
+		if(c1 == '=') {
+			c = OAND;
+			goto asop;
+		}
+		break;
+
+	case '|':
+		c1 = getc();
+		if(c1 == '|') {
+			c = LOROR;
+			goto lx;
+		}
+		if(c1 == '=') {
+			c = OOR;
+			goto asop;
+		}
+		break;
+
+	case '^':
+		c1 = getc();
+		if(c1 == '=') {
+			c = OXOR;
+			goto asop;
+		}
+		break;
+
+	/*
+	 * clumsy dance:
+	 * to implement rule that disallows
+	 *	if T{1}[0] { ... }
+	 * but allows
+	 * 	if (T{1}[0]) { ... }
+	 * the block bodies for if/for/switch/select
+	 * begin with an LBODY token, not '{'.
+	 *
+	 * when we see the keyword, the next
+	 * non-parenthesized '{' becomes an LBODY.
+	 * loophack is normally 0.
+	 * a keyword makes it go up to 1.
+	 * parens push loophack onto a stack and go back to 0.
+	 * a '{' with loophack == 1 becomes LBODY and disables loophack.
+	 *
+	 * i said it was clumsy.
+	 */
+	case '(':
+	case '[':
+		if(loophack || lstk != nil) {
+			h = malloc(sizeof *h);
+			if(h == nil) {
+				flusherrors();
+				yyerror("out of memory");
+				errorexit();
+			}
+			h->v = loophack;
+			h->next = lstk;
+			lstk = h;
+			loophack = 0;
+		}
+		goto lx;
+	case ')':
+	case ']':
+		if(lstk != nil) {
+			h = lstk;
+			loophack = h->v;
+			lstk = h->next;
+			free(h);
+		}
+		goto lx;
+	case '{':
+		if(loophack == 1) {
+			DBG("%L lex: LBODY\n", lexlineno);
+			loophack = 0;
+			return LBODY;
+		}
+		goto lx;
+
+	default:
+		goto lx;
+	}
+	ungetc(c1);
+
+lx:
+	if(c > 0xff)
+		DBG("%L lex: TOKEN %s\n", lexlineno, lexname(c));
+	else
+		DBG("%L lex: TOKEN '%c'\n", lexlineno, c);
+	if(isfrog(c)) {
+		yyerror("illegal character 0x%ux", c);
+		goto l0;
+	}
+	if(importpkg == nil && (c == '#' || c == '$' || c == '?' || c == '@' || c == '\\')) {
+		yyerror("%s: unexpected %c", "syntax error", c);
+		goto l0;
+	}
+	return c;
+
+asop:
+	yylval.i = c;	// rathole to hold which asop
+	DBG("lex: TOKEN ASOP %c\n", c);
+	return LASOP;
+
+talph:
+	/*
+	 * cp is set to lexbuf and some
+	 * prefix has been stored
+	 */
+	for(;;) {
+		if(cp+10 >= ep) {
+			yyerror("identifier too long");
+			errorexit();
+		}
+		if(c >= Runeself) {
+			ungetc(c);
+			rune = getr();
+			// 0xb7 · is used for internal names
+			if(!isalpharune(rune) && !isdigitrune(rune) && (importpkg == nil || rune != 0xb7))
+				yyerror("invalid identifier character U+%04x", rune);
+			cp += runetochar(cp, &rune);
+		} else if(!yy_isalnum(c) && c != '_')
+			break;
+		else
+			*cp++ = c;
+		c = getc();
+	}
+	*cp = 0;
+	ungetc(c);
+
+	s = lookup(lexbuf);
+	switch(s->lexical) {
+	case LIGNORE:
+		goto l0;
+
+	case LFOR:
+	case LIF:
+	case LSWITCH:
+	case LSELECT:
+		loophack = 1;	// see comment about loophack above
+		break;
+	}
+
+	DBG("lex: %S %s\n", s, lexname(s->lexical));
+	yylval.sym = s;
+	return s->lexical;
+
+tnum:
+	cp = lexbuf;
+	ep = lexbuf+sizeof lexbuf;
+	if(c != '0') {
+		for(;;) {
+			if(cp+10 >= ep) {
+				yyerror("identifier too long");
+				errorexit();
+			}
+			*cp++ = c;
+			c = getc();
+			if(yy_isdigit(c))
+				continue;
+			goto dc;
+		}
+	}
+	*cp++ = c;
+	c = getc();
+	if(c == 'x' || c == 'X') {
+		for(;;) {
+			if(cp+10 >= ep) {
+				yyerror("identifier too long");
+				errorexit();
+			}
+			*cp++ = c;
+			c = getc();
+			if(yy_isdigit(c))
+				continue;
+			if(c >= 'a' && c <= 'f')
+				continue;
+			if(c >= 'A' && c <= 'F')
+				continue;
+			if(cp == lexbuf+2)
+				yyerror("malformed hex constant");
+			if(c == 'p')
+				goto caseep;
+			goto ncu;
+		}
+	}
+
+	if(c == 'p')	// 0p begins floating point zero
+		goto caseep;
+
+	c1 = 0;
+	for(;;) {
+		if(cp+10 >= ep) {
+			yyerror("identifier too long");
+			errorexit();
+		}
+		if(!yy_isdigit(c))
+			break;
+		if(c < '0' || c > '7')
+			c1 = 1;		// not octal
+		*cp++ = c;
+		c = getc();
+	}
+	if(c == '.')
+		goto casedot;
+	if(c == 'e' || c == 'E')
+		goto caseep;
+	if(c == 'i')
+		goto casei;
+	if(c1)
+		yyerror("malformed octal constant");
+	goto ncu;
+
+dc:
+	if(c == '.')
+		goto casedot;
+	if(c == 'e' || c == 'E' || c == 'p' || c == 'P')
+		goto caseep;
+	if(c == 'i')
+		goto casei;
+
+ncu:
+	*cp = 0;
+	ungetc(c);
+
+	yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
+	mpatofix(yylval.val.u.xval, lexbuf);
+	if(yylval.val.u.xval->ovf) {
+		yyerror("overflow in constant");
+		mpmovecfix(yylval.val.u.xval, 0);
+	}
+	yylval.val.ctype = CTINT;
+	DBG("lex: integer literal\n");
+	strcpy(litbuf, "literal ");
+	strcat(litbuf, lexbuf);
+	return LLITERAL;
+
+casedot:
+	for(;;) {
+		if(cp+10 >= ep) {
+			yyerror("identifier too long");
+			errorexit();
+		}
+		*cp++ = c;
+		c = getc();
+		if(!yy_isdigit(c))
+			break;
+	}
+	if(c == 'i')
+		goto casei;
+	if(c != 'e' && c != 'E')
+		goto caseout;
+
+caseep:
+	*cp++ = c;
+	c = getc();
+	if(c == '+' || c == '-') {
+		*cp++ = c;
+		c = getc();
+	}
+	if(!yy_isdigit(c))
+		yyerror("malformed fp constant exponent");
+	while(yy_isdigit(c)) {
+		if(cp+10 >= ep) {
+			yyerror("identifier too long");
+			errorexit();
+		}
+		*cp++ = c;
+		c = getc();
+	}
+	if(c == 'i')
+		goto casei;
+	goto caseout;
+
+casei:
+	// imaginary constant
+	*cp = 0;
+	yylval.val.u.cval = mal(sizeof(*yylval.val.u.cval));
+	mpmovecflt(&yylval.val.u.cval->real, 0.0);
+	mpatoflt(&yylval.val.u.cval->imag, lexbuf);
+	if(yylval.val.u.cval->imag.val.ovf) {
+		yyerror("overflow in imaginary constant");
+		mpmovecflt(&yylval.val.u.cval->real, 0.0);
+	}
+	yylval.val.ctype = CTCPLX;
+	DBG("lex: imaginary literal\n");
+	strcpy(litbuf, "literal ");
+	strcat(litbuf, lexbuf);
+	return LLITERAL;
+
+caseout:
+	*cp = 0;
+	ungetc(c);
+
+	yylval.val.u.fval = mal(sizeof(*yylval.val.u.fval));
+	mpatoflt(yylval.val.u.fval, lexbuf);
+	if(yylval.val.u.fval->val.ovf) {
+		yyerror("overflow in float constant");
+		mpmovecflt(yylval.val.u.fval, 0.0);
+	}
+	yylval.val.ctype = CTFLT;
+	DBG("lex: floating literal\n");
+	strcpy(litbuf, "literal ");
+	strcat(litbuf, lexbuf);
+	return LLITERAL;
+}
+
+/*
+ * read and interpret syntax that looks like
+ * //line parse.y:15
+ * as a discontinuity in sequential line numbers.
+ * the next line of input comes from parse.y:15
+ */
+static int
+getlinepragma(void)
+{
+	int i, c, n;
+	char *cp, *ep, *linep;
+	Hist *h;
+
+	c = getr();
+	if(c == 'g')
+		goto go;
+	if(c != 'l')	
+		goto out;
+	for(i=1; i<5; i++) {
+		c = getr();
+		if(c != "line "[i])
+			goto out;
+	}
+
+	cp = lexbuf;
+	ep = lexbuf+sizeof(lexbuf)-5;
+	linep = nil;
+	for(;;) {
+		c = getr();
+		if(c == EOF)
+			goto out;
+		if(c == '\n')
+			break;
+		if(c == ' ')
+			continue;
+		if(c == ':')
+			linep = cp;
+		if(cp < ep)
+			*cp++ = c;
+	}
+	*cp = 0;
+
+	if(linep == nil || linep >= ep)
+		goto out;
+	*linep++ = '\0';
+	n = 0;
+	for(cp=linep; *cp; cp++) {
+		if(*cp < '0' || *cp > '9')
+			goto out;
+		n = n*10 + *cp - '0';
+		if(n > 1e8) {
+			yyerror("line number out of range");
+			errorexit();
+		}
+	}
+	if(n <= 0)
+		goto out;
+
+	// try to avoid allocating file name over and over
+	for(h=ctxt->hist; h!=nil; h=h->link) {
+		if(h->name != nil && strcmp(h->name, lexbuf) == 0) {
+			linehist(h->name, n, 0);
+			goto out;
+		}
+	}
+	linehist(strdup(lexbuf), n, 0);
+	goto out;
+
+go:
+	cp = lexbuf;
+	ep = lexbuf+sizeof(lexbuf)-5;
+	*cp++ = 'g'; // already read
+	for(;;) {
+		c = getr();
+		if(c == EOF || c >= Runeself)
+			goto out;
+		if(c == '\n')
+			break;
+		if(cp < ep)
+			*cp++ = c;
+	}
+	*cp = 0;
+	ep = strchr(lexbuf, ' ');
+	if(ep != nil)
+		*ep = 0;
+
+	if(strcmp(lexbuf, "go:nointerface") == 0 && fieldtrack_enabled) {
+		nointerface = 1;
+		goto out;
+	}
+	if(strcmp(lexbuf, "go:noescape") == 0) {
+		noescape = 1;
+		goto out;
+	}
+	if(strcmp(lexbuf, "go:nosplit") == 0) {
+		nosplit = 1;
+		goto out;
+	}
+	
+out:
+	return c;
+}
+
+int32
+yylex(void)
+{
+	int lx;
+	
+	lx = _yylex();
+	
+	if(curio.nlsemi && lx == EOF) {
+		// Treat EOF as "end of line" for the purposes
+		// of inserting a semicolon.
+		lx = ';';
+	}
+
+	switch(lx) {
+	case LNAME:
+	case LLITERAL:
+	case LBREAK:
+	case LCONTINUE:
+	case LFALL:
+	case LRETURN:
+	case LINC:
+	case LDEC:
+	case ')':
+	case '}':
+	case ']':
+		curio.nlsemi = 1;
+		break;
+	default:
+		curio.nlsemi = 0;
+		break;
+	}
+
+	// Track last two tokens returned by yylex.
+	yyprev = yylast;
+	yylast = lx;
+	return lx;
+}
+
+static int
+getc(void)
+{
+	int c, c1, c2;
+
+	c = curio.peekc;
+	if(c != 0) {
+		curio.peekc = curio.peekc1;
+		curio.peekc1 = 0;
+		goto check;
+	}
+	
+	if(curio.bin == nil) {
+		c = *curio.cp & 0xff;
+		if(c != 0)
+			curio.cp++;
+	} else {
+	loop:
+		c = BGETC(curio.bin);
+		if(c == 0xef) {
+			c1 = BGETC(curio.bin);
+			c2 = BGETC(curio.bin);
+			if(c1 == 0xbb && c2 == 0xbf) {
+				yyerrorl(lexlineno, "Unicode (UTF-8) BOM in middle of file");
+				goto loop;
+			}
+			Bungetc(curio.bin);
+			Bungetc(curio.bin);
+		}
+	}
+
+check:
+	switch(c) {
+	case 0:
+		if(curio.bin != nil) {
+			yyerror("illegal NUL byte");
+			break;
+		}
+	case EOF:
+		// insert \n at EOF
+		if(curio.eofnl || curio.last == '\n')
+			return EOF;
+		curio.eofnl = 1;
+		c = '\n';
+	case '\n':
+		if(pushedio.bin == nil)
+			lexlineno++;
+		break;
+	}
+	curio.last = c;
+	return c;
+}
+
+static void
+ungetc(int c)
+{
+	curio.peekc1 = curio.peekc;
+	curio.peekc = c;
+	if(c == '\n' && pushedio.bin == nil)
+		lexlineno--;
+}
+
+static int32
+getr(void)
+{
+	int c, i;
+	char str[UTFmax+1];
+	Rune rune;
+
+	c = getc();
+	if(c < Runeself)
+		return c;
+	i = 0;
+	str[i++] = c;
+
+loop:
+	c = getc();
+	str[i++] = c;
+	if(!fullrune(str, i))
+		goto loop;
+	c = chartorune(&rune, str);
+	if(rune == Runeerror && c == 1) {
+		lineno = lexlineno;
+		yyerror("illegal UTF-8 sequence");
+		flusherrors();
+		print("\t");
+		for(c=0; c<i; c++)
+			print("%s%.2x", c > 0 ? " " : "", *(uchar*)(str+c));
+		print("\n");
+	}
+	return rune;
+}
+
+static int
+escchar(int e, int *escflg, vlong *val)
+{
+	int i, u, c;
+	vlong l;
+
+	*escflg = 0;
+
+	c = getr();
+	switch(c) {
+	case EOF:
+		yyerror("eof in string");
+		return 1;
+	case '\n':
+		yyerror("newline in string");
+		return 1;
+	case '\\':
+		break;
+	default:
+		if(c == e)
+			return 1;
+		*val = c;
+		return 0;
+	}
+
+	u = 0;
+	c = getr();
+	switch(c) {
+	case 'x':
+		*escflg = 1;	// it's a byte
+		i = 2;
+		goto hex;
+
+	case 'u':
+		i = 4;
+		u = 1;
+		goto hex;
+
+	case 'U':
+		i = 8;
+		u = 1;
+		goto hex;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+		*escflg = 1;	// it's a byte
+		goto oct;
+
+	case 'a': c = '\a'; break;
+	case 'b': c = '\b'; break;
+	case 'f': c = '\f'; break;
+	case 'n': c = '\n'; break;
+	case 'r': c = '\r'; break;
+	case 't': c = '\t'; break;
+	case 'v': c = '\v'; break;
+	case '\\': c = '\\'; break;
+
+	default:
+		if(c != e)
+			yyerror("unknown escape sequence: %c", c);
+	}
+	*val = c;
+	return 0;
+
+hex:
+	l = 0;
+	for(; i>0; i--) {
+		c = getc();
+		if(c >= '0' && c <= '9') {
+			l = l*16 + c-'0';
+			continue;
+		}
+		if(c >= 'a' && c <= 'f') {
+			l = l*16 + c-'a' + 10;
+			continue;
+		}
+		if(c >= 'A' && c <= 'F') {
+			l = l*16 + c-'A' + 10;
+			continue;
+		}
+		yyerror("non-hex character in escape sequence: %c", c);
+		ungetc(c);
+		break;
+	}
+	if(u && (l > Runemax || (0xd800 <= l && l < 0xe000))) {
+		yyerror("invalid Unicode code point in escape sequence: %#llx", l);
+		l = Runeerror;
+	}
+	*val = l;
+	return 0;
+
+oct:
+	l = c - '0';
+	for(i=2; i>0; i--) {
+		c = getc();
+		if(c >= '0' && c <= '7') {
+			l = l*8 + c-'0';
+			continue;
+		}
+		yyerror("non-octal character in escape sequence: %c", c);
+		ungetc(c);
+	}
+	if(l > 255)
+		yyerror("octal escape value > 255: %d", l);
+
+	*val = l;
+	return 0;
+}
+
+static	struct
+{
+	char*	name;
+	int	lexical;
+	int	etype;
+	int	op;
+} syms[] =
+{
+/*	name		lexical		etype		op
+ */
+/* basic types */
+	{"int8",		LNAME,		TINT8,		OXXX},
+	{"int16",	LNAME,		TINT16,		OXXX},
+	{"int32",	LNAME,		TINT32,		OXXX},
+	{"int64",	LNAME,		TINT64,		OXXX},
+
+	{"uint8",	LNAME,		TUINT8,		OXXX},
+	{"uint16",	LNAME,		TUINT16,	OXXX},
+	{"uint32",	LNAME,		TUINT32,	OXXX},
+	{"uint64",	LNAME,		TUINT64,	OXXX},
+
+	{"float32",	LNAME,		TFLOAT32,	OXXX},
+	{"float64",	LNAME,		TFLOAT64,	OXXX},
+
+	{"complex64",	LNAME,		TCOMPLEX64,	OXXX},
+	{"complex128",	LNAME,		TCOMPLEX128,	OXXX},
+
+	{"bool",		LNAME,		TBOOL,		OXXX},
+	{"string",	LNAME,		TSTRING,	OXXX},
+
+	{"any",		LNAME,		TANY,		OXXX},
+
+	{"break",	LBREAK,		Txxx,		OXXX},
+	{"case",		LCASE,		Txxx,		OXXX},
+	{"chan",		LCHAN,		Txxx,		OXXX},
+	{"const",	LCONST,		Txxx,		OXXX},
+	{"continue",	LCONTINUE,	Txxx,		OXXX},
+	{"default",	LDEFAULT,	Txxx,		OXXX},
+	{"else",		LELSE,		Txxx,		OXXX},
+	{"defer",	LDEFER,		Txxx,		OXXX},
+	{"fallthrough",	LFALL,		Txxx,		OXXX},
+	{"for",		LFOR,		Txxx,		OXXX},
+	{"func",		LFUNC,		Txxx,		OXXX},
+	{"go",		LGO,		Txxx,		OXXX},
+	{"goto",		LGOTO,		Txxx,		OXXX},
+	{"if",		LIF,		Txxx,		OXXX},
+	{"import",	LIMPORT,	Txxx,		OXXX},
+	{"interface",	LINTERFACE,	Txxx,		OXXX},
+	{"map",		LMAP,		Txxx,		OXXX},
+	{"package",	LPACKAGE,	Txxx,		OXXX},
+	{"range",	LRANGE,		Txxx,		OXXX},
+	{"return",	LRETURN,	Txxx,		OXXX},
+	{"select",	LSELECT,	Txxx,		OXXX},
+	{"struct",	LSTRUCT,	Txxx,		OXXX},
+	{"switch",	LSWITCH,	Txxx,		OXXX},
+	{"type",		LTYPE,		Txxx,		OXXX},
+	{"var",		LVAR,		Txxx,		OXXX},
+
+	{"append",	LNAME,		Txxx,		OAPPEND},
+	{"cap",		LNAME,		Txxx,		OCAP},
+	{"close",	LNAME,		Txxx,		OCLOSE},
+	{"complex",	LNAME,		Txxx,		OCOMPLEX},
+	{"copy",		LNAME,		Txxx,		OCOPY},
+	{"delete",	LNAME,		Txxx,		ODELETE},
+	{"imag",		LNAME,		Txxx,		OIMAG},
+	{"len",		LNAME,		Txxx,		OLEN},
+	{"make",		LNAME,		Txxx,		OMAKE},
+	{"new",		LNAME,		Txxx,		ONEW},
+	{"panic",	LNAME,		Txxx,		OPANIC},
+	{"print",	LNAME,		Txxx,		OPRINT},
+	{"println",	LNAME,		Txxx,		OPRINTN},
+	{"real",		LNAME,		Txxx,		OREAL},
+	{"recover",	LNAME,		Txxx,		ORECOVER},
+
+	{"notwithstanding",		LIGNORE,	Txxx,		OXXX},
+	{"thetruthofthematter",		LIGNORE,	Txxx,		OXXX},
+	{"despiteallobjections",		LIGNORE,	Txxx,		OXXX},
+	{"whereas",			LIGNORE,	Txxx,		OXXX},
+	{"insofaras",			LIGNORE,	Txxx,		OXXX},
+};
+
+static void
+lexinit(void)
+{
+	int i, lex;
+	Sym *s, *s1;
+	Type *t;
+	int etype;
+	Val v;
+
+	/*
+	 * initialize basic types array
+	 * initialize known symbols
+	 */
+	for(i=0; i<nelem(syms); i++) {
+		lex = syms[i].lexical;
+		s = lookup(syms[i].name);
+		s->lexical = lex;
+
+		etype = syms[i].etype;
+		if(etype != Txxx) {
+			if(etype < 0 || etype >= nelem(types))
+				fatal("lexinit: %s bad etype", s->name);
+			s1 = pkglookup(syms[i].name, builtinpkg);
+			t = types[etype];
+			if(t == T) {
+				t = typ(etype);
+				t->sym = s1;
+
+				if(etype != TANY && etype != TSTRING)
+					dowidth(t);
+				types[etype] = t;
+			}
+			s1->lexical = LNAME;
+			s1->def = typenod(t);
+			continue;
+		}
+
+		etype = syms[i].op;
+		if(etype != OXXX) {
+			s1 = pkglookup(syms[i].name, builtinpkg);
+			s1->lexical = LNAME;
+			s1->def = nod(ONAME, N, N);
+			s1->def->sym = s1;
+			s1->def->etype = etype;
+			s1->def->builtin = 1;
+		}
+	}
+
+	// logically, the type of a string literal.
+	// types[TSTRING] is the named type string
+	// (the type of x in var x string or var x = "hello").
+	// this is the ideal form
+	// (the type of x in const x = "hello").
+	idealstring = typ(TSTRING);
+	idealbool = typ(TBOOL);
+
+	s = pkglookup("true", builtinpkg);
+	s->def = nodbool(1);
+	s->def->sym = lookup("true");
+	s->def->type = idealbool;
+
+	s = pkglookup("false", builtinpkg);
+	s->def = nodbool(0);
+	s->def->sym = lookup("false");
+	s->def->type = idealbool;
+
+	s = lookup("_");
+	s->block = -100;
+	s->def = nod(ONAME, N, N);
+	s->def->sym = s;
+	types[TBLANK] = typ(TBLANK);
+	s->def->type = types[TBLANK];
+	nblank = s->def;
+
+	s = pkglookup("_", builtinpkg);
+	s->block = -100;
+	s->def = nod(ONAME, N, N);
+	s->def->sym = s;
+	types[TBLANK] = typ(TBLANK);
+	s->def->type = types[TBLANK];
+
+	types[TNIL] = typ(TNIL);
+	s = pkglookup("nil", builtinpkg);
+	v.ctype = CTNIL;
+	s->def = nodlit(v);
+	s->def->sym = s;
+}
+
+static void
+lexinit1(void)
+{
+	Sym *s, *s1;
+	Type *t, *f, *rcvr, *in, *out;
+
+	// t = interface { Error() string }
+	rcvr = typ(TSTRUCT);
+	rcvr->type = typ(TFIELD);
+	rcvr->type->type = ptrto(typ(TSTRUCT));
+	rcvr->funarg = 1;
+	in = typ(TSTRUCT);
+	in->funarg = 1;
+	out = typ(TSTRUCT);
+	out->type = typ(TFIELD);
+	out->type->type = types[TSTRING];
+	out->funarg = 1;
+	f = typ(TFUNC);
+	*getthis(f) = rcvr;
+	*getoutarg(f) = out;
+	*getinarg(f) = in;
+	f->thistuple = 1;
+	f->intuple = 0;
+	f->outnamed = 0;
+	f->outtuple = 1;
+	t = typ(TINTER);
+	t->type = typ(TFIELD);
+	t->type->sym = lookup("Error");
+	t->type->type = f;
+
+	// error type
+	s = lookup("error");
+	s->lexical = LNAME;
+	s1 = pkglookup("error", builtinpkg);
+	errortype = t;
+	errortype->sym = s1;
+	s1->lexical = LNAME;
+	s1->def = typenod(errortype);
+
+	// byte alias
+	s = lookup("byte");
+	s->lexical = LNAME;
+	s1 = pkglookup("byte", builtinpkg);
+	bytetype = typ(TUINT8);
+	bytetype->sym = s1;
+	s1->lexical = LNAME;
+	s1->def = typenod(bytetype);
+
+	// rune alias
+	s = lookup("rune");
+	s->lexical = LNAME;
+	s1 = pkglookup("rune", builtinpkg);
+	runetype = typ(TINT32);
+	runetype->sym = s1;
+	s1->lexical = LNAME;
+	s1->def = typenod(runetype);
+}
+
+static void
+lexfini(void)
+{
+	Sym *s;
+	int lex, etype, i;
+	Val v;
+
+	for(i=0; i<nelem(syms); i++) {
+		lex = syms[i].lexical;
+		if(lex != LNAME)
+			continue;
+		s = lookup(syms[i].name);
+		s->lexical = lex;
+
+		etype = syms[i].etype;
+		if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N) {
+			s->def = typenod(types[etype]);
+			s->origpkg = builtinpkg;
+		}
+
+		etype = syms[i].op;
+		if(etype != OXXX && s->def == N) {
+			s->def = nod(ONAME, N, N);
+			s->def->sym = s;
+			s->def->etype = etype;
+			s->def->builtin = 1;
+			s->origpkg = builtinpkg;
+		}
+	}
+
+	// backend-specific builtin types (e.g. int).
+	for(i=0; typedefs[i].name; i++) {
+		s = lookup(typedefs[i].name);
+		if(s->def == N) {
+			s->def = typenod(types[typedefs[i].etype]);
+			s->origpkg = builtinpkg;
+		}
+	}
+
+	// there's only so much table-driven we can handle.
+	// these are special cases.
+	s = lookup("byte");
+	if(s->def == N) {
+		s->def = typenod(bytetype);
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("error");
+	if(s->def == N) {
+		s->def = typenod(errortype);
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("rune");
+	if(s->def == N) {
+		s->def = typenod(runetype);
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("nil");
+	if(s->def == N) {
+		v.ctype = CTNIL;
+		s->def = nodlit(v);
+		s->def->sym = s;
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("iota");
+	if(s->def == N) {
+		s->def = nod(OIOTA, N, N);
+		s->def->sym = s;
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("true");
+	if(s->def == N) {
+		s->def = nodbool(1);
+		s->def->sym = s;
+		s->origpkg = builtinpkg;
+	}
+
+	s = lookup("false");
+	if(s->def == N) {
+		s->def = nodbool(0);
+		s->def->sym = s;
+		s->origpkg = builtinpkg;
+	}
+
+	nodfp = nod(ONAME, N, N);
+	nodfp->type = types[TINT32];
+	nodfp->xoffset = 0;
+	nodfp->class = PPARAM;
+	nodfp->sym = lookup(".fp");
+}
+
+struct
+{
+	int	lex;
+	char*	name;
+} lexn[] =
+{
+	{LANDAND,	"ANDAND"},
+	{LANDNOT,	"ANDNOT"},
+	{LASOP,		"ASOP"},
+	{LBREAK,		"BREAK"},
+	{LCASE,		"CASE"},
+	{LCHAN,		"CHAN"},
+	{LCOLAS,		"COLAS"},
+	{LCOMM,		"<-"},
+	{LCONST,		"CONST"},
+	{LCONTINUE,	"CONTINUE"},
+	{LDDD,		"..."},
+	{LDEC,		"DEC"},
+	{LDEFAULT,	"DEFAULT"},
+	{LDEFER,		"DEFER"},
+	{LELSE,		"ELSE"},
+	{LEQ,		"EQ"},
+	{LFALL,		"FALL"},
+	{LFOR,		"FOR"},
+	{LFUNC,		"FUNC"},
+	{LGE,		"GE"},
+	{LGO,		"GO"},
+	{LGOTO,		"GOTO"},
+	{LGT,		"GT"},
+	{LIF,		"IF"},
+	{LIMPORT,	"IMPORT"},
+	{LINC,		"INC"},
+	{LINTERFACE,	"INTERFACE"},
+	{LLE,		"LE"},
+	{LLITERAL,	"LITERAL"},
+	{LLSH,		"LSH"},
+	{LLT,		"LT"},
+	{LMAP,		"MAP"},
+	{LNAME,		"NAME"},
+	{LNE,		"NE"},
+	{LOROR,		"OROR"},
+	{LPACKAGE,	"PACKAGE"},
+	{LRANGE,		"RANGE"},
+	{LRETURN,	"RETURN"},
+	{LRSH,		"RSH"},
+	{LSELECT,	"SELECT"},
+	{LSTRUCT,	"STRUCT"},
+	{LSWITCH,	"SWITCH"},
+	{LTYPE,		"TYPE"},
+	{LVAR,		"VAR"},
+};
+
+char*
+lexname(int lex)
+{
+	int i;
+	static char buf[100];
+
+	for(i=0; i<nelem(lexn); i++)
+		if(lexn[i].lex == lex)
+			return lexn[i].name;
+	snprint(buf, sizeof(buf), "LEX-%d", lex);
+	return buf;
+}
+
+struct
+{
+	char *have;
+	char *want;
+} yytfix[] =
+{
+	{"$end",	"EOF"},
+	{"LLITERAL",	"literal"},
+	{"LASOP",	"op="},
+	{"LBREAK",	"break"},
+	{"LCASE",	"case"},
+	{"LCHAN",	"chan"},
+	{"LCOLAS",	":="},
+	{"LCONST",	"const"},
+	{"LCONTINUE",	"continue"},
+	{"LDDD",	"..."},
+	{"LDEFAULT",	"default"},
+	{"LDEFER",	"defer"},
+	{"LELSE",	"else"},
+	{"LFALL",	"fallthrough"},
+	{"LFOR",	"for"},
+	{"LFUNC",	"func"},
+	{"LGO",	"go"},
+	{"LGOTO",	"goto"},
+	{"LIF",	"if"},
+	{"LIMPORT",	"import"},
+	{"LINTERFACE",	"interface"},
+	{"LMAP",	"map"},
+	{"LNAME",	"name"},
+	{"LPACKAGE",	"package"},
+	{"LRANGE",	"range"},
+	{"LRETURN",	"return"},
+	{"LSELECT",	"select"},
+	{"LSTRUCT",	"struct"},
+	{"LSWITCH",	"switch"},
+	{"LTYPE",	"type"},
+	{"LVAR",	"var"},
+	{"LANDAND",	"&&"},
+	{"LANDNOT",	"&^"},
+	{"LBODY",	"{"},
+	{"LCOMM",	"<-"},
+	{"LDEC",	"--"},
+	{"LINC",	"++"},
+	{"LEQ",	"=="},
+	{"LGE",	">="},
+	{"LGT",	">"},
+	{"LLE",	"<="},
+	{"LLT",	"<"},
+	{"LLSH",	"<<"},
+	{"LRSH",	">>"},
+	{"LOROR",	"||"},
+	{"LNE",	"!="},
+	
+	// spell out to avoid confusion with punctuation in error messages
+	{"';'",	"semicolon or newline"},
+	{"','",	"comma"},
+};
+
+static void
+yytinit(void)
+{
+	int i, j;
+	extern char *yytname[];
+	char *s, *t;
+
+	for(i=0; yytname[i] != nil; i++) {
+		s = yytname[i];
+		
+		if(strcmp(s, "LLITERAL") == 0) {
+			strcpy(litbuf, "literal");
+			yytname[i] = litbuf;
+			goto loop;
+		}
+		
+		// apply yytfix if possible
+		for(j=0; j<nelem(yytfix); j++) {
+			if(strcmp(s, yytfix[j].have) == 0) {
+				yytname[i] = yytfix[j].want;
+				goto loop;
+			}
+		}
+
+		// turn 'x' into x.
+		if(s[0] == '\'') {
+			t = strdup(s+1);
+			t[strlen(t)-1] = '\0';
+			yytname[i] = t;
+		}
+	loop:;
+	}		
+}
+
+static void
+pkgnotused(int lineno, Strlit *path, char *name)
+{
+	char *elem;
+	
+	// If the package was imported with a name other than the final
+	// import path element, show it explicitly in the error message.
+	// Note that this handles both renamed imports and imports of
+	// packages containing unconventional package declarations.
+	// Note that this uses / always, even on Windows, because Go import
+	// paths always use forward slashes.
+	elem = strrchr(path->s, '/');
+	if(elem != nil)
+		elem++;
+	else
+		elem = path->s;
+	if(name == nil || strcmp(elem, name) == 0)
+		yyerrorl(lineno, "imported and not used: \"%Z\"", path);
+	else
+		yyerrorl(lineno, "imported and not used: \"%Z\" as %s", path, name);
+}
+
+void
+mkpackage(char* pkgname)
+{
+	Sym *s;
+	int32 h;
+	char *p, *q;
+
+	if(localpkg->name == nil) {
+		if(strcmp(pkgname, "_") == 0)
+			yyerror("invalid package name _");
+		localpkg->name = pkgname;
+	} else {
+		if(strcmp(pkgname, localpkg->name) != 0)
+			yyerror("package %s; expected %s", pkgname, localpkg->name);
+		for(h=0; h<NHASH; h++) {
+			for(s = hash[h]; s != S; s = s->link) {
+				if(s->def == N || s->pkg != localpkg)
+					continue;
+				if(s->def->op == OPACK) {
+					// throw away top-level package name leftover
+					// from previous file.
+					// leave s->block set to cause redeclaration
+					// errors if a conflicting top-level name is
+					// introduced by a different file.
+					if(!s->def->used && !nsyntaxerrors)
+						pkgnotused(s->def->lineno, s->def->pkg->path, s->name);
+					s->def = N;
+					continue;
+				}
+				if(s->def->sym != s) {
+					// throw away top-level name left over
+					// from previous import . "x"
+					if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
+						pkgnotused(s->def->pack->lineno, s->def->pack->pkg->path, nil);
+						s->def->pack->used = 1;
+					}
+					s->def = N;
+					continue;
+				}
+			}
+		}
+	}
+
+	if(outfile == nil) {
+		p = strrchr(infile, '/');
+		if(ctxt->windows) {
+			q = strrchr(infile, '\\');
+			if(q > p)
+				p = q;
+		}
+		if(p == nil)
+			p = infile;
+		else
+			p = p+1;
+		snprint(namebuf, sizeof(namebuf), "%s", p);
+		p = strrchr(namebuf, '.');
+		if(p != nil)
+			*p = 0;
+		outfile = smprint("%s.%c", namebuf, thechar);
+	}
+}
diff --git a/src/cmd/gc/md5.c b/src/cmd/gc/md5.c
new file mode 100644
index 0000000..46cb6b7
--- /dev/null
+++ b/src/cmd/gc/md5.c
@@ -0,0 +1,302 @@
+// 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.
+
+// 64-bit MD5 (does full MD5 but returns 64 bits only).
+// Translation of ../../crypto/md5/md5*.go.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+#include "md5.h"
+
+static int md5block(MD5 *dig, uchar *p, int nn);
+
+enum {
+	_Chunk = 64
+};
+
+#define _Init0 0x67452301
+#define _Init1 0xEFCDAB89
+#define _Init2 0x98BADCFE
+#define _Init3 0x10325476
+/*c2go
+enum {
+	_Init0 = 0x67452301,
+	_Init1 = 0xEFCDAB89,
+	_Init2 = 0x98BADCFE,
+	_Init3 = 0x10325476
+};
+*/
+	
+void
+md5reset(MD5 *d)
+{
+	d->s[0] = _Init0;
+	d->s[1] = _Init1;
+	d->s[2] = _Init2;
+	d->s[3] = _Init3;
+	d->nx = 0;
+	d->len = 0;
+}
+
+void
+md5write(MD5 *d, uchar *p, int nn)
+{
+	int i, n;
+
+	d->len += nn;
+	if(d->nx > 0) {
+		n = nn;
+		if(n > _Chunk - d->nx)
+			n = _Chunk - d->nx;
+		for(i=0; i<n; i++)
+			d->x[d->nx+i] = p[i];
+		d->nx += n;
+		if(d->nx == _Chunk) {
+			md5block(d, d->x, _Chunk);
+			d->nx = 0;
+		}
+		p += n;
+		nn -= n;
+	}
+	n = md5block(d, p, nn);
+	p += n;
+	nn -= n;
+	if(nn > 0) {
+		for(i=0; i<nn; i++)
+			d->x[i] = p[i];
+		d->nx = nn;
+	}
+}
+
+uint64
+md5sum(MD5 *d, uint64 *hi)
+{
+	uchar tmp[64];
+	int i;
+	uint64 len;
+
+	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
+	len = d->len;
+	memset(tmp, 0, sizeof tmp);
+	tmp[0] = 0x80;
+	if(len%64 < 56)
+		md5write(d, tmp, 56-len%64);
+	else
+		md5write(d, tmp, 64+56-len%64);
+
+	// Length in bits.
+	len <<= 3;
+	for(i=0; i<8; i++)
+		tmp[i] = len>>(8*i);
+	md5write(d, tmp, 8);
+
+	if(d->nx != 0)
+		fatal("md5sum");
+
+	if(hi != nil)
+		*hi = d->s[2] | ((uint64)d->s[3]<<32);
+	return d->s[0] | ((uint64)d->s[1]<<32);
+}
+
+
+// MD5 block step.
+// In its own file so that a faster assembly or C version
+// can be substituted easily.
+
+// table[i] = int((1<<32) * abs(sin(i+1 radians))).
+static uint32 table[64] = {
+	// round 1
+	0xd76aa478,
+	0xe8c7b756,
+	0x242070db,
+	0xc1bdceee,
+	0xf57c0faf,
+	0x4787c62a,
+	0xa8304613,
+	0xfd469501,
+	0x698098d8,
+	0x8b44f7af,
+	0xffff5bb1,
+	0x895cd7be,
+	0x6b901122,
+	0xfd987193,
+	0xa679438e,
+	0x49b40821,
+
+	// round 2
+	0xf61e2562,
+	0xc040b340,
+	0x265e5a51,
+	0xe9b6c7aa,
+	0xd62f105d,
+	0x2441453,
+	0xd8a1e681,
+	0xe7d3fbc8,
+	0x21e1cde6,
+	0xc33707d6,
+	0xf4d50d87,
+	0x455a14ed,
+	0xa9e3e905,
+	0xfcefa3f8,
+	0x676f02d9,
+	0x8d2a4c8a,
+
+	// round3
+	0xfffa3942,
+	0x8771f681,
+	0x6d9d6122,
+	0xfde5380c,
+	0xa4beea44,
+	0x4bdecfa9,
+	0xf6bb4b60,
+	0xbebfbc70,
+	0x289b7ec6,
+	0xeaa127fa,
+	0xd4ef3085,
+	0x4881d05,
+	0xd9d4d039,
+	0xe6db99e5,
+	0x1fa27cf8,
+	0xc4ac5665,
+
+	// round 4
+	0xf4292244,
+	0x432aff97,
+	0xab9423a7,
+	0xfc93a039,
+	0x655b59c3,
+	0x8f0ccc92,
+	0xffeff47d,
+	0x85845dd1,
+	0x6fa87e4f,
+	0xfe2ce6e0,
+	0xa3014314,
+	0x4e0811a1,
+	0xf7537e82,
+	0xbd3af235,
+	0x2ad7d2bb,
+	0xeb86d391,
+};
+
+static uint32 shift1[] = { 7, 12, 17, 22 };
+static uint32 shift2[] = { 5, 9, 14, 20 };
+static uint32 shift3[] = { 4, 11, 16, 23 };
+static uint32 shift4[] = { 6, 10, 15, 21 };
+
+static int
+md5block(MD5 *dig, uchar *p, int nn)
+{
+	uint32 a, b, c, d, aa, bb, cc, dd;
+	int i, j, n;
+	uint32 X[16];
+
+	a = dig->s[0];
+	b = dig->s[1];
+	c = dig->s[2];
+	d = dig->s[3];
+	n = 0;
+
+	while(nn >= _Chunk) {
+		aa = a;
+		bb = b;
+		cc = c;
+		dd = d;
+
+		for(i=0; i<16; i++) {
+			j = i*4;
+			X[i] = p[j] | (p[j+1]<<8) | (p[j+2]<<16) | ((uint32)p[j+3]<<24);
+		}
+
+		// Round 1.
+		for(i=0; i<16; i++) {
+			uint32 x, t, s, f;
+			x = i;
+			t = i;
+			s = shift1[i%4];
+			f = ((c ^ d) & b) ^ d;
+			a += f + X[x] + table[t];
+			a = a<<s | a>>(32-s);
+			a += b;
+
+			t = d;
+			d = c;
+			c = b;
+			b = a;
+			a = t;
+		}
+
+		// Round 2.
+		for(i=0; i<16; i++) {
+			uint32 x, t, s, g;
+
+			x = (1+5*i)%16;
+			t = 16+i;
+			s = shift2[i%4];
+			g = ((b ^ c) & d) ^ c;
+			a += g + X[x] + table[t];
+			a = a<<s | a>>(32-s);
+			a += b;
+
+			t = d;
+			d = c;
+			c = b;
+			b = a;
+			a = t;
+		}
+
+		// Round 3.
+		for(i=0; i<16; i++) {
+			uint32 x, t, s, h;
+
+			x = (5+3*i)%16;
+			t = 32+i;
+			s = shift3[i%4];
+			h = b ^ c ^ d;
+			a += h + X[x] + table[t];
+			a = a<<s | a>>(32-s);
+			a += b;
+
+			t = d;
+			d = c;
+			c = b;
+			b = a;
+			a = t;
+		}
+
+		// Round 4.
+		for(i=0; i<16; i++) {
+			uint32 x, s, t, ii;
+
+			x = (7*i)%16;
+			s = shift4[i%4];
+			t = 48+i;
+			ii = c ^ (b | ~d);
+			a += ii + X[x] + table[t];
+			a = a<<s | a>>(32-s);
+			a += b;
+
+			t = d;
+			d = c;
+			c = b;
+			b = a;
+			a = t;
+		}
+
+		a += aa;
+		b += bb;
+		c += cc;
+		d += dd;
+
+		p += _Chunk;
+		n += _Chunk;
+		nn -= _Chunk;
+	}
+
+	dig->s[0] = a;
+	dig->s[1] = b;
+	dig->s[2] = c;
+	dig->s[3] = d;
+	return n;
+}
diff --git a/src/cmd/gc/md5.h b/src/cmd/gc/md5.h
new file mode 100644
index 0000000..5a60106
--- /dev/null
+++ b/src/cmd/gc/md5.h
@@ -0,0 +1,16 @@
+// 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.
+
+typedef struct MD5 MD5;
+struct MD5
+{
+	uint32 s[4];
+	uchar x[64];
+	int nx;
+	uint64 len;
+};
+
+void md5reset(MD5*);
+void md5write(MD5*, uchar*, int);
+uint64 md5sum(MD5*, uint64*);
diff --git a/src/cmd/gc/mkbuiltin b/src/cmd/gc/mkbuiltin
new file mode 100755
index 0000000..1dab1c9
--- /dev/null
+++ b/src/cmd/gc/mkbuiltin
@@ -0,0 +1,32 @@
+#!/bin/sh
+# 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.
+
+# Generate builtin.c from $* (runtime.go and unsafe.go).
+# Run this after changing runtime.go and unsafe.go
+# or after changing the export metadata format in the compiler.
+# Either way, you need to have a working compiler binary first.
+
+set -e
+
+eval $(go tool dist env)
+if [ -z "$GOCHAR" ]; then
+	echo 'missing $GOCHAR - go tool dist failed?' 1>&2
+	exit 1
+fi
+
+GC=${GOCHAR}g
+gcc -o mkbuiltin1 mkbuiltin1.c
+rm -f _builtin.c
+echo "// AUTO-GENERATED by mkbuiltin; DO NOT EDIT" >>_builtin.c
+for i in runtime unsafe
+do
+	go tool $GC -A $i.go
+	O=$GOCHAR ./mkbuiltin1 $i >>_builtin.c
+done
+
+# If _builtin.c has changed vs builtin.c,
+# check in the new change.
+cmp -s _builtin.c builtin.c || cp _builtin.c builtin.c
+rm _builtin.c mkbuiltin1 unsafe.$GOCHAR runtime.$GOCHAR
diff --git a/src/cmd/gc/mkbuiltin1.c b/src/cmd/gc/mkbuiltin1.c
new file mode 100644
index 0000000..69027fd
--- /dev/null
+++ b/src/cmd/gc/mkbuiltin1.c
@@ -0,0 +1,102 @@
+// 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.
+
+// +build ignore
+
+// Compile .go file, import data from .6 file, and generate C string version.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+
+void esc(char*);
+void fatal(char*, ...);
+
+int
+main(int argc, char **argv)
+{
+	char *name;
+	FILE *fin;
+	char buf[1024], initfunc[1024], *p, *q;
+
+	if(argc != 2) {
+		fprintf(stderr, "usage: mkbuiltin1 sys\n");
+		fatal("in file $1.6 s/PACKAGE/$1/");
+	}
+
+	name = argv[1];
+	snprintf(initfunc, sizeof(initfunc), "init_%s_function", name);
+
+	snprintf(buf, sizeof(buf), "%s.%s", name, getenv("O"));
+	if((fin = fopen(buf, "r")) == NULL) {
+		fatal("open %s: %s", buf, strerror(errno));
+	}
+
+	// look for $$ that introduces imports
+	while(fgets(buf, sizeof buf, fin) != NULL)
+		if(strstr(buf, "$$"))
+			goto begin;
+	fatal("did not find beginning of imports");
+
+begin:
+	printf("char *%simport =\n", name);
+
+	// process imports, stopping at $$ that closes them
+	while(fgets(buf, sizeof buf, fin) != NULL) {
+		buf[strlen(buf)-1] = 0;	// chop \n
+		if(strstr(buf, "$$"))
+			goto end;
+
+		// chop leading white space
+		for(p=buf; *p==' ' || *p == '\t'; p++)
+			;
+
+		// cut out decl of init_$1_function - it doesn't exist
+		if(strstr(buf, initfunc))
+			continue;
+
+		// sys.go claims to be in package PACKAGE to avoid
+		// conflicts during "6g sys.go".  rename PACKAGE to $2.
+		printf("\t\"");
+		while((q = strstr(p, "PACKAGE")) != NULL) {
+			*q = 0;
+			esc(p);	// up to the substitution
+			printf("%s", name);	// the sub name
+			p = q+7;		// continue with rest
+		}
+
+		esc(p);
+		printf("\\n\"\n");
+	}
+	fatal("did not find end of imports");
+
+end:
+	printf("\t\"$$\\n\";\n");
+	return 0;
+}
+
+void
+esc(char *p)
+{
+	for(; *p; p++) {
+		if(*p == '\\' || *p == '\"')
+			printf("\\");
+		putchar(*p);
+	}
+}
+
+void
+fatal(char *msg, ...)
+{
+	va_list arg;
+	
+	va_start(arg, msg);
+	fprintf(stderr, "fatal: ");
+	vfprintf(stderr, msg, arg);
+	fprintf(stderr, "\n");
+	exit(2);
+}
diff --git a/src/cmd/gc/mkopnames b/src/cmd/gc/mkopnames
new file mode 100755
index 0000000..d3f27e8
--- /dev/null
+++ b/src/cmd/gc/mkopnames
@@ -0,0 +1,24 @@
+#!/bin/sh
+# 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.
+
+# Disable colored grep if user has it set to --color=always.
+# (Arguably user error.)
+export GREP_OPTIONS=""
+
+echo '// auto generated by mkopnames'
+echo 'static char*'
+echo 'opnames[] = '
+echo '{'
+sed -n '/OXXX/,/OEND/p' go.h |
+	cpp |
+	sed 's!//.*!!; /^#/d'  |
+	tr ' ' '\012' |
+	tr -d ' \011,' |
+	grep . |
+	sort |
+	grep -v '^OEND$' |
+	sed 's/O//; s/.*/	[O&] =	"&",/'
+echo '};'
+
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c
new file mode 100644
index 0000000..d33a81e
--- /dev/null
+++ b/src/cmd/gc/mparith1.c
@@ -0,0 +1,641 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+/// uses arithmetic
+
+int
+mpcmpfixflt(Mpint *a, Mpflt *b)
+{
+	char buf[500];
+	Mpflt c;
+
+	snprint(buf, sizeof(buf), "%B", a);
+	mpatoflt(&c, buf);
+	return mpcmpfltflt(&c, b);
+}
+
+int
+mpcmpfltfix(Mpflt *a, Mpint *b)
+{
+	char buf[500];
+	Mpflt c;
+
+	snprint(buf, sizeof(buf), "%B", b);
+	mpatoflt(&c, buf);
+	return mpcmpfltflt(a, &c);
+}
+
+int
+mpcmpfixfix(Mpint *a, Mpint *b)
+{
+	Mpint c;
+
+	mpmovefixfix(&c, a);
+	mpsubfixfix(&c, b);
+	return mptestfix(&c);
+}
+
+int
+mpcmpfixc(Mpint *b, vlong c)
+{
+	Mpint c1;
+
+	mpmovecfix(&c1, c);
+	return mpcmpfixfix(b, &c1);
+}
+
+int
+mpcmpfltflt(Mpflt *a, Mpflt *b)
+{
+	Mpflt c;
+
+	mpmovefltflt(&c, a);
+	mpsubfltflt(&c, b);
+	return mptestflt(&c);
+}
+
+int
+mpcmpfltc(Mpflt *b, double c)
+{
+	Mpflt a;
+
+	mpmovecflt(&a, c);
+	return mpcmpfltflt(b, &a);
+}
+
+void
+mpsubfixfix(Mpint *a, Mpint *b)
+{
+	mpnegfix(a);
+	mpaddfixfix(a, b, 0);
+	mpnegfix(a);
+}
+
+void
+mpsubfltflt(Mpflt *a, Mpflt *b)
+{
+	mpnegflt(a);
+	mpaddfltflt(a, b);
+	mpnegflt(a);
+}
+
+void
+mpaddcfix(Mpint *a, vlong c)
+{
+	Mpint b;
+
+	mpmovecfix(&b, c);
+	mpaddfixfix(a, &b, 0);
+}
+
+void
+mpaddcflt(Mpflt *a, double c)
+{
+	Mpflt b;
+
+	mpmovecflt(&b, c);
+	mpaddfltflt(a, &b);
+}
+
+void
+mpmulcfix(Mpint *a, vlong c)
+{
+	Mpint b;
+
+	mpmovecfix(&b, c);
+	mpmulfixfix(a, &b);
+}
+
+void
+mpmulcflt(Mpflt *a, double c)
+{
+	Mpflt b;
+
+	mpmovecflt(&b, c);
+	mpmulfltflt(a, &b);
+}
+
+void
+mpdivfixfix(Mpint *a, Mpint *b)
+{
+	Mpint q, r;
+
+	mpdivmodfixfix(&q, &r, a, b);
+	mpmovefixfix(a, &q);
+}
+
+void
+mpmodfixfix(Mpint *a, Mpint *b)
+{
+	Mpint q, r;
+
+	mpdivmodfixfix(&q, &r, a, b);
+	mpmovefixfix(a, &r);
+}
+
+void
+mpcomfix(Mpint *a)
+{
+	Mpint b;
+
+	mpmovecfix(&b, 1);
+	mpnegfix(a);
+	mpsubfixfix(a, &b);
+}
+
+void
+mpmovefixflt(Mpflt *a, Mpint *b)
+{
+	a->val = *b;
+	a->exp = 0;
+	mpnorm(a);
+}
+
+// convert (truncate) b to a.
+// return -1 (but still convert) if b was non-integer.
+static int
+mpexactfltfix(Mpint *a, Mpflt *b)
+{
+	Mpflt f;
+
+	*a = b->val;
+	mpshiftfix(a, b->exp);
+	if(b->exp < 0) {
+		f.val = *a;
+		f.exp = 0;
+		mpnorm(&f);
+		if(mpcmpfltflt(b, &f) != 0)
+			return -1;
+	}
+	return 0;
+}
+
+int
+mpmovefltfix(Mpint *a, Mpflt *b)
+{
+	Mpflt f;
+	int i;
+
+	if(mpexactfltfix(a, b) == 0)
+		return 0;
+
+	// try rounding down a little
+	f = *b;
+	f.val.a[0] = 0;
+	if(mpexactfltfix(a, &f) == 0)
+		return 0;
+
+	// try rounding up a little
+	for(i=1; i<Mpprec; i++) {
+		f.val.a[i]++;
+		if(f.val.a[i] != Mpbase)
+			break;
+		f.val.a[i] = 0;
+	}
+	mpnorm(&f);
+	if(mpexactfltfix(a, &f) == 0)
+		return 0;
+
+	return -1;
+}
+
+void
+mpmovefixfix(Mpint *a, Mpint *b)
+{
+	*a = *b;
+}
+
+void
+mpmovefltflt(Mpflt *a, Mpflt *b)
+{
+	*a = *b;
+}
+
+static	double	tab[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7 };
+static void
+mppow10flt(Mpflt *a, int p)
+{
+	if(p < 0)
+		abort();
+	if(p < nelem(tab)) {
+		mpmovecflt(a, tab[p]);
+		return;
+	}
+	mppow10flt(a, p>>1);
+	mpmulfltflt(a, a);
+	if(p & 1)
+		mpmulcflt(a, 10);
+}
+
+static void
+mphextofix(Mpint *a, char *s, int n)
+{
+	char *hexdigitp, *end, c;
+	long d;
+	int bit;
+
+	while(*s == '0') {
+		s++;
+		n--;
+	}
+
+	// overflow
+	if(4*n > Mpscale*Mpprec) {
+		a->ovf = 1;
+		return;
+	}
+
+	end = s+n-1;
+	for(hexdigitp=end; hexdigitp>=s; hexdigitp--) {
+		c = *hexdigitp;
+		if(c >= '0' && c <= '9')
+			d = c-'0';
+		else if(c >= 'A' && c <= 'F')
+			d = c-'A'+10;
+		else
+			d = c-'a'+10;
+
+		bit = 4*(end - hexdigitp);
+		while(d > 0) {
+			if(d & 1)
+				a->a[bit/Mpscale] |= (long)1 << (bit%Mpscale);
+			bit++;
+			d = d >> 1;
+		}
+	}
+}
+
+//
+// floating point input
+// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
+//
+void
+mpatoflt(Mpflt *a, char *as)
+{
+	Mpflt b;
+	int dp, c, f, ef, ex, eb, base;
+	char *s, *start;
+
+	while(*as == ' ' || *as == '\t')
+		as++;
+
+	/* determine base */
+	s = as;
+	base = -1;
+	while(base == -1) {
+		switch(*s++) {
+		case '-':
+		case '+':
+			break;
+
+		case '0':
+			if(*s == 'x')
+				base = 16;
+			else
+				base = 10;
+			break;
+
+		default:
+			base = 10;
+		}
+	}
+
+	s = as;
+	dp = 0;		/* digits after decimal point */
+	f = 0;		/* sign */
+	ex = 0;		/* exponent */
+	eb = 0;		/* binary point */
+
+	mpmovecflt(a, 0.0);
+	if(base == 16) {
+		start = nil;
+		for(;;) {
+			c = *s;
+			if(c == '-') {
+				f = 1;
+				s++;
+			}
+			else if(c == '+') {
+				s++;
+			}
+			else if(c == '0' && s[1] == 'x') {
+				s += 2;
+				start = s;
+			}
+			else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
+				s++;
+			}
+			else {
+				break;
+			}
+		}
+		if(start == nil)
+			goto bad;
+
+		mphextofix(&a->val, start, s-start);
+		if(a->val.ovf)
+			goto bad;
+		a->exp = 0;
+		mpnorm(a);
+	}
+	for(;;) {
+		switch(c = *s++) {
+		default:
+			goto bad;
+
+		case '-':
+			f = 1;
+
+		case ' ':
+		case '\t':
+		case '+':
+			continue;
+
+		case '.':
+			if(base == 16)
+				goto bad;
+			dp = 1;
+			continue;
+
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		case '0':
+			mpmulcflt(a, 10);
+			mpaddcflt(a, c-'0');
+			if(dp)
+				dp++;
+			continue;
+
+		case 'P':
+		case 'p':
+			eb = 1;
+
+		case 'E':
+		case 'e':
+			ex = 0;
+			ef = 0;
+			for(;;) {
+				c = *s++;
+				if(c == '+' || c == ' ' || c == '\t')
+					continue;
+				if(c == '-') {
+					ef = 1;
+					continue;
+				}
+				if(c >= '0' && c <= '9') {
+					ex = ex*10 + (c-'0');
+					if(ex > 1e8) {
+						yyerror("constant exponent out of range: %s", as);
+						errorexit();
+					}
+					continue;
+				}
+				break;
+			}
+			if(ef)
+				ex = -ex;
+
+		case 0:
+			break;
+		}
+		break;
+	}
+
+	if(eb) {
+		if(dp)
+			goto bad;
+		mpsetexp(a, a->exp+ex);
+		goto out;
+	}
+
+	if(dp)
+		dp--;
+	if(mpcmpfltc(a, 0.0) != 0) {
+		if(ex >= dp) {
+			mppow10flt(&b, ex-dp);
+			mpmulfltflt(a, &b);
+		} else {
+			// 4 approximates least_upper_bound(log2(10)).
+			if(dp-ex >= (1<<(8*sizeof(dp)-3)) || (short)(4*(dp-ex)) != 4*(dp-ex)) {
+				mpmovecflt(a, 0.0);
+			}
+			else {
+				mppow10flt(&b, dp-ex);
+				mpdivfltflt(a, &b);
+			}
+		}
+	}
+
+out:
+	if(f)
+		mpnegflt(a);
+	return;
+
+bad:
+	yyerror("constant too large: %s", as);
+	mpmovecflt(a, 0.0);
+}
+
+//
+// fixed point input
+// required syntax is [+-][0[x]]d*
+//
+void
+mpatofix(Mpint *a, char *as)
+{
+	int c, f;
+	char *s, *s0;
+
+	s = as;
+	f = 0;
+	mpmovecfix(a, 0);
+
+	c = *s++;
+	switch(c) {
+	case '-':
+		f = 1;
+
+	case '+':
+		c = *s++;
+		if(c != '0')
+			break;
+
+	case '0':
+		goto oct;
+	}
+
+	while(c) {
+		if(c >= '0' && c <= '9') {
+			mpmulcfix(a, 10);
+			mpaddcfix(a, c-'0');
+			c = *s++;
+			continue;
+		}
+		goto bad;
+	}
+	goto out;
+
+oct:
+	c = *s++;
+	if(c == 'x' || c == 'X')
+		goto hex;
+	while(c) {
+		if(c >= '0' && c <= '7') {
+			mpmulcfix(a, 8);
+			mpaddcfix(a, c-'0');
+			c = *s++;
+			continue;
+		}
+		goto bad;
+	}
+	goto out;
+
+hex:
+	s0 = s;
+	c = *s;
+	while(c) {
+		if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
+			s++;
+			c = *s;
+			continue;
+		}
+		goto bad;
+	}
+	mphextofix(a, s0, s-s0);
+	if(a->ovf)
+		goto bad;
+
+out:
+	if(f)
+		mpnegfix(a);
+	return;
+
+bad:
+	yyerror("constant too large: %s", as);
+	mpmovecfix(a, 0);
+}
+
+int
+Bconv(Fmt *fp)
+{
+	char buf[500], *p;
+	Mpint *xval, q, r, ten, sixteen;
+	int f, digit;
+
+	xval = va_arg(fp->args, Mpint*);
+	mpmovefixfix(&q, xval);
+	f = 0;
+	if(mptestfix(&q) < 0) {
+		f = 1;
+		mpnegfix(&q);
+	}
+
+	p = &buf[sizeof(buf)];
+	*--p = 0;
+	if(fp->flags & FmtSharp) {
+		// Hexadecimal
+		mpmovecfix(&sixteen, 16);
+		for(;;) {
+			mpdivmodfixfix(&q, &r, &q, &sixteen);
+			digit = mpgetfix(&r);
+			if(digit < 10)
+				*--p = digit + '0';
+			else
+				*--p = digit - 10 + 'A';
+			if(mptestfix(&q) <= 0)
+				break;
+		}
+		*--p = 'x';
+		*--p = '0';
+	} else {
+		// Decimal
+		mpmovecfix(&ten, 10);
+		for(;;) {
+			mpdivmodfixfix(&q, &r, &q, &ten);
+			*--p = mpgetfix(&r) + '0';
+			if(mptestfix(&q) <= 0)
+				break;
+		}
+	}
+	if(f)
+		*--p = '-';
+	return fmtstrcpy(fp, p);
+}
+
+int
+Fconv(Fmt *fp)
+{
+	char buf[500];
+	Mpflt *fvp, fv;
+	double d, dexp;
+	int exp;
+
+	fvp = va_arg(fp->args, Mpflt*);
+	if(fp->flags & FmtSharp) {
+		// alternate form - decimal for error messages.
+		// for well in range, convert to double and use print's %g
+		exp = fvp->exp + sigfig(fvp)*Mpscale;
+		if(-900 < exp && exp < 900) {
+			d = mpgetflt(fvp);
+			if(d >= 0 && (fp->flags & FmtSign))
+				fmtprint(fp, "+");
+			return fmtprint(fp, "%g", d);
+		}
+		
+		// very out of range. compute decimal approximation by hand.
+		// decimal exponent
+		dexp = fvp->exp * 0.301029995663981195; // log_10(2)
+		exp = (int)dexp;
+		// decimal mantissa
+		fv = *fvp;
+		fv.val.neg = 0;
+		fv.exp = 0;
+		d = mpgetflt(&fv);
+		d *= pow(10, dexp-exp);
+		while(d >= 9.99995) {
+			d /= 10;
+			exp++;
+		}
+		if(fvp->val.neg)
+			fmtprint(fp, "-");
+		else if(fp->flags & FmtSign)
+			fmtprint(fp, "+");
+		return fmtprint(fp, "%.5fe+%d", d, exp);
+	}
+
+	if(sigfig(fvp) == 0) {
+		snprint(buf, sizeof(buf), "0p+0");
+		goto out;
+	}
+	fv = *fvp;
+
+	while(fv.val.a[0] == 0) {
+		mpshiftfix(&fv.val, -Mpscale);
+		fv.exp += Mpscale;
+	}
+	while((fv.val.a[0]&1) == 0) {
+		mpshiftfix(&fv.val, -1);
+		fv.exp += 1;
+	}
+
+	if(fv.exp >= 0) {
+		snprint(buf, sizeof(buf), "%#Bp+%d", &fv.val, fv.exp);
+		goto out;
+	}
+	snprint(buf, sizeof(buf), "%#Bp-%d", &fv.val, -fv.exp);
+
+out:
+	return fmtstrcpy(fp, buf);
+}
diff --git a/src/cmd/gc/mparith2.c b/src/cmd/gc/mparith2.c
new file mode 100644
index 0000000..fd9f591
--- /dev/null
+++ b/src/cmd/gc/mparith2.c
@@ -0,0 +1,716 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+//
+// return the significant
+// words of the argument
+//
+static int
+mplen(Mpint *a)
+{
+	int i, n;
+	long *a1;
+
+	n = -1;
+	a1 = &a->a[0];
+	for(i=0; i<Mpprec; i++) {
+		if(*a1++ != 0)
+			n = i;
+	}
+	return n+1;
+}
+
+//
+// left shift mpint by one
+// ignores sign
+//
+static void
+mplsh(Mpint *a, int quiet)
+{
+	long *a1, x;
+	int i, c;
+
+	c = 0;
+	a1 = &a->a[0];
+	for(i=0; i<Mpprec; i++) {
+		x = (*a1 << 1) + c;
+		c = 0;
+		if(x >= Mpbase) {
+			x -= Mpbase;
+			c = 1;
+		}
+		*a1++ = x;
+	}
+	a->ovf = c;
+	if(a->ovf && !quiet)
+		yyerror("constant shift overflow");
+}
+
+//
+// left shift mpint by Mpscale
+// ignores sign
+//
+static void
+mplshw(Mpint *a, int quiet)
+{
+	long *a1;
+	int i;
+
+	a1 = &a->a[Mpprec-1];
+	if(*a1) {
+		a->ovf = 1;
+		if(!quiet)
+			yyerror("constant shift overflow");
+	}
+	for(i=1; i<Mpprec; i++) {
+		a1[0] = a1[-1];
+		a1--;
+	}
+	a1[0] = 0;
+}
+
+//
+// right shift mpint by one
+// ignores sign and overflow
+//
+static void
+mprsh(Mpint *a)
+{
+	long *a1, x, lo;
+	int i, c;
+
+	c = 0;
+	lo = a->a[0] & 1;
+	a1 = &a->a[Mpprec];
+	for(i=0; i<Mpprec; i++) {
+		x = *--a1;
+		*a1 = (x + c) >> 1;
+		c = 0;
+		if(x & 1)
+			c = Mpbase;
+	}
+	if(a->neg && lo != 0)
+		mpaddcfix(a, -1);
+}
+
+//
+// right shift mpint by Mpscale
+// ignores sign and overflow
+//
+static void
+mprshw(Mpint *a)
+{
+	long *a1, lo;
+	int i;
+
+	lo = a->a[0];
+	a1 = &a->a[0];
+	for(i=1; i<Mpprec; i++) {
+		a1[0] = a1[1];
+		a1++;
+	}
+	a1[0] = 0;
+	if(a->neg && lo != 0)
+		mpaddcfix(a, -1);
+}
+
+//
+// return the sign of (abs(a)-abs(b))
+//
+static int
+mpcmp(Mpint *a, Mpint *b)
+{
+	long x, *a1, *b1;
+	int i;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in cmp");
+		return 0;
+	}
+
+	a1 = &a->a[0] + Mpprec;
+	b1 = &b->a[0] + Mpprec;
+
+	for(i=0; i<Mpprec; i++) {
+		x = *--a1 - *--b1;
+		if(x > 0)
+			return +1;
+		if(x < 0)
+			return -1;
+	}
+	return 0;
+}
+
+//
+// negate a
+// ignore sign and ovf
+//
+static void
+mpneg(Mpint *a)
+{
+	long x, *a1;
+	int i, c;
+
+	a1 = &a->a[0];
+	c = 0;
+	for(i=0; i<Mpprec; i++) {
+		x = -*a1 -c;
+		c = 0;
+		if(x < 0) {
+			x += Mpbase;
+			c = 1;
+		}
+		*a1++ = x;
+	}
+}
+
+// shift left by s (or right by -s)
+void
+mpshiftfix(Mpint *a, int s)
+{
+	if(s >= 0) {
+		while(s >= Mpscale) {
+			mplshw(a, 0);
+			s -= Mpscale;
+		}
+		while(s > 0) {
+			mplsh(a, 0);
+			s--;
+		}
+	} else {
+		s = -s;
+		while(s >= Mpscale) {
+			mprshw(a);
+			s -= Mpscale;
+		}
+		while(s > 0) {
+			mprsh(a);
+			s--;
+		}
+	}
+}
+
+/// implements fix arihmetic
+
+void
+mpaddfixfix(Mpint *a, Mpint *b, int quiet)
+{
+	int i, c;
+	long x, *a1, *b1;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mpaddxx");
+		a->ovf = 1;
+		return;
+	}
+
+	c = 0;
+	a1 = &a->a[0];
+	b1 = &b->a[0];
+	if(a->neg != b->neg)
+		goto sub;
+
+	// perform a+b
+	for(i=0; i<Mpprec; i++) {
+		x = *a1 + *b1++ + c;
+		c = 0;
+		if(x >= Mpbase) {
+			x -= Mpbase;
+			c = 1;
+		}
+		*a1++ = x;
+	}
+	a->ovf = c;
+	if(a->ovf && !quiet)
+		yyerror("constant addition overflow");
+
+	return;
+
+sub:
+	// perform a-b
+	switch(mpcmp(a, b)) {
+	case 0:
+		mpmovecfix(a, 0);
+		break;
+
+	case 1:
+		for(i=0; i<Mpprec; i++) {
+			x = *a1 - *b1++ - c;
+			c = 0;
+			if(x < 0) {
+				x += Mpbase;
+				c = 1;
+			}
+			*a1++ = x;
+		}
+		break;
+
+	case -1:
+		a->neg ^= 1;
+		for(i=0; i<Mpprec; i++) {
+			x = *b1++ - *a1 - c;
+			c = 0;
+			if(x < 0) {
+				x += Mpbase;
+				c = 1;
+			}
+			*a1++ = x;
+		}
+		break;
+	}
+}
+
+void
+mpmulfixfix(Mpint *a, Mpint *b)
+{
+
+	int i, j, na, nb;
+	long *a1, x;
+	Mpint s, q;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mpmulfixfix");
+		a->ovf = 1;
+		return;
+	}
+
+	// pick the smaller
+	// to test for bits
+	na = mplen(a);
+	nb = mplen(b);
+	if(na > nb) {
+		mpmovefixfix(&s, a);
+		a1 = &b->a[0];
+		na = nb;
+	} else {
+		mpmovefixfix(&s, b);
+		a1 = &a->a[0];
+	}
+	s.neg = 0;
+
+	mpmovecfix(&q, 0);
+	for(i=0; i<na; i++) {
+		x = *a1++;
+		for(j=0; j<Mpscale; j++) {
+			if(x & 1) {
+				if(s.ovf) {
+					q.ovf = 1;
+					goto out;
+				}
+				mpaddfixfix(&q, &s, 1);
+				if(q.ovf)
+					goto out;
+			}
+			mplsh(&s, 1);
+			x >>= 1;
+		}
+	}
+
+out:
+	q.neg = a->neg ^ b->neg;
+	mpmovefixfix(a, &q);
+	if(a->ovf)
+		yyerror("constant multiplication overflow");
+}
+
+void
+mpmulfract(Mpint *a, Mpint *b)
+{
+
+	int i, j;
+	long *a1, x;
+	Mpint s, q;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mpmulflt");
+		a->ovf = 1;
+		return;
+	}
+
+	mpmovefixfix(&s, b);
+	a1 = &a->a[Mpprec];
+	s.neg = 0;
+	mpmovecfix(&q, 0);
+
+	x = *--a1;
+	if(x != 0)
+		yyerror("mpmulfract not normal");
+
+	for(i=0; i<Mpprec-1; i++) {
+		x = *--a1;
+		if(x == 0) {
+			mprshw(&s);
+			continue;
+		}
+		for(j=0; j<Mpscale; j++) {
+			x <<= 1;
+			if(x & Mpbase)
+				mpaddfixfix(&q, &s, 1);
+			mprsh(&s);
+		}
+	}
+
+	q.neg = a->neg ^ b->neg;
+	mpmovefixfix(a, &q);
+	if(a->ovf)
+		yyerror("constant multiplication overflow");
+}
+
+void
+mporfixfix(Mpint *a, Mpint *b)
+{
+	int i;
+	long x, *a1, *b1;
+
+	x = 0;
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mporfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	if(a->neg) {
+		a->neg = 0;
+		mpneg(a);
+	}
+	if(b->neg)
+		mpneg(b);
+
+	a1 = &a->a[0];
+	b1 = &b->a[0];
+	for(i=0; i<Mpprec; i++) {
+		x = *a1 | *b1++;
+		*a1++ = x;
+	}
+
+	if(b->neg)
+		mpneg(b);
+	if(x & Mpsign) {
+		a->neg = 1;
+		mpneg(a);
+	}
+}
+
+void
+mpandfixfix(Mpint *a, Mpint *b)
+{
+	int i;
+	long x, *a1, *b1;
+
+	x = 0;
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mpandfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	if(a->neg) {
+		a->neg = 0;
+		mpneg(a);
+	}
+	if(b->neg)
+		mpneg(b);
+
+	a1 = &a->a[0];
+	b1 = &b->a[0];
+	for(i=0; i<Mpprec; i++) {
+		x = *a1 & *b1++;
+		*a1++ = x;
+	}
+
+	if(b->neg)
+		mpneg(b);
+	if(x & Mpsign) {
+		a->neg = 1;
+		mpneg(a);
+	}
+}
+
+void
+mpandnotfixfix(Mpint *a, Mpint *b)
+{
+	int i;
+	long x, *a1, *b1;
+
+	x = 0;
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mpandnotfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	if(a->neg) {
+		a->neg = 0;
+		mpneg(a);
+	}
+	if(b->neg)
+		mpneg(b);
+
+	a1 = &a->a[0];
+	b1 = &b->a[0];
+	for(i=0; i<Mpprec; i++) {
+		x = *a1 & ~*b1++;
+		*a1++ = x;
+	}
+
+	if(b->neg)
+		mpneg(b);
+	if(x & Mpsign) {
+		a->neg = 1;
+		mpneg(a);
+	}
+}
+
+void
+mpxorfixfix(Mpint *a, Mpint *b)
+{
+	int i;
+	long x, *a1, *b1;
+
+	x = 0;
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mporfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	if(a->neg) {
+		a->neg = 0;
+		mpneg(a);
+	}
+	if(b->neg)
+		mpneg(b);
+
+	a1 = &a->a[0];
+	b1 = &b->a[0];
+	for(i=0; i<Mpprec; i++) {
+		x = *a1 ^ *b1++;
+		*a1++ = x;
+	}
+
+	if(b->neg)
+		mpneg(b);
+	if(x & Mpsign) {
+		a->neg = 1;
+		mpneg(a);
+	}
+}
+
+void
+mplshfixfix(Mpint *a, Mpint *b)
+{
+	vlong s;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mporfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	s = mpgetfix(b);
+	if(s < 0 || s >= Mpprec*Mpscale) {
+		yyerror("stupid shift: %lld", s);
+		mpmovecfix(a, 0);
+		return;
+	}
+
+	mpshiftfix(a, s);
+}
+
+void
+mprshfixfix(Mpint *a, Mpint *b)
+{
+	vlong s;
+
+	if(a->ovf || b->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("ovf in mprshfixfix");
+		mpmovecfix(a, 0);
+		a->ovf = 1;
+		return;
+	}
+	s = mpgetfix(b);
+	if(s < 0 || s >= Mpprec*Mpscale) {
+		yyerror("stupid shift: %lld", s);
+		if(a->neg)
+			mpmovecfix(a, -1);
+		else
+			mpmovecfix(a, 0);
+		return;
+	}
+
+	mpshiftfix(a, -s);
+}
+
+void
+mpnegfix(Mpint *a)
+{
+	a->neg ^= 1;
+}
+
+vlong
+mpgetfix(Mpint *a)
+{
+	vlong v;
+
+	if(a->ovf) {
+		if(nsavederrors+nerrors == 0)
+			yyerror("constant overflow");
+		return 0;
+	}
+
+	v = (uvlong)a->a[0];
+	v |= (uvlong)a->a[1] << Mpscale;
+	v |= (uvlong)a->a[2] << (Mpscale+Mpscale);
+	if(a->neg)
+		v = -(uvlong)v;
+	return v;
+}
+
+void
+mpmovecfix(Mpint *a, vlong c)
+{
+	int i;
+	long *a1;
+	vlong x;
+
+	a->neg = 0;
+	a->ovf = 0;
+
+	x = c;
+	if(x < 0) {
+		a->neg = 1;
+		x = -(uvlong)x;
+	}
+
+	a1 = &a->a[0];
+	for(i=0; i<Mpprec; i++) {
+		*a1++ = x&Mpmask;
+		x >>= Mpscale;
+	}
+}
+
+void
+mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
+{
+	int i, ns, ds;
+
+	ns = n->neg;
+	ds = d->neg;
+	n->neg = 0;
+	d->neg = 0;
+
+	mpmovefixfix(r, n);
+	mpmovecfix(q, 0);
+
+	// shift denominator until it
+	// is larger than numerator
+	for(i=0; i<Mpprec*Mpscale; i++) {
+		if(mpcmp(d, r) > 0)
+			break;
+		mplsh(d, 1);
+	}
+
+	// if it never happens
+	// denominator is probably zero
+	if(i >= Mpprec*Mpscale) {
+		q->ovf = 1;
+		r->ovf = 1;
+		n->neg = ns;
+		d->neg = ds;
+		yyerror("constant division overflow");
+		return;
+	}
+
+	// shift denominator back creating
+	// quotient a bit at a time
+	// when done the remaining numerator
+	// will be the remainder
+	for(; i>0; i--) {
+		mplsh(q, 1);
+		mprsh(d);
+		if(mpcmp(d, r) <= 0) {
+			mpaddcfix(q, 1);
+			mpsubfixfix(r, d);
+		}
+	}
+
+	n->neg = ns;
+	d->neg = ds;
+	r->neg = ns;
+	q->neg = ns^ds;
+}
+
+static int
+mpiszero(Mpint *a)
+{
+	long *a1;
+	int i;
+	a1 = &a->a[0] + Mpprec;
+	for(i=0; i<Mpprec; i++) {
+		if(*--a1 != 0)
+			return 0;
+	}
+	return 1;
+}
+
+void
+mpdivfract(Mpint *a, Mpint *b)
+{
+	Mpint n, d;
+	int i, j, neg;
+	long *a1, x;
+
+	mpmovefixfix(&n, a);	// numerator
+	mpmovefixfix(&d, b);	// denominator
+	a1 = &a->a[Mpprec];	// quotient
+
+	neg = n.neg ^ d.neg;
+	n.neg = 0;
+	d.neg = 0;
+	for(i=0; i<Mpprec; i++) {
+		x = 0;
+		for(j=0; j<Mpscale; j++) {
+			x <<= 1;
+			if(mpcmp(&d, &n) <= 0) {
+				if(!mpiszero(&d))
+					x |= 1;
+				mpsubfixfix(&n, &d);
+			}
+			mprsh(&d);
+		}
+		*--a1 = x;
+	}
+	a->neg = neg;
+}
+
+int
+mptestfix(Mpint *a)
+{
+	Mpint b;
+	int r;
+
+	mpmovecfix(&b, 0);
+	r = mpcmp(a, &b);
+	if(a->neg) {
+		if(r > 0)
+			return -1;
+		if(r < 0)
+			return +1;
+	}
+	return r;
+}
diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c
new file mode 100644
index 0000000..6afd75c
--- /dev/null
+++ b/src/cmd/gc/mparith3.c
@@ -0,0 +1,346 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+/*
+ * returns the leading non-zero
+ * word of the number
+ */
+int
+sigfig(Mpflt *a)
+{
+	int i;
+
+	for(i=Mpprec-1; i>=0; i--)
+		if(a->val.a[i] != 0)
+			break;
+//print("sigfig %d %d\n", i-z+1, z);
+	return i+1;
+}
+
+/*
+ * sets the exponent.
+ * a too large exponent is an error.
+ * a too small exponent rounds the number to zero.
+ */
+void
+mpsetexp(Mpflt *a, int exp) {
+	if((short)exp != exp) {
+		if(exp > 0) {
+			yyerror("float constant is too large");
+			a->exp = 0x7fff;
+		}
+		else {
+			mpmovecflt(a, 0);
+		}
+	}
+	else {
+		a->exp = exp;
+	}
+}
+
+/*
+ * shifts the leading non-zero
+ * word of the number to Mpnorm
+ */
+void
+mpnorm(Mpflt *a)
+{
+	int s, os;
+	long x;
+
+	os = sigfig(a);
+	if(os == 0) {
+		// zero
+		a->exp = 0;
+		a->val.neg = 0;
+		return;
+	}
+
+	// this will normalize to the nearest word
+	x = a->val.a[os-1];
+	s = (Mpnorm-os) * Mpscale;
+
+	// further normalize to the nearest bit
+	for(;;) {
+		x <<= 1;
+		if(x & Mpbase)
+			break;
+		s++;
+		if(x == 0) {
+			// this error comes from trying to
+			// convert an Inf or something
+			// where the initial x=0x80000000
+			s = (Mpnorm-os) * Mpscale;
+			break;
+		}
+	}
+
+	mpshiftfix(&a->val, s);
+	mpsetexp(a, a->exp-s);
+}
+
+/// implements float arihmetic
+
+void
+mpaddfltflt(Mpflt *a, Mpflt *b)
+{
+	int sa, sb, s;
+	Mpflt c;
+
+	if(Mpdebug)
+		print("\n%F + %F", a, b);
+
+	sa = sigfig(a);
+	if(sa == 0) {
+		mpmovefltflt(a, b);
+		goto out;
+	}
+
+	sb = sigfig(b);
+	if(sb == 0)
+		goto out;
+
+	s = a->exp - b->exp;
+	if(s > 0) {
+		// a is larger, shift b right
+		mpmovefltflt(&c, b);
+		mpshiftfix(&c.val, -s);
+		mpaddfixfix(&a->val, &c.val, 0);
+		goto out;
+	}
+	if(s < 0) {
+		// b is larger, shift a right
+		mpshiftfix(&a->val, s);
+		mpsetexp(a, a->exp-s);
+		mpaddfixfix(&a->val, &b->val, 0);
+		goto out;
+	}
+	mpaddfixfix(&a->val, &b->val, 0);
+
+out:
+	mpnorm(a);
+	if(Mpdebug)
+		print(" = %F\n\n", a);
+}
+
+void
+mpmulfltflt(Mpflt *a, Mpflt *b)
+{
+	int sa, sb;
+
+	if(Mpdebug)
+		print("%F\n * %F\n", a, b);
+
+	sa = sigfig(a);
+	if(sa == 0) {
+		// zero
+		a->exp = 0;
+		a->val.neg = 0;
+		return;
+	}
+
+	sb = sigfig(b);
+	if(sb == 0) {
+		// zero
+		mpmovefltflt(a, b);
+		return;
+	}
+
+	mpmulfract(&a->val, &b->val);
+	mpsetexp(a, (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1);
+
+	mpnorm(a);
+	if(Mpdebug)
+		print(" = %F\n\n", a);
+}
+
+void
+mpdivfltflt(Mpflt *a, Mpflt *b)
+{
+	int sa, sb;
+	Mpflt c;
+
+	if(Mpdebug)
+		print("%F\n / %F\n", a, b);
+
+	sb = sigfig(b);
+	if(sb == 0) {
+		// zero and ovfl
+		a->exp = 0;
+		a->val.neg = 0;
+		a->val.ovf = 1;
+		yyerror("constant division by zero");
+		return;
+	}
+
+	sa = sigfig(a);
+	if(sa == 0) {
+		// zero
+		a->exp = 0;
+		a->val.neg = 0;
+		return;
+	}
+
+	// adjust b to top
+	mpmovefltflt(&c, b);
+	mpshiftfix(&c.val, Mpscale);
+
+	// divide
+	mpdivfract(&a->val, &c.val);
+	mpsetexp(a, (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1);
+
+	mpnorm(a);
+	if(Mpdebug)
+		print(" = %F\n\n", a);
+}
+
+static double
+mpgetfltN(Mpflt *a, int prec, int bias)
+{
+	int s, i, e, minexp;
+	uvlong v;
+	double f;
+
+	if(a->val.ovf && nsavederrors+nerrors == 0)
+		yyerror("mpgetflt ovf");
+
+	s = sigfig(a);
+	if(s == 0)
+		return 0;
+
+	if(s != Mpnorm) {
+		yyerror("mpgetflt norm");
+		mpnorm(a);
+	}
+
+	while((a->val.a[Mpnorm-1] & Mpsign) == 0) {
+		mpshiftfix(&a->val, 1);
+		mpsetexp(a, a->exp-1);	// can set 'a' to zero
+		s = sigfig(a);
+		if(s == 0)
+			return 0;
+	}
+
+	// pick up the mantissa, a rounding bit, and a tie-breaking bit in a uvlong
+	s = prec+2;
+	v = 0;
+	for(i=Mpnorm-1; s>=Mpscale; i--) {
+		v = (v<<Mpscale) | a->val.a[i];
+		s -= Mpscale;
+	}
+	if(s > 0) {
+		v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
+		if((a->val.a[i]&((1<<(Mpscale-s))-1)) != 0)
+			v |= 1;
+		i--;
+	}
+	for(; i >= 0; i--) {
+		if(a->val.a[i] != 0)
+			v |= 1;
+	}
+
+	// gradual underflow
+	e = Mpnorm*Mpscale + a->exp - prec;
+	minexp = bias+1-prec+1;
+	if(e < minexp) {
+		s = minexp - e;
+		if(s > prec+1)
+			s = prec+1;
+		if((v & ((1ULL<<s)-1)) != 0)
+			v |= 1ULL<<s;
+		v >>= s;
+		e = minexp;
+	}
+	
+	// round to even
+	v |= (v&4)>>2;
+	v += v&1;
+	v >>= 2;
+
+	f = (double)(v);
+	f = ldexp(f, e);
+
+	if(a->val.neg)
+		f = -f;
+
+	return f;
+}
+
+double
+mpgetflt(Mpflt *a)
+{
+	return mpgetfltN(a, 53, -1023);
+}
+
+double
+mpgetflt32(Mpflt *a)
+{
+	return mpgetfltN(a, 24, -127);
+}
+
+void
+mpmovecflt(Mpflt *a, double c)
+{
+	int i;
+	double f;
+	long l;
+
+	if(Mpdebug)
+		print("\nconst %g", c);
+	mpmovecfix(&a->val, 0);
+	a->exp = 0;
+	if(c == 0)
+		goto out;
+	if(c < 0) {
+		a->val.neg = 1;
+		c = -c;
+	}
+
+	f = frexp(c, &i);
+	a->exp = i;
+
+	for(i=0; i<10; i++) {
+		f = f*Mpbase;
+		l = floor(f);
+		f = f - l;
+		a->exp -= Mpscale;
+		a->val.a[0] = l;
+		if(f == 0)
+			break;
+		mpshiftfix(&a->val, Mpscale);
+	}
+
+out:
+	mpnorm(a);
+	if(Mpdebug)
+		print(" = %F\n", a);
+}
+
+void
+mpnegflt(Mpflt *a)
+{
+	a->val.neg ^= 1;
+}
+
+int
+mptestflt(Mpflt *a)
+{
+	int s;
+
+	if(Mpdebug)
+		print("\n%F?", a);
+	s = sigfig(a);
+	if(s != 0) {
+		s = +1;
+		if(a->val.neg)
+			s = -1;
+	}
+	if(Mpdebug)
+		print(" = %d\n", s);
+	return s;
+}
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
new file mode 100644
index 0000000..b752a13
--- /dev/null
+++ b/src/cmd/gc/obj.c
@@ -0,0 +1,284 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+#include "../ld/textflag.h"
+
+/*
+ * architecture-independent object file output
+ */
+
+static	void	dumpglobls(void);
+
+enum
+{
+	ArhdrSize = 60
+};
+
+static void
+formathdr(char *arhdr, char *name, vlong size)
+{
+	snprint(arhdr, ArhdrSize, "%-16s%-12d%-6d%-6d%-8o%-10lld`",
+		name, 0, 0, 0, 0644, size);
+	arhdr[ArhdrSize-1] = '\n'; // overwrite \0 written by snprint
+}
+
+void
+dumpobj(void)
+{
+	NodeList *externs, *tmp;
+	char arhdr[ArhdrSize];
+	vlong startobj, size;
+	Sym *zero;
+
+	bout = Bopen(outfile, OWRITE);
+	if(bout == nil) {
+		flusherrors();
+		print("can't create %s: %r\n", outfile);
+		errorexit();
+	}
+
+	startobj = 0;
+	if(writearchive) {
+		Bwrite(bout, "!<arch>\n", 8);
+		memset(arhdr, 0, sizeof arhdr);
+		Bwrite(bout, arhdr, sizeof arhdr);
+		startobj = Boffset(bout);
+	}
+	Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
+	dumpexport();
+	
+	if(writearchive) {
+		Bflush(bout);
+		size = Boffset(bout) - startobj;
+		if(size&1)
+			Bputc(bout, 0);
+		Bseek(bout, startobj - ArhdrSize, 0);
+		formathdr(arhdr, "__.PKGDEF", size);
+		Bwrite(bout, arhdr, ArhdrSize);
+		Bflush(bout);
+
+		Bseek(bout, startobj + size + (size&1), 0);
+		memset(arhdr, 0, ArhdrSize);
+		Bwrite(bout, arhdr, ArhdrSize);
+		startobj = Boffset(bout);
+		Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
+	}
+
+	Bprint(bout, "\n!\n");
+
+	externs = nil;
+	if(externdcl != nil)
+		externs = externdcl->end;
+
+	dumpglobls();
+	dumptypestructs();
+
+	// Dump extra globals.
+	tmp = externdcl;
+	if(externs != nil)
+		externdcl = externs->next;
+	dumpglobls();
+	externdcl = tmp;
+
+	zero = pkglookup("zerovalue", runtimepkg);
+	ggloblsym(zero, zerosize, DUPOK|RODATA);
+
+	dumpdata();
+	writeobj(ctxt, bout);
+
+	if(writearchive) {
+		Bflush(bout);
+		size = Boffset(bout) - startobj;
+		if(size&1)
+			Bputc(bout, 0);
+		Bseek(bout, startobj - ArhdrSize, 0);
+		snprint(namebuf, sizeof namebuf, "_go_.%c", thechar);
+		formathdr(arhdr, namebuf, size);
+		Bwrite(bout, arhdr, ArhdrSize);
+	}
+	Bterm(bout);
+}
+
+static void
+dumpglobls(void)
+{
+	Node *n;
+	NodeList *l;
+
+	// add globals
+	for(l=externdcl; l; l=l->next) {
+		n = l->n;
+		if(n->op != ONAME)
+			continue;
+
+		if(n->type == T)
+			fatal("external %N nil type\n", n);
+		if(n->class == PFUNC)
+			continue;
+		if(n->sym->pkg != localpkg)
+			continue;
+		dowidth(n->type);
+
+		ggloblnod(n);
+	}
+	
+	for(l=funcsyms; l; l=l->next) {
+		n = l->n;
+		dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
+		ggloblsym(n->sym, widthptr, DUPOK|RODATA);
+	}
+	
+	// Do not reprocess funcsyms on next dumpglobls call.
+	funcsyms = nil;
+}
+
+void
+Bputname(Biobuf *b, LSym *s)
+{
+	Bwrite(b, s->name, strlen(s->name)+1);
+}
+
+LSym*
+linksym(Sym *s)
+{
+	char *p;
+
+	if(s == nil)
+		return nil;
+	if(s->lsym != nil)
+		return s->lsym;
+	if(isblanksym(s))
+		s->lsym = linklookup(ctxt, "_", 0);
+	else {
+		p = smprint("%s.%s", s->pkg->prefix, s->name);
+		s->lsym = linklookup(ctxt, p, 0);
+		free(p);
+	}
+	return s->lsym;	
+}
+
+int
+duintxx(Sym *s, int off, uint64 v, int wid)
+{
+	// Update symbol data directly instead of generating a
+	// DATA instruction that liblink will have to interpret later.
+	// This reduces compilation time and memory usage.
+	off = rnd(off, wid);
+	return setuintxx(ctxt, linksym(s), off, v, wid);
+}
+
+int
+duint8(Sym *s, int off, uint8 v)
+{
+	return duintxx(s, off, v, 1);
+}
+
+int
+duint16(Sym *s, int off, uint16 v)
+{
+	return duintxx(s, off, v, 2);
+}
+
+int
+duint32(Sym *s, int off, uint32 v)
+{
+	return duintxx(s, off, v, 4);
+}
+
+int
+duint64(Sym *s, int off, uint64 v)
+{
+	return duintxx(s, off, v, 8);
+}
+
+int
+duintptr(Sym *s, int off, uint64 v)
+{
+	return duintxx(s, off, v, widthptr);
+}
+
+Sym*
+stringsym(char *s, int len)
+{
+	static int gen;
+	Sym *sym;
+	int off, n, m;
+	struct {
+		Strlit lit;
+		char buf[110];
+	} tmp;
+	Pkg *pkg;
+
+	if(len > 100) {
+		// huge strings are made static to avoid long names
+		snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
+		pkg = localpkg;
+	} else {
+		// small strings get named by their contents,
+		// so that multiple modules using the same string
+		// can share it.
+		tmp.lit.len = len;
+		memmove(tmp.lit.s, s, len);
+		tmp.lit.s[len] = '\0';
+		snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
+		pkg = gostringpkg;
+	}
+	sym = pkglookup(namebuf, pkg);
+	
+	// SymUniq flag indicates that data is generated already
+	if(sym->flags & SymUniq)
+		return sym;
+	sym->flags |= SymUniq;
+	sym->def = newname(sym);
+
+	off = 0;
+	
+	// string header
+	off = dsymptr(sym, off, sym, widthptr+widthint);
+	off = duintxx(sym, off, len, widthint);
+	
+	// string data
+	for(n=0; n<len; n+=m) {
+		m = 8;
+		if(m > len-n)
+			m = len-n;
+		off = dsname(sym, off, s+n, m);
+	}
+	off = duint8(sym, off, 0);  // terminating NUL for runtime
+	off = (off+widthptr-1)&~(widthptr-1);  // round to pointer alignment
+	ggloblsym(sym, off, DUPOK|RODATA);
+
+	return sym;	
+}
+
+void
+slicebytes(Node *nam, char *s, int len)
+{
+	int off, n, m;
+	static int gen;
+	Sym *sym;
+
+	snprint(namebuf, sizeof(namebuf), ".gobytes.%d", ++gen);
+	sym = pkglookup(namebuf, localpkg);
+	sym->def = newname(sym);
+
+	off = 0;
+	for(n=0; n<len; n+=m) {
+		m = 8;
+		if(m > len-n)
+			m = len-n;
+		off = dsname(sym, off, s+n, m);
+	}
+	ggloblsym(sym, off, NOPTR);
+	
+	if(nam->op != ONAME)
+		fatal("slicebytes %N", nam);
+	off = nam->xoffset;
+	off = dsymptr(nam->sym, off, sym, 0);
+	off = duintxx(nam->sym, off, len, widthint);
+	duintxx(nam->sym, off, len, widthint);
+}
diff --git a/src/cmd/gc/opnames.h b/src/cmd/gc/opnames.h
new file mode 100644
index 0000000..be93036
--- /dev/null
+++ b/src/cmd/gc/opnames.h
@@ -0,0 +1,155 @@
+// auto generated by go tool dist
+static char *opnames[] = {
+	[OXXX] = "XXX",
+	[ONAME] = "NAME",
+	[ONONAME] = "NONAME",
+	[OTYPE] = "TYPE",
+	[OPACK] = "PACK",
+	[OLITERAL] = "LITERAL",
+	[OADD] = "ADD",
+	[OSUB] = "SUB",
+	[OOR] = "OR",
+	[OXOR] = "XOR",
+	[OADDSTR] = "ADDSTR",
+	[OADDR] = "ADDR",
+	[OANDAND] = "ANDAND",
+	[OAPPEND] = "APPEND",
+	[OARRAYBYTESTR] = "ARRAYBYTESTR",
+	[OARRAYBYTESTRTMP] = "ARRAYBYTESTRTMP",
+	[OARRAYRUNESTR] = "ARRAYRUNESTR",
+	[OSTRARRAYBYTE] = "STRARRAYBYTE",
+	[OSTRARRAYRUNE] = "STRARRAYRUNE",
+	[OAS] = "AS",
+	[OAS2] = "AS2",
+	[OAS2FUNC] = "AS2FUNC",
+	[OAS2RECV] = "AS2RECV",
+	[OAS2MAPR] = "AS2MAPR",
+	[OAS2DOTTYPE] = "AS2DOTTYPE",
+	[OASOP] = "ASOP",
+	[OCALL] = "CALL",
+	[OCALLFUNC] = "CALLFUNC",
+	[OCALLMETH] = "CALLMETH",
+	[OCALLINTER] = "CALLINTER",
+	[OCALLPART] = "CALLPART",
+	[OCAP] = "CAP",
+	[OCLOSE] = "CLOSE",
+	[OCLOSURE] = "CLOSURE",
+	[OCMPIFACE] = "CMPIFACE",
+	[OCMPSTR] = "CMPSTR",
+	[OCOMPLIT] = "COMPLIT",
+	[OMAPLIT] = "MAPLIT",
+	[OSTRUCTLIT] = "STRUCTLIT",
+	[OARRAYLIT] = "ARRAYLIT",
+	[OPTRLIT] = "PTRLIT",
+	[OCONV] = "CONV",
+	[OCONVIFACE] = "CONVIFACE",
+	[OCONVNOP] = "CONVNOP",
+	[OCOPY] = "COPY",
+	[ODCL] = "DCL",
+	[ODCLFUNC] = "DCLFUNC",
+	[ODCLFIELD] = "DCLFIELD",
+	[ODCLCONST] = "DCLCONST",
+	[ODCLTYPE] = "DCLTYPE",
+	[ODELETE] = "DELETE",
+	[ODOT] = "DOT",
+	[ODOTPTR] = "DOTPTR",
+	[ODOTMETH] = "DOTMETH",
+	[ODOTINTER] = "DOTINTER",
+	[OXDOT] = "XDOT",
+	[ODOTTYPE] = "DOTTYPE",
+	[ODOTTYPE2] = "DOTTYPE2",
+	[OEQ] = "EQ",
+	[ONE] = "NE",
+	[OLT] = "LT",
+	[OLE] = "LE",
+	[OGE] = "GE",
+	[OGT] = "GT",
+	[OIND] = "IND",
+	[OINDEX] = "INDEX",
+	[OINDEXMAP] = "INDEXMAP",
+	[OKEY] = "KEY",
+	[OPARAM] = "PARAM",
+	[OLEN] = "LEN",
+	[OMAKE] = "MAKE",
+	[OMAKECHAN] = "MAKECHAN",
+	[OMAKEMAP] = "MAKEMAP",
+	[OMAKESLICE] = "MAKESLICE",
+	[OMUL] = "MUL",
+	[ODIV] = "DIV",
+	[OMOD] = "MOD",
+	[OLSH] = "LSH",
+	[ORSH] = "RSH",
+	[OAND] = "AND",
+	[OANDNOT] = "ANDNOT",
+	[ONEW] = "NEW",
+	[ONOT] = "NOT",
+	[OCOM] = "COM",
+	[OPLUS] = "PLUS",
+	[OMINUS] = "MINUS",
+	[OOROR] = "OROR",
+	[OPANIC] = "PANIC",
+	[OPRINT] = "PRINT",
+	[OPRINTN] = "PRINTN",
+	[OPAREN] = "PAREN",
+	[OSEND] = "SEND",
+	[OSLICE] = "SLICE",
+	[OSLICEARR] = "SLICEARR",
+	[OSLICESTR] = "SLICESTR",
+	[OSLICE3] = "SLICE3",
+	[OSLICE3ARR] = "SLICE3ARR",
+	[ORECOVER] = "RECOVER",
+	[ORECV] = "RECV",
+	[ORUNESTR] = "RUNESTR",
+	[OSELRECV] = "SELRECV",
+	[OSELRECV2] = "SELRECV2",
+	[OIOTA] = "IOTA",
+	[OREAL] = "REAL",
+	[OIMAG] = "IMAG",
+	[OCOMPLEX] = "COMPLEX",
+	[OBLOCK] = "BLOCK",
+	[OBREAK] = "BREAK",
+	[OCASE] = "CASE",
+	[OXCASE] = "XCASE",
+	[OCONTINUE] = "CONTINUE",
+	[ODEFER] = "DEFER",
+	[OEMPTY] = "EMPTY",
+	[OFALL] = "FALL",
+	[OXFALL] = "XFALL",
+	[OFOR] = "FOR",
+	[OGOTO] = "GOTO",
+	[OIF] = "IF",
+	[OLABEL] = "LABEL",
+	[OPROC] = "PROC",
+	[ORANGE] = "RANGE",
+	[ORETURN] = "RETURN",
+	[OSELECT] = "SELECT",
+	[OSWITCH] = "SWITCH",
+	[OTYPESW] = "TYPESW",
+	[OTCHAN] = "TCHAN",
+	[OTMAP] = "TMAP",
+	[OTSTRUCT] = "TSTRUCT",
+	[OTINTER] = "TINTER",
+	[OTFUNC] = "TFUNC",
+	[OTARRAY] = "TARRAY",
+	[ODDD] = "DDD",
+	[ODDDARG] = "DDDARG",
+	[OINLCALL] = "INLCALL",
+	[OEFACE] = "EFACE",
+	[OITAB] = "ITAB",
+	[OSPTR] = "SPTR",
+	[OCLOSUREVAR] = "CLOSUREVAR",
+	[OCFUNC] = "CFUNC",
+	[OCHECKNIL] = "CHECKNIL",
+	[OVARKILL] = "VARKILL",
+	[OREGISTER] = "REGISTER",
+	[OINDREG] = "INDREG",
+	[OCMP] = "CMP",
+	[ODEC] = "DEC",
+	[OINC] = "INC",
+	[OEXTEND] = "EXTEND",
+	[OHMUL] = "HMUL",
+	[OLROT] = "LROT",
+	[ORROTC] = "RROTC",
+	[ORETJMP] = "RETJMP",
+	[OEND] = "END",
+};
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
new file mode 100644
index 0000000..76820fd
--- /dev/null
+++ b/src/cmd/gc/order.c
@@ -0,0 +1,1101 @@
+// Copyright 2012 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.
+
+// Rewrite tree to use separate statements to enforce
+// order of evaluation.  Makes walk easier, because it
+// can (after this runs) reorder at will within an expression.
+//
+// Rewrite x op= y into x = x op y.
+//
+// Introduce temporaries as needed by runtime routines.
+// For example, the map runtime routines take the map key
+// by reference, so make sure all map keys are addressable
+// by copying them to temporaries as needed.
+// The same is true for channel operations.
+//
+// Arrange that map index expressions only appear in direct
+// assignments x = m[k] or m[k] = x, never in larger expressions.
+//
+// Arrange that receive expressions only appear in direct assignments
+// x = <-c or as standalone statements <-c, never in larger expressions.
+
+// TODO(rsc): The temporary introduction during multiple assignments
+// should be moved into this file, so that the temporaries can be cleaned
+// and so that conversions implicit in the OAS2FUNC and OAS2RECV
+// nodes can be made explicit and then have their temporaries cleaned.
+
+// TODO(rsc): Goto and multilevel break/continue can jump over
+// inserted VARKILL annotations. Work out a way to handle these.
+// The current implementation is safe, in that it will execute correctly.
+// But it won't reuse temporaries as aggressively as it might, and
+// it can result in unnecessary zeroing of those variables in the function
+// prologue.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+// Order holds state during the ordering process.
+typedef struct Order Order;
+struct Order
+{
+	NodeList *out; // list of generated statements
+	NodeList *temp; // head of stack of temporary variables
+	NodeList *free; // free list of NodeList* structs (for use in temp)
+};
+
+static void	orderstmt(Node*, Order*);
+static void	orderstmtlist(NodeList*, Order*);
+static void	orderblock(NodeList **l);
+static void	orderexpr(Node**, Order*);
+static void orderexprinplace(Node**, Order*);
+static void	orderexprlist(NodeList*, Order*);
+static void	orderexprlistinplace(NodeList*, Order*);
+
+// Order rewrites fn->nbody to apply the ordering constraints
+// described in the comment at the top of the file.
+void
+order(Node *fn)
+{
+	orderblock(&fn->nbody);
+}
+
+// Ordertemp allocates a new temporary with the given type,
+// pushes it onto the temp stack, and returns it.
+// If clear is true, ordertemp emits code to zero the temporary.
+static Node*
+ordertemp(Type *t, Order *order, int clear)
+{
+	Node *var, *a;
+	NodeList *l;
+
+	var = temp(t);
+	if(clear) {
+		a = nod(OAS, var, N);
+		typecheck(&a, Etop);
+		order->out = list(order->out, a);
+	}
+	if((l = order->free) == nil)
+		l = mal(sizeof *l);
+	order->free = l->next;
+	l->next = order->temp;
+	l->n = var;
+	order->temp = l;
+	return var;
+}
+
+// Ordercopyexpr behaves like ordertemp but also emits
+// code to initialize the temporary to the value n.
+//
+// The clear argument is provided for use when the evaluation
+// of tmp = n turns into a function call that is passed a pointer
+// to the temporary as the output space. If the call blocks before
+// tmp has been written, the garbage collector will still treat the
+// temporary as live, so we must zero it before entering that call.
+// Today, this only happens for channel receive operations.
+// (The other candidate would be map access, but map access
+// returns a pointer to the result data instead of taking a pointer
+// to be filled in.)
+static Node*
+ordercopyexpr(Node *n, Type *t, Order *order, int clear)
+{
+	Node *a, *var;
+
+	var = ordertemp(t, order, clear);
+	a = nod(OAS, var, n);
+	typecheck(&a, Etop);
+	order->out = list(order->out, a);
+	return var;
+}
+
+// Ordercheapexpr returns a cheap version of n.
+// The definition of cheap is that n is a variable or constant.
+// If not, ordercheapexpr allocates a new tmp, emits tmp = n,
+// and then returns tmp.
+static Node*
+ordercheapexpr(Node *n, Order *order)
+{
+	switch(n->op) {
+	case ONAME:
+	case OLITERAL:
+		return n;
+	}
+	return ordercopyexpr(n, n->type, order, 0);
+}
+
+// Ordersafeexpr returns a safe version of n.
+// The definition of safe is that n can appear multiple times
+// without violating the semantics of the original program,
+// and that assigning to the safe version has the same effect
+// as assigning to the original n.
+//
+// The intended use is to apply to x when rewriting x += y into x = x + y.
+static Node*
+ordersafeexpr(Node *n, Order *order)
+{
+	Node *l, *r, *a;
+	
+	switch(n->op) {
+	default:
+		fatal("ordersafeexpr %O", n->op);
+
+	case ONAME:
+	case OLITERAL:
+		return n;
+
+	case ODOT:
+		l = ordersafeexpr(n->left, order);
+		if(l == n->left)
+			return n;
+		a = nod(OXXX, N, N);
+		*a = *n;
+		a->orig = a;
+		a->left = l;
+		typecheck(&a, Erv);
+		return a;
+
+	case ODOTPTR:
+	case OIND:
+		l = ordercheapexpr(n->left, order);
+		if(l == n->left)
+			return n;
+		a = nod(OXXX, N, N);
+		*a = *n;
+		a->orig = a;
+		a->left = l;
+		typecheck(&a, Erv);
+		return a;
+		
+	case OINDEX:
+	case OINDEXMAP:
+		if(isfixedarray(n->left->type))
+			l = ordersafeexpr(n->left, order);
+		else
+			l = ordercheapexpr(n->left, order);
+		r = ordercheapexpr(n->right, order);
+		if(l == n->left && r == n->right)
+			return n;
+		a = nod(OXXX, N, N);
+		*a = *n;
+		a->orig = a;
+		a->left = l;
+		a->right = r;
+		typecheck(&a, Erv);
+		return a;
+	}
+}		
+
+// Istemp reports whether n is a temporary variable.
+static int
+istemp(Node *n)
+{
+	if(n->op != ONAME)
+		return 0;
+	return strncmp(n->sym->name, "autotmp_", 8) == 0;
+}
+
+// Isaddrokay reports whether it is okay to pass n's address to runtime routines.
+// Taking the address of a variable makes the liveness and optimization analyses
+// lose track of where the variable's lifetime ends. To avoid hurting the analyses
+// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
+// because we emit explicit VARKILL instructions marking the end of those
+// temporaries' lifetimes.
+static int
+isaddrokay(Node *n)
+{
+	return islvalue(n) && (n->op != ONAME || n->class == PEXTERN || istemp(n));
+}
+
+// Orderaddrtemp ensures that *np is okay to pass by address to runtime routines.
+// If the original argument *np is not okay, orderaddrtemp creates a tmp, emits
+// tmp = *np, and then sets *np to the tmp variable.
+static void
+orderaddrtemp(Node **np, Order *order)
+{
+	Node *n;
+	
+	n = *np;
+	if(isaddrokay(n))
+		return;
+	*np = ordercopyexpr(n, n->type, order, 0);
+}
+
+// Marktemp returns the top of the temporary variable stack.
+static NodeList*
+marktemp(Order *order)
+{
+	return order->temp;
+}
+
+// Poptemp pops temporaries off the stack until reaching the mark,
+// which must have been returned by marktemp.
+static void
+poptemp(NodeList *mark, Order *order)
+{
+	NodeList *l;
+
+	while((l = order->temp) != mark) {
+		order->temp = l->next;
+		l->next = order->free;
+		order->free = l;
+	}
+}
+
+// Cleantempnopop emits to *out VARKILL instructions for each temporary
+// above the mark on the temporary stack, but it does not pop them
+// from the stack.
+static void
+cleantempnopop(NodeList *mark, Order *order, NodeList **out)
+{
+	NodeList *l;
+	Node *kill;
+
+	for(l=order->temp; l != mark; l=l->next) {
+		kill = nod(OVARKILL, l->n, N);
+		typecheck(&kill, Etop);
+		*out = list(*out, kill);
+	}
+}
+
+// Cleantemp emits VARKILL instructions for each temporary above the
+// mark on the temporary stack and removes them from the stack.
+static void
+cleantemp(NodeList *top, Order *order)
+{
+	cleantempnopop(top, order, &order->out);
+	poptemp(top, order);
+}
+
+// Orderstmtlist orders each of the statements in the list.
+static void
+orderstmtlist(NodeList *l, Order *order)
+{
+	for(; l; l=l->next)
+		orderstmt(l->n, order);
+}
+
+// Orderblock orders the block of statements *l onto a new list,
+// and then replaces *l with that list.
+static void
+orderblock(NodeList **l)
+{
+	Order order;
+	NodeList *mark;
+	
+	memset(&order, 0, sizeof order);
+	mark = marktemp(&order);
+	orderstmtlist(*l, &order);
+	cleantemp(mark, &order);
+	*l = order.out;
+}
+
+// Orderexprinplace orders the side effects in *np and
+// leaves them as the init list of the final *np.
+static void
+orderexprinplace(Node **np, Order *outer)
+{
+	Node *n;
+	NodeList **lp;
+	Order order;
+	
+	n = *np;
+	memset(&order, 0, sizeof order);
+	orderexpr(&n, &order);
+	addinit(&n, order.out);
+	
+	// insert new temporaries from order
+	// at head of outer list.
+	lp = &order.temp;
+	while(*lp != nil)
+		lp = &(*lp)->next;
+	*lp = outer->temp;
+	outer->temp = order.temp;
+
+	*np = n;
+}
+
+// Orderstmtinplace orders the side effects of the single statement *np
+// and replaces it with the resulting statement list.
+void
+orderstmtinplace(Node **np)
+{
+	Node *n;
+	Order order;
+	NodeList *mark;
+	
+	n = *np;
+	memset(&order, 0, sizeof order);
+	mark = marktemp(&order);
+	orderstmt(n, &order);
+	cleantemp(mark, &order);
+	*np = liststmt(order.out);
+}
+
+// Orderinit moves n's init list to order->out.
+static void
+orderinit(Node *n, Order *order)
+{
+	orderstmtlist(n->ninit, order);
+	n->ninit = nil;
+}
+
+// Ismulticall reports whether the list l is f() for a multi-value function.
+// Such an f() could appear as the lone argument to a multi-arg function.
+static int
+ismulticall(NodeList *l)
+{
+	Node *n;
+	
+	// one arg only
+	if(l == nil || l->next != nil)
+		return 0;
+	n = l->n;
+	
+	// must be call
+	switch(n->op) {
+	default:
+		return 0;
+	case OCALLFUNC:
+	case OCALLMETH:
+	case OCALLINTER:
+		break;
+	}
+	
+	// call must return multiple values
+	return n->left->type->outtuple > 1;
+}
+
+// Copyret emits t1, t2, ... = n, where n is a function call,
+// and then returns the list t1, t2, ....
+static NodeList*
+copyret(Node *n, Order *order)
+{
+	Type *t;
+	Node *tmp, *as;
+	NodeList *l1, *l2;
+	Iter tl;
+	
+	if(n->type->etype != TSTRUCT || !n->type->funarg)
+		fatal("copyret %T %d", n->type, n->left->type->outtuple);
+
+	l1 = nil;
+	l2 = nil;
+	for(t=structfirst(&tl, &n->type); t; t=structnext(&tl)) {
+		tmp = temp(t->type);
+		l1 = list(l1, tmp);
+		l2 = list(l2, tmp);
+	}
+	
+	as = nod(OAS2, N, N);
+	as->list = l1;
+	as->rlist = list1(n);
+	typecheck(&as, Etop);
+	orderstmt(as, order);
+
+	return l2;
+}
+
+// Ordercallargs orders the list of call arguments *l.
+static void
+ordercallargs(NodeList **l, Order *order)
+{
+	if(ismulticall(*l)) {
+		// return f() where f() is multiple values.
+		*l = copyret((*l)->n, order);
+	} else {
+		orderexprlist(*l, order);
+	}
+}
+
+// Ordercall orders the call expression n.
+// n->op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
+static void
+ordercall(Node *n, Order *order)
+{
+	orderexpr(&n->left, order);
+	orderexpr(&n->right, order); // ODDDARG temp
+	ordercallargs(&n->list, order);
+}
+
+// Ordermapassign appends n to order->out, introducing temporaries
+// to make sure that all map assignments have the form m[k] = x,
+// where x is adressable.
+// (Orderexpr has already been called on n, so we know k is addressable.)
+//
+// If n is m[k] = x where x is not addressable, the rewrite is:
+//	tmp = x
+//	m[k] = tmp
+//
+// If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is
+//	t1 = m
+//	t2 = k
+//	...., t3, ... = x
+//	t1[t2] = t3
+//
+// The temporaries t1, t2 are needed in case the ... being assigned
+// contain m or k. They are usually unnecessary, but in the unnecessary
+// cases they are also typically registerizable, so not much harm done.
+// And this only applies to the multiple-assignment form.
+// We could do a more precise analysis if needed, like in walk.c.
+//
+// Ordermapassign also inserts these temporaries if needed for
+// calling writebarrierfat with a pointer to n->right.
+static void
+ordermapassign(Node *n, Order *order)
+{
+	Node *m, *a;
+	NodeList *l;
+	NodeList *post;
+
+	switch(n->op) {
+	default:
+		fatal("ordermapassign %O", n->op);
+
+	case OAS:
+		order->out = list(order->out, n);
+		// We call writebarrierfat only for values > 4 pointers long. See walk.c.
+		if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) {
+			m = n->left;
+			n->left = ordertemp(m->type, order, 0);
+			a = nod(OAS, m, n->left);
+			typecheck(&a, Etop);
+			order->out = list(order->out, a);
+		}
+		break;
+
+	case OAS2:
+	case OAS2DOTTYPE:
+	case OAS2MAPR:
+	case OAS2FUNC:
+		post = nil;
+		for(l=n->list; l != nil; l=l->next) {
+			if(l->n->op == OINDEXMAP) {
+				m = l->n;
+				if(!istemp(m->left))
+					m->left = ordercopyexpr(m->left, m->left->type, order, 0);
+				if(!istemp(m->right))
+					m->right = ordercopyexpr(m->right, m->right->type, order, 0);
+				l->n = ordertemp(m->type, order, 0);
+				a = nod(OAS, m, l->n);
+				typecheck(&a, Etop);
+				post = list(post, a);
+			}
+		}
+		order->out = list(order->out, n);
+		order->out = concat(order->out, post);
+		break;
+	}
+}
+
+// Orderstmt orders the statement n, appending to order->out.
+// Temporaries created during the statement are cleaned
+// up using VARKILL instructions as possible.
+static void
+orderstmt(Node *n, Order *order)
+{
+	int lno;
+	NodeList *l, *t, *t1;
+	Node *r, *tmp1, *tmp2, **np;
+	Type *ch;
+
+	if(n == N)
+		return;
+
+	lno = setlineno(n);
+
+	orderinit(n, order);
+
+	switch(n->op) {
+	default:
+		fatal("orderstmt %O", n->op);
+
+	case OVARKILL:
+		order->out = list(order->out, n);
+		break;
+
+	case OAS:
+	case OAS2:
+	case OAS2DOTTYPE:
+	case OCLOSE:
+	case OCOPY:
+	case OPRINT:
+	case OPRINTN:
+	case ORECOVER:
+	case ORECV:
+		t = marktemp(order);
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		orderexprlist(n->list, order);
+		orderexprlist(n->rlist, order);
+		switch(n->op) {
+		case OAS:
+		case OAS2:
+		case OAS2DOTTYPE:
+			ordermapassign(n, order);
+			break;
+		default:
+			order->out = list(order->out, n);
+			break;
+		}
+		cleantemp(t, order);
+		break;
+
+	case OASOP:
+		// Special: rewrite l op= r into l = l op r.
+		// This simplies quite a few operations;
+		// most important is that it lets us separate
+		// out map read from map write when l is
+		// a map index expression.
+		t = marktemp(order);
+		orderexpr(&n->left, order);
+		n->left = ordersafeexpr(n->left, order);
+		tmp1 = treecopy(n->left);
+		if(tmp1->op == OINDEXMAP)
+			tmp1->etype = 0; // now an rvalue not an lvalue
+		tmp1 = ordercopyexpr(tmp1, n->left->type, order, 0);
+		n->right = nod(n->etype, tmp1, n->right);
+		typecheck(&n->right, Erv);
+		orderexpr(&n->right, order);
+		n->etype = 0;
+		n->op = OAS;
+		ordermapassign(n, order);
+		cleantemp(t, order);
+		break;
+
+	case OAS2MAPR:
+		// Special: make sure key is addressable,
+		// and make sure OINDEXMAP is not copied out.
+		t = marktemp(order);
+		orderexprlist(n->list, order);
+		r = n->rlist->n;
+		orderexpr(&r->left, order);
+		orderexpr(&r->right, order);
+		// See case OINDEXMAP below.
+		if(r->right->op == OARRAYBYTESTR)
+			r->right->op = OARRAYBYTESTRTMP;
+		orderaddrtemp(&r->right, order);
+		ordermapassign(n, order);
+		cleantemp(t, order);
+		break;
+
+	case OAS2FUNC:
+		// Special: avoid copy of func call n->rlist->n.
+		t = marktemp(order);
+		orderexprlist(n->list, order);
+		ordercall(n->rlist->n, order);
+		ordermapassign(n, order);
+		cleantemp(t, order);
+		break;
+
+	case OAS2RECV:
+		// Special: avoid copy of receive.
+		// Use temporary variables to hold result,
+		// so that chanrecv can take address of temporary.
+		t = marktemp(order);
+		orderexprlist(n->list, order);
+		orderexpr(&n->rlist->n->left, order);  // arg to recv
+		ch = n->rlist->n->left->type;
+		tmp1 = ordertemp(ch->type, order, haspointers(ch->type));
+		if(!isblank(n->list->next->n))
+			tmp2 = ordertemp(n->list->next->n->type, order, 0);
+		else
+			tmp2 = ordertemp(types[TBOOL], order, 0);
+		order->out = list(order->out, n);
+		r = nod(OAS, n->list->n, tmp1);
+		typecheck(&r, Etop);
+		ordermapassign(r, order);
+		r = nod(OAS, n->list->next->n, tmp2);
+		typecheck(&r, Etop);
+		ordermapassign(r, order);
+		n->list = list(list1(tmp1), tmp2);
+		cleantemp(t, order);
+		break;
+
+	case OBLOCK:
+	case OEMPTY:
+		// Special: does not save n onto out.
+		orderstmtlist(n->list, order);
+		break;
+
+	case OBREAK:
+	case OCONTINUE:
+	case ODCL:
+	case ODCLCONST:
+	case ODCLTYPE:
+	case OFALL:
+	case OXFALL:
+	case OGOTO:
+	case OLABEL:
+	case ORETJMP:
+		// Special: n->left is not an expression; save as is.
+		order->out = list(order->out, n);
+		break;
+
+	case OCALLFUNC:
+	case OCALLINTER:
+	case OCALLMETH:
+		// Special: handle call arguments.
+		t = marktemp(order);
+		ordercall(n, order);
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case ODEFER:
+	case OPROC:
+		// Special: order arguments to inner call but not call itself.
+		t = marktemp(order);
+		switch(n->left->op) {
+		case ODELETE:
+			// Delete will take the address of the key.
+			// Copy key into new temp and do not clean it
+			// (it persists beyond the statement).
+			orderexprlist(n->left->list, order);
+			t1 = marktemp(order);
+			np = &n->left->list->next->n; // map key
+			*np = ordercopyexpr(*np, (*np)->type, order, 0);
+			poptemp(t1, order);
+			break;
+		default:
+			ordercall(n->left, order);
+			break;
+		}
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case ODELETE:
+		t = marktemp(order);
+		orderexpr(&n->list->n, order);
+		orderexpr(&n->list->next->n, order);
+		orderaddrtemp(&n->list->next->n, order); // map key
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case OFOR:
+		// Clean temporaries from condition evaluation at
+		// beginning of loop body and after for statement.
+		t = marktemp(order);
+		orderexprinplace(&n->ntest, order);
+		l = nil;
+		cleantempnopop(t, order, &l);
+		n->nbody = concat(l, n->nbody);
+		orderblock(&n->nbody);
+		orderstmtinplace(&n->nincr);
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+		
+	case OIF:
+		// Clean temporaries from condition at
+		// beginning of both branches.
+		t = marktemp(order);
+		orderexprinplace(&n->ntest, order);
+		l = nil;
+		cleantempnopop(t, order, &l);
+		n->nbody = concat(l, n->nbody);
+		l = nil;
+		cleantempnopop(t, order, &l);
+		n->nelse = concat(l, n->nelse);
+		poptemp(t, order);
+		orderblock(&n->nbody);
+		orderblock(&n->nelse);
+		order->out = list(order->out, n);
+		break;
+
+	case OPANIC:
+		// Special: argument will be converted to interface using convT2E
+		// so make sure it is an addressable temporary.
+		t = marktemp(order);
+		orderexpr(&n->left, order);
+		if(!isinter(n->left->type))
+			orderaddrtemp(&n->left, order);
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case ORANGE:
+		// n->right is the expression being ranged over.
+		// order it, and then make a copy if we need one.
+		// We almost always do, to ensure that we don't
+		// see any value changes made during the loop.
+		// Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny).
+		// The exception is ranging over an array value (not a slice, not a pointer to array),
+		// which must make a copy to avoid seeing updates made during
+		// the range body. Ranging over an array value is uncommon though.
+		t = marktemp(order);
+		orderexpr(&n->right, order);
+		switch(n->type->etype) {
+		default:
+			fatal("orderstmt range %T", n->type);
+		case TARRAY:
+			if(count(n->list) < 2 || isblank(n->list->next->n)) {
+				// for i := range x will only use x once, to compute len(x).
+				// No need to copy it.
+				break;
+			}
+			// fall through
+		case TCHAN:
+		case TSTRING:
+			// chan, string, slice, array ranges use value multiple times.
+			// make copy.
+			r = n->right;
+			if(r->type->etype == TSTRING && r->type != types[TSTRING]) {
+				r = nod(OCONV, r, N);
+				r->type = types[TSTRING];
+				typecheck(&r, Erv);
+			}
+			n->right = ordercopyexpr(r, r->type, order, 0);
+			break;
+		case TMAP:
+			// copy the map value in case it is a map literal.
+			// TODO(rsc): Make tmp = literal expressions reuse tmp.
+			// For maps tmp is just one word so it hardly matters.
+			r = n->right;
+			n->right = ordercopyexpr(r, r->type, order, 0);
+			// n->alloc is the temp for the iterator.
+			n->alloc = ordertemp(types[TUINT8], order, 1);
+			break;
+		}
+		for(l=n->list; l; l=l->next)
+			orderexprinplace(&l->n, order);
+		orderblock(&n->nbody);
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case ORETURN:
+		ordercallargs(&n->list, order);
+		order->out = list(order->out, n);
+		break;
+	
+	case OSELECT:
+		// Special: clean case temporaries in each block entry.
+		// Select must enter one of its blocks, so there is no
+		// need for a cleaning at the end.
+		// Doubly special: evaluation order for select is stricter
+		// than ordinary expressions. Even something like p.c
+		// has to be hoisted into a temporary, so that it cannot be
+		// reordered after the channel evaluation for a different
+		// case (if p were nil, then the timing of the fault would
+		// give this away).
+		t = marktemp(order);
+		for(l=n->list; l; l=l->next) {
+			if(l->n->op != OXCASE)
+				fatal("order select case %O", l->n->op);
+			r = l->n->left;
+			setlineno(l->n);
+			// Append any new body prologue to ninit.
+			// The next loop will insert ninit into nbody.
+			if(l->n->ninit != nil)
+				fatal("order select ninit");
+			if(r != nil) {
+				switch(r->op) {
+				default:
+					yyerror("unknown op in select %O", r->op);
+					dump("select case", r);
+					break;
+
+				case OSELRECV:
+				case OSELRECV2:
+					// If this is case x := <-ch or case x, y := <-ch, the case has
+					// the ODCL nodes to declare x and y. We want to delay that
+					// declaration (and possible allocation) until inside the case body.
+					// Delete the ODCL nodes here and recreate them inside the body below.
+					if(r->colas) {
+						t = r->ninit;
+						if(t != nil && t->n->op == ODCL && t->n->left == r->left)
+							t = t->next;
+						if(t != nil && t->n->op == ODCL && t->n->left == r->ntest)
+							t = t->next;
+						if(t == nil)
+							r->ninit = nil;
+					}
+					if(r->ninit != nil) {
+						yyerror("ninit on select recv");
+						dumplist("ninit", r->ninit);
+					}
+					// case x = <-c
+					// case x, ok = <-c
+					// r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c.
+					// r->left == N means 'case <-c'.
+					// c is always evaluated; x and ok are only evaluated when assigned.
+					orderexpr(&r->right->left, order);
+					if(r->right->left->op != ONAME)
+						r->right->left = ordercopyexpr(r->right->left, r->right->left->type, order, 0);
+
+					// Introduce temporary for receive and move actual copy into case body.
+					// avoids problems with target being addressed, as usual.
+					// NOTE: If we wanted to be clever, we could arrange for just one
+					// temporary per distinct type, sharing the temp among all receives
+					// with that temp. Similarly one ok bool could be shared among all
+					// the x,ok receives. Not worth doing until there's a clear need.
+					if(r->left != N && isblank(r->left))
+						r->left = N;
+					if(r->left != N) {
+						// use channel element type for temporary to avoid conversions,
+						// such as in case interfacevalue = <-intchan.
+						// the conversion happens in the OAS instead.
+						tmp1 = r->left;
+						if(r->colas) {
+							tmp2 = nod(ODCL, tmp1, N);
+							typecheck(&tmp2, Etop);
+							l->n->ninit = list(l->n->ninit, tmp2);
+						}
+						r->left = ordertemp(r->right->left->type->type, order, haspointers(r->right->left->type->type));
+						tmp2 = nod(OAS, tmp1, r->left);
+						typecheck(&tmp2, Etop);
+						l->n->ninit = list(l->n->ninit, tmp2);
+					}
+					if(r->ntest != N && isblank(r->ntest))
+						r->ntest = N;
+					if(r->ntest != N) {
+						tmp1 = r->ntest;
+						if(r->colas) {
+							tmp2 = nod(ODCL, tmp1, N);
+							typecheck(&tmp2, Etop);
+							l->n->ninit = list(l->n->ninit, tmp2);
+						}
+						r->ntest = ordertemp(tmp1->type, order, 0);
+						tmp2 = nod(OAS, tmp1, r->ntest);
+						typecheck(&tmp2, Etop);
+						l->n->ninit = list(l->n->ninit, tmp2);
+					}
+					orderblock(&l->n->ninit);
+					break;
+
+				case OSEND:
+					if(r->ninit != nil) {
+						yyerror("ninit on select send");
+						dumplist("ninit", r->ninit);
+					}
+					// case c <- x
+					// r->left is c, r->right is x, both are always evaluated.
+					orderexpr(&r->left, order);
+					if(!istemp(r->left))
+						r->left = ordercopyexpr(r->left, r->left->type, order, 0);
+					orderexpr(&r->right, order);
+					if(!istemp(r->right))
+						r->right = ordercopyexpr(r->right, r->right->type, order, 0);
+					break;
+				}
+			}
+			orderblock(&l->n->nbody);
+		}
+		// Now that we have accumulated all the temporaries, clean them.
+		// Also insert any ninit queued during the previous loop.
+		// (The temporary cleaning must follow that ninit work.)
+		for(l=n->list; l; l=l->next) {
+			cleantempnopop(t, order, &l->n->ninit);
+			l->n->nbody = concat(l->n->ninit, l->n->nbody);
+			l->n->ninit = nil;
+		}
+		order->out = list(order->out, n);
+		poptemp(t, order);
+		break;
+
+	case OSEND:
+		// Special: value being sent is passed as a pointer; make it addressable.
+		t = marktemp(order);
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		orderaddrtemp(&n->right, order);
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+
+	case OSWITCH:
+		// TODO(rsc): Clean temporaries more aggressively.
+		// Note that because walkswitch will rewrite some of the
+		// switch into a binary search, this is not as easy as it looks.
+		// (If we ran that code here we could invoke orderstmt on
+		// the if-else chain instead.)
+		// For now just clean all the temporaries at the end.
+		// In practice that's fine.
+		t = marktemp(order);
+		orderexpr(&n->ntest, order);
+		for(l=n->list; l; l=l->next) {
+			if(l->n->op != OXCASE)
+				fatal("order switch case %O", l->n->op);
+			orderexprlistinplace(l->n->list, order);
+			orderblock(&l->n->nbody);
+		}
+		order->out = list(order->out, n);
+		cleantemp(t, order);
+		break;
+	}
+	
+	lineno = lno;
+}
+
+// Orderexprlist orders the expression list l into order.
+static void
+orderexprlist(NodeList *l, Order *order)
+{
+	for(; l; l=l->next)
+		orderexpr(&l->n, order);
+}
+
+// Orderexprlist orders the expression list l but saves
+// the side effects on the individual expression ninit lists.
+static void
+orderexprlistinplace(NodeList *l, Order *order)
+{
+	for(; l; l=l->next)
+		orderexprinplace(&l->n, order);
+}
+
+// Orderexpr orders a single expression, appending side
+// effects to order->out as needed.
+static void
+orderexpr(Node **np, Order *order)
+{
+	Node *n;
+	NodeList *mark, *l;
+	Type *t;
+	int lno;
+
+	n = *np;
+	if(n == N)
+		return;
+
+	lno = setlineno(n);
+	orderinit(n, order);
+
+	switch(n->op) {
+	default:
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		orderexprlist(n->list, order);
+		orderexprlist(n->rlist, order);
+		break;
+	
+	case OADDSTR:
+		// Addition of strings turns into a function call.
+		// Allocate a temporary to hold the strings.
+		// Fewer than 5 strings use direct runtime helpers.
+		orderexprlist(n->list, order);
+		if(count(n->list) > 5) {
+			t = typ(TARRAY);
+			t->bound = count(n->list);
+			t->type = types[TSTRING];
+			n->alloc = ordertemp(t, order, 0);
+		}
+		break;
+
+	case OINDEXMAP:
+		// key must be addressable
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+
+		// For x = m[string(k)] where k is []byte, the allocation of
+		// backing bytes for the string can be avoided by reusing
+		// the []byte backing array. This is a special case that it
+		// would be nice to handle more generally, but because
+		// there are no []byte-keyed maps, this specific case comes
+		// up in important cases in practice. See issue 3512.
+		// Nothing can change the []byte we are not copying before
+		// the map index, because the map access is going to
+		// be forced to happen immediately following this
+		// conversion (by the ordercopyexpr a few lines below).
+		if(n->etype == 0 && n->right->op == OARRAYBYTESTR)
+			n->right->op = OARRAYBYTESTRTMP;
+
+		orderaddrtemp(&n->right, order);
+		if(n->etype == 0) {
+			// use of value (not being assigned);
+			// make copy in temporary.
+			n = ordercopyexpr(n, n->type, order, 0);
+		}
+		break;
+	
+	case OCONVIFACE:
+		// concrete type (not interface) argument must be addressable
+		// temporary to pass to runtime.
+		orderexpr(&n->left, order);
+		if(!isinter(n->left->type))
+			orderaddrtemp(&n->left, order);
+		break;
+	
+	case OANDAND:
+	case OOROR:
+		mark = marktemp(order);
+		orderexpr(&n->left, order);
+		// Clean temporaries from first branch at beginning of second.
+		// Leave them on the stack so that they can be killed in the outer
+		// context in case the short circuit is taken.
+		l = nil;
+		cleantempnopop(mark, order, &l);
+		n->right->ninit = concat(l, n->right->ninit);
+		orderexprinplace(&n->right, order);
+		break;
+	
+	case OAPPEND:
+	case OCALLFUNC:
+	case OCALLINTER:
+	case OCALLMETH:
+	case OCAP:
+	case OCOMPLEX:
+	case OCOPY:
+	case OIMAG:
+	case OLEN:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case ONEW:
+	case OREAL:
+	case ORECOVER:
+		ordercall(n, order);
+		n = ordercopyexpr(n, n->type, order, 0);
+		break;
+
+	case OCLOSURE:
+		if(n->noescape && n->cvars != nil)
+			n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
+		break;
+
+	case OARRAYLIT:
+	case OCALLPART:
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		orderexprlist(n->list, order);
+		orderexprlist(n->rlist, order);
+		if(n->noescape)
+			n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
+		break;
+
+	case ODDDARG:
+		if(n->noescape) {
+			// The ddd argument does not live beyond the call it is created for.
+			// Allocate a temporary that will be cleaned up when this statement
+			// completes. We could be more aggressive and try to arrange for it
+			// to be cleaned up when the call completes.
+			n->alloc = ordertemp(n->type->type, order, 0);
+		}
+		break;
+
+	case ORECV:
+		orderexpr(&n->left, order);
+		n = ordercopyexpr(n, n->type, order, 1);
+		break;
+
+	case OEQ:
+	case ONE:
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		t = n->left->type;
+		if(t->etype == TSTRUCT || isfixedarray(t)) {
+			// for complex comparisons, we need both args to be
+			// addressable so we can pass them to the runtime.
+			orderaddrtemp(&n->left, order);
+			orderaddrtemp(&n->right, order);
+		}
+		break;
+	}
+	
+	lineno = lno;
+
+	*np = n;
+}
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
new file mode 100644
index 0000000..39028e3
--- /dev/null
+++ b/src/cmd/gc/pgen.c
@@ -0,0 +1,539 @@
+// Copyright 2011 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.
+
+// "Portable" code generation.
+// Compiled separately for 5g, 6g, and 8g, so allowed to use gg.h, opt.h.
+// Must code to the intersection of the three back ends.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"md5.h"
+#include	"gg.h"
+#include	"opt.h"
+#include	"../../runtime/funcdata.h"
+
+static void allocauto(Prog* p);
+static void emitptrargsmap(void);
+
+static Sym*
+makefuncdatasym(char *namefmt, int64 funcdatakind)
+{
+	Node nod;
+	Node *pnod;
+	Sym *sym;
+	static int32 nsym;
+
+	snprint(namebuf, sizeof(namebuf), namefmt, nsym++);
+	sym = lookup(namebuf);
+	pnod = newname(sym);
+	pnod->class = PEXTERN;
+	nodconst(&nod, types[TINT32], funcdatakind);
+	gins(AFUNCDATA, &nod, pnod);
+	return sym;
+}
+
+// gvardef inserts a VARDEF for n into the instruction stream.
+// VARDEF is an annotation for the liveness analysis, marking a place
+// where a complete initialization (definition) of a variable begins.
+// Since the liveness analysis can see initialization of single-word
+// variables quite easy, gvardef is usually only called for multi-word
+// or 'fat' variables, those satisfying isfat(n->type).
+// However, gvardef is also called when a non-fat variable is initialized
+// via a block move; the only time this happens is when you have
+//	return f()
+// for a function with multiple return values exactly matching the return
+// types of the current function.
+//
+// A 'VARDEF x' annotation in the instruction stream tells the liveness
+// analysis to behave as though the variable x is being initialized at that
+// point in the instruction stream. The VARDEF must appear before the
+// actual (multi-instruction) initialization, and it must also appear after
+// any uses of the previous value, if any. For example, if compiling:
+//
+//	x = x[1:]
+//
+// it is important to generate code like:
+//
+//	base, len, cap = pieces of x[1:]
+//	VARDEF x
+//	x = {base, len, cap}
+//
+// If instead the generated code looked like:
+//
+//	VARDEF x
+//	base, len, cap = pieces of x[1:]
+//	x = {base, len, cap}
+//
+// then the liveness analysis would decide the previous value of x was
+// unnecessary even though it is about to be used by the x[1:] computation.
+// Similarly, if the generated code looked like:
+//
+//	base, len, cap = pieces of x[1:]
+//	x = {base, len, cap}
+//	VARDEF x
+//
+// then the liveness analysis will not preserve the new value of x, because
+// the VARDEF appears to have "overwritten" it.
+//
+// VARDEF is a bit of a kludge to work around the fact that the instruction
+// stream is working on single-word values but the liveness analysis
+// wants to work on individual variables, which might be multi-word
+// aggregates. It might make sense at some point to look into letting
+// the liveness analysis work on single-word values as well, although
+// there are complications around interface values, slices, and strings,
+// all of which cannot be treated as individual words.
+//
+// VARKILL is the opposite of VARDEF: it marks a value as no longer needed,
+// even if its address has been taken. That is, a VARKILL annotation asserts
+// that its argument is certainly dead, for use when the liveness analysis
+// would not otherwise be able to deduce that fact.
+
+static void
+gvardefx(Node *n, int as)
+{
+	if(n == N)
+		fatal("gvardef nil");
+	if(n->op != ONAME) {
+		yyerror("gvardef %#O; %N", n->op, n);
+		return;
+	}
+	switch(n->class) {
+	case PAUTO:
+	case PPARAM:
+	case PPARAMOUT:
+		gins(as, N, n);
+	}
+}
+
+void
+gvardef(Node *n)
+{
+	gvardefx(n, AVARDEF);
+}
+
+void
+gvarkill(Node *n)
+{
+	gvardefx(n, AVARKILL);
+}
+
+static void
+removevardef(Prog *firstp)
+{
+	Prog *p;
+
+	for(p = firstp; p != P; p = p->link) {
+		while(p->link != P && (p->link->as == AVARDEF || p->link->as == AVARKILL))
+			p->link = p->link->link;
+		if(p->to.type == D_BRANCH)
+			while(p->to.u.branch != P && (p->to.u.branch->as == AVARDEF || p->to.u.branch->as == AVARKILL))
+				p->to.u.branch = p->to.u.branch->link;
+	}
+}
+
+static void
+gcsymdup(Sym *s)
+{
+	LSym *ls;
+	uint64 lo, hi;
+	
+	ls = linksym(s);
+	if(ls->nr > 0)
+		fatal("cannot rosymdup %s with relocations", ls->name);
+	MD5 d;
+	md5reset(&d);
+	md5write(&d, ls->p, ls->np);
+	lo = md5sum(&d, &hi);
+	ls->name = smprint("gclocals·%016llux%016llux", lo, hi);
+	ls->dupok = 1;
+}
+
+void
+compile(Node *fn)
+{
+	Plist *pl;
+	Node nod1, *n;
+	Prog *ptxt, *p;
+	int32 lno;
+	Type *t;
+	Iter save;
+	vlong oldstksize;
+	NodeList *l;
+	Sym *gcargs;
+	Sym *gclocals;
+
+	if(newproc == N) {
+		newproc = sysfunc("newproc");
+		deferproc = sysfunc("deferproc");
+		deferreturn = sysfunc("deferreturn");
+		panicindex = sysfunc("panicindex");
+		panicslice = sysfunc("panicslice");
+		throwreturn = sysfunc("throwreturn");
+	}
+
+	lno = setlineno(fn);
+
+	curfn = fn;
+	dowidth(curfn->type);
+
+	if(fn->nbody == nil) {
+		if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0) {
+			yyerror("missing function body", fn);
+			goto ret;
+		}
+		if(debug['A'])
+			goto ret;
+		emitptrargsmap();
+		goto ret;
+	}
+
+	saveerrors();
+
+	// set up domain for labels
+	clearlabels();
+
+	if(curfn->type->outnamed) {
+		// add clearing of the output parameters
+		t = structfirst(&save, getoutarg(curfn->type));
+		while(t != T) {
+			if(t->nname != N) {
+				n = nod(OAS, t->nname, N);
+				typecheck(&n, Etop);
+				curfn->nbody = concat(list1(n), curfn->nbody);
+			}
+			t = structnext(&save);
+		}
+	}
+	
+	order(curfn);
+	if(nerrors != 0)
+		goto ret;
+	
+	hasdefer = 0;
+	walk(curfn);
+	if(nerrors != 0)
+		goto ret;
+	if(flag_race)
+		racewalk(curfn);
+	if(nerrors != 0)
+		goto ret;
+
+	continpc = P;
+	breakpc = P;
+
+	pl = newplist();
+	pl->name = linksym(curfn->nname->sym);
+
+	setlineno(curfn);
+
+	nodconst(&nod1, types[TINT32], 0);
+	ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
+	if(fn->dupok)
+		ptxt->TEXTFLAG |= DUPOK;
+	if(fn->wrapper)
+		ptxt->TEXTFLAG |= WRAPPER;
+	if(fn->needctxt)
+		ptxt->TEXTFLAG |= NEEDCTXT;
+	if(fn->nosplit)
+		ptxt->TEXTFLAG |= NOSPLIT;
+
+	// Clumsy but important.
+	// See test/recover.go for test cases and src/reflect/value.go
+	// for the actual functions being considered.
+	if(myimportpath != nil && strcmp(myimportpath, "reflect") == 0) {
+		if(strcmp(curfn->nname->sym->name, "callReflect") == 0 || strcmp(curfn->nname->sym->name, "callMethod") == 0)
+			ptxt->TEXTFLAG |= WRAPPER;
+	}	
+	
+	afunclit(&ptxt->from, curfn->nname);
+
+	ginit();
+
+	gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
+	gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
+
+	for(t=curfn->paramfld; t; t=t->down)
+		gtrack(tracksym(t->type));
+
+	for(l=fn->dcl; l; l=l->next) {
+		n = l->n;
+		if(n->op != ONAME) // might be OTYPE or OLITERAL
+			continue;
+		switch(n->class) {
+		case PAUTO:
+		case PPARAM:
+		case PPARAMOUT:
+			nodconst(&nod1, types[TUINTPTR], l->n->type->width);
+			p = gins(ATYPE, l->n, &nod1);
+			p->from.gotype = linksym(ngotype(l->n));
+			break;
+		}
+	}
+
+	genlist(curfn->enter);
+	genlist(curfn->nbody);
+	gclean();
+	checklabels();
+	if(nerrors != 0)
+		goto ret;
+	if(curfn->endlineno)
+		lineno = curfn->endlineno;
+
+	if(curfn->type->outtuple != 0)
+		ginscall(throwreturn, 0);
+
+	ginit();
+	// TODO: Determine when the final cgen_ret can be omitted. Perhaps always?
+	cgen_ret(nil);
+	if(hasdefer) {
+		// deferreturn pretends to have one uintptr argument.
+		// Reserve space for it so stack scanner is happy.
+		if(maxarg < widthptr)
+			maxarg = widthptr;
+	}
+	gclean();
+	if(nerrors != 0)
+		goto ret;
+
+	pc->as = ARET;	// overwrite AEND
+	pc->lineno = lineno;
+
+	fixjmp(ptxt);
+	if(!debug['N'] || debug['R'] || debug['P']) {
+		regopt(ptxt);
+		nilopt(ptxt);
+	}
+	expandchecks(ptxt);
+
+	oldstksize = stksize;
+	allocauto(ptxt);
+
+	if(0)
+		print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
+	USED(oldstksize);
+
+	setlineno(curfn);
+	if((int64)stksize+maxarg > (1ULL<<31)) {
+		yyerror("stack frame too large (>2GB)");
+		goto ret;
+	}
+
+	// Emit garbage collection symbols.
+	liveness(curfn, ptxt, gcargs, gclocals);
+	gcsymdup(gcargs);
+	gcsymdup(gclocals);
+
+	defframe(ptxt);
+
+	if(0)
+		frame(0);
+
+	// Remove leftover instrumentation from the instruction stream.
+	removevardef(ptxt);
+ret:
+	lineno = lno;
+}
+
+static void
+emitptrargsmap(void)
+{
+	int nptr, nbitmap, j, off;
+	vlong xoffset;
+	Bvec *bv;
+	Sym *sym;
+	
+	sym = lookup(smprint("%s.args_stackmap", curfn->nname->sym->name));
+
+	nptr = curfn->type->argwid / widthptr;
+	bv = bvalloc(nptr*2);
+	nbitmap = 1;
+	if(curfn->type->outtuple > 0)
+		nbitmap = 2;
+	off = duint32(sym, 0, nbitmap);
+	off = duint32(sym, off, bv->n);
+	if(curfn->type->thistuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getthisx(curfn->type), &xoffset, bv);
+	}
+	if(curfn->type->intuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getinargx(curfn->type), &xoffset, bv);
+	}
+	for(j = 0; j < bv->n; j += 32)
+		off = duint32(sym, off, bv->b[j/32]);
+	if(curfn->type->outtuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getoutargx(curfn->type), &xoffset, bv);
+		for(j = 0; j < bv->n; j += 32)
+			off = duint32(sym, off, bv->b[j/32]);
+	}
+	ggloblsym(sym, off, RODATA);
+	free(bv);
+}
+
+// Sort the list of stack variables. Autos after anything else,
+// within autos, unused after used, within used, things with
+// pointers first, zeroed things first, and then decreasing size.
+// Because autos are laid out in decreasing addresses
+// on the stack, pointers first, zeroed things first and decreasing size
+// really means, in memory, things with pointers needing zeroing at
+// the top of the stack and increasing in size.
+// Non-autos sort on offset.
+static int
+cmpstackvar(Node *a, Node *b)
+{
+	int ap, bp;
+
+	if (a->class != b->class)
+		return (a->class == PAUTO) ? +1 : -1;
+	if (a->class != PAUTO) {
+		if (a->xoffset < b->xoffset)
+			return -1;
+		if (a->xoffset > b->xoffset)
+			return +1;
+		return 0;
+	}
+	if ((a->used == 0) != (b->used == 0))
+		return b->used - a->used;
+
+	ap = haspointers(a->type);
+	bp = haspointers(b->type);
+	if(ap != bp)
+		return bp - ap;
+
+	ap = a->needzero;
+	bp = b->needzero;
+	if(ap != bp)
+		return bp - ap;
+
+	if(a->type->width < b->type->width)
+		return +1;
+	if(a->type->width > b->type->width)
+		return -1;
+
+	return strcmp(a->sym->name, b->sym->name);
+}
+
+// TODO(lvd) find out where the PAUTO/OLITERAL nodes come from.
+static void
+allocauto(Prog* ptxt)
+{
+	NodeList *ll;
+	Node* n;
+	vlong w;
+
+	stksize = 0;
+	stkptrsize = 0;
+
+	if(curfn->dcl == nil)
+		return;
+
+	// Mark the PAUTO's unused.
+	for(ll=curfn->dcl; ll != nil; ll=ll->next)
+		if (ll->n->class == PAUTO)
+			ll->n->used = 0;
+
+	markautoused(ptxt);
+
+	listsort(&curfn->dcl, cmpstackvar);
+
+	// Unused autos are at the end, chop 'em off.
+	ll = curfn->dcl;
+	n = ll->n;
+	if (n->class == PAUTO && n->op == ONAME && !n->used) {
+		// No locals used at all
+		curfn->dcl = nil;
+		fixautoused(ptxt);
+		return;
+	}
+
+	for(ll = curfn->dcl; ll->next != nil; ll=ll->next) {
+		n = ll->next->n;
+		if (n->class == PAUTO && n->op == ONAME && !n->used) {
+			ll->next = nil;
+			curfn->dcl->end = ll;
+			break;
+		}
+	}
+
+	// Reassign stack offsets of the locals that are still there.
+	for(ll = curfn->dcl; ll != nil; ll=ll->next) {
+		n = ll->n;
+		if (n->class != PAUTO || n->op != ONAME)
+			continue;
+
+		dowidth(n->type);
+		w = n->type->width;
+		if(w >= MAXWIDTH || w < 0)
+			fatal("bad width");
+		stksize += w;
+		stksize = rnd(stksize, n->type->align);
+		if(haspointers(n->type))
+			stkptrsize = stksize;
+		if(thechar == '5')
+			stksize = rnd(stksize, widthptr);
+		if(stksize >= (1ULL<<31)) {
+			setlineno(curfn);
+			yyerror("stack frame too large (>2GB)");
+		}
+		n->stkdelta = -stksize - n->xoffset;
+	}
+	stksize = rnd(stksize, widthreg);
+	stkptrsize = rnd(stkptrsize, widthreg);
+
+	fixautoused(ptxt);
+
+	// The debug information needs accurate offsets on the symbols.
+	for(ll = curfn->dcl; ll != nil; ll=ll->next) {
+		if (ll->n->class != PAUTO || ll->n->op != ONAME)
+			continue;
+		ll->n->xoffset += ll->n->stkdelta;
+		ll->n->stkdelta = 0;
+	}
+}
+
+static void movelargefn(Node*);
+
+void
+movelarge(NodeList *l)
+{
+	for(; l; l=l->next)
+		if(l->n->op == ODCLFUNC)
+			movelargefn(l->n);
+}
+
+static void
+movelargefn(Node *fn)
+{
+	NodeList *l;
+	Node *n;
+
+	for(l=fn->dcl; l != nil; l=l->next) {
+		n = l->n;
+		if(n->class == PAUTO && n->type != T && n->type->width > MaxStackVarSize)
+			addrescapes(n);
+	}
+}
+
+void
+cgen_checknil(Node *n)
+{
+	Node reg;
+
+	if(disable_checknil)
+		return;
+	// Ideally we wouldn't see any integer types here, but we do.
+	if(n->type == T || (!isptr[n->type->etype] && !isint[n->type->etype] && n->type->etype != TUNSAFEPTR)) {
+		dump("checknil", n);
+		fatal("bad checknil");
+	}
+	if((thechar == '5' && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
+		regalloc(&reg, types[tptr], n);
+		cgen(n, &reg);
+		gins(ACHECKNIL, &reg, N);
+		regfree(&reg);
+		return;
+	}
+	gins(ACHECKNIL, n, N);
+}
diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c
new file mode 100644
index 0000000..0feb2c7
--- /dev/null
+++ b/src/cmd/gc/plive.c
@@ -0,0 +1,2017 @@
+// Copyright 2013 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.
+
+// Garbage collector liveness bitmap generation.
+
+// The command line flag -live causes this code to print debug information.
+// The levels are:
+//
+//	-live (aka -live=1): print liveness lists as code warnings at safe points
+//	-live=2: print an assembly listing with liveness annotations
+//	-live=3: print information during each computation phase (much chattier)
+//
+// Each level includes the earlier output as well.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+#include "../ld/textflag.h"
+#include "../../runtime/funcdata.h"
+#include "../../runtime/mgc0.h"
+
+enum {
+	UNVISITED = 0,
+	VISITED = 1,
+};
+
+// An ordinary basic block.
+//
+// Instructions are threaded together in a doubly-linked list.  To iterate in
+// program order follow the link pointer from the first node and stop after the
+// last node has been visited
+//
+//   for(p = bb->first;; p = p->link) {
+//     ...
+//     if(p == bb->last)
+//       break;
+//   }
+//
+// To iterate in reverse program order by following the opt pointer from the
+// last node
+//
+//   for(p = bb->last; p != nil; p = p->opt) {
+//     ...
+//   }
+typedef struct BasicBlock BasicBlock;
+struct BasicBlock {
+	// An array of preceding blocks.  If the length of this array is 0 the
+	// block is probably the start block of the CFG.
+	Array *pred;
+
+	// An array out succeeding blocks.  If the length of this array is zero,
+	// the block probably ends in a return instruction.
+	Array *succ;
+
+	// First instruction in the block.  When part of a fully initialized
+	// control flow graph, the opt member will be nil.
+	Prog *first;
+
+	// Last instruction in the basic block.
+	Prog *last;
+
+	// The reverse post order number.  This value is initialized to -1 and
+	// will be replaced by a non-negative value when the CFG is constructed.
+	// After CFG construction, if rpo is -1 this block is unreachable.
+	int rpo;
+
+	// State to denote whether the block has been visited during a
+	// traversal.
+	int mark;
+	
+	// For use during livenessepilogue.
+	int lastbitmapindex;
+};
+
+// A collection of global state used by liveness analysis.
+typedef struct Liveness Liveness;
+struct Liveness {
+	// A pointer to the node corresponding to the function being analyzed.
+	Node *fn;
+
+	// A linked list of instructions for this function.
+	Prog *ptxt;
+
+	// A list of arguments and local variables in this function.
+	Array *vars;
+
+	// A list of basic blocks that are overlayed on the instruction list.
+	// The blocks are roughly in the same order as the instructions
+	// in the function (first block has TEXT instruction, and so on).
+	Array *cfg;
+
+	// Summary sets of block effects.
+	// The Bvec** is indexed by bb->rpo to yield a single Bvec*.
+	// That bit vector is indexed by variable number (same as lv->vars).
+	//
+	// Computed during livenessprologue using only the content of
+	// individual blocks:
+	//
+	//	uevar: upward exposed variables (used before set in block)
+	//	varkill: killed variables (set in block)
+	//	avarinit: addrtaken variables set or used (proof of initialization)
+	//
+	// Computed during livenesssolve using control flow information:
+	//
+	//	livein: variables live at block entry
+	//	liveout: variables live at block exit
+	//	avarinitany: addrtaken variables possibly initialized at block exit
+	//		(initialized in block or at exit from any predecessor block)
+	//	avarinitall: addrtaken variables certainly initialized at block exit
+	//		(initialized in block or at exit from all predecessor blocks)
+	Bvec **uevar;
+	Bvec **varkill;
+	Bvec **livein;
+	Bvec **liveout;
+	Bvec **avarinit;
+	Bvec **avarinitany;
+	Bvec **avarinitall;
+
+	// An array with a bit vector for each safe point tracking live pointers
+	// in the arguments and locals area, indexed by bb->rpo.
+	Array *argslivepointers;
+	Array *livepointers;
+};
+
+static void*
+xmalloc(uintptr size)
+{
+	void *result;
+
+	result = malloc(size);
+	if(result == nil)
+		fatal("malloc failed");
+	return result;
+}
+
+// Constructs a new basic block containing a single instruction.
+static BasicBlock*
+newblock(Prog *prog)
+{
+	BasicBlock *result;
+
+	if(prog == nil)
+		fatal("newblock: prog cannot be nil");
+	result = xmalloc(sizeof(*result));
+	result->rpo = -1;
+	result->mark = UNVISITED;
+	result->first = prog;
+	result->last = prog;
+	result->pred = arraynew(2, sizeof(BasicBlock*));
+	result->succ = arraynew(2, sizeof(BasicBlock*));
+	return result;
+}
+
+// Frees a basic block and all of its leaf data structures.
+static void
+freeblock(BasicBlock *bb)
+{
+	if(bb == nil)
+		fatal("freeblock: cannot free nil");
+	arrayfree(bb->pred);
+	arrayfree(bb->succ);
+	free(bb);
+}
+
+// Adds an edge between two basic blocks by making from a predecessor of to and
+// to a successor of from.
+static void
+addedge(BasicBlock *from, BasicBlock *to)
+{
+	if(from == nil)
+		fatal("addedge: from is nil");
+	if(to == nil)
+		fatal("addedge: to is nil");
+	arrayadd(from->succ, &to);
+	arrayadd(to->pred, &from);
+}
+
+// Inserts prev before curr in the instruction
+// stream.  Any control flow, such as branches or fall throughs, that target the
+// existing instruction are adjusted to target the new instruction.
+static void
+splicebefore(Liveness *lv, BasicBlock *bb, Prog *prev, Prog *curr)
+{
+	Prog *next, tmp;
+
+	USED(lv);
+
+	// There may be other instructions pointing at curr,
+	// and we want them to now point at prev. Instead of
+	// trying to find all such instructions, swap the contents
+	// so that the problem becomes inserting next after curr.
+	// The "opt" field is the backward link in the linked list.
+
+	// Overwrite curr's data with prev, but keep the list links.
+	tmp = *curr;
+	*curr = *prev;
+	curr->opt = tmp.opt;
+	curr->link = tmp.link;
+	
+	// Overwrite prev (now next) with curr's old data.
+	next = prev;
+	*next = tmp;
+	next->opt = nil;
+	next->link = nil;
+
+	// Now insert next after curr.
+	next->link = curr->link;
+	next->opt = curr;
+	curr->link = next;
+	if(next->link && next->link->opt == curr)
+		next->link->opt = next;
+
+	if(bb->last == curr)
+		bb->last = next;
+}
+
+// A pretty printer for basic blocks.
+static void
+printblock(BasicBlock *bb)
+{
+	BasicBlock *pred;
+	BasicBlock *succ;
+	Prog *prog;
+	int i;
+
+	print("basic block %d\n", bb->rpo);
+	print("\tpred:");
+	for(i = 0; i < arraylength(bb->pred); i++) {
+		pred = *(BasicBlock**)arrayget(bb->pred, i);
+		print(" %d", pred->rpo);
+	}
+	print("\n");
+	print("\tsucc:");
+	for(i = 0; i < arraylength(bb->succ); i++) {
+		succ = *(BasicBlock**)arrayget(bb->succ, i);
+		print(" %d", succ->rpo);
+	}
+	print("\n");
+	print("\tprog:\n");
+	for(prog = bb->first;; prog=prog->link) {
+		print("\t\t%P\n", prog);
+		if(prog == bb->last)
+			break;
+	}
+}
+
+
+// Iterates over a basic block applying a callback to each instruction.  There
+// are two criteria for termination.  If the end of basic block is reached a
+// value of zero is returned.  If the callback returns a non-zero value, the
+// iteration is stopped and the value of the callback is returned.
+static int
+blockany(BasicBlock *bb, int (*callback)(Prog*))
+{
+	Prog *p;
+	int result;
+
+	for(p = bb->last; p != nil; p = p->opt) {
+		result = (*callback)(p);
+		if(result != 0)
+			return result;
+	}
+	return 0;
+}
+
+// Collects and returns and array of Node*s for functions arguments and local
+// variables.
+static Array*
+getvariables(Node *fn)
+{
+	Array *result;
+	NodeList *ll;
+
+	result = arraynew(0, sizeof(Node*));
+	for(ll = fn->dcl; ll != nil; ll = ll->next) {
+		if(ll->n->op == ONAME) {
+			// In order for GODEBUG=gcdead=1 to work, each bitmap needs
+			// to contain information about all variables covered by the bitmap.
+			// For local variables, the bitmap only covers the stkptrsize
+			// bytes in the frame where variables containing pointers live.
+			// For arguments and results, the bitmap covers all variables,
+			// so we must include all the variables, even the ones without
+			// pointers.
+			//
+			// The Node.opt field is available for use by optimization passes.
+			// We use it to hold the index of the node in the variables array, plus 1
+			// (so that 0 means the Node is not in the variables array).
+			// Each pass should clear opt when done, but you never know,
+			// so clear them all ourselves too.
+			// The Node.curfn field is supposed to be set to the current function
+			// already, but for some compiler-introduced names it seems not to be,
+			// so fix that here.
+			// Later, when we want to find the index of a node in the variables list,
+			// we will check that n->curfn == curfn and n->opt > 0. Then n->opt - 1
+			// is the index in the variables list.
+			ll->n->opt = nil;
+			ll->n->curfn = curfn;
+			switch(ll->n->class) {
+			case PAUTO:
+				if(haspointers(ll->n->type)) {
+					ll->n->opt = (void*)(uintptr)(arraylength(result)+1);
+					arrayadd(result, &ll->n);
+				}
+				break;
+			case PPARAM:
+			case PPARAMOUT:
+				ll->n->opt = (void*)(uintptr)(arraylength(result)+1);
+				arrayadd(result, &ll->n);
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+// A pretty printer for control flow graphs.  Takes an array of BasicBlock*s.
+static void
+printcfg(Array *cfg)
+{
+	BasicBlock *bb;
+	int32 i;
+
+	for(i = 0; i < arraylength(cfg); i++) {
+		bb = *(BasicBlock**)arrayget(cfg, i);
+		printblock(bb);
+	}
+}
+
+// Assigns a reverse post order number to each connected basic block using the
+// standard algorithm.  Unconnected blocks will not be affected.
+static void
+reversepostorder(BasicBlock *root, int32 *rpo)
+{
+	BasicBlock *bb;
+	int i;
+
+	root->mark = VISITED;
+	for(i = 0; i < arraylength(root->succ); i++) {
+		bb = *(BasicBlock**)arrayget(root->succ, i);
+		if(bb->mark == UNVISITED)
+			reversepostorder(bb, rpo);
+	}
+	*rpo -= 1;
+	root->rpo = *rpo;
+}
+
+// Comparison predicate used for sorting basic blocks by their rpo in ascending
+// order.
+static int
+blockrpocmp(const void *p1, const void *p2)
+{
+	BasicBlock *bb1;
+	BasicBlock *bb2;
+
+	bb1 = *(BasicBlock**)p1;
+	bb2 = *(BasicBlock**)p2;
+	if(bb1->rpo < bb2->rpo)
+		return -1;
+	if(bb1->rpo > bb2->rpo)
+		return 1;
+	return 0;
+}
+
+// A pattern matcher for call instructions.  Returns true when the instruction
+// is a call to a specific package qualified function name.
+static int
+iscall(Prog *prog, LSym *name)
+{
+	if(prog == nil)
+		fatal("iscall: prog is nil");
+	if(name == nil)
+		fatal("iscall: function name is nil");
+	if(prog->as != ACALL)
+		return 0;
+	return name == prog->to.sym;
+}
+
+// Returns true for instructions that call a runtime function implementing a
+// select communication clause.
+static int
+isselectcommcasecall(Prog *prog)
+{
+	static LSym* names[5];
+	int32 i;
+
+	if(names[0] == nil) {
+		names[0] = linksym(pkglookup("selectsend", runtimepkg));
+		names[1] = linksym(pkglookup("selectrecv", runtimepkg));
+		names[2] = linksym(pkglookup("selectrecv2", runtimepkg));
+		names[3] = linksym(pkglookup("selectdefault", runtimepkg));
+	}
+	for(i = 0; names[i] != nil; i++)
+		if(iscall(prog, names[i]))
+			return 1;
+	return 0;
+}
+
+// Returns true for call instructions that target runtime·newselect.
+static int
+isnewselect(Prog *prog)
+{
+	static LSym *sym;
+
+	if(sym == nil)
+		sym = linksym(pkglookup("newselect", runtimepkg));
+	return iscall(prog, sym);
+}
+
+// Returns true for call instructions that target runtime·selectgo.
+static int
+isselectgocall(Prog *prog)
+{
+	static LSym *sym;
+
+	if(sym == nil)
+		sym = linksym(pkglookup("selectgo", runtimepkg));
+	return iscall(prog, sym);
+}
+
+static int
+isdeferreturn(Prog *prog)
+{
+	static LSym *sym;
+
+	if(sym == nil)
+		sym = linksym(pkglookup("deferreturn", runtimepkg));
+	return iscall(prog, sym);
+}
+
+// Walk backwards from a runtime·selectgo call up to its immediately dominating
+// runtime·newselect call.  Any successor nodes of communication clause nodes
+// are implicit successors of the runtime·selectgo call node.  The goal of this
+// analysis is to add these missing edges to complete the control flow graph.
+static void
+addselectgosucc(BasicBlock *selectgo)
+{
+	BasicBlock *pred;
+	BasicBlock *succ;
+
+	pred = selectgo;
+	for(;;) {
+		if(arraylength(pred->pred) == 0)
+			fatal("selectgo does not have a newselect");
+		pred = *(BasicBlock**)arrayget(pred->pred, 0);
+		if(blockany(pred, isselectcommcasecall)) {
+			// A select comm case block should have exactly one
+			// successor.
+			if(arraylength(pred->succ) != 1)
+				fatal("select comm case has too many successors");
+			succ = *(BasicBlock**)arrayget(pred->succ, 0);
+			// Its successor should have exactly two successors.
+			// The drop through should flow to the selectgo block
+			// and the branch should lead to the select case
+			// statements block.
+			if(arraylength(succ->succ) != 2)
+				fatal("select comm case successor has too many successors");
+			// Add the block as a successor of the selectgo block.
+			addedge(selectgo, succ);
+		}
+		if(blockany(pred, isnewselect)) {
+			// Reached the matching newselect.
+			break;
+		}
+	}
+}
+
+// The entry point for the missing selectgo control flow algorithm.  Takes an
+// array of BasicBlock*s containing selectgo calls.
+static void
+fixselectgo(Array *selectgo)
+{
+	BasicBlock *bb;
+	int32 i;
+
+	for(i = 0; i < arraylength(selectgo); i++) {
+		bb = *(BasicBlock**)arrayget(selectgo, i);
+		addselectgosucc(bb);
+	}
+}
+
+// Constructs a control flow graph from a sequence of instructions.  This
+// procedure is complicated by various sources of implicit control flow that are
+// not accounted for using the standard cfg construction algorithm.  Returns an
+// array of BasicBlock*s in control flow graph form (basic blocks ordered by
+// their RPO number).
+static Array*
+newcfg(Prog *firstp)
+{
+	Prog *p;
+	Prog *prev;
+	BasicBlock *bb;
+	Array *cfg;
+	Array *selectgo;
+	int32 i;
+	int32 rpo;
+
+	// Reset the opt field of each prog to nil.  In the first and second
+	// passes, instructions that are labels temporarily use the opt field to
+	// point to their basic block.  In the third pass, the opt field reset
+	// to point to the predecessor of an instruction in its basic block.
+	for(p = firstp; p != P; p = p->link)
+		p->opt = nil;
+
+	// Allocate an array to remember where we have seen selectgo calls.
+	// These blocks will be revisited to add successor control flow edges.
+	selectgo = arraynew(0, sizeof(BasicBlock*));
+
+	// Loop through all instructions identifying branch targets
+	// and fall-throughs and allocate basic blocks.
+	cfg = arraynew(0, sizeof(BasicBlock*));
+	bb = newblock(firstp);
+	arrayadd(cfg, &bb);
+	for(p = firstp; p != P; p = p->link) {
+		if(p->to.type == D_BRANCH) {
+			if(p->to.u.branch == nil)
+				fatal("prog branch to nil");
+			if(p->to.u.branch->opt == nil) {
+				p->to.u.branch->opt = newblock(p->to.u.branch);
+				arrayadd(cfg, &p->to.u.branch->opt);
+			}
+			if(p->as != AJMP && p->link != nil && p->link->opt == nil) {
+				p->link->opt = newblock(p->link);
+				arrayadd(cfg, &p->link->opt);
+			}
+		} else if(isselectcommcasecall(p) || isselectgocall(p)) {
+			// Accommodate implicit selectgo control flow.
+			if(p->link->opt == nil) {
+				p->link->opt = newblock(p->link);
+				arrayadd(cfg, &p->link->opt);
+			}
+		}
+	}
+
+	// Loop through all basic blocks maximally growing the list of
+	// contained instructions until a label is reached.  Add edges
+	// for branches and fall-through instructions.
+	for(i = 0; i < arraylength(cfg); i++) {
+		bb = *(BasicBlock**)arrayget(cfg, i);
+		for(p = bb->last; p != nil; p = p->link) {
+			if(p->opt != nil && p != bb->last)
+				break;
+			bb->last = p;
+
+			// Stop before an unreachable RET, to avoid creating
+			// unreachable control flow nodes.
+			if(p->link != nil && p->link->as == ARET && p->link->mode == 1)
+				break;
+
+			// Collect basic blocks with selectgo calls.
+			if(isselectgocall(p))
+				arrayadd(selectgo, &bb);
+		}
+		if(bb->last->to.type == D_BRANCH)
+			addedge(bb, bb->last->to.u.branch->opt);
+		if(bb->last->link != nil) {
+			// Add a fall-through when the instruction is
+			// not an unconditional control transfer.
+			switch(bb->last->as) {
+			case AJMP:
+			case ARET:
+			case AUNDEF:
+				break;
+			default:
+				addedge(bb, bb->last->link->opt);
+			}
+		}
+	}
+
+	// Add back links so the instructions in a basic block can be traversed
+	// backward.  This is the final state of the instruction opt field.
+	for(i = 0; i < arraylength(cfg); i++) {
+		bb = *(BasicBlock**)arrayget(cfg, i);
+		p = bb->first;
+		prev = nil;
+		for(;;) {
+			p->opt = prev;
+			if(p == bb->last)
+				break;
+			prev = p;
+			p = p->link;
+		}
+	}
+
+	// Add missing successor edges to the selectgo blocks.
+	if(arraylength(selectgo))
+		fixselectgo(selectgo);
+	arrayfree(selectgo);
+
+	// Find a depth-first order and assign a depth-first number to
+	// all basic blocks.
+	for(i = 0; i < arraylength(cfg); i++) {
+		bb = *(BasicBlock**)arrayget(cfg, i);
+		bb->mark = UNVISITED;
+	}
+	bb = *(BasicBlock**)arrayget(cfg, 0);
+	rpo = arraylength(cfg);
+	reversepostorder(bb, &rpo);
+
+	// Sort the basic blocks by their depth first number.  The
+	// array is now a depth-first spanning tree with the first
+	// node being the root.
+	arraysort(cfg, blockrpocmp);
+	bb = *(BasicBlock**)arrayget(cfg, 0);
+
+	// Unreachable control flow nodes are indicated by a -1 in the rpo
+	// field.  If we see these nodes something must have gone wrong in an
+	// upstream compilation phase.
+	if(bb->rpo == -1) {
+		print("newcfg: unreachable basic block for %P\n", bb->last);
+		printcfg(cfg);
+		fatal("newcfg: invalid control flow graph");
+	}
+
+	return cfg;
+}
+
+// Frees a control flow graph (an array of BasicBlock*s) and all of its leaf
+// data structures.
+static void
+freecfg(Array *cfg)
+{
+	BasicBlock *bb;
+	BasicBlock *bb0;
+	Prog *p;
+	int32 i;
+	int32 len;
+
+	len = arraylength(cfg);
+	if(len > 0) {
+		bb0 = *(BasicBlock**)arrayget(cfg, 0);
+		for(p = bb0->first; p != P; p = p->link) {
+			p->opt = nil;
+		}
+		for(i = 0; i < len; i++) {
+			bb = *(BasicBlock**)arrayget(cfg, i);
+			freeblock(bb);
+		}
+	}
+	arrayfree(cfg);
+}
+
+// Returns true if the node names a variable that is otherwise uninteresting to
+// the liveness computation.
+static int
+isfunny(Node *node)
+{
+	char *names[] = { ".fp", ".args", nil };
+	int i;
+
+	if(node->sym != nil && node->sym->name != nil)
+		for(i = 0; names[i] != nil; i++)
+			if(strcmp(node->sym->name, names[i]) == 0)
+				return 1;
+	return 0;
+}
+
+// Computes the effects of an instruction on a set of
+// variables.  The vars argument is an array of Node*s.
+//
+// The output vectors give bits for variables:
+//	uevar - used by this instruction
+//	varkill - killed by this instruction
+//		for variables without address taken, means variable was set
+//		for variables with address taken, means variable was marked dead
+//	avarinit - initialized or referred to by this instruction,
+//		only for variables with address taken but not escaping to heap
+//
+// The avarinit output serves as a signal that the data has been
+// initialized, because any use of a variable must come after its
+// initialization.
+static void
+progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
+{
+	ProgInfo info;
+	Addr *from;
+	Addr *to;
+	Node *node;
+	int32 i;
+	int32 pos;
+
+	bvresetall(uevar);
+	bvresetall(varkill);
+	bvresetall(avarinit);
+
+	proginfo(&info, prog);
+	if(prog->as == ARET) {
+		// Return instructions implicitly read all the arguments.  For
+		// the sake of correctness, out arguments must be read.  For the
+		// sake of backtrace quality, we read in arguments as well.
+		//
+		// A return instruction with a p->to is a tail return, which brings
+		// the stack pointer back up (if it ever went down) and then jumps
+		// to a new function entirely. That form of instruction must read
+		// all the parameters for correctness, and similarly it must not
+		// read the out arguments - they won't be set until the new
+		// function runs.
+		for(i = 0; i < arraylength(vars); i++) {
+			node = *(Node**)arrayget(vars, i);
+			switch(node->class & ~PHEAP) {
+			case PPARAM:
+				bvset(uevar, i);
+				break;
+			case PPARAMOUT:
+				// If the result had its address taken, it is being tracked
+				// by the avarinit code, which does not use uevar.
+				// If we added it to uevar too, we'd not see any kill
+				// and decide that the varible was live entry, which it is not.
+				// So only use uevar in the non-addrtaken case.
+				// The p->to.type == D_NONE limits the bvset to
+				// non-tail-call return instructions; see note above
+				// the for loop for details.
+				if(!node->addrtaken && prog->to.type == D_NONE)
+					bvset(uevar, i);
+				break;
+			}
+		}
+		return;
+	}
+	if(prog->as == ATEXT) {
+		// A text instruction marks the entry point to a function and
+		// the definition point of all in arguments.
+		for(i = 0; i < arraylength(vars); i++) {
+			node = *(Node**)arrayget(vars, i);
+			switch(node->class & ~PHEAP) {
+			case PPARAM:
+				if(node->addrtaken)
+					bvset(avarinit, i);
+				bvset(varkill, i);
+				break;
+			}
+		}
+		return;
+	}
+	if(info.flags & (LeftRead | LeftWrite | LeftAddr)) {
+		from = &prog->from;
+		if (from->node != nil && from->sym != nil && from->node->curfn == curfn) {
+			switch(from->node->class & ~PHEAP) {
+			case PAUTO:
+			case PPARAM:
+			case PPARAMOUT:
+				pos = (int)(uintptr)from->node->opt - 1; // index in vars
+				if(pos == -1)
+					goto Next;
+				if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != from->node)
+					fatal("bad bookkeeping in liveness %N %d", from->node, pos);
+				if(from->node->addrtaken) {
+					bvset(avarinit, pos);
+				} else {
+					if(info.flags & (LeftRead | LeftAddr))
+						bvset(uevar, pos);
+					if(info.flags & LeftWrite)
+						if(from->node != nil && !isfat(from->node->type))
+							bvset(varkill, pos);
+				}
+			}
+		}
+	}
+Next:
+	if(info.flags & (RightRead | RightWrite | RightAddr)) {
+		to = &prog->to;
+		if (to->node != nil && to->sym != nil && to->node->curfn == curfn) {
+			switch(to->node->class & ~PHEAP) {
+			case PAUTO:
+			case PPARAM:
+			case PPARAMOUT:
+				pos = (int)(uintptr)to->node->opt - 1; // index in vars
+				if(pos == -1)
+					goto Next1;
+				if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node)
+					fatal("bad bookkeeping in liveness %N %d", to->node, pos);
+				if(to->node->addrtaken) {
+					if(prog->as != AVARKILL)
+						bvset(avarinit, pos);
+					if(prog->as == AVARDEF || prog->as == AVARKILL)
+						bvset(varkill, pos);
+				} else {
+					// RightRead is a read, obviously.
+					// RightAddr by itself is also implicitly a read.
+					//
+					// RightAddr|RightWrite means that the address is being taken
+					// but only so that the instruction can write to the value.
+					// It is not a read. It is equivalent to RightWrite except that
+					// having the RightAddr bit set keeps the registerizer from
+					// trying to substitute a register for the memory location.
+					if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
+						bvset(uevar, pos);
+					if(info.flags & RightWrite)
+						if(to->node != nil && (!isfat(to->node->type) || prog->as == AVARDEF))
+							bvset(varkill, pos);
+				}
+			}
+		}
+	}
+Next1:;
+}
+
+// Constructs a new liveness structure used to hold the global state of the
+// liveness computation.  The cfg argument is an array of BasicBlock*s and the
+// vars argument is an array of Node*s.
+static Liveness*
+newliveness(Node *fn, Prog *ptxt, Array *cfg, Array *vars)
+{
+	Liveness *result;
+	int32 i;
+	int32 nblocks;
+	int32 nvars;
+
+	result = xmalloc(sizeof(*result));
+	result->fn = fn;
+	result->ptxt = ptxt;
+	result->cfg = cfg;
+	result->vars = vars;
+
+	nblocks = arraylength(cfg);
+	result->uevar = xmalloc(sizeof(Bvec*) * nblocks);
+	result->varkill = xmalloc(sizeof(Bvec*) * nblocks);
+	result->livein = xmalloc(sizeof(Bvec*) * nblocks);
+	result->liveout = xmalloc(sizeof(Bvec*) * nblocks);
+	result->avarinit = xmalloc(sizeof(Bvec*) * nblocks);
+	result->avarinitany = xmalloc(sizeof(Bvec*) * nblocks);
+	result->avarinitall = xmalloc(sizeof(Bvec*) * nblocks);
+
+	nvars = arraylength(vars);
+	for(i = 0; i < nblocks; i++) {
+		result->uevar[i] = bvalloc(nvars);
+		result->varkill[i] = bvalloc(nvars);
+		result->livein[i] = bvalloc(nvars);
+		result->liveout[i] = bvalloc(nvars);
+		result->avarinit[i] = bvalloc(nvars);
+		result->avarinitany[i] = bvalloc(nvars);
+		result->avarinitall[i] = bvalloc(nvars);
+	}
+
+	result->livepointers = arraynew(0, sizeof(Bvec*));
+	result->argslivepointers = arraynew(0, sizeof(Bvec*));
+	return result;
+}
+
+// Frees the liveness structure and all of its leaf data structures.
+static void
+freeliveness(Liveness *lv)
+{
+	int32 i;
+
+	if(lv == nil)
+		fatal("freeliveness: cannot free nil");
+
+	for(i = 0; i < arraylength(lv->livepointers); i++)
+		free(*(Bvec**)arrayget(lv->livepointers, i));
+	arrayfree(lv->livepointers);
+
+	for(i = 0; i < arraylength(lv->argslivepointers); i++)
+		free(*(Bvec**)arrayget(lv->argslivepointers, i));
+	arrayfree(lv->argslivepointers);
+
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		free(lv->uevar[i]);
+		free(lv->varkill[i]);
+		free(lv->livein[i]);
+		free(lv->liveout[i]);
+		free(lv->avarinit[i]);
+		free(lv->avarinitany[i]);
+		free(lv->avarinitall[i]);
+	}
+
+	free(lv->uevar);
+	free(lv->varkill);
+	free(lv->livein);
+	free(lv->liveout);
+	free(lv->avarinit);
+	free(lv->avarinitany);
+	free(lv->avarinitall);
+
+	free(lv);
+}
+
+static void
+printeffects(Prog *p, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
+{
+	print("effects of %P", p);
+	print("\nuevar: ");
+	bvprint(uevar);
+	print("\nvarkill: ");
+	bvprint(varkill);
+	print("\navarinit: ");
+	bvprint(avarinit);
+	print("\n");
+}
+
+// Pretty print a variable node.  Uses Pascal like conventions for pointers and
+// addresses to avoid confusing the C like conventions used in the node variable
+// names.
+static void
+printnode(Node *node)
+{
+	char *p;
+	char *a;
+
+	p = haspointers(node->type) ? "^" : "";
+	a = node->addrtaken ? "@" : "";
+	print(" %N%s%s", node, p, a);
+}
+
+// Pretty print a list of variables.  The vars argument is an array of Node*s.
+static void
+printvars(char *name, Bvec *bv, Array *vars)
+{
+	int32 i;
+
+	print("%s:", name);
+	for(i = 0; i < arraylength(vars); i++)
+		if(bvget(bv, i))
+			printnode(*(Node**)arrayget(vars, i));
+	print("\n");
+}
+
+// Prints a basic block annotated with the information computed by liveness
+// analysis.
+static void
+livenessprintblock(Liveness *lv, BasicBlock *bb)
+{
+	BasicBlock *pred;
+	BasicBlock *succ;
+	Prog *prog;
+	Bvec *live;
+	int i;
+	int32 pos;
+
+	print("basic block %d\n", bb->rpo);
+
+	print("\tpred:");
+	for(i = 0; i < arraylength(bb->pred); i++) {
+		pred = *(BasicBlock**)arrayget(bb->pred, i);
+		print(" %d", pred->rpo);
+	}
+	print("\n");
+
+	print("\tsucc:");
+	for(i = 0; i < arraylength(bb->succ); i++) {
+		succ = *(BasicBlock**)arrayget(bb->succ, i);
+		print(" %d", succ->rpo);
+	}
+	print("\n");
+
+	printvars("\tuevar", lv->uevar[bb->rpo], lv->vars);
+	printvars("\tvarkill", lv->varkill[bb->rpo], lv->vars);
+	printvars("\tlivein", lv->livein[bb->rpo], lv->vars);
+	printvars("\tliveout", lv->liveout[bb->rpo], lv->vars);
+	printvars("\tavarinit", lv->avarinit[bb->rpo], lv->vars);
+	printvars("\tavarinitany", lv->avarinitany[bb->rpo], lv->vars);
+	printvars("\tavarinitall", lv->avarinitall[bb->rpo], lv->vars);
+
+	print("\tprog:\n");
+	for(prog = bb->first;; prog = prog->link) {
+		print("\t\t%P", prog);
+		if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
+			pos = prog->to.offset;
+			live = *(Bvec**)arrayget(lv->livepointers, pos);
+			print(" ");
+			bvprint(live);
+		}
+		print("\n");
+		if(prog == bb->last)
+			break;
+	}
+}
+
+// Prints a control flow graph annotated with any information computed by
+// liveness analysis.
+static void
+livenessprintcfg(Liveness *lv)
+{
+	BasicBlock *bb;
+	int32 i;
+
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+		livenessprintblock(lv, bb);
+	}
+}
+
+static void
+checkauto(Node *fn, Prog *p, Node *n)
+{
+	NodeList *l;
+
+	for(l = fn->dcl; l != nil; l = l->next)
+		if(l->n->op == ONAME && l->n->class == PAUTO && l->n == n)
+			return;
+
+	print("checkauto %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
+	for(l = fn->dcl; l != nil; l = l->next)
+		print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
+	yyerror("checkauto: invariant lost");
+}
+
+static void
+checkparam(Node *fn, Prog *p, Node *n)
+{
+	NodeList *l;
+	Node *a;
+	int class;
+
+	if(isfunny(n))
+		return;
+	for(l = fn->dcl; l != nil; l = l->next) {
+		a = l->n;
+		class = a->class & ~PHEAP;
+		if(a->op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n)
+			return;
+	}
+
+	print("checkparam %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
+	for(l = fn->dcl; l != nil; l = l->next)
+		print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
+	yyerror("checkparam: invariant lost");
+}
+
+static void
+checkprog(Node *fn, Prog *p)
+{
+	if(p->from.type == D_AUTO)
+		checkauto(fn, p, p->from.node);
+	if(p->from.type == D_PARAM)
+		checkparam(fn, p, p->from.node);
+	if(p->to.type == D_AUTO)
+		checkauto(fn, p, p->to.node);
+	if(p->to.type == D_PARAM)
+		checkparam(fn, p, p->to.node);
+}
+
+// Check instruction invariants.  We assume that the nodes corresponding to the
+// sources and destinations of memory operations will be declared in the
+// function.  This is not strictly true, as is the case for the so-called funny
+// nodes and there are special cases to skip over that stuff.  The analysis will
+// fail if this invariant blindly changes.
+static void
+checkptxt(Node *fn, Prog *firstp)
+{
+	Prog *p;
+
+	if(debuglive == 0)
+		return;
+
+	for(p = firstp; p != P; p = p->link) {
+		if(0)
+			print("analyzing '%P'\n", p);
+		switch(p->as) {
+		case ADATA:
+		case AGLOBL:
+		case ANAME:
+		case ASIGNAME:
+		case ATYPE:
+			continue;
+		}
+		checkprog(fn, p);
+	}
+}
+
+// NOTE: The bitmap for a specific type t should be cached in t after the first run
+// and then simply copied into bv at the correct offset on future calls with
+// the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, twobitwalktype1
+// accounts for 40% of the 6g execution time.
+void
+twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
+{
+	vlong fieldoffset;
+	vlong i;
+	vlong o;
+	Type *t1;
+
+	if(t->align > 0 && (*xoffset & (t->align - 1)) != 0)
+		fatal("twobitwalktype1: invalid initial alignment, %T", t);
+
+	switch(t->etype) {
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TINT:
+	case TUINT:
+	case TUINTPTR:
+	case TBOOL:
+	case TFLOAT32:
+	case TFLOAT64:
+	case TCOMPLEX64:
+	case TCOMPLEX128:
+		for(i = 0; i < t->width; i++) {
+			bvset(bv, ((*xoffset + i) / widthptr) * BitsPerPointer); // 1 = live scalar
+		}
+		*xoffset += t->width;
+		break;
+
+	case TPTR32:
+	case TPTR64:
+	case TUNSAFEPTR:
+	case TFUNC:
+	case TCHAN:
+	case TMAP:
+		if((*xoffset & (widthptr-1)) != 0)
+			fatal("twobitwalktype1: invalid alignment, %T", t);
+		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr
+		*xoffset += t->width;
+		break;
+
+	case TSTRING:
+		// struct { byte *str; intgo len; }
+		if((*xoffset & (widthptr-1)) != 0)
+			fatal("twobitwalktype1: invalid alignment, %T", t);
+		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr in first slot
+		*xoffset += t->width;
+		break;
+
+	case TINTER:
+		// struct { Itab *tab;	union { void *ptr, uintptr val } data; }
+		// or, when isnilinter(t)==true:
+		// struct { Type *type; union { void *ptr, uintptr val } data; }
+		if((*xoffset & (widthptr-1)) != 0)
+			fatal("twobitwalktype1: invalid alignment, %T", t);
+		bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 0);
+		bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1); // 3 = multiword
+		// next word contains 2 = Iface, 3 = Eface
+		if(isnilinter(t)) {
+			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 2);
+			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
+		} else {
+			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
+		}
+		*xoffset += t->width;
+		break;
+
+	case TARRAY:
+		// The value of t->bound is -1 for slices types and >0 for
+		// for fixed array types.  All other values are invalid.
+		if(t->bound < -1)
+			fatal("twobitwalktype1: invalid bound, %T", t);
+		if(isslice(t)) {
+			// struct { byte *array; uintgo len; uintgo cap; }
+			if((*xoffset & (widthptr-1)) != 0)
+				fatal("twobitwalktype1: invalid TARRAY alignment, %T", t);
+			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr in first slot
+			*xoffset += t->width;
+		} else
+			for(i = 0; i < t->bound; i++)
+				twobitwalktype1(t->type, xoffset, bv);
+		break;
+
+	case TSTRUCT:
+		o = 0;
+		for(t1 = t->type; t1 != T; t1 = t1->down) {
+			fieldoffset = t1->width;
+			*xoffset += fieldoffset - o;
+			twobitwalktype1(t1->type, xoffset, bv);
+			o = fieldoffset + t1->type->width;
+		}
+		*xoffset += t->width - o;
+		break;
+
+	default:
+		fatal("twobitwalktype1: unexpected type, %T", t);
+	}
+}
+
+// Returns the number of words of local variables.
+static int32
+localswords(void)
+{
+	return stkptrsize / widthptr;
+}
+
+// Returns the number of words of in and out arguments.
+static int32
+argswords(void)
+{
+	return curfn->type->argwid / widthptr;
+}
+
+// Generates live pointer value maps for arguments and local variables.  The
+// this argument and the in arguments are always assumed live.  The vars
+// argument is an array of Node*s.
+static void
+twobitlivepointermap(Liveness *lv, Bvec *liveout, Array *vars, Bvec *args, Bvec *locals)
+{
+	Node *node;
+	Type *thisargtype;
+	Type *inargtype;
+	vlong xoffset;
+	int32 i;
+
+	for(i = 0; (i = bvnext(liveout, i)) >= 0; i++) {
+		node = *(Node**)arrayget(vars, i);
+		switch(node->class) {
+		case PAUTO:
+			xoffset = node->xoffset + stkptrsize;
+			twobitwalktype1(node->type, &xoffset, locals);
+			break;
+		case PPARAM:
+		case PPARAMOUT:
+			xoffset = node->xoffset;
+			twobitwalktype1(node->type, &xoffset, args);
+			break;
+		}
+	}
+	
+	// The node list only contains declared names.
+	// If the receiver or arguments are unnamed, they will be omitted
+	// from the list above. Preserve those values - even though they are unused -
+	// in order to keep their addresses live for use in stack traces.
+	thisargtype = getthisx(lv->fn->type);
+	if(thisargtype != nil) {
+		xoffset = 0;
+		twobitwalktype1(thisargtype, &xoffset, args);
+	}
+	inargtype = getinargx(lv->fn->type);
+	if(inargtype != nil) {
+		xoffset = 0;
+		twobitwalktype1(inargtype, &xoffset, args);
+	}
+}
+
+// Construct a disembodied instruction.
+static Prog*
+unlinkedprog(int as)
+{
+	Prog *p;
+
+	p = mal(sizeof(*p));
+	clearp(p);
+	p->as = as;
+	return p;
+}
+
+// Construct a new PCDATA instruction associated with and for the purposes of
+// covering an existing instruction.
+static Prog*
+newpcdataprog(Prog *prog, int32 index)
+{
+	Node from, to;
+	Prog *pcdata;
+
+	nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
+	nodconst(&to, types[TINT32], index);
+	pcdata = unlinkedprog(APCDATA);
+	pcdata->lineno = prog->lineno;
+	naddr(&from, &pcdata->from, 0);
+	naddr(&to, &pcdata->to, 0);
+	return pcdata;
+}
+
+// Returns true for instructions that are safe points that must be annotated
+// with liveness information.
+static int
+issafepoint(Prog *prog)
+{
+	return prog->as == ATEXT || prog->as == ACALL;
+}
+
+// Initializes the sets for solving the live variables.  Visits all the
+// instructions in each basic block to summarizes the information at each basic
+// block
+static void
+livenessprologue(Liveness *lv)
+{
+	BasicBlock *bb;
+	Bvec *uevar, *varkill, *avarinit;
+	Prog *p;
+	int32 i;
+	int32 nvars;
+
+	nvars = arraylength(lv->vars);
+	uevar = bvalloc(nvars);
+	varkill = bvalloc(nvars);
+	avarinit = bvalloc(nvars);
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+		// Walk the block instructions backward and update the block
+		// effects with the each prog effects.
+		for(p = bb->last; p != nil; p = p->opt) {
+			progeffects(p, lv->vars, uevar, varkill, avarinit);
+			if(debuglive >= 3)
+				printeffects(p, uevar, varkill, avarinit);
+			bvor(lv->varkill[i], lv->varkill[i], varkill);
+			bvandnot(lv->uevar[i], lv->uevar[i], varkill);
+			bvor(lv->uevar[i], lv->uevar[i], uevar);			
+		}
+		// Walk the block instructions forward to update avarinit bits.
+		// avarinit describes the effect at the end of the block, not the beginning.
+		bvresetall(varkill);
+		for(p = bb->first;; p = p->link) {
+			progeffects(p, lv->vars, uevar, varkill, avarinit);
+			if(debuglive >= 3)
+				printeffects(p, uevar, varkill, avarinit);
+			bvandnot(lv->avarinit[i], lv->avarinit[i], varkill);
+			bvor(lv->avarinit[i], lv->avarinit[i], avarinit);
+			if(p == bb->last)
+				break;
+		}
+	}
+	free(uevar);
+	free(varkill);
+	free(avarinit);
+}
+
+// Solve the liveness dataflow equations.
+static void
+livenesssolve(Liveness *lv)
+{
+	BasicBlock *bb, *succ, *pred;
+	Bvec *newlivein, *newliveout, *any, *all;
+	int32 rpo, i, j, change;
+
+	// These temporary bitvectors exist to avoid successive allocations and
+	// frees within the loop.
+	newlivein = bvalloc(arraylength(lv->vars));
+	newliveout = bvalloc(arraylength(lv->vars));
+	any = bvalloc(arraylength(lv->vars));
+	all = bvalloc(arraylength(lv->vars));
+
+	// Push avarinitall, avarinitany forward.
+	// avarinitall says the addressed var is initialized along all paths reaching the block exit.
+	// avarinitany says the addressed var is initialized along some path reaching the block exit.
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+		rpo = bb->rpo;
+		if(i == 0)
+			bvcopy(lv->avarinitall[rpo], lv->avarinit[rpo]);
+		else {
+			bvresetall(lv->avarinitall[rpo]);
+			bvnot(lv->avarinitall[rpo]);
+		}
+		bvcopy(lv->avarinitany[rpo], lv->avarinit[rpo]);
+	}
+
+	change = 1;
+	while(change != 0) {
+		change = 0;
+		for(i = 0; i < arraylength(lv->cfg); i++) {
+			bb = *(BasicBlock**)arrayget(lv->cfg, i);
+			rpo = bb->rpo;
+			bvresetall(any);
+			bvresetall(all);
+			for(j = 0; j < arraylength(bb->pred); j++) {
+				pred = *(BasicBlock**)arrayget(bb->pred, j);
+				if(j == 0) {
+					bvcopy(any, lv->avarinitany[pred->rpo]);
+					bvcopy(all, lv->avarinitall[pred->rpo]);
+				} else {
+					bvor(any, any, lv->avarinitany[pred->rpo]);
+					bvand(all, all, lv->avarinitall[pred->rpo]);
+				}
+			}
+			bvandnot(any, any, lv->varkill[rpo]);
+			bvandnot(all, all, lv->varkill[rpo]);
+			bvor(any, any, lv->avarinit[rpo]);
+			bvor(all, all, lv->avarinit[rpo]);
+			if(bvcmp(any, lv->avarinitany[rpo])) {
+				change = 1;
+				bvcopy(lv->avarinitany[rpo], any);
+			}
+			if(bvcmp(all, lv->avarinitall[rpo])) {
+				change = 1;
+				bvcopy(lv->avarinitall[rpo], all);
+			}
+		}
+	}
+
+	// Iterate through the blocks in reverse round-robin fashion.  A work
+	// queue might be slightly faster.  As is, the number of iterations is
+	// so low that it hardly seems to be worth the complexity.
+	change = 1;
+	while(change != 0) {
+		change = 0;
+		// Walk blocks in the general direction of propagation.  This
+		// improves convergence.
+		for(i = arraylength(lv->cfg) - 1; i >= 0; i--) {
+			// A variable is live on output from this block
+			// if it is live on input to some successor.
+			//
+			// out[b] = \bigcup_{s \in succ[b]} in[s]
+			bb = *(BasicBlock**)arrayget(lv->cfg, i);
+			rpo = bb->rpo;
+			bvresetall(newliveout);
+			for(j = 0; j < arraylength(bb->succ); j++) {
+				succ = *(BasicBlock**)arrayget(bb->succ, j);
+				bvor(newliveout, newliveout, lv->livein[succ->rpo]);
+			}
+			if(bvcmp(lv->liveout[rpo], newliveout)) {
+				change = 1;
+				bvcopy(lv->liveout[rpo], newliveout);
+			}
+
+			// A variable is live on input to this block
+			// if it is live on output from this block and
+			// not set by the code in this block.
+			//
+			// in[b] = uevar[b] \cup (out[b] \setminus varkill[b])
+			bvandnot(newlivein, lv->liveout[rpo], lv->varkill[rpo]);
+			bvor(lv->livein[rpo], newlivein, lv->uevar[rpo]);
+		}
+	}
+
+	free(newlivein);
+	free(newliveout);
+	free(any);
+	free(all);
+}
+
+// This function is slow but it is only used for generating debug prints.
+// Check whether n is marked live in args/locals.
+static int
+islive(Node *n, Bvec *args, Bvec *locals)
+{
+	int i;
+
+	switch(n->class) {
+	case PPARAM:
+	case PPARAMOUT:
+		for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
+			if(bvget(args, n->xoffset/widthptr*BitsPerPointer + i))
+				return 1;
+		break;
+	case PAUTO:
+		for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
+			if(bvget(locals, (n->xoffset + stkptrsize)/widthptr*BitsPerPointer + i))
+				return 1;
+		break;
+	}
+	return 0;
+}
+
+// Visits all instructions in a basic block and computes a bit vector of live
+// variables at each safe point locations.
+static void
+livenessepilogue(Liveness *lv)
+{
+	BasicBlock *bb, *pred;
+	Bvec *ambig, *livein, *liveout, *uevar, *varkill, *args, *locals, *avarinit, *any, *all;
+	Node *n;
+	Prog *p, *next;
+	int32 i, j, numlive, startmsg, nmsg, nvars, pos;
+	vlong xoffset;
+	char **msg;
+	Fmt fmt;
+
+	nvars = arraylength(lv->vars);
+	livein = bvalloc(nvars);
+	liveout = bvalloc(nvars);
+	uevar = bvalloc(nvars);
+	varkill = bvalloc(nvars);
+	avarinit = bvalloc(nvars);
+	any = bvalloc(nvars);
+	all = bvalloc(nvars);
+	ambig = bvalloc(localswords() * BitsPerPointer);
+	msg = nil;
+	nmsg = 0;
+	startmsg = 0;
+
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+		
+		// Compute avarinitany and avarinitall for entry to block.
+		// This duplicates information known during livenesssolve
+		// but avoids storing two more vectors for each block.
+		bvresetall(any);
+		bvresetall(all);
+		for(j = 0; j < arraylength(bb->pred); j++) {
+			pred = *(BasicBlock**)arrayget(bb->pred, j);
+			if(j == 0) {
+				bvcopy(any, lv->avarinitany[pred->rpo]);
+				bvcopy(all, lv->avarinitall[pred->rpo]);
+			} else {
+				bvor(any, any, lv->avarinitany[pred->rpo]);
+				bvand(all, all, lv->avarinitall[pred->rpo]);
+			}
+		}
+
+		// Walk forward through the basic block instructions and
+		// allocate liveness maps for those instructions that need them.
+		// Seed the maps with information about the addrtaken variables.
+		for(p = bb->first;; p = p->link) {
+			progeffects(p, lv->vars, uevar, varkill, avarinit);
+			bvandnot(any, any, varkill);
+			bvandnot(all, all, varkill);
+			bvor(any, any, avarinit);
+			bvor(all, all, avarinit);
+
+			if(issafepoint(p)) {
+				// Annotate ambiguously live variables so that they can
+				// be zeroed at function entry.
+				// livein and liveout are dead here and used as temporaries.
+				// For now, only enabled when using GOEXPERIMENT=precisestack
+				// during make.bash / all.bash.
+				if(precisestack_enabled) {
+					bvresetall(livein);
+					bvandnot(liveout, any, all);
+					if(!bvisempty(liveout)) {
+						for(pos = 0; pos < liveout->n; pos++) {
+							if(!bvget(liveout, pos))
+								continue;
+							bvset(all, pos); // silence future warnings in this block
+							n = *(Node**)arrayget(lv->vars, pos);
+							if(!n->needzero) {
+								n->needzero = 1;
+								if(debuglive >= 1)
+									warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
+								// Record in 'ambiguous' bitmap.
+								xoffset = n->xoffset + stkptrsize;
+								twobitwalktype1(n->type, &xoffset, ambig);
+							}
+						}
+					}
+				}
+	
+				// Allocate a bit vector for each class and facet of
+				// value we are tracking.
+	
+				// Live stuff first.
+				args = bvalloc(argswords() * BitsPerPointer);
+				arrayadd(lv->argslivepointers, &args);
+				locals = bvalloc(localswords() * BitsPerPointer);
+				arrayadd(lv->livepointers, &locals);
+
+				if(debuglive >= 3) {
+					print("%P\n", p);
+					printvars("avarinitany", any, lv->vars);
+				}
+
+				// Record any values with an "address taken" reaching
+				// this code position as live. Must do now instead of below
+				// because the any/all calculation requires walking forward
+				// over the block (as this loop does), while the liveout
+				// requires walking backward (as the next loop does).
+				twobitlivepointermap(lv, any, lv->vars, args, locals);
+			}
+			
+			if(p == bb->last)
+				break;
+		}
+		bb->lastbitmapindex = arraylength(lv->livepointers) - 1;
+	}
+	
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+		
+		if(debuglive >= 1 && strcmp(curfn->nname->sym->name, "init") != 0 && curfn->nname->sym->name[0] != '.') {
+			nmsg = arraylength(lv->livepointers);
+			startmsg = nmsg;
+			msg = xmalloc(nmsg*sizeof msg[0]);
+			for(j=0; j<nmsg; j++)
+				msg[j] = nil;
+		}
+
+		// walk backward, emit pcdata and populate the maps
+		pos = bb->lastbitmapindex;
+		if(pos < 0) {
+			// the first block we encounter should have the ATEXT so
+			// at no point should pos ever be less than zero.
+			fatal("livenessepilogue");
+		}
+
+		bvcopy(livein, lv->liveout[bb->rpo]);
+		for(p = bb->last; p != nil; p = next) {
+			next = p->opt; // splicebefore modifies p->opt
+			// Propagate liveness information
+			progeffects(p, lv->vars, uevar, varkill, avarinit);
+			bvcopy(liveout, livein);
+			bvandnot(livein, liveout, varkill);
+			bvor(livein, livein, uevar);
+			if(debuglive >= 3 && issafepoint(p)){
+				print("%P\n", p);
+				printvars("uevar", uevar, lv->vars);
+				printvars("varkill", varkill, lv->vars);
+				printvars("livein", livein, lv->vars);
+				printvars("liveout", liveout, lv->vars);
+			}
+			if(issafepoint(p)) {
+				// Found an interesting instruction, record the
+				// corresponding liveness information.  
+				
+				// Useful sanity check: on entry to the function,
+				// the only things that can possibly be live are the
+				// input parameters.
+				if(p->as == ATEXT) {
+					for(j = 0; j < liveout->n; j++) {
+						if(!bvget(liveout, j))
+							continue;
+						n = *(Node**)arrayget(lv->vars, j);
+						if(n->class != PPARAM)
+							yyerrorl(p->lineno, "internal error: %N %lN recorded as live on entry", curfn->nname, n);
+					}
+				}
+
+				// Record live pointers.
+				args = *(Bvec**)arrayget(lv->argslivepointers, pos);
+				locals = *(Bvec**)arrayget(lv->livepointers, pos);
+				twobitlivepointermap(lv, liveout, lv->vars, args, locals);
+				
+				// Ambiguously live variables are zeroed immediately after
+				// function entry. Mark them live for all the non-entry bitmaps
+				// so that GODEBUG=gcdead=1 mode does not poison them.
+				if(p->as == ACALL)
+					bvor(locals, locals, ambig);
+
+				// Show live pointer bitmaps.
+				// We're interpreting the args and locals bitmap instead of liveout so that we
+				// include the bits added by the avarinit logic in the
+				// previous loop.
+				if(msg != nil) {
+					fmtstrinit(&fmt);
+					fmtprint(&fmt, "%L: live at ", p->lineno);
+					if(p->as == ACALL && p->to.node)
+						fmtprint(&fmt, "call to %s:", p->to.node->sym->name);
+					else if(p->as == ACALL)
+						fmtprint(&fmt, "indirect call:");
+					else
+						fmtprint(&fmt, "entry to %s:", p->from.node->sym->name);
+					numlive = 0;
+					for(j = 0; j < arraylength(lv->vars); j++) {
+						n = *(Node**)arrayget(lv->vars, j);
+						if(islive(n, args, locals)) {
+							fmtprint(&fmt, " %N", n);
+							numlive++;
+						}
+					}
+					fmtprint(&fmt, "\n");
+					if(numlive == 0) // squelch message
+						free(fmtstrflush(&fmt));
+					else
+						msg[--startmsg] = fmtstrflush(&fmt);
+				}
+
+				// Only CALL instructions need a PCDATA annotation.
+				// The TEXT instruction annotation is implicit.
+				if(p->as == ACALL) {
+					if(isdeferreturn(p)) {
+						// runtime.deferreturn modifies its return address to return
+						// back to the CALL, not to the subsequent instruction.
+						// Because the return comes back one instruction early,
+						// the PCDATA must begin one instruction early too.
+						// The instruction before a call to deferreturn is always a
+						// no-op, to keep PC-specific data unambiguous.
+						splicebefore(lv, bb, newpcdataprog(p->opt, pos), p->opt);
+					} else {
+						splicebefore(lv, bb, newpcdataprog(p, pos), p);
+					}
+				}
+
+				pos--;
+			}
+		}
+		if(msg != nil) {
+			for(j=startmsg; j<nmsg; j++) 
+				if(msg[j] != nil)
+					print("%s", msg[j]);
+			free(msg);
+			msg = nil;
+			nmsg = 0;
+			startmsg = 0;
+		}
+	}
+
+	free(livein);
+	free(liveout);
+	free(uevar);
+	free(varkill);
+	free(avarinit);
+	free(any);
+	free(all);
+	free(ambig);
+	
+	flusherrors();
+}
+
+// FNV-1 hash function constants.
+#define H0 2166136261UL
+#define Hp 16777619UL
+/*c2go
+enum
+{
+	H0 = 2166136261,
+	Hp = 16777619,
+};
+*/
+
+static uint32
+hashbitmap(uint32 h, Bvec *bv)
+{
+	uchar *p, *ep;
+	
+	p = (uchar*)bv->b;
+	ep = p + 4*((bv->n+31)/32);
+	while(p < ep)
+		h = (h*Hp) ^ *p++;
+	return h;
+}
+
+// Compact liveness information by coalescing identical per-call-site bitmaps.
+// The merging only happens for a single function, not across the entire binary.
+//
+// There are actually two lists of bitmaps, one list for the local variables and one
+// list for the function arguments. Both lists are indexed by the same PCDATA
+// index, so the corresponding pairs must be considered together when
+// merging duplicates. The argument bitmaps change much less often during
+// function execution than the local variable bitmaps, so it is possible that
+// we could introduce a separate PCDATA index for arguments vs locals and
+// then compact the set of argument bitmaps separately from the set of
+// local variable bitmaps. As of 2014-04-02, doing this to the godoc binary
+// is actually a net loss: we save about 50k of argument bitmaps but the new
+// PCDATA tables cost about 100k. So for now we keep using a single index for
+// both bitmap lists.
+static void
+livenesscompact(Liveness *lv)
+{
+	int *table, *remap, i, j, n, tablesize, uniq;
+	uint32 h;
+	Bvec *local, *arg, *jlocal, *jarg;
+	Prog *p;
+
+	// Linear probing hash table of bitmaps seen so far.
+	// The hash table has 4n entries to keep the linear
+	// scan short. An entry of -1 indicates an empty slot.
+	n = arraylength(lv->livepointers);
+	tablesize = 4*n;
+	table = xmalloc(tablesize*sizeof table[0]);
+	memset(table, 0xff, tablesize*sizeof table[0]);
+	
+	// remap[i] = the new index of the old bit vector #i.
+	remap = xmalloc(n*sizeof remap[0]);
+	memset(remap, 0xff, n*sizeof remap[0]);
+	uniq = 0; // unique tables found so far
+
+	// Consider bit vectors in turn.
+	// If new, assign next number using uniq,
+	// record in remap, record in lv->livepointers and lv->argslivepointers
+	// under the new index, and add entry to hash table.
+	// If already seen, record earlier index in remap and free bitmaps.
+	for(i=0; i<n; i++) {
+		local = *(Bvec**)arrayget(lv->livepointers, i);
+		arg = *(Bvec**)arrayget(lv->argslivepointers, i);
+		h = hashbitmap(hashbitmap(H0, local), arg) % tablesize;
+
+		for(;;) {
+			j = table[h];
+			if(j < 0)
+				break;
+			jlocal = *(Bvec**)arrayget(lv->livepointers, j);
+			jarg = *(Bvec**)arrayget(lv->argslivepointers, j);
+			if(bvcmp(local, jlocal) == 0 && bvcmp(arg, jarg) == 0) {
+				free(local);
+				free(arg);
+				remap[i] = j;
+				goto Next;
+			}
+			if(++h == tablesize)
+				h = 0;
+		}
+		table[h] = uniq;
+		remap[i] = uniq;
+		*(Bvec**)arrayget(lv->livepointers, uniq) = local;
+		*(Bvec**)arrayget(lv->argslivepointers, uniq) = arg;
+		uniq++;
+	Next:;
+	}
+
+	// We've already reordered lv->livepointers[0:uniq]
+	// and lv->argslivepointers[0:uniq] and freed the bitmaps
+	// we don't need anymore. Clear the pointers later in the
+	// array so that we can tell where the coalesced bitmaps stop
+	// and so that we don't double-free when cleaning up.
+	for(j=uniq; j<n; j++) {
+		*(Bvec**)arrayget(lv->livepointers, j) = nil;
+		*(Bvec**)arrayget(lv->argslivepointers, j) = nil;
+	}
+	
+	// Rewrite PCDATA instructions to use new numbering.
+	for(p=lv->ptxt; p != P; p=p->link) {
+		if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) {
+			i = p->to.offset;
+			if(i >= 0)
+				p->to.offset = remap[i];
+		}
+	}
+
+	free(table);
+	free(remap);
+}
+
+static int
+printbitset(int printed, char *name, Array *vars, Bvec *bits)
+{
+	int i, started;
+	Node *n;
+
+	started = 0;	
+	for(i=0; i<arraylength(vars); i++) {
+		if(!bvget(bits, i))
+			continue;
+		if(!started) {
+			if(!printed)
+				print("\t");
+			else
+				print(" ");
+			started = 1;
+			printed = 1;
+			print("%s=", name);
+		} else {
+			print(",");
+		}
+		n = *(Node**)arrayget(vars, i);
+		print("%s", n->sym->name);
+	}
+	return printed;
+}
+
+// Prints the computed liveness information and inputs, for debugging.
+// This format synthesizes the information used during the multiple passes
+// into a single presentation.
+static void
+livenessprintdebug(Liveness *lv)
+{
+	int i, j, pcdata, printed;
+	BasicBlock *bb;
+	Prog *p;
+	Bvec *uevar, *varkill, *avarinit, *args, *locals;
+	Node *n;
+
+	print("liveness: %s\n", curfn->nname->sym->name);
+
+	uevar = bvalloc(arraylength(lv->vars));
+	varkill = bvalloc(arraylength(lv->vars));
+	avarinit = bvalloc(arraylength(lv->vars));
+
+	pcdata = 0;
+	for(i = 0; i < arraylength(lv->cfg); i++) {
+		if(i > 0)
+			print("\n");
+		bb = *(BasicBlock**)arrayget(lv->cfg, i);
+
+		// bb#0 pred=1,2 succ=3,4
+		print("bb#%d pred=", i);
+		for(j = 0; j < arraylength(bb->pred); j++) {
+			if(j > 0)
+				print(",");
+			print("%d", (*(BasicBlock**)arrayget(bb->pred, j))->rpo);
+		}
+		print(" succ=");
+		for(j = 0; j < arraylength(bb->succ); j++) {
+			if(j > 0)
+				print(",");
+			print("%d", (*(BasicBlock**)arrayget(bb->succ, j))->rpo);
+		}
+		print("\n");
+		
+		// initial settings
+		printed = 0;
+		printed = printbitset(printed, "uevar", lv->vars, lv->uevar[bb->rpo]);
+		printed = printbitset(printed, "livein", lv->vars, lv->livein[bb->rpo]);
+		if(printed)
+			print("\n");
+		
+		// program listing, with individual effects listed
+		for(p = bb->first;; p = p->link) {
+			print("%P\n", p);
+			if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex)
+				pcdata = p->to.offset;
+			progeffects(p, lv->vars, uevar, varkill, avarinit);
+			printed = 0;
+			printed = printbitset(printed, "uevar", lv->vars, uevar);
+			printed = printbitset(printed, "varkill", lv->vars, varkill);
+			printed = printbitset(printed, "avarinit", lv->vars, avarinit);
+			if(printed)
+				print("\n");
+			if(issafepoint(p)) {
+				args = *(Bvec**)arrayget(lv->argslivepointers, pcdata);
+				locals = *(Bvec**)arrayget(lv->livepointers, pcdata);
+				print("\tlive=");
+				printed = 0;
+				for(j = 0; j < arraylength(lv->vars); j++) {
+					n = *(Node**)arrayget(lv->vars, j);
+					if(islive(n, args, locals)) {
+						if(printed++)
+							print(",");
+						print("%N", n);
+					}
+				}
+				print("\n");
+			}
+			if(p == bb->last)
+				break;
+		}
+		
+		// bb bitsets
+		print("end\n");
+		printed = printbitset(printed, "varkill", lv->vars, lv->varkill[bb->rpo]);
+		printed = printbitset(printed, "liveout", lv->vars, lv->liveout[bb->rpo]);
+		printed = printbitset(printed, "avarinit", lv->vars, lv->avarinit[bb->rpo]);
+		printed = printbitset(printed, "avarinitany", lv->vars, lv->avarinitany[bb->rpo]);
+		printed = printbitset(printed, "avarinitall", lv->vars, lv->avarinitall[bb->rpo]);
+		if(printed)
+			print("\n");
+	}
+	print("\n");
+
+	free(uevar);
+	free(varkill);
+	free(avarinit);
+}
+
+// Dumps an array of bitmaps to a symbol as a sequence of uint32 values.  The
+// first word dumped is the total number of bitmaps.  The second word is the
+// length of the bitmaps.  All bitmaps are assumed to be of equal length.  The
+// words that are followed are the raw bitmap words.  The arr argument is an
+// array of Node*s.
+static void
+twobitwritesymbol(Array *arr, Sym *sym)
+{
+	Bvec *bv;
+	int off, i, j, len;
+	uint32 word;
+
+	len = arraylength(arr);
+	off = 0;
+	off += 4; // number of bitmaps, to fill in later
+	bv = *(Bvec**)arrayget(arr, 0);
+	off = duint32(sym, off, bv->n); // number of bits in each bitmap
+	for(i = 0; i < len; i++) {
+		// bitmap words
+		bv = *(Bvec**)arrayget(arr, i);
+		if(bv == nil)
+			break;
+		for(j = 0; j < bv->n; j += 32) {
+			word = bv->b[j/32];
+			// Runtime reads the bitmaps as byte arrays. Oblige.
+			off = duint8(sym, off, word);
+			off = duint8(sym, off, word>>8);
+			off = duint8(sym, off, word>>16);
+			off = duint8(sym, off, word>>24);
+		}
+	}
+	duint32(sym, 0, i); // number of bitmaps
+	ggloblsym(sym, off, RODATA);
+}
+
+static void
+printprog(Prog *p)
+{
+	while(p != nil) {
+		print("%P\n", p);
+		p = p->link;
+	}
+}
+
+// Entry pointer for liveness analysis.  Constructs a complete CFG, solves for
+// the liveness of pointer variables in the function, and emits a runtime data
+// structure read by the garbage collector.
+void
+liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym)
+{
+	Array *cfg, *vars;
+	Liveness *lv;
+	int debugdelta;
+	NodeList *l;
+
+	// Change name to dump debugging information only for a specific function.
+	debugdelta = 0;
+	if(strcmp(curfn->nname->sym->name, "!") == 0)
+		debugdelta = 2;
+	
+	debuglive += debugdelta;
+	if(debuglive >= 3) {
+		print("liveness: %s\n", curfn->nname->sym->name);
+		printprog(firstp);
+	}
+	checkptxt(fn, firstp);
+
+	// Construct the global liveness state.
+	cfg = newcfg(firstp);
+	if(debuglive >= 3)
+		printcfg(cfg);
+	vars = getvariables(fn);
+	lv = newliveness(fn, firstp, cfg, vars);
+
+	// Run the dataflow framework.
+	livenessprologue(lv);
+	if(debuglive >= 3)
+		livenessprintcfg(lv);
+	livenesssolve(lv);
+	if(debuglive >= 3)
+		livenessprintcfg(lv);
+	livenessepilogue(lv);
+	if(debuglive >= 3)
+		livenessprintcfg(lv);
+	livenesscompact(lv);
+
+	if(debuglive >= 2)
+		livenessprintdebug(lv);
+
+	// Emit the live pointer map data structures
+	twobitwritesymbol(lv->livepointers, livesym);
+	twobitwritesymbol(lv->argslivepointers, argssym);
+
+	// Free everything.
+	for(l=fn->dcl; l != nil; l = l->next)
+		if(l->n != N)
+			l->n->opt = nil;
+	freeliveness(lv);
+	arrayfree(vars);
+	freecfg(cfg);
+	
+	debuglive -= debugdelta;
+}
diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c
new file mode 100644
index 0000000..993bb24
--- /dev/null
+++ b/src/cmd/gc/popt.c
@@ -0,0 +1,1005 @@
+// Derived from Inferno utils/6c/reg.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/reg.c
+//
+//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//	Portions Copyright © 1997-1999 Vita Nuova Limited
+//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//	Portions Copyright © 2004,2006 Bruce Ellis
+//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// "Portable" optimizations.
+// Compiled separately for 5g, 6g, and 8g, so allowed to use gg.h, opt.h.
+// Must code to the intersection of the three back ends.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"gg.h"
+#include	"opt.h"
+
+// p is a call instruction. Does the call fail to return?
+int
+noreturn(Prog *p)
+{
+	Sym *s;
+	int i;
+	static Sym*	symlist[10];
+
+	if(symlist[0] == S) {
+		symlist[0] = pkglookup("panicindex", runtimepkg);
+		symlist[1] = pkglookup("panicslice", runtimepkg);
+		symlist[2] = pkglookup("throwinit", runtimepkg);
+		symlist[3] = pkglookup("gopanic", runtimepkg);
+		symlist[4] = pkglookup("panicwrap", runtimepkg);
+		symlist[5] = pkglookup("throwreturn", runtimepkg);
+		symlist[6] = pkglookup("selectgo", runtimepkg);
+		symlist[7] = pkglookup("block", runtimepkg);
+	}
+
+	if(p->to.node == nil)
+		return 0;
+	s = p->to.node->sym;
+	if(s == S)
+		return 0;
+	for(i=0; symlist[i]!=S; i++)
+		if(s == symlist[i])
+			return 1;
+	return 0;
+}
+
+// JMP chasing and removal.
+//
+// The code generator depends on being able to write out jump
+// instructions that it can jump to now but fill in later.
+// the linker will resolve them nicely, but they make the code
+// longer and more difficult to follow during debugging.
+// Remove them.
+
+/* what instruction does a JMP to p eventually land on? */
+static Prog*
+chasejmp(Prog *p, int *jmploop)
+{
+	int n;
+
+	n = 0;
+	while(p != P && p->as == AJMP && p->to.type == D_BRANCH) {
+		if(++n > 10) {
+			*jmploop = 1;
+			break;
+		}
+		p = p->to.u.branch;
+	}
+	return p;
+}
+
+/*
+ * reuse reg pointer for mark/sweep state.
+ * leave reg==nil at end because alive==nil.
+ */
+#define alive ((void*)0)
+#define dead ((void*)1)
+/*c2go
+extern void *alive;
+extern void *dead;
+*/
+
+/* mark all code reachable from firstp as alive */
+static void
+mark(Prog *firstp)
+{
+	Prog *p;
+	
+	for(p=firstp; p; p=p->link) {
+		if(p->opt != dead)
+			break;
+		p->opt = alive;
+		if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch)
+			mark(p->to.u.branch);
+		if(p->as == AJMP || p->as == ARET || p->as == AUNDEF)
+			break;
+	}
+}
+
+void
+fixjmp(Prog *firstp)
+{
+	int jmploop;
+	Prog *p, *last;
+	
+	if(debug['R'] && debug['v'])
+		print("\nfixjmp\n");
+
+	// pass 1: resolve jump to jump, mark all code as dead.
+	jmploop = 0;
+	for(p=firstp; p; p=p->link) {
+		if(debug['R'] && debug['v'])
+			print("%P\n", p);
+		if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch && p->to.u.branch->as == AJMP) {
+			p->to.u.branch = chasejmp(p->to.u.branch, &jmploop);
+			if(debug['R'] && debug['v'])
+				print("->%P\n", p);
+		}
+		p->opt = dead;
+	}
+	if(debug['R'] && debug['v'])
+		print("\n");
+
+	// pass 2: mark all reachable code alive
+	mark(firstp);
+	
+	// pass 3: delete dead code (mostly JMPs).
+	last = nil;
+	for(p=firstp; p; p=p->link) {
+		if(p->opt == dead) {
+			if(p->link == P && p->as == ARET && last && last->as != ARET) {
+				// This is the final ARET, and the code so far doesn't have one.
+				// Let it stay. The register allocator assumes that all live code in
+				// the function can be traversed by starting at all the RET instructions
+				// and following predecessor links. If we remove the final RET,
+				// this assumption will not hold in the case of an infinite loop
+				// at the end of a function.
+				// Keep the RET but mark it dead for the liveness analysis.
+				p->mode = 1;
+			} else {
+				if(debug['R'] && debug['v'])
+					print("del %P\n", p);
+				continue;
+			}
+		}
+		if(last)
+			last->link = p;
+		last = p;
+	}
+	last->link = P;
+	
+	// pass 4: elide JMP to next instruction.
+	// only safe if there are no jumps to JMPs anymore.
+	if(!jmploop) {
+		last = nil;
+		for(p=firstp; p; p=p->link) {
+			if(p->as == AJMP && p->to.type == D_BRANCH && p->to.u.branch == p->link) {
+				if(debug['R'] && debug['v'])
+					print("del %P\n", p);
+				continue;
+			}
+			if(last)
+				last->link = p;
+			last = p;
+		}
+		last->link = P;
+	}
+	
+	if(debug['R'] && debug['v']) {
+		print("\n");
+		for(p=firstp; p; p=p->link)
+			print("%P\n", p);
+		print("\n");
+	}
+}
+
+#undef alive
+#undef dead
+
+// Control flow analysis. The Flow structures hold predecessor and successor
+// information as well as basic loop analysis.
+//
+//	graph = flowstart(firstp, sizeof(Flow));
+//	... use flow graph ...
+//	flowend(graph); // free graph
+//
+// Typical uses of the flow graph are to iterate over all the flow-relevant instructions:
+//
+//	for(f = graph->start; f != nil; f = f->link)
+//
+// or, given an instruction f, to iterate over all the predecessors, which is
+// f->p1 and this list:
+//
+//	for(f2 = f->p2; f2 != nil; f2 = f2->p2link)
+//	
+// Often the Flow struct is embedded as the first field inside a larger struct S.
+// In that case casts are needed to convert Flow* to S* in many places but the
+// idea is the same. Pass sizeof(S) instead of sizeof(Flow) to flowstart.
+
+Graph*
+flowstart(Prog *firstp, int size)
+{
+	int nf;
+	Flow *f, *f1, *start, *last;
+	Graph *graph;
+	Prog *p;
+	ProgInfo info;
+
+	// Count and mark instructions to annotate.
+	nf = 0;
+	for(p = firstp; p != P; p = p->link) {
+		p->opt = nil; // should be already, but just in case
+		proginfo(&info, p);
+		if(info.flags & Skip)
+			continue;
+		p->opt = (void*)1;
+		nf++;
+	}
+	
+	if(nf == 0)
+		return nil;
+
+	if(nf >= 20000) {
+		// fatal("%S is too big (%d instructions)", curfn->nname->sym, nf);
+		return nil;
+	}
+
+	// Allocate annotations and assign to instructions.
+	graph = calloc(sizeof *graph + size*nf, 1);
+	if(graph == nil)
+		fatal("out of memory");
+	start = (Flow*)(graph+1);
+	last = nil;
+	f = start;
+	for(p = firstp; p != P; p = p->link) {
+		if(p->opt == nil)
+			continue;
+		p->opt = f;
+		f->prog = p;
+		if(last)
+			last->link = f;
+		last = f;
+		
+		f = (Flow*)((uchar*)f + size);
+	}
+
+	// Fill in pred/succ information.
+	for(f = start; f != nil; f = f->link) {
+		p = f->prog;
+		proginfo(&info, p);
+		if(!(info.flags & Break)) {
+			f1 = f->link;
+			f->s1 = f1;
+			f1->p1 = f;
+		}
+		if(p->to.type == D_BRANCH) {
+			if(p->to.u.branch == P)
+				fatal("pnil %P", p);
+			f1 = p->to.u.branch->opt;
+			if(f1 == nil)
+				fatal("fnil %P / %P", p, p->to.u.branch);
+			if(f1 == f) {
+				//fatal("self loop %P", p);
+				continue;
+			}
+			f->s2 = f1;
+			f->p2link = f1->p2;
+			f1->p2 = f;
+		}
+	}
+	
+	graph->start = start;
+	graph->num = nf;
+	return graph;
+}
+
+void
+flowend(Graph *graph)
+{
+	Flow *f;
+	
+	for(f = graph->start; f != nil; f = f->link)
+		f->prog->opt = nil;
+	free(graph);
+}
+
+/*
+ * find looping structure
+ *
+ * 1) find reverse postordering
+ * 2) find approximate dominators,
+ *	the actual dominators if the flow graph is reducible
+ *	otherwise, dominators plus some other non-dominators.
+ *	See Matthew S. Hecht and Jeffrey D. Ullman,
+ *	"Analysis of a Simple Algorithm for Global Data Flow Problems",
+ *	Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
+ *	Oct. 1-3, 1973, pp.  207-217.
+ * 3) find all nodes with a predecessor dominated by the current node.
+ *	such a node is a loop head.
+ *	recursively, all preds with a greater rpo number are in the loop
+ */
+static int32
+postorder(Flow *r, Flow **rpo2r, int32 n)
+{
+	Flow *r1;
+
+	r->rpo = 1;
+	r1 = r->s1;
+	if(r1 && !r1->rpo)
+		n = postorder(r1, rpo2r, n);
+	r1 = r->s2;
+	if(r1 && !r1->rpo)
+		n = postorder(r1, rpo2r, n);
+	rpo2r[n] = r;
+	n++;
+	return n;
+}
+
+static int32
+rpolca(int32 *idom, int32 rpo1, int32 rpo2)
+{
+	int32 t;
+
+	if(rpo1 == -1)
+		return rpo2;
+	while(rpo1 != rpo2){
+		if(rpo1 > rpo2){
+			t = rpo2;
+			rpo2 = rpo1;
+			rpo1 = t;
+		}
+		while(rpo1 < rpo2){
+			t = idom[rpo2];
+			if(t >= rpo2)
+				fatal("bad idom");
+			rpo2 = t;
+		}
+	}
+	return rpo1;
+}
+
+static int
+doms(int32 *idom, int32 r, int32 s)
+{
+	while(s > r)
+		s = idom[s];
+	return s == r;
+}
+
+static int
+loophead(int32 *idom, Flow *r)
+{
+	int32 src;
+
+	src = r->rpo;
+	if(r->p1 != nil && doms(idom, src, r->p1->rpo))
+		return 1;
+	for(r = r->p2; r != nil; r = r->p2link)
+		if(doms(idom, src, r->rpo))
+			return 1;
+	return 0;
+}
+
+static void
+loopmark(Flow **rpo2r, int32 head, Flow *r)
+{
+	if(r->rpo < head || r->active == head)
+		return;
+	r->active = head;
+	r->loop += LOOP;
+	if(r->p1 != nil)
+		loopmark(rpo2r, head, r->p1);
+	for(r = r->p2; r != nil; r = r->p2link)
+		loopmark(rpo2r, head, r);
+}
+
+void
+flowrpo(Graph *g)
+{
+	Flow *r1;
+	int32 i, d, me, nr, *idom;
+	Flow **rpo2r;
+
+	free(g->rpo);
+	g->rpo = calloc(g->num*sizeof g->rpo[0], 1);
+	idom = calloc(g->num*sizeof idom[0], 1);
+	if(g->rpo == nil || idom == nil)
+		fatal("out of memory");
+
+	for(r1 = g->start; r1 != nil; r1 = r1->link)
+		r1->active = 0;
+
+	rpo2r = g->rpo;
+	d = postorder(g->start, rpo2r, 0);
+	nr = g->num;
+	if(d > nr)
+		fatal("too many reg nodes %d %d", d, nr);
+	nr = d;
+	for(i = 0; i < nr / 2; i++) {
+		r1 = rpo2r[i];
+		rpo2r[i] = rpo2r[nr - 1 - i];
+		rpo2r[nr - 1 - i] = r1;
+	}
+	for(i = 0; i < nr; i++)
+		rpo2r[i]->rpo = i;
+
+	idom[0] = 0;
+	for(i = 0; i < nr; i++) {
+		r1 = rpo2r[i];
+		me = r1->rpo;
+		d = -1;
+		// rpo2r[r->rpo] == r protects against considering dead code,
+		// which has r->rpo == 0.
+		if(r1->p1 != nil && rpo2r[r1->p1->rpo] == r1->p1 && r1->p1->rpo < me)
+			d = r1->p1->rpo;
+		for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
+			if(rpo2r[r1->rpo] == r1 && r1->rpo < me)
+				d = rpolca(idom, d, r1->rpo);
+		idom[i] = d;
+	}
+
+	for(i = 0; i < nr; i++) {
+		r1 = rpo2r[i];
+		r1->loop++;
+		if(r1->p2 != nil && loophead(idom, r1))
+			loopmark(rpo2r, i, r1);
+	}
+	free(idom);
+
+	for(r1 = g->start; r1 != nil; r1 = r1->link)
+		r1->active = 0;
+}
+
+Flow*
+uniqp(Flow *r)
+{
+	Flow *r1;
+
+	r1 = r->p1;
+	if(r1 == nil) {
+		r1 = r->p2;
+		if(r1 == nil || r1->p2link != nil)
+			return nil;
+	} else
+		if(r->p2 != nil)
+			return nil;
+	return r1;
+}
+
+Flow*
+uniqs(Flow *r)
+{
+	Flow *r1;
+
+	r1 = r->s1;
+	if(r1 == nil) {
+		r1 = r->s2;
+		if(r1 == nil)
+			return nil;
+	} else
+		if(r->s2 != nil)
+			return nil;
+	return r1;
+}
+
+// The compilers assume they can generate temporary variables
+// as needed to preserve the right semantics or simplify code
+// generation and the back end will still generate good code.
+// This results in a large number of ephemeral temporary variables.
+// Merge temps with non-overlapping lifetimes and equal types using the
+// greedy algorithm in Poletto and Sarkar, "Linear Scan Register Allocation",
+// ACM TOPLAS 1999.
+
+typedef struct TempVar TempVar;
+typedef struct TempFlow TempFlow;
+
+struct TempVar
+{
+	Node *node;
+	TempFlow *def; // definition of temp var
+	TempFlow *use; // use list, chained through TempFlow.uselink
+	TempVar *freelink; // next free temp in Type.opt list
+	TempVar *merge; // merge var with this one
+	vlong start; // smallest Prog.pc in live range
+	vlong end; // largest Prog.pc in live range
+	uchar addr; // address taken - no accurate end
+	uchar removed; // removed from program
+};
+
+struct TempFlow
+{
+	Flow	f;
+	TempFlow *uselink;
+};
+
+static int
+startcmp(const void *va, const void *vb)
+{
+	TempVar *a, *b;
+	
+	a = *(TempVar**)va;
+	b = *(TempVar**)vb;
+
+	if(a->start < b->start)
+		return -1;
+	if(a->start > b->start)
+		return +1;
+	return 0;
+}
+
+// Is n available for merging?
+static int
+canmerge(Node *n)
+{
+	return n->class == PAUTO && strncmp(n->sym->name, "autotmp", 7) == 0;
+}
+
+static void mergewalk(TempVar*, TempFlow*, uint32);
+static void varkillwalk(TempVar*, TempFlow*, uint32);
+
+void
+mergetemp(Prog *firstp)
+{
+	int i, j, nvar, ninuse, nfree, nkill;
+	TempVar *var, *v, *v1, **bystart, **inuse;
+	TempFlow *r;
+	NodeList *l, **lp;
+	Node *n;
+	Prog *p, *p1;
+	Type *t;
+	ProgInfo info, info1;
+	int32 gen;
+	Graph *g;
+
+	enum { Debug = 0 };
+
+	g = flowstart(firstp, sizeof(TempFlow));
+	if(g == nil)
+		return;
+	
+	// Build list of all mergeable variables.
+	nvar = 0;
+	for(l = curfn->dcl; l != nil; l = l->next)
+		if(canmerge(l->n))
+			nvar++;
+	
+	var = calloc(nvar*sizeof var[0], 1);
+	nvar = 0;
+	for(l = curfn->dcl; l != nil; l = l->next) {
+		n = l->n;
+		if(canmerge(n)) {
+			v = &var[nvar++];
+			n->opt = v;
+			v->node = n;
+		}
+	}
+	
+	// Build list of uses.
+	// We assume that the earliest reference to a temporary is its definition.
+	// This is not true of variables in general but our temporaries are all
+	// single-use (that's why we have so many!).
+	for(r = (TempFlow*)g->start; r != nil; r = (TempFlow*)r->f.link) {
+		p = r->f.prog;
+		proginfo(&info, p);
+
+		if(p->from.node != N && p->from.node->opt && p->to.node != N && p->to.node->opt)
+			fatal("double node %P", p);
+		if((n = p->from.node) != N && (v = n->opt) != nil ||
+		   (n = p->to.node) != N && (v = n->opt) != nil) {
+		   	if(v->def == nil)
+		   		v->def = r;
+			r->uselink = v->use;
+			v->use = r;
+			if(n == p->from.node && (info.flags & LeftAddr))
+				v->addr = 1;
+		}
+	}
+	
+	if(Debug > 1)
+		dumpit("before", g->start, 0);
+	
+	nkill = 0;
+
+	// Special case.
+	for(v = var; v < var+nvar; v++) {
+		if(v->addr)
+			continue;
+		// Used in only one instruction, which had better be a write.
+		if((r = v->use) != nil && r->uselink == nil) {
+			p = r->f.prog;
+			proginfo(&info, p);
+			if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
+				p->as = ANOP;
+				p->to = zprog.to;
+				v->removed = 1;
+				if(Debug)
+					print("drop write-only %S\n", v->node->sym);
+			} else
+				fatal("temp used and not set: %P", p);
+			nkill++;
+			continue;
+		}
+		
+		// Written in one instruction, read in the next, otherwise unused,
+		// no jumps to the next instruction. Happens mainly in 386 compiler.
+		if((r = v->use) != nil && r->f.link == &r->uselink->f && r->uselink->uselink == nil && uniqp(r->f.link) == &r->f) {
+			p = r->f.prog;
+			proginfo(&info, p);
+			p1 = r->f.link->prog;
+			proginfo(&info1, p1);
+			enum {
+				SizeAny = SizeB | SizeW | SizeL | SizeQ | SizeF | SizeD,
+			};
+			if(p->from.node == v->node && p1->to.node == v->node && (info.flags & Move) &&
+			   !((info.flags|info1.flags) & (LeftAddr|RightAddr)) &&
+			   (info.flags & SizeAny) == (info1.flags & SizeAny)) {
+				p1->from = p->from;
+				excise(&r->f);
+				v->removed = 1;
+				if(Debug)
+					print("drop immediate-use %S\n", v->node->sym);
+			}
+			nkill++;
+			continue;
+		}			   
+	}
+
+	// Traverse live range of each variable to set start, end.
+	// Each flood uses a new value of gen so that we don't have
+	// to clear all the r->f.active words after each variable.
+	gen = 0;
+	for(v = var; v < var+nvar; v++) {
+		gen++;
+		for(r = v->use; r != nil; r = r->uselink)
+			mergewalk(v, r, gen);
+		if(v->addr) {
+			gen++;
+			for(r = v->use; r != nil; r = r->uselink)
+				varkillwalk(v, r, gen);
+		}
+	}
+
+	// Sort variables by start.
+	bystart = malloc(nvar*sizeof bystart[0]);
+	for(i=0; i<nvar; i++)
+		bystart[i] = &var[i];
+	qsort(bystart, nvar, sizeof bystart[0], startcmp);
+
+	// List of in-use variables, sorted by end, so that the ones that
+	// will last the longest are the earliest ones in the array.
+	// The tail inuse[nfree:] holds no-longer-used variables.
+	// In theory we should use a sorted tree so that insertions are
+	// guaranteed O(log n) and then the loop is guaranteed O(n log n).
+	// In practice, it doesn't really matter.
+	inuse = malloc(nvar*sizeof inuse[0]);
+	ninuse = 0;
+	nfree = nvar;
+	for(i=0; i<nvar; i++) {
+		v = bystart[i];
+		if(v->removed)
+			continue;
+
+		// Expire no longer in use.
+		while(ninuse > 0 && inuse[ninuse-1]->end < v->start) {
+			v1 = inuse[--ninuse];
+			inuse[--nfree] = v1;
+		}
+
+		// Find old temp to reuse if possible.
+		t = v->node->type;
+		for(j=nfree; j<nvar; j++) {
+			v1 = inuse[j];
+			// Require the types to match but also require the addrtaken bits to match.
+			// If a variable's address is taken, that disables registerization for the individual
+			// words of the variable (for example, the base,len,cap of a slice).
+			// We don't want to merge a non-addressed var with an addressed one and
+			// inhibit registerization of the former.
+			if(eqtype(t, v1->node->type) && v->node->addrtaken == v1->node->addrtaken) {
+				inuse[j] = inuse[nfree++];
+				if(v1->merge)
+					v->merge = v1->merge;
+				else
+					v->merge = v1;
+				nkill++;
+				break;
+			}
+		}
+
+		// Sort v into inuse.
+		j = ninuse++;
+		while(j > 0 && inuse[j-1]->end < v->end) {
+			inuse[j] = inuse[j-1];
+			j--;
+		}
+		inuse[j] = v;
+	}
+
+	if(Debug) {
+		print("%S [%d - %d]\n", curfn->nname->sym, nvar, nkill);
+		for(v=var; v<var+nvar; v++) {
+			print("var %#N %T %lld-%lld", v->node, v->node->type, v->start, v->end);
+			if(v->addr)
+				print(" addr=1");
+			if(v->removed)
+				print(" dead=1");
+			if(v->merge)
+				print(" merge %#N", v->merge->node);
+			if(v->start == v->end)
+				print(" %P", v->def->f.prog);
+			print("\n");
+		}
+	
+		if(Debug > 1)
+			dumpit("after", g->start, 0);
+	}
+
+	// Update node references to use merged temporaries.
+	for(r = (TempFlow*)g->start; r != nil; r = (TempFlow*)r->f.link) {
+		p = r->f.prog;
+		if((n = p->from.node) != N && (v = n->opt) != nil && v->merge != nil)
+			p->from.node = v->merge->node;
+		if((n = p->to.node) != N && (v = n->opt) != nil && v->merge != nil)
+			p->to.node = v->merge->node;
+	}
+
+	// Delete merged nodes from declaration list.
+	for(lp = &curfn->dcl; (l = *lp); ) {
+		curfn->dcl->end = l;
+		n = l->n;
+		v = n->opt;
+		if(v && (v->merge || v->removed)) {
+			*lp = l->next;
+			continue;
+		}
+		lp = &l->next;
+	}
+
+	// Clear aux structures.
+	for(v=var; v<var+nvar; v++)
+		v->node->opt = nil;
+	free(var);
+	free(bystart);
+	free(inuse);
+	flowend(g);
+}
+
+static void
+mergewalk(TempVar *v, TempFlow *r0, uint32 gen)
+{
+	Prog *p;
+	TempFlow *r1, *r, *r2;
+	
+	for(r1 = r0; r1 != nil; r1 = (TempFlow*)r1->f.p1) {
+		if(r1->f.active == gen)
+			break;
+		r1->f.active = gen;
+		p = r1->f.prog;
+		if(v->end < p->pc)
+			v->end = p->pc;
+		if(r1 == v->def) {
+			v->start = p->pc;
+			break;
+		}
+	}
+	
+	for(r = r0; r != r1; r = (TempFlow*)r->f.p1)
+		for(r2 = (TempFlow*)r->f.p2; r2 != nil; r2 = (TempFlow*)r2->f.p2link)
+			mergewalk(v, r2, gen);
+}
+
+static void
+varkillwalk(TempVar *v, TempFlow *r0, uint32 gen)
+{
+	Prog *p;
+	TempFlow *r1, *r;
+	
+	for(r1 = r0; r1 != nil; r1 = (TempFlow*)r1->f.s1) {
+		if(r1->f.active == gen)
+			break;
+		r1->f.active = gen;
+		p = r1->f.prog;
+		if(v->end < p->pc)
+			v->end = p->pc;
+		if(v->start > p->pc)
+			v->start = p->pc;
+		if(p->as == ARET || (p->as == AVARKILL && p->to.node == v->node))
+			break;
+	}
+	
+	for(r = r0; r != r1; r = (TempFlow*)r->f.s1)
+		varkillwalk(v, (TempFlow*)r->f.s2, gen);
+}
+
+// Eliminate redundant nil pointer checks.
+//
+// The code generation pass emits a CHECKNIL for every possibly nil pointer.
+// This pass removes a CHECKNIL if every predecessor path has already
+// checked this value for nil.
+//
+// Simple backwards flood from check to definition.
+// Run prog loop backward from end of program to beginning to avoid quadratic
+// behavior removing a run of checks.
+//
+// Assume that stack variables with address not taken can be loaded multiple times
+// from memory without being rechecked. Other variables need to be checked on
+// each load.
+	
+typedef struct NilVar NilVar;
+typedef struct NilFlow NilFlow;
+
+struct NilFlow {
+	Flow f;
+	int kill;
+};
+
+static void nilwalkback(NilFlow *rcheck);
+static void nilwalkfwd(NilFlow *rcheck);
+
+void
+nilopt(Prog *firstp)
+{
+	NilFlow *r;
+	Prog *p;
+	Graph *g;
+	int ncheck, nkill;
+
+	g = flowstart(firstp, sizeof(NilFlow));
+	if(g == nil)
+		return;
+
+	if(debug_checknil > 1 /* || strcmp(curfn->nname->sym->name, "f1") == 0 */)
+		dumpit("nilopt", g->start, 0);
+
+	ncheck = 0;
+	nkill = 0;
+	for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
+		p = r->f.prog;
+		if(p->as != ACHECKNIL || !regtyp(&p->from))
+			continue;
+		ncheck++;
+		if(stackaddr(&p->from)) {
+			if(debug_checknil && p->lineno > 1)
+				warnl(p->lineno, "removed nil check of SP address");
+			r->kill = 1;
+			continue;
+		}
+		nilwalkfwd(r);
+		if(r->kill) {
+			if(debug_checknil && p->lineno > 1)
+				warnl(p->lineno, "removed nil check before indirect");
+			continue;
+		}
+		nilwalkback(r);
+		if(r->kill) {
+			if(debug_checknil && p->lineno > 1)
+				warnl(p->lineno, "removed repeated nil check");
+			continue;
+		}
+	}
+	
+	for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
+		if(r->kill) {
+			nkill++;
+			excise(&r->f);
+		}
+	}
+
+	flowend(g);
+	
+	if(debug_checknil > 1)
+		print("%S: removed %d of %d nil checks\n", curfn->nname->sym, nkill, ncheck);
+}
+
+static void
+nilwalkback(NilFlow *rcheck)
+{
+	Prog *p;
+	ProgInfo info;
+	NilFlow *r;
+	
+	for(r = rcheck; r != nil; r = (NilFlow*)uniqp(&r->f)) {
+		p = r->f.prog;
+		proginfo(&info, p);
+		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
+			// Found initialization of value we're checking for nil.
+			// without first finding the check, so this one is unchecked.
+			return;
+		}
+		if(r != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from)) {
+			rcheck->kill = 1;
+			return;
+		}
+	}
+
+	// Here is a more complex version that scans backward across branches.
+	// It assumes rcheck->kill = 1 has been set on entry, and its job is to find a reason
+	// to keep the check (setting rcheck->kill = 0).
+	// It doesn't handle copying of aggregates as well as I would like,
+	// nor variables with their address taken,
+	// and it's too subtle to turn on this late in Go 1.2. Perhaps for Go 1.3.
+	/*
+	for(r1 = r0; r1 != nil; r1 = (NilFlow*)r1->f.p1) {
+		if(r1->f.active == gen)
+			break;
+		r1->f.active = gen;
+		p = r1->f.prog;
+		
+		// If same check, stop this loop but still check
+		// alternate predecessors up to this point.
+		if(r1 != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from))
+			break;
+
+		proginfo(&info, p);
+		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
+			// Found initialization of value we're checking for nil.
+			// without first finding the check, so this one is unchecked.
+			rcheck->kill = 0;
+			return;
+		}
+		
+		if(r1->f.p1 == nil && r1->f.p2 == nil) {
+			print("lost pred for %P\n", rcheck->f.prog);
+			for(r1=r0; r1!=nil; r1=(NilFlow*)r1->f.p1) {
+				proginfo(&info, r1->f.prog);
+				print("\t%P %d %d %D %D\n", r1->f.prog, info.flags&RightWrite, sameaddr(&r1->f.prog->to, &rcheck->f.prog->from), &r1->f.prog->to, &rcheck->f.prog->from);
+			}
+			fatal("lost pred trail");
+		}
+	}
+
+	for(r = r0; r != r1; r = (NilFlow*)r->f.p1)
+		for(r2 = (NilFlow*)r->f.p2; r2 != nil; r2 = (NilFlow*)r2->f.p2link)
+			nilwalkback(rcheck, r2, gen);
+	*/
+}
+
+static void
+nilwalkfwd(NilFlow *rcheck)
+{
+	NilFlow *r, *last;
+	Prog *p;
+	ProgInfo info;
+	
+	// If the path down from rcheck dereferences the address
+	// (possibly with a small offset) before writing to memory
+	// and before any subsequent checks, it's okay to wait for
+	// that implicit check. Only consider this basic block to
+	// avoid problems like:
+	//	_ = *x // should panic
+	//	for {} // no writes but infinite loop may be considered visible
+	last = nil;
+	for(r = (NilFlow*)uniqs(&rcheck->f); r != nil; r = (NilFlow*)uniqs(&r->f)) {
+		p = r->f.prog;
+		proginfo(&info, p);
+		
+		if((info.flags & LeftRead) && smallindir(&p->from, &rcheck->f.prog->from)) {
+			rcheck->kill = 1;
+			return;
+		}
+		if((info.flags & (RightRead|RightWrite)) && smallindir(&p->to, &rcheck->f.prog->from)) {
+			rcheck->kill = 1;
+			return;
+		}
+		
+		// Stop if another nil check happens.
+		if(p->as == ACHECKNIL)
+			return;
+		// Stop if value is lost.
+		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from))
+			return;
+		// Stop if memory write.
+		if((info.flags & RightWrite) && !regtyp(&p->to))
+			return;
+		// Stop if we jump backward.
+		// This test is valid because all the NilFlow* are pointers into
+		// a single contiguous array. We will need to add an explicit
+		// numbering when the code is converted to Go.
+		if(last != nil && r <= last)
+			return;
+		last = r;
+	}
+}
diff --git a/src/cmd/gc/popt.h b/src/cmd/gc/popt.h
new file mode 100644
index 0000000..8d5dfff
--- /dev/null
+++ b/src/cmd/gc/popt.h
@@ -0,0 +1,46 @@
+// Copyright 2013 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.
+
+typedef struct Flow Flow;
+typedef struct Graph Graph;
+
+struct Flow {
+	Prog*	prog;   	// actual instruction
+	Flow*	p1;     	// predecessors of this instruction: p1,
+	Flow*	p2;     	// and then p2 linked though p2link.
+	Flow*	p2link;
+	Flow*	s1;     	// successors of this instruction (at most two: s1 and s2).
+	Flow*	s2;
+	Flow*	link;   	// next instruction in function code
+	
+	int32	active;	// usable by client
+
+	int32	rpo;		// reverse post ordering
+	uint16	loop;		// x5 for every loop
+	uchar	refset;		// diagnostic generated
+};
+
+struct Graph
+{
+	Flow*	start;
+	int	num;
+	
+	// After calling flowrpo, rpo lists the flow nodes in reverse postorder,
+	// and each non-dead Flow node f has g->rpo[f->rpo] == f.
+	Flow**	rpo;
+};
+
+void	fixjmp(Prog*);
+Graph*	flowstart(Prog*, int);
+void	flowrpo(Graph*);
+void	flowend(Graph*);
+void	mergetemp(Prog*);
+void	nilopt(Prog*);
+int	noreturn(Prog*);
+int	regtyp(Addr*);
+int	sameaddr(Addr*, Addr*);
+int	smallindir(Addr*, Addr*);
+int	stackaddr(Addr*);
+Flow*	uniqp(Flow*);
+Flow*	uniqs(Flow*);
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
new file mode 100644
index 0000000..c9e27fe
--- /dev/null
+++ b/src/cmd/gc/racewalk.c
@@ -0,0 +1,664 @@
+// Copyright 2012 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.
+
+// The racewalk pass modifies the code tree for the function as follows:
+//
+// 1. It inserts a call to racefuncenter at the beginning of each function.
+// 2. It inserts a call to racefuncexit at the end of each function.
+// 3. It inserts a call to raceread before each memory read.
+// 4. It inserts a call to racewrite before each memory write.
+//
+// The rewriting is not yet complete. Certain nodes are not rewritten
+// but should be.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+// TODO(dvyukov): do not instrument initialization as writes:
+// a := make([]int, 10)
+
+static void racewalklist(NodeList *l, NodeList **init);
+static void racewalknode(Node **np, NodeList **init, int wr, int skip);
+static int callinstr(Node **n, NodeList **init, int wr, int skip);
+static Node* uintptraddr(Node *n);
+static void makeaddable(Node *n);
+static Node* basenod(Node *n);
+static void foreach(Node *n, void(*f)(Node*, void*), void *c);
+static void hascallspred(Node *n, void *c);
+static void appendinit(Node **np, NodeList *init);
+static Node* detachexpr(Node *n, NodeList **init);
+
+// Do not instrument the following packages at all,
+// at best instrumentation would cause infinite recursion.
+static const char *omit_pkgs[] = {"runtime", "runtime/race"};
+// Only insert racefuncenter/racefuncexit into the following packages.
+// Memory accesses in the packages are either uninteresting or will cause false positives.
+static const char *noinst_pkgs[] = {"sync", "sync/atomic"};
+
+static int
+ispkgin(const char **pkgs, int n)
+{
+	int i;
+
+	if(myimportpath) {
+		for(i=0; i<n; i++) {
+			if(strcmp(myimportpath, pkgs[i]) == 0)
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static int
+isforkfunc(Node *fn)
+{
+	// Special case for syscall.forkAndExecInChild.
+	// In the child, this function must not acquire any locks, because
+	// they might have been locked at the time of the fork.  This means
+	// no rescheduling, no malloc calls, and no new stack segments.
+	// Race instrumentation does all of the above.
+	return myimportpath != nil && strcmp(myimportpath, "syscall") == 0 &&
+		strcmp(fn->nname->sym->name, "forkAndExecInChild") == 0;
+}
+
+void
+racewalk(Node *fn)
+{
+	Node *nd;
+	Node *nodpc;
+	char s[1024];
+
+	if(ispkgin(omit_pkgs, nelem(omit_pkgs)) || isforkfunc(fn))
+		return;
+
+	if(!ispkgin(noinst_pkgs, nelem(noinst_pkgs))) {
+		racewalklist(fn->nbody, nil);
+		// nothing interesting for race detector in fn->enter
+		racewalklist(fn->exit, nil);
+	}
+
+	// nodpc is the PC of the caller as extracted by
+	// getcallerpc. We use -widthptr(FP) for x86.
+	// BUG: this will not work on arm.
+	nodpc = nod(OXXX, nil, nil);
+	*nodpc = *nodfp;
+	nodpc->type = types[TUINTPTR];
+	nodpc->xoffset = -widthptr;
+	nd = mkcall("racefuncenter", T, nil, nodpc);
+	fn->enter = concat(list1(nd), fn->enter);
+	nd = mkcall("racefuncexit", T, nil);
+	fn->exit = list(fn->exit, nd);
+
+	if(debug['W']) {
+		snprint(s, sizeof(s), "after racewalk %S", fn->nname->sym);
+		dumplist(s, fn->nbody);
+		snprint(s, sizeof(s), "enter %S", fn->nname->sym);
+		dumplist(s, fn->enter);
+		snprint(s, sizeof(s), "exit %S", fn->nname->sym);
+		dumplist(s, fn->exit);
+	}
+}
+
+static void
+racewalklist(NodeList *l, NodeList **init)
+{
+	NodeList *instr;
+
+	for(; l; l = l->next) {
+		instr = nil;
+		racewalknode(&l->n, &instr, 0, 0);
+		if(init == nil)
+			l->n->ninit = concat(l->n->ninit, instr);
+		else
+			*init = concat(*init, instr);
+	}
+}
+
+// walkexpr and walkstmt combined
+// walks the tree and adds calls to the
+// instrumentation code to top-level (statement) nodes' init
+static void
+racewalknode(Node **np, NodeList **init, int wr, int skip)
+{
+	Node *n, *n1;
+	NodeList *l;
+	NodeList *fini;
+
+	n = *np;
+
+	if(n == N)
+		return;
+
+	if(debug['w'] > 1)
+		dump("racewalk-before", n);
+	setlineno(n);
+	if(init == nil)
+		fatal("racewalk: bad init list");
+	if(init == &n->ninit) {
+		// If init == &n->ninit and n->ninit is non-nil,
+		// racewalknode might append it to itself.
+		// nil it out and handle it separately before putting it back.
+		l = n->ninit;
+		n->ninit = nil;
+		racewalklist(l, nil);
+		racewalknode(&n, &l, wr, skip);  // recurse with nil n->ninit
+		appendinit(&n, l);
+		*np = n;
+		return;
+	}
+
+	racewalklist(n->ninit, nil);
+
+	switch(n->op) {
+	default:
+		fatal("racewalk: unknown node type %O", n->op);
+
+	case OASOP:
+	case OAS:
+	case OAS2:
+	case OAS2RECV:
+	case OAS2FUNC:
+	case OAS2MAPR:
+		racewalknode(&n->left, init, 1, 0);
+		racewalknode(&n->right, init, 0, 0);
+		goto ret;
+
+	case OCFUNC:
+	case OVARKILL:
+		// can't matter
+		goto ret;
+
+	case OBLOCK:
+		if(n->list == nil)
+			goto ret;
+
+		switch(n->list->n->op) {
+		case OCALLFUNC:
+		case OCALLMETH:
+		case OCALLINTER:
+			// Blocks are used for multiple return function calls.
+			// x, y := f() becomes BLOCK{CALL f, AS x [SP+0], AS y [SP+n]}
+			// We don't want to instrument between the statements because it will
+			// smash the results.
+			racewalknode(&n->list->n, &n->list->n->ninit, 0, 0);
+			fini = nil;
+			racewalklist(n->list->next, &fini);
+			n->list = concat(n->list, fini);
+			break;
+
+		default:
+			// Ordinary block, for loop initialization or inlined bodies.
+			racewalklist(n->list, nil);
+			break;
+		}
+		goto ret;
+
+	case ODEFER:
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case OPROC:
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case OCALLINTER:
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case OCALLFUNC:
+		// Instrument dst argument of runtime.writebarrier* calls
+		// as we do not instrument runtime code.
+		if(n->left->sym != S && n->left->sym->pkg == runtimepkg && strncmp(n->left->sym->name, "writebarrier", 12) == 0) {
+			// Find the dst argument.
+			// The list can be reordered, so it's not necessary just the first or the second element.
+			for(l = n->list; l; l = l->next) {
+				if(strcmp(n->left->sym->name, "writebarrierfat") == 0) {
+					if(l->n->left->xoffset == widthptr)
+						break;
+				} else {
+					if(l->n->left->xoffset == 0)
+						break;
+				}
+			}
+			if(l == nil)
+				fatal("racewalk: writebarrier no arg");
+			if(l->n->right->op != OADDR)
+				fatal("racewalk: writebarrier bad arg");
+			callinstr(&l->n->right->left, init, 1, 0);
+		}
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case ONOT:
+	case OMINUS:
+	case OPLUS:
+	case OREAL:
+	case OIMAG:
+	case OCOM:
+		racewalknode(&n->left, init, wr, 0);
+		goto ret;
+
+	case ODOTINTER:
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case ODOT:
+		racewalknode(&n->left, init, 0, 1);
+		callinstr(&n, init, wr, skip);
+		goto ret;
+
+	case ODOTPTR: // dst = (*x).f with implicit *; otherwise it's ODOT+OIND
+		racewalknode(&n->left, init, 0, 0);
+		callinstr(&n, init, wr, skip);
+		goto ret;
+
+	case OIND: // *p
+		racewalknode(&n->left, init, 0, 0);
+		callinstr(&n, init, wr, skip);
+		goto ret;
+
+	case OSPTR:
+	case OLEN:
+	case OCAP:
+		racewalknode(&n->left, init, 0, 0);
+		if(istype(n->left->type, TMAP)) {
+			n1 = nod(OCONVNOP, n->left, N);
+			n1->type = ptrto(types[TUINT8]);
+			n1 = nod(OIND, n1, N);
+			typecheck(&n1, Erv);
+			callinstr(&n1, init, 0, skip);
+		}
+		goto ret;
+
+	case OLSH:
+	case ORSH:
+	case OLROT:
+	case OAND:
+	case OANDNOT:
+	case OOR:
+	case OXOR:
+	case OSUB:
+	case OMUL:
+	case OHMUL:
+	case OEQ:
+	case ONE:
+	case OLT:
+	case OLE:
+	case OGE:
+	case OGT:
+	case OADD:
+	case OCOMPLEX:
+		racewalknode(&n->left, init, wr, 0);
+		racewalknode(&n->right, init, wr, 0);
+		goto ret;
+
+	case OANDAND:
+	case OOROR:
+		racewalknode(&n->left, init, wr, 0);
+		// walk has ensured the node has moved to a location where
+		// side effects are safe.
+		// n->right may not be executed,
+		// so instrumentation goes to n->right->ninit, not init.
+		racewalknode(&n->right, &n->right->ninit, wr, 0);
+		goto ret;
+
+	case ONAME:
+		callinstr(&n, init, wr, skip);
+		goto ret;
+
+	case OCONV:
+		racewalknode(&n->left, init, wr, 0);
+		goto ret;
+
+	case OCONVNOP:
+		racewalknode(&n->left, init, wr, 0);
+		goto ret;
+
+	case ODIV:
+	case OMOD:
+		racewalknode(&n->left, init, wr, 0);
+		racewalknode(&n->right, init, wr, 0);
+		goto ret;
+
+	case OINDEX:
+		if(!isfixedarray(n->left->type))
+			racewalknode(&n->left, init, 0, 0);
+		else if(!islvalue(n->left)) {
+			// index of unaddressable array, like Map[k][i].
+			racewalknode(&n->left, init, wr, 0);
+			racewalknode(&n->right, init, 0, 0);
+			goto ret;
+		}
+		racewalknode(&n->right, init, 0, 0);
+		if(n->left->type->etype != TSTRING)
+			callinstr(&n, init, wr, skip);
+		goto ret;
+
+	case OSLICE:
+	case OSLICEARR:
+	case OSLICE3:
+	case OSLICE3ARR:
+		// Seems to only lead to double instrumentation.
+		//racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	case OADDR:
+		racewalknode(&n->left, init, 0, 1);
+		goto ret;
+
+	case OEFACE:
+		racewalknode(&n->left, init, 0, 0);
+		racewalknode(&n->right, init, 0, 0);
+		goto ret;
+
+	case OITAB:
+		racewalknode(&n->left, init, 0, 0);
+		goto ret;
+
+	// should not appear in AST by now
+	case OSEND:
+	case ORECV:
+	case OCLOSE:
+	case ONEW:
+	case OXCASE:
+	case OXFALL:
+	case OCASE:
+	case OPANIC:
+	case ORECOVER:
+	case OCONVIFACE:
+	case OCMPIFACE:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case OCALL:
+	case OCOPY:
+	case OAPPEND:
+	case ORUNESTR:
+	case OARRAYBYTESTR:
+	case OARRAYRUNESTR:
+	case OSTRARRAYBYTE:
+	case OSTRARRAYRUNE:
+	case OINDEXMAP:  // lowered to call
+	case OCMPSTR:
+	case OADDSTR:
+	case ODOTTYPE:
+	case ODOTTYPE2:
+	case OAS2DOTTYPE:
+	case OCALLPART: // lowered to PTRLIT
+	case OCLOSURE:  // lowered to PTRLIT
+	case ORANGE:    // lowered to ordinary for loop
+	case OARRAYLIT: // lowered to assignments
+	case OMAPLIT:
+	case OSTRUCTLIT:
+		yyerror("racewalk: %O must be lowered by now", n->op);
+		goto ret;
+
+	// impossible nodes: only appear in backend.
+	case ORROTC:
+	case OEXTEND:
+		yyerror("racewalk: %O cannot exist now", n->op);
+		goto ret;
+
+	// just do generic traversal
+	case OFOR:
+	case OIF:
+	case OCALLMETH:
+	case ORETURN:
+	case ORETJMP:
+	case OSWITCH:
+	case OSELECT:
+	case OEMPTY:
+	case OBREAK:
+	case OCONTINUE:
+	case OFALL:
+	case OGOTO:
+	case OLABEL:
+		goto ret;
+
+	// does not require instrumentation
+	case OPRINT:     // don't bother instrumenting it
+	case OPRINTN:    // don't bother instrumenting it
+	case OCHECKNIL: // always followed by a read.
+	case OPARAM:     // it appears only in fn->exit to copy heap params back
+	case OCLOSUREVAR:// immutable pointer to captured variable
+	case ODOTMETH:   // either part of CALLMETH or CALLPART (lowered to PTRLIT)
+	case OINDREG:    // at this stage, only n(SP) nodes from nodarg
+	case ODCL:       // declarations (without value) cannot be races
+	case ODCLCONST:
+	case ODCLTYPE:
+	case OTYPE:
+	case ONONAME:
+	case OLITERAL:
+	case OSLICESTR:  // always preceded by bounds checking, avoid double instrumentation.
+	case OTYPESW:    // ignored by code generation, do not instrument.
+		goto ret;
+	}
+
+ret:
+	if(n->op != OBLOCK)  // OBLOCK is handled above in a special way.
+		racewalklist(n->list, init);
+	if(n->ntest != N)
+		racewalknode(&n->ntest, &n->ntest->ninit, 0, 0);
+	if(n->nincr != N)
+		racewalknode(&n->nincr, &n->nincr->ninit, 0, 0);
+	racewalklist(n->nbody, nil);
+	racewalklist(n->nelse, nil);
+	racewalklist(n->rlist, nil);
+	*np = n;
+}
+
+static int
+isartificial(Node *n)
+{
+	// compiler-emitted artificial things that we do not want to instrument,
+	// cant' possibly participate in a data race.
+	if(n->op == ONAME && n->sym != S && n->sym->name != nil) {
+		if(strcmp(n->sym->name, "_") == 0)
+			return 1;
+		// autotmp's are always local
+		if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
+			return 1;
+		// statictmp's are read-only
+		if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
+			return 1;
+		// go.itab is accessed only by the compiler and runtime (assume safe)
+		if(n->sym->pkg && n->sym->pkg->name && strcmp(n->sym->pkg->name, "go.itab") == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static int
+callinstr(Node **np, NodeList **init, int wr, int skip)
+{
+	Node *f, *b, *n;
+	Type *t;
+	int class, hascalls;
+
+	n = *np;
+	//print("callinstr for %+N [ %O ] etype=%E class=%d\n",
+	//	  n, n->op, n->type ? n->type->etype : -1, n->class);
+
+	if(skip || n->type == T || n->type->etype >= TIDEAL)
+		return 0;
+	t = n->type;
+	if(isartificial(n))
+		return 0;
+
+	b = basenod(n);
+	// it skips e.g. stores to ... parameter array
+	if(isartificial(b))
+		return 0;
+	class = b->class;
+	// BUG: we _may_ want to instrument PAUTO sometimes
+	// e.g. if we've got a local variable/method receiver
+	// that has got a pointer inside. Whether it points to
+	// the heap or not is impossible to know at compile time
+	if((class&PHEAP) || class == PPARAMREF || class == PEXTERN
+		|| b->op == OINDEX || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) {
+		hascalls = 0;
+		foreach(n, hascallspred, &hascalls);
+		if(hascalls) {
+			n = detachexpr(n, init);
+			*np = n;
+		}
+		n = treecopy(n);
+		makeaddable(n);
+		if(t->etype == TSTRUCT || isfixedarray(t)) {
+			f = mkcall(wr ? "racewriterange" : "racereadrange", T, init, uintptraddr(n),
+					nodintconst(t->width));
+		} else
+			f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n));
+		*init = list(*init, f);
+		return 1;
+	}
+	return 0;
+}
+
+// makeaddable returns a node whose memory location is the
+// same as n, but which is addressable in the Go language
+// sense.
+// This is different from functions like cheapexpr that may make
+// a copy of their argument.
+static void
+makeaddable(Node *n)
+{
+	// The arguments to uintptraddr technically have an address but
+	// may not be addressable in the Go sense: for example, in the case
+	// of T(v).Field where T is a struct type and v is
+	// an addressable value.
+	switch(n->op) {
+	case OINDEX:
+		if(isfixedarray(n->left->type))
+			makeaddable(n->left);
+		break;
+	case ODOT:
+	case OXDOT:
+		// Turn T(v).Field into v.Field
+		if(n->left->op == OCONVNOP)
+			n->left = n->left->left;
+		makeaddable(n->left);
+		break;
+	case ODOTPTR:
+	default:
+		// nothing to do
+		break;
+	}
+}
+
+static Node*
+uintptraddr(Node *n)
+{
+	Node *r;
+
+	r = nod(OADDR, n, N);
+	r->bounded = 1;
+	r = conv(r, types[TUNSAFEPTR]);
+	r = conv(r, types[TUINTPTR]);
+	return r;
+}
+
+// basenod returns the simplest child node of n pointing to the same
+// memory area.
+static Node*
+basenod(Node *n)
+{
+	for(;;) {
+		if(n->op == ODOT || n->op == OXDOT || n->op == OCONVNOP || n->op == OCONV || n->op == OPAREN) {
+			n = n->left;
+			continue;
+		}
+		if(n->op == OINDEX && isfixedarray(n->type)) {
+			n = n->left;
+			continue;
+		}
+		break;
+	}
+	return n;
+}
+
+static Node*
+detachexpr(Node *n, NodeList **init)
+{
+	Node *addr, *as, *ind, *l;
+
+	addr = nod(OADDR, n, N);
+	l = temp(ptrto(n->type));
+	as = nod(OAS, l, addr);
+	typecheck(&as, Etop);
+	walkexpr(&as, init);
+	*init = list(*init, as);
+	ind = nod(OIND, l, N);
+	typecheck(&ind, Erv);
+	walkexpr(&ind, init);
+	return ind;
+}
+
+static void
+foreachnode(Node *n, void(*f)(Node*, void*), void *c)
+{
+	if(n)
+		f(n, c);
+}
+
+static void
+foreachlist(NodeList *l, void(*f)(Node*, void*), void *c)
+{
+	for(; l; l = l->next)
+		foreachnode(l->n, f, c);
+}
+
+static void
+foreach(Node *n, void(*f)(Node*, void*), void *c)
+{
+	foreachlist(n->ninit, f, c);
+	foreachnode(n->left, f, c);
+	foreachnode(n->right, f, c);
+	foreachlist(n->list, f, c);
+	foreachnode(n->ntest, f, c);
+	foreachnode(n->nincr, f, c);
+	foreachlist(n->nbody, f, c);
+	foreachlist(n->nelse, f, c);
+	foreachlist(n->rlist, f, c);
+}
+
+static void
+hascallspred(Node *n, void *c)
+{
+	switch(n->op) {
+	case OCALL:
+	case OCALLFUNC:
+	case OCALLMETH:
+	case OCALLINTER:
+		(*(int*)c)++;
+	}
+}
+
+// appendinit is like addinit in subr.c
+// but appends rather than prepends.
+static void
+appendinit(Node **np, NodeList *init)
+{
+	Node *n;
+
+	if(init == nil)
+		return;
+
+	n = *np;
+	switch(n->op) {
+	case ONAME:
+	case OLITERAL:
+		// There may be multiple refs to this node;
+		// introduce OCONVNOP to hold init list.
+		n = nod(OCONVNOP, n, N);
+		n->type = n->left->type;
+		n->typecheck = 1;
+		*np = n;
+		break;
+	}
+	n->ninit = concat(n->ninit, init);
+	n->ullman = UINF;
+}
+
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
new file mode 100644
index 0000000..4ed4528
--- /dev/null
+++ b/src/cmd/gc/range.c
@@ -0,0 +1,296 @@
+// 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.
+
+/*
+ * range
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+void
+typecheckrange(Node *n)
+{
+	char *why;
+	Type *t, *t1, *t2;
+	Node *v1, *v2;
+	NodeList *ll;
+
+	// delicate little dance.  see typecheckas2
+	for(ll=n->list; ll; ll=ll->next)
+		if(ll->n->defn != n)
+			typecheck(&ll->n, Erv | Easgn);
+
+	typecheck(&n->right, Erv);
+	if((t = n->right->type) == T)
+		goto out;
+	if(isptr[t->etype] && isfixedarray(t->type))
+		t = t->type;
+	n->type = t;
+
+	switch(t->etype) {
+	default:
+		yyerror("cannot range over %lN", n->right);
+		goto out;
+
+	case TARRAY:
+		t1 = types[TINT];
+		t2 = t->type;
+		break;
+
+	case TMAP:
+		t1 = t->down;
+		t2 = t->type;
+		break;
+
+	case TCHAN:
+		if(!(t->chan & Crecv)) {
+			yyerror("invalid operation: range %N (receive from send-only type %T)", n->right, n->right->type);
+			goto out;
+		}
+		t1 = t->type;
+		t2 = nil;
+		if(count(n->list) == 2)
+			goto toomany;
+		break;
+
+	case TSTRING:
+		t1 = types[TINT];
+		t2 = runetype;
+		break;
+	}
+
+	if(count(n->list) > 2) {
+	toomany:
+		yyerror("too many variables in range");
+	}
+
+	v1 = N;
+	if(n->list)
+		v1 = n->list->n;
+	v2 = N;
+	if(n->list && n->list->next)
+		v2 = n->list->next->n;
+
+	// this is not only a optimization but also a requirement in the spec.
+	// "if the second iteration variable is the blank identifier, the range
+	// clause is equivalent to the same clause with only the first variable
+	// present."
+	if(isblank(v2)) {
+		if(v1 != N)
+			n->list = list1(v1);
+		v2 = N;
+	}
+
+	if(v1) {
+		if(v1->defn == n)
+			v1->type = t1;
+		else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
+			yyerror("cannot assign type %T to %lN in range%s", t1, v1, why);
+	}
+	if(v2) {
+		if(v2->defn == n)
+			v2->type = t2;
+		else if(v2->type != T && assignop(t2, v2->type, &why) == 0)
+			yyerror("cannot assign type %T to %lN in range%s", t2, v2, why);
+	}
+
+out:
+	typechecklist(n->nbody, Etop);
+
+	// second half of dance
+	n->typecheck = 1;
+	for(ll=n->list; ll; ll=ll->next)
+		if(ll->n->typecheck == 0)
+			typecheck(&ll->n, Erv | Easgn);
+}
+
+void
+walkrange(Node *n)
+{
+	Node *ohv1, *hv1, *hv2;	// hidden (old) val 1, 2
+	Node *ha, *hit;	// hidden aggregate, iterator
+	Node *hn, *hp;	// hidden len, pointer
+	Node *hb;  // hidden bool
+	Node *a, *v1, *v2;	// not hidden aggregate, val 1, 2
+	Node *fn, *tmp;
+	Node *keyname, *valname;
+	Node *key, *val;
+	NodeList *body, *init;
+	Type *th, *t;
+	int lno;
+
+	t = n->type;
+	init = nil;
+
+	a = n->right;
+	lno = setlineno(a);
+
+	v1 = N;
+	if(n->list)
+		v1 = n->list->n;
+	v2 = N;
+	if(n->list && n->list->next && !isblank(n->list->next->n))
+		v2 = n->list->next->n;
+	// n->list has no meaning anymore, clear it
+	// to avoid erroneous processing by racewalk.
+	n->list = nil;
+	hv2 = N;
+
+	switch(t->etype) {
+	default:
+		fatal("walkrange");
+
+	case TARRAY:
+		// orderstmt arranged for a copy of the array/slice variable if needed.
+		ha = a;
+		hv1 = temp(types[TINT]);
+		hn = temp(types[TINT]);
+		hp = nil;
+
+		init = list(init, nod(OAS, hv1, N));
+		init = list(init, nod(OAS, hn, nod(OLEN, ha, N)));
+		if(v2) {
+			hp = temp(ptrto(n->type->type));
+			tmp = nod(OINDEX, ha, nodintconst(0));
+			tmp->bounded = 1;
+			init = list(init, nod(OAS, hp, nod(OADDR, tmp, N)));
+		}
+
+		n->ntest = nod(OLT, hv1, hn);
+		n->nincr = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)));
+		if(v1 == N)
+			body = nil;
+		else if(v2 == N)
+			body = list1(nod(OAS, v1, hv1));
+		else {
+			a = nod(OAS2, N, N);
+			a->list = list(list1(v1), v2);
+			a->rlist = list(list1(hv1), nod(OIND, hp, N));
+			body = list1(a);
+			
+			// Advance pointer as part of increment.
+			// We used to advance the pointer before executing the loop body,
+			// but doing so would make the pointer point past the end of the
+			// array during the final iteration, possibly causing another unrelated
+			// piece of memory not to be garbage collected until the loop finished.
+			// Advancing during the increment ensures that the pointer p only points
+			// pass the end of the array during the final "p++; i++; if(i >= len(x)) break;",
+			// after which p is dead, so it cannot confuse the collector.
+			tmp = nod(OADD, hp, nodintconst(t->type->width));
+			tmp->type = hp->type;
+			tmp->typecheck = 1;
+			tmp->right->type = types[tptr];
+			tmp->right->typecheck = 1;
+			a = nod(OAS, hp, tmp);
+			typecheck(&a, Etop);
+			n->nincr->ninit = list1(a);
+		}
+		break;
+
+	case TMAP:
+		// orderstmt allocated the iterator for us.
+		// we only use a once, so no copy needed.
+		ha = a;
+		th = hiter(t);
+		hit = n->alloc;
+		hit->type = th;
+		n->left = N;
+		keyname = newname(th->type->sym);  // depends on layout of iterator struct.  See reflect.c:hiter
+		valname = newname(th->type->down->sym); // ditto
+
+		fn = syslook("mapiterinit", 1);
+		argtype(fn, t->down);
+		argtype(fn, t->type);
+		argtype(fn, th);
+		init = list(init, mkcall1(fn, T, nil, typename(t), ha, nod(OADDR, hit, N)));
+		n->ntest = nod(ONE, nod(ODOT, hit, keyname), nodnil());
+
+		fn = syslook("mapiternext", 1);
+		argtype(fn, th);
+		n->nincr = mkcall1(fn, T, nil, nod(OADDR, hit, N));
+
+		key = nod(ODOT, hit, keyname);
+		key = nod(OIND, key, N);
+		if(v1 == N)
+			body = nil;
+		else if(v2 == N) {
+			body = list1(nod(OAS, v1, key));
+		} else {
+			val = nod(ODOT, hit, valname);
+			val = nod(OIND, val, N);
+			a = nod(OAS2, N, N);
+			a->list = list(list1(v1), v2);
+			a->rlist = list(list1(key), val);
+			body = list1(a);
+		}
+		break;
+
+	case TCHAN:
+		// orderstmt arranged for a copy of the channel variable.
+		ha = a;
+		n->ntest = N;
+		
+		hv1 = temp(t->type);
+		hv1->typecheck = 1;
+		if(haspointers(t->type))
+			init = list(init, nod(OAS, hv1, N));
+		hb = temp(types[TBOOL]);
+
+		n->ntest = nod(ONE, hb, nodbool(0));
+		a = nod(OAS2RECV, N, N);
+		a->typecheck = 1;
+		a->list = list(list1(hv1), hb);
+		a->rlist = list1(nod(ORECV, ha, N));
+		n->ntest->ninit = list1(a);
+		if(v1 == N)
+			body = nil;
+		else
+			body = list1(nod(OAS, v1, hv1));
+		break;
+
+	case TSTRING:
+		// orderstmt arranged for a copy of the string variable.
+		ha = a;
+
+		ohv1 = temp(types[TINT]);
+
+		hv1 = temp(types[TINT]);
+		init = list(init, nod(OAS, hv1, N));
+
+		if(v2 == N)
+			a = nod(OAS, hv1, mkcall("stringiter", types[TINT], nil, ha, hv1));
+		else {
+			hv2 = temp(runetype);
+			a = nod(OAS2, N, N);
+			a->list = list(list1(hv1), hv2);
+			fn = syslook("stringiter2", 0);
+			a->rlist = list1(mkcall1(fn, getoutargx(fn->type), nil, ha, hv1));
+		}
+		n->ntest = nod(ONE, hv1, nodintconst(0));
+		n->ntest->ninit = list(list1(nod(OAS, ohv1, hv1)), a);
+
+		
+		body = nil;
+		if(v1 != N)
+			body = list1(nod(OAS, v1, ohv1));
+		if(v2 != N)
+			body = list(body, nod(OAS, v2, hv2));
+		break;
+	}
+
+	n->op = OFOR;
+	typechecklist(init, Etop);
+	n->ninit = concat(n->ninit, init);
+	typechecklist(n->ntest->ninit, Etop);
+	typecheck(&n->ntest, Erv);
+	typecheck(&n->nincr, Etop);
+	typechecklist(body, Etop);
+	n->nbody = concat(body, n->nbody);
+	walkstmt(&n);
+	
+	lineno = lno;
+}
+
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
new file mode 100644
index 0000000..8788a67
--- /dev/null
+++ b/src/cmd/gc/reflect.c
@@ -0,0 +1,1577 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+#include "../ld/textflag.h"
+#include "../../runtime/mgc0.h"
+#include "../../runtime/typekind.h"
+
+/*
+ * runtime interface and reflection data structures
+ */
+
+static	NodeList*	signatlist;
+static	Sym*	dtypesym(Type*);
+static	Sym*	weaktypesym(Type*);
+static	Sym*	dalgsym(Type*);
+static	int	usegcprog(Type*);
+static	void	gengcprog(Type*, Sym**, Sym**);
+static	void	gengcmask(Type*, uint8[16]);
+
+static int
+sigcmp(Sig *a, Sig *b)
+{
+	int i;
+
+	i = strcmp(a->name, b->name);
+	if(i != 0)
+		return i;
+	if(a->pkg == b->pkg)
+		return 0;
+	if(a->pkg == nil)
+		return -1;
+	if(b->pkg == nil)
+		return +1;
+	return strcmp(a->pkg->path->s, b->pkg->path->s);
+}
+
+static Sig*
+lsort(Sig *l, int(*f)(Sig*, Sig*))
+{
+	Sig *l1, *l2, *le;
+
+	if(l == 0 || l->link == 0)
+		return l;
+
+	l1 = l;
+	l2 = l;
+	for(;;) {
+		l2 = l2->link;
+		if(l2 == 0)
+			break;
+		l2 = l2->link;
+		if(l2 == 0)
+			break;
+		l1 = l1->link;
+	}
+
+	l2 = l1->link;
+	l1->link = 0;
+	l1 = lsort(l, f);
+	l2 = lsort(l2, f);
+
+	/* set up lead element */
+	if((*f)(l1, l2) < 0) {
+		l = l1;
+		l1 = l1->link;
+	} else {
+		l = l2;
+		l2 = l2->link;
+	}
+	le = l;
+
+	for(;;) {
+		if(l1 == 0) {
+			while(l2) {
+				le->link = l2;
+				le = l2;
+				l2 = l2->link;
+			}
+			le->link = 0;
+			break;
+		}
+		if(l2 == 0) {
+			while(l1) {
+				le->link = l1;
+				le = l1;
+				l1 = l1->link;
+			}
+			break;
+		}
+		if((*f)(l1, l2) < 0) {
+			le->link = l1;
+			le = l1;
+			l1 = l1->link;
+		} else {
+			le->link = l2;
+			le = l2;
+			l2 = l2->link;
+		}
+	}
+	le->link = 0;
+	return l;
+}
+
+// Builds a type respresenting a Bucket structure for
+// the given map type.  This type is not visible to users -
+// we include only enough information to generate a correct GC
+// program for it.
+// Make sure this stays in sync with ../../runtime/hashmap.c!
+enum {
+	BUCKETSIZE = 8,
+	MAXKEYSIZE = 128,
+	MAXVALSIZE = 128,
+};
+
+static Type*
+mapbucket(Type *t)
+{
+	Type *keytype, *valtype;
+	Type *bucket;
+	Type *overflowfield, *keysfield, *valuesfield;
+	int32 offset;
+
+	if(t->bucket != T)
+		return t->bucket;
+
+	keytype = t->down;
+	valtype = t->type;
+	dowidth(keytype);
+	dowidth(valtype);
+	if(keytype->width > MAXKEYSIZE)
+		keytype = ptrto(keytype);
+	if(valtype->width > MAXVALSIZE)
+		valtype = ptrto(valtype);
+
+	bucket = typ(TSTRUCT);
+	bucket->noalg = 1;
+
+	// The first field is: uint8 topbits[BUCKETSIZE].
+	// We don't need to encode it as GC doesn't care about it.
+	offset = BUCKETSIZE * 1;
+
+	keysfield = typ(TFIELD);
+	keysfield->type = typ(TARRAY);
+	keysfield->type->type = keytype;
+	keysfield->type->bound = BUCKETSIZE;
+	keysfield->type->width = BUCKETSIZE * keytype->width;
+	keysfield->width = offset;
+	keysfield->sym = mal(sizeof(Sym));
+	keysfield->sym->name = "keys";
+	offset += BUCKETSIZE * keytype->width;
+
+	valuesfield = typ(TFIELD);
+	valuesfield->type = typ(TARRAY);
+	valuesfield->type->type = valtype;
+	valuesfield->type->bound = BUCKETSIZE;
+	valuesfield->type->width = BUCKETSIZE * valtype->width;
+	valuesfield->width = offset;
+	valuesfield->sym = mal(sizeof(Sym));
+	valuesfield->sym->name = "values";
+	offset += BUCKETSIZE * valtype->width;
+
+	overflowfield = typ(TFIELD);
+	overflowfield->type = ptrto(bucket);
+	overflowfield->width = offset;         // "width" is offset in structure
+	overflowfield->sym = mal(sizeof(Sym)); // not important but needs to be set to give this type a name
+	overflowfield->sym->name = "overflow";
+	offset += widthptr;
+	
+	// Pad to the native integer alignment.
+	// This is usually the same as widthptr; the exception (as usual) is nacl/amd64.
+	if(widthreg > widthptr)
+		offset += widthreg - widthptr;
+
+	// link up fields
+	bucket->type = keysfield;
+	keysfield->down = valuesfield;
+	valuesfield->down = overflowfield;
+	overflowfield->down = T;
+
+	bucket->width = offset;
+	bucket->local = t->local;
+	t->bucket = bucket;
+	bucket->map = t;
+	return bucket;
+}
+
+// Builds a type respresenting a Hmap structure for
+// the given map type.  This type is not visible to users -
+// we include only enough information to generate a correct GC
+// program for it.
+// Make sure this stays in sync with ../../runtime/hashmap.go!
+static Type*
+hmap(Type *t)
+{
+	Type *h, *bucket;
+	Type *bucketsfield, *oldbucketsfield;
+	int32 offset;
+
+	if(t->hmap != T)
+		return t->hmap;
+
+	bucket = mapbucket(t);
+	h = typ(TSTRUCT);
+	h->noalg = 1;
+
+	offset = widthint; // count
+	offset += 4;       // flags
+	offset += 4;       // hash0
+	offset += 1;       // B
+	offset = (offset + widthptr - 1) / widthptr * widthptr;
+	
+	bucketsfield = typ(TFIELD);
+	bucketsfield->type = ptrto(bucket);
+	bucketsfield->width = offset;
+	bucketsfield->sym = mal(sizeof(Sym));
+	bucketsfield->sym->name = "buckets";
+	offset += widthptr;
+
+	oldbucketsfield = typ(TFIELD);
+	oldbucketsfield->type = ptrto(bucket);
+	oldbucketsfield->width = offset;
+	oldbucketsfield->sym = mal(sizeof(Sym));
+	oldbucketsfield->sym->name = "oldbuckets";
+	offset += widthptr;
+
+	offset += widthptr; // nevacuate (last field in Hmap)
+
+	// link up fields
+	h->type = bucketsfield;
+	bucketsfield->down = oldbucketsfield;
+	oldbucketsfield->down = T;
+
+	h->width = offset;
+	h->local = t->local;
+	t->hmap = h;
+	h->map = t;
+	return h;
+}
+
+Type*
+hiter(Type *t)
+{
+	int32 n, off;
+	Type *field[7];
+	Type *i;
+
+	if(t->hiter != T)
+		return t->hiter;
+
+	// build a struct:
+	// hash_iter {
+	//    key *Key
+	//    val *Value
+	//    t *MapType
+	//    h *Hmap
+	//    buckets *Bucket
+	//    bptr *Bucket
+	//    other [4]uintptr
+	// }
+	// must match ../../runtime/hashmap.c:hash_iter.
+	field[0] = typ(TFIELD);
+	field[0]->type = ptrto(t->down);
+	field[0]->sym = mal(sizeof(Sym));
+	field[0]->sym->name = "key";
+	
+	field[1] = typ(TFIELD);
+	field[1]->type = ptrto(t->type);
+	field[1]->sym = mal(sizeof(Sym));
+	field[1]->sym->name = "val";
+	
+	field[2] = typ(TFIELD);
+	field[2]->type = ptrto(types[TUINT8]); // TODO: is there a Type type?
+	field[2]->sym = mal(sizeof(Sym));
+	field[2]->sym->name = "t";
+	
+	field[3] = typ(TFIELD);
+	field[3]->type = ptrto(hmap(t));
+	field[3]->sym = mal(sizeof(Sym));
+	field[3]->sym->name = "h";
+	
+	field[4] = typ(TFIELD);
+	field[4]->type = ptrto(mapbucket(t));
+	field[4]->sym = mal(sizeof(Sym));
+	field[4]->sym->name = "buckets";
+	
+	field[5] = typ(TFIELD);
+	field[5]->type = ptrto(mapbucket(t));
+	field[5]->sym = mal(sizeof(Sym));
+	field[5]->sym->name = "bptr";
+	
+	// all other non-pointer fields
+	field[6] = typ(TFIELD);
+	field[6]->type = typ(TARRAY);
+	field[6]->type->type = types[TUINTPTR];
+	field[6]->type->bound = 4;
+	field[6]->type->width = 4 * widthptr;
+	field[6]->sym = mal(sizeof(Sym));
+	field[6]->sym->name = "other";
+	
+	// build iterator struct holding the above fields
+	i = typ(TSTRUCT);
+	i->noalg = 1;
+	i->type = field[0];
+	off = 0;
+	for(n = 0; n < 6; n++) {
+		field[n]->down = field[n+1];
+		field[n]->width = off;
+		off += field[n]->type->width;
+	}
+	field[6]->down = T;
+	off += field[6]->type->width;
+	if(off != 10 * widthptr)
+		yyerror("hash_iter size not correct %d %d", off, 10 * widthptr);
+	t->hiter = i;
+	i->map = t;
+	return i;
+}
+
+/*
+ * f is method type, with receiver.
+ * return function type, receiver as first argument (or not).
+ */
+Type*
+methodfunc(Type *f, Type *receiver)
+{
+	NodeList *in, *out;
+	Node *d;
+	Type *t;
+
+	in = nil;
+	if(receiver) {
+		d = nod(ODCLFIELD, N, N);
+		d->type = receiver;
+		in = list(in, d);
+	}
+	for(t=getinargx(f)->type; t; t=t->down) {
+		d = nod(ODCLFIELD, N, N);
+		d->type = t->type;
+		d->isddd = t->isddd;
+		in = list(in, d);
+	}
+
+	out = nil;
+	for(t=getoutargx(f)->type; t; t=t->down) {
+		d = nod(ODCLFIELD, N, N);
+		d->type = t->type;
+		out = list(out, d);
+	}
+
+	t = functype(N, in, out);
+	if(f->nname) {
+		// Link to name of original method function.
+		t->nname = f->nname;
+	}
+	return t;
+}
+
+/*
+ * return methods of non-interface type t, sorted by name.
+ * generates stub functions as needed.
+ */
+static Sig*
+methods(Type *t)
+{
+	Type *f, *mt, *it, *this;
+	Sig *a, *b;
+	Sym *method;
+
+	// method type
+	mt = methtype(t, 0);
+	if(mt == T)
+		return nil;
+	expandmeth(mt);
+
+	// type stored in interface word
+	it = t;
+	if(!isdirectiface(it))
+		it = ptrto(t);
+
+	// make list of methods for t,
+	// generating code if necessary.
+	a = nil;
+	for(f=mt->xmethod; f; f=f->down) {
+		if(f->etype != TFIELD)
+			fatal("methods: not field %T", f);
+		if (f->type->etype != TFUNC || f->type->thistuple == 0)
+			fatal("non-method on %T method %S %T\n", mt, f->sym, f);
+		if (!getthisx(f->type)->type)
+			fatal("receiver with no type on %T method %S %T\n", mt, f->sym, f);
+		if(f->nointerface)
+			continue;
+
+		method = f->sym;
+		if(method == nil)
+			continue;
+
+		// get receiver type for this particular method.
+		// if pointer receiver but non-pointer t and
+		// this is not an embedded pointer inside a struct,
+		// method does not apply.
+		this = getthisx(f->type)->type->type;
+		if(isptr[this->etype] && this->type == t)
+			continue;
+		if(isptr[this->etype] && !isptr[t->etype]
+		&& f->embedded != 2 && !isifacemethod(f->type))
+			continue;
+
+		b = mal(sizeof(*b));
+		b->link = a;
+		a = b;
+
+		a->name = method->name;
+		if(!exportname(method->name)) {
+			if(method->pkg == nil)
+				fatal("methods: missing package");
+			a->pkg = method->pkg;
+		}
+		a->isym = methodsym(method, it, 1);
+		a->tsym = methodsym(method, t, 0);
+		a->type = methodfunc(f->type, t);
+		a->mtype = methodfunc(f->type, nil);
+
+		if(!(a->isym->flags & SymSiggen)) {
+			a->isym->flags |= SymSiggen;
+			if(!eqtype(this, it) || this->width < types[tptr]->width) {
+				compiling_wrappers = 1;
+				genwrapper(it, f, a->isym, 1);
+				compiling_wrappers = 0;
+			}
+		}
+
+		if(!(a->tsym->flags & SymSiggen)) {
+			a->tsym->flags |= SymSiggen;
+			if(!eqtype(this, t)) {
+				compiling_wrappers = 1;
+				genwrapper(t, f, a->tsym, 0);
+				compiling_wrappers = 0;
+			}
+		}
+	}
+
+	return lsort(a, sigcmp);
+}
+
+/*
+ * return methods of interface type t, sorted by name.
+ */
+static Sig*
+imethods(Type *t)
+{
+	Sig *a, *all, *last;
+	Type *f;
+	Sym *method, *isym;
+
+	all = nil;
+	last = nil;
+	for(f=t->type; f; f=f->down) {
+		if(f->etype != TFIELD)
+			fatal("imethods: not field");
+		if(f->type->etype != TFUNC || f->sym == nil)
+			continue;
+		method = f->sym;
+		a = mal(sizeof(*a));
+		a->name = method->name;
+		if(!exportname(method->name)) {
+			if(method->pkg == nil)
+				fatal("imethods: missing package");
+			a->pkg = method->pkg;
+		}
+		a->mtype = f->type;
+		a->offset = 0;
+		a->type = methodfunc(f->type, nil);
+
+		if(last && sigcmp(last, a) >= 0)
+			fatal("sigcmp vs sortinter %s %s", last->name, a->name);
+		if(last == nil)
+			all = a;
+		else
+			last->link = a;
+		last = a;
+
+		// Compiler can only refer to wrappers for non-blank methods.
+		if(isblanksym(method))
+			continue;
+
+		// NOTE(rsc): Perhaps an oversight that
+		// IfaceType.Method is not in the reflect data.
+		// Generate the method body, so that compiled
+		// code can refer to it.
+		isym = methodsym(method, t, 0);
+		if(!(isym->flags & SymSiggen)) {
+			isym->flags |= SymSiggen;
+			genwrapper(t, f, isym, 0);
+		}
+	}
+	return all;
+}
+
+static void
+dimportpath(Pkg *p)
+{
+	static Pkg *gopkg;
+	char *nam;
+	Node *n;
+
+	if(p->pathsym != S)
+		return;
+
+	if(gopkg == nil) {
+		gopkg = mkpkg(strlit("go"));
+		gopkg->name = "go";
+	}
+	nam = smprint("importpath.%s.", p->prefix);
+
+	n = nod(ONAME, N, N);
+	n->sym = pkglookup(nam, gopkg);
+	free(nam);
+	n->class = PEXTERN;
+	n->xoffset = 0;
+	p->pathsym = n->sym;
+
+	gdatastring(n, p->path);
+	ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
+}
+
+static int
+dgopkgpath(Sym *s, int ot, Pkg *pkg)
+{
+	if(pkg == nil)
+		return dgostringptr(s, ot, nil);
+
+	// Emit reference to go.importpath.""., which 6l will
+	// rewrite using the correct import path.  Every package
+	// that imports this one directly defines the symbol.
+	if(pkg == localpkg) {
+		static Sym *ns;
+
+		if(ns == nil)
+			ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
+		return dsymptr(s, ot, ns, 0);
+	}
+
+	dimportpath(pkg);
+	return dsymptr(s, ot, pkg->pathsym, 0);
+}
+
+/*
+ * uncommonType
+ * ../../runtime/type.go:/uncommonType
+ */
+static int
+dextratype(Sym *sym, int off, Type *t, int ptroff)
+{
+	int ot, n;
+	Sym *s;
+	Sig *a, *m;
+
+	m = methods(t);
+	if(t->sym == nil && m == nil)
+		return off;
+
+	// fill in *extraType pointer in header
+	off = rnd(off, widthptr);
+	dsymptr(sym, ptroff, sym, off);
+
+	n = 0;
+	for(a=m; a; a=a->link) {
+		dtypesym(a->type);
+		n++;
+	}
+
+	ot = off;
+	s = sym;
+	if(t->sym) {
+		ot = dgostringptr(s, ot, t->sym->name);
+		if(t != types[t->etype] && t != errortype)
+			ot = dgopkgpath(s, ot, t->sym->pkg);
+		else
+			ot = dgostringptr(s, ot, nil);
+	} else {
+		ot = dgostringptr(s, ot, nil);
+		ot = dgostringptr(s, ot, nil);
+	}
+
+	// slice header
+	ot = dsymptr(s, ot, s, ot + widthptr + 2*widthint);
+	ot = duintxx(s, ot, n, widthint);
+	ot = duintxx(s, ot, n, widthint);
+
+	// methods
+	for(a=m; a; a=a->link) {
+		// method
+		// ../../runtime/type.go:/method
+		ot = dgostringptr(s, ot, a->name);
+		ot = dgopkgpath(s, ot, a->pkg);
+		ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
+		ot = dsymptr(s, ot, dtypesym(a->type), 0);
+		if(a->isym)
+			ot = dsymptr(s, ot, a->isym, 0);
+		else
+			ot = duintptr(s, ot, 0);
+		if(a->tsym)
+			ot = dsymptr(s, ot, a->tsym, 0);
+		else
+			ot = duintptr(s, ot, 0);
+	}
+
+	return ot;
+}
+
+static int
+kinds[] =
+{
+	[TINT]		= KindInt,
+	[TUINT]		= KindUint,
+	[TINT8]		= KindInt8,
+	[TUINT8]	= KindUint8,
+	[TINT16]	= KindInt16,
+	[TUINT16]	= KindUint16,
+	[TINT32]	= KindInt32,
+	[TUINT32]	= KindUint32,
+	[TINT64]	= KindInt64,
+	[TUINT64]	= KindUint64,
+	[TUINTPTR]	= KindUintptr,
+	[TFLOAT32]	= KindFloat32,
+	[TFLOAT64]	= KindFloat64,
+	[TBOOL]		= KindBool,
+	[TSTRING]		= KindString,
+	[TPTR32]		= KindPtr,
+	[TPTR64]		= KindPtr,
+	[TSTRUCT]	= KindStruct,
+	[TINTER]		= KindInterface,
+	[TCHAN]		= KindChan,
+	[TMAP]		= KindMap,
+	[TARRAY]		= KindArray,
+	[TFUNC]		= KindFunc,
+	[TCOMPLEX64]	= KindComplex64,
+	[TCOMPLEX128]	= KindComplex128,
+	[TUNSAFEPTR]	= KindUnsafePointer,
+};
+
+int
+haspointers(Type *t)
+{
+	Type *t1;
+	int ret;
+
+	if(t->haspointers != 0)
+		return t->haspointers - 1;
+
+	switch(t->etype) {
+	case TINT:
+	case TUINT:
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TUINTPTR:
+	case TFLOAT32:
+	case TFLOAT64:
+	case TCOMPLEX64:
+	case TCOMPLEX128:
+	case TBOOL:
+		ret = 0;
+		break;
+	case TARRAY:
+		if(t->bound < 0) {	// slice
+			ret = 1;
+			break;
+		}
+		if(t->bound == 0) {	// empty array
+			ret = 0;
+			break;
+		}
+		ret = haspointers(t->type);
+		break;
+	case TSTRUCT:
+		ret = 0;
+		for(t1=t->type; t1!=T; t1=t1->down) {
+			if(haspointers(t1->type)) {
+				ret = 1;
+				break;
+			}
+		}
+		break;
+	case TSTRING:
+	case TPTR32:
+	case TPTR64:
+	case TUNSAFEPTR:
+	case TINTER:
+	case TCHAN:
+	case TMAP:
+	case TFUNC:
+	default:
+		ret = 1;
+		break;
+	}
+	
+	t->haspointers = 1+ret;
+	return ret;
+}
+
+/*
+ * commonType
+ * ../../runtime/type.go:/commonType
+ */
+static int
+dcommontype(Sym *s, int ot, Type *t)
+{
+	int i, alg, sizeofAlg, gcprog;
+	Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1, *sbits;
+	uint8 gcmask[16];
+	static Sym *algarray;
+	uint64 x1, x2;
+	char *p;
+	
+	if(ot != 0)
+		fatal("dcommontype %d", ot);
+
+	sizeofAlg = 2*widthptr;
+	if(algarray == nil)
+		algarray = pkglookup("algarray", runtimepkg);
+	dowidth(t);
+	alg = algtype(t);
+	algsym = S;
+	if(alg < 0)
+		algsym = dalgsym(t);
+
+	if(t->sym != nil && !isptr[t->etype])
+		sptr = dtypesym(ptrto(t));
+	else
+		sptr = weaktypesym(ptrto(t));
+
+	// All (non-reflect-allocated) Types share the same zero object.
+	// Each place in the compiler where a pointer to the zero object
+	// might be returned by a runtime call (map access return value,
+	// 2-arg type cast) declares the size of the zerovalue it needs.
+	// The linker magically takes the max of all the sizes.
+	zero = pkglookup("zerovalue", runtimepkg);
+
+	// We use size 0 here so we get the pointer to the zero value,
+	// but don't allocate space for the zero value unless we need it.
+	// TODO: how do we get this symbol into bss?  We really want
+	// a read-only bss, but I don't think such a thing exists.
+
+	// ../../pkg/reflect/type.go:/^type.commonType
+	// actual type structure
+	//	type commonType struct {
+	//		size          uintptr
+	//		hash          uint32
+	//		_             uint8
+	//		align         uint8
+	//		fieldAlign    uint8
+	//		kind          uint8
+	//		alg           unsafe.Pointer
+	//		gc            unsafe.Pointer
+	//		string        *string
+	//		*extraType
+	//		ptrToThis     *Type
+	//		zero          unsafe.Pointer
+	//	}
+	ot = duintptr(s, ot, t->width);
+	ot = duint32(s, ot, typehash(t));
+	ot = duint8(s, ot, 0);	// unused
+
+	// runtime (and common sense) expects alignment to be a power of two.
+	i = t->align;
+	if(i == 0)
+		i = 1;
+	if((i&(i-1)) != 0)
+		fatal("invalid alignment %d for %T", t->align, t);
+	ot = duint8(s, ot, t->align);	// align
+	ot = duint8(s, ot, t->align);	// fieldAlign
+
+	gcprog = usegcprog(t);
+	i = kinds[t->etype];
+	if(t->etype == TARRAY && t->bound < 0)
+		i = KindSlice;
+	if(!haspointers(t))
+		i |= KindNoPointers;
+	if(isdirectiface(t))
+		i |= KindDirectIface;
+	if(gcprog)
+		i |= KindGCProg;
+	ot = duint8(s, ot, i);  // kind
+	if(alg >= 0)
+		ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
+	else
+		ot = dsymptr(s, ot, algsym, 0);
+	// gc
+	if(gcprog) {
+		gengcprog(t, &gcprog0, &gcprog1);
+		if(gcprog0 != S)
+			ot = dsymptr(s, ot, gcprog0, 0);
+		else
+			ot = duintptr(s, ot, 0);
+		ot = dsymptr(s, ot, gcprog1, 0);
+	} else {
+		gengcmask(t, gcmask);
+		x1 = 0;
+		for(i=0; i<8; i++)
+			x1 = x1<<8 | gcmask[i];
+		if(widthptr == 4) {
+			p = smprint("gcbits.%#016llux", x1);
+		} else {
+			x2 = 0;
+			for(i=0; i<8; i++)
+				x2 = x2<<8 | gcmask[i+8];
+			p = smprint("gcbits.%#016llux%016llux", x1, x2);
+		}
+		sbits = pkglookup(p, runtimepkg);
+		if((sbits->flags & SymUniq) == 0) {
+			sbits->flags |= SymUniq;
+			for(i = 0; i < 2*widthptr; i++)
+				duint8(sbits, i, gcmask[i]);
+			ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
+		}
+		ot = dsymptr(s, ot, sbits, 0);
+		ot = duintptr(s, ot, 0);
+	}
+	p = smprint("%-uT", t);
+	//print("dcommontype: %s\n", p);
+	ot = dgostringptr(s, ot, p);	// string
+	free(p);
+
+	// skip pointer to extraType,
+	// which follows the rest of this type structure.
+	// caller will fill in if needed.
+	// otherwise linker will assume 0.
+	ot += widthptr;
+
+	ot = dsymptr(s, ot, sptr, 0);  // ptrto type
+	ot = dsymptr(s, ot, zero, 0);  // ptr to zero value
+	return ot;
+}
+
+Sym*
+typesym(Type *t)
+{
+	char *p;
+	Sym *s;
+
+	p = smprint("%-T", t);
+	s = pkglookup(p, typepkg);
+	//print("typesym: %s -> %+S\n", p, s);
+	free(p);
+	return s;
+}
+
+Sym*
+tracksym(Type *t)
+{
+	char *p;
+	Sym *s;
+
+	p = smprint("%-T.%s", t->outer, t->sym->name);
+	s = pkglookup(p, trackpkg);
+	free(p);
+	return s;
+}
+
+Sym*
+typelinksym(Type *t)
+{
+	char *p;
+	Sym *s;
+
+	// %-uT is what the generated Type's string field says.
+	// It uses (ambiguous) package names instead of import paths.
+	// %-T is the complete, unambiguous type name.
+	// We want the types to end up sorted by string field,
+	// so use that first in the name, and then add :%-T to
+	// disambiguate. The names are a little long but they are
+	// discarded by the linker and do not end up in the symbol
+	// table of the final binary.
+	p = smprint("%-uT/%-T", t, t);
+	s = pkglookup(p, typelinkpkg);
+	//print("typelinksym: %s -> %+S\n", p, s);
+	free(p);
+	return s;
+}
+
+Sym*
+typesymprefix(char *prefix, Type *t)
+{
+	char *p;
+	Sym *s;
+
+	p = smprint("%s.%-T", prefix, t);
+	s = pkglookup(p, typepkg);
+	//print("algsym: %s -> %+S\n", p, s);
+	free(p);
+	return s;
+}
+
+Sym*
+typenamesym(Type *t)
+{
+	Sym *s;
+	Node *n;
+
+	if(t == T || (isptr[t->etype] && t->type == T) || isideal(t))
+		fatal("typename %T", t);
+	s = typesym(t);
+	if(s->def == N) {
+		n = nod(ONAME, N, N);
+		n->sym = s;
+		n->type = types[TUINT8];
+		n->addable = 1;
+		n->ullman = 1;
+		n->class = PEXTERN;
+		n->xoffset = 0;
+		n->typecheck = 1;
+		s->def = n;
+
+		signatlist = list(signatlist, typenod(t));
+	}
+	return s->def->sym;
+}
+
+Node*
+typename(Type *t)
+{
+	Sym *s;
+	Node *n;
+
+	s = typenamesym(t);
+	n = nod(OADDR, s->def, N);
+	n->type = ptrto(s->def->type);
+	n->addable = 1;
+	n->ullman = 2;
+	n->typecheck = 1;
+	return n;
+}
+
+static Sym*
+weaktypesym(Type *t)
+{
+	char *p;
+	Sym *s;
+
+	p = smprint("%-T", t);
+	s = pkglookup(p, weaktypepkg);
+	//print("weaktypesym: %s -> %+S\n", p, s);
+	free(p);
+	return s;
+}
+
+static Sym*
+dtypesym(Type *t)
+{
+	int ot, xt, n, isddd, dupok;
+	Sym *s, *s1, *s2, *s3, *s4, *slink;
+	Sig *a, *m;
+	Type *t1, *tbase, *t2;
+
+	// Replace byte, rune aliases with real type.
+	// They've been separate internally to make error messages
+	// better, but we have to merge them in the reflect tables.
+	if(t == bytetype || t == runetype)
+		t = types[t->etype];
+
+	if(isideal(t))
+		fatal("dtypesym %T", t);
+
+	s = typesym(t);
+	if(s->flags & SymSiggen)
+		return s;
+	s->flags |= SymSiggen;
+
+	// special case (look for runtime below):
+	// when compiling package runtime,
+	// emit the type structures for int, float, etc.
+	tbase = t;
+	if(isptr[t->etype] && t->sym == S && t->type->sym != S)
+		tbase = t->type;
+	dupok = 0;
+	if(tbase->sym == S)
+		dupok = DUPOK;
+
+	if(compiling_runtime &&
+			(tbase == types[tbase->etype] ||
+			tbase == bytetype ||
+			tbase == runetype ||
+			tbase == errortype)) { // int, float, etc
+		goto ok;
+	}
+
+	// named types from other files are defined only by those files
+	if(tbase->sym && !tbase->local)
+		return s;
+	if(isforw[tbase->etype])
+		return s;
+
+ok:
+	ot = 0;
+	xt = 0;
+	switch(t->etype) {
+	default:
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		break;
+
+	case TARRAY:
+		if(t->bound >= 0) {
+			// ../../runtime/type.go:/ArrayType
+			s1 = dtypesym(t->type);
+			t2 = typ(TARRAY);
+			t2->type = t->type;
+			t2->bound = -1;  // slice
+			s2 = dtypesym(t2);
+			ot = dcommontype(s, ot, t);
+			xt = ot - 3*widthptr;
+			ot = dsymptr(s, ot, s1, 0);
+			ot = dsymptr(s, ot, s2, 0);
+			ot = duintptr(s, ot, t->bound);
+		} else {
+			// ../../runtime/type.go:/SliceType
+			s1 = dtypesym(t->type);
+			ot = dcommontype(s, ot, t);
+			xt = ot - 3*widthptr;
+			ot = dsymptr(s, ot, s1, 0);
+		}
+		break;
+
+	case TCHAN:
+		// ../../runtime/type.go:/ChanType
+		s1 = dtypesym(t->type);
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = dsymptr(s, ot, s1, 0);
+		ot = duintptr(s, ot, t->chan);
+		break;
+
+	case TFUNC:
+		for(t1=getthisx(t)->type; t1; t1=t1->down)
+			dtypesym(t1->type);
+		isddd = 0;
+		for(t1=getinargx(t)->type; t1; t1=t1->down) {
+			isddd = t1->isddd;
+			dtypesym(t1->type);
+		}
+		for(t1=getoutargx(t)->type; t1; t1=t1->down)
+			dtypesym(t1->type);
+
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = duint8(s, ot, isddd);
+
+		// two slice headers: in and out.
+		ot = rnd(ot, widthptr);
+		ot = dsymptr(s, ot, s, ot+2*(widthptr+2*widthint));
+		n = t->thistuple + t->intuple;
+		ot = duintxx(s, ot, n, widthint);
+		ot = duintxx(s, ot, n, widthint);
+		ot = dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr);
+		ot = duintxx(s, ot, t->outtuple, widthint);
+		ot = duintxx(s, ot, t->outtuple, widthint);
+
+		// slice data
+		for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
+			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+		for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
+			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+		for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
+			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+		break;
+
+	case TINTER:
+		m = imethods(t);
+		n = 0;
+		for(a=m; a; a=a->link) {
+			dtypesym(a->type);
+			n++;
+		}
+
+		// ../../runtime/type.go:/InterfaceType
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+		ot = duintxx(s, ot, n, widthint);
+		ot = duintxx(s, ot, n, widthint);
+		for(a=m; a; a=a->link) {
+			// ../../runtime/type.go:/imethod
+			ot = dgostringptr(s, ot, a->name);
+			ot = dgopkgpath(s, ot, a->pkg);
+			ot = dsymptr(s, ot, dtypesym(a->type), 0);
+		}
+		break;
+
+	case TMAP:
+		// ../../runtime/type.go:/MapType
+		s1 = dtypesym(t->down);
+		s2 = dtypesym(t->type);
+		s3 = dtypesym(mapbucket(t));
+		s4 = dtypesym(hmap(t));
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = dsymptr(s, ot, s1, 0);
+		ot = dsymptr(s, ot, s2, 0);
+		ot = dsymptr(s, ot, s3, 0);
+		ot = dsymptr(s, ot, s4, 0);
+		if(t->down->width > MAXKEYSIZE) {
+			ot = duint8(s, ot, widthptr);
+			ot = duint8(s, ot, 1); // indirect
+		} else {
+			ot = duint8(s, ot, t->down->width);
+			ot = duint8(s, ot, 0); // not indirect
+		}
+		if(t->type->width > MAXVALSIZE) {
+			ot = duint8(s, ot, widthptr);
+			ot = duint8(s, ot, 1); // indirect
+		} else {
+			ot = duint8(s, ot, t->type->width);
+			ot = duint8(s, ot, 0); // not indirect
+		}
+		ot = duint16(s, ot, mapbucket(t)->width);
+		break;
+
+	case TPTR32:
+	case TPTR64:
+		if(t->type->etype == TANY) {
+			// ../../runtime/type.go:/UnsafePointerType
+			ot = dcommontype(s, ot, t);
+			break;
+		}
+		// ../../runtime/type.go:/PtrType
+		s1 = dtypesym(t->type);
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = dsymptr(s, ot, s1, 0);
+		break;
+
+	case TSTRUCT:
+		// ../../runtime/type.go:/StructType
+		// for security, only the exported fields.
+		n = 0;
+		for(t1=t->type; t1!=T; t1=t1->down) {
+			dtypesym(t1->type);
+			n++;
+		}
+		ot = dcommontype(s, ot, t);
+		xt = ot - 3*widthptr;
+		ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+		ot = duintxx(s, ot, n, widthint);
+		ot = duintxx(s, ot, n, widthint);
+		for(t1=t->type; t1!=T; t1=t1->down) {
+			// ../../runtime/type.go:/structField
+			if(t1->sym && !t1->embedded) {
+				ot = dgostringptr(s, ot, t1->sym->name);
+				if(exportname(t1->sym->name))
+					ot = dgostringptr(s, ot, nil);
+				else
+					ot = dgopkgpath(s, ot, t1->sym->pkg);
+			} else {
+				ot = dgostringptr(s, ot, nil);
+				if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg)
+					ot = dgopkgpath(s, ot, localpkg);
+				else
+					ot = dgostringptr(s, ot, nil);
+			}
+			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+			ot = dgostrlitptr(s, ot, t1->note);
+			ot = duintptr(s, ot, t1->width);	// field offset
+		}
+		break;
+	}
+	ot = dextratype(s, ot, t, xt);
+	ggloblsym(s, ot, dupok|RODATA);
+
+	// generate typelink.foo pointing at s = type.foo.
+	// The linker will leave a table of all the typelinks for
+	// types in the binary, so reflect can find them.
+	// We only need the link for unnamed composites that
+	// we want be able to find.
+	if(t->sym == S) {
+		switch(t->etype) {
+		case TARRAY:
+		case TCHAN:
+		case TMAP:
+			slink = typelinksym(t);
+			dsymptr(slink, 0, s, 0);
+			ggloblsym(slink, widthptr, dupok|RODATA);
+		}
+	}
+
+	return s;
+}
+
+void
+dumptypestructs(void)
+{
+	int i;
+	NodeList *l;
+	Node *n;
+	Type *t;
+	Pkg *p;
+
+	// copy types from externdcl list to signatlist
+	for(l=externdcl; l; l=l->next) {
+		n = l->n;
+		if(n->op != OTYPE)
+			continue;
+		signatlist = list(signatlist, n);
+	}
+
+	// process signatlist
+	for(l=signatlist; l; l=l->next) {
+		n = l->n;
+		if(n->op != OTYPE)
+			continue;
+		t = n->type;
+		dtypesym(t);
+		if(t->sym)
+			dtypesym(ptrto(t));
+	}
+
+	// generate import strings for imported packages
+	for(i=0; i<nelem(phash); i++)
+		for(p=phash[i]; p; p=p->link)
+			if(p->direct)
+				dimportpath(p);
+
+	// do basic types if compiling package runtime.
+	// they have to be in at least one package,
+	// and runtime is always loaded implicitly,
+	// so this is as good as any.
+	// another possible choice would be package main,
+	// but using runtime means fewer copies in .6 files.
+	if(compiling_runtime) {
+		for(i=1; i<=TBOOL; i++)
+			dtypesym(ptrto(types[i]));
+		dtypesym(ptrto(types[TSTRING]));
+		dtypesym(ptrto(types[TUNSAFEPTR]));
+
+		// emit type structs for error and func(error) string.
+		// The latter is the type of an auto-generated wrapper.
+		dtypesym(ptrto(errortype));
+		dtypesym(functype(nil,
+			list1(nod(ODCLFIELD, N, typenod(errortype))),
+			list1(nod(ODCLFIELD, N, typenod(types[TSTRING])))));
+
+		// add paths for runtime and main, which 6l imports implicitly.
+		dimportpath(runtimepkg);
+		if(flag_race)
+			dimportpath(racepkg);
+		dimportpath(mkpkg(strlit("main")));
+	}
+}
+
+static Sym*
+dalgsym(Type *t)
+{
+	int ot;
+	Sym *s, *hash, *hashfunc, *eq, *eqfunc;
+
+	// dalgsym is only called for a type that needs an algorithm table,
+	// which implies that the type is comparable (or else it would use ANOEQ).
+
+	s = typesymprefix(".alg", t);
+	hash = typesymprefix(".hash", t);
+	genhash(hash, t);
+	eq = typesymprefix(".eq", t);
+	geneq(eq, t);
+
+	// make Go funcs (closures) for calling hash and equal from Go
+	hashfunc = typesymprefix(".hashfunc", t);
+	dsymptr(hashfunc, 0, hash, 0);
+	ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
+	eqfunc = typesymprefix(".eqfunc", t);
+	dsymptr(eqfunc, 0, eq, 0);
+	ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
+
+	// ../../runtime/alg.go:/typeAlg
+	ot = 0;
+	ot = dsymptr(s, ot, hashfunc, 0);
+	ot = dsymptr(s, ot, eqfunc, 0);
+
+	ggloblsym(s, ot, DUPOK|RODATA);
+	return s;
+}
+
+static int
+usegcprog(Type *t)
+{
+	vlong size, nptr;
+
+	if(!haspointers(t))
+		return 0;
+	if(t->width == BADWIDTH)
+		dowidth(t);
+	// Calculate size of the unrolled GC mask.
+	nptr = (t->width+widthptr-1)/widthptr;
+	size = nptr;
+	if(size%2)
+		size *= 2;	// repeated
+	size = size*gcBits/8;	// 4 bits per word
+	// Decide whether to use unrolled GC mask or GC program.
+	// We could use a more elaborate condition, but this seems to work well in practice.
+	// For small objects GC program can't give significant reduction.
+	// While large objects usually contain arrays; and even if it don't
+	// the program uses 2-bits per word while mask uses 4-bits per word,
+	// so the program is still smaller.
+	return size > 2*widthptr;
+}
+
+// Generates sparse GC bitmask (4 bits per word).
+static void
+gengcmask(Type *t, uint8 gcmask[16])
+{
+	Bvec *vec;
+	vlong xoffset, nptr, i, j;
+	int  half, mw;
+	uint8 bits, *pos;
+
+	memset(gcmask, 0, 16);
+	if(!haspointers(t))
+		return;
+
+	// Generate compact mask as stacks use.
+	xoffset = 0;
+	vec = bvalloc(2*widthptr*8);
+	twobitwalktype1(t, &xoffset, vec);
+
+	// Unfold the mask for the GC bitmap format:
+	// 4 bits per word, 2 high bits encode pointer info.
+	pos = (uint8*)gcmask;
+	nptr = (t->width+widthptr-1)/widthptr;
+	half = 0;
+	mw = 0;
+	// If number of words is odd, repeat the mask.
+	// This makes simpler handling of arrays in runtime.
+	for(j=0; j<=(nptr%2); j++) {
+		for(i=0; i<nptr; i++) {
+			bits = bvget(vec, i*BitsPerPointer) | bvget(vec, i*BitsPerPointer+1)<<1;
+			// Some fake types (e.g. Hmap) has missing fileds.
+			// twobitwalktype1 generates BitsDead for that holes,
+			// replace BitsDead with BitsScalar.
+			if(!mw && bits == BitsDead)
+				bits = BitsScalar;
+			mw = !mw && bits == BitsMultiWord;
+			bits <<= 2;
+			if(half)
+				bits <<= 4;
+			*pos |= bits;
+			half = !half;
+			if(!half)
+				pos++;
+		}
+	}
+}
+
+// Helper object for generation of GC programs.
+typedef struct ProgGen ProgGen;
+struct ProgGen
+{
+	Sym*	s;
+	int32	datasize;
+	uint8	data[256/PointersPerByte];
+	vlong	ot;
+};
+
+static void
+proggeninit(ProgGen *g, Sym *s)
+{
+	g->s = s;
+	g->datasize = 0;
+	g->ot = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
+
+static void
+proggenemit(ProgGen *g, uint8 v)
+{
+	g->ot = duint8(g->s, g->ot, v);
+}
+
+// Emits insData block from g->data.
+static void
+proggendataflush(ProgGen *g)
+{
+	int32 i, s;
+
+	if(g->datasize == 0)
+		return;
+	proggenemit(g, insData);
+	proggenemit(g, g->datasize);
+	s = (g->datasize + PointersPerByte - 1)/PointersPerByte;
+	for(i = 0; i < s; i++)
+		proggenemit(g, g->data[i]);
+	g->datasize = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
+
+static void
+proggendata(ProgGen *g, uint8 d)
+{
+	g->data[g->datasize/PointersPerByte] |= d << ((g->datasize%PointersPerByte)*BitsPerPointer);
+	g->datasize++;
+	if(g->datasize == 255)
+		proggendataflush(g);
+}
+
+// Skip v bytes due to alignment, etc.
+static void
+proggenskip(ProgGen *g, vlong off, vlong v)
+{
+	vlong i;
+
+	for(i = off; i < off+v; i++) {
+		if((i%widthptr) == 0)
+			proggendata(g, BitsScalar);
+	}
+}
+
+// Emit insArray instruction.
+static void
+proggenarray(ProgGen *g, vlong len)
+{
+	int32 i;
+
+	proggendataflush(g);
+	proggenemit(g, insArray);
+	for(i = 0; i < widthptr; i++, len >>= 8)
+		proggenemit(g, len);
+}
+
+static void
+proggenarrayend(ProgGen *g)
+{
+	proggendataflush(g);
+	proggenemit(g, insArrayEnd);
+}
+
+static vlong
+proggenfini(ProgGen *g)
+{
+	proggendataflush(g);
+	proggenemit(g, insEnd);
+	return g->ot;
+}
+
+static void gengcprog1(ProgGen *g, Type *t, vlong *xoffset);
+
+// Generates GC program for large types.
+static void
+gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
+{
+	Sym *gc0, *gc1;
+	vlong nptr, size, ot, xoffset;
+	ProgGen g;
+
+	nptr = (t->width+widthptr-1)/widthptr;
+	size = nptr;
+	if(size%2)
+		size *= 2;	// repeated twice
+	size = size*PointersPerByte/8;	// 4 bits per word
+	size++;	// unroll flag in the beginning, used by runtime (see runtime.markallocated)
+	// emity space in BSS for unrolled program
+	*pgc0 = S;
+	// Don't generate it if it's too large, runtime will unroll directly into GC bitmap.
+	if(size <= MaxGCMask) {
+		gc0 = typesymprefix(".gc", t);
+		ggloblsym(gc0, size, DUPOK|NOPTR);
+		*pgc0 = gc0;
+	}
+
+	// program in RODATA
+	gc1 = typesymprefix(".gcprog", t);
+	proggeninit(&g, gc1);
+	xoffset = 0;
+	gengcprog1(&g, t, &xoffset);
+	ot = proggenfini(&g);
+	ggloblsym(gc1, ot, DUPOK|RODATA);
+	*pgc1 = gc1;
+}
+
+// Recursively walks type t and writes GC program into g.
+static void
+gengcprog1(ProgGen *g, Type *t, vlong *xoffset)
+{
+	vlong fieldoffset, i, o, n;
+	Type *t1;
+
+	switch(t->etype) {
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TINT:
+	case TUINT:
+	case TUINTPTR:
+	case TBOOL:
+	case TFLOAT32:
+	case TFLOAT64:
+	case TCOMPLEX64:
+	case TCOMPLEX128:
+		proggenskip(g, *xoffset, t->width);
+		*xoffset += t->width;
+		break;
+	case TPTR32:
+	case TPTR64:
+	case TUNSAFEPTR:
+	case TFUNC:
+	case TCHAN:
+	case TMAP:
+		proggendata(g, BitsPointer);
+		*xoffset += t->width;
+		break;
+	case TSTRING:
+		proggendata(g, BitsPointer);
+		proggendata(g, BitsScalar);
+		*xoffset += t->width;
+		break;
+	case TINTER:
+		proggendata(g, BitsMultiWord);
+		if(isnilinter(t))
+			proggendata(g, BitsEface);
+		else
+			proggendata(g, BitsIface);
+		*xoffset += t->width;
+		break;
+	case TARRAY:
+		if(isslice(t)) {
+			proggendata(g, BitsPointer);
+			proggendata(g, BitsScalar);
+			proggendata(g, BitsScalar);
+		} else {
+			t1 = t->type;
+			if(t1->width == 0) {
+				// ignore
+			} if(t->bound <= 1 || t->bound*t1->width < 32*widthptr) {
+				for(i = 0; i < t->bound; i++)
+					gengcprog1(g, t1, xoffset);
+			} else if(!haspointers(t1)) {
+				n = t->width;
+				n -= -*xoffset&(widthptr-1); // skip to next ptr boundary
+				proggenarray(g, (n+widthptr-1)/widthptr);
+				proggendata(g, BitsScalar);
+				proggenarrayend(g);
+				*xoffset -= (n+widthptr-1)/widthptr*widthptr - t->width;
+			} else {
+				proggenarray(g, t->bound);
+				gengcprog1(g, t1, xoffset);
+				*xoffset += (t->bound-1)*t1->width;
+				proggenarrayend(g);
+			}
+		}
+		break;
+	case TSTRUCT:
+		o = 0;
+		for(t1 = t->type; t1 != T; t1 = t1->down) {
+			fieldoffset = t1->width;
+			proggenskip(g, *xoffset, fieldoffset - o);
+			*xoffset += fieldoffset - o;
+			gengcprog1(g, t1->type, xoffset);
+			o = fieldoffset + t1->type->width;
+		}
+		proggenskip(g, *xoffset, t->width - o);
+		*xoffset += t->width - o;
+		break;
+	default:
+		fatal("gengcprog1: unexpected type, %T", t);
+	}
+}
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
new file mode 100644
index 0000000..0fb15c2
--- /dev/null
+++ b/src/cmd/gc/runtime.go
@@ -0,0 +1,164 @@
+// 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.
+
+// NOTE: If you change this file you must run "./mkbuiltin"
+// to update builtin.c.  This is not done automatically
+// to avoid depending on having a working compiler binary.
+
+// +build ignore
+
+package PACKAGE
+
+// emitted by compiler, not referred to by go programs
+
+func newobject(typ *byte) *any
+func panicindex()
+func panicslice()
+func panicdivide()
+func throwreturn()
+func throwinit()
+func panicwrap(string, string, string)
+
+func gopanic(interface{})
+func gorecover(*int32) interface{}
+
+func printbool(bool)
+func printfloat(float64)
+func printint(int64)
+func printhex(uint64)
+func printuint(uint64)
+func printcomplex(complex128)
+func printstring(string)
+func printpointer(any)
+func printiface(any)
+func printeface(any)
+func printslice(any)
+func printnl()
+func printsp()
+
+func concatstring2(string, string) string
+func concatstring3(string, string, string) string
+func concatstring4(string, string, string, string) string
+func concatstring5(string, string, string, string, string) string
+func concatstrings([]string) string
+
+func cmpstring(string, string) int
+func eqstring(string, string) bool
+func intstring(int64) string
+func slicebytetostring([]byte) string
+func slicebytetostringtmp([]byte) string
+func slicerunetostring([]rune) string
+func stringtoslicebyte(string) []byte
+func stringtoslicerune(string) []rune
+func stringiter(string, int) int
+func stringiter2(string, int) (retk int, retv rune)
+func slicecopy(to any, fr any, wid uintptr) int
+func slicestringcopy(to any, fr any) int
+
+// interface conversions
+func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
+func convI2E(elem any) (ret any)
+func convI2I(typ *byte, elem any) (ret any)
+func convT2E(typ *byte, elem *any) (ret any)
+func convT2I(typ *byte, typ2 *byte, cache **byte, elem *any) (ret any)
+
+// interface type assertions  x.(T)
+func assertE2E(typ *byte, iface any) (ret any)
+func assertE2E2(typ *byte, iface any) (ret any, ok bool)
+func assertE2I(typ *byte, iface any) (ret any)
+func assertE2I2(typ *byte, iface any) (ret any, ok bool)
+func assertE2T(typ *byte, iface any) (ret any)
+func assertE2T2(typ *byte, iface any) (ret any, ok bool)
+func assertI2E(typ *byte, iface any) (ret any)
+func assertI2E2(typ *byte, iface any) (ret any, ok bool)
+func assertI2I(typ *byte, iface any) (ret any)
+func assertI2I2(typ *byte, iface any) (ret any, ok bool)
+func assertI2T(typ *byte, iface any) (ret any)
+func assertI2T2(typ *byte, iface any) (ret any, ok bool)
+func assertI2TOK(typ *byte, iface any) (ok bool)
+func assertE2TOK(typ *byte, iface any) (ok bool)
+
+func ifaceeq(i1 any, i2 any) (ret bool)
+func efaceeq(i1 any, i2 any) (ret bool)
+func ifacethash(i1 any) (ret uint32)
+func efacethash(i1 any) (ret uint32)
+
+// *byte is really *runtime.Type
+func makemap(mapType *byte, hint int64) (hmap map[any]any)
+func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
+func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
+func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
+func mapaccess1_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
+func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
+func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
+func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
+func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
+func mapassign1(mapType *byte, hmap map[any]any, key *any, val *any)
+func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
+func mapdelete(mapType *byte, hmap map[any]any, key *any)
+func mapiternext(hiter *any)
+
+// *byte is really *runtime.Type
+func makechan(chanType *byte, hint int64) (hchan chan any)
+func chanrecv1(chanType *byte, hchan <-chan any, elem *any)
+func chanrecv2(chanType *byte, hchan <-chan any, elem *any) bool
+func chansend1(chanType *byte, hchan chan<- any, elem *any)
+func closechan(hchan any)
+
+// *byte is really *runtime.Type
+func writebarrierptr(dst *any, src any)
+func writebarrierstring(dst *any, src any)
+func writebarrierslice(dst *any, src any)
+func writebarrieriface(dst *any, src any)
+
+// The unused *byte argument makes sure that src is 2-pointer-aligned,
+// which is the maximum alignment on NaCl amd64p32
+// (and possibly on 32-bit systems if we start 64-bit aligning uint64s).
+func writebarrierfat2(dst *any, _ *byte, src any)
+func writebarrierfat3(dst *any, _ *byte, src any)
+func writebarrierfat4(dst *any, _ *byte, src any)
+func writebarrierfat(typ *byte, dst *any, src *any)
+
+func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
+func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
+func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool
+
+func newselect(sel *byte, selsize int64, size int32)
+func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool)
+func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
+func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool)
+func selectdefault(sel *byte) (selected bool)
+func selectgo(sel *byte)
+func block()
+
+func makeslice(typ *byte, nel int64, cap int64) (ary []any)
+func growslice(typ *byte, old []any, n int64) (ary []any)
+func memmove(to *any, frm *any, length uintptr)
+
+func memequal(x, y *any, size uintptr) bool
+func memequal8(x, y *any, size uintptr) bool
+func memequal16(x, y *any, size uintptr) bool
+func memequal32(x, y *any, size uintptr) bool
+func memequal64(x, y *any, size uintptr) bool
+func memequal128(x, y *any, size uintptr) bool
+
+// only used on 32-bit
+func int64div(int64, int64) int64
+func uint64div(uint64, uint64) uint64
+func int64mod(int64, int64) int64
+func uint64mod(uint64, uint64) uint64
+func float64toint64(float64) int64
+func float64touint64(float64) uint64
+func int64tofloat64(int64) float64
+func uint64tofloat64(uint64) float64
+
+func complex128div(num complex128, den complex128) (quo complex128)
+
+// race detection
+func racefuncenter(uintptr)
+func racefuncexit()
+func raceread(uintptr)
+func racewrite(uintptr)
+func racereadrange(addr, size uintptr)
+func racewriterange(addr, size uintptr)
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c
new file mode 100644
index 0000000..965ad27
--- /dev/null
+++ b/src/cmd/gc/select.c
@@ -0,0 +1,377 @@
+// 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.
+
+/*
+ * select
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+static Type* selecttype(int32 size);
+
+void
+typecheckselect(Node *sel)
+{
+	Node *ncase, *n, *def;
+	NodeList *l;
+	int lno, count;
+
+	def = nil;
+	lno = setlineno(sel);
+	count = 0;
+	typechecklist(sel->ninit, Etop);
+	for(l=sel->list; l; l=l->next) {
+		count++;
+		ncase = l->n;
+		setlineno(ncase);
+		if(ncase->op != OXCASE)
+			fatal("typecheckselect %O", ncase->op);
+
+		if(ncase->list == nil) {
+			// default
+			if(def != N)
+				yyerror("multiple defaults in select (first at %L)", def->lineno);
+			else
+				def = ncase;
+		} else if(ncase->list->next) {
+			yyerror("select cases cannot be lists");
+		} else {
+			n = typecheck(&ncase->list->n, Etop);
+			ncase->left = n;
+			ncase->list = nil;
+			setlineno(n);
+			switch(n->op) {
+			default:
+				yyerror("select case must be receive, send or assign recv");
+				break;
+
+			case OAS:
+				// convert x = <-c into OSELRECV(x, <-c).
+				// remove implicit conversions; the eventual assignment
+				// will reintroduce them.
+				if((n->right->op == OCONVNOP || n->right->op == OCONVIFACE) && n->right->implicit)
+					n->right = n->right->left;
+
+				if(n->right->op != ORECV) {
+					yyerror("select assignment must have receive on right hand side");
+					break;
+				}
+				n->op = OSELRECV;
+				break;
+
+			case OAS2RECV:
+				// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
+				if(n->rlist->n->op != ORECV) {
+					yyerror("select assignment must have receive on right hand side");
+					break;
+				}
+				n->op = OSELRECV2;
+				n->left = n->list->n;
+				n->ntest = n->list->next->n;
+				n->list = nil;
+				n->right = n->rlist->n;
+				n->rlist = nil;
+				break;
+
+			case ORECV:
+				// convert <-c into OSELRECV(N, <-c)
+				n = nod(OSELRECV, N, n);
+				n->typecheck = 1;
+				ncase->left = n;
+				break;
+
+			case OSEND:
+				break;
+			}
+		}
+		typechecklist(ncase->nbody, Etop);
+	}
+	sel->xoffset = count;
+	lineno = lno;
+}
+
+void
+walkselect(Node *sel)
+{
+	int lno, i;
+	Node *n, *r, *a, *var, *selv, *cas, *dflt, *ch;
+	NodeList *l, *init;
+	
+	if(sel->list == nil && sel->xoffset != 0)
+		fatal("double walkselect");	// already rewrote
+	
+	lno = setlineno(sel);
+	i = count(sel->list);
+	
+	// optimization: zero-case select
+	if(i == 0) {
+		sel->nbody = list1(mkcall("block", nil, nil));
+		goto out;
+	}
+
+	// optimization: one-case select: single op.
+	// TODO(rsc): Reenable optimization once order.c can handle it.
+	// golang.org/issue/7672.
+	if(i == 1) {
+		cas = sel->list->n;
+		setlineno(cas);
+		l = cas->ninit;
+		if(cas->left != N) {  // not default:
+			n = cas->left;
+			l = concat(l, n->ninit);
+			n->ninit = nil;
+			switch(n->op) {
+			default:
+				fatal("select %O", n->op);
+
+			case OSEND:
+				// ok already
+				ch = n->left;
+				break;
+
+			case OSELRECV:
+				ch = n->right->left;
+			Selrecv1:
+				if(n->left == N)
+					n = n->right;
+				else
+					n->op = OAS;
+				break;
+			
+			case OSELRECV2:
+				ch = n->right->left;
+				if(n->ntest == N)
+					goto Selrecv1;
+				if(n->left == N) {
+					typecheck(&nblank, Erv | Easgn);
+					n->left = nblank;
+				}
+				n->op = OAS2;
+				n->list = list(list1(n->left), n->ntest);
+				n->rlist = list1(n->right);
+				n->right = N;
+				n->left = N;
+				n->ntest = N;
+				n->typecheck = 0;
+				typecheck(&n, Etop);
+				break;
+			}
+
+			// if ch == nil { block() }; n;
+			a = nod(OIF, N, N);
+			a->ntest = nod(OEQ, ch, nodnil());
+			a->nbody = list1(mkcall("block", nil, &l));
+			typecheck(&a, Etop);
+			l = list(l, a);
+			l = list(l, n);
+		}
+		l = concat(l, cas->nbody);
+		sel->nbody = l;
+		goto out;
+	}
+
+	// convert case value arguments to addresses.
+	// this rewrite is used by both the general code and the next optimization.
+	for(l=sel->list; l; l=l->next) {
+		cas = l->n;
+		setlineno(cas);
+		n = cas->left;
+		if(n == N)
+			continue;
+		switch(n->op) {
+		case OSEND:
+			n->right = nod(OADDR, n->right, N);
+			typecheck(&n->right, Erv);
+			break;
+		case OSELRECV:
+		case OSELRECV2:
+			if(n->op == OSELRECV2 && n->ntest == N)
+				n->op = OSELRECV;
+			if(n->op == OSELRECV2) {
+				n->ntest = nod(OADDR, n->ntest, N);
+				typecheck(&n->ntest, Erv);
+			}
+			if(n->left == N)
+				n->left = nodnil();
+			else {
+				n->left = nod(OADDR, n->left, N);
+				typecheck(&n->left, Erv);
+			}			
+			break;
+		}
+	}
+
+	// optimization: two-case select but one is default: single non-blocking op.
+	if(i == 2 && (sel->list->n->left == nil || sel->list->next->n->left == nil)) {
+		if(sel->list->n->left == nil) {
+			cas = sel->list->next->n;
+			dflt = sel->list->n;
+		} else {
+			dflt = sel->list->next->n;
+			cas = sel->list->n;
+		}
+		
+		n = cas->left;
+		setlineno(n);
+		r = nod(OIF, N, N);
+		r->ninit = cas->ninit;
+		switch(n->op) {
+		default:
+			fatal("select %O", n->op);
+
+		case OSEND:
+			// if selectnbsend(c, v) { body } else { default body }
+			ch = n->left;
+			r->ntest = mkcall1(chanfn("selectnbsend", 2, ch->type),
+					types[TBOOL], &r->ninit, typename(ch->type), ch, n->right);
+			break;
+			
+		case OSELRECV:
+			// if c != nil && selectnbrecv(&v, c) { body } else { default body }
+			r = nod(OIF, N, N);
+			r->ninit = cas->ninit;
+			ch = n->right->left;
+			r->ntest = mkcall1(chanfn("selectnbrecv", 2, ch->type),
+					types[TBOOL], &r->ninit, typename(ch->type), n->left, ch);
+			break;
+
+		case OSELRECV2:
+			// if c != nil && selectnbrecv2(&v, c) { body } else { default body }
+			r = nod(OIF, N, N);
+			r->ninit = cas->ninit;
+			ch = n->right->left;
+			r->ntest = mkcall1(chanfn("selectnbrecv2", 2, ch->type),
+					types[TBOOL], &r->ninit, typename(ch->type), n->left, n->ntest, ch);
+			break;
+		}
+		typecheck(&r->ntest, Erv);
+		r->nbody = cas->nbody;
+		r->nelse = concat(dflt->ninit, dflt->nbody);
+		sel->nbody = list1(r);
+		goto out;
+	}		
+
+	init = sel->ninit;
+	sel->ninit = nil;
+
+	// generate sel-struct
+	setlineno(sel);
+	selv = temp(selecttype(sel->xoffset));
+	r = nod(OAS, selv, N);
+	typecheck(&r, Etop);
+	init = list(init, r);
+	var = conv(conv(nod(OADDR, selv, N), types[TUNSAFEPTR]), ptrto(types[TUINT8]));
+	r = mkcall("newselect", T, nil, var, nodintconst(selv->type->width), nodintconst(sel->xoffset));
+	typecheck(&r, Etop);
+	init = list(init, r);
+
+	// register cases
+	for(l=sel->list; l; l=l->next) {
+		cas = l->n;
+		setlineno(cas);
+		n = cas->left;
+		r = nod(OIF, N, N);
+		r->ninit = cas->ninit;
+		cas->ninit = nil;
+		if(n != nil) {
+			r->ninit = concat(r->ninit, n->ninit);
+			n->ninit = nil;
+		}
+		if(n == nil) {
+			// selectdefault(sel *byte);
+			r->ntest = mkcall("selectdefault", types[TBOOL], &r->ninit, var);
+		} else {
+			switch(n->op) {
+			default:
+				fatal("select %O", n->op);
+	
+			case OSEND:
+				// selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
+				r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL],
+					&r->ninit, var, n->left, n->right);
+				break;
+
+			case OSELRECV:
+				// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
+				r->ntest = mkcall1(chanfn("selectrecv", 2, n->right->left->type), types[TBOOL],
+					&r->ninit, var, n->right->left, n->left);
+				break;
+
+			case OSELRECV2:
+				// selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool);
+				r->ntest = mkcall1(chanfn("selectrecv2", 2, n->right->left->type), types[TBOOL],
+					&r->ninit, var, n->right->left, n->left, n->ntest);
+				break;
+			}
+		}
+		// selv is no longer alive after use.
+		r->nbody = list(r->nbody, nod(OVARKILL, selv, N));
+		r->nbody = concat(r->nbody, cas->nbody);
+		r->nbody = list(r->nbody, nod(OBREAK, N, N));
+		init = list(init, r);
+	}
+
+	// run the select
+	setlineno(sel);
+	init = list(init, mkcall("selectgo", T, nil, var));
+	sel->nbody = init;
+
+out:
+	sel->list = nil;
+	walkstmtlist(sel->nbody);
+	lineno = lno;
+}
+
+// Keep in sync with src/runtime/chan.h.
+static Type*
+selecttype(int32 size)
+{
+	Node *sel, *sudog, *scase, *arr;
+
+	// TODO(dvyukov): it's possible to generate SudoG and Scase only once
+	// and then cache; and also cache Select per size.
+	sudog = nod(OTSTRUCT, N, N);
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("g")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("selectdone")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("link")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("prev")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("releasetime")), typenod(types[TUINT64])));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("nrelease")), typenod(types[TINT32])));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("waitlink")), typenod(ptrto(types[TUINT8]))));
+	typecheck(&sudog, Etype);
+	sudog->type->noalg = 1;
+	sudog->type->local = 1;
+
+	scase = nod(OTSTRUCT, N, N);
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("chan")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("pc")), typenod(types[TUINTPTR])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("kind")), typenod(types[TUINT16])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("so")), typenod(types[TUINT16])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("receivedp")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("releasetime")), typenod(types[TUINT64])));
+	typecheck(&scase, Etype);
+	scase->type->noalg = 1;
+	scase->type->local = 1;
+
+	sel = nod(OTSTRUCT, N, N);
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("tcase")), typenod(types[TUINT16])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("ncase")), typenod(types[TUINT16])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("pollorder")), typenod(ptrto(types[TUINT8]))));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("lockorder")), typenod(ptrto(types[TUINT8]))));
+	arr = nod(OTARRAY, nodintconst(size), scase);
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("scase")), arr));
+	arr = nod(OTARRAY, nodintconst(size), typenod(ptrto(types[TUINT8])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("lockorderarr")), arr));
+	arr = nod(OTARRAY, nodintconst(size), typenod(types[TUINT16]));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("pollorderarr")), arr));
+	typecheck(&sel, Etype);
+	sel->type->noalg = 1;
+	sel->type->local = 1;
+
+	return sel->type;
+}
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c
new file mode 100644
index 0000000..8ad7ae7
--- /dev/null
+++ b/src/cmd/gc/sinit.c
@@ -0,0 +1,1505 @@
+// 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.
+
+/*
+ * static initialization
+ */
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+enum
+{
+	InitNotStarted = 0,
+	InitDone = 1,
+	InitPending = 2,
+};
+
+static void initplan(Node*);
+static NodeList *initlist;
+static void init2(Node*, NodeList**);
+static void init2list(NodeList*, NodeList**);
+static int staticinit(Node*, NodeList**);
+static Node *staticname(Type*, int);
+
+// init1 walks the AST starting at n, and accumulates in out
+// the list of definitions needing init code in dependency order.
+static void
+init1(Node *n, NodeList **out)
+{
+	NodeList *l;
+	Node *nv;
+
+	if(n == N)
+		return;
+	init1(n->left, out);
+	init1(n->right, out);
+	for(l=n->list; l; l=l->next)
+		init1(l->n, out);
+
+	if(n->left && n->type && n->left->op == OTYPE && n->class == PFUNC) {
+		// Methods called as Type.Method(receiver, ...).
+		// Definitions for method expressions are stored in type->nname.
+		init1(n->type->nname, out);
+	}
+
+	if(n->op != ONAME)
+		return;
+	switch(n->class) {
+	case PEXTERN:
+	case PFUNC:
+		break;
+	default:
+		if(isblank(n) && n->curfn == N && n->defn != N && n->defn->initorder == InitNotStarted) {
+			// blank names initialization is part of init() but not
+			// when they are inside a function.
+			break;
+		}
+		return;
+	}
+
+	if(n->initorder == InitDone)
+		return;
+	if(n->initorder == InitPending) {
+		// Since mutually recursive sets of functions are allowed,
+		// we don't necessarily raise an error if n depends on a node
+		// which is already waiting for its dependencies to be visited.
+		//
+		// initlist contains a cycle of identifiers referring to each other.
+		// If this cycle contains a variable, then this variable refers to itself.
+		// Conversely, if there exists an initialization cycle involving
+		// a variable in the program, the tree walk will reach a cycle
+		// involving that variable.
+		if(n->class != PFUNC) {
+			nv = n;
+			goto foundinitloop;
+		}
+		for(l=initlist; l->n!=n; l=l->next) {
+			if(l->n->class != PFUNC) {
+				nv = l->n;
+				goto foundinitloop;
+			}
+		}
+		// The loop involves only functions, ok.
+		return;
+
+	foundinitloop:
+		// if there have already been errors printed,
+		// those errors probably confused us and
+		// there might not be a loop.  let the user
+		// fix those first.
+		flusherrors();
+		if(nerrors > 0)
+			errorexit();
+
+		// There is a loop involving nv. We know about
+		// n and initlist = n1 <- ... <- nv <- ... <- n <- ...
+		print("%L: initialization loop:\n", nv->lineno);
+		// Build back pointers in initlist.
+		for(l=initlist; l; l=l->next)
+			if(l->next != nil)
+				l->next->end = l;
+		// Print nv -> ... -> n1 -> n.
+		for(l=initlist; l->n!=nv; l=l->next);
+		for(; l; l=l->end)
+			print("\t%L %S refers to\n", l->n->lineno, l->n->sym);
+		// Print n -> ... -> nv.
+		for(l=initlist; l->n!=n; l=l->next);
+		for(; l->n != nv; l=l->end)
+			print("\t%L %S refers to\n", l->n->lineno, l->n->sym);
+		print("\t%L %S\n", nv->lineno, nv->sym);
+		errorexit();
+	}
+
+	// reached a new unvisited node.
+	n->initorder = InitPending;
+	l = malloc(sizeof *l);
+	if(l == nil) {
+		flusherrors();
+		yyerror("out of memory");
+		errorexit();
+	}
+	l->next = initlist;
+	l->n = n;
+	l->end = nil;
+	initlist = l;
+
+	// make sure that everything n depends on is initialized.
+	// n->defn is an assignment to n
+	if(n->defn != N) {
+		switch(n->defn->op) {
+		default:
+			goto bad;
+
+		case ODCLFUNC:
+			init2list(n->defn->nbody, out);
+			break;
+
+		case OAS:
+			if(n->defn->left != n)
+				goto bad;
+			if(isblank(n->defn->left) && candiscard(n->defn->right)) {
+				n->defn->op = OEMPTY;
+				n->defn->left = N;
+				n->defn->right = N;
+				break;
+			}
+
+			init2(n->defn->right, out);
+			if(debug['j'])
+				print("%S\n", n->sym);
+			if(isblank(n) || !staticinit(n, out)) {
+				if(debug['%'])
+					dump("nonstatic", n->defn);
+				*out = list(*out, n->defn);
+			}
+			break;
+
+		case OAS2FUNC:
+		case OAS2MAPR:
+		case OAS2DOTTYPE:
+		case OAS2RECV:
+			if(n->defn->initorder != InitNotStarted)
+				break;
+			n->defn->initorder = InitDone;
+			for(l=n->defn->rlist; l; l=l->next)
+				init1(l->n, out);
+			if(debug['%']) dump("nonstatic", n->defn);
+			*out = list(*out, n->defn);
+			break;
+		}
+	}
+	l = initlist;
+	initlist = l->next;
+	if(l->n != n)
+		fatal("bad initlist");
+	free(l);
+	n->initorder = InitDone;
+	return;
+
+bad:
+	dump("defn", n->defn);
+	fatal("init1: bad defn");
+}
+
+// recurse over n, doing init1 everywhere.
+static void
+init2(Node *n, NodeList **out)
+{
+	if(n == N || n->initorder == InitDone)
+		return;
+
+	if(n->op == ONAME && n->ninit)
+		fatal("name %S with ninit: %+N\n", n->sym, n);
+
+	init1(n, out);
+	init2(n->left, out);
+	init2(n->right, out);
+	init2(n->ntest, out);
+	init2list(n->ninit, out);
+	init2list(n->list, out);
+	init2list(n->rlist, out);
+	init2list(n->nbody, out);
+	init2list(n->nelse, out);
+	
+	if(n->op == OCLOSURE)
+		init2list(n->closure->nbody, out);
+	if(n->op == ODOTMETH || n->op == OCALLPART)
+		init2(n->type->nname, out);
+}
+
+static void
+init2list(NodeList *l, NodeList **out)
+{
+	for(; l; l=l->next)
+		init2(l->n, out);
+}
+
+static void
+initreorder(NodeList *l, NodeList **out)
+{
+	Node *n;
+
+	for(; l; l=l->next) {
+		n = l->n;
+		switch(n->op) {
+		case ODCLFUNC:
+		case ODCLCONST:
+		case ODCLTYPE:
+			continue;
+		}
+		initreorder(n->ninit, out);
+		n->ninit = nil;
+		init1(n, out);
+	}
+}
+
+// initfix computes initialization order for a list l of top-level
+// declarations and outputs the corresponding list of statements
+// to include in the init() function body.
+NodeList*
+initfix(NodeList *l)
+{
+	NodeList *lout;
+	int lno;
+
+	lout = nil;
+	lno = lineno;
+	initreorder(l, &lout);
+	lineno = lno;
+	return lout;
+}
+
+/*
+ * compilation of top-level (static) assignments
+ * into DATA statements if at all possible.
+ */
+
+static int staticassign(Node*, Node*, NodeList**);
+
+static int
+staticinit(Node *n, NodeList **out)
+{
+	Node *l, *r;
+
+	if(n->op != ONAME || n->class != PEXTERN || n->defn == N || n->defn->op != OAS)
+		fatal("staticinit");
+
+	lineno = n->lineno;
+	l = n->defn->left;
+	r = n->defn->right;
+	return staticassign(l, r, out);
+}
+
+// like staticassign but we are copying an already
+// initialized value r.
+static int
+staticcopy(Node *l, Node *r, NodeList **out)
+{
+	int i;
+	InitEntry *e;
+	InitPlan *p;
+	Node *a, *ll, *rr, *orig, n1;
+
+	if(r->op != ONAME || r->class != PEXTERN || r->sym->pkg != localpkg)
+		return 0;
+	if(r->defn == N)	// probably zeroed but perhaps supplied externally and of unknown value
+		return 0;
+	if(r->defn->op != OAS)
+		return 0;
+	orig = r;
+	r = r->defn->right;
+	
+	switch(r->op) {
+	case ONAME:
+		if(staticcopy(l, r, out))
+			return 1;
+		*out = list(*out, nod(OAS, l, r));
+		return 1;
+	
+	case OLITERAL:
+		if(iszero(r))
+			return 1;
+		gdata(l, r, l->type->width);
+		return 1;
+
+	case OADDR:
+		switch(r->left->op) {
+		case ONAME:
+			gdata(l, r, l->type->width);
+			return 1;
+		}
+		break;
+	
+	case OPTRLIT:
+		switch(r->left->op) {
+		default:
+			//dump("not static addr", r);
+			break;
+		case OARRAYLIT:
+		case OSTRUCTLIT:
+		case OMAPLIT:
+			// copy pointer
+			gdata(l, nod(OADDR, r->nname, N), l->type->width);
+			return 1;
+		}
+		break;
+
+	case OARRAYLIT:
+		if(isslice(r->type)) {
+			// copy slice
+			a = r->nname;
+			n1 = *l;
+			n1.xoffset = l->xoffset + Array_array;
+			gdata(&n1, nod(OADDR, a, N), widthptr);
+			n1.xoffset = l->xoffset + Array_nel;
+			gdata(&n1, r->right, widthint);
+			n1.xoffset = l->xoffset + Array_cap;
+			gdata(&n1, r->right, widthint);
+			return 1;
+		}
+		// fall through
+	case OSTRUCTLIT:
+		p = r->initplan;
+		n1 = *l;
+		for(i=0; i<p->len; i++) {
+			e = &p->e[i];
+			n1.xoffset = l->xoffset + e->xoffset;
+			n1.type = e->expr->type;
+			if(e->expr->op == OLITERAL)
+				gdata(&n1, e->expr, n1.type->width);
+			else {
+				ll = nod(OXXX, N, N);
+				*ll = n1;
+				ll->orig = ll; // completely separate copy
+				if(!staticassign(ll, e->expr, out)) {
+					// Requires computation, but we're
+					// copying someone else's computation.
+					rr = nod(OXXX, N, N);
+					*rr = *orig;
+					rr->orig = rr; // completely separate copy
+					rr->type = ll->type;
+					rr->xoffset += e->xoffset;
+					*out = list(*out, nod(OAS, ll, rr));
+				}
+			}
+		}
+		return 1;
+	}
+	return 0;
+}
+
+static int
+staticassign(Node *l, Node *r, NodeList **out)
+{
+	Node *a, n1;
+	Type *ta;
+	InitPlan *p;
+	InitEntry *e;
+	int i;
+	Strlit *sval;
+	
+	switch(r->op) {
+	default:
+		//dump("not static", r);
+		break;
+	
+	case ONAME:
+		if(r->class == PEXTERN && r->sym->pkg == localpkg)
+			return staticcopy(l, r, out);
+		break;
+
+	case OLITERAL:
+		if(iszero(r))
+			return 1;
+		gdata(l, r, l->type->width);
+		return 1;
+
+	case OADDR:
+		switch(r->left->op) {
+		default:
+			//dump("not static addr", r);
+			break;
+
+		case ONAME:
+			gdata(l, r, l->type->width);
+			return 1;
+		}
+	
+	case OPTRLIT:
+		switch(r->left->op) {
+		default:
+			//dump("not static ptrlit", r);
+			break;
+
+		case OARRAYLIT:
+		case OMAPLIT:
+		case OSTRUCTLIT:
+			// Init pointer.
+			a = staticname(r->left->type, 1);
+			r->nname = a;
+			gdata(l, nod(OADDR, a, N), l->type->width);
+			// Init underlying literal.
+			if(!staticassign(a, r->left, out))
+				*out = list(*out, nod(OAS, a, r->left));
+			return 1;
+		}
+		break;
+
+	case OSTRARRAYBYTE:
+		if(l->class == PEXTERN && r->left->op == OLITERAL) {
+			sval = r->left->val.u.sval;
+			slicebytes(l, sval->s, sval->len);
+			return 1;
+		}
+		break;
+
+	case OARRAYLIT:
+		initplan(r);
+		if(isslice(r->type)) {
+			// Init slice.
+			ta = typ(TARRAY);
+			ta->type = r->type->type;
+			ta->bound = mpgetfix(r->right->val.u.xval);
+			a = staticname(ta, 1);
+			r->nname = a;
+			n1 = *l;
+			n1.xoffset = l->xoffset + Array_array;
+			gdata(&n1, nod(OADDR, a, N), widthptr);
+			n1.xoffset = l->xoffset + Array_nel;
+			gdata(&n1, r->right, widthint);
+			n1.xoffset = l->xoffset + Array_cap;
+			gdata(&n1, r->right, widthint);
+			// Fall through to init underlying array.
+			l = a;
+		}
+		// fall through
+	case OSTRUCTLIT:
+		initplan(r);
+		p = r->initplan;
+		n1 = *l;
+		for(i=0; i<p->len; i++) {
+			e = &p->e[i];
+			n1.xoffset = l->xoffset + e->xoffset;
+			n1.type = e->expr->type;
+			if(e->expr->op == OLITERAL)
+				gdata(&n1, e->expr, n1.type->width);
+			else {
+				a = nod(OXXX, N, N);
+				*a = n1;
+				a->orig = a; // completely separate copy
+				if(!staticassign(a, e->expr, out))
+					*out = list(*out, nod(OAS, a, e->expr));
+			}
+		}
+		return 1;
+
+	case OMAPLIT:
+		// TODO: Table-driven map insert.
+		break;
+	}
+	return 0;
+}
+
+/*
+ * from here down is the walk analysis
+ * of composite literals.
+ * most of the work is to generate
+ * data statements for the constant
+ * part of the composite literal.
+ */
+
+static	void	structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init);
+static	void	arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init);
+static	void	slicelit(int ctxt, Node *n, Node *var, NodeList **init);
+static	void	maplit(int ctxt, Node *n, Node *var, NodeList **init);
+
+static Node*
+staticname(Type *t, int ctxt)
+{
+	Node *n;
+
+	snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen);
+	statuniqgen++;
+	n = newname(lookup(namebuf));
+	if(!ctxt)
+		n->readonly = 1;
+	addvar(n, t, PEXTERN);
+	return n;
+}
+
+static int
+isliteral(Node *n)
+{
+	if(n->op == OLITERAL)
+		if(n->val.ctype != CTNIL)
+			return 1;
+	return 0;
+}
+
+static int
+simplename(Node *n)
+{
+	if(n->op != ONAME)
+		goto no;
+	if(!n->addable)
+		goto no;
+	if(n->class & PHEAP)
+		goto no;
+	if(n->class == PPARAMREF)
+		goto no;
+	return 1;
+
+no:
+	return 0;
+}
+
+static void
+litas(Node *l, Node *r, NodeList **init)
+{
+	Node *a;
+
+	a = nod(OAS, l, r);
+	typecheck(&a, Etop);
+	walkexpr(&a, init);
+	*init = list(*init, a);
+}
+
+enum
+{
+	MODEDYNAM	= 1,
+	MODECONST	= 2,
+};
+
+static int
+getdyn(Node *n, int top)
+{
+	NodeList *nl;
+	Node *value;
+	int mode;
+
+	mode = 0;
+	switch(n->op) {
+	default:
+		if(isliteral(n))
+			return MODECONST;
+		return MODEDYNAM;
+	case OARRAYLIT:
+		if(!top && n->type->bound < 0)
+			return MODEDYNAM;
+	case OSTRUCTLIT:
+		break;
+	}
+
+	for(nl=n->list; nl; nl=nl->next) {
+		value = nl->n->right;
+		mode |= getdyn(value, 0);
+		if(mode == (MODEDYNAM|MODECONST))
+			break;
+	}
+	return mode;
+}
+
+static void
+structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
+{
+	Node *r, *a;
+	NodeList *nl;
+	Node *index, *value;
+
+	for(nl=n->list; nl; nl=nl->next) {
+		r = nl->n;
+		if(r->op != OKEY)
+			fatal("structlit: rhs not OKEY: %N", r);
+		index = r->left;
+		value = r->right;
+
+		switch(value->op) {
+		case OARRAYLIT:
+			if(value->type->bound < 0) {
+				if(pass == 1 && ctxt != 0) {
+					a = nod(ODOT, var, newname(index->sym));
+					slicelit(ctxt, value, a, init);
+				} else
+				if(pass == 2 && ctxt == 0) {
+					a = nod(ODOT, var, newname(index->sym));
+					slicelit(ctxt, value, a, init);
+				} else
+				if(pass == 3)
+					break;
+				continue;
+			}
+			a = nod(ODOT, var, newname(index->sym));
+			arraylit(ctxt, pass, value, a, init);
+			continue;
+
+		case OSTRUCTLIT:
+			a = nod(ODOT, var, newname(index->sym));
+			structlit(ctxt, pass, value, a, init);
+			continue;
+		}
+
+		if(isliteral(value)) {
+			if(pass == 2)
+				continue;
+		} else
+			if(pass == 1)
+				continue;
+
+		// build list of var.field = expr
+		a = nod(ODOT, var, newname(index->sym));
+		a = nod(OAS, a, value);
+		typecheck(&a, Etop);
+		if(pass == 1) {
+			walkexpr(&a, init);	// add any assignments in r to top
+			if(a->op != OAS)
+				fatal("structlit: not as");
+			a->dodata = 2;
+		} else {
+			orderstmtinplace(&a);
+			walkstmt(&a);
+		}
+		*init = list(*init, a);
+	}
+}
+
+static void
+arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
+{
+	Node *r, *a;
+	NodeList *l;
+	Node *index, *value;
+
+	for(l=n->list; l; l=l->next) {
+		r = l->n;
+		if(r->op != OKEY)
+			fatal("arraylit: rhs not OKEY: %N", r);
+		index = r->left;
+		value = r->right;
+
+		switch(value->op) {
+		case OARRAYLIT:
+			if(value->type->bound < 0) {
+				if(pass == 1 && ctxt != 0) {
+					a = nod(OINDEX, var, index);
+					slicelit(ctxt, value, a, init);
+				} else
+				if(pass == 2 && ctxt == 0) {
+					a = nod(OINDEX, var, index);
+					slicelit(ctxt, value, a, init);
+				} else
+				if(pass == 3)
+					break;
+				continue;
+			}
+			a = nod(OINDEX, var, index);
+			arraylit(ctxt, pass, value, a, init);
+			continue;
+
+		case OSTRUCTLIT:
+			a = nod(OINDEX, var, index);
+			structlit(ctxt, pass, value, a, init);
+			continue;
+		}
+
+		if(isliteral(index) && isliteral(value)) {
+			if(pass == 2)
+				continue;
+		} else
+			if(pass == 1)
+				continue;
+
+		// build list of var[index] = value
+		a = nod(OINDEX, var, index);
+		a = nod(OAS, a, value);
+		typecheck(&a, Etop);
+		if(pass == 1) {
+			walkexpr(&a, init);
+			if(a->op != OAS)
+				fatal("arraylit: not as");
+			a->dodata = 2;
+		} else {
+			orderstmtinplace(&a);
+			walkstmt(&a);
+		}
+		*init = list(*init, a);
+	}
+}
+
+static void
+slicelit(int ctxt, Node *n, Node *var, NodeList **init)
+{
+	Node *r, *a;
+	NodeList *l;
+	Type *t;
+	Node *vstat, *vauto;
+	Node *index, *value;
+	int mode;
+
+	// make an array type
+	t = shallow(n->type);
+	t->bound = mpgetfix(n->right->val.u.xval);
+	t->width = 0;
+	t->sym = nil;
+	t->haspointers = 0;
+	dowidth(t);
+
+	if(ctxt != 0) {
+		// put everything into static array
+		vstat = staticname(t, ctxt);
+		arraylit(ctxt, 1, n, vstat, init);
+		arraylit(ctxt, 2, n, vstat, init);
+
+		// copy static to slice
+		a = nod(OSLICE, vstat, nod(OKEY, N, N));
+		a = nod(OAS, var, a);
+		typecheck(&a, Etop);
+		a->dodata = 2;
+		*init = list(*init, a);
+		return;
+	}
+
+	// recipe for var = []t{...}
+	// 1. make a static array
+	//	var vstat [...]t
+	// 2. assign (data statements) the constant part
+	//	vstat = constpart{}
+	// 3. make an auto pointer to array and allocate heap to it
+	//	var vauto *[...]t = new([...]t)
+	// 4. copy the static array to the auto array
+	//	*vauto = vstat
+	// 5. assign slice of allocated heap to var
+	//	var = [0:]*auto
+	// 6. for each dynamic part assign to the slice
+	//	var[i] = dynamic part
+	//
+	// an optimization is done if there is no constant part
+	//	3. var vauto *[...]t = new([...]t)
+	//	5. var = [0:]*auto
+	//	6. var[i] = dynamic part
+
+	// if the literal contains constants,
+	// make static initialized array (1),(2)
+	vstat = N;
+	mode = getdyn(n, 1);
+	if(mode & MODECONST) {
+		vstat = staticname(t, ctxt);
+		arraylit(ctxt, 1, n, vstat, init);
+	}
+
+	// make new auto *array (3 declare)
+	vauto = temp(ptrto(t));
+
+	// set auto to point at new temp or heap (3 assign)
+	if(n->alloc != N) {
+		// temp allocated during order.c for dddarg
+		n->alloc->type = t;
+		if(vstat == N) {
+			a = nod(OAS, n->alloc, N);
+			typecheck(&a, Etop);
+			*init = list(*init, a);  // zero new temp
+		}
+		a = nod(OADDR, n->alloc, N);
+	} else if(n->esc == EscNone) {
+		a = temp(t);
+		if(vstat == N) {
+			a = nod(OAS, temp(t), N);
+			typecheck(&a, Etop);
+			*init = list(*init, a);  // zero new temp
+			a = a->left;
+		}
+		a = nod(OADDR, a, N);
+	} else {
+		a = nod(ONEW, N, N);
+		a->list = list1(typenod(t));
+	}
+	a = nod(OAS, vauto, a);
+	typecheck(&a, Etop);
+	walkexpr(&a, init);
+	*init = list(*init, a);
+
+	if(vstat != N) {
+		// copy static to heap (4)
+		a = nod(OIND, vauto, N);
+		a = nod(OAS, a, vstat);
+		typecheck(&a, Etop);
+		walkexpr(&a, init);
+		*init = list(*init, a);
+	}
+
+	// make slice out of heap (5)
+	a = nod(OAS, var, nod(OSLICE, vauto, nod(OKEY, N, N)));
+	typecheck(&a, Etop);
+	orderstmtinplace(&a);
+	walkstmt(&a);
+	*init = list(*init, a);
+
+	// put dynamics into slice (6)
+	for(l=n->list; l; l=l->next) {
+		r = l->n;
+		if(r->op != OKEY)
+			fatal("slicelit: rhs not OKEY: %N", r);
+		index = r->left;
+		value = r->right;
+		a = nod(OINDEX, var, index);
+		a->bounded = 1;
+		// TODO need to check bounds?
+
+		switch(value->op) {
+		case OARRAYLIT:
+			if(value->type->bound < 0)
+				break;
+			arraylit(ctxt, 2, value, a, init);
+			continue;
+
+		case OSTRUCTLIT:
+			structlit(ctxt, 2, value, a, init);
+			continue;
+		}
+
+		if(isliteral(index) && isliteral(value))
+			continue;
+
+		// build list of var[c] = expr
+		a = nod(OAS, a, value);
+		typecheck(&a, Etop);
+		orderstmtinplace(&a);
+		walkstmt(&a);
+		*init = list(*init, a);
+	}
+}
+
+static void
+maplit(int ctxt, Node *n, Node *var, NodeList **init)
+{
+	Node *r, *a;
+	NodeList *l;
+	int nerr;
+	int64 b;
+	Type *t, *tk, *tv, *t1;
+	Node *vstat, *index, *value, *key, *val;
+	Sym *syma, *symb;
+
+USED(ctxt);
+ctxt = 0;
+
+	// make the map var
+	nerr = nerrors;
+
+	a = nod(OMAKE, N, N);
+	a->list = list1(typenod(n->type));
+	litas(var, a, init);
+
+	// count the initializers
+	b = 0;
+	for(l=n->list; l; l=l->next) {
+		r = l->n;
+
+		if(r->op != OKEY)
+			fatal("maplit: rhs not OKEY: %N", r);
+		index = r->left;
+		value = r->right;
+
+		if(isliteral(index) && isliteral(value))
+			b++;
+	}
+
+	if(b != 0) {
+		// build type [count]struct { a Tindex, b Tvalue }
+		t = n->type;
+		tk = t->down;
+		tv = t->type;
+
+		symb = lookup("b");
+		t = typ(TFIELD);
+		t->type = tv;
+		t->sym = symb;
+
+		syma = lookup("a");
+		t1 = t;
+		t = typ(TFIELD);
+		t->type = tk;
+		t->sym = syma;
+		t->down = t1;
+
+		t1 = t;
+		t = typ(TSTRUCT);
+		t->type = t1;
+
+		t1 = t;
+		t = typ(TARRAY);
+		t->bound = b;
+		t->type = t1;
+
+		dowidth(t);
+
+		// make and initialize static array
+		vstat = staticname(t, ctxt);
+		b = 0;
+		for(l=n->list; l; l=l->next) {
+			r = l->n;
+
+			if(r->op != OKEY)
+				fatal("maplit: rhs not OKEY: %N", r);
+			index = r->left;
+			value = r->right;
+
+			if(isliteral(index) && isliteral(value)) {
+				// build vstat[b].a = key;
+				a = nodintconst(b);
+				a = nod(OINDEX, vstat, a);
+				a = nod(ODOT, a, newname(syma));
+				a = nod(OAS, a, index);
+				typecheck(&a, Etop);
+				walkexpr(&a, init);
+				a->dodata = 2;
+				*init = list(*init, a);
+
+				// build vstat[b].b = value;
+				a = nodintconst(b);
+				a = nod(OINDEX, vstat, a);
+				a = nod(ODOT, a, newname(symb));
+				a = nod(OAS, a, value);
+				typecheck(&a, Etop);
+				walkexpr(&a, init);
+				a->dodata = 2;
+				*init = list(*init, a);
+
+				b++;
+			}
+		}
+
+		// loop adding structure elements to map
+		// for i = 0; i < len(vstat); i++ {
+		//	map[vstat[i].a] = vstat[i].b
+		// }
+		index = temp(types[TINT]);
+
+		a = nod(OINDEX, vstat, index);
+		a->bounded = 1;
+		a = nod(ODOT, a, newname(symb));
+
+		r = nod(OINDEX, vstat, index);
+		r->bounded = 1;
+		r = nod(ODOT, r, newname(syma));
+		r = nod(OINDEX, var, r);
+
+		r = nod(OAS, r, a);
+
+		a = nod(OFOR, N, N);
+		a->nbody = list1(r);
+
+		a->ninit = list1(nod(OAS, index, nodintconst(0)));
+		a->ntest = nod(OLT, index, nodintconst(t->bound));
+		a->nincr = nod(OAS, index, nod(OADD, index, nodintconst(1)));
+
+		typecheck(&a, Etop);
+		walkstmt(&a);
+		*init = list(*init, a);
+	}
+
+	// put in dynamic entries one-at-a-time
+	key = nil;
+	val = nil;
+	for(l=n->list; l; l=l->next) {
+		r = l->n;
+
+		if(r->op != OKEY)
+			fatal("maplit: rhs not OKEY: %N", r);
+		index = r->left;
+		value = r->right;
+
+		if(isliteral(index) && isliteral(value))
+			continue;
+			
+		// build list of var[c] = expr.
+		// use temporary so that mapassign1 can have addressable key, val.
+		if(key == nil) {
+			key = temp(var->type->down);
+			val = temp(var->type->type);
+		}
+		a = nod(OAS, key, r->left);
+		typecheck(&a, Etop);
+		walkstmt(&a);
+		*init = list(*init, a);
+		a = nod(OAS, val, r->right);
+		typecheck(&a, Etop);
+		walkstmt(&a);
+		*init = list(*init, a);
+
+		a = nod(OAS, nod(OINDEX, var, key), val);
+		typecheck(&a, Etop);
+		walkstmt(&a);
+		*init = list(*init, a);
+
+		if(nerr != nerrors)
+			break;
+	}
+	
+	if(key != nil) {
+		a = nod(OVARKILL, key, N);
+		typecheck(&a, Etop);
+		*init = list(*init, a);
+		a = nod(OVARKILL, val, N);
+		typecheck(&a, Etop);
+		*init = list(*init, a);
+	}
+}
+
+void
+anylit(int ctxt, Node *n, Node *var, NodeList **init)
+{
+	Type *t;
+	Node *a, *vstat, *r;
+
+	t = n->type;
+	switch(n->op) {
+	default:
+		fatal("anylit: not lit");
+
+	case OPTRLIT:
+		if(!isptr[t->etype])
+			fatal("anylit: not ptr");
+
+		if(n->right != N) {
+			r = nod(OADDR, n->right, N);
+			typecheck(&r, Erv);
+		} else {
+			r = nod(ONEW, N, N);
+			r->typecheck = 1;
+			r->type = t;
+			r->esc = n->esc;
+		}
+		walkexpr(&r, init);
+		a = nod(OAS, var, r);
+
+		typecheck(&a, Etop);
+		*init = list(*init, a);
+
+		var = nod(OIND, var, N);
+		typecheck(&var, Erv | Easgn);
+		anylit(ctxt, n->left, var, init);
+		break;
+
+	case OSTRUCTLIT:
+		if(t->etype != TSTRUCT)
+			fatal("anylit: not struct");
+
+		if(simplename(var) && count(n->list) > 4) {
+
+			if(ctxt == 0) {
+				// lay out static data
+				vstat = staticname(t, ctxt);
+				structlit(ctxt, 1, n, vstat, init);
+
+				// copy static to var
+				a = nod(OAS, var, vstat);
+				typecheck(&a, Etop);
+				walkexpr(&a, init);
+				*init = list(*init, a);
+
+				// add expressions to automatic
+				structlit(ctxt, 2, n, var, init);
+				break;
+			}
+			structlit(ctxt, 1, n, var, init);
+			structlit(ctxt, 2, n, var, init);
+			break;
+		}
+
+		// initialize of not completely specified
+		if(simplename(var) || count(n->list) < structcount(t)) {
+			a = nod(OAS, var, N);
+			typecheck(&a, Etop);
+			walkexpr(&a, init);
+			*init = list(*init, a);
+		}
+		structlit(ctxt, 3, n, var, init);
+		break;
+
+	case OARRAYLIT:
+		if(t->etype != TARRAY)
+			fatal("anylit: not array");
+		if(t->bound < 0) {
+			slicelit(ctxt, n, var, init);
+			break;
+		}
+
+		if(simplename(var) && count(n->list) > 4) {
+
+			if(ctxt == 0) {
+				// lay out static data
+				vstat = staticname(t, ctxt);
+				arraylit(1, 1, n, vstat, init);
+
+				// copy static to automatic
+				a = nod(OAS, var, vstat);
+				typecheck(&a, Etop);
+				walkexpr(&a, init);
+				*init = list(*init, a);
+
+				// add expressions to automatic
+				arraylit(ctxt, 2, n, var, init);
+				break;
+			}
+			arraylit(ctxt, 1, n, var, init);
+			arraylit(ctxt, 2, n, var, init);
+			break;
+		}
+
+		// initialize of not completely specified
+		if(simplename(var) || count(n->list) < t->bound) {
+			a = nod(OAS, var, N);
+			typecheck(&a, Etop);
+			walkexpr(&a, init);
+			*init = list(*init, a);
+		}
+		arraylit(ctxt, 3, n, var, init);
+		break;
+
+	case OMAPLIT:
+		if(t->etype != TMAP)
+			fatal("anylit: not map");
+		maplit(ctxt, n, var, init);
+		break;
+	}
+}
+
+int
+oaslit(Node *n, NodeList **init)
+{
+	int ctxt;
+
+	if(n->left == N || n->right == N)
+		goto no;
+	if(n->left->type == T || n->right->type == T)
+		goto no;
+	if(!simplename(n->left))
+		goto no;
+	if(!eqtype(n->left->type, n->right->type))
+		goto no;
+
+	// context is init() function.
+	// implies generated data executed
+	// exactly once and not subject to races.
+	ctxt = 0;
+//	if(n->dodata == 1)
+//		ctxt = 1;
+
+	switch(n->right->op) {
+	default:
+		goto no;
+
+	case OSTRUCTLIT:
+	case OARRAYLIT:
+	case OMAPLIT:
+		if(vmatch1(n->left, n->right))
+			goto no;
+		anylit(ctxt, n->right, n->left, init);
+		break;
+	}
+	n->op = OEMPTY;
+	return 1;
+
+no:
+	// not a special composit literal assignment
+	return 0;
+}
+
+static int
+getlit(Node *lit)
+{
+	if(smallintconst(lit))
+		return mpgetfix(lit->val.u.xval);
+	return -1;
+}
+
+int
+stataddr(Node *nam, Node *n)
+{
+	int l;
+
+	if(n == N)
+		goto no;
+
+	switch(n->op) {
+
+	case ONAME:
+		*nam = *n;
+		return n->addable;
+
+	case ODOT:
+		if(!stataddr(nam, n->left))
+			break;
+		nam->xoffset += n->xoffset;
+		nam->type = n->type;
+		return 1;
+
+	case OINDEX:
+		if(n->left->type->bound < 0)
+			break;
+		if(!stataddr(nam, n->left))
+			break;
+		l = getlit(n->right);
+		if(l < 0)
+			break;
+		// Check for overflow.
+		if(n->type->width != 0 && MAXWIDTH/n->type->width <= l)
+			break;
+ 		nam->xoffset += l*n->type->width;
+		nam->type = n->type;
+		return 1;
+	}
+
+no:
+	return 0;
+}
+
+int
+gen_as_init(Node *n)
+{
+	Node *nr, *nl;
+	Node nam, nod1;
+
+	if(n->dodata == 0)
+		goto no;
+
+	nr = n->right;
+	nl = n->left;
+	if(nr == N) {
+		if(!stataddr(&nam, nl))
+			goto no;
+		if(nam.class != PEXTERN)
+			goto no;
+		goto yes;
+	}
+
+	if(nr->type == T || !eqtype(nl->type, nr->type))
+		goto no;
+
+	if(!stataddr(&nam, nl))
+		goto no;
+
+	if(nam.class != PEXTERN)
+		goto no;
+
+	switch(nr->op) {
+	default:
+		goto no;
+
+	case OCONVNOP:
+		nr = nr->left;
+		if(nr == N || nr->op != OSLICEARR)
+			goto no;
+		// fall through
+	
+	case OSLICEARR:
+		if(nr->right->op == OKEY && nr->right->left == N && nr->right->right == N) {
+			nr = nr->left;
+			goto slice;
+		}
+		goto no;
+
+	case OLITERAL:
+		break;
+	}
+
+	switch(nr->type->etype) {
+	default:
+		goto no;
+
+	case TBOOL:
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TINT:
+	case TUINT:
+	case TUINTPTR:
+	case TPTR32:
+	case TPTR64:
+	case TFLOAT32:
+	case TFLOAT64:
+		gdata(&nam, nr, nr->type->width);
+		break;
+
+	case TCOMPLEX64:
+	case TCOMPLEX128:
+		gdatacomplex(&nam, nr->val.u.cval);
+		break;
+
+	case TSTRING:
+		gdatastring(&nam, nr->val.u.sval);
+		break;
+	}
+
+yes:
+	return 1;
+
+slice:
+	gused(N); // in case the data is the dest of a goto
+	nl = nr;
+	if(nr == N || nr->op != OADDR)
+		goto no;
+	nr = nr->left;
+	if(nr == N || nr->op != ONAME)
+		goto no;
+
+	// nr is the array being converted to a slice
+	if(nr->type == T || nr->type->etype != TARRAY || nr->type->bound < 0)
+		goto no;
+
+	nam.xoffset += Array_array;
+	gdata(&nam, nl, types[tptr]->width);
+
+	nam.xoffset += Array_nel-Array_array;
+	nodconst(&nod1, types[TINT], nr->type->bound);
+	gdata(&nam, &nod1, widthint);
+
+	nam.xoffset += Array_cap-Array_nel;
+	gdata(&nam, &nod1, widthint);
+
+	goto yes;
+
+no:
+	if(n->dodata == 2) {
+		dump("\ngen_as_init", n);
+		fatal("gen_as_init couldnt make data statement");
+	}
+	return 0;
+}
+
+static int isvaluelit(Node*);
+static InitEntry* entry(InitPlan*);
+static void addvalue(InitPlan*, vlong, Node*, Node*);
+
+static void
+initplan(Node *n)
+{
+	InitPlan *p;
+	Node *a;
+	NodeList *l;
+
+	if(n->initplan != nil)
+		return;
+	p = mal(sizeof *p);
+	n->initplan = p;
+	switch(n->op) {
+	default:
+		fatal("initplan");
+	case OARRAYLIT:
+		for(l=n->list; l; l=l->next) {
+			a = l->n;
+			if(a->op != OKEY || !smallintconst(a->left))
+				fatal("initplan arraylit");
+			addvalue(p, n->type->type->width*mpgetfix(a->left->val.u.xval), N, a->right);
+		}
+		break;
+	case OSTRUCTLIT:
+		for(l=n->list; l; l=l->next) {
+			a = l->n;
+			if(a->op != OKEY || a->left->type == T)
+				fatal("initplan structlit");
+			addvalue(p, a->left->type->width, N, a->right);
+		}
+		break;
+	case OMAPLIT:
+		for(l=n->list; l; l=l->next) {
+			a = l->n;
+			if(a->op != OKEY)
+				fatal("initplan maplit");
+			addvalue(p, -1, a->left, a->right);
+		}
+		break;
+	}
+}
+
+static void
+addvalue(InitPlan *p, vlong xoffset, Node *key, Node *n)
+{
+	int i;
+	InitPlan *q;
+	InitEntry *e;
+
+	USED(key);
+
+	// special case: zero can be dropped entirely
+	if(iszero(n)) {
+		p->zero += n->type->width;
+		return;
+	}
+	
+	// special case: inline struct and array (not slice) literals
+	if(isvaluelit(n)) {
+		initplan(n);
+		q = n->initplan;
+		for(i=0; i<q->len; i++) {
+			e = entry(p);
+			*e = q->e[i];
+			e->xoffset += xoffset;
+		}
+		return;
+	}
+	
+	// add to plan
+	if(n->op == OLITERAL)
+		p->lit += n->type->width;
+	else
+		p->expr += n->type->width;
+
+	e = entry(p);
+	e->xoffset = xoffset;
+	e->expr = n;
+}
+
+int
+iszero(Node *n)
+{
+	NodeList *l;
+
+	switch(n->op) {
+	case OLITERAL:
+		switch(n->val.ctype) {
+		default:
+			dump("unexpected literal", n);
+			fatal("iszero");
+	
+		case CTNIL:
+			return 1;
+		
+		case CTSTR:
+			return n->val.u.sval == nil || n->val.u.sval->len == 0;
+	
+		case CTBOOL:
+			return n->val.u.bval == 0;
+			
+		case CTINT:
+		case CTRUNE:
+			return mpcmpfixc(n->val.u.xval, 0) == 0;
+	
+		case CTFLT:
+			return mpcmpfltc(n->val.u.fval, 0) == 0;
+	
+		case CTCPLX:
+			return mpcmpfltc(&n->val.u.cval->real, 0) == 0 && mpcmpfltc(&n->val.u.cval->imag, 0) == 0;
+		}
+		break;
+	case OARRAYLIT:
+		if(isslice(n->type))
+			break;
+		// fall through
+	case OSTRUCTLIT:
+		for(l=n->list; l; l=l->next)
+			if(!iszero(l->n->right))
+				return 0;
+		return 1;
+	}
+	return 0;
+}
+
+static int
+isvaluelit(Node *n)
+{
+	return (n->op == OARRAYLIT && isfixedarray(n->type)) || n->op == OSTRUCTLIT;
+}
+
+static InitEntry*
+entry(InitPlan *p)
+{
+	if(p->len >= p->cap) {
+		if(p->cap == 0)
+			p->cap = 4;
+		else
+			p->cap *= 2;
+		p->e = realloc(p->e, p->cap*sizeof p->e[0]);
+		if(p->e == nil)
+			fatal("out of memory");
+	}
+	return &p->e[p->len++];
+}
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
new file mode 100644
index 0000000..26153d3
--- /dev/null
+++ b/src/cmd/gc/subr.c
@@ -0,0 +1,3849 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"md5.h"
+#include	"y.tab.h"
+#include	"yerr.h"
+
+typedef struct Error Error;
+struct Error
+{
+	int lineno;
+	int seq;
+	char *msg;
+};
+static Error *err;
+static int nerr;
+static int merr;
+
+void
+errorexit(void)
+{
+	flusherrors();
+	if(outfile)
+		remove(outfile);
+	exits("error");
+}
+
+extern int yychar;
+int
+parserline(void)
+{
+	if(yychar != 0 && yychar != -2)	// parser has one symbol lookahead
+		return prevlineno;
+	return lineno;
+}
+
+static void
+adderr(int line, char *fmt, va_list arg)
+{
+	Fmt f;
+	Error *p;
+
+	fmtstrinit(&f);
+	fmtprint(&f, "%L: ", line);
+	fmtvprint(&f, fmt, arg);
+	fmtprint(&f, "\n");
+
+	if(nerr >= merr) {
+		if(merr == 0)
+			merr = 16;
+		else
+			merr *= 2;
+		p = realloc(err, merr*sizeof err[0]);
+		if(p == nil) {
+			merr = nerr;
+			flusherrors();
+			print("out of memory\n");
+			errorexit();
+		}
+		err = p;
+	}
+	err[nerr].seq = nerr;
+	err[nerr].lineno = line;
+	err[nerr].msg = fmtstrflush(&f);
+	nerr++;
+}
+
+static int
+errcmp(const void *va, const void *vb)
+{
+	Error *a, *b;
+
+	a = (Error*)va;
+	b = (Error*)vb;
+	if(a->lineno != b->lineno)
+		return a->lineno - b->lineno;
+	if(a->seq != b->seq)
+		return a->seq - b->seq;
+	return strcmp(a->msg, b->msg);
+}
+
+void
+flusherrors(void)
+{
+	int i;
+
+	Bflush(&bstdout);
+	if(nerr == 0)
+		return;
+	qsort(err, nerr, sizeof err[0], errcmp);
+	for(i=0; i<nerr; i++)
+		if(i==0 || strcmp(err[i].msg, err[i-1].msg) != 0)
+			print("%s", err[i].msg);
+	nerr = 0;
+}
+
+static void
+hcrash(void)
+{
+	if(debug['h']) {
+		flusherrors();
+		if(outfile)
+			remove(outfile);
+		*(volatile int*)0 = 0;
+	}
+}
+
+void
+yyerrorl(int line, char *fmt, ...)
+{
+	va_list arg;
+
+	va_start(arg, fmt);
+	adderr(line, fmt, arg);
+	va_end(arg);
+
+	hcrash();
+	nerrors++;
+	if(nsavederrors+nerrors >= 10 && !debug['e']) {
+		flusherrors();
+		print("%L: too many errors\n", line);
+		errorexit();
+	}
+}
+
+extern int yystate, yychar;
+
+void
+yyerror(char *fmt, ...)
+{
+	int i;
+	static int lastsyntax;
+	va_list arg;
+	char buf[512], *p;
+
+	if(strncmp(fmt, "syntax error", 12) == 0) {
+		nsyntaxerrors++;
+		
+		if(debug['x'])	
+			print("yyerror: yystate=%d yychar=%d\n", yystate, yychar);
+
+		// An unexpected EOF caused a syntax error. Use the previous
+		// line number since getc generated a fake newline character.
+		if(curio.eofnl)
+			lexlineno = prevlineno;
+
+		// only one syntax error per line
+		if(lastsyntax == lexlineno)
+			return;
+		lastsyntax = lexlineno;
+			
+		if(strstr(fmt, "{ or {") || strstr(fmt, " or ?") || strstr(fmt, " or @")) {
+			// The grammar has { and LBRACE but both show up as {.
+			// Rewrite syntax error referring to "{ or {" to say just "{".
+			strecpy(buf, buf+sizeof buf, fmt);
+			p = strstr(buf, "{ or {");
+			if(p)
+				memmove(p+1, p+6, strlen(p+6)+1);
+			
+			// The grammar has ? and @ but only for reading imports.
+			// Silence them in ordinary errors.
+			p = strstr(buf, " or ?");
+			if(p)
+				memmove(p, p+5, strlen(p+5)+1);
+			p = strstr(buf, " or @");
+			if(p)
+				memmove(p, p+5, strlen(p+5)+1);
+			fmt = buf;
+		}
+		
+		// look for parse state-specific errors in list (see go.errors).
+		for(i=0; i<nelem(yymsg); i++) {
+			if(yymsg[i].yystate == yystate && yymsg[i].yychar == yychar) {
+				yyerrorl(lexlineno, "syntax error: %s", yymsg[i].msg);
+				return;
+			}
+		}
+		
+		// plain "syntax error" gets "near foo" added
+		if(strcmp(fmt, "syntax error") == 0) {
+			yyerrorl(lexlineno, "syntax error near %s", lexbuf);
+			return;
+		}
+		
+		// if bison says "syntax error, more info"; print "syntax error: more info".
+		if(fmt[12] == ',') {
+			yyerrorl(lexlineno, "syntax error:%s", fmt+13);
+			return;
+		}
+
+		yyerrorl(lexlineno, "%s", fmt);
+		return;
+	}
+
+	va_start(arg, fmt);
+	adderr(parserline(), fmt, arg);
+	va_end(arg);
+
+	hcrash();
+	nerrors++;
+	if(nsavederrors+nerrors >= 10 && !debug['e']) {
+		flusherrors();
+		print("%L: too many errors\n", parserline());
+		errorexit();
+	}
+}
+
+void
+warn(char *fmt, ...)
+{
+	va_list arg;
+
+	va_start(arg, fmt);
+	adderr(parserline(), fmt, arg);
+	va_end(arg);
+
+	hcrash();
+}
+
+void
+warnl(int line, char *fmt, ...)
+{
+	va_list arg;
+
+	va_start(arg, fmt);
+	adderr(line, fmt, arg);
+	va_end(arg);
+	if(debug['m'])
+		flusherrors();
+}
+
+void
+fatal(char *fmt, ...)
+{
+	va_list arg;
+
+	flusherrors();
+
+	print("%L: internal compiler error: ", lineno);
+	va_start(arg, fmt);
+	vfprint(1, fmt, arg);
+	va_end(arg);
+	print("\n");
+	
+	// If this is a released compiler version, ask for a bug report.
+	if(strncmp(getgoversion(), "release", 7) == 0) {
+		print("\n");
+		print("Please file a bug report including a short program that triggers the error.\n");
+		print("http://code.google.com/p/go/issues/entry?template=compilerbug\n");
+	}
+	hcrash();
+	errorexit();
+}
+
+void
+linehist(char *file, int32 off, int relative)
+{
+	if(debug['i']) {
+		if(file != nil) {
+			if(off < 0)
+				print("pragma %s", file);
+			else
+			if(off > 0)
+				print("line %s", file);
+			else
+				print("import %s", file);
+		} else
+			print("end of import");
+		print(" at line %L\n", lexlineno);
+	}
+	
+	if(off < 0 && file[0] != '/' && !relative)
+		file = smprint("%s/%s", ctxt->pathname, file);
+	linklinehist(ctxt, lexlineno, file, off);
+}
+
+int32
+setlineno(Node *n)
+{
+	int32 lno;
+
+	lno = lineno;
+	if(n != N)
+	switch(n->op) {
+	case ONAME:
+	case OTYPE:
+	case OPACK:
+	case OLITERAL:
+		break;
+	default:
+		lineno = n->lineno;
+		if(lineno == 0) {
+			if(debug['K'])
+				warn("setlineno: line 0");
+			lineno = lno;
+		}
+	}
+	return lno;
+}
+
+uint32
+stringhash(char *p)
+{
+	uint32 h;
+	int c;
+
+	h = 0;
+	for(;;) {
+		c = *p++;
+		if(c == 0)
+			break;
+		h = h*PRIME1 + c;
+	}
+
+	if((int32)h < 0) {
+		h = -h;
+		if((int32)h < 0)
+			h = 0;
+	}
+	return h;
+}
+
+Sym*
+lookup(char *name)
+{
+	return pkglookup(name, localpkg);
+}
+
+Sym*
+pkglookup(char *name, Pkg *pkg)
+{
+	Sym *s;
+	uint32 h;
+	int c;
+
+	h = stringhash(name) % NHASH;
+	c = name[0];
+	for(s = hash[h]; s != S; s = s->link) {
+		if(s->name[0] != c || s->pkg != pkg)
+			continue;
+		if(strcmp(s->name, name) == 0)
+			return s;
+	}
+
+	s = mal(sizeof(*s));
+	s->name = mal(strlen(name)+1);
+	strcpy(s->name, name);
+
+	s->pkg = pkg;
+
+	s->link = hash[h];
+	hash[h] = s;
+	s->lexical = LNAME;
+
+	return s;
+}
+
+Sym*
+restrictlookup(char *name, Pkg *pkg)
+{
+	if(!exportname(name) && pkg != localpkg)
+		yyerror("cannot refer to unexported name %s.%s", pkg->name, name);
+	return pkglookup(name, pkg);
+}
+
+
+// find all the exported symbols in package opkg
+// and make them available in the current package
+void
+importdot(Pkg *opkg, Node *pack)
+{
+	Sym *s, *s1;
+	uint32 h;
+	int n;
+	char *pkgerror;
+
+	n = 0;
+	for(h=0; h<NHASH; h++) {
+		for(s = hash[h]; s != S; s = s->link) {
+			if(s->pkg != opkg)
+				continue;
+			if(s->def == N)
+				continue;
+			if(!exportname(s->name) || utfrune(s->name, 0xb7))	// 0xb7 = center dot
+				continue;
+			s1 = lookup(s->name);
+			if(s1->def != N) {
+				pkgerror = smprint("during import \"%Z\"", opkg->path);
+				redeclare(s1, pkgerror);
+				continue;
+			}
+			s1->def = s->def;
+			s1->block = s->block;
+			s1->def->pack = pack;
+			s1->origpkg = opkg;
+			n++;
+		}
+	}
+	if(n == 0) {
+		// can't possibly be used - there were no symbols
+		yyerrorl(pack->lineno, "imported and not used: \"%Z\"", opkg->path);
+	}
+}
+
+static void
+gethunk(void)
+{
+	char *h;
+	int32 nh;
+
+	nh = NHUNK;
+	if(thunk >= 10L*NHUNK)
+		nh = 10L*NHUNK;
+	h = (char*)malloc(nh);
+	if(h == nil) {
+		flusherrors();
+		yyerror("out of memory");
+		errorexit();
+	}
+	hunk = h;
+	nhunk = nh;
+	thunk += nh;
+}
+
+void*
+mal(int32 n)
+{
+	void *p;
+
+	if(n >= NHUNK) {
+		p = malloc(n);
+		if(p == nil) {
+			flusherrors();
+			yyerror("out of memory");
+			errorexit();
+		}
+		memset(p, 0, n);
+		return p;
+	}
+
+	while((uintptr)hunk & MAXALIGN) {
+		hunk++;
+		nhunk--;
+	}
+	if(nhunk < n)
+		gethunk();
+
+	p = hunk;
+	nhunk -= n;
+	hunk += n;
+	memset(p, 0, n);
+	return p;
+}
+
+void*
+remal(void *p, int32 on, int32 n)
+{
+	void *q;
+
+	q = (uchar*)p + on;
+	if(q != hunk || nhunk < n) {
+		if(on+n >= NHUNK) {
+			q = mal(on+n);
+			memmove(q, p, on);
+			return q;
+		}
+		if(nhunk < on+n)
+			gethunk();
+		memmove(hunk, p, on);
+		p = hunk;
+		hunk += on;
+		nhunk -= on;
+	}
+	hunk += n;
+	nhunk -= n;
+	return p;
+}
+
+Node*
+nod(int op, Node *nleft, Node *nright)
+{
+	Node *n;
+
+	n = mal(sizeof(*n));
+	n->op = op;
+	n->left = nleft;
+	n->right = nright;
+	n->lineno = parserline();
+	n->xoffset = BADWIDTH;
+	n->orig = n;
+	n->curfn = curfn;
+	return n;
+}
+
+void
+saveorignode(Node *n)
+{
+	Node *norig;
+
+	if(n->orig != N)
+		return;
+	norig = nod(n->op, N, N);
+	*norig = *n;
+	n->orig = norig;
+}
+
+// ispaddedfield reports whether the given field
+// is followed by padding. For the case where t is
+// the last field, total gives the size of the enclosing struct.
+static int
+ispaddedfield(Type *t, vlong total)
+{
+	if(t->etype != TFIELD)
+		fatal("ispaddedfield called non-field %T", t);
+	if(t->down == T)
+		return t->width + t->type->width != total;
+	return t->width + t->type->width != t->down->width;
+}
+
+int
+algtype1(Type *t, Type **bad)
+{
+	int a, ret;
+	Type *t1;
+	
+	if(bad)
+		*bad = T;
+	if(t->broke)
+		return AMEM;
+	if(t->noalg)
+		return ANOEQ;
+
+	switch(t->etype) {
+	case TANY:
+	case TFORW:
+		// will be defined later.
+		*bad = t;
+		return -1;
+
+	case TINT8:
+	case TUINT8:
+	case TINT16:
+	case TUINT16:
+	case TINT32:
+	case TUINT32:
+	case TINT64:
+	case TUINT64:
+	case TINT:
+	case TUINT:
+	case TUINTPTR:
+	case TBOOL:
+	case TPTR32:
+	case TPTR64:
+	case TCHAN:
+	case TUNSAFEPTR:
+		return AMEM;
+
+	case TFUNC:
+	case TMAP:
+		if(bad)
+			*bad = t;
+		return ANOEQ;
+
+	case TFLOAT32:
+		return AFLOAT32;
+
+	case TFLOAT64:
+		return AFLOAT64;
+
+	case TCOMPLEX64:
+		return ACPLX64;
+
+	case TCOMPLEX128:
+		return ACPLX128;
+
+	case TSTRING:
+		return ASTRING;
+	
+	case TINTER:
+		if(isnilinter(t))
+			return ANILINTER;
+		return AINTER;
+	
+	case TARRAY:
+		if(isslice(t)) {
+			if(bad)
+				*bad = t;
+			return ANOEQ;
+		}
+		a = algtype1(t->type, bad);
+		if(a == ANOEQ || a == AMEM) {
+			if(a == ANOEQ && bad)
+				*bad = t;
+			return a;
+		}
+		return -1;  // needs special compare
+
+	case TSTRUCT:
+		if(t->type != T && t->type->down == T && !isblanksym(t->type->sym)) {
+			// One-field struct is same as that one field alone.
+			return algtype1(t->type->type, bad);
+		}
+		ret = AMEM;
+		for(t1=t->type; t1!=T; t1=t1->down) {
+			// All fields must be comparable.
+			a = algtype1(t1->type, bad);
+			if(a == ANOEQ)
+				return ANOEQ;
+
+			// Blank fields, padded fields, fields with non-memory
+			// equality need special compare.
+			if(a != AMEM || isblanksym(t1->sym) || ispaddedfield(t1, t->width)) {
+				ret = -1;
+				continue;
+			}
+		}
+		return ret;
+	}
+
+	fatal("algtype1: unexpected type %T", t);
+	return 0;
+}
+
+int
+algtype(Type *t)
+{
+	int a;
+	
+	a = algtype1(t, nil);
+	if(a == AMEM || a == ANOEQ) {
+		if(isslice(t))
+			return ASLICE;
+		switch(t->width) {
+		case 0:
+			return a + AMEM0 - AMEM;
+		case 1:
+			return a + AMEM8 - AMEM;
+		case 2:
+			return a + AMEM16 - AMEM;
+		case 4:
+			return a + AMEM32 - AMEM;
+		case 8:
+			return a + AMEM64 - AMEM;
+		case 16:
+			return a + AMEM128 - AMEM;
+		}
+	}
+	return a;
+}
+
+Type*
+maptype(Type *key, Type *val)
+{
+	Type *t;
+	Type *bad;
+	int atype, mtype;
+
+	if(key != nil) {
+		atype = algtype1(key, &bad);
+		if(bad == T)
+			mtype = key->etype;
+		else
+			mtype = bad->etype;
+		switch(mtype) {
+		default:
+			if(atype == ANOEQ)
+				yyerror("invalid map key type %T", key);
+			break;
+		case TANY:
+			// will be resolved later.
+			break;
+		case TFORW:
+			// map[key] used during definition of key.
+			// postpone check until key is fully defined.
+			// if there are multiple uses of map[key]
+			// before key is fully defined, the error
+			// will only be printed for the first one.
+			// good enough.
+			if(key->maplineno == 0)
+				key->maplineno = lineno;
+			break;
+		}
+	}
+	t = typ(TMAP);
+	t->down = key;
+	t->type = val;
+	return t;
+}
+
+Type*
+typ(int et)
+{
+	Type *t;
+
+	t = mal(sizeof(*t));
+	t->etype = et;
+	t->width = BADWIDTH;
+	t->lineno = lineno;
+	t->orig = t;
+	return t;
+}
+
+static int
+methcmp(const void *va, const void *vb)
+{
+	Type *a, *b;
+	int i;
+	
+	a = *(Type**)va;
+	b = *(Type**)vb;
+	if(a->sym == S && b->sym == S)
+		return 0;
+	if(a->sym == S)
+		return -1;
+	if(b->sym == S)
+		return 1;
+	i = strcmp(a->sym->name, b->sym->name);
+	if(i != 0)
+		return i;
+	if(!exportname(a->sym->name)) {
+		i = strcmp(a->sym->pkg->path->s, b->sym->pkg->path->s);
+		if(i != 0)
+			return i;
+	}
+	return 0;
+}
+
+Type*
+sortinter(Type *t)
+{
+	Type *f;
+	int i;
+	Type **a;
+	
+	if(t->type == nil || t->type->down == nil)
+		return t;
+
+	i=0;
+	for(f=t->type; f; f=f->down)
+		i++;
+	a = mal(i*sizeof f);
+	i = 0;
+	for(f=t->type; f; f=f->down)
+		a[i++] = f;
+	qsort(a, i, sizeof a[0], methcmp);
+	while(i-- > 0) {
+		a[i]->down = f;
+		f = a[i];
+	}
+	t->type = f;
+	return t;
+}
+
+Node*
+nodintconst(int64 v)
+{
+	Node *c;
+
+	c = nod(OLITERAL, N, N);
+	c->addable = 1;
+	c->val.u.xval = mal(sizeof(*c->val.u.xval));
+	mpmovecfix(c->val.u.xval, v);
+	c->val.ctype = CTINT;
+	c->type = types[TIDEAL];
+	ullmancalc(c);
+	return c;
+}
+
+Node*
+nodfltconst(Mpflt* v)
+{
+	Node *c;
+
+	c = nod(OLITERAL, N, N);
+	c->addable = 1;
+	c->val.u.fval = mal(sizeof(*c->val.u.fval));
+	mpmovefltflt(c->val.u.fval, v);
+	c->val.ctype = CTFLT;
+	c->type = types[TIDEAL];
+	ullmancalc(c);
+	return c;
+}
+
+void
+nodconst(Node *n, Type *t, int64 v)
+{
+	memset(n, 0, sizeof(*n));
+	n->op = OLITERAL;
+	n->addable = 1;
+	ullmancalc(n);
+	n->val.u.xval = mal(sizeof(*n->val.u.xval));
+	mpmovecfix(n->val.u.xval, v);
+	n->val.ctype = CTINT;
+	n->type = t;
+
+	if(isfloat[t->etype])
+		fatal("nodconst: bad type %T", t);
+}
+
+Node*
+nodnil(void)
+{
+	Node *c;
+
+	c = nodintconst(0);
+	c->val.ctype = CTNIL;
+	c->type = types[TNIL];
+	return c;
+}
+
+Node*
+nodbool(int b)
+{
+	Node *c;
+
+	c = nodintconst(0);
+	c->val.ctype = CTBOOL;
+	c->val.u.bval = b;
+	c->type = idealbool;
+	return c;
+}
+
+Type*
+aindex(Node *b, Type *t)
+{
+	Type *r;
+	int64 bound;
+
+	bound = -1;	// open bound
+	typecheck(&b, Erv);
+	if(b != nil) {
+		switch(consttype(b)) {
+		default:
+			yyerror("array bound must be an integer expression");
+			break;
+		case CTINT:
+		case CTRUNE:
+			bound = mpgetfix(b->val.u.xval);
+			if(bound < 0)
+				yyerror("array bound must be non negative");
+			break;
+		}
+	}
+
+	// fixed array
+	r = typ(TARRAY);
+	r->type = t;
+	r->bound = bound;
+	return r;
+}
+
+Node*
+treecopy(Node *n)
+{
+	Node *m;
+
+	if(n == N)
+		return N;
+
+	switch(n->op) {
+	default:
+		m = nod(OXXX, N, N);
+		*m = *n;
+		m->orig = m;
+		m->left = treecopy(n->left);
+		m->right = treecopy(n->right);
+		m->list = listtreecopy(n->list);
+		if(m->defn)
+			abort();
+		break;
+
+	case ONONAME:
+		if(n->sym == lookup("iota")) {
+			// Not sure yet whether this is the real iota,
+			// but make a copy of the Node* just in case,
+			// so that all the copies of this const definition
+			// don't have the same iota value.
+			m = nod(OXXX, N, N);
+			*m = *n;
+			m->iota = iota;
+			break;
+		}
+		// fall through
+	case ONAME:
+	case OLITERAL:
+	case OTYPE:
+		m = n;
+		break;
+	}
+	return m;
+}
+
+
+int
+isnil(Node *n)
+{
+	if(n == N)
+		return 0;
+	if(n->op != OLITERAL)
+		return 0;
+	if(n->val.ctype != CTNIL)
+		return 0;
+	return 1;
+}
+
+int
+isptrto(Type *t, int et)
+{
+	if(t == T)
+		return 0;
+	if(!isptr[t->etype])
+		return 0;
+	t = t->type;
+	if(t == T)
+		return 0;
+	if(t->etype != et)
+		return 0;
+	return 1;
+}
+
+int
+istype(Type *t, int et)
+{
+	return t != T && t->etype == et;
+}
+
+int
+isfixedarray(Type *t)
+{
+	return t != T && t->etype == TARRAY && t->bound >= 0;
+}
+
+int
+isslice(Type *t)
+{
+	return t != T && t->etype == TARRAY && t->bound < 0;
+}
+
+int
+isblank(Node *n)
+{
+	if(n == N)
+		return 0;
+	return isblanksym(n->sym);
+}
+
+int
+isblanksym(Sym *s)
+{
+	char *p;
+
+	if(s == S)
+		return 0;
+	p = s->name;
+	if(p == nil)
+		return 0;
+	return p[0] == '_' && p[1] == '\0';
+}
+
+int
+isinter(Type *t)
+{
+	return t != T && t->etype == TINTER;
+}
+
+int
+isnilinter(Type *t)
+{
+	if(!isinter(t))
+		return 0;
+	if(t->type != T)
+		return 0;
+	return 1;
+}
+
+int
+isideal(Type *t)
+{
+	if(t == T)
+		return 0;
+	if(t == idealstring || t == idealbool)
+		return 1;
+	switch(t->etype) {
+	case TNIL:
+	case TIDEAL:
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * given receiver of type t (t == r or t == *r)
+ * return type to hang methods off (r).
+ */
+Type*
+methtype(Type *t, int mustname)
+{
+	if(t == T)
+		return T;
+
+	// strip away pointer if it's there
+	if(isptr[t->etype]) {
+		if(t->sym != S)
+			return T;
+		t = t->type;
+		if(t == T)
+			return T;
+	}
+
+	// need a type name
+	if(t->sym == S && (mustname || t->etype != TSTRUCT))
+		return T;
+
+	// check types
+	if(!issimple[t->etype])
+	switch(t->etype) {
+	default:
+		return T;
+	case TSTRUCT:
+	case TARRAY:
+	case TMAP:
+	case TCHAN:
+	case TSTRING:
+	case TFUNC:
+		break;
+	}
+
+	return t;
+}
+
+int
+cplxsubtype(int et)
+{
+	switch(et) {
+	case TCOMPLEX64:
+		return TFLOAT32;
+	case TCOMPLEX128:
+		return TFLOAT64;
+	}
+	fatal("cplxsubtype: %E\n", et);
+	return 0;
+}
+
+static int
+eqnote(Strlit *a, Strlit *b)
+{
+	if(a == b)
+		return 1;
+	if(a == nil || b == nil)
+		return 0;
+	if(a->len != b->len)
+		return 0;
+	return memcmp(a->s, b->s, a->len) == 0;
+}
+
+typedef struct TypePairList TypePairList;
+struct TypePairList
+{
+	Type *t1;
+	Type *t2;
+	TypePairList *next;
+};
+
+static int
+onlist(TypePairList *l, Type *t1, Type *t2) 
+{
+	for(; l; l=l->next)
+		if((l->t1 == t1 && l->t2 == t2) || (l->t1 == t2 && l->t2 == t1))
+			return 1;
+	return 0;
+}
+
+static int eqtype1(Type*, Type*, TypePairList*);
+
+// Return 1 if t1 and t2 are identical, following the spec rules.
+//
+// Any cyclic type must go through a named type, and if one is
+// named, it is only identical to the other if they are the same
+// pointer (t1 == t2), so there's no chance of chasing cycles
+// ad infinitum, so no need for a depth counter.
+int
+eqtype(Type *t1, Type *t2)
+{
+	return eqtype1(t1, t2, nil);
+}
+
+static int
+eqtype1(Type *t1, Type *t2, TypePairList *assumed_equal)
+{
+	TypePairList l;
+
+	if(t1 == t2)
+		return 1;
+	if(t1 == T || t2 == T || t1->etype != t2->etype)
+		return 0;
+	if(t1->sym || t2->sym) {
+		// Special case: we keep byte and uint8 separate
+		// for error messages.  Treat them as equal.
+		switch(t1->etype) {
+		case TUINT8:
+			if((t1 == types[TUINT8] || t1 == bytetype) && (t2 == types[TUINT8] || t2 == bytetype))
+				return 1;
+			break;
+		case TINT:
+		case TINT32:
+			if((t1 == types[runetype->etype] || t1 == runetype) && (t2 == types[runetype->etype] || t2 == runetype))
+				return 1;
+			break;
+		}
+		return 0;
+	}
+
+	if(onlist(assumed_equal, t1, t2))
+		return 1;
+	l.next = assumed_equal;
+	l.t1 = t1;
+	l.t2 = t2;
+
+	switch(t1->etype) {
+	case TINTER:
+	case TSTRUCT:
+		for(t1=t1->type, t2=t2->type; t1 && t2; t1=t1->down, t2=t2->down) {
+			if(t1->etype != TFIELD || t2->etype != TFIELD)
+				fatal("struct/interface missing field: %T %T", t1, t2);
+			if(t1->sym != t2->sym || t1->embedded != t2->embedded || !eqtype1(t1->type, t2->type, &l) || !eqnote(t1->note, t2->note))
+				goto no;
+		}
+		if(t1 == T && t2 == T)
+			goto yes;
+		goto no;
+
+	case TFUNC:
+		// Loop over structs: receiver, in, out.
+		for(t1=t1->type, t2=t2->type; t1 && t2; t1=t1->down, t2=t2->down) {
+			Type *ta, *tb;
+
+			if(t1->etype != TSTRUCT || t2->etype != TSTRUCT)
+				fatal("func missing struct: %T %T", t1, t2);
+
+			// Loop over fields in structs, ignoring argument names.
+			for(ta=t1->type, tb=t2->type; ta && tb; ta=ta->down, tb=tb->down) {
+				if(ta->etype != TFIELD || tb->etype != TFIELD)
+					fatal("func struct missing field: %T %T", ta, tb);
+				if(ta->isddd != tb->isddd || !eqtype1(ta->type, tb->type, &l))
+					goto no;
+			}
+			if(ta != T || tb != T)
+				goto no;
+		}
+		if(t1 == T && t2 == T)
+			goto yes;
+		goto no;
+	
+	case TARRAY:
+		if(t1->bound != t2->bound)
+			goto no;
+		break;
+	
+	case TCHAN:
+		if(t1->chan != t2->chan)
+			goto no;
+		break;
+	}
+
+	if(eqtype1(t1->down, t2->down, &l) && eqtype1(t1->type, t2->type, &l))
+		goto yes;
+	goto no;
+
+yes:
+	return 1;
+
+no:
+	return 0;
+}
+
+// Are t1 and t2 equal struct types when field names are ignored?
+// For deciding whether the result struct from g can be copied
+// directly when compiling f(g()).
+int
+eqtypenoname(Type *t1, Type *t2)
+{
+	if(t1 == T || t2 == T || t1->etype != TSTRUCT || t2->etype != TSTRUCT)
+		return 0;
+
+	t1 = t1->type;
+	t2 = t2->type;
+	for(;;) {
+		if(!eqtype(t1, t2))
+			return 0;
+		if(t1 == T)
+			return 1;
+		t1 = t1->down;
+		t2 = t2->down;
+	}
+}
+
+// Is type src assignment compatible to type dst?
+// If so, return op code to use in conversion.
+// If not, return 0.
+int
+assignop(Type *src, Type *dst, char **why)
+{
+	Type *missing, *have;
+	int ptr;
+
+	if(why != nil)
+		*why = "";
+
+	// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
+	// https://code.google.com/p/go/issues/detail?id=2795
+	if(safemode && importpkg == nil && src != T && src->etype == TUNSAFEPTR) {
+		yyerror("cannot use unsafe.Pointer");
+		errorexit();
+	}
+
+	if(src == dst)
+		return OCONVNOP;
+	if(src == T || dst == T || src->etype == TFORW || dst->etype == TFORW || src->orig == T || dst->orig == T)
+		return 0;
+
+	// 1. src type is identical to dst.
+	if(eqtype(src, dst))
+		return OCONVNOP;
+	
+	// 2. src and dst have identical underlying types
+	// and either src or dst is not a named type or
+	// both are empty interface types.
+	// For assignable but different non-empty interface types,
+	// we want to recompute the itab.
+	if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || isnilinter(src)))
+		return OCONVNOP;
+
+	// 3. dst is an interface type and src implements dst.
+	if(dst->etype == TINTER && src->etype != TNIL) {
+		if(implements(src, dst, &missing, &have, &ptr))
+			return OCONVIFACE;
+
+		// we'll have complained about this method anyway, suppress spurious messages.
+		if(have && have->sym == missing->sym && (have->type->broke || missing->type->broke))
+			return OCONVIFACE;
+
+		if(why != nil) {
+			if(isptrto(src, TINTER))
+				*why = smprint(":\n\t%T is pointer to interface, not interface", src);
+			else if(have && have->sym == missing->sym && have->nointerface)
+				*why = smprint(":\n\t%T does not implement %T (%S method is marked 'nointerface')",
+					src, dst, missing->sym);
+			else if(have && have->sym == missing->sym)
+				*why = smprint(":\n\t%T does not implement %T (wrong type for %S method)\n"
+					"\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym,
+					have->sym, have->type, missing->sym, missing->type);
+			else if(ptr)
+				*why = smprint(":\n\t%T does not implement %T (%S method has pointer receiver)",
+					src, dst, missing->sym);
+			else if(have)
+				*why = smprint(":\n\t%T does not implement %T (missing %S method)\n"
+					"\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym,
+					have->sym, have->type, missing->sym, missing->type);
+			else
+				*why = smprint(":\n\t%T does not implement %T (missing %S method)",
+					src, dst, missing->sym);
+		}
+		return 0;
+	}
+	if(isptrto(dst, TINTER)) {
+		if(why != nil)
+			*why = smprint(":\n\t%T is pointer to interface, not interface", dst);
+		return 0;
+	}
+	if(src->etype == TINTER && dst->etype != TBLANK) {
+		if(why != nil && implements(dst, src, &missing, &have, &ptr))
+			*why = ": need type assertion";
+		return 0;
+	}
+
+	// 4. src is a bidirectional channel value, dst is a channel type,
+	// src and dst have identical element types, and
+	// either src or dst is not a named type.
+	if(src->etype == TCHAN && src->chan == Cboth && dst->etype == TCHAN)
+	if(eqtype(src->type, dst->type) && (src->sym == S || dst->sym == S))
+		return OCONVNOP;
+
+	// 5. src is the predeclared identifier nil and dst is a nillable type.
+	if(src->etype == TNIL) {
+		switch(dst->etype) {
+		case TARRAY:
+			if(dst->bound != -100)	// not slice
+				break;
+		case TPTR32:
+		case TPTR64:
+		case TFUNC:
+		case TMAP:
+		case TCHAN:
+		case TINTER:
+			return OCONVNOP;
+		}
+	}
+
+	// 6. rule about untyped constants - already converted by defaultlit.
+	
+	// 7. Any typed value can be assigned to the blank identifier.
+	if(dst->etype == TBLANK)
+		return OCONVNOP;
+
+	return 0;
+}
+
+// Can we convert a value of type src to a value of type dst?
+// If so, return op code to use in conversion (maybe OCONVNOP).
+// If not, return 0.
+int
+convertop(Type *src, Type *dst, char **why)
+{
+	int op;
+	
+	if(why != nil)
+		*why = "";
+
+	if(src == dst)
+		return OCONVNOP;
+	if(src == T || dst == T)
+		return 0;
+	
+	// 1. src can be assigned to dst.
+	if((op = assignop(src, dst, why)) != 0)
+		return op;
+
+	// The rules for interfaces are no different in conversions
+	// than assignments.  If interfaces are involved, stop now
+	// with the good message from assignop.
+	// Otherwise clear the error.
+	if(src->etype == TINTER || dst->etype == TINTER)
+		return 0;
+	if(why != nil)
+		*why = "";
+
+	// 2. src and dst have identical underlying types.
+	if(eqtype(src->orig, dst->orig))
+		return OCONVNOP;
+	
+	// 3. src and dst are unnamed pointer types 
+	// and their base types have identical underlying types.
+	if(isptr[src->etype] && isptr[dst->etype] && src->sym == S && dst->sym == S)
+	if(eqtype(src->type->orig, dst->type->orig))
+		return OCONVNOP;
+
+	// 4. src and dst are both integer or floating point types.
+	if((isint[src->etype] || isfloat[src->etype]) && (isint[dst->etype] || isfloat[dst->etype])) {
+		if(simtype[src->etype] == simtype[dst->etype])
+			return OCONVNOP;
+		return OCONV;
+	}
+
+	// 5. src and dst are both complex types.
+	if(iscomplex[src->etype] && iscomplex[dst->etype]) {
+		if(simtype[src->etype] == simtype[dst->etype])
+			return OCONVNOP;
+		return OCONV;
+	}
+
+	// 6. src is an integer or has type []byte or []rune
+	// and dst is a string type.
+	if(isint[src->etype] && dst->etype == TSTRING)
+		return ORUNESTR;
+
+	if(isslice(src) && dst->etype == TSTRING) {
+		if(src->type->etype == bytetype->etype)
+			return OARRAYBYTESTR;
+		if(src->type->etype == runetype->etype)
+			return OARRAYRUNESTR;
+	}
+	
+	// 7. src is a string and dst is []byte or []rune.
+	// String to slice.
+	if(src->etype == TSTRING && isslice(dst)) {
+		if(dst->type->etype == bytetype->etype)
+			return OSTRARRAYBYTE;
+		if(dst->type->etype == runetype->etype)
+			return OSTRARRAYRUNE;
+	}
+	
+	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
+	if((isptr[src->etype] || src->etype == TUINTPTR) && dst->etype == TUNSAFEPTR)
+		return OCONVNOP;
+
+	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
+	if(src->etype == TUNSAFEPTR && (isptr[dst->etype] || dst->etype == TUINTPTR))
+		return OCONVNOP;
+
+	return 0;
+}
+
+// Convert node n for assignment to type t.
+Node*
+assignconv(Node *n, Type *t, char *context)
+{
+	int op;
+	Node *r, *old;
+	char *why;
+	
+	if(n == N || n->type == T || n->type->broke)
+		return n;
+
+	if(t->etype == TBLANK && n->type->etype == TNIL)
+		yyerror("use of untyped nil");
+
+	old = n;
+	old->diag++;  // silence errors about n; we'll issue one below
+	defaultlit(&n, t);
+	old->diag--;
+	if(t->etype == TBLANK)
+		return n;
+
+	// Convert ideal bool from comparison to plain bool
+	// if the next step is non-bool (like interface{}).
+	if(n->type == idealbool && t->etype != TBOOL) {
+		if(n->op == ONAME || n->op == OLITERAL) {
+			r = nod(OCONVNOP, n, N);
+			r->type = types[TBOOL];
+			r->typecheck = 1;
+			r->implicit = 1;
+			n = r;
+		}
+	}
+
+	if(eqtype(n->type, t))
+		return n;
+
+	op = assignop(n->type, t, &why);
+	if(op == 0) {
+		yyerror("cannot use %lN as type %T in %s%s", n, t, context, why);
+		op = OCONV;
+	}
+
+	r = nod(op, n, N);
+	r->type = t;
+	r->typecheck = 1;
+	r->implicit = 1;
+	r->orig = n->orig;
+	return r;
+}
+
+static int
+subtype(Type **stp, Type *t, int d)
+{
+	Type *st;
+
+loop:
+	st = *stp;
+	if(st == T)
+		return 0;
+
+	d++;
+	if(d >= 10)
+		return 0;
+
+	switch(st->etype) {
+	default:
+		return 0;
+
+	case TPTR32:
+	case TPTR64:
+	case TCHAN:
+	case TARRAY:
+		stp = &st->type;
+		goto loop;
+
+	case TANY:
+		if(!st->copyany)
+			return 0;
+		*stp = t;
+		break;
+
+	case TMAP:
+		if(subtype(&st->down, t, d))
+			break;
+		stp = &st->type;
+		goto loop;
+
+	case TFUNC:
+		for(;;) {
+			if(subtype(&st->type, t, d))
+				break;
+			if(subtype(&st->type->down->down, t, d))
+				break;
+			if(subtype(&st->type->down, t, d))
+				break;
+			return 0;
+		}
+		break;
+
+	case TSTRUCT:
+		for(st=st->type; st!=T; st=st->down)
+			if(subtype(&st->type, t, d))
+				return 1;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Is this a 64-bit type?
+ */
+int
+is64(Type *t)
+{
+	if(t == T)
+		return 0;
+	switch(simtype[t->etype]) {
+	case TINT64:
+	case TUINT64:
+	case TPTR64:
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Is a conversion between t1 and t2 a no-op?
+ */
+int
+noconv(Type *t1, Type *t2)
+{
+	int e1, e2;
+
+	e1 = simtype[t1->etype];
+	e2 = simtype[t2->etype];
+
+	switch(e1) {
+	case TINT8:
+	case TUINT8:
+		return e2 == TINT8 || e2 == TUINT8;
+
+	case TINT16:
+	case TUINT16:
+		return e2 == TINT16 || e2 == TUINT16;
+
+	case TINT32:
+	case TUINT32:
+	case TPTR32:
+		return e2 == TINT32 || e2 == TUINT32 || e2 == TPTR32;
+
+	case TINT64:
+	case TUINT64:
+	case TPTR64:
+		return e2 == TINT64 || e2 == TUINT64 || e2 == TPTR64;
+
+	case TFLOAT32:
+		return e2 == TFLOAT32;
+
+	case TFLOAT64:
+		return e2 == TFLOAT64;
+	}
+	return 0;
+}
+
+void
+argtype(Node *on, Type *t)
+{
+	dowidth(t);
+	if(!subtype(&on->type, t, 0))
+		fatal("argtype: failed %N %T\n", on, t);
+}
+
+Type*
+shallow(Type *t)
+{
+	Type *nt;
+
+	if(t == T)
+		return T;
+	nt = typ(0);
+	*nt = *t;
+	if(t->orig == t)
+		nt->orig = nt;
+	return nt;
+}
+
+static Type*
+deep(Type *t)
+{
+	Type *nt, *xt;
+
+	if(t == T)
+		return T;
+
+	switch(t->etype) {
+	default:
+		nt = t;	// share from here down
+		break;
+
+	case TANY:
+		nt = shallow(t);
+		nt->copyany = 1;
+		break;
+
+	case TPTR32:
+	case TPTR64:
+	case TCHAN:
+	case TARRAY:
+		nt = shallow(t);
+		nt->type = deep(t->type);
+		break;
+
+	case TMAP:
+		nt = shallow(t);
+		nt->down = deep(t->down);
+		nt->type = deep(t->type);
+		break;
+
+	case TFUNC:
+		nt = shallow(t);
+		nt->type = deep(t->type);
+		nt->type->down = deep(t->type->down);
+		nt->type->down->down = deep(t->type->down->down);
+		break;
+
+	case TSTRUCT:
+		nt = shallow(t);
+		nt->type = shallow(t->type);
+		xt = nt->type;
+
+		for(t=t->type; t!=T; t=t->down) {
+			xt->type = deep(t->type);
+			xt->down = shallow(t->down);
+			xt = xt->down;
+		}
+		break;
+	}
+	return nt;
+}
+
+Node*
+syslook(char *name, int copy)
+{
+	Sym *s;
+	Node *n;
+
+	s = pkglookup(name, runtimepkg);
+	if(s == S || s->def == N)
+		fatal("syslook: can't find runtime.%s", name);
+
+	if(!copy)
+		return s->def;
+
+	n = nod(0, N, N);
+	*n = *s->def;
+	n->type = deep(s->def->type);
+
+	return n;
+}
+
+/*
+ * compute a hash value for type t.
+ * if t is a method type, ignore the receiver
+ * so that the hash can be used in interface checks.
+ * %T already contains
+ * all the necessary logic to generate a representation
+ * of the type that completely describes it.
+ * using smprint here avoids duplicating that code.
+ * using md5 here is overkill, but i got tired of
+ * accidental collisions making the runtime think
+ * two types are equal when they really aren't.
+ */
+uint32
+typehash(Type *t)
+{
+	char *p;
+	MD5 d;
+
+	if(t->thistuple) {
+		// hide method receiver from Tpretty
+		t->thistuple = 0;
+		p = smprint("%-uT", t);
+		t->thistuple = 1;
+	} else
+		p = smprint("%-uT", t);
+	//print("typehash: %s\n", p);
+	md5reset(&d);
+	md5write(&d, (uchar*)p, strlen(p));
+	free(p);
+	return md5sum(&d, nil);
+}
+
+Type*
+ptrto(Type *t)
+{
+	Type *t1;
+
+	if(tptr == 0)
+		fatal("ptrto: no tptr");
+	t1 = typ(tptr);
+	t1->type = t;
+	t1->width = widthptr;
+	t1->align = widthptr;
+	return t1;
+}
+
+void
+frame(int context)
+{
+	char *p;
+	NodeList *l;
+	Node *n;
+	int flag;
+
+	p = "stack";
+	l = nil;
+	if(curfn)
+		l = curfn->dcl;
+	if(context) {
+		p = "external";
+		l = externdcl;
+	}
+
+	flag = 1;
+	for(; l; l=l->next) {
+		n = l->n;
+		switch(n->op) {
+		case ONAME:
+			if(flag)
+				print("--- %s frame ---\n", p);
+			print("%O %S G%d %T\n", n->op, n->sym, n->vargen, n->type);
+			flag = 0;
+			break;
+
+		case OTYPE:
+			if(flag)
+				print("--- %s frame ---\n", p);
+			print("%O %T\n", n->op, n->type);
+			flag = 0;
+			break;
+		}
+	}
+}
+
+/*
+ * calculate sethi/ullman number
+ * roughly how many registers needed to
+ * compile a node. used to compile the
+ * hardest side first to minimize registers.
+ */
+void
+ullmancalc(Node *n)
+{
+	int ul, ur;
+
+	if(n == N)
+		return;
+
+	if(n->ninit != nil) {
+		ul = UINF;
+		goto out;
+	}
+
+	switch(n->op) {
+	case OREGISTER:
+	case OLITERAL:
+	case ONAME:
+		ul = 1;
+		if(n->class == PPARAMREF || (n->class & PHEAP))
+			ul++;
+		goto out;
+	case OCALL:
+	case OCALLFUNC:
+	case OCALLMETH:
+	case OCALLINTER:
+		ul = UINF;
+		goto out;
+	case OANDAND:
+	case OOROR:
+		// hard with race detector
+		if(flag_race) {
+			ul = UINF;
+			goto out;
+		}
+	}
+	ul = 1;
+	if(n->left != N)
+		ul = n->left->ullman;
+	ur = 1;
+	if(n->right != N)
+		ur = n->right->ullman;
+	if(ul == ur)
+		ul += 1;
+	if(ur > ul)
+		ul = ur;
+
+out:
+	if(ul > 200)
+		ul = 200; // clamp to uchar with room to grow
+	n->ullman = ul;
+}
+
+void
+badtype(int o, Type *tl, Type *tr)
+{
+	Fmt fmt;
+	char *s;
+	
+	fmtstrinit(&fmt);
+	if(tl != T)
+		fmtprint(&fmt, "\n	%T", tl);
+	if(tr != T)
+		fmtprint(&fmt, "\n	%T", tr);
+
+	// common mistake: *struct and *interface.
+	if(tl && tr && isptr[tl->etype] && isptr[tr->etype]) {
+		if(tl->type->etype == TSTRUCT && tr->type->etype == TINTER)
+			fmtprint(&fmt, "\n	(*struct vs *interface)");
+		else if(tl->type->etype == TINTER && tr->type->etype == TSTRUCT)
+			fmtprint(&fmt, "\n	(*interface vs *struct)");
+	}
+	s = fmtstrflush(&fmt);
+	yyerror("illegal types for operand: %O%s", o, s);
+}
+
+/*
+ * iterator to walk a structure declaration
+ */
+Type*
+structfirst(Iter *s, Type **nn)
+{
+	Type *n, *t;
+
+	n = *nn;
+	if(n == T)
+		goto bad;
+
+	switch(n->etype) {
+	default:
+		goto bad;
+
+	case TSTRUCT:
+	case TINTER:
+	case TFUNC:
+		break;
+	}
+
+	t = n->type;
+	if(t == T)
+		goto rnil;
+
+	if(t->etype != TFIELD)
+		fatal("structfirst: not field %T", t);
+
+	s->t = t;
+	return t;
+
+bad:
+	fatal("structfirst: not struct %T", n);
+
+rnil:
+	return T;
+}
+
+Type*
+structnext(Iter *s)
+{
+	Type *n, *t;
+
+	n = s->t;
+	t = n->down;
+	if(t == T)
+		goto rnil;
+
+	if(t->etype != TFIELD)
+		goto bad;
+
+	s->t = t;
+	return t;
+
+bad:
+	fatal("structnext: not struct %T", n);
+
+rnil:
+	return T;
+}
+
+/*
+ * iterator to this and inargs in a function
+ */
+Type*
+funcfirst(Iter *s, Type *t)
+{
+	Type *fp;
+
+	if(t == T)
+		goto bad;
+
+	if(t->etype != TFUNC)
+		goto bad;
+
+	s->tfunc = t;
+	s->done = 0;
+	fp = structfirst(s, getthis(t));
+	if(fp == T) {
+		s->done = 1;
+		fp = structfirst(s, getinarg(t));
+	}
+	return fp;
+
+bad:
+	fatal("funcfirst: not func %T", t);
+	return T;
+}
+
+Type*
+funcnext(Iter *s)
+{
+	Type *fp;
+
+	fp = structnext(s);
+	if(fp == T && !s->done) {
+		s->done = 1;
+		fp = structfirst(s, getinarg(s->tfunc));
+	}
+	return fp;
+}
+
+Type**
+getthis(Type *t)
+{
+	if(t->etype != TFUNC)
+		fatal("getthis: not a func %T", t);
+	return &t->type;
+}
+
+Type**
+getoutarg(Type *t)
+{
+	if(t->etype != TFUNC)
+		fatal("getoutarg: not a func %T", t);
+	return &t->type->down;
+}
+
+Type**
+getinarg(Type *t)
+{
+	if(t->etype != TFUNC)
+		fatal("getinarg: not a func %T", t);
+	return &t->type->down->down;
+}
+
+Type*
+getthisx(Type *t)
+{
+	return *getthis(t);
+}
+
+Type*
+getoutargx(Type *t)
+{
+	return *getoutarg(t);
+}
+
+Type*
+getinargx(Type *t)
+{
+	return *getinarg(t);
+}
+
+/*
+ * return !(op)
+ * eg == <=> !=
+ */
+int
+brcom(int a)
+{
+	switch(a) {
+	case OEQ:	return ONE;
+	case ONE:	return OEQ;
+	case OLT:	return OGE;
+	case OGT:	return OLE;
+	case OLE:	return OGT;
+	case OGE:	return OLT;
+	}
+	fatal("brcom: no com for %A\n", a);
+	return a;
+}
+
+/*
+ * return reverse(op)
+ * eg a op b <=> b r(op) a
+ */
+int
+brrev(int a)
+{
+	switch(a) {
+	case OEQ:	return OEQ;
+	case ONE:	return ONE;
+	case OLT:	return OGT;
+	case OGT:	return OLT;
+	case OLE:	return OGE;
+	case OGE:	return OLE;
+	}
+	fatal("brcom: no rev for %A\n", a);
+	return a;
+}
+
+/*
+ * return side effect-free n, appending side effects to init.
+ * result is assignable if n is.
+ */
+Node*
+safeexpr(Node *n, NodeList **init)
+{
+	Node *l;
+	Node *r;
+	Node *a;
+
+	if(n == N)
+		return N;
+
+	if(n->ninit) {
+		walkstmtlist(n->ninit);
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+	}
+
+	switch(n->op) {
+	case ONAME:
+	case OLITERAL:
+		return n;
+
+	case ODOT:
+		l = safeexpr(n->left, init);
+		if(l == n->left)
+			return n;
+		r = nod(OXXX, N, N);
+		*r = *n;
+		r->left = l;
+		typecheck(&r, Erv);
+		walkexpr(&r, init);
+		return r;
+
+	case ODOTPTR:
+	case OIND:
+		l = safeexpr(n->left, init);
+		if(l == n->left)
+			return n;
+		a = nod(OXXX, N, N);
+		*a = *n;
+		a->left = l;
+		walkexpr(&a, init);
+		return a;
+
+	case OINDEX:
+	case OINDEXMAP:
+		l = safeexpr(n->left, init);
+		r = safeexpr(n->right, init);
+		if(l == n->left && r == n->right)
+			return n;
+		a = nod(OXXX, N, N);
+		*a = *n;
+		a->left = l;
+		a->right = r;
+		walkexpr(&a, init);
+		return a;
+	}
+
+	// make a copy; must not be used as an lvalue
+	if(islvalue(n))
+		fatal("missing lvalue case in safeexpr: %N", n);
+	return cheapexpr(n, init);
+}
+
+Node*
+copyexpr(Node *n, Type *t, NodeList **init)
+{
+	Node *a, *l;
+	
+	l = temp(t);
+	a = nod(OAS, l, n);
+	typecheck(&a, Etop);
+	walkexpr(&a, init);
+	*init = list(*init, a);
+	return l;
+}
+
+/*
+ * return side-effect free and cheap n, appending side effects to init.
+ * result may not be assignable.
+ */
+Node*
+cheapexpr(Node *n, NodeList **init)
+{
+	switch(n->op) {
+	case ONAME:
+	case OLITERAL:
+		return n;
+	}
+
+	return copyexpr(n, n->type, init);
+}
+
+/*
+ * return n in a local variable of type t if it is not already.
+ * the value is guaranteed not to change except by direct
+ * assignment to it.
+ */
+Node*
+localexpr(Node *n, Type *t, NodeList **init)
+{
+	if(n->op == ONAME && (!n->addrtaken || strncmp(n->sym->name, "autotmp_", 8) == 0) &&
+		(n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
+		convertop(n->type, t, nil) == OCONVNOP)
+		return n;
+	
+	return copyexpr(n, t, init);
+}
+
+void
+setmaxarg(Type *t)
+{
+	int64 w;
+
+	dowidth(t);
+	w = t->argwid;
+	if(t->argwid >= MAXWIDTH)
+		fatal("bad argwid %T", t);
+	if(w > maxarg)
+		maxarg = w;
+}
+
+/*
+ * unicode-aware case-insensitive strcmp
+ */
+
+static int
+ucistrcmp(char *p, char *q)
+{
+	Rune rp, rq;
+
+	while(*p || *q) {
+		if(*p == 0)
+			return +1;
+		if(*q == 0)
+			return -1;
+		p += chartorune(&rp, p);
+		q += chartorune(&rq, q);
+		rp = tolowerrune(rp);
+		rq = tolowerrune(rq);
+		if(rp < rq)
+			return -1;
+		if(rp > rq)
+			return +1;
+	}
+	return 0;
+}
+
+/*
+ * code to resolve elided DOTs
+ * in embedded types
+ */
+
+// search depth 0 --
+// return count of fields+methods
+// found with a given name
+static int
+lookdot0(Sym *s, Type *t, Type **save, int ignorecase)
+{
+	Type *f, *u;
+	int c;
+
+	u = t;
+	if(isptr[u->etype])
+		u = u->type;
+
+	c = 0;
+	if(u->etype == TSTRUCT || u->etype == TINTER) {
+		for(f=u->type; f!=T; f=f->down)
+			if(f->sym == s || (ignorecase && f->type->etype == TFUNC && f->type->thistuple > 0 && ucistrcmp(f->sym->name, s->name) == 0)) {
+				if(save)
+					*save = f;
+				c++;
+			}
+	}
+	u = methtype(t, 0);
+	if(u != T) {
+		for(f=u->method; f!=T; f=f->down)
+			if(f->embedded == 0 && (f->sym == s || (ignorecase && ucistrcmp(f->sym->name, s->name) == 0))) {
+				if(save)
+					*save = f;
+				c++;
+			}
+	}
+	return c;
+}
+
+// search depth d for field/method s --
+// return count of fields+methods
+// found at search depth.
+// answer is in dotlist array and
+// count of number of ways is returned.
+int
+adddot1(Sym *s, Type *t, int d, Type **save, int ignorecase)
+{
+	Type *f, *u;
+	int c, a;
+
+	if(t->trecur)
+		return 0;
+	t->trecur = 1;
+
+	if(d == 0) {
+		c = lookdot0(s, t, save, ignorecase);
+		goto out;
+	}
+
+	c = 0;
+	u = t;
+	if(isptr[u->etype])
+		u = u->type;
+	if(u->etype != TSTRUCT && u->etype != TINTER)
+		goto out;
+
+	d--;
+	for(f=u->type; f!=T; f=f->down) {
+		if(!f->embedded)
+			continue;
+		if(f->sym == S)
+			continue;
+		a = adddot1(s, f->type, d, save, ignorecase);
+		if(a != 0 && c == 0)
+			dotlist[d].field = f;
+		c += a;
+	}
+
+out:
+	t->trecur = 0;
+	return c;
+}
+
+// in T.field
+// find missing fields that
+// will give shortest unique addressing.
+// modify the tree with missing type names.
+Node*
+adddot(Node *n)
+{
+	Type *t;
+	Sym *s;
+	int c, d;
+
+	typecheck(&n->left, Etype|Erv);
+	n->diag |= n->left->diag;
+	t = n->left->type;
+	if(t == T)
+		goto ret;
+	
+	if(n->left->op == OTYPE)
+		goto ret;
+
+	if(n->right->op != ONAME)
+		goto ret;
+	s = n->right->sym;
+	if(s == S)
+		goto ret;
+
+	for(d=0; d<nelem(dotlist); d++) {
+		c = adddot1(s, t, d, nil, 0);
+		if(c > 0)
+			goto out;
+	}
+	goto ret;
+
+out:
+	if(c > 1) {
+		yyerror("ambiguous selector %N", n);
+		n->left = N;
+		return n;
+	}
+
+	// rebuild elided dots
+	for(c=d-1; c>=0; c--)
+		n->left = nod(ODOT, n->left, newname(dotlist[c].field->sym));
+ret:
+	return n;
+}
+
+
+/*
+ * code to help generate trampoline
+ * functions for methods on embedded
+ * subtypes.
+ * these are approx the same as
+ * the corresponding adddot routines
+ * except that they expect to be called
+ * with unique tasks and they return
+ * the actual methods.
+ */
+
+typedef	struct	Symlink	Symlink;
+struct	Symlink
+{
+	Type*		field;
+	uchar		good;
+	uchar		followptr;
+	Symlink*	link;
+};
+static	Symlink*	slist;
+
+static void
+expand0(Type *t, int followptr)
+{
+	Type *f, *u;
+	Symlink *sl;
+
+	u = t;
+	if(isptr[u->etype]) {
+		followptr = 1;
+		u = u->type;
+	}
+
+	if(u->etype == TINTER) {
+		for(f=u->type; f!=T; f=f->down) {
+			if(f->sym->flags & SymUniq)
+				continue;
+			f->sym->flags |= SymUniq;
+			sl = mal(sizeof(*sl));
+			sl->field = f;
+			sl->link = slist;
+			sl->followptr = followptr;
+			slist = sl;
+		}
+		return;
+	}
+
+	u = methtype(t, 0);
+	if(u != T) {
+		for(f=u->method; f!=T; f=f->down) {
+			if(f->sym->flags & SymUniq)
+				continue;
+			f->sym->flags |= SymUniq;
+			sl = mal(sizeof(*sl));
+			sl->field = f;
+			sl->link = slist;
+			sl->followptr = followptr;
+			slist = sl;
+		}
+	}
+}
+
+static void
+expand1(Type *t, int d, int followptr)
+{
+	Type *f, *u;
+
+	if(t->trecur)
+		return;
+	if(d == 0)
+		return;
+	t->trecur = 1;
+
+	if(d != nelem(dotlist)-1)
+		expand0(t, followptr);
+
+	u = t;
+	if(isptr[u->etype]) {
+		followptr = 1;
+		u = u->type;
+	}
+	if(u->etype != TSTRUCT && u->etype != TINTER)
+		goto out;
+
+	for(f=u->type; f!=T; f=f->down) {
+		if(!f->embedded)
+			continue;
+		if(f->sym == S)
+			continue;
+		expand1(f->type, d-1, followptr);
+	}
+
+out:
+	t->trecur = 0;
+}
+
+void
+expandmeth(Type *t)
+{
+	Symlink *sl;
+	Type *f;
+	int c, d;
+
+	if(t == T || t->xmethod != nil)
+		return;
+
+	// mark top-level method symbols
+	// so that expand1 doesn't consider them.
+	for(f=t->method; f != nil; f=f->down)
+		f->sym->flags |= SymUniq;
+
+	// generate all reachable methods
+	slist = nil;
+	expand1(t, nelem(dotlist)-1, 0);
+
+	// check each method to be uniquely reachable
+	for(sl=slist; sl!=nil; sl=sl->link) {
+		sl->field->sym->flags &= ~SymUniq;
+		for(d=0; d<nelem(dotlist); d++) {
+			c = adddot1(sl->field->sym, t, d, &f, 0);
+			if(c == 0)
+				continue;
+			if(c == 1) {
+				// addot1 may have dug out arbitrary fields, we only want methods.
+				if(f->type->etype == TFUNC && f->type->thistuple > 0) {
+					sl->good = 1;
+					sl->field = f;
+				}
+			}
+			break;
+		}
+	}
+
+	for(f=t->method; f != nil; f=f->down)
+		f->sym->flags &= ~SymUniq;
+
+	t->xmethod = t->method;
+	for(sl=slist; sl!=nil; sl=sl->link) {
+		if(sl->good) {
+			// add it to the base type method list
+			f = typ(TFIELD);
+			*f = *sl->field;
+			f->embedded = 1;	// needs a trampoline
+			if(sl->followptr)
+				f->embedded = 2;
+			f->down = t->xmethod;
+			t->xmethod = f;
+		}
+	}
+}
+
+/*
+ * Given funarg struct list, return list of ODCLFIELD Node fn args.
+ */
+static NodeList*
+structargs(Type **tl, int mustname)
+{
+	Iter savet;
+	Node *a, *n;
+	NodeList *args;
+	Type *t;
+	char buf[100];
+	int gen;
+
+	args = nil;
+	gen = 0;
+	for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
+		n = N;
+		if(mustname && (t->sym == nil || strcmp(t->sym->name, "_") == 0)) {
+			// invent a name so that we can refer to it in the trampoline
+			snprint(buf, sizeof buf, ".anon%d", gen++);
+			n = newname(lookup(buf));
+		} else if(t->sym)
+			n = newname(t->sym);
+		a = nod(ODCLFIELD, n, typenod(t->type));
+		a->isddd = t->isddd;
+		if(n != N)
+			n->isddd = t->isddd;
+		args = list(args, a);
+	}
+	return args;
+}
+
+/*
+ * Generate a wrapper function to convert from
+ * a receiver of type T to a receiver of type U.
+ * That is,
+ *
+ *	func (t T) M() {
+ *		...
+ *	}
+ *
+ * already exists; this function generates
+ *
+ *	func (u U) M() {
+ *		u.M()
+ *	}
+ *
+ * where the types T and U are such that u.M() is valid
+ * and calls the T.M method.
+ * The resulting function is for use in method tables.
+ *
+ *	rcvr - U
+ *	method - M func (t T)(), a TFIELD type struct
+ *	newnam - the eventual mangled name of this function
+ */
+void
+genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
+{
+	Node *this, *fn, *call, *n, *t, *pad, *dot, *as;
+	NodeList *l, *args, *in, *out;
+	Type *tpad, *methodrcvr;
+	int isddd;
+	Val v;
+	static int linehistdone = 0;
+
+	if(0 && debug['r'])
+		print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
+			rcvr, method, newnam);
+
+	lexlineno++;
+	lineno = lexlineno;
+	if (linehistdone == 0) {
+		// All the wrappers can share the same linehist entry.
+		linehist("<autogenerated>", 0, 0);
+		linehistdone = 1;
+	}
+
+	dclcontext = PEXTERN;
+	markdcl();
+
+	this = nod(ODCLFIELD, newname(lookup(".this")), typenod(rcvr));
+	this->left->ntype = this->right;
+	in = structargs(getinarg(method->type), 1);
+	out = structargs(getoutarg(method->type), 0);
+
+	t = nod(OTFUNC, N, N);
+	l = list1(this);
+	if(iface && rcvr->width < types[tptr]->width) {
+		// Building method for interface table and receiver
+		// is smaller than the single pointer-sized word
+		// that the interface call will pass in.
+		// Add a dummy padding argument after the
+		// receiver to make up the difference.
+		tpad = typ(TARRAY);
+		tpad->type = types[TUINT8];
+		tpad->bound = types[tptr]->width - rcvr->width;
+		pad = nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad));
+		l = list(l, pad);
+	}
+	t->list = concat(l, in);
+	t->rlist = out;
+
+	fn = nod(ODCLFUNC, N, N);
+	fn->nname = newname(newnam);
+	fn->nname->defn = fn;
+	fn->nname->ntype = t;
+	declare(fn->nname, PFUNC);
+	funchdr(fn);
+
+	// arg list
+	args = nil;
+	isddd = 0;
+	for(l=in; l; l=l->next) {
+		args = list(args, l->n->left);
+		isddd = l->n->left->isddd;
+	}
+	
+	methodrcvr = getthisx(method->type)->type->type;
+
+	// generate nil pointer check for better error
+	if(isptr[rcvr->etype] && rcvr->type == methodrcvr) {
+		// generating wrapper from *T to T.
+		n = nod(OIF, N, N);
+		n->ntest = nod(OEQ, this->left, nodnil());
+		// these strings are already in the reflect tables,
+		// so no space cost to use them here.
+		l = nil;
+		v.ctype = CTSTR;
+		v.u.sval = strlit(rcvr->type->sym->pkg->name);  // package name
+		l = list(l, nodlit(v));
+		v.u.sval = strlit(rcvr->type->sym->name);  // type name
+		l = list(l, nodlit(v));
+		v.u.sval = strlit(method->sym->name);
+		l = list(l, nodlit(v));  // method name
+		call = nod(OCALL, syslook("panicwrap", 0), N);
+		call->list = l;
+		n->nbody = list1(call);
+		fn->nbody = list(fn->nbody, n);
+	}
+	
+	dot = adddot(nod(OXDOT, this->left, newname(method->sym)));
+	
+	// generate call
+	if(!flag_race && isptr[rcvr->etype] && isptr[methodrcvr->etype] && method->embedded && !isifacemethod(method->type)) {
+		// generate tail call: adjust pointer receiver and jump to embedded method.
+		dot = dot->left;	// skip final .M
+		if(!isptr[dotlist[0].field->type->etype])
+			dot = nod(OADDR, dot, N);
+		as = nod(OAS, this->left, nod(OCONVNOP, dot, N));
+		as->right->type = rcvr;
+		fn->nbody = list(fn->nbody, as);
+		n = nod(ORETJMP, N, N);
+		n->left = newname(methodsym(method->sym, methodrcvr, 0));
+		fn->nbody = list(fn->nbody, n);
+	} else {
+		fn->wrapper = 1; // ignore frame for panic+recover matching
+		call = nod(OCALL, dot, N);
+		call->list = args;
+		call->isddd = isddd;
+		if(method->type->outtuple > 0) {
+			n = nod(ORETURN, N, N);
+			n->list = list1(call);
+			call = n;
+		}
+		fn->nbody = list(fn->nbody, call);
+	}
+
+	if(0 && debug['r'])
+		dumplist("genwrapper body", fn->nbody);
+
+	funcbody(fn);
+	curfn = fn;
+	// wrappers where T is anonymous (struct or interface) can be duplicated.
+	if(rcvr->etype == TSTRUCT ||
+		rcvr->etype == TINTER ||
+		isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
+		fn->dupok = 1;
+	typecheck(&fn, Etop);
+	typechecklist(fn->nbody, Etop);
+
+	// Set inl_nonlocal to whether we are calling a method on a
+	// type defined in a different package.  Checked in inlvar.
+	if(!methodrcvr->local)
+		inl_nonlocal = 1;
+
+	inlcalls(fn);
+
+	inl_nonlocal = 0;
+
+	curfn = nil;
+	funccompile(fn, 0);
+}
+
+static Node*
+hashmem(Type *t)
+{
+	Node *tfn, *n;
+	Sym *sym;
+	
+	sym = pkglookup("memhash", runtimepkg);
+
+	n = newname(sym);
+	n->class = PFUNC;
+	tfn = nod(OTFUNC, N, N);
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->rlist = list(tfn->rlist, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	typecheck(&tfn, Etype);
+	n->type = tfn->type;
+	return n;
+}
+
+static Node*
+hashfor(Type *t)
+{
+	int a;
+	Sym *sym;
+	Node *tfn, *n;
+
+	a = algtype1(t, nil);
+	switch(a) {
+	case AMEM:
+		return hashmem(t);
+	case AINTER:
+		sym = pkglookup("interhash", runtimepkg);
+		break;
+	case ANILINTER:
+		sym = pkglookup("nilinterhash", runtimepkg);
+		break;
+	case ASTRING:
+		sym = pkglookup("strhash", runtimepkg);
+		break;
+	case AFLOAT32:
+		sym = pkglookup("f32hash", runtimepkg);
+		break;
+	case AFLOAT64:
+		sym = pkglookup("f64hash", runtimepkg);
+		break;
+	case ACPLX64:
+		sym = pkglookup("c64hash", runtimepkg);
+		break;
+	case ACPLX128:
+		sym = pkglookup("c128hash", runtimepkg);
+		break;
+	default:
+		sym = typesymprefix(".hash", t);
+		break;
+	}
+
+	n = newname(sym);
+	n->class = PFUNC;
+	tfn = nod(OTFUNC, N, N);
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->rlist = list(tfn->rlist, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	typecheck(&tfn, Etype);
+	n->type = tfn->type;
+	return n;
+}
+
+/*
+ * Generate a helper function to compute the hash of a value of type t.
+ */
+void
+genhash(Sym *sym, Type *t)
+{
+	Node *n, *fn, *np, *nh, *ni, *call, *nx, *na, *tfn, *r;
+	Node *hashel;
+	Type *first, *t1;
+	int old_safemode;
+	int64 size, mul, offend;
+
+	if(debug['r'])
+		print("genhash %S %T\n", sym, t);
+
+	lineno = 1;  // less confusing than end of input
+	dclcontext = PEXTERN;
+	markdcl();
+
+	// func sym(p *T, s uintptr, h uintptr) uintptr
+	fn = nod(ODCLFUNC, N, N);
+	fn->nname = newname(sym);
+	fn->nname->class = PFUNC;
+	tfn = nod(OTFUNC, N, N);
+	fn->nname->ntype = tfn;
+
+	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
+	tfn->list = list(tfn->list, n);
+	np = n->left;
+	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
+	tfn->list = list(tfn->list, n);
+	n = nod(ODCLFIELD, newname(lookup("h")), typenod(types[TUINTPTR]));
+	tfn->list = list(tfn->list, n);
+	nh = n->left;
+	n = nod(ODCLFIELD, N, typenod(types[TUINTPTR])); // return value
+	tfn->rlist = list(tfn->rlist, n);
+
+	funchdr(fn);
+	typecheck(&fn->nname->ntype, Etype);
+
+	// genhash is only called for types that have equality but
+	// cannot be handled by the standard algorithms,
+	// so t must be either an array or a struct.
+	switch(t->etype) {
+	default:
+		fatal("genhash %T", t);
+	case TARRAY:
+		if(isslice(t))
+			fatal("genhash %T", t);
+		// An array of pure memory would be handled by the
+		// standard algorithm, so the element type must not be
+		// pure memory.
+		hashel = hashfor(t->type);
+		n = nod(ORANGE, N, nod(OIND, np, N));
+		ni = newname(lookup("i"));
+		ni->type = types[TINT];
+		n->list = list1(ni);
+		n->colas = 1;
+		colasdefn(n->list, n);
+		ni = n->list->n;
+
+		// TODO: with aeshash we don't need these shift/mul parts
+
+		// h = h<<3 | h>>61
+		n->nbody = list(n->nbody,
+			nod(OAS,
+			    nh,
+				nod(OOR,
+					nod(OLSH, nh, nodintconst(3)),
+					nod(ORSH, nh, nodintconst(widthptr*8-3)))));
+
+		// h *= mul
+		// Same multipliers as in runtime.memhash.
+		if(widthptr == 4)
+			mul = 3267000013LL;
+		else
+			mul = 23344194077549503LL;
+		n->nbody = list(n->nbody,
+			nod(OAS,
+				nh,
+				nod(OMUL, nh, nodintconst(mul))));
+
+		// h = hashel(&p[i], sizeof(p[i]), h)
+		call = nod(OCALL, hashel, N);
+		nx = nod(OINDEX, np, ni);
+		nx->bounded = 1;
+		na = nod(OADDR, nx, N);
+		na->etype = 1;  // no escape to heap
+		call->list = list(call->list, na);
+		call->list = list(call->list, nodintconst(t->type->width));
+		call->list = list(call->list, nh);
+		n->nbody = list(n->nbody, nod(OAS, nh, call));
+
+		fn->nbody = list(fn->nbody, n);
+		break;
+
+	case TSTRUCT:
+		// Walk the struct using memhash for runs of AMEM
+		// and calling specific hash functions for the others.
+		first = T;
+		offend = 0;
+		for(t1=t->type;; t1=t1->down) {
+			if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
+				offend = t1->width + t1->type->width;
+				if(first == T)
+					first = t1;
+				// If it's a memory field but it's padded, stop here.
+				if(ispaddedfield(t1, t->width))
+					t1 = t1->down;
+				else
+					continue;
+			}
+			// Run memhash for fields up to this one.
+			if(first != T) {
+				size = offend - first->width; // first->width is offset
+				hashel = hashmem(first->type);
+				// h = hashel(&p.first, size, h)
+				call = nod(OCALL, hashel, N);
+				nx = nod(OXDOT, np, newname(first->sym));  // TODO: fields from other packages?
+				na = nod(OADDR, nx, N);
+				na->etype = 1;  // no escape to heap
+				call->list = list(call->list, na);
+				call->list = list(call->list, nodintconst(size));
+				call->list = list(call->list, nh);
+				fn->nbody = list(fn->nbody, nod(OAS, nh, call));
+
+				first = T;
+			}
+			if(t1 == T)
+				break;
+			if(isblanksym(t1->sym))
+				continue;
+
+			// Run hash for this field.
+			hashel = hashfor(t1->type);
+			// h = hashel(&p.t1, size, h)
+			call = nod(OCALL, hashel, N);
+			nx = nod(OXDOT, np, newname(t1->sym));  // TODO: fields from other packages?
+			na = nod(OADDR, nx, N);
+			na->etype = 1;  // no escape to heap
+			call->list = list(call->list, na);
+			call->list = list(call->list, nodintconst(t1->type->width));
+			call->list = list(call->list, nh);
+			fn->nbody = list(fn->nbody, nod(OAS, nh, call));
+		}
+		break;
+	}
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nh);
+	fn->nbody = list(fn->nbody, r);
+
+	if(debug['r'])
+		dumplist("genhash body", fn->nbody);
+
+	funcbody(fn);
+	curfn = fn;
+	fn->dupok = 1;
+	typecheck(&fn, Etop);
+	typechecklist(fn->nbody, Etop);
+	curfn = nil;
+
+	// 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;
+	funccompile(fn, 0);
+	safemode = old_safemode;
+}
+
+// Return node for
+//	if p.field != q.field { return false }
+static Node*
+eqfield(Node *p, Node *q, Node *field)
+{
+	Node *nif, *nx, *ny, *r;
+
+	nx = nod(OXDOT, p, field);
+	ny = nod(OXDOT, q, field);
+	nif = nod(OIF, N, N);
+	nif->ntest = nod(ONE, nx, ny);
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(0));
+	nif->nbody = list(nif->nbody, r);
+	return nif;
+}
+
+static Node*
+eqmemfunc(vlong size, Type *type)
+{
+	char buf[30];
+	Node *fn;
+
+	switch(size) {
+	default:
+		fn = syslook("memequal", 1);
+		break;
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+	case 16:
+		snprint(buf, sizeof buf, "memequal%d", (int)size*8);
+		fn = syslook(buf, 1);
+		break;
+	}
+	argtype(fn, type);
+	argtype(fn, type);
+	return fn;
+}
+
+// Return node for
+//	if !memequal(&p.field, &q.field, size) { return false }
+static Node*
+eqmem(Node *p, Node *q, Node *field, vlong size)
+{
+	Node *nif, *nx, *ny, *call, *r;
+
+	nx = nod(OADDR, nod(OXDOT, p, field), N);
+	nx->etype = 1;  // does not escape
+	ny = nod(OADDR, nod(OXDOT, q, field), N);
+	ny->etype = 1;  // does not escape
+	typecheck(&nx, Erv);
+	typecheck(&ny, Erv);
+
+	call = nod(OCALL, eqmemfunc(size, nx->type->type), N);
+	call->list = list(call->list, nx);
+	call->list = list(call->list, ny);
+	call->list = list(call->list, nodintconst(size));
+
+	nif = nod(OIF, N, N);
+	nif->ninit = list(nif->ninit, call);
+	nif->ntest = nod(ONOT, call, N);
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(0));
+	nif->nbody = list(nif->nbody, r);
+	return nif;
+}
+
+/*
+ * Generate a helper function to check equality of two values of type t.
+ */
+void
+geneq(Sym *sym, Type *t)
+{
+	Node *n, *fn, *np, *nq, *tfn, *nif, *ni, *nx, *ny, *nrange, *r;
+	Type *t1, *first;
+	int old_safemode;
+	int64 size;
+	int64 offend;
+
+	if(debug['r'])
+		print("geneq %S %T\n", sym, t);
+
+	lineno = 1;  // less confusing than end of input
+	dclcontext = PEXTERN;
+	markdcl();
+
+	// func sym(p, q *T, s uintptr) bool
+	fn = nod(ODCLFUNC, N, N);
+	fn->nname = newname(sym);
+	fn->nname->class = PFUNC;
+	tfn = nod(OTFUNC, N, N);
+	fn->nname->ntype = tfn;
+
+	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
+	tfn->list = list(tfn->list, n);
+	np = n->left;
+	n = nod(ODCLFIELD, newname(lookup("q")), typenod(ptrto(t)));
+	tfn->list = list(tfn->list, n);
+	nq = n->left;
+	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
+	tfn->list = list(tfn->list, n);
+	n = nod(ODCLFIELD, N, typenod(types[TBOOL]));
+	tfn->rlist = list(tfn->rlist, n);
+
+	funchdr(fn);
+
+	// geneq is only called for types that have equality but
+	// cannot be handled by the standard algorithms,
+	// so t must be either an array or a struct.
+	switch(t->etype) {
+	default:
+		fatal("geneq %T", t);
+	case TARRAY:
+		if(isslice(t))
+			fatal("geneq %T", t);
+		// An array of pure memory would be handled by the
+		// standard memequal, so the element type must not be
+		// pure memory.  Even if we unrolled the range loop,
+		// each iteration would be a function call, so don't bother
+		// unrolling.
+		nrange = nod(ORANGE, N, nod(OIND, np, N));
+		ni = newname(lookup("i"));
+		ni->type = types[TINT];
+		nrange->list = list1(ni);
+		nrange->colas = 1;
+		colasdefn(nrange->list, nrange);
+		ni = nrange->list->n;
+		
+		// if p[i] != q[i] { return false }
+		nx = nod(OINDEX, np, ni);
+		nx->bounded = 1;
+		ny = nod(OINDEX, nq, ni);
+		ny->bounded = 1;
+
+		nif = nod(OIF, N, N);
+		nif->ntest = nod(ONE, nx, ny);
+		r = nod(ORETURN, N, N);
+		r->list = list(r->list, nodbool(0));
+		nif->nbody = list(nif->nbody, r);
+		nrange->nbody = list(nrange->nbody, nif);
+		fn->nbody = list(fn->nbody, nrange);
+		break;
+
+	case TSTRUCT:
+		// Walk the struct using memequal for runs of AMEM
+		// and calling specific equality tests for the others.
+		// Skip blank-named fields.
+		first = T;
+		offend = 0;
+		for(t1=t->type;; t1=t1->down) {
+			if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
+				offend = t1->width + t1->type->width;
+				if(first == T)
+					first = t1;
+				// If it's a memory field but it's padded, stop here.
+				if(ispaddedfield(t1, t->width))
+					t1 = t1->down;
+				else
+					continue;
+			}
+			// Run memequal for fields up to this one.
+			// TODO(rsc): All the calls to newname are wrong for
+			// cross-package unexported fields.
+			if(first != T) {
+				if(first->down == t1) {
+					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
+				} else if(first->down->down == t1) {
+					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
+					first = first->down;
+					if(!isblanksym(first->sym))
+						fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
+				} else {
+					// More than two fields: use memequal.
+					size = offend - first->width; // first->width is offset
+					fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size));
+				}
+				first = T;
+			}
+			if(t1 == T)
+				break;
+			if(isblanksym(t1->sym))
+				continue;
+
+			// Check this field, which is not just memory.
+			fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym)));
+		}
+
+		break;
+	}
+
+	// return true
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(1));
+	fn->nbody = list(fn->nbody, r);
+
+	if(debug['r'])
+		dumplist("geneq body", fn->nbody);
+
+	funcbody(fn);
+	curfn = fn;
+	fn->dupok = 1;
+	typecheck(&fn, Etop);
+	typechecklist(fn->nbody, Etop);
+	curfn = nil;
+	
+	// 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;
+	funccompile(fn, 0);
+	safemode = old_safemode;
+}
+
+static Type*
+ifacelookdot(Sym *s, Type *t, int *followptr, int ignorecase)
+{
+	int i, c, d;
+	Type *m;
+
+	*followptr = 0;
+
+	if(t == T)
+		return T;
+
+	for(d=0; d<nelem(dotlist); d++) {
+		c = adddot1(s, t, d, &m, ignorecase);
+		if(c > 1) {
+			yyerror("%T.%S is ambiguous", t, s);
+			return T;
+		}
+		if(c == 1) {
+			for(i=0; i<d; i++) {
+				if(isptr[dotlist[i].field->type->etype]) {
+					*followptr = 1;
+					break;
+				}
+			}
+			if(m->type->etype != TFUNC || m->type->thistuple == 0) {
+				yyerror("%T.%S is a field, not a method", t, s);
+				return T;
+			}
+			return m;
+		}
+	}
+	return T;
+}
+
+int
+implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr)
+{
+	Type *t0, *im, *tm, *rcvr, *imtype;
+	int followptr;
+
+	t0 = t;
+	if(t == T)
+		return 0;
+
+	// if this is too slow,
+	// could sort these first
+	// and then do one loop.
+
+	if(t->etype == TINTER) {
+		for(im=iface->type; im; im=im->down) {
+			for(tm=t->type; tm; tm=tm->down) {
+				if(tm->sym == im->sym) {
+					if(eqtype(tm->type, im->type))
+						goto found;
+					*m = im;
+					*samename = tm;
+					*ptr = 0;
+					return 0;
+				}
+			}
+			*m = im;
+			*samename = nil;
+			*ptr = 0;
+			return 0;
+		found:;
+		}
+		return 1;
+	}
+
+	t = methtype(t, 0);
+	if(t != T)
+		expandmeth(t);
+	for(im=iface->type; im; im=im->down) {
+		imtype = methodfunc(im->type, 0);
+		tm = ifacelookdot(im->sym, t, &followptr, 0);
+		if(tm == T || tm->nointerface || !eqtype(methodfunc(tm->type, 0), imtype)) {
+			if(tm == T)
+				tm = ifacelookdot(im->sym, t, &followptr, 1);
+			*m = im;
+			*samename = tm;
+			*ptr = 0;
+			return 0;
+		}
+		// if pointer receiver in method,
+		// the method does not exist for value types.
+		rcvr = getthisx(tm->type)->type->type;
+		if(isptr[rcvr->etype] && !isptr[t0->etype] && !followptr && !isifacemethod(tm->type)) {
+			if(0 && debug['r'])
+				yyerror("interface pointer mismatch");
+
+			*m = im;
+			*samename = nil;
+			*ptr = 1;
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/*
+ * even simpler simtype; get rid of ptr, bool.
+ * assuming that the front end has rejected
+ * all the invalid conversions (like ptr -> bool)
+ */
+int
+simsimtype(Type *t)
+{
+	int et;
+
+	if(t == 0)
+		return 0;
+
+	et = simtype[t->etype];
+	switch(et) {
+	case TPTR32:
+		et = TUINT32;
+		break;
+	case TPTR64:
+		et = TUINT64;
+		break;
+	case TBOOL:
+		et = TUINT8;
+		break;
+	}
+	return et;
+}
+
+NodeList*
+concat(NodeList *a, NodeList *b)
+{
+	if(a == nil)
+		return b;
+	if(b == nil)
+		return a;
+
+	a->end->next = b;
+	a->end = b->end;
+	b->end = nil;
+	return a;
+}
+
+NodeList*
+list1(Node *n)
+{
+	NodeList *l;
+
+	if(n == nil)
+		return nil;
+	if(n->op == OBLOCK && n->ninit == nil) {
+		// Flatten list and steal storage.
+		// Poison pointer to catch errant uses.
+		l = n->list;
+		n->list = (NodeList*)1;
+		return l;
+	}
+	l = mal(sizeof *l);
+	l->n = n;
+	l->end = l;
+	return l;
+}
+
+NodeList*
+list(NodeList *l, Node *n)
+{
+	return concat(l, list1(n));
+}
+
+void
+listsort(NodeList** l, int(*f)(Node*, Node*))
+{
+	NodeList *l1, *l2, *le;
+
+	if(*l == nil || (*l)->next == nil)
+		return;
+
+	l1 = *l;
+	l2 = *l;
+	for(;;) {
+		l2 = l2->next;
+		if(l2 == nil)
+			break;
+		l2 = l2->next;
+		if(l2 == nil)
+			break;
+		l1 = l1->next;
+	}
+
+	l2 = l1->next;
+	l1->next = nil;
+	l2->end = (*l)->end;
+	(*l)->end = l1;
+
+	l1 = *l;
+	listsort(&l1, f);
+	listsort(&l2, f);
+
+	if((*f)(l1->n, l2->n) < 0) {
+		*l = l1;
+	} else {
+		*l = l2;
+		l2 = l1;
+		l1 = *l;
+	}
+
+	// now l1 == *l; and l1 < l2
+
+	while ((l1 != nil) && (l2 != nil)) {
+		while ((l1->next != nil) && (*f)(l1->next->n, l2->n) < 0)
+			l1 = l1->next;
+		
+		// l1 is last one from l1 that is < l2
+		le = l1->next;		// le is the rest of l1, first one that is >= l2
+		if(le != nil)
+			le->end = (*l)->end;
+
+		(*l)->end = l1;		// cut *l at l1
+		*l = concat(*l, l2);	// glue l2 to *l's tail
+
+		l1 = l2;		// l1 is the first element of *l that is < the new l2
+		l2 = le;		// ... because l2 now is the old tail of l1
+	}
+
+	*l = concat(*l, l2);		// any remainder 
+}
+
+NodeList*
+listtreecopy(NodeList *l)
+{
+	NodeList *out;
+
+	out = nil;
+	for(; l; l=l->next)
+		out = list(out, treecopy(l->n));
+	return out;
+}
+
+Node*
+liststmt(NodeList *l)
+{
+	Node *n;
+
+	n = nod(OBLOCK, N, N);
+	n->list = l;
+	if(l)
+		n->lineno = l->n->lineno;
+	return n;
+}
+
+/*
+ * return nelem of list
+ */
+int
+count(NodeList *l)
+{
+	vlong n;
+
+	n = 0;
+	for(; l; l=l->next)
+		n++;
+	if((int)n != n) { // Overflow.
+		yyerror("too many elements in list");
+	}
+	return n;
+}
+
+/*
+ * return nelem of list
+ */
+int
+structcount(Type *t)
+{
+	int v;
+	Iter s;
+
+	v = 0;
+	for(t = structfirst(&s, &t); t != T; t = structnext(&s))
+		v++;
+	return v;
+}
+
+/*
+ * return power of 2 of the constant
+ * operand. -1 if it is not a power of 2.
+ * 1000+ if it is a -(power of 2)
+ */
+int
+powtwo(Node *n)
+{
+	uvlong v, b;
+	int i;
+
+	if(n == N || n->op != OLITERAL || n->type == T)
+		goto no;
+	if(!isint[n->type->etype])
+		goto no;
+
+	v = mpgetfix(n->val.u.xval);
+	b = 1ULL;
+	for(i=0; i<64; i++) {
+		if(b == v)
+			return i;
+		b = b<<1;
+	}
+
+	if(!issigned[n->type->etype])
+		goto no;
+
+	v = -v;
+	b = 1ULL;
+	for(i=0; i<64; i++) {
+		if(b == v)
+			return i+1000;
+		b = b<<1;
+	}
+
+no:
+	return -1;
+}
+
+/*
+ * return the unsigned type for
+ * a signed integer type.
+ * returns T if input is not a
+ * signed integer type.
+ */
+Type*
+tounsigned(Type *t)
+{
+
+	// this is types[et+1], but not sure
+	// that this relation is immutable
+	switch(t->etype) {
+	default:
+		print("tounsigned: unknown type %T\n", t);
+		t = T;
+		break;
+	case TINT:
+		t = types[TUINT];
+		break;
+	case TINT8:
+		t = types[TUINT8];
+		break;
+	case TINT16:
+		t = types[TUINT16];
+		break;
+	case TINT32:
+		t = types[TUINT32];
+		break;
+	case TINT64:
+		t = types[TUINT64];
+		break;
+	}
+	return t;
+}
+
+/*
+ * magic number for signed division
+ * see hacker's delight chapter 10
+ */
+void
+smagic(Magic *m)
+{
+	int p;
+	uint64 ad, anc, delta, q1, r1, q2, r2, t;
+	uint64 mask, two31;
+
+	m->bad = 0;
+	switch(m->w) {
+	default:
+		m->bad = 1;
+		return;
+	case 8:
+		mask = 0xffLL;
+		break;
+	case 16:
+		mask = 0xffffLL;
+		break;
+	case 32:
+		mask = 0xffffffffLL;
+		break;
+	case 64:
+		mask = 0xffffffffffffffffULL;
+		break;
+	}
+	two31 = mask ^ (mask>>1);
+
+	p = m->w-1;
+	ad = m->sd;
+	if(m->sd < 0)
+		ad = -(uvlong)m->sd;
+
+	// bad denominators
+	if(ad == 0 || ad == 1 || ad == two31) {
+		m->bad = 1;
+		return;
+	}
+
+	t = two31;
+	ad &= mask;
+
+	anc = t - 1 - t%ad;
+	anc &= mask;
+
+	q1 = two31/anc;
+	r1 = two31 - q1*anc;
+	q1 &= mask;
+	r1 &= mask;
+
+	q2 = two31/ad;
+	r2 = two31 - q2*ad;
+	q2 &= mask;
+	r2 &= mask;
+
+	for(;;) {
+		p++;
+		q1 <<= 1;
+		r1 <<= 1;
+		q1 &= mask;
+		r1 &= mask;
+		if(r1 >= anc) {
+			q1++;
+			r1 -= anc;
+			q1 &= mask;
+			r1 &= mask;
+		}
+
+		q2 <<= 1;
+		r2 <<= 1;
+		q2 &= mask;
+		r2 &= mask;
+		if(r2 >= ad) {
+			q2++;
+			r2 -= ad;
+			q2 &= mask;
+			r2 &= mask;
+		}
+
+		delta = ad - r2;
+		delta &= mask;
+		if(q1 < delta || (q1 == delta && r1 == 0)) {
+			continue;
+		}
+		break;
+	}
+
+	m->sm = q2+1;
+	if(m->sm & two31)
+		m->sm |= ~mask;
+	m->s = p-m->w;
+}
+
+/*
+ * magic number for unsigned division
+ * see hacker's delight chapter 10
+ */
+void
+umagic(Magic *m)
+{
+	int p;
+	uint64 nc, delta, q1, r1, q2, r2;
+	uint64 mask, two31;
+
+	m->bad = 0;
+	m->ua = 0;
+
+	switch(m->w) {
+	default:
+		m->bad = 1;
+		return;
+	case 8:
+		mask = 0xffLL;
+		break;
+	case 16:
+		mask = 0xffffLL;
+		break;
+	case 32:
+		mask = 0xffffffffLL;
+		break;
+	case 64:
+		mask = 0xffffffffffffffffULL;
+		break;
+	}
+	two31 = mask ^ (mask>>1);
+
+	m->ud &= mask;
+	if(m->ud == 0 || m->ud == two31) {
+		m->bad = 1;
+		return;
+	}
+	nc = mask - (-m->ud&mask)%m->ud;
+	p = m->w-1;
+
+	q1 = two31/nc;
+	r1 = two31 - q1*nc;
+	q1 &= mask;
+	r1 &= mask;
+
+	q2 = (two31-1) / m->ud;
+	r2 = (two31-1) - q2*m->ud;
+	q2 &= mask;
+	r2 &= mask;
+
+	for(;;) {
+		p++;
+		if(r1 >= nc-r1) {
+			q1 <<= 1;
+			q1++;
+			r1 <<= 1;
+			r1 -= nc;
+		} else {
+			q1 <<= 1;
+			r1 <<= 1;
+		}
+		q1 &= mask;
+		r1 &= mask;
+		if(r2+1 >= m->ud-r2) {
+			if(q2 >= two31-1) {
+				m->ua = 1;
+			}
+			q2 <<= 1;
+			q2++;
+			r2 <<= 1;
+			r2++;
+			r2 -= m->ud;
+		} else {
+			if(q2 >= two31) {
+				m->ua = 1;
+			}
+			q2 <<= 1;
+			r2 <<= 1;
+			r2++;
+		}
+		q2 &= mask;
+		r2 &= mask;
+
+		delta = m->ud - 1 - r2;
+		delta &= mask;
+
+		if(p < m->w+m->w)
+		if(q1 < delta || (q1 == delta && r1 == 0)) {
+			continue;
+		}
+		break;
+	}
+	m->um = q2+1;
+	m->s = p-m->w;
+}
+
+Sym*
+ngotype(Node *n)
+{
+	if(n->type != T)
+		return typenamesym(n->type);
+	return S;
+}
+
+/*
+ * Convert raw string to the prefix that will be used in the symbol
+ * table.  All control characters, space, '%' and '"', as well as
+ * non-7-bit clean bytes turn into %xx.  The period needs escaping
+ * only in the last segment of the path, and it makes for happier
+ * users if we escape that as little as possible.
+ *
+ * If you edit this, edit ../ld/lib.c:/^pathtoprefix too.
+ * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
+ */
+static char*
+pathtoprefix(char *s)
+{
+	static char hex[] = "0123456789abcdef";
+	char *p, *r, *w, *l;
+	int n;
+
+	// find first character past the last slash, if any.
+	l = s;
+	for(r=s; *r; r++)
+		if(*r == '/')
+			l = r+1;
+
+	// check for chars that need escaping
+	n = 0;
+	for(r=s; *r; r++)
+		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f)
+			n++;
+
+	// quick exit
+	if(n == 0)
+		return s;
+
+	// escape
+	p = mal((r-s)+1+2*n);
+	for(r=s, w=p; *r; r++) {
+		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) {
+			*w++ = '%';
+			*w++ = hex[(*r>>4)&0xF];
+			*w++ = hex[*r&0xF];
+		} else
+			*w++ = *r;
+	}
+	*w = '\0';
+	return p;
+}
+
+Pkg*
+mkpkg(Strlit *path)
+{
+	Pkg *p;
+	int h;
+
+	h = stringhash(path->s) & (nelem(phash)-1);
+	for(p=phash[h]; p; p=p->link)
+		if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0)
+			return p;
+
+	p = mal(sizeof *p);
+	p->path = path;
+	p->prefix = pathtoprefix(path->s);
+	p->link = phash[h];
+	phash[h] = p;
+	return p;
+}
+
+Strlit*
+strlit(char *s)
+{
+	Strlit *t;
+	
+	t = mal(sizeof *t + strlen(s));
+	strcpy(t->s, s);
+	t->len = strlen(s);
+	return t;
+}
+
+void
+addinit(Node **np, NodeList *init)
+{
+	Node *n;
+	
+	if(init == nil)
+		return;
+
+	n = *np;
+	switch(n->op) {
+	case ONAME:
+	case OLITERAL:
+		// There may be multiple refs to this node;
+		// introduce OCONVNOP to hold init list.
+		n = nod(OCONVNOP, n, N);
+		n->type = n->left->type;
+		n->typecheck = 1;
+		*np = n;
+		break;
+	}
+	n->ninit = concat(init, n->ninit);
+	n->ullman = UINF;
+}
+
+static char* reservedimports[] = {
+	"go",
+	"type",
+};
+
+int
+isbadimport(Strlit *path)
+{
+	int i;
+	char *s;
+	Rune r;
+
+	if(strlen(path->s) != path->len) {
+		yyerror("import path contains NUL");
+		return 1;
+	}
+	
+	for(i=0; i<nelem(reservedimports); i++) {
+		if(strcmp(path->s, reservedimports[i]) == 0) {
+			yyerror("import path \"%s\" is reserved and cannot be used", path->s);
+			return 1;
+		}
+	}
+
+	s = path->s;
+	while(*s) {
+		s += chartorune(&r, s);
+		if(r == Runeerror) {
+			yyerror("import path contains invalid UTF-8 sequence: \"%Z\"", path);
+			return 1;
+		}
+		if(r < 0x20 || r == 0x7f) {
+			yyerror("import path contains control character: \"%Z\"", path);
+			return 1;
+		}
+		if(r == '\\') {
+			yyerror("import path contains backslash; use slash: \"%Z\"", path);
+			return 1;
+		}
+		if(isspacerune(r)) {
+			yyerror("import path contains space character: \"%Z\"", path);
+			return 1;
+		}
+		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
+			yyerror("import path contains invalid character '%C': \"%Z\"", r, path);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void
+checknil(Node *x, NodeList **init)
+{
+	Node *n;
+	
+	if(isinter(x->type)) {
+		x = nod(OITAB, x, N);
+		typecheck(&x, Erv);
+	}
+	n = nod(OCHECKNIL, x, N);
+	n->typecheck = 1;
+	*init = list(*init, n);
+}
+
+/*
+ * Can this type be stored directly in an interface word?
+ */
+int
+isdirectiface(Type *t)
+{
+	// Setting IfacePointerOnly = 1 changes the
+	// interface representation so that the data word
+	// in an interface value must always be a pointer.
+	// Setting it to 0 uses the original representation,
+	// where the data word can hold a pointer or any
+	// non-pointer value no bigger than a pointer.
+	enum {
+		IfacePointerOnly = 1,
+	};
+
+	if(IfacePointerOnly) {
+		switch(t->etype) {
+		case TPTR32:
+		case TPTR64:
+		case TCHAN:
+		case TMAP:
+		case TFUNC:
+		case TUNSAFEPTR:
+			return 1;
+		case TARRAY:
+			// Array of 1 direct iface type can be direct.
+			return t->bound == 1 && isdirectiface(t->type);
+		case TSTRUCT:
+			// Struct with 1 field of direct iface type can be direct.
+			return t->type != T && t->type->down == T && isdirectiface(t->type->type);
+		}
+		return 0;
+	}
+	
+	dowidth(t);
+	return t->width <= widthptr;
+}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
new file mode 100644
index 0000000..e1d8af8
--- /dev/null
+++ b/src/cmd/gc/swt.c
@@ -0,0 +1,948 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+
+enum
+{
+	Snorm		= 0,
+	Strue,
+	Sfalse,
+	Stype,
+
+	Tdefault,	// default case
+	Texprconst,	// normal constant case
+	Texprvar,	// normal variable case
+	Ttypenil,	// case nil
+	Ttypeconst,	// type hashes
+	Ttypevar,	// interface type
+
+	Ncase	= 4,	// count needed to split
+};
+
+typedef	struct	Case	Case;
+struct	Case
+{
+	Node*	node;		// points at case statement
+	uint32	hash;		// hash of a type switch
+	uint8	type;		// type of case
+	uint8	diag;		// suppress multiple diagnostics
+	uint16	ordinal;	// position in switch
+	Case*	link;		// linked list to link
+};
+#define	C	((Case*)nil)
+/*c2go Case *C; */
+
+void
+dumpcase(Case *c0)
+{
+	Case *c;
+
+	for(c=c0; c!=C; c=c->link) {
+		switch(c->type) {
+		case Tdefault:
+			print("case-default\n");
+			print("	ord=%d\n", c->ordinal);
+			break;
+		case Texprconst:
+			print("case-exprconst\n");
+			print("	ord=%d\n", c->ordinal);
+			break;
+		case Texprvar:
+			print("case-exprvar\n");
+			print("	ord=%d\n", c->ordinal);
+			print("	op=%O\n", c->node->left->op);
+			break;
+		case Ttypenil:
+			print("case-typenil\n");
+			print("	ord=%d\n", c->ordinal);
+			break;
+		case Ttypeconst:
+			print("case-typeconst\n");
+			print("	ord=%d\n", c->ordinal);
+			print("	hash=%ux\n", c->hash);
+			break;
+		case Ttypevar:
+			print("case-typevar\n");
+			print("	ord=%d\n", c->ordinal);
+			break;
+		default:
+			print("case-???\n");
+			print("	ord=%d\n", c->ordinal);
+			print("	op=%O\n", c->node->left->op);
+			print("	hash=%ux\n", c->hash);
+			break;
+		}
+	}
+	print("\n");
+}
+
+static int
+ordlcmp(Case *c1, Case *c2)
+{
+	// sort default first
+	if(c1->type == Tdefault)
+		return -1;
+	if(c2->type == Tdefault)
+		return +1;
+
+	// sort nil second
+	if(c1->type == Ttypenil)
+		return -1;
+	if(c2->type == Ttypenil)
+		return +1;
+
+	// sort by ordinal
+	if(c1->ordinal > c2->ordinal)
+		return +1;
+	if(c1->ordinal < c2->ordinal)
+		return -1;
+	return 0;
+}
+
+static int
+exprcmp(Case *c1, Case *c2)
+{
+	int ct, n;
+	Node *n1, *n2;
+
+	// sort non-constants last
+	if(c1->type != Texprconst)
+		return +1;
+	if(c2->type != Texprconst)
+		return -1;
+
+	n1 = c1->node->left;
+	n2 = c2->node->left;
+
+	// sort by type (for switches on interface)
+	ct = n1->val.ctype;
+	if(ct != n2->val.ctype)
+		return ct - n2->val.ctype;
+	if(!eqtype(n1->type, n2->type)) {
+		if(n1->type->vargen > n2->type->vargen)
+			return +1;
+		else
+			return -1;
+	}
+
+	// sort by constant value
+	n = 0;
+	switch(ct) {
+	case CTFLT:
+		n = mpcmpfltflt(n1->val.u.fval, n2->val.u.fval);
+		break;
+	case CTINT:
+	case CTRUNE:
+		n = mpcmpfixfix(n1->val.u.xval, n2->val.u.xval);
+		break;
+	case CTSTR:
+		n = cmpslit(n1, n2);
+		break;
+	}
+
+	return n;
+}
+
+static int
+typecmp(Case *c1, Case *c2)
+{
+
+	// sort non-constants last
+	if(c1->type != Ttypeconst)
+		return +1;
+	if(c2->type != Ttypeconst)
+		return -1;
+
+	// sort by hash code
+	if(c1->hash > c2->hash)
+		return +1;
+	if(c1->hash < c2->hash)
+		return -1;
+
+	// sort by ordinal so duplicate error
+	// happens on later case.
+	if(c1->ordinal > c2->ordinal)
+		return +1;
+	if(c1->ordinal < c2->ordinal)
+		return -1;
+	return 0;
+}
+
+static Case*
+csort(Case *l, int(*f)(Case*, Case*))
+{
+	Case *l1, *l2, *le;
+
+	if(l == C || l->link == C)
+		return l;
+
+	l1 = l;
+	l2 = l;
+	for(;;) {
+		l2 = l2->link;
+		if(l2 == C)
+			break;
+		l2 = l2->link;
+		if(l2 == C)
+			break;
+		l1 = l1->link;
+	}
+
+	l2 = l1->link;
+	l1->link = C;
+	l1 = csort(l, f);
+	l2 = csort(l2, f);
+
+	/* set up lead element */
+	if((*f)(l1, l2) < 0) {
+		l = l1;
+		l1 = l1->link;
+	} else {
+		l = l2;
+		l2 = l2->link;
+	}
+	le = l;
+
+	for(;;) {
+		if(l1 == C) {
+			while(l2) {
+				le->link = l2;
+				le = l2;
+				l2 = l2->link;
+			}
+			le->link = C;
+			break;
+		}
+		if(l2 == C) {
+			while(l1) {
+				le->link = l1;
+				le = l1;
+				l1 = l1->link;
+			}
+			break;
+		}
+		if((*f)(l1, l2) < 0) {
+			le->link = l1;
+			le = l1;
+			l1 = l1->link;
+		} else {
+			le->link = l2;
+			le = l2;
+			l2 = l2->link;
+		}
+	}
+	le->link = C;
+	return l;
+}
+
+static Node*
+newlabel(void)
+{
+	static int label;
+
+	label++;
+	snprint(namebuf, sizeof(namebuf), "%.6d", label);
+	return newname(lookup(namebuf));
+}
+
+/*
+ * build separate list of statements and cases
+ * make labels between cases and statements
+ * deal with fallthrough, break, unreachable statements
+ */
+static void
+casebody(Node *sw, Node *typeswvar)
+{
+	Node *n, *c, *last;
+	Node *def;
+	NodeList *cas, *stat, *l, *lc;
+	Node *go, *br;
+	int32 lno, needvar;
+
+	if(sw->list == nil)
+		return;
+
+	lno = setlineno(sw);
+
+	cas = nil;	// cases
+	stat = nil;	// statements
+	def = N;	// defaults
+	br = nod(OBREAK, N, N);
+
+	for(l=sw->list; l; l=l->next) {
+		n = l->n;
+		setlineno(n);
+		if(n->op != OXCASE)
+			fatal("casebody %O", n->op);
+		n->op = OCASE;
+		needvar = count(n->list) != 1 || n->list->n->op == OLITERAL;
+
+		go = nod(OGOTO, newlabel(), N);
+		if(n->list == nil) {
+			if(def != N)
+				yyerror("more than one default case");
+			// reuse original default case
+			n->right = go;
+			def = n;
+		}
+
+		if(n->list != nil && n->list->next == nil) {
+			// one case - reuse OCASE node.
+			c = n->list->n;
+			n->left = c;
+			n->right = go;
+			n->list = nil;
+			cas = list(cas, n);
+		} else {
+			// expand multi-valued cases
+			for(lc=n->list; lc; lc=lc->next) {
+				c = lc->n;
+				cas = list(cas, nod(OCASE, c, go));
+			}
+		}
+
+		stat = list(stat, nod(OLABEL, go->left, N));
+		if(typeswvar && needvar && n->nname != N) {
+			NodeList *l;
+
+			l = list1(nod(ODCL, n->nname, N));
+			l = list(l, nod(OAS, n->nname, typeswvar));
+			typechecklist(l, Etop);
+			stat = concat(stat, l);
+		}
+		stat = concat(stat, n->nbody);
+
+		// botch - shouldn't fall thru declaration
+		last = stat->end->n;
+		if(last->xoffset == n->xoffset && last->op == OXFALL) {
+			if(typeswvar) {
+				setlineno(last);
+				yyerror("cannot fallthrough in type switch");
+			}
+			if(l->next == nil) {
+				setlineno(last);
+				yyerror("cannot fallthrough final case in switch");
+			}
+			last->op = OFALL;
+		} else
+			stat = list(stat, br);
+	}
+
+	stat = list(stat, br);
+	if(def)
+		cas = list(cas, def);
+
+	sw->list = cas;
+	sw->nbody = stat;
+	lineno = lno;
+}
+
+static Case*
+mkcaselist(Node *sw, int arg)
+{
+	Node *n;
+	Case *c, *c1, *c2;
+	NodeList *l;
+	int ord;
+
+	c = C;
+	ord = 0;
+
+	for(l=sw->list; l; l=l->next) {
+		n = l->n;
+		c1 = mal(sizeof(*c1));
+		c1->link = c;
+		c = c1;
+
+		ord++;
+		if((uint16)ord != ord)
+			fatal("too many cases in switch");
+		c->ordinal = ord;
+		c->node = n;
+
+		if(n->left == N) {
+			c->type = Tdefault;
+			continue;
+		}
+
+		switch(arg) {
+		case Stype:
+			c->hash = 0;
+			if(n->left->op == OLITERAL) {
+				c->type = Ttypenil;
+				continue;
+			}
+			if(istype(n->left->type, TINTER)) {
+				c->type = Ttypevar;
+				continue;
+			}
+
+			c->hash = typehash(n->left->type);
+			c->type = Ttypeconst;
+			continue;
+
+		case Snorm:
+		case Strue:
+		case Sfalse:
+			c->type = Texprvar;
+			c->hash = typehash(n->left->type);
+			switch(consttype(n->left)) {
+			case CTFLT:
+			case CTINT:
+			case CTRUNE:
+			case CTSTR:
+				c->type = Texprconst;
+			}
+			continue;
+		}
+	}
+
+	if(c == C)
+		return C;
+
+	// sort by value and diagnose duplicate cases
+	switch(arg) {
+	case Stype:
+		c = csort(c, typecmp);
+		for(c1=c; c1!=C; c1=c1->link) {
+			for(c2=c1->link; c2!=C && c2->hash==c1->hash; c2=c2->link) {
+				if(c1->type == Ttypenil || c1->type == Tdefault)
+					break;
+				if(c2->type == Ttypenil || c2->type == Tdefault)
+					break;
+				if(!eqtype(c1->node->left->type, c2->node->left->type))
+					continue;
+				yyerrorl(c2->node->lineno, "duplicate case %T in type switch\n\tprevious case at %L", c2->node->left->type, c1->node->lineno);
+			}
+		}
+		break;
+	case Snorm:
+	case Strue:
+	case Sfalse:
+		c = csort(c, exprcmp);
+		for(c1=c; c1->link!=C; c1=c1->link) {
+			if(exprcmp(c1, c1->link) != 0)
+				continue;
+			setlineno(c1->link->node);
+			yyerror("duplicate case %N in switch\n\tprevious case at %L", c1->node->left, c1->node->lineno);
+		}
+		break;
+	}
+
+	// put list back in processing order
+	c = csort(c, ordlcmp);
+	return c;
+}
+
+static	Node*	exprname;
+
+static Node*
+exprbsw(Case *c0, int ncase, int arg)
+{
+	NodeList *cas;
+	Node *a, *n;
+	Case *c;
+	int i, half, lno;
+
+	cas = nil;
+	if(ncase < Ncase) {
+		for(i=0; i<ncase; i++) {
+			n = c0->node;
+			lno = setlineno(n);
+
+			if(assignop(n->left->type, exprname->type, nil) == OCONVIFACE ||
+			   assignop(exprname->type, n->left->type, nil) == OCONVIFACE)
+				goto snorm;
+
+			switch(arg) {
+			case Strue:
+				a = nod(OIF, N, N);
+				a->ntest = n->left;			// if val
+				a->nbody = list1(n->right);			// then goto l
+				break;
+
+			case Sfalse:
+				a = nod(OIF, N, N);
+				a->ntest = nod(ONOT, n->left, N);	// if !val
+				typecheck(&a->ntest, Erv);
+				a->nbody = list1(n->right);			// then goto l
+				break;
+
+			default:
+			snorm:
+				a = nod(OIF, N, N);
+				a->ntest = nod(OEQ, exprname, n->left);	// if name == val
+				typecheck(&a->ntest, Erv);
+				a->nbody = list1(n->right);			// then goto l
+				break;
+			}
+
+			cas = list(cas, a);
+			c0 = c0->link;
+			lineno = lno;
+		}
+		return liststmt(cas);
+	}
+
+	// find the middle and recur
+	c = c0;
+	half = ncase>>1;
+	for(i=1; i<half; i++)
+		c = c->link;
+	a = nod(OIF, N, N);
+	a->ntest = nod(OLE, exprname, c->node->left);
+	typecheck(&a->ntest, Erv);
+	a->nbody = list1(exprbsw(c0, half, arg));
+	a->nelse = list1(exprbsw(c->link, ncase-half, arg));
+	return a;
+}
+
+/*
+ * normal (expression) switch.
+ * rebulid case statements into if .. goto
+ */
+static void
+exprswitch(Node *sw)
+{
+	Node *def;
+	NodeList *cas;
+	Node *a;
+	Case *c0, *c, *c1;
+	Type *t;
+	int arg, ncase;
+
+	casebody(sw, N);
+
+	arg = Snorm;
+	if(isconst(sw->ntest, CTBOOL)) {
+		arg = Strue;
+		if(sw->ntest->val.u.bval == 0)
+			arg = Sfalse;
+	}
+	walkexpr(&sw->ntest, &sw->ninit);
+	t = sw->type;
+	if(t == T)
+		return;
+
+	/*
+	 * convert the switch into OIF statements
+	 */
+	exprname = N;
+	cas = nil;
+	if(arg != Strue && arg != Sfalse) {
+		exprname = temp(sw->ntest->type);
+		cas = list1(nod(OAS, exprname, sw->ntest));
+		typechecklist(cas, Etop);
+	} else {
+		exprname = nodbool(arg == Strue);
+	}
+
+	c0 = mkcaselist(sw, arg);
+	if(c0 != C && c0->type == Tdefault) {
+		def = c0->node->right;
+		c0 = c0->link;
+	} else {
+		def = nod(OBREAK, N, N);
+	}
+
+loop:
+	if(c0 == C) {
+		cas = list(cas, def);
+		sw->nbody = concat(cas, sw->nbody);
+		sw->list = nil;
+		walkstmtlist(sw->nbody);
+		return;
+	}
+
+	// deal with the variables one-at-a-time
+	if(!okforcmp[t->etype] || c0->type != Texprconst) {
+		a = exprbsw(c0, 1, arg);
+		cas = list(cas, a);
+		c0 = c0->link;
+		goto loop;
+	}
+
+	// do binary search on run of constants
+	ncase = 1;
+	for(c=c0; c->link!=C; c=c->link) {
+		if(c->link->type != Texprconst)
+			break;
+		ncase++;
+	}
+
+	// break the chain at the count
+	c1 = c->link;
+	c->link = C;
+
+	// sort and compile constants
+	c0 = csort(c0, exprcmp);
+	a = exprbsw(c0, ncase, arg);
+	cas = list(cas, a);
+
+	c0 = c1;
+	goto loop;
+
+}
+
+static	Node*	hashname;
+static	Node*	facename;
+static	Node*	boolname;
+
+static Node*
+typeone(Node *t)
+{
+	NodeList *init;
+	Node *a, *b, *var;
+
+	var = t->nname;
+	init = nil;
+	if(var == N) {
+		typecheck(&nblank, Erv | Easgn);
+		var = nblank;
+	} else
+		init = list1(nod(ODCL, var, N));
+
+	a = nod(OAS2, N, N);
+	a->list = list(list1(var), boolname);	// var,bool =
+	b = nod(ODOTTYPE, facename, N);
+	b->type = t->left->type;		// interface.(type)
+	a->rlist = list1(b);
+	typecheck(&a, Etop);
+	init = list(init, a);
+
+	b = nod(OIF, N, N);
+	b->ntest = boolname;
+	b->nbody = list1(t->right);		// if bool { goto l }
+	a = liststmt(list(init, b));
+	return a;
+}
+
+static Node*
+typebsw(Case *c0, int ncase)
+{
+	NodeList *cas;
+	Node *a, *n;
+	Case *c;
+	int i, half;
+
+	cas = nil;
+
+	if(ncase < Ncase) {
+		for(i=0; i<ncase; i++) {
+			n = c0->node;
+			if(c0->type != Ttypeconst)
+				fatal("typebsw");
+			a = nod(OIF, N, N);
+			a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
+			typecheck(&a->ntest, Erv);
+			a->nbody = list1(n->right);
+			cas = list(cas, a);
+			c0 = c0->link;
+		}
+		return liststmt(cas);
+	}
+
+	// find the middle and recur
+	c = c0;
+	half = ncase>>1;
+	for(i=1; i<half; i++)
+		c = c->link;
+	a = nod(OIF, N, N);
+	a->ntest = nod(OLE, hashname, nodintconst(c->hash));
+	typecheck(&a->ntest, Erv);
+	a->nbody = list1(typebsw(c0, half));
+	a->nelse = list1(typebsw(c->link, ncase-half));
+	return a;
+}
+
+/*
+ * convert switch of the form
+ *	switch v := i.(type) { case t1: ..; case t2: ..; }
+ * into if statements
+ */
+static void
+typeswitch(Node *sw)
+{
+	Node *def;
+	NodeList *cas, *hash;
+	Node *a, *n;
+	Case *c, *c0, *c1;
+	int ncase;
+	Type *t;
+	Val v;
+
+	if(sw->ntest == nil)
+		return;
+	if(sw->ntest->right == nil) {
+		setlineno(sw);
+		yyerror("type switch must have an assignment");
+		return;
+	}
+	walkexpr(&sw->ntest->right, &sw->ninit);
+	if(!istype(sw->ntest->right->type, TINTER)) {
+		yyerror("type switch must be on an interface");
+		return;
+	}
+	cas = nil;
+
+	/*
+	 * predeclare temporary variables
+	 * and the boolean var
+	 */
+	facename = temp(sw->ntest->right->type);
+	a = nod(OAS, facename, sw->ntest->right);
+	typecheck(&a, Etop);
+	cas = list(cas, a);
+
+	casebody(sw, facename);
+
+	boolname = temp(types[TBOOL]);
+	typecheck(&boolname, Erv);
+
+	hashname = temp(types[TUINT32]);
+	typecheck(&hashname, Erv);
+
+	t = sw->ntest->right->type;
+	if(isnilinter(t))
+		a = syslook("efacethash", 1);
+	else
+		a = syslook("ifacethash", 1);
+	argtype(a, t);
+	a = nod(OCALL, a, N);
+	a->list = list1(facename);
+	a = nod(OAS, hashname, a);
+	typecheck(&a, Etop);
+	cas = list(cas, a);
+
+	c0 = mkcaselist(sw, Stype);
+	if(c0 != C && c0->type == Tdefault) {
+		def = c0->node->right;
+		c0 = c0->link;
+	} else {
+		def = nod(OBREAK, N, N);
+	}
+	
+	/*
+	 * insert if statement into each case block
+	 */
+	for(c=c0; c!=C; c=c->link) {
+		n = c->node;
+		switch(c->type) {
+
+		case Ttypenil:
+			v.ctype = CTNIL;
+			a = nod(OIF, N, N);
+			a->ntest = nod(OEQ, facename, nodlit(v));
+			typecheck(&a->ntest, Erv);
+			a->nbody = list1(n->right);		// if i==nil { goto l }
+			n->right = a;
+			break;
+		
+		case Ttypevar:
+		case Ttypeconst:
+			n->right = typeone(n);
+			break;
+		}
+	}
+
+	/*
+	 * generate list of if statements, binary search for constant sequences
+	 */
+	while(c0 != C) {
+		if(c0->type != Ttypeconst) {
+			n = c0->node;
+			cas = list(cas, n->right);
+			c0=c0->link;
+			continue;
+		}
+		
+		// identify run of constants
+		c1 = c = c0;
+		while(c->link!=C && c->link->type==Ttypeconst)
+			c = c->link;
+		c0 = c->link;
+		c->link = nil;
+
+		// sort by hash
+		c1 = csort(c1, typecmp);
+		
+		// for debugging: linear search
+		if(0) {
+			for(c=c1; c!=C; c=c->link) {
+				n = c->node;
+				cas = list(cas, n->right);
+			}
+			continue;
+		}
+
+		// combine adjacent cases with the same hash
+		ncase = 0;
+		for(c=c1; c!=C; c=c->link) {
+			ncase++;
+			hash = list1(c->node->right);
+			while(c->link != C && c->link->hash == c->hash) {
+				hash = list(hash, c->link->node->right);
+				c->link = c->link->link;
+			}
+			c->node->right = liststmt(hash);
+		}
+		
+		// binary search among cases to narrow by hash
+		cas = list(cas, typebsw(c1, ncase));
+	}
+	if(nerrors == 0) {
+		cas = list(cas, def);
+		sw->nbody = concat(cas, sw->nbody);
+		sw->list = nil;
+		walkstmtlist(sw->nbody);
+	}
+}
+
+void
+walkswitch(Node *sw)
+{
+	/*
+	 * reorder the body into (OLIST, cases, statements)
+	 * cases have OGOTO into statements.
+	 * both have inserted OBREAK statements
+	 */
+	if(sw->ntest == N) {
+		sw->ntest = nodbool(1);
+		typecheck(&sw->ntest, Erv);
+	}
+
+	if(sw->ntest->op == OTYPESW) {
+		typeswitch(sw);
+//dump("sw", sw);
+		return;
+	}
+	exprswitch(sw);
+	// Discard old AST elements after a walk. They can confuse racewealk.
+	sw->ntest = nil;
+	sw->list = nil;
+}
+
+/*
+ * type check switch statement
+ */
+void
+typecheckswitch(Node *n)
+{
+	int top, lno, ptr;
+	char *nilonly;
+	Type *t, *badtype, *missing, *have;
+	NodeList *l, *ll;
+	Node *ncase, *nvar;
+	Node *def;
+
+	lno = lineno;
+	typechecklist(n->ninit, Etop);
+	nilonly = nil;
+
+	if(n->ntest != N && n->ntest->op == OTYPESW) {
+		// type switch
+		top = Etype;
+		typecheck(&n->ntest->right, Erv);
+		t = n->ntest->right->type;
+		if(t != T && t->etype != TINTER)
+			yyerror("cannot type switch on non-interface value %lN", n->ntest->right);
+	} else {
+		// value switch
+		top = Erv;
+		if(n->ntest) {
+			typecheck(&n->ntest, Erv);
+			defaultlit(&n->ntest, T);
+			t = n->ntest->type;
+		} else
+			t = types[TBOOL];
+		if(t) {
+			if(!okforeq[t->etype])
+				yyerror("cannot switch on %lN", n->ntest);
+			else if(t->etype == TARRAY && !isfixedarray(t))
+				nilonly = "slice";
+			else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ)
+				yyerror("cannot switch on %lN", n->ntest);
+			else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ)
+				yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype);
+			else if(t->etype == TFUNC)
+				nilonly = "func";
+			else if(t->etype == TMAP)
+				nilonly = "map";
+		}
+	}
+	n->type = t;
+
+	def = N;
+	for(l=n->list; l; l=l->next) {
+		ncase = l->n;
+		setlineno(n);
+		if(ncase->list == nil) {
+			// default
+			if(def != N)
+				yyerror("multiple defaults in switch (first at %L)", def->lineno);
+			else
+				def = ncase;
+		} else {
+			for(ll=ncase->list; ll; ll=ll->next) {
+				setlineno(ll->n);
+				typecheck(&ll->n, Erv | Etype);
+				if(ll->n->type == T || t == T)
+					continue;
+				setlineno(ncase);
+				switch(top) {
+				case Erv:	// expression switch
+					defaultlit(&ll->n, t);
+					if(ll->n->op == OTYPE)
+						yyerror("type %T is not an expression", ll->n->type);
+					else if(ll->n->type != T && !assignop(ll->n->type, t, nil) && !assignop(t, ll->n->type, nil)) {
+						if(n->ntest)
+							yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t);
+						else
+							yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, ll->n->type);
+					} else if(nilonly && !isconst(ll->n, CTNIL)) {
+						yyerror("invalid case %N in switch (can only compare %s %N to nil)", ll->n, nilonly, n->ntest);
+					}
+					break;
+				case Etype:	// type switch
+					if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL)) {
+						;
+					} else if(ll->n->op != OTYPE && ll->n->type != T) {  // should this be ||?
+						yyerror("%lN is not a type", ll->n);
+						// reset to original type
+						ll->n = n->ntest->right;
+					} else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) {
+						if(have && !missing->broke && !have->broke)
+							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
+								" (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT",
+								n->ntest->right, ll->n->type, missing->sym, have->sym, have->type,
+								missing->sym, missing->type);
+						else if(!missing->broke)
+							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
+								" (missing %S method)", n->ntest->right, ll->n->type, missing->sym);
+					}
+					break;
+				}
+			}
+		}
+		if(top == Etype && n->type != T) {
+			ll = ncase->list;
+			nvar = ncase->nname;
+			if(nvar != N) {
+				if(ll && ll->next == nil && ll->n->type != T && !istype(ll->n->type, TNIL)) {
+					// single entry type switch
+					nvar->ntype = typenod(ll->n->type);
+				} else {
+					// multiple entry type switch or default
+					nvar->ntype = typenod(n->type);
+				}
+			}
+		}
+		typechecklist(ncase->nbody, Etop);
+	}
+
+	lineno = lno;
+}
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
new file mode 100644
index 0000000..ce12f15
--- /dev/null
+++ b/src/cmd/gc/typecheck.c
@@ -0,0 +1,3582 @@
+// 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.
+
+/*
+ * type check the whole tree of an expression.
+ * calculates expression types.
+ * evaluates compile time constants.
+ * marks variables that escape the local frame.
+ * rewrites n->op to be more specific in some cases.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+static void	implicitstar(Node**);
+static int	onearg(Node*, char*, ...);
+static int	twoarg(Node*);
+static int	lookdot(Node*, Type*, int);
+static int	looktypedot(Node*, Type*, int);
+static void	typecheckaste(int, Node*, int, Type*, NodeList*, char*);
+static Type*	lookdot1(Node*, Sym *s, Type *t, Type *f, int);
+static int	nokeys(NodeList*);
+static void	typecheckcomplit(Node**);
+static void	typecheckas2(Node*);
+static void	typecheckas(Node*);
+static void	typecheckfunc(Node*);
+static void	checklvalue(Node*, char*);
+static void	checkassign(Node*);
+static void	checkassignlist(NodeList*);
+static void	stringtoarraylit(Node**);
+static Node*	resolve(Node*);
+static void	checkdefergo(Node*);
+static int	checkmake(Type*, char*, Node*);
+static int	checksliceindex(Node*, Node*, Type*);
+static int	checksliceconst(Node*, Node*);
+
+static	NodeList*	typecheckdefstack;
+
+/*
+ * resolve ONONAME to definition, if any.
+ */
+static Node*
+resolve(Node *n)
+{
+	Node *r;
+
+	if(n != N && n->op == ONONAME && n->sym != S && (r = n->sym->def) != N) {
+		if(r->op != OIOTA)
+			n = r;
+		else if(n->iota >= 0)
+			n = nodintconst(n->iota);
+	}
+	return n;
+}
+
+void
+typechecklist(NodeList *l, int top)
+{
+	for(; l; l=l->next)
+		typecheck(&l->n, top);
+}
+
+static char* _typekind[] = {
+	[TINT]		= "int",
+	[TUINT]		= "uint",
+	[TINT8]		= "int8",
+	[TUINT8]	= "uint8",
+	[TINT16]	= "int16",
+	[TUINT16]	= "uint16",
+	[TINT32]	= "int32",
+	[TUINT32]	= "uint32",
+	[TINT64]	= "int64",
+	[TUINT64]	= "uint64",
+	[TUINTPTR]	= "uintptr",
+	[TCOMPLEX64]	= "complex64",
+	[TCOMPLEX128]	= "complex128",
+	[TFLOAT32]	= "float32",
+	[TFLOAT64]	= "float64",
+	[TBOOL]		= "bool",
+	[TSTRING]	= "string",
+	[TPTR32]	= "pointer",
+	[TPTR64]	= "pointer",
+	[TUNSAFEPTR]	= "unsafe.Pointer",
+	[TSTRUCT]	= "struct",
+	[TINTER]	= "interface",
+	[TCHAN]		= "chan",
+	[TMAP]		= "map",
+	[TARRAY]	= "array",
+	[TFUNC]		= "func",
+	[TNIL]		= "nil",
+	[TIDEAL]	= "untyped number",
+};
+
+static char*
+typekind(Type *t)
+{
+	int et;
+	static char buf[50];
+	char *s;
+	
+	if(isslice(t))
+		return "slice";
+	et = t->etype;
+	if(0 <= et && et < nelem(_typekind) && (s=_typekind[et]) != nil)
+		return s;
+	snprint(buf, sizeof buf, "etype=%d", et);
+	return buf;
+}
+
+/*
+ * sprint_depchain prints a dependency chain
+ * of nodes into fmt.
+ * It is used by typecheck in the case of OLITERAL nodes
+ * to print constant definition loops.
+ */
+static void
+sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first)
+{
+	NodeList *l;
+
+	for(l = stack; l; l=l->next) {
+		if(l->n->op == cur->op) {
+			if(l->n != first)
+				sprint_depchain(fmt, l->next, l->n, first);
+			fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur);
+			return;
+		}
+	}
+}
+
+/*
+ * type check node *np.
+ * replaces *np with a new pointer in some cases.
+ * returns the final value of *np as a convenience.
+ */
+static void typecheck1(Node **, int);
+Node*
+typecheck(Node **np, int top)
+{
+	Node *n;
+	int lno;
+	Fmt fmt;
+	NodeList *l;
+	static NodeList *tcstack, *tcfree;
+
+	// cannot type check until all the source has been parsed
+	if(!typecheckok)
+		fatal("early typecheck");
+
+	n = *np;
+	if(n == N)
+		return N;
+	
+	lno = setlineno(n);
+
+	// Skip over parens.
+	while(n->op == OPAREN)
+		n = n->left;
+
+	// Resolve definition of name and value of iota lazily.
+	n = resolve(n);
+
+	*np = n;
+
+	// Skip typecheck if already done.
+	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
+	if(n->typecheck == 1) {
+		switch(n->op) {
+		case ONAME:
+		case OTYPE:
+		case OLITERAL:
+		case OPACK:
+			break;
+		default:
+			lineno = lno;
+			return n;
+		}
+	}
+
+	if(n->typecheck == 2) {
+		// Typechecking loop. Trying printing a meaningful message,
+		// otherwise a stack trace of typechecking.
+		switch(n->op) {
+		case ONAME:
+			// We can already diagnose variables used as types.
+			if((top & (Erv|Etype)) == Etype)
+				yyerror("%N is not a type", n);
+			break;
+		case OLITERAL:
+			if((top & (Erv|Etype)) == Etype) {
+				yyerror("%N is not a type", n);
+				break;
+			}
+			fmtstrinit(&fmt);
+			sprint_depchain(&fmt, tcstack, n, n);
+			yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt));
+			break;
+		}
+		if(nsavederrors+nerrors == 0) {
+			fmtstrinit(&fmt);
+			for(l=tcstack; l; l=l->next)
+				fmtprint(&fmt, "\n\t%L %N", l->n->lineno, l->n);
+			yyerror("typechecking loop involving %N%s", n, fmtstrflush(&fmt));
+		}
+		lineno = lno;
+		return n;
+	}
+	n->typecheck = 2;
+
+	if(tcfree != nil) {
+		l = tcfree;
+		tcfree = l->next;
+	} else
+		l = mal(sizeof *l);
+	l->next = tcstack;
+	l->n = n;
+	tcstack = l;
+
+	typecheck1(&n, top);
+	*np = n;
+	n->typecheck = 1;
+
+	if(tcstack != l)
+		fatal("typecheck stack out of sync");
+	tcstack = l->next;
+	l->next = tcfree;
+	tcfree = l;
+
+	lineno = lno;
+	return n;
+}
+
+/*
+ * does n contain a call or receive operation?
+ */
+static int callrecvlist(NodeList*);
+
+static int
+callrecv(Node *n)
+{
+	if(n == nil)
+		return 0;
+	
+	switch(n->op) {
+	case OCALL:
+	case OCALLMETH:
+	case OCALLINTER:
+	case OCALLFUNC:
+	case ORECV:
+	case OCAP:
+	case OLEN:
+	case OCOPY:
+	case ONEW:
+	case OAPPEND:
+	case ODELETE:
+		return 1;
+	}
+
+	return callrecv(n->left) ||
+		callrecv(n->right) ||
+		callrecv(n->ntest) ||
+		callrecv(n->nincr) ||
+		callrecvlist(n->ninit) ||
+		callrecvlist(n->nbody) ||
+		callrecvlist(n->nelse) ||
+		callrecvlist(n->list) ||
+		callrecvlist(n->rlist);
+}
+
+static int
+callrecvlist(NodeList *l)
+{
+	for(; l; l=l->next)
+		if(callrecv(l->n))
+			return 1;
+	return 0;
+}
+
+// indexlit implements typechecking of untyped values as
+// array/slice indexes. It is equivalent to defaultlit
+// except for constants of numerical kind, which are acceptable
+// whenever they can be represented by a value of type int.
+static void
+indexlit(Node **np)
+{
+	Node *n;
+
+	n = *np;
+	if(n == N || !isideal(n->type))
+		return;
+	switch(consttype(n)) {
+	case CTINT:
+	case CTRUNE:
+	case CTFLT:
+	case CTCPLX:
+		defaultlit(np, types[TINT]);
+		break;
+	}
+	defaultlit(np, T);
+}
+
+static void
+typecheck1(Node **np, int top)
+{
+	int et, aop, op, ptr;
+	Node *n, *l, *r, *lo, *mid, *hi;
+	NodeList *args;
+	int ok, ntop;
+	Type *t, *tp, *missing, *have, *badtype;
+	Val v;
+	char *why, *desc, descbuf[64];
+	vlong x;
+	
+	n = *np;
+
+	if(n->sym) {
+		if(n->op == ONAME && n->etype != 0 && !(top & Ecall)) {
+			yyerror("use of builtin %S not in function call", n->sym);
+			goto error;
+		}
+
+		typecheckdef(n);
+		if(n->op == ONONAME)
+			goto error;
+	}
+	*np = n;
+
+reswitch:
+	ok = 0;
+	switch(n->op) {
+	default:
+		// until typecheck is complete, do nothing.
+		dump("typecheck", n);
+		fatal("typecheck %O", n->op);
+
+	/*
+	 * names
+	 */
+	case OLITERAL:
+		ok |= Erv;
+		if(n->type == T && n->val.ctype == CTSTR)
+			n->type = idealstring;
+		goto ret;
+
+	case ONONAME:
+		ok |= Erv;
+		goto ret;
+
+	case ONAME:
+		if(n->etype != 0) {
+			ok |= Ecall;
+			goto ret;
+		}
+		if(!(top & Easgn)) {
+			// not a write to the variable
+			if(isblank(n)) {
+				yyerror("cannot use _ as value");
+				goto error;
+			}
+			n->used = 1;
+		}
+		if(!(top &Ecall) && isunsafebuiltin(n)) {
+			yyerror("%N is not an expression, must be called", n);
+			goto error;
+		}
+		ok |= Erv;
+		goto ret;
+
+	case OPACK:
+		yyerror("use of package %S without selector", n->sym);
+		goto error;
+
+	case ODDD:
+		break;
+
+	/*
+	 * types (OIND is with exprs)
+	 */
+	case OTYPE:
+		ok |= Etype;
+		if(n->type == T)
+			goto error;
+		break;
+	
+	case OTARRAY:
+		ok |= Etype;
+		t = typ(TARRAY);
+		l = n->left;
+		r = n->right;
+		if(l == nil) {
+			t->bound = -1;	// slice
+		} else if(l->op == ODDD) {
+			t->bound = -100;	// to be filled in
+			if(!(top&Ecomplit) && !n->diag) {
+				t->broke = 1;
+				n->diag = 1;
+				yyerror("use of [...] array outside of array literal");
+			}
+		} else {
+			l = typecheck(&n->left, Erv);
+			switch(consttype(l)) {
+			case CTINT:
+			case CTRUNE:
+				v = l->val;
+				break;
+			case CTFLT:
+				v = toint(l->val);
+				break;
+			default:
+				if(l->type != T && isint[l->type->etype] && l->op != OLITERAL)
+					yyerror("non-constant array bound %N", l);
+				else
+					yyerror("invalid array bound %N", l);
+				goto error;
+			}
+			t->bound = mpgetfix(v.u.xval);
+			if(doesoverflow(v, types[TINT])) {
+				yyerror("array bound is too large"); 
+				goto error;
+			} else if(t->bound < 0) {
+				yyerror("array bound must be non-negative");
+				goto error;
+			}
+		}
+		typecheck(&r, Etype);
+		if(r->type == T)
+			goto error;
+		t->type = r->type;
+		n->op = OTYPE;
+		n->type = t;
+		n->left = N;
+		n->right = N;
+		if(t->bound != -100)
+			checkwidth(t);
+		break;
+
+	case OTMAP:
+		ok |= Etype;
+		l = typecheck(&n->left, Etype);
+		r = typecheck(&n->right, Etype);
+		if(l->type == T || r->type == T)
+			goto error;
+		n->op = OTYPE;
+		n->type = maptype(l->type, r->type);
+		n->left = N;
+		n->right = N;
+		break;
+
+	case OTCHAN:
+		ok |= Etype;
+		l = typecheck(&n->left, Etype);
+		if(l->type == T)
+			goto error;
+		t = typ(TCHAN);
+		t->type = l->type;
+		t->chan = n->etype;
+		n->op = OTYPE;
+		n->type = t;
+		n->left = N;
+		n->etype = 0;
+		break;
+
+	case OTSTRUCT:
+		ok |= Etype;
+		n->op = OTYPE;
+		n->type = tostruct(n->list);
+		if(n->type == T || n->type->broke)
+			goto error;
+		n->list = nil;
+		break;
+
+	case OTINTER:
+		ok |= Etype;
+		n->op = OTYPE;
+		n->type = tointerface(n->list);
+		if(n->type == T)
+			goto error;
+		break;
+
+	case OTFUNC:
+		ok |= Etype;
+		n->op = OTYPE;
+		n->type = functype(n->left, n->list, n->rlist);
+		if(n->type == T)
+			goto error;
+		break;
+
+	/*
+	 * type or expr
+	 */
+	case OIND:
+		ntop = Erv | Etype;
+		if(!(top & Eaddr))  		// The *x in &*x is not an indirect.
+			ntop |= Eindir;
+		ntop |= top & Ecomplit;
+		l = typecheck(&n->left, ntop);
+		if((t = l->type) == T)
+			goto error;
+		if(l->op == OTYPE) {
+			ok |= Etype;
+			n->op = OTYPE;
+			n->type = ptrto(l->type);
+			n->left = N;
+			goto ret;
+		}
+		if(!isptr[t->etype]) {
+			if(top & (Erv | Etop)) {
+				yyerror("invalid indirect of %lN", n->left);
+				goto error;
+			}
+			goto ret;
+		}
+		ok |= Erv;
+		n->type = t->type;
+		goto ret;
+
+	/*
+	 * arithmetic exprs
+	 */
+	case OASOP:
+		ok |= Etop;
+		l = typecheck(&n->left, Erv);
+		checkassign(n->left);
+		r = typecheck(&n->right, Erv);
+		if(l->type == T || r->type == T)
+			goto error;
+		op = n->etype;
+		goto arith;
+
+	case OADD:
+	case OAND:
+	case OANDAND:
+	case OANDNOT:
+	case ODIV:
+	case OEQ:
+	case OGE:
+	case OGT:
+	case OLE:
+	case OLT:
+	case OLSH:
+	case ORSH:
+	case OMOD:
+	case OMUL:
+	case ONE:
+	case OOR:
+	case OOROR:
+	case OSUB:
+	case OXOR:
+		ok |= Erv;
+		l = typecheck(&n->left, Erv | (top & Eiota));
+		r = typecheck(&n->right, Erv | (top & Eiota));
+		if(l->type == T || r->type == T)
+			goto error;
+		op = n->op;
+	arith:
+		if(op == OLSH || op == ORSH)
+			goto shift;
+		// ideal mixed with non-ideal
+		defaultlit2(&l, &r, 0);
+		n->left = l;
+		n->right = r;
+		if(l->type == T || r->type == T)
+			goto error;
+		t = l->type;
+		if(t->etype == TIDEAL)
+			t = r->type;
+		et = t->etype;
+		if(et == TIDEAL)
+			et = TINT;
+		if(iscmp[n->op] && t->etype != TIDEAL && !eqtype(l->type, r->type)) {
+			// comparison is okay as long as one side is
+			// assignable to the other.  convert so they have
+			// the same type.
+			//
+			// the only conversion that isn't a no-op is concrete == interface.
+			// in that case, check comparability of the concrete type.
+			if(r->type->etype != TBLANK && (aop = assignop(l->type, r->type, nil)) != 0) {
+				if(isinter(r->type) && !isinter(l->type) && algtype1(l->type, nil) == ANOEQ) {
+					yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(l->type));
+					goto error;
+				}
+				l = nod(aop, l, N);
+				l->type = r->type;
+				l->typecheck = 1;
+				n->left = l;
+				t = l->type;
+			} else if(l->type->etype != TBLANK && (aop = assignop(r->type, l->type, nil)) != 0) {
+				if(isinter(l->type) && !isinter(r->type) && algtype1(r->type, nil) == ANOEQ) {
+					yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(r->type));
+					goto error;
+				}
+				r = nod(aop, r, N);
+				r->type = l->type;
+				r->typecheck = 1;
+				n->right = r;
+				t = r->type;
+			}
+			et = t->etype;
+		}
+		if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
+			defaultlit2(&l, &r, 1);
+			if(n->op == OASOP && n->implicit) {
+				yyerror("invalid operation: %N (non-numeric type %T)", n, l->type);
+				goto error;
+			}
+			yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
+			goto error;
+		}
+		if(!okfor[op][et]) {
+			yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(t));
+			goto error;
+		}
+		// okfor allows any array == array, map == map, func == func.
+		// restrict to slice/map/func == nil and nil == slice/map/func.
+		if(isfixedarray(l->type) && algtype1(l->type, nil) == ANOEQ) {
+			yyerror("invalid operation: %N (%T cannot be compared)", n, l->type);
+			goto error;
+		}
+		if(isslice(l->type) && !isnil(l) && !isnil(r)) {
+			yyerror("invalid operation: %N (slice can only be compared to nil)", n);
+			goto error;
+		}
+		if(l->type->etype == TMAP && !isnil(l) && !isnil(r)) {
+			yyerror("invalid operation: %N (map can only be compared to nil)", n);
+			goto error;
+		}
+		if(l->type->etype == TFUNC && !isnil(l) && !isnil(r)) {
+			yyerror("invalid operation: %N (func can only be compared to nil)", n);
+			goto error;
+		}
+		if(l->type->etype == TSTRUCT && algtype1(l->type, &badtype) == ANOEQ) {
+			yyerror("invalid operation: %N (struct containing %T cannot be compared)", n, badtype);
+			goto error;
+		}
+		
+		t = l->type;
+		if(iscmp[n->op]) {
+			evconst(n);
+			t = idealbool;
+			if(n->op != OLITERAL) {
+				defaultlit2(&l, &r, 1);
+				n->left = l;
+				n->right = r;
+			}
+		// non-comparison operators on ideal bools should make them lose their ideal-ness
+		} else if(t == idealbool)
+			t = types[TBOOL];
+
+		if(et == TSTRING) {
+			if(iscmp[n->op]) {
+				n->etype = n->op;
+				n->op = OCMPSTR;
+			} else if(n->op == OADD) {
+				// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
+				n->op = OADDSTR;
+				if(l->op == OADDSTR)
+					n->list = l->list;
+				else
+					n->list = list1(l);
+				if(r->op == OADDSTR)
+					n->list = concat(n->list, r->list);
+				else
+					n->list = list(n->list, r);
+				n->left = N;
+				n->right = N;
+			}
+		}
+		if(et == TINTER) {
+			if(l->op == OLITERAL && l->val.ctype == CTNIL) {
+				// swap for back end
+				n->left = r;
+				n->right = l;
+			} else if(r->op == OLITERAL && r->val.ctype == CTNIL) {
+				// leave alone for back end
+			} else {
+				n->etype = n->op;
+				n->op = OCMPIFACE;
+			}
+		}
+
+		if((op == ODIV || op == OMOD) && isconst(r, CTINT))
+		if(mpcmpfixc(r->val.u.xval, 0) == 0) {
+			yyerror("division by zero");
+			goto error;
+		} 
+
+		n->type = t;
+		goto ret;
+
+	shift:
+		defaultlit(&r, types[TUINT]);
+		n->right = r;
+		t = r->type;
+		if(!isint[t->etype] || issigned[t->etype]) {
+			yyerror("invalid operation: %N (shift count type %T, must be unsigned integer)", n, r->type);
+			goto error;
+		}
+		t = l->type;
+		if(t != T && t->etype != TIDEAL && !isint[t->etype]) {
+			yyerror("invalid operation: %N (shift of type %T)", n, t);
+			goto error;
+		}
+		// no defaultlit for left
+		// the outer context gives the type
+		n->type = l->type;
+		goto ret;
+
+	case OCOM:
+	case OMINUS:
+	case ONOT:
+	case OPLUS:
+		ok |= Erv;
+		l = typecheck(&n->left, Erv | (top & Eiota));
+		if((t = l->type) == T)
+			goto error;
+		if(!okfor[n->op][t->etype]) {
+			yyerror("invalid operation: %O %T", n->op, t);
+			goto error;
+		}
+		n->type = t;
+		goto ret;
+
+	/*
+	 * exprs
+	 */
+	case OADDR:
+		ok |= Erv;
+		typecheck(&n->left, Erv | Eaddr);
+		if(n->left->type == T)
+			goto error;
+		checklvalue(n->left, "take the address of");
+		r = outervalue(n->left);
+		for(l = n->left; l != r; l = l->left)
+			l->addrtaken = 1;
+		if(l->orig != l && l->op == ONAME)
+			fatal("found non-orig name node %N", l);
+		l->addrtaken = 1;
+		defaultlit(&n->left, T);
+		l = n->left;
+		if((t = l->type) == T)
+			goto error;
+		n->type = ptrto(t);
+		goto ret;
+
+	case OCOMPLIT:
+		ok |= Erv;
+		typecheckcomplit(&n);
+		if(n->type == T)
+			goto error;
+		goto ret;
+
+	case OXDOT:
+		n = adddot(n);
+		n->op = ODOT;
+		if(n->left == N)
+			goto error;
+		// fall through
+	case ODOT:
+		typecheck(&n->left, Erv|Etype);
+		defaultlit(&n->left, T);
+		if((t = n->left->type) == T)
+			goto error;
+		if(n->right->op != ONAME) {
+			yyerror("rhs of . must be a name");	// impossible
+			goto error;
+		}
+		r = n->right;
+
+		if(n->left->op == OTYPE) {
+			if(!looktypedot(n, t, 0)) {
+				if(looktypedot(n, t, 1))
+					yyerror("%N undefined (cannot refer to unexported method %S)", n, n->right->sym);
+				else
+					yyerror("%N undefined (type %T has no method %S)", n, t, n->right->sym);
+				goto error;
+			}
+			if(n->type->etype != TFUNC || n->type->thistuple != 1) {
+				yyerror("type %T has no method %hS", n->left->type, n->right->sym);
+				n->type = T;
+				goto error;
+			}
+			n->op = ONAME;
+			n->sym = n->right->sym;
+			n->type = methodfunc(n->type, n->left->type);
+			n->xoffset = 0;
+			n->class = PFUNC;
+			ok = Erv;
+			goto ret;
+		}
+		if(isptr[t->etype] && t->type->etype != TINTER) {
+			t = t->type;
+			if(t == T)
+				goto error;
+			n->op = ODOTPTR;
+			checkwidth(t);
+		}
+		if(isblank(n->right)) {
+			yyerror("cannot refer to blank field or method");
+			goto error;
+		}
+		if(!lookdot(n, t, 0)) {
+			if(lookdot(n, t, 1))
+				yyerror("%N undefined (cannot refer to unexported field or method %S)", n, n->right->sym);
+			else
+				yyerror("%N undefined (type %T has no field or method %S)", n, n->left->type, n->right->sym);
+			goto error;
+		}
+		switch(n->op) {
+		case ODOTINTER:
+		case ODOTMETH:
+			if(top&Ecall)
+				ok |= Ecall;
+			else {
+				typecheckpartialcall(n, r);
+				ok |= Erv;
+			}
+			break;
+		default:
+			ok |= Erv;
+			break;
+		}
+		goto ret;
+
+	case ODOTTYPE:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, T);
+		l = n->left;
+		if((t = l->type) == T)
+			goto error;
+		if(!isinter(t)) {
+			yyerror("invalid type assertion: %N (non-interface type %T on left)", n, t);
+			goto error;
+		}
+		if(n->right != N) {
+			typecheck(&n->right, Etype);
+			n->type = n->right->type;
+			n->right = N;
+			if(n->type == T)
+				goto error;
+		}
+		if(n->type != T && n->type->etype != TINTER)
+		if(!implements(n->type, t, &missing, &have, &ptr)) {
+			if(have && have->sym == missing->sym)
+				yyerror("impossible type assertion:\n\t%T does not implement %T (wrong type for %S method)\n"
+					"\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
+					have->sym, have->type, missing->sym, missing->type);
+			else if(ptr)
+				yyerror("impossible type assertion:\n\t%T does not implement %T (%S method has pointer receiver)",
+					n->type, t, missing->sym);
+			else if(have)
+				yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)\n"
+					"\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
+					have->sym, have->type, missing->sym, missing->type);
+			else
+				yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)",
+					n->type, t, missing->sym);
+			goto error;
+		}
+		goto ret;
+
+	case OINDEX:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, T);
+		implicitstar(&n->left);
+		l = n->left;
+		typecheck(&n->right, Erv);
+		r = n->right;
+		if((t = l->type) == T || r->type == T)
+			goto error;
+		switch(t->etype) {
+		default:
+			yyerror("invalid operation: %N (type %T does not support indexing)", n, t);
+			goto error;
+
+
+		case TSTRING:
+		case TARRAY:
+			indexlit(&n->right);
+			if(t->etype == TSTRING)
+				n->type = types[TUINT8];
+			else
+				n->type = t->type;
+			why = "string";
+			if(t->etype == TARRAY) {
+				if(isfixedarray(t))
+					why = "array";
+				else
+					why = "slice";
+			}
+			if(n->right->type != T && !isint[n->right->type->etype]) {
+				yyerror("non-integer %s index %N", why, n->right);
+				break;
+			}
+			if(isconst(n->right, CTINT)) {
+				x = mpgetfix(n->right->val.u.xval);
+				if(x < 0)
+					yyerror("invalid %s index %N (index must be non-negative)", why, n->right);
+				else if(isfixedarray(t) && t->bound > 0 && x >= t->bound)
+					yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound);
+				else if(isconst(n->left, CTSTR) && x >= n->left->val.u.sval->len)
+					yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len);
+				else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
+					yyerror("invalid %s index %N (index too large)", why, n->right);
+			}
+			break;
+
+		case TMAP:
+			n->etype = 0;
+			defaultlit(&n->right, t->down);
+			if(n->right->type != T)
+				n->right = assignconv(n->right, t->down, "map index");
+			n->type = t->type;
+			n->op = OINDEXMAP;
+			break;
+		}
+		goto ret;
+
+	case ORECV:
+		ok |= Etop | Erv;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, T);
+		l = n->left;
+		if((t = l->type) == T)
+			goto error;
+		if(t->etype != TCHAN) {
+			yyerror("invalid operation: %N (receive from non-chan type %T)", n, t);
+			goto error;
+		}
+		if(!(t->chan & Crecv)) {
+			yyerror("invalid operation: %N (receive from send-only type %T)", n, t);
+			goto error;
+		}
+		n->type = t->type;
+		goto ret;
+
+	case OSEND:
+		ok |= Etop;
+		l = typecheck(&n->left, Erv);
+		typecheck(&n->right, Erv);
+		defaultlit(&n->left, T);
+		l = n->left;
+		if((t = l->type) == T)
+			goto error;
+		if(t->etype != TCHAN) {
+			yyerror("invalid operation: %N (send to non-chan type %T)", n, t);
+			goto error;
+		}
+		if(!(t->chan & Csend)) {
+			yyerror("invalid operation: %N (send to receive-only type %T)", n, t);
+			goto error;
+		}
+		defaultlit(&n->right, t->type);
+		r = n->right;
+		if(r->type == T)
+			goto error;
+		n->right = assignconv(r, l->type->type, "send");
+		// TODO: more aggressive
+		n->etype = 0;
+		n->type = T;
+		goto ret;
+
+	case OSLICE:
+		ok |= Erv;
+		typecheck(&n->left, top);
+		typecheck(&n->right->left, Erv);
+		typecheck(&n->right->right, Erv);
+		defaultlit(&n->left, T);
+		indexlit(&n->right->left);
+		indexlit(&n->right->right);
+		l = n->left;
+		if(isfixedarray(l->type)) {
+			if(!islvalue(n->left)) {
+				yyerror("invalid operation %N (slice of unaddressable value)", n);
+				goto error;
+			}
+			n->left = nod(OADDR, n->left, N);
+			n->left->implicit = 1;
+			typecheck(&n->left, Erv);
+			l = n->left;
+		}
+		if((t = l->type) == T)
+			goto error;
+		tp = nil;
+		if(istype(t, TSTRING)) {
+			n->type = t;
+			n->op = OSLICESTR;
+		} else if(isptr[t->etype] && isfixedarray(t->type)) {
+			tp = t->type;
+			n->type = typ(TARRAY);
+			n->type->type = tp->type;
+			n->type->bound = -1;
+			dowidth(n->type);
+			n->op = OSLICEARR;
+		} else if(isslice(t)) {
+			n->type = t;
+		} else {
+			yyerror("cannot slice %N (type %T)", l, t);
+			goto error;
+		}
+		if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
+			goto error;
+		if((hi = n->right->right) != N && checksliceindex(l, hi, tp) < 0)
+			goto error;
+		if(checksliceconst(lo, hi) < 0)
+			goto error;
+		goto ret;
+
+	case OSLICE3:
+		ok |= Erv;
+		typecheck(&n->left, top);
+		typecheck(&n->right->left, Erv);
+		typecheck(&n->right->right->left, Erv);
+		typecheck(&n->right->right->right, Erv);
+		defaultlit(&n->left, T);
+		indexlit(&n->right->left);
+		indexlit(&n->right->right->left);
+		indexlit(&n->right->right->right);
+		l = n->left;
+		if(isfixedarray(l->type)) {
+			if(!islvalue(n->left)) {
+				yyerror("invalid operation %N (slice of unaddressable value)", n);
+				goto error;
+			}
+			n->left = nod(OADDR, n->left, N);
+			n->left->implicit = 1;
+			typecheck(&n->left, Erv);
+			l = n->left;
+		}
+		if((t = l->type) == T)
+			goto error;
+		tp = nil;
+		if(istype(t, TSTRING)) {
+			yyerror("invalid operation %N (3-index slice of string)", n);
+			goto error;
+		}
+		if(isptr[t->etype] && isfixedarray(t->type)) {
+			tp = t->type;
+			n->type = typ(TARRAY);
+			n->type->type = tp->type;
+			n->type->bound = -1;
+			dowidth(n->type);
+			n->op = OSLICE3ARR;
+		} else if(isslice(t)) {
+			n->type = t;
+		} else {
+			yyerror("cannot slice %N (type %T)", l, t);
+			goto error;
+		}
+		if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
+			goto error;
+		if((mid = n->right->right->left) != N && checksliceindex(l, mid, tp) < 0)
+			goto error;
+		if((hi = n->right->right->right) != N && checksliceindex(l, hi, tp) < 0)
+			goto error;
+		if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0)
+			goto error;
+		goto ret;
+
+	/*
+	 * call and call like
+	 */
+	case OCALL:
+		l = n->left;
+		if(l->op == ONAME && (r = unsafenmagic(n)) != N) {
+			if(n->isddd)
+				yyerror("invalid use of ... with builtin %N", l);
+			n = r;
+			goto reswitch;
+		}
+		typecheck(&n->left, Erv | Etype | Ecall |(top&Eproc));
+		n->diag |= n->left->diag;
+		l = n->left;
+		if(l->op == ONAME && l->etype != 0) {
+			if(n->isddd && l->etype != OAPPEND)
+				yyerror("invalid use of ... with builtin %N", l);
+			// builtin: OLEN, OCAP, etc.
+			n->op = l->etype;
+			n->left = n->right;
+			n->right = N;
+			goto reswitch;
+		}
+		defaultlit(&n->left, T);
+		l = n->left;
+		if(l->op == OTYPE) {
+			if(n->isddd || l->type->bound == -100) {
+				if(!l->type->broke)
+					yyerror("invalid use of ... in type conversion", l);
+				n->diag = 1;
+			}
+			// pick off before type-checking arguments
+			ok |= Erv;
+			// turn CALL(type, arg) into CONV(arg) w/ type
+			n->left = N;
+			n->op = OCONV;
+			n->type = l->type;
+			if(onearg(n, "conversion to %T", l->type) < 0)
+				goto error;
+			goto doconv;
+		}
+
+		if(count(n->list) == 1 && !n->isddd)
+			typecheck(&n->list->n, Erv | Efnstruct);
+		else
+			typechecklist(n->list, Erv);
+		if((t = l->type) == T)
+			goto error;
+		checkwidth(t);
+
+		switch(l->op) {
+		case ODOTINTER:
+			n->op = OCALLINTER;
+			break;
+
+		case ODOTMETH:
+			n->op = OCALLMETH;
+			// typecheckaste was used here but there wasn't enough
+			// information further down the call chain to know if we
+			// were testing a method receiver for unexported fields.
+			// It isn't necessary, so just do a sanity check.
+			tp = getthisx(t)->type->type;
+			if(l->left == N || !eqtype(l->left->type, tp))
+				fatal("method receiver");
+			break;
+
+		default:
+			n->op = OCALLFUNC;
+			if(t->etype != TFUNC) {
+				yyerror("cannot call non-function %N (type %T)", l, t);
+				goto error;
+			}
+			break;
+		}
+		if(snprint(descbuf, sizeof descbuf, "argument to %N", n->left) < sizeof descbuf)
+			desc = descbuf;
+		else
+			desc = "function argument";
+		typecheckaste(OCALL, n->left, n->isddd, getinargx(t), n->list, desc);
+		ok |= Etop;
+		if(t->outtuple == 0)
+			goto ret;
+		ok |= Erv;
+		if(t->outtuple == 1) {
+			t = getoutargx(l->type)->type;
+			if(t == T)
+				goto error;
+			if(t->etype == TFIELD)
+				t = t->type;
+			n->type = t;
+			goto ret;
+		}
+		// multiple return
+		if(!(top & (Efnstruct | Etop))) {
+			yyerror("multiple-value %N() in single-value context", l);
+			goto ret;
+		}
+		n->type = getoutargx(l->type);
+		goto ret;
+
+	case OCAP:
+	case OLEN:
+	case OREAL:
+	case OIMAG:
+		ok |= Erv;
+		if(onearg(n, "%O", n->op) < 0)
+			goto error;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, T);
+		implicitstar(&n->left);
+		l = n->left;
+		t = l->type;
+		if(t == T)
+			goto error;
+		switch(n->op) {
+		case OCAP:
+			if(!okforcap[t->etype])
+				goto badcall1;
+			break;
+		case OLEN:
+			if(!okforlen[t->etype])
+				goto badcall1;
+			break;
+		case OREAL:
+		case OIMAG:
+			if(!iscomplex[t->etype])
+				goto badcall1;
+			if(isconst(l, CTCPLX)){
+				r = n;
+				if(n->op == OREAL)
+					n = nodfltconst(&l->val.u.cval->real);
+				else
+					n = nodfltconst(&l->val.u.cval->imag);
+				n->orig = r;
+			}
+			n->type = types[cplxsubtype(t->etype)];
+			goto ret;
+		}
+		// might be constant
+		switch(t->etype) {
+		case TSTRING:
+			if(isconst(l, CTSTR)) {
+				r = nod(OXXX, N, N);
+				nodconst(r, types[TINT], l->val.u.sval->len);
+				r->orig = n;
+				n = r;
+			}
+			break;
+		case TARRAY:
+			if(t->bound < 0) // slice
+				break;
+			if(callrecv(l)) // has call or receive
+				break;
+			r = nod(OXXX, N, N);
+			nodconst(r, types[TINT], t->bound);
+			r->orig = n;
+			n = r;
+			break;
+		}
+		n->type = types[TINT];
+		goto ret;
+
+	case OCOMPLEX:
+		ok |= Erv;
+		if(count(n->list) == 1) {
+			typechecklist(n->list, Efnstruct);
+			t = n->list->n->left->type;
+			if(t->outtuple != 2) {
+				yyerror("invalid operation: complex expects two arguments, %N returns %d results", n->list->n, t->outtuple);
+				goto error;
+			}
+			t = n->list->n->type->type;
+			l = t->nname;
+			r = t->down->nname;
+		} else {
+			if(twoarg(n) < 0)
+				goto error;
+			l = typecheck(&n->left, Erv | (top & Eiota));
+			r = typecheck(&n->right, Erv | (top & Eiota));
+			if(l->type == T || r->type == T)
+				goto error;
+			defaultlit2(&l, &r, 0);
+			if(l->type == T || r->type == T)
+				goto error;
+			n->left = l;
+			n->right = r;
+		}
+		if(!eqtype(l->type, r->type)) {
+			yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
+			goto error;
+		}
+		switch(l->type->etype) {
+		default:
+			yyerror("invalid operation: %N (arguments have type %T, expected floating-point)", n, l->type, r->type);
+			goto error;
+		case TIDEAL:
+			t = types[TIDEAL];
+			break;
+		case TFLOAT32:
+			t = types[TCOMPLEX64];
+			break;
+		case TFLOAT64:
+			t = types[TCOMPLEX128];
+			break;
+		}
+		if(l->op == OLITERAL && r->op == OLITERAL) {
+			// make it a complex literal
+			r = nodcplxlit(l->val, r->val);
+			r->orig = n;
+			n = r;
+		}
+		n->type = t;
+		goto ret;
+
+	case OCLOSE:
+		if(onearg(n, "%O", n->op) < 0)
+			goto error;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, T);
+		l = n->left;
+		if((t = l->type) == T)
+			goto error;
+		if(t->etype != TCHAN) {
+			yyerror("invalid operation: %N (non-chan type %T)", n, t);
+			goto error;
+		}
+		if(!(t->chan & Csend)) {
+			yyerror("invalid operation: %N (cannot close receive-only channel)", n);
+			goto error;
+		}
+		ok |= Etop;
+		goto ret;
+
+	case ODELETE:
+		args = n->list;
+		if(args == nil) {
+			yyerror("missing arguments to delete");
+			goto error;
+		}
+		if(args->next == nil) {
+			yyerror("missing second (key) argument to delete");
+			goto error;
+		}
+		if(args->next->next != nil) {
+			yyerror("too many arguments to delete");
+			goto error;
+		}
+		ok |= Etop;
+		typechecklist(args, Erv);
+		l = args->n;
+		r = args->next->n;
+		if(l->type != T && l->type->etype != TMAP) {
+			yyerror("first argument to delete must be map; have %lT", l->type);
+			goto error;
+		}
+		args->next->n = assignconv(r, l->type->down, "delete");
+		goto ret;
+
+	case OAPPEND:
+		ok |= Erv;
+		args = n->list;
+		if(args == nil) {
+			yyerror("missing arguments to append");
+			goto error;
+		}
+
+		if(count(args) == 1 && !n->isddd)
+			typecheck(&args->n, Erv | Efnstruct);
+		else
+			typechecklist(args, Erv);
+
+		if((t = args->n->type) == T)
+			goto error;
+
+		// Unpack multiple-return result before type-checking.
+		if(istype(t, TSTRUCT) && t->funarg) {
+			t = t->type;
+			if(istype(t, TFIELD))
+				t = t->type;
+		}
+
+		n->type = t;
+		if(!isslice(t)) {
+			if(isconst(args->n, CTNIL)) {
+				yyerror("first argument to append must be typed slice; have untyped nil", t);
+				goto error;
+			}
+			yyerror("first argument to append must be slice; have %lT", t);
+			goto error;
+		}
+
+		if(n->isddd) {
+			if(args->next == nil) {
+				yyerror("cannot use ... on first argument to append");
+				goto error;
+			}
+			if(args->next->next != nil) {
+				yyerror("too many arguments to append");
+				goto error;
+			}
+			if(istype(t->type, TUINT8) && istype(args->next->n->type, TSTRING)) {
+				defaultlit(&args->next->n, types[TSTRING]);
+				goto ret;
+			}
+			args->next->n = assignconv(args->next->n, t->orig, "append");
+			goto ret;
+		}
+		for(args=args->next; args != nil; args=args->next) {
+			if(args->n->type == T)
+				continue;
+			args->n = assignconv(args->n, t->type, "append");
+		}
+		goto ret;
+
+	case OCOPY:
+		ok |= Etop|Erv;
+		args = n->list;
+		if(args == nil || args->next == nil) {
+			yyerror("missing arguments to copy");
+			goto error;
+		}
+		if(args->next->next != nil) {
+			yyerror("too many arguments to copy");
+			goto error;
+		}
+		n->left = args->n;
+		n->right = args->next->n;
+		n->list = nil;
+		n->type = types[TINT];
+		typecheck(&n->left, Erv);
+		typecheck(&n->right, Erv);
+		if(n->left->type == T || n->right->type == T)
+			goto error;
+		defaultlit(&n->left, T);
+		defaultlit(&n->right, T);
+		if(n->left->type == T || n->right->type == T)
+			goto error;
+
+		// copy([]byte, string)
+		if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
+			if(eqtype(n->left->type->type, bytetype))
+				goto ret;
+			yyerror("arguments to copy have different element types: %lT and string", n->left->type);
+			goto error;
+		}
+
+		if(!isslice(n->left->type) || !isslice(n->right->type)) {
+			if(!isslice(n->left->type) && !isslice(n->right->type))
+				yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
+			else if(!isslice(n->left->type))
+				yyerror("first argument to copy should be slice; have %lT", n->left->type);
+			else
+				yyerror("second argument to copy should be slice or string; have %lT", n->right->type);
+			goto error;
+		}
+		if(!eqtype(n->left->type->type, n->right->type->type)) {
+			yyerror("arguments to copy have different element types: %lT and %lT", n->left->type, n->right->type);
+			goto error;
+		}
+		goto ret;
+
+	case OCONV:
+	doconv:
+		ok |= Erv;
+		saveorignode(n);
+		typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
+		convlit1(&n->left, n->type, 1);
+		if((t = n->left->type) == T || n->type == T)
+			goto error;
+		if((n->op = convertop(t, n->type, &why)) == 0) {
+			if(!n->diag && !n->type->broke) {
+				yyerror("cannot convert %lN to type %T%s", n->left, n->type, why);
+				n->diag = 1;
+			}
+			n->op = OCONV;
+		}
+		switch(n->op) {
+		case OCONVNOP:
+			if(n->left->op == OLITERAL) {
+				r = nod(OXXX, N, N);
+				n->op = OCONV;
+				n->orig = r;
+				*r = *n;
+				n->op = OLITERAL;
+				n->val = n->left->val;
+			}
+			break;
+		case OSTRARRAYBYTE:
+			// do not use stringtoarraylit.
+			// generated code and compiler memory footprint is better without it.
+			break;
+		case OSTRARRAYRUNE:
+			if(n->left->op == OLITERAL)
+				stringtoarraylit(&n);
+			break;
+		}
+		goto ret;
+
+	case OMAKE:
+		ok |= Erv;
+		args = n->list;
+		if(args == nil) {
+			yyerror("missing argument to make");
+			goto error;
+		}
+		n->list = nil;
+		l = args->n;
+		args = args->next;
+		typecheck(&l, Etype);
+		if((t = l->type) == T)
+			goto error;
+
+		switch(t->etype) {
+		default:
+		badmake:
+			yyerror("cannot make type %T", t);
+			goto error;
+
+		case TARRAY:
+			if(!isslice(t))
+				goto badmake;
+			if(args == nil) {
+				yyerror("missing len argument to make(%T)", t);
+				goto error;
+			}
+			l = args->n;
+			args = args->next;
+			typecheck(&l, Erv);
+			r = N;
+			if(args != nil) {
+				r = args->n;
+				args = args->next;
+				typecheck(&r, Erv);
+			}
+			if(l->type == T || (r && r->type == T))
+				goto error;
+			et = checkmake(t, "len", l) < 0;
+			et |= r && checkmake(t, "cap", r) < 0;
+			if(et)
+				goto error;
+			if(isconst(l, CTINT) && r && isconst(r, CTINT) && mpcmpfixfix(l->val.u.xval, r->val.u.xval) > 0) {
+				yyerror("len larger than cap in make(%T)", t);
+				goto error;
+			}
+			n->left = l;
+			n->right = r;
+			n->op = OMAKESLICE;
+			break;
+
+		case TMAP:
+			if(args != nil) {
+				l = args->n;
+				args = args->next;
+				typecheck(&l, Erv);
+				defaultlit(&l, types[TINT]);
+				if(l->type == T)
+					goto error;
+				if(checkmake(t, "size", l) < 0)
+					goto error;
+				n->left = l;
+			} else
+				n->left = nodintconst(0);
+			n->op = OMAKEMAP;
+			break;
+
+		case TCHAN:
+			l = N;
+			if(args != nil) {
+				l = args->n;
+				args = args->next;
+				typecheck(&l, Erv);
+				defaultlit(&l, types[TINT]);
+				if(l->type == T)
+					goto error;
+				if(checkmake(t, "buffer", l) < 0)
+					goto error;
+				n->left = l;
+			} else
+				n->left = nodintconst(0);
+			n->op = OMAKECHAN;
+			break;
+		}
+		if(args != nil) {
+			yyerror("too many arguments to make(%T)", t);
+			n->op = OMAKE;
+			goto error;
+		}
+		n->type = t;
+		goto ret;
+
+	case ONEW:
+		ok |= Erv;
+		args = n->list;
+		if(args == nil) {
+			yyerror("missing argument to new");
+			goto error;
+		}
+		l = args->n;
+		typecheck(&l, Etype);
+		if((t = l->type) == T)
+			goto error;
+		if(args->next != nil) {
+			yyerror("too many arguments to new(%T)", t);
+			goto error;
+		}
+		n->left = l;
+		n->type = ptrto(t);
+		goto ret;
+
+	case OPRINT:
+	case OPRINTN:
+		ok |= Etop;
+		typechecklist(n->list, Erv | Eindir);  // Eindir: address does not escape
+		for(args=n->list; args; args=args->next) {
+			// Special case for print: int constant is int64, not int.
+			if(isconst(args->n, CTINT))
+				defaultlit(&args->n, types[TINT64]);
+			else
+				defaultlit(&args->n, T);
+		}
+		goto ret;
+
+	case OPANIC:
+		ok |= Etop;
+		if(onearg(n, "panic") < 0)
+			goto error;
+		typecheck(&n->left, Erv);
+		defaultlit(&n->left, types[TINTER]);
+		if(n->left->type == T)
+			goto error;
+		goto ret;
+	
+	case ORECOVER:
+		ok |= Erv|Etop;
+		if(n->list != nil) {
+			yyerror("too many arguments to recover");
+			goto error;
+		}
+		n->type = types[TINTER];
+		goto ret;
+
+	case OCLOSURE:
+		ok |= Erv;
+		typecheckclosure(n, top);
+		if(n->type == T)
+			goto error;
+		goto ret;
+	
+	case OITAB:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		if((t = n->left->type) == T)
+			goto error;
+		if(t->etype != TINTER)
+			fatal("OITAB of %T", t);
+		n->type = ptrto(types[TUINTPTR]);
+		goto ret;
+
+	case OSPTR:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		if((t = n->left->type) == T)
+			goto error;
+		if(!isslice(t) && t->etype != TSTRING)
+			fatal("OSPTR of %T", t);
+		if(t->etype == TSTRING)
+			n->type = ptrto(types[TUINT8]);
+		else
+			n->type = ptrto(t->type);
+		goto ret;
+
+	case OCLOSUREVAR:
+		ok |= Erv;
+		goto ret;
+	
+	case OCFUNC:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		n->type = types[TUINTPTR];
+		goto ret;
+
+	case OCONVNOP:
+		ok |= Erv;
+		typecheck(&n->left, Erv);
+		goto ret;
+
+	/*
+	 * statements
+	 */
+	case OAS:
+		ok |= Etop;
+		typecheckas(n);
+		goto ret;
+
+	case OAS2:
+		ok |= Etop;
+		typecheckas2(n);
+		goto ret;
+
+	case OBREAK:
+	case OCONTINUE:
+	case ODCL:
+	case OEMPTY:
+	case OGOTO:
+	case OLABEL:
+	case OXFALL:
+	case OVARKILL:
+		ok |= Etop;
+		goto ret;
+
+	case ODEFER:
+		ok |= Etop;
+		typecheck(&n->left, Etop|Erv);
+		if(!n->left->diag)
+			checkdefergo(n);
+		goto ret;
+
+	case OPROC:
+		ok |= Etop;
+		typecheck(&n->left, Etop|Eproc|Erv);
+		checkdefergo(n);
+		goto ret;
+
+	case OFOR:
+		ok |= Etop;
+		typechecklist(n->ninit, Etop);
+		typecheck(&n->ntest, Erv);
+		if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
+			yyerror("non-bool %lN used as for condition", n->ntest);
+		typecheck(&n->nincr, Etop);
+		typechecklist(n->nbody, Etop);
+		goto ret;
+
+	case OIF:
+		ok |= Etop;
+		typechecklist(n->ninit, Etop);
+		typecheck(&n->ntest, Erv);
+		if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
+			yyerror("non-bool %lN used as if condition", n->ntest);
+		typechecklist(n->nbody, Etop);
+		typechecklist(n->nelse, Etop);
+		goto ret;
+
+	case ORETURN:
+		ok |= Etop;
+		if(count(n->list) == 1)
+			typechecklist(n->list, Erv | Efnstruct);
+		else
+			typechecklist(n->list, Erv);
+		if(curfn == N) {
+			yyerror("return outside function");
+			goto error;
+		}
+		if(curfn->type->outnamed && n->list == nil)
+			goto ret;
+		typecheckaste(ORETURN, nil, 0, getoutargx(curfn->type), n->list, "return argument");
+		goto ret;
+	
+	case ORETJMP:
+		ok |= Etop;
+		goto ret;
+
+	case OSELECT:
+		ok |= Etop;
+		typecheckselect(n);
+		goto ret;
+
+	case OSWITCH:
+		ok |= Etop;
+		typecheckswitch(n);
+		goto ret;
+
+	case ORANGE:
+		ok |= Etop;
+		typecheckrange(n);
+		goto ret;
+
+	case OTYPESW:
+		yyerror("use of .(type) outside type switch");
+		goto error;
+
+	case OXCASE:
+		ok |= Etop;
+		typechecklist(n->list, Erv);
+		typechecklist(n->nbody, Etop);
+		goto ret;
+
+	case ODCLFUNC:
+		ok |= Etop;
+		typecheckfunc(n);
+		goto ret;
+
+	case ODCLCONST:
+		ok |= Etop;
+		typecheck(&n->left, Erv);
+		goto ret;
+
+	case ODCLTYPE:
+		ok |= Etop;
+		typecheck(&n->left, Etype);
+		if(!incannedimport)
+			checkwidth(n->left->type);
+		goto ret;
+	}
+
+ret:
+	t = n->type;
+	if(t && !t->funarg && n->op != OTYPE) {
+		switch(t->etype) {
+		case TFUNC:	// might have TANY; wait until its called
+		case TANY:
+		case TFORW:
+		case TIDEAL:
+		case TNIL:
+		case TBLANK:
+			break;
+		default:
+			checkwidth(t);
+		}
+	}
+
+	if(safemode && !incannedimport && !importpkg && !compiling_wrappers && t && t->etype == TUNSAFEPTR)
+		yyerror("cannot use unsafe.Pointer");
+
+	evconst(n);
+	if(n->op == OTYPE && !(top & Etype)) {
+		yyerror("type %T is not an expression", n->type);
+		goto error;
+	}
+	if((top & (Erv|Etype)) == Etype && n->op != OTYPE) {
+		yyerror("%N is not a type", n);
+		goto error;
+	}
+	// TODO(rsc): simplify
+	if((top & (Ecall|Erv|Etype)) && !(top & Etop) && !(ok & (Erv|Etype|Ecall))) {
+		yyerror("%N used as value", n);
+		goto error;
+	}
+	if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) {
+		if(n->diag == 0) {
+			yyerror("%N evaluated but not used", n);
+			n->diag = 1;
+		}
+		goto error;
+	}
+
+	/* TODO
+	if(n->type == T)
+		fatal("typecheck nil type");
+	*/
+	goto out;
+
+badcall1:
+	yyerror("invalid argument %lN for %O", n->left, n->op);
+	goto error;
+
+error:
+	n->type = T;
+
+out:
+	*np = n;
+}
+
+static int
+checksliceindex(Node *l, Node *r, Type *tp)
+{
+	Type *t;
+
+	if((t = r->type) == T)
+		return -1;
+	if(!isint[t->etype]) {
+		yyerror("invalid slice index %N (type %T)", r, t);
+		return -1;
+	}
+	if(r->op == OLITERAL) {
+		if(mpgetfix(r->val.u.xval) < 0) {
+			yyerror("invalid slice index %N (index must be non-negative)", r);
+			return -1;
+		} else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) {
+			yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound);
+			return -1;
+		} else if(isconst(l, CTSTR) && mpgetfix(r->val.u.xval) > l->val.u.sval->len) {
+			yyerror("invalid slice index %N (out of bounds for %d-byte string)", r, l->val.u.sval->len);
+			return -1;
+		} else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) {
+			yyerror("invalid slice index %N (index too large)", r);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int
+checksliceconst(Node *lo, Node *hi)
+{
+	if(lo != N && hi != N && lo->op == OLITERAL && hi->op == OLITERAL
+	   && mpcmpfixfix(lo->val.u.xval, hi->val.u.xval) > 0) {
+		yyerror("invalid slice index: %N > %N", lo, hi);
+		return -1;
+	}
+	return 0;
+}
+
+static void
+checkdefergo(Node *n)
+{
+	char *what;
+	
+	what = "defer";
+	if(n->op == OPROC)
+		what = "go";
+
+	switch(n->left->op) {
+	case OCALLINTER:
+	case OCALLMETH:
+	case OCALLFUNC:
+	case OCLOSE:
+	case OCOPY:
+	case ODELETE:
+	case OPANIC:
+	case OPRINT:
+	case OPRINTN:
+	case ORECOVER:
+		// ok
+		break;
+	case OAPPEND:
+	case OCAP:
+	case OCOMPLEX:
+	case OIMAG:
+	case OLEN:
+	case OMAKE:
+	case OMAKESLICE:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case ONEW:
+	case OREAL:
+	case OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
+		if(n->left->orig != N && n->left->orig->op == OCONV)
+			goto conv;
+		yyerror("%s discards result of %N", what, n->left);
+		break;
+	default:
+	conv:
+		// type is broken or missing, most likely a method call on a broken type
+		// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
+		if(n->left->type == T || n->left->type->broke)
+			break;
+
+		if(!n->diag) {
+			// The syntax made sure it was a call, so this must be
+			// a conversion.
+			n->diag = 1;
+			yyerror("%s requires function call, not conversion", what);
+		}
+		break;
+	}
+}
+
+static void
+implicitstar(Node **nn)
+{
+	Type *t;
+	Node *n;
+
+	// insert implicit * if needed for fixed array
+	n = *nn;
+	t = n->type;
+	if(t == T || !isptr[t->etype])
+		return;
+	t = t->type;
+	if(t == T)
+		return;
+	if(!isfixedarray(t))
+		return;
+	n = nod(OIND, n, N);
+	n->implicit = 1;
+	typecheck(&n, Erv);
+	*nn = n;
+}
+
+static int
+onearg(Node *n, char *f, ...)
+{
+	va_list arg;
+	char *p;
+
+	if(n->left != N)
+		return 0;
+	if(n->list == nil) {
+		va_start(arg, f);
+		p = vsmprint(f, arg);
+		va_end(arg);
+		yyerror("missing argument to %s: %N", p, n);
+		return -1;
+	}
+	if(n->list->next != nil) {
+		va_start(arg, f);
+		p = vsmprint(f, arg);
+		va_end(arg);
+		yyerror("too many arguments to %s: %N", p, n);
+		n->left = n->list->n;
+		n->list = nil;
+		return -1;
+	}
+	n->left = n->list->n;
+	n->list = nil;
+	return 0;
+}
+
+static int
+twoarg(Node *n)
+{
+	if(n->left != N)
+		return 0;
+	if(n->list == nil) {
+		yyerror("missing argument to %O - %N", n->op, n);
+		return -1;
+	}
+	n->left = n->list->n;
+	if(n->list->next == nil) {
+		yyerror("missing argument to %O - %N", n->op, n);
+		n->list = nil;
+		return -1;
+	}
+	if(n->list->next->next != nil) {
+		yyerror("too many arguments to %O - %N", n->op, n);
+		n->list = nil;
+		return -1;
+	}
+	n->right = n->list->next->n;
+	n->list = nil;
+	return 0;
+}
+
+static Type*
+lookdot1(Node *errnode, Sym *s, Type *t, Type *f, int dostrcmp)
+{
+	Type *r;
+
+	r = T;
+	for(; f!=T; f=f->down) {
+		if(dostrcmp && strcmp(f->sym->name, s->name) == 0)
+			return f;
+		if(f->sym != s)
+			continue;
+		if(r != T) {
+			if(errnode)
+				yyerror("ambiguous selector %N", errnode);
+			else if(isptr[t->etype])
+				yyerror("ambiguous selector (%T).%S", t, s);
+			else
+				yyerror("ambiguous selector %T.%S", t, s);
+			break;
+		}
+		r = f;
+	}
+	return r;
+}
+
+static int
+looktypedot(Node *n, Type *t, int dostrcmp)
+{
+	Type *f1, *f2;
+	Sym *s;
+	
+	s = n->right->sym;
+
+	if(t->etype == TINTER) {
+		f1 = lookdot1(n, s, t, t->type, dostrcmp);
+		if(f1 == T)
+			return 0;
+
+		n->right = methodname(n->right, t);
+		n->xoffset = f1->width;
+		n->type = f1->type;
+		n->op = ODOTINTER;
+		return 1;
+	}
+
+	// Find the base type: methtype will fail if t
+	// is not of the form T or *T.
+	f2 = methtype(t, 0);
+	if(f2 == T)
+		return 0;
+
+	expandmeth(f2);
+	f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp);
+	if(f2 == T)
+		return 0;
+
+	// disallow T.m if m requires *T receiver
+	if(isptr[getthisx(f2->type)->type->type->etype]
+	&& !isptr[t->etype]
+	&& f2->embedded != 2
+	&& !isifacemethod(f2->type)) {
+		yyerror("invalid method expression %N (needs pointer receiver: (*%T).%hS)", n, t, f2->sym);
+		return 0;
+	}
+
+	n->right = methodname(n->right, t);
+	n->xoffset = f2->width;
+	n->type = f2->type;
+	n->op = ODOTMETH;
+	return 1;
+}
+
+static Type*
+derefall(Type* t)
+{
+	while(t && t->etype == tptr)
+		t = t->type;
+	return t;
+}
+
+static int
+lookdot(Node *n, Type *t, int dostrcmp)
+{
+	Type *f1, *f2, *tt, *rcvr;
+	Sym *s;
+
+	s = n->right->sym;
+
+	dowidth(t);
+	f1 = T;
+	if(t->etype == TSTRUCT || t->etype == TINTER)
+		f1 = lookdot1(n, s, t, t->type, dostrcmp);
+
+	f2 = T;
+	if(n->left->type == t || n->left->type->sym == S) {
+		f2 = methtype(t, 0);
+		if(f2 != T) {
+			// Use f2->method, not f2->xmethod: adddot has
+			// already inserted all the necessary embedded dots.
+			f2 = lookdot1(n, s, f2, f2->method, dostrcmp);
+		}
+	}
+
+	if(f1 != T) {
+		if(f2 != T)
+			yyerror("%S is both field and method",
+				n->right->sym);
+		if(f1->width == BADWIDTH)
+			fatal("lookdot badwidth %T %p", f1, f1);
+		n->xoffset = f1->width;
+		n->type = f1->type;
+		n->paramfld = f1;
+		if(t->etype == TINTER) {
+			if(isptr[n->left->type->etype]) {
+				n->left = nod(OIND, n->left, N);	// implicitstar
+				n->left->implicit = 1;
+				typecheck(&n->left, Erv);
+			}
+			n->op = ODOTINTER;
+		}
+		return 1;
+	}
+
+	if(f2 != T) {
+		tt = n->left->type;
+		dowidth(tt);
+		rcvr = getthisx(f2->type)->type->type;
+		if(!eqtype(rcvr, tt)) {
+			if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) {
+				checklvalue(n->left, "call pointer method on");
+				n->left = nod(OADDR, n->left, N);
+				n->left->implicit = 1;
+				typecheck(&n->left, Etype|Erv);
+			} else if(tt->etype == tptr && rcvr->etype != tptr && eqtype(tt->type, rcvr)) {
+				n->left = nod(OIND, n->left, N);
+				n->left->implicit = 1;
+				typecheck(&n->left, Etype|Erv);
+			} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), derefall(rcvr))) {
+				yyerror("calling method %N with receiver %lN requires explicit dereference", n->right, n->left);
+				while(tt->etype == tptr) {
+					// Stop one level early for method with pointer receiver.
+					if(rcvr->etype == tptr && tt->type->etype != tptr)
+						break;
+					n->left = nod(OIND, n->left, N);
+					n->left->implicit = 1;
+					typecheck(&n->left, Etype|Erv);
+					tt = tt->type;
+				}
+			} else {
+				fatal("method mismatch: %T for %T", rcvr, tt);
+			}
+		}
+		n->right = methodname(n->right, n->left->type);
+		n->xoffset = f2->width;
+		n->type = f2->type;
+//		print("lookdot found [%p] %T\n", f2->type, f2->type);
+		n->op = ODOTMETH;
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+nokeys(NodeList *l)
+{
+	for(; l; l=l->next)
+		if(l->n->op == OKEY)
+			return 0;
+	return 1;
+}
+
+static int
+hasddd(Type *t)
+{
+	Type *tl;
+
+	for(tl=t->type; tl; tl=tl->down) {
+		if(tl->isddd)
+			return 1;
+	}
+	return 0;
+}
+
+static int
+downcount(Type *t)
+{
+	Type *tl;
+	int n;
+
+	n = 0;
+	for(tl=t->type; tl; tl=tl->down) {
+		n++;
+	}
+	return n;
+}
+
+/*
+ * typecheck assignment: type list = expression list
+ */
+static void
+typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *desc)
+{
+	Type *t, *tl, *tn;
+	Node *n;
+	int lno;
+	char *why;
+	int n1, n2;
+
+	lno = lineno;
+
+	if(tstruct->broke)
+		goto out;
+
+	n = N;
+	if(nl != nil && nl->next == nil && (n = nl->n)->type != T)
+	if(n->type->etype == TSTRUCT && n->type->funarg) {
+		if(!hasddd(tstruct)) {
+			n1 = downcount(tstruct);
+			n2 = downcount(n->type);
+			if(n2 > n1)
+				goto toomany;
+			if(n2 < n1)
+				goto notenough;
+		}
+		
+		tn = n->type->type;
+		for(tl=tstruct->type; tl; tl=tl->down) {
+			if(tl->isddd) {
+				for(; tn; tn=tn->down) {
+					if(assignop(tn->type, tl->type->type, &why) == 0) {
+						if(call != N)
+							yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type->type, call, why);
+						else
+							yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type->type, desc, why);
+					}
+				}
+				goto out;
+			}
+			if(tn == T)
+				goto notenough;
+			if(assignop(tn->type, tl->type, &why) == 0) {
+				if(call != N)
+					yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type, call, why);
+				else
+					yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type, desc, why);
+			}
+			tn = tn->down;
+		}
+		if(tn != T)
+			goto toomany;
+		goto out;
+	}
+
+	n1 = downcount(tstruct);
+	n2 = count(nl);
+	if(!hasddd(tstruct)) {
+		if(n2 > n1)
+			goto toomany;
+		if(n2 < n1)
+			goto notenough;
+	}
+	else {
+		if(!isddd) {
+			if(n2 < n1-1)
+				goto notenough;
+		} else {
+			if(n2 > n1)
+				goto toomany;
+			if(n2 < n1)
+				goto notenough;
+		}
+	}
+
+	for(tl=tstruct->type; tl; tl=tl->down) {
+		t = tl->type;
+		if(tl->isddd) {
+			if(isddd) {
+				if(nl == nil)
+					goto notenough;
+				if(nl->next != nil)
+					goto toomany;
+				n = nl->n;
+				setlineno(n);
+				if(n->type != T)
+					nl->n = assignconv(n, t, desc);
+				goto out;
+			}
+			for(; nl; nl=nl->next) {
+				n = nl->n;
+				setlineno(nl->n);
+				if(n->type != T)
+					nl->n = assignconv(n, t->type, desc);
+			}
+			goto out;
+		}
+		if(nl == nil)
+			goto notenough;
+		n = nl->n;
+		setlineno(n);
+		if(n->type != T)
+			nl->n = assignconv(n, t, desc);
+		nl = nl->next;
+	}
+	if(nl != nil)
+		goto toomany;
+	if(isddd) {
+		if(call != N)
+			yyerror("invalid use of ... in call to %N", call);
+		else
+			yyerror("invalid use of ... in %O", op);
+	}
+
+out:
+	lineno = lno;
+	return;
+
+notenough:
+	if(n == N || !n->diag) {
+		if(call != N)
+			yyerror("not enough arguments in call to %N", call);
+		else
+			yyerror("not enough arguments to %O", op);
+		if(n != N)
+			n->diag = 1;
+	}
+	goto out;
+
+toomany:
+	if(call != N)
+		yyerror("too many arguments in call to %N", call);
+	else
+		yyerror("too many arguments to %O", op);
+	goto out;
+}
+
+/*
+ * type check composite
+ */
+
+static void
+fielddup(Node *n, Node *hash[], ulong nhash)
+{
+	uint h;
+	char *s;
+	Node *a;
+
+	if(n->op != ONAME)
+		fatal("fielddup: not ONAME");
+	s = n->sym->name;
+	h = stringhash(s)%nhash;
+	for(a=hash[h]; a!=N; a=a->ntest) {
+		if(strcmp(a->sym->name, s) == 0) {
+			yyerror("duplicate field name in struct literal: %s", s);
+			return;
+		}
+	}
+	n->ntest = hash[h];
+	hash[h] = n;
+}
+
+static void
+keydup(Node *n, Node *hash[], ulong nhash)
+{
+	uint h;
+	ulong b;
+	double d;
+	int i;
+	Node *a, *orign;
+	Node cmp;
+	char *s;
+
+	orign = n;
+	if(n->op == OCONVIFACE)
+		n = n->left;
+	evconst(n);
+	if(n->op != OLITERAL)
+		return;	// we dont check variables
+
+	switch(n->val.ctype) {
+	default:	// unknown, bool, nil
+		b = 23;
+		break;
+	case CTINT:
+	case CTRUNE:
+		b = mpgetfix(n->val.u.xval);
+		break;
+	case CTFLT:
+		d = mpgetflt(n->val.u.fval);
+		s = (char*)&d;
+		b = 0;
+		for(i=sizeof(d); i>0; i--)
+			b = b*PRIME1 + *s++;
+		break;
+	case CTSTR:
+		b = 0;
+		s = n->val.u.sval->s;
+		for(i=n->val.u.sval->len; i>0; i--)
+			b = b*PRIME1 + *s++;
+		break;
+	}
+
+	h = b%nhash;
+	memset(&cmp, 0, sizeof(cmp));
+	for(a=hash[h]; a!=N; a=a->ntest) {
+		cmp.op = OEQ;
+		cmp.left = n;
+		b = 0;
+		if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
+			if(eqtype(a->left->type, n->type)) {
+				cmp.right = a->left;
+				evconst(&cmp);
+				b = cmp.val.u.bval;
+			}
+		} else if(eqtype(a->type, n->type)) {
+			cmp.right = a;
+			evconst(&cmp);
+			b = cmp.val.u.bval;
+		}
+		if(b) {
+			yyerror("duplicate key %N in map literal", n);
+			return;
+		}
+	}
+	orign->ntest = hash[h];
+	hash[h] = orign;
+}
+
+static void
+indexdup(Node *n, Node *hash[], ulong nhash)
+{
+	uint h;
+	Node *a;
+	ulong b, c;
+
+	if(n->op != OLITERAL)
+		fatal("indexdup: not OLITERAL");
+
+	b = mpgetfix(n->val.u.xval);
+	h = b%nhash;
+	for(a=hash[h]; a!=N; a=a->ntest) {
+		c = mpgetfix(a->val.u.xval);
+		if(b == c) {
+			yyerror("duplicate index in array literal: %ld", b);
+			return;
+		}
+	}
+	n->ntest = hash[h];
+	hash[h] = n;
+}
+
+static int
+prime(ulong h, ulong sr)
+{
+	ulong n;
+
+	for(n=3; n<=sr; n+=2)
+		if(h%n == 0)
+			return 0;
+	return 1;
+}
+
+static ulong
+inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash)
+{
+	ulong h, sr;
+	NodeList *ll;
+	int i;
+
+	// count the number of entries
+	h = 0;
+	for(ll=n->list; ll; ll=ll->next)
+		h++;
+
+	// if the auto hash table is
+	// large enough use it.
+	if(h <= nautohash) {
+		*hash = autohash;
+		memset(*hash, 0, nautohash * sizeof(**hash));
+		return nautohash;
+	}
+
+	// make hash size odd and 12% larger than entries
+	h += h/8;
+	h |= 1;
+
+	// calculate sqrt of h
+	sr = h/2;
+	for(i=0; i<5; i++)
+		sr = (sr + h/sr)/2;
+
+	// check for primeality
+	while(!prime(h, sr))
+		h += 2;
+
+	// build and return a throw-away hash table
+	*hash = mal(h * sizeof(**hash));
+	memset(*hash, 0, h * sizeof(**hash));
+	return h;
+}
+
+static int
+iscomptype(Type *t)
+{
+	switch(t->etype) {
+	case TARRAY:
+	case TSTRUCT:
+	case TMAP:
+		return 1;
+	case TPTR32:
+	case TPTR64:
+		switch(t->type->etype) {
+		case TARRAY:
+		case TSTRUCT:
+		case TMAP:
+			return 1;
+		}
+		break;
+	}
+	return 0;
+}
+
+static void
+pushtype(Node *n, Type *t)
+{
+	if(n == N || n->op != OCOMPLIT || !iscomptype(t))
+		return;
+	
+	if(n->right == N) {
+		n->right = typenod(t);
+		n->implicit = 1;  // don't print
+		n->right->implicit = 1;  // * is okay
+	}
+	else if(debug['s']) {
+		typecheck(&n->right, Etype);
+		if(n->right->type != T && eqtype(n->right->type, t))
+			print("%lL: redundant type: %T\n", n->lineno, t);
+	}
+}
+
+static void
+typecheckcomplit(Node **np)
+{
+	int bad, i, nerr;
+	int64 len;
+	Node *l, *n, *norig, *r, **hash;
+	NodeList *ll;
+	Type *t, *f;
+	Sym *s, *s1;
+	int32 lno;
+	ulong nhash;
+	Node *autohash[101];
+
+	n = *np;
+	lno = lineno;
+
+	if(n->right == N) {
+		if(n->list != nil)
+			setlineno(n->list->n);
+		yyerror("missing type in composite literal");
+		goto error;
+	}
+
+	// Save original node (including n->right)
+	norig = nod(n->op, N, N);
+	*norig = *n;
+
+	setlineno(n->right);
+	l = typecheck(&n->right /* sic */, Etype|Ecomplit);
+	if((t = l->type) == T)
+		goto error;
+	nerr = nerrors;
+	n->type = t;
+
+	if(isptr[t->etype]) {
+		// For better or worse, we don't allow pointers as the composite literal type,
+		// except when using the &T syntax, which sets implicit on the OIND.
+		if(!n->right->implicit) {
+			yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
+			goto error;
+		}
+		// Also, the underlying type must be a struct, map, slice, or array.
+		if(!iscomptype(t)) {
+			yyerror("invalid pointer type %T for composite literal", t);
+			goto error;
+		}
+		t = t->type;
+	}
+
+	switch(t->etype) {
+	default:
+		yyerror("invalid type for composite literal: %T", t);
+		n->type = T;
+		break;
+
+	case TARRAY:
+		nhash = inithash(n, &hash, autohash, nelem(autohash));
+
+		len = 0;
+		i = 0;
+		for(ll=n->list; ll; ll=ll->next) {
+			l = ll->n;
+			setlineno(l);
+			if(l->op != OKEY) {
+				l = nod(OKEY, nodintconst(i), l);
+				l->left->type = types[TINT];
+				l->left->typecheck = 1;
+				ll->n = l;
+			}
+
+			typecheck(&l->left, Erv);
+			evconst(l->left);
+			i = nonnegconst(l->left);
+			if(i < 0 && !l->left->diag) {
+				yyerror("array index must be non-negative integer constant");
+				l->left->diag = 1;
+				i = -(1<<30);	// stay negative for a while
+			}
+			if(i >= 0)
+				indexdup(l->left, hash, nhash);
+			i++;
+			if(i > len) {
+				len = i;
+				if(t->bound >= 0 && len > t->bound) {
+					setlineno(l);
+					yyerror("array index %lld out of bounds [0:%lld]", len-1, t->bound);
+					t->bound = -1;	// no more errors
+				}
+			}
+
+			r = l->right;
+			pushtype(r, t->type);
+			typecheck(&r, Erv);
+			defaultlit(&r, t->type);
+			l->right = assignconv(r, t->type, "array element");
+		}
+		if(t->bound == -100)
+			t->bound = len;
+		if(t->bound < 0)
+			n->right = nodintconst(len);
+		n->op = OARRAYLIT;
+		break;
+
+	case TMAP:
+		nhash = inithash(n, &hash, autohash, nelem(autohash));
+
+		for(ll=n->list; ll; ll=ll->next) {
+			l = ll->n;
+			setlineno(l);
+			if(l->op != OKEY) {
+				typecheck(&ll->n, Erv);
+				yyerror("missing key in map literal");
+				continue;
+			}
+
+			typecheck(&l->left, Erv);
+			defaultlit(&l->left, t->down);
+			l->left = assignconv(l->left, t->down, "map key");
+			if (l->left->op != OCONV)
+				keydup(l->left, hash, nhash);
+
+			r = l->right;
+			pushtype(r, t->type);
+			typecheck(&r, Erv);
+			defaultlit(&r, t->type);
+			l->right = assignconv(r, t->type, "map value");
+		}
+		n->op = OMAPLIT;
+		break;
+
+	case TSTRUCT:
+		bad = 0;
+		if(n->list != nil && nokeys(n->list)) {
+			// simple list of variables
+			f = t->type;
+			for(ll=n->list; ll; ll=ll->next) {
+				setlineno(ll->n);
+				typecheck(&ll->n, Erv);
+				if(f == nil) {
+					if(!bad++)
+						yyerror("too many values in struct initializer");
+					continue;
+				}
+				s = f->sym;
+				if(s != nil && !exportname(s->name) && s->pkg != localpkg)
+					yyerror("implicit assignment of unexported field '%s' in %T literal", s->name, t);
+				// No pushtype allowed here.  Must name fields for that.
+				ll->n = assignconv(ll->n, f->type, "field value");
+				ll->n = nod(OKEY, newname(f->sym), ll->n);
+				ll->n->left->type = f;
+				ll->n->left->typecheck = 1;
+				f = f->down;
+			}
+			if(f != nil)
+				yyerror("too few values in struct initializer");
+		} else {
+			nhash = inithash(n, &hash, autohash, nelem(autohash));
+
+			// keyed list
+			for(ll=n->list; ll; ll=ll->next) {
+				l = ll->n;
+				setlineno(l);
+				if(l->op != OKEY) {
+					if(!bad++)
+						yyerror("mixture of field:value and value initializers");
+					typecheck(&ll->n, Erv);
+					continue;
+				}
+				s = l->left->sym;
+				if(s == S) {
+					yyerror("invalid field name %N in struct initializer", l->left);
+					typecheck(&l->right, Erv);
+					continue;
+				}
+
+				// Sym might have resolved to name in other top-level
+				// package, because of import dot.  Redirect to correct sym
+				// before we do the lookup.
+				if(s->pkg != localpkg && exportname(s->name)) {
+					s1 = lookup(s->name);
+					if(s1->origpkg == s->pkg)
+						s = s1;
+				}
+				f = lookdot1(nil, s, t, t->type, 0);
+				if(f == nil) {
+					yyerror("unknown %T field '%S' in struct literal", t, s);
+					continue;
+				}
+				l->left = newname(s);
+				l->left->typecheck = 1;
+				l->left->type = f;
+				s = f->sym;
+				fielddup(newname(s), hash, nhash);
+				r = l->right;
+				// No pushtype allowed here.  Tried and rejected.
+				typecheck(&r, Erv);
+				l->right = assignconv(r, f->type, "field value");
+			}
+		}
+		n->op = OSTRUCTLIT;
+		break;
+	}
+	if(nerr != nerrors)
+		goto error;
+	
+	n->orig = norig;
+	if(isptr[n->type->etype]) {
+		n = nod(OPTRLIT, n, N);
+		n->typecheck = 1;
+		n->type = n->left->type;
+		n->left->type = t;
+		n->left->typecheck = 1;
+	}
+
+	n->orig = norig;
+	*np = n;
+	lineno = lno;
+	return;
+
+error:
+	n->type = T;
+	*np = n;
+	lineno = lno;
+}
+
+/*
+ * lvalue etc
+ */
+int
+islvalue(Node *n)
+{
+	switch(n->op) {
+	case OINDEX:
+		if(isfixedarray(n->left->type))
+			return islvalue(n->left);
+		if(n->left->type != T && n->left->type->etype == TSTRING)
+			return 0;
+		// fall through
+	case OIND:
+	case ODOTPTR:
+	case OCLOSUREVAR:
+		return 1;
+	case ODOT:
+		return islvalue(n->left);
+	case ONAME:
+		if(n->class == PFUNC)
+			return 0;
+		return 1;
+	}
+	return 0;
+}
+
+static void
+checklvalue(Node *n, char *verb)
+{
+	if(!islvalue(n))
+		yyerror("cannot %s %N", verb, n);
+}
+
+static void
+checkassign(Node *n)
+{
+	if(islvalue(n))
+		return;
+	if(n->op == OINDEXMAP) {
+		n->etype = 1;
+		return;
+	}
+
+	// have already complained about n being undefined
+	if(n->op == ONONAME)
+		return;
+
+	yyerror("cannot assign to %N", n);
+}
+
+static void
+checkassignlist(NodeList *l)
+{
+	for(; l; l=l->next)
+		checkassign(l->n);
+}
+
+// Check whether l and r are the same side effect-free expression,
+// so that it is safe to reuse one instead of computing both.
+static int
+samesafeexpr(Node *l, Node *r)
+{
+	if(l->op != r->op || !eqtype(l->type, r->type))
+		return 0;
+	
+	switch(l->op) {
+	case ONAME:
+	case OCLOSUREVAR:
+		return l == r;
+	
+	case ODOT:
+	case ODOTPTR:
+		return l->right != nil && r->right != nil && l->right->sym == r->right->sym && samesafeexpr(l->left, r->left);
+	
+	case OIND:
+		return samesafeexpr(l->left, r->left);
+	
+	case OINDEX:
+		return samesafeexpr(l->left, r->left) && samesafeexpr(l->right, r->right);
+	}
+	
+	return 0;
+}
+
+/*
+ * type check assignment.
+ * if this assignment is the definition of a var on the left side,
+ * fill in the var's type.
+ */
+
+static void
+typecheckas(Node *n)
+{
+	// delicate little dance.
+	// the definition of n may refer to this assignment
+	// as its definition, in which case it will call typecheckas.
+	// in that case, do not call typecheck back, or it will cycle.
+	// if the variable has a type (ntype) then typechecking
+	// will not look at defn, so it is okay (and desirable,
+	// so that the conversion below happens).
+	n->left = resolve(n->left);
+	if(n->left->defn != n || n->left->ntype)
+		typecheck(&n->left, Erv | Easgn);
+
+	checkassign(n->left);
+	typecheck(&n->right, Erv);
+	if(n->right && n->right->type != T) {
+		if(n->left->type != T)
+			n->right = assignconv(n->right, n->left->type, "assignment");
+	}
+	if(n->left->defn == n && n->left->ntype == N) {
+		defaultlit(&n->right, T);
+		n->left->type = n->right->type;
+	}
+
+	// second half of dance.
+	// now that right is done, typecheck the left
+	// just to get it over with.  see dance above.
+	n->typecheck = 1;
+	if(n->left->typecheck == 0)
+		typecheck(&n->left, Erv | Easgn);
+	
+	// Recognize slices being updated in place, for better code generation later.
+	// Don't rewrite if using race detector, to avoid needing to teach race detector
+	// about this optimization.
+	if(n->left && n->left->op != OINDEXMAP && n->right && !flag_race) {
+		switch(n->right->op) {
+		case OSLICE:
+		case OSLICE3:
+		case OSLICESTR:
+			// For x = x[0:y], x can be updated in place, without touching pointer.
+			if(samesafeexpr(n->left, n->right->left) && (n->right->right->left == N || iszero(n->right->right->left)))
+				n->right->reslice = 1;
+			break;
+		
+		case OAPPEND:
+			// For x = append(x, ...), x can be updated in place when there is capacity,
+			// without touching the pointer; otherwise the emitted code to growslice
+			// can take care of updating the pointer, and only in that case.
+			if(n->right->list != nil && samesafeexpr(n->left, n->right->list->n))
+				n->right->reslice = 1;
+			break;
+		}
+	}
+}
+
+static void
+checkassignto(Type *src, Node *dst)
+{
+	char *why;
+
+	if(assignop(src, dst->type, &why) == 0) {
+		yyerror("cannot assign %T to %lN in multiple assignment%s", src, dst, why);
+		return;
+	}
+}
+
+static void
+typecheckas2(Node *n)
+{
+	int cl, cr;
+	NodeList *ll, *lr;
+	Node *l, *r;
+	Iter s;
+	Type *t;
+
+	for(ll=n->list; ll; ll=ll->next) {
+		// delicate little dance.
+		ll->n = resolve(ll->n);
+		if(ll->n->defn != n || ll->n->ntype)
+			typecheck(&ll->n, Erv | Easgn);
+	}
+	cl = count(n->list);
+	cr = count(n->rlist);
+	checkassignlist(n->list);
+	if(cl > 1 && cr == 1)
+		typecheck(&n->rlist->n, Erv | Efnstruct);
+	else
+		typechecklist(n->rlist, Erv);
+
+	if(cl == cr) {
+		// easy
+		for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next) {
+			if(ll->n->type != T && lr->n->type != T)
+				lr->n = assignconv(lr->n, ll->n->type, "assignment");
+			if(ll->n->defn == n && ll->n->ntype == N) {
+				defaultlit(&lr->n, T);
+				ll->n->type = lr->n->type;
+			}
+		}
+		goto out;
+	}
+
+
+	l = n->list->n;
+	r = n->rlist->n;
+
+	// m[i] = x, ok
+	if(cl == 1 && cr == 2 && l->op == OINDEXMAP) {
+		if(l->type == T)
+			goto out;
+		yyerror("assignment count mismatch: %d = %d (use delete)", cl, cr);
+		goto out;
+	}
+
+	// x,y,z = f()
+	if(cr == 1) {
+		if(r->type == T)
+			goto out;
+		switch(r->op) {
+		case OCALLMETH:
+		case OCALLINTER:
+		case OCALLFUNC:
+			if(r->type->etype != TSTRUCT || r->type->funarg == 0)
+				break;
+			cr = structcount(r->type);
+			if(cr != cl)
+				goto mismatch;
+			n->op = OAS2FUNC;
+			t = structfirst(&s, &r->type);
+			for(ll=n->list; ll; ll=ll->next) {
+				if(t->type != T && ll->n->type != T)
+					checkassignto(t->type, ll->n);
+				if(ll->n->defn == n && ll->n->ntype == N)
+					ll->n->type = t->type;
+				t = structnext(&s);
+			}
+			goto out;
+		}
+	}
+
+	// x, ok = y
+	if(cl == 2 && cr == 1) {
+		if(r->type == T)
+			goto out;
+		switch(r->op) {
+		case OINDEXMAP:
+			n->op = OAS2MAPR;
+			goto common;
+		case ORECV:
+			n->op = OAS2RECV;
+			goto common;
+		case ODOTTYPE:
+			n->op = OAS2DOTTYPE;
+			r->op = ODOTTYPE2;
+		common:
+			if(l->type != T)
+				checkassignto(r->type, l);
+			if(l->defn == n)
+				l->type = r->type;
+			l = n->list->next->n;
+			if(l->type != T && l->type->etype != TBOOL)
+				checkassignto(types[TBOOL], l);
+			if(l->defn == n && l->ntype == N)
+				l->type = types[TBOOL];
+			goto out;
+		}
+	}
+
+mismatch:
+	yyerror("assignment count mismatch: %d = %d", cl, cr);
+
+out:
+	// second half of dance
+	n->typecheck = 1;
+	for(ll=n->list; ll; ll=ll->next)
+		if(ll->n->typecheck == 0)
+			typecheck(&ll->n, Erv | Easgn);
+}
+
+/*
+ * type check function definition
+ */
+static void
+typecheckfunc(Node *n)
+{
+	Type *t, *rcvr;
+
+	typecheck(&n->nname, Erv | Easgn);
+	if((t = n->nname->type) == T)
+		return;
+	n->type = t;
+	t->nname = n->nname;
+	rcvr = getthisx(t)->type;
+	if(rcvr != nil && n->shortname != N && !isblank(n->shortname))
+		addmethod(n->shortname->sym, t, 1, n->nname->nointerface);
+}
+
+static void
+stringtoarraylit(Node **np)
+{
+	int32 i;
+	NodeList *l;
+	Strlit *s;
+	char *p, *ep;
+	Rune r;
+	Node *nn, *n;
+
+	n = *np;
+	if(n->left->op != OLITERAL || n->left->val.ctype != CTSTR)
+		fatal("stringtoarraylit %N", n);
+
+	s = n->left->val.u.sval;
+	l = nil;
+	p = s->s;
+	ep = s->s + s->len;
+	i = 0;
+	if(n->type->type->etype == TUINT8) {
+		// raw []byte
+		while(p < ep)
+			l = list(l, nod(OKEY, nodintconst(i++), nodintconst((uchar)*p++)));
+	} else {
+		// utf-8 []rune
+		while(p < ep) {
+			p += chartorune(&r, p);
+			l = list(l, nod(OKEY, nodintconst(i++), nodintconst(r)));
+		}
+	}
+	nn = nod(OCOMPLIT, N, typenod(n->type));
+	nn->list = l;
+	typecheck(&nn, Erv);
+	*np = nn;
+}
+
+
+static int ntypecheckdeftype;
+static NodeList *methodqueue;
+
+static void
+domethod(Node *n)
+{
+	Node *nt;
+	Type *t;
+
+	nt = n->type->nname;
+	typecheck(&nt, Etype);
+	if(nt->type == T) {
+		// type check failed; leave empty func
+		n->type->etype = TFUNC;
+		n->type->nod = N;
+		return;
+	}
+	
+	// If we have
+	//	type I interface {
+	//		M(_ int)
+	//	}
+	// then even though I.M looks like it doesn't care about the
+	// value of its argument, a specific implementation of I may
+	// care.  The _ would suppress the assignment to that argument
+	// while generating a call, so remove it.
+	for(t=getinargx(nt->type)->type; t; t=t->down) {
+		if(t->sym != nil && strcmp(t->sym->name, "_") == 0)
+			t->sym = nil;
+	}
+
+	*n->type = *nt->type;
+	n->type->nod = N;
+	checkwidth(n->type);
+}
+
+static NodeList *mapqueue;
+
+void
+copytype(Node *n, Type *t)
+{
+	int maplineno, embedlineno, lno;
+	NodeList *l;
+
+	if(t->etype == TFORW) {
+		// This type isn't computed yet; when it is, update n.
+		t->copyto = list(t->copyto, n);
+		return;
+	}
+
+	maplineno = n->type->maplineno;
+	embedlineno = n->type->embedlineno;
+
+	l = n->type->copyto;
+	*n->type = *t;
+
+	t = n->type;
+	t->sym = n->sym;
+	t->local = n->local;
+	t->vargen = n->vargen;
+	t->siggen = 0;
+	t->method = nil;
+	t->xmethod = nil;
+	t->nod = N;
+	t->printed = 0;
+	t->deferwidth = 0;
+	t->copyto = nil;
+	
+	// Update nodes waiting on this type.
+	for(; l; l=l->next)
+		copytype(l->n, t);
+
+	// Double-check use of type as embedded type.
+	lno = lineno;
+	if(embedlineno) {
+		lineno = embedlineno;
+		if(isptr[t->etype])
+			yyerror("embedded type cannot be a pointer");
+	}
+	lineno = lno;
+	
+	// Queue check for map until all the types are done settling.
+	if(maplineno) {
+		t->maplineno = maplineno;
+		mapqueue = list(mapqueue, n);
+	}
+}
+
+static void
+typecheckdeftype(Node *n)
+{
+	int lno;
+	Type *t;
+	NodeList *l;
+
+	ntypecheckdeftype++;
+	lno = lineno;
+	setlineno(n);
+	n->type->sym = n->sym;
+	n->typecheck = 1;
+	typecheck(&n->ntype, Etype);
+	if((t = n->ntype->type) == T) {
+		n->diag = 1;
+		n->type = T;
+		goto ret;
+	}
+	if(n->type == T) {
+		n->diag = 1;
+		goto ret;
+	}
+
+	// copy new type and clear fields
+	// that don't come along.
+	// anything zeroed here must be zeroed in
+	// typedcl2 too.
+	copytype(n, t);
+
+ret:
+	lineno = lno;
+
+	// if there are no type definitions going on, it's safe to
+	// try to resolve the method types for the interfaces
+	// we just read.
+	if(ntypecheckdeftype == 1) {
+		while((l = methodqueue) != nil) {
+			methodqueue = nil;
+			for(; l; l=l->next)
+				domethod(l->n);
+		}
+		for(l=mapqueue; l; l=l->next) {
+			lineno = l->n->type->maplineno;
+			maptype(l->n->type, types[TBOOL]);
+		}
+		lineno = lno;
+	}
+	ntypecheckdeftype--;
+}
+
+void
+queuemethod(Node *n)
+{
+	if(ntypecheckdeftype == 0) {
+		domethod(n);
+		return;
+	}
+	methodqueue = list(methodqueue, n);
+}
+
+Node*
+typecheckdef(Node *n)
+{
+	int lno, nerrors0;
+	Node *e;
+	Type *t;
+	NodeList *l;
+
+	lno = lineno;
+	setlineno(n);
+
+	if(n->op == ONONAME) {
+		if(!n->diag) {
+			n->diag = 1;
+			if(n->lineno != 0)
+				lineno = n->lineno;
+			yyerror("undefined: %S", n->sym);
+		}
+		return n;
+	}
+
+	if(n->walkdef == 1)
+		return n;
+
+	l = mal(sizeof *l);
+	l->n = n;
+	l->next = typecheckdefstack;
+	typecheckdefstack = l;
+
+	if(n->walkdef == 2) {
+		flusherrors();
+		print("typecheckdef loop:");
+		for(l=typecheckdefstack; l; l=l->next)
+			print(" %S", l->n->sym);
+		print("\n");
+		fatal("typecheckdef loop");
+	}
+	n->walkdef = 2;
+
+	if(n->type != T || n->sym == S)	// builtin or no name
+		goto ret;
+
+	switch(n->op) {
+	default:
+		fatal("typecheckdef %O", n->op);
+
+	case OGOTO:
+	case OLABEL:
+		// not really syms
+		break;
+
+	case OLITERAL:
+		if(n->ntype != N) {
+			typecheck(&n->ntype, Etype);
+			n->type = n->ntype->type;
+			n->ntype = N;
+			if(n->type == T) {
+				n->diag = 1;
+				goto ret;
+			}
+		}
+		e = n->defn;
+		n->defn = N;
+		if(e == N) {
+			lineno = n->lineno;
+			dump("typecheckdef nil defn", n);
+			yyerror("xxx");
+		}
+		typecheck(&e, Erv | Eiota);
+		if(isconst(e, CTNIL)) {
+			yyerror("const initializer cannot be nil");
+			goto ret;
+		}
+		if(e->type != T && e->op != OLITERAL || !isgoconst(e)) {
+			if(!e->diag) {
+				yyerror("const initializer %N is not a constant", e);
+				e->diag = 1;
+			}
+			goto ret;
+		}
+		t = n->type;
+		if(t != T) {
+			if(!okforconst[t->etype]) {
+				yyerror("invalid constant type %T", t);
+				goto ret;
+			}
+			if(!isideal(e->type) && !eqtype(t, e->type)) {
+				yyerror("cannot use %lN as type %T in const initializer", e, t);
+				goto ret;
+			}
+			convlit(&e, t);
+		}
+		n->val = e->val;
+		n->type = e->type;
+		break;
+
+	case ONAME:
+		if(n->ntype != N) {
+			typecheck(&n->ntype, Etype);
+			n->type = n->ntype->type;
+
+			if(n->type == T) {
+				n->diag = 1;
+				goto ret;
+			}
+		}
+		if(n->type != T)
+			break;
+		if(n->defn == N) {
+			if(n->etype != 0)	// like OPRINTN
+				break;
+			if(nsavederrors+nerrors > 0) {
+				// Can have undefined variables in x := foo
+				// that make x have an n->ndefn == nil.
+				// If there are other errors anyway, don't
+				// bother adding to the noise.
+				break;
+			}
+			fatal("var without type, init: %S", n->sym);
+		}
+		if(n->defn->op == ONAME) {
+			typecheck(&n->defn, Erv);
+			n->type = n->defn->type;
+			break;
+		}
+		typecheck(&n->defn, Etop);	// fills in n->type
+		break;
+
+	case OTYPE:
+		if(curfn)
+			defercheckwidth();
+		n->walkdef = 1;
+		n->type = typ(TFORW);
+		n->type->sym = n->sym;
+		nerrors0 = nerrors;
+		typecheckdeftype(n);
+		if(n->type->etype == TFORW && nerrors > nerrors0) {
+			// Something went wrong during type-checking,
+			// but it was reported. Silence future errors.
+			n->type->broke = 1;
+		}
+		if(curfn)
+			resumecheckwidth();
+		break;
+
+	case OPACK:
+		// nothing to see here
+		break;
+	}
+
+ret:
+	if(n->op != OLITERAL && n->type != T && isideal(n->type))
+		fatal("got %T for %N", n->type, n);
+	if(typecheckdefstack->n != n)
+		fatal("typecheckdefstack mismatch");
+	l = typecheckdefstack;
+	typecheckdefstack = l->next;
+
+	lineno = lno;
+	n->walkdef = 1;
+	return n;
+}
+
+static int
+checkmake(Type *t, char *arg, Node *n)
+{
+	if(n->op == OLITERAL) {
+		switch(n->val.ctype) {
+		case CTINT:
+		case CTRUNE:
+		case CTFLT:
+		case CTCPLX:
+			n->val = toint(n->val);
+			if(mpcmpfixc(n->val.u.xval, 0) < 0) {
+				yyerror("negative %s argument in make(%T)", arg, t);
+				return -1;
+			}
+			if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
+				yyerror("%s argument too large in make(%T)", arg, t);
+				return -1;
+			}
+			
+			// Delay defaultlit until after we've checked range, to avoid
+			// a redundant "constant NNN overflows int" error.
+			defaultlit(&n, types[TINT]);
+			return 0;
+		default:
+		       	break;
+		}
+	}
+
+	if(!isint[n->type->etype] && n->type->etype != TIDEAL) {
+		yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type);
+		return -1;
+	}
+
+	// Defaultlit still necessary for non-constant: n might be 1<<k.
+	defaultlit(&n, types[TINT]);
+
+	return 0;
+}
+
+static void	markbreaklist(NodeList*, Node*);
+
+static void
+markbreak(Node *n, Node *implicit)
+{
+	Label *lab;
+
+	if(n == N)
+		return;
+
+	switch(n->op) {
+	case OBREAK:
+		if(n->left == N) {
+			if(implicit)
+				implicit->hasbreak = 1;
+		} else {
+			lab = n->left->sym->label;
+			if(lab != L)
+				lab->def->hasbreak = 1;
+		}
+		break;
+	
+	case OFOR:
+	case OSWITCH:
+	case OTYPESW:
+	case OSELECT:
+	case ORANGE:
+		implicit = n;
+		// fall through
+	
+	default:
+		markbreak(n->left, implicit);
+		markbreak(n->right, implicit);
+		markbreak(n->ntest, implicit);
+		markbreak(n->nincr, implicit);
+		markbreaklist(n->ninit, implicit);
+		markbreaklist(n->nbody, implicit);
+		markbreaklist(n->nelse, implicit);
+		markbreaklist(n->list, implicit);
+		markbreaklist(n->rlist, implicit);
+		break;
+	}
+}
+
+static void
+markbreaklist(NodeList *l, Node *implicit)
+{
+	Node *n;
+	Label *lab;
+
+	for(; l; l=l->next) {
+		n = l->n;
+		if(n->op == OLABEL && l->next && n->defn == l->next->n) {
+			switch(n->defn->op) {
+			case OFOR:
+			case OSWITCH:
+			case OTYPESW:
+			case OSELECT:
+			case ORANGE:
+				lab = mal(sizeof *lab);
+				lab->def = n->defn;
+				n->left->sym->label = lab;
+				markbreak(n->defn, n->defn);
+				n->left->sym->label = L;
+				l = l->next;
+				continue;
+			}
+		}
+		markbreak(n, implicit);
+	}
+}
+
+static int
+isterminating(NodeList *l, int top)
+{
+	int def;
+	Node *n;
+
+	if(l == nil)
+		return 0;
+	if(top) {
+		while(l->next && l->n->op != OLABEL)
+			l = l->next;
+		markbreaklist(l, nil);
+	}
+	while(l->next)
+		l = l->next;
+	n = l->n;
+
+	if(n == N)
+		return 0;
+
+	switch(n->op) {
+	// NOTE: OLABEL is treated as a separate statement,
+	// not a separate prefix, so skipping to the last statement
+	// in the block handles the labeled statement case by
+	// skipping over the label. No case OLABEL here.
+
+	case OBLOCK:
+		return isterminating(n->list, 0);
+
+	case OGOTO:
+	case ORETURN:
+	case ORETJMP:
+	case OPANIC:
+	case OXFALL:
+		return 1;
+
+	case OFOR:
+		if(n->ntest != N)
+			return 0;
+		if(n->hasbreak)
+			return 0;
+		return 1;
+
+	case OIF:
+		return isterminating(n->nbody, 0) && isterminating(n->nelse, 0);
+
+	case OSWITCH:
+	case OTYPESW:
+	case OSELECT:
+		if(n->hasbreak)
+			return 0;
+		def = 0;
+		for(l=n->list; l; l=l->next) {
+			if(!isterminating(l->n->nbody, 0))
+				return 0;
+			if(l->n->list == nil) // default
+				def = 1;
+		}
+		if(n->op != OSELECT && !def)
+			return 0;
+		return 1;
+	}
+	
+	return 0;
+}
+
+void
+checkreturn(Node *fn)
+{
+	if(fn->type->outtuple && fn->nbody != nil)
+		if(!isterminating(fn->nbody, 1))
+			yyerrorl(fn->endlineno, "missing return at end of function");
+}
diff --git a/src/cmd/gc/unsafe.c b/src/cmd/gc/unsafe.c
new file mode 100644
index 0000000..ff08c0e
--- /dev/null
+++ b/src/cmd/gc/unsafe.c
@@ -0,0 +1,148 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+/*
+ * look for
+ *	unsafe.Sizeof
+ *	unsafe.Offsetof
+ *	unsafe.Alignof
+ * rewrite with a constant
+ */
+Node*
+unsafenmagic(Node *nn)
+{
+	Node *r, *n, *base, *r1;
+	Sym *s;
+	Type *t, *tr;
+	vlong v;
+	Val val;
+	Node *fn;
+	NodeList *args;
+
+	fn = nn->left;
+	args = nn->list;
+
+	if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
+		goto no;
+	if(s->pkg != unsafepkg)
+		goto no;
+
+	if(args == nil) {
+		yyerror("missing argument for %S", s);
+		goto no;
+	}
+	r = args->n;
+
+	if(strcmp(s->name, "Sizeof") == 0) {
+		typecheck(&r, Erv);
+		defaultlit(&r, T);
+		tr = r->type;
+		if(tr == T)
+			goto bad;
+		dowidth(tr);
+		v = tr->width;
+		goto yes;
+	}
+	if(strcmp(s->name, "Offsetof") == 0) {
+		// must be a selector.
+		if(r->op != OXDOT)
+			goto bad;
+		// Remember base of selector to find it back after dot insertion.
+		// Since r->left may be mutated by typechecking, check it explicitly
+		// first to track it correctly.
+		typecheck(&r->left, Erv);
+		base = r->left;
+		typecheck(&r, Erv);
+		switch(r->op) {
+		case ODOT:
+		case ODOTPTR:
+			break;
+		case OCALLPART:
+			yyerror("invalid expression %N: argument is a method value", nn);
+			v = 0;
+			goto ret;
+		default:
+			goto bad;
+		}
+		v = 0;
+		// add offsets for inserted dots.
+		for(r1=r; r1->left!=base; r1=r1->left) {
+			switch(r1->op) {
+			case ODOT:
+				v += r1->xoffset;
+				break;
+			case ODOTPTR:
+				yyerror("invalid expression %N: selector implies indirection of embedded %N", nn, r1->left);
+				goto ret;
+			default:
+				dump("unsafenmagic", r);
+				fatal("impossible %#O node after dot insertion", r1->op);
+				goto bad;
+			}
+		}
+		v += r1->xoffset;
+		goto yes;
+	}
+	if(strcmp(s->name, "Alignof") == 0) {
+		typecheck(&r, Erv);
+		defaultlit(&r, T);
+		tr = r->type;
+		if(tr == T)
+			goto bad;
+
+		// make struct { byte; T; }
+		t = typ(TSTRUCT);
+		t->type = typ(TFIELD);
+		t->type->type = types[TUINT8];
+		t->type->down = typ(TFIELD);
+		t->type->down->type = tr;
+		// compute struct widths
+		dowidth(t);
+
+		// the offset of T is its required alignment
+		v = t->type->down->width;
+		goto yes;
+	}
+
+no:
+	return N;
+
+bad:
+	yyerror("invalid expression %N", nn);
+	v = 0;
+	goto ret;
+
+yes:
+	if(args->next != nil)
+		yyerror("extra arguments for %S", s);
+ret:
+	// any side effects disappear; ignore init
+	val.ctype = CTINT;
+	val.u.xval = mal(sizeof(*n->val.u.xval));
+	mpmovecfix(val.u.xval, v);
+	n = nod(OLITERAL, N, N);
+	n->orig = nn;
+	n->val = val;
+	n->type = types[TUINTPTR];
+	nn->type = types[TUINTPTR];
+	return n;
+}
+
+int
+isunsafebuiltin(Node *n)
+{
+	if(n == N || n->op != ONAME || n->sym == S || n->sym->pkg != unsafepkg)
+		return 0;
+	if(strcmp(n->sym->name, "Sizeof") == 0)
+		return 1;
+	if(strcmp(n->sym->name, "Offsetof") == 0)
+		return 1;
+	if(strcmp(n->sym->name, "Alignof") == 0)
+		return 1;
+	return 0;
+}
diff --git a/src/cmd/gc/unsafe.go b/src/cmd/gc/unsafe.go
new file mode 100644
index 0000000..c3c6278
--- /dev/null
+++ b/src/cmd/gc/unsafe.go
@@ -0,0 +1,18 @@
+// 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.
+
+// NOTE: If you change this file you must run "./mkbuiltin"
+// to update builtin.c.boot.  This is not done automatically
+// to avoid depending on having a working compiler binary.
+
+// +build ignore
+
+package PACKAGE
+
+type Pointer uintptr // not really; filled in by compiler
+
+// return types here are ignored; see unsafe.c
+func Offsetof(any) uintptr
+func Sizeof(any) uintptr
+func Alignof(any) uintptr
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
new file mode 100644
index 0000000..ff9b362
--- /dev/null
+++ b/src/cmd/gc/walk.c
@@ -0,0 +1,3937 @@
+// 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.
+
+#include	<u.h>
+#include	<libc.h>
+#include	"go.h"
+#include	"../ld/textflag.h"
+
+static	Node*	walkprint(Node*, NodeList**);
+static	Node*	writebarrierfn(char*, Type*, Type*);
+static	Node*	applywritebarrier(Node*, NodeList**);
+static	Node*	mapfn(char*, Type*);
+static	Node*	mapfndel(char*, Type*);
+static	Node*	ascompatee1(int, Node*, Node*, NodeList**);
+static	NodeList*	ascompatee(int, NodeList*, NodeList*, NodeList**);
+static	NodeList*	ascompatet(int, NodeList*, Type**, int, NodeList**);
+static	NodeList*	ascompatte(int, Node*, int, Type**, NodeList*, int, NodeList**);
+static	Node*	convas(Node*, NodeList**);
+static	void	heapmoves(void);
+static	NodeList*	paramstoheap(Type **argin, int out);
+static	NodeList*	reorder1(NodeList*);
+static	NodeList*	reorder3(NodeList*);
+static	Node*	addstr(Node*, NodeList**);
+static	Node*	appendslice(Node*, NodeList**);
+static	Node*	append(Node*, NodeList**);
+static	Node*	copyany(Node*, NodeList**, int);
+static	Node*	sliceany(Node*, NodeList**);
+static	void	walkcompare(Node**, NodeList**);
+static	void	walkrotate(Node**);
+static	void	walkmul(Node**, NodeList**);
+static	void	walkdiv(Node**, NodeList**);
+static	int	bounded(Node*, int64);
+static	Mpint	mpzero;
+static	void	walkprintfunc(Node**, NodeList**);
+
+void
+walk(Node *fn)
+{
+	char s[50];
+	NodeList *l;
+	int lno;
+
+	curfn = fn;
+
+	if(debug['W']) {
+		snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
+		dumplist(s, curfn->nbody);
+	}
+
+	lno = 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; 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; l=l->next)
+		if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO && l->n->defn && l->n->defn->op == OTYPESW && l->n->used)
+			l->n->defn->left->used++;
+	
+	for(l=fn->dcl; l; l=l->next) {
+		if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used)
+			continue;
+		if(l->n->defn && l->n->defn->op == OTYPESW) {
+			if(l->n->defn->left->used)
+				continue;
+			lineno = l->n->defn->left->lineno;
+			yyerror("%S declared and not used", l->n->sym);
+			l->n->defn->left->used = 1; // suppress repeats
+		} else {
+			lineno = l->n->lineno;
+			yyerror("%S declared and not used", l->n->sym);
+		}
+	}	
+
+	lineno = lno;
+	if(nerrors != 0)
+		return;
+	walkstmtlist(curfn->nbody);
+	if(debug['W']) {
+		snprint(s, sizeof(s), "after walk %S", curfn->nname->sym);
+		dumplist(s, curfn->nbody);
+	}
+	heapmoves();
+	if(debug['W'] && curfn->enter != nil) {
+		snprint(s, sizeof(s), "enter %S", curfn->nname->sym);
+		dumplist(s, curfn->enter);
+	}
+}
+
+
+void
+walkstmtlist(NodeList *l)
+{
+	for(; l; l=l->next)
+		walkstmt(&l->n);
+}
+
+static int
+samelist(NodeList *a, NodeList *b)
+{
+	for(; a && b; a=a->next, b=b->next)
+		if(a->n != b->n)
+			return 0;
+	return a == b;
+}
+
+static int
+paramoutheap(Node *fn)
+{
+	NodeList *l;
+
+	for(l=fn->dcl; l; l=l->next) {
+		switch(l->n->class) {
+		case PPARAMOUT:
+		case PPARAMOUT|PHEAP:
+			return l->n->addrtaken;
+		case PAUTO:
+		case PAUTO|PHEAP:
+			// stop early - parameters are over
+			return 0;
+		}
+	}
+	return 0;
+}
+
+void
+walkstmt(Node **np)
+{
+	NodeList *init;
+	NodeList *ll, *rl;
+	int cl;
+	Node *n, *f;
+
+	n = *np;
+	if(n == N)
+		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("%S is not a top level statement", n->sym);
+		else
+			yyerror("%O is not a top level statement", n->op);
+		dump("nottop", n);
+		break;
+
+	case OAS:
+	case OASOP:
+	case OAS2:
+	case OAS2DOTTYPE:
+	case OAS2RECV:
+	case OAS2FUNC:
+	case OAS2MAPR:
+	case OCLOSE:
+	case OCOPY:
+	case OCALLMETH:
+	case OCALLINTER:
+	case OCALL:
+	case OCALLFUNC:
+	case ODELETE:
+	case OSEND:
+	case OPRINT:
+	case OPRINTN:
+	case OPANIC:
+	case OEMPTY:
+	case ORECOVER:
+		if(n->typecheck == 0)
+			fatal("missing typecheck: %+N", n);
+		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.
+		break;
+
+	case ORECV:
+		// special case for a receive where we throw away
+		// the value received.
+		if(n->typecheck == 0)
+			fatal("missing typecheck: %+N", n);
+		init = n->ninit;
+		n->ninit = nil;
+
+		walkexpr(&n->left, &init);
+		n = mkcall1(chanfn("chanrecv1", 2, n->left->type), T, &init, typename(n->left->type), n->left, nodnil());
+		walkexpr(&n, &init);
+
+		addinit(&n, init);
+		break;
+
+	case OBREAK:
+	case ODCL:
+	case OCONTINUE:
+	case OFALL:
+	case OGOTO:
+	case OLABEL:
+	case ODCLCONST:
+	case ODCLTYPE:
+	case OCHECKNIL:
+	case OVARKILL:
+		break;
+
+	case OBLOCK:
+		walkstmtlist(n->list);
+		break;
+
+	case OXCASE:
+		yyerror("case statement out of place");
+		n->op = OCASE;
+	case OCASE:
+		walkstmt(&n->right);
+		break;
+
+	case ODEFER:
+		hasdefer = 1;
+		switch(n->left->op) {
+		case OPRINT:
+		case OPRINTN:
+			walkprintfunc(&n->left, &n->ninit);
+			break;
+		case OCOPY:
+			n->left = copyany(n->left, &n->ninit, 1);
+			break;
+		default:
+			walkexpr(&n->left, &n->ninit);
+			break;
+		}
+		break;
+
+	case OFOR:
+		if(n->ntest != N) {
+			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);
+		break;
+
+	case OIF:
+		walkexpr(&n->ntest, &n->ninit);
+		walkstmtlist(n->nbody);
+		walkstmtlist(n->nelse);
+		break;
+
+	case OPROC:
+		switch(n->left->op) {
+		case OPRINT:
+		case OPRINTN:
+			walkprintfunc(&n->left, &n->ninit);
+			break;
+		case OCOPY:
+			n->left = copyany(n->left, &n->ninit, 1);
+			break;
+		default:
+			walkexpr(&n->left, &n->ninit);
+			break;
+		}
+		break;
+
+	case ORETURN:
+		walkexprlist(n->list, &n->ninit);
+		if(n->list == nil)
+			break;
+		if((curfn->type->outnamed && count(n->list) > 1) || paramoutheap(curfn)) {
+			// assign to the function out parameters,
+			// so that reorder3 can fix up conflicts
+			rl = nil;
+			for(ll=curfn->dcl; ll != nil; ll=ll->next) {
+				cl = ll->n->class & ~PHEAP;
+				if(cl == PAUTO)
+					break;
+				if(cl == PPARAMOUT)
+					rl = list(rl, ll->n);
+			}
+			if(samelist(rl, n->list)) {
+				// special return in disguise
+				n->list = nil;
+				break;
+			}
+			if(count(n->list) == 1 && count(rl) > 1) {
+				// OAS2FUNC in disguise
+				f = n->list->n;
+				if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER)
+					fatal("expected return of call, have %N", f);
+				n->list = concat(list1(f), ascompatet(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(n->op, rl, n->list, &n->ninit);
+			n->list = reorder3(ll);
+			break;
+		}
+		ll = ascompatte(n->op, nil, 0, getoutarg(curfn->type), n->list, 1, &n->ninit);
+		n->list = ll;
+		break;
+
+	case ORETJMP:
+		break;
+
+	case OSELECT:
+		walkselect(n);
+		break;
+
+	case OSWITCH:
+		walkswitch(n);
+		break;
+
+	case ORANGE:
+		walkrange(n);
+		break;
+
+	case OXFALL:
+		yyerror("fallthrough statement out of place");
+		n->op = OFALL;
+		break;
+	}
+
+	if(n->op == ONAME)
+		fatal("walkstmt ended up with name: %+N", n);
+	
+	*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
+ */
+
+void
+walkexprlist(NodeList *l, NodeList **init)
+{
+	for(; l; l=l->next)
+		walkexpr(&l->n, init);
+}
+
+void
+walkexprlistsafe(NodeList *l, NodeList **init)
+{
+	for(; l; l=l->next) {
+		l->n = safeexpr(l->n, init);
+		walkexpr(&l->n, init);
+	}
+}
+
+void
+walkexpr(Node **np, NodeList **init)
+{
+	Node *r, *l, *var, *a;
+	Node *map, *key;
+	NodeList *ll, *lr;
+	Type *t;
+	int et, old_safemode;
+	int64 v;
+	int32 lno;
+	Node *n, *fn, *n1, *n2;
+	Sym *sym;
+	char buf[100], *p;
+
+	n = *np;
+
+	if(n == N)
+		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: %+N\n", n);
+
+	switch(n->op) {
+	default:
+		dump("walk", n);
+		fatal("walkexpr: switch 1 unknown op %+hN", n);
+		break;
+
+	case OTYPE:
+	case ONONAME:
+	case OINDREG:
+	case OEMPTY:
+		goto ret;
+
+	case ONOT:
+	case OMINUS:
+	case OPLUS:
+	case OCOM:
+	case OREAL:
+	case OIMAG:
+	case ODOTMETH:
+	case 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:
+	case OITAB:
+		walkexpr(&n->left, init);
+		goto ret;
+
+	case OLEN:
+	case OCAP:
+		walkexpr(&n->left, init);
+
+		// replace len(*[10]int) with 10.
+		// delayed until now to preserve side effects.
+		t = n->left->type;
+		if(isptr[t->etype])
+			t = t->type;
+		if(isfixedarray(t)) {
+			safeexpr(n->left, init);
+			nodconst(n, n->type, t->bound);
+			n->typecheck = 1;
+		}
+		goto ret;
+
+	case OLSH:
+	case ORSH:
+		walkexpr(&n->left, init);
+		walkexpr(&n->right, init);
+		t = n->left->type;
+		n->bounded = bounded(n->right, 8*t->width);
+		if(debug['m'] && n->etype && !isconst(n->right, CTINT))
+			warn("shift bounds check elided");
+		goto ret;
+
+	case OAND:
+	case OSUB:
+	case OHMUL:
+	case OLT:
+	case OLE:
+	case OGE:
+	case OGT:
+	case OADD:
+	case OCOMPLEX:
+	case OLROT:
+		// Use results from call expression as arguments for complex.
+		if(n->op == OCOMPLEX && n->left == N && n->right == N) {
+			n->left = n->list->n;
+			n->right = n->list->next->n;
+		}
+		walkexpr(&n->left, init);
+		walkexpr(&n->right, init);
+		goto ret;
+
+	case OOR:
+	case OXOR:
+		walkexpr(&n->left, init);
+		walkexpr(&n->right, init);
+		walkrotate(&n);
+		goto ret;
+
+	case OEQ:
+	case 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:
+	case 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:
+	case OPRINTN:
+		walkexprlist(n->list, init);
+		n = walkprint(n, init);
+		goto ret;
+
+	case OPANIC:
+		n = mkcall("gopanic", T, init, n->left);
+		goto ret;
+
+	case ORECOVER:
+		n = mkcall("gorecover", n->type, init, nod(OADDR, nodfp, N));
+		goto ret;
+
+	case OLITERAL:
+		n->addable = 1;
+		goto ret;
+
+	case OCLOSUREVAR:
+	case OCFUNC:
+		n->addable = 1;
+		goto ret;
+
+	case ONAME:
+		if(!(n->class & PHEAP) && n->class != PPARAMREF)
+			n->addable = 1;
+		goto ret;
+
+	case OCALLINTER:
+		t = n->left->type;
+		if(n->list && n->list->n->op == OAS)
+			goto ret;
+		walkexpr(&n->left, init);
+		walkexprlist(n->list, init);
+		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
+		n->list = reorder1(ll);
+		goto ret;
+
+	case OCALLFUNC:
+		t = n->left->type;
+		if(n->list && n->list->n->op == OAS)
+			goto ret;
+
+		walkexpr(&n->left, init);
+		walkexprlist(n->list, init);
+
+		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
+		n->list = reorder1(ll);
+		goto ret;
+
+	case OCALLMETH:
+		t = n->left->type;
+		if(n->list && n->list->n->op == OAS)
+			goto ret;
+		walkexpr(&n->left, init);
+		walkexprlist(n->list, init);
+		ll = ascompatte(n->op, n, 0, getthis(t), list1(n->left->left), 0, init);
+		lr = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
+		ll = concat(ll, lr);
+		n->left->left = N;
+		ullmancalc(n->left);
+		n->list = reorder1(ll);
+		goto ret;
+
+	case OAS:
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+
+		walkexpr(&n->left, init);
+		n->left = safeexpr(n->left, init);
+
+		if(oaslit(n, init))
+			goto ret;
+
+		if(n->right == N || iszero(n->right) && !flag_race)
+			goto ret;
+
+		switch(n->right->op) {
+		default:
+			walkexpr(&n->right, init);
+			break;
+		
+		case ORECV:
+			// x = <-c; n->left is x, n->right->left is c.
+			// orderstmt made sure x is addressable.
+			walkexpr(&n->right->left, init);
+			n1 = nod(OADDR, n->left, N);
+			r = n->right->left; // the channel
+			n = mkcall1(chanfn("chanrecv1", 2, r->type), T, init, typename(r->type), r, n1);
+			walkexpr(&n, init);
+			goto ret;
+		}
+
+		if(n->left != N && n->right != N) {
+			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;
+
+	case OAS2FUNC:
+		// a,b,... = fn()
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+		r = n->rlist->n;
+		walkexprlistsafe(n->list, init);
+		walkexpr(&r, init);
+
+		ll = ascompatet(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;
+
+	case OAS2RECV:
+		// x, y = <-c
+		// orderstmt made sure x is addressable.
+		*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, N);
+		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;
+
+	case OAS2MAPR:
+		// a,b = m[i];
+		*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 = nil;
+		if(t->type->width <= 128) { // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
+			switch(simsimtype(t->down)) {
+			case TINT32:
+			case TUINT32:
+				p = "mapaccess2_fast32";
+				break;
+			case TINT64:
+			case TUINT64:
+				p = "mapaccess2_fast64";
+				break;
+			case TSTRING:
+				p = "mapaccess2_faststr";
+				break;
+			}
+		}
+		if(p != nil) {
+			// 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, N);
+			p = "mapaccess2";
+		}
+
+		// from:
+		//   a,b = m[i]
+		// to:
+		//   var,b = mapaccess2*(t, m, i)
+		//   a = *var
+		a = n->list->n;
+		var = temp(ptrto(t->type));
+		var->typecheck = 1;
+		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;
+		n->list->n = var;
+		walkexpr(&n, init);
+		*init = list(*init, n);
+		n = nod(OAS, a, nod(OIND, var, N));
+		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, N);
+		t = map->type;
+		n = mkcall1(mapfndel("mapdelete", t), T, init, typename(t), map, key);
+		goto ret;
+
+	case OAS2DOTTYPE:
+		// a,b = i.(T)
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+		r = n->rlist->n;
+		walkexprlistsafe(n->list, init);
+		if(isblank(n->list->n) && !isinter(r->type)) {
+			strcpy(buf, "assert");
+			p = buf+strlen(buf);
+			if(isnilinter(r->left->type))
+				*p++ = 'E';
+			else
+				*p++ = 'I';
+			*p++ = '2';
+			*p++ = 'T';
+			*p++ = 'O';
+			*p++ = 'K';
+			*p = '\0';
+			
+			fn = syslook(buf, 1);
+
+			// runtime.assert(E|I)2TOK 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))
+				fn->type->type->down->type->type = n->list->next->n->type;
+			ll = list1(typename(r->type));
+			ll = list(ll, r->left);
+			argtype(fn, r->left->type);
+			n1 = nod(OCALL, fn, N);
+			n1->list = ll;
+			n = nod(OAS, n->list->next->n, n1);
+			typecheck(&n, Etop);
+			walkexpr(&n, init);
+			goto ret;
+		}
+
+		r->op = ODOTTYPE2;
+		walkexpr(&r, init);
+		ll = ascompatet(n->op, n->list, &r->type, 0, init);
+		n = liststmt(concat(list1(r), ll));
+		goto ret;
+
+	case ODOTTYPE:
+	case ODOTTYPE2:
+		// Build name of function: assertI2E2 etc.
+		strcpy(buf, "assert");
+		p = buf+strlen(buf);
+		if(isnilinter(n->left->type))
+			*p++ = 'E';
+		else
+			*p++ = 'I';
+		*p++ = '2';
+		if(isnilinter(n->type))
+			*p++ = 'E';
+		else if(isinter(n->type))
+			*p++ = 'I';
+		else
+			*p++ = 'T';
+		if(n->op == ODOTTYPE2)
+			*p++ = '2';
+		*p = '\0';
+
+		fn = syslook(buf, 1);
+		ll = list1(typename(n->type));
+		ll = list(ll, n->left);
+		argtype(fn, n->left->type);
+		argtype(fn, n->type);
+		n = nod(OCALL, fn, N);
+		n->list = ll;
+		typecheck(&n, Erv | Efnstruct);
+		walkexpr(&n, init);
+		goto ret;
+
+	case OCONVIFACE:
+		walkexpr(&n->left, init);
+
+		// Optimize convT2E as a two-word copy when T is uintptr-shaped.
+		if(isnilinter(n->type) && isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
+			l = nod(OEFACE, typename(n->left->type), n->left);
+			l->type = n->type;
+			l->typecheck = n->typecheck;
+			n = l;
+			goto ret;
+		}
+
+		// Build name of function: convI2E etc.
+		// Not all names are possible
+		// (e.g., we'll never generate convE2E or convE2I).
+		strcpy(buf, "conv");
+		p = buf+strlen(buf);
+		if(isnilinter(n->left->type))
+			*p++ = 'E';
+		else if(isinter(n->left->type))
+			*p++ = 'I';
+		else
+			*p++ = 'T';
+		*p++ = '2';
+		if(isnilinter(n->type))
+			*p++ = 'E';
+		else
+			*p++ = 'I';
+		*p = '\0';
+
+		fn = syslook(buf, 1);
+		ll = nil;
+		if(!isinter(n->left->type))
+			ll = list(ll, typename(n->left->type));
+		if(!isnilinter(n->type))
+			ll = list(ll, typename(n->type));
+		if(!isinter(n->left->type) && !isnilinter(n->type)){
+			sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg);
+			if(sym->def == N) {
+				l = nod(ONAME, N, N);
+				l->sym = sym;
+				l->type = ptrto(types[TUINT8]);
+				l->addable = 1;
+				l->class = PEXTERN;
+				l->xoffset = 0;
+				sym->def = l;
+				ggloblsym(sym, widthptr, DUPOK|NOPTR);
+			}
+			l = nod(OADDR, sym->def, N);
+			l->addable = 1;
+			ll = list(ll, l);
+
+			if(isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
+				/* For pointer types, we can make a special form of optimization
+				 *
+				 * These statements are put onto the expression init list:
+				 * 	Itab *tab = atomicloadtype(&cache);
+				 * 	if(tab == nil)
+				 * 		tab = typ2Itab(type, itype, &cache);
+				 *
+				 * The CONVIFACE expression is replaced with this:
+				 * 	OEFACE{tab, ptr};
+				 */
+				l = temp(ptrto(types[TUINT8]));
+
+				n1 = nod(OAS, l, sym->def);
+				typecheck(&n1, Etop);
+				*init = list(*init, n1);
+
+				fn = syslook("typ2Itab", 1);
+				n1 = nod(OCALL, fn, N);
+				n1->list = ll;
+				typecheck(&n1, Erv);
+				walkexpr(&n1, init);
+
+				n2 = nod(OIF, N, N);
+				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)) {
+			ll = list(ll, n->left);
+		} else {
+			// regular types are passed by reference to avoid C vararg calls
+			// orderexpr arranged for n->left to be a temporary for all
+			// the conversions it could see. comparison of an interface
+			// with a non-interface, especially in a switch on interface value
+			// with non-interface cases, is not visible to orderstmt, so we
+			// have to fall back on allocating a temp here.
+			if(islvalue(n->left))
+				ll = list(ll, nod(OADDR, n->left, N));
+			else
+				ll = list(ll, nod(OADDR, copyexpr(n->left, n->left->type, init), N));
+		}
+		argtype(fn, n->left->type);
+		argtype(fn, n->type);
+		dowidth(fn->type);
+		n = nod(OCALL, fn, N);
+		n->list = ll;
+		typecheck(&n, Erv);
+		walkexpr(&n, init);
+		goto ret;
+
+	case OCONV:
+	case OCONVNOP:
+		if(thechar == '5') {
+			if(isfloat[n->left->type->etype]) {
+				if(n->type->etype == TINT64) {
+					n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
+					goto ret;
+				}
+				if(n->type->etype == TUINT64) {
+					n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
+					goto ret;
+				}
+			}
+			if(isfloat[n->type->etype]) {
+				if(n->left->type->etype == TINT64) {
+					n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
+					goto ret;
+				}
+				if(n->left->type->etype == TUINT64) {
+					n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
+					goto ret;
+				}
+			}
+		}
+		walkexpr(&n->left, init);
+		goto ret;
+
+	case OANDNOT:
+		walkexpr(&n->left, init);
+		n->op = OAND;
+		n->right = nod(OCOM, n->right, N);
+		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:
+	case OMOD:
+		walkexpr(&n->left, init);
+		walkexpr(&n->right, init);
+		/*
+		 * rewrite complex div into function call.
+		 */
+		et = n->left->type->etype;
+		if(iscomplex[et] && n->op == ODIV) {
+			t = n->type;
+			n = mkcall("complex128div", types[TCOMPLEX128], init,
+				conv(n->left, types[TCOMPLEX128]),
+				conv(n->right, types[TCOMPLEX128]));
+			n = conv(n, t);
+			goto ret;
+		}
+		// Nothing to do for float divisions.
+		if(isfloat[et])
+			goto ret;
+
+		// Try rewriting as shifts or magic multiplies.
+		walkdiv(&n, init);
+
+		/*
+		 * rewrite 64-bit div and mod into function calls
+		 * on 32-bit architectures.
+		 */
+		switch(n->op) {
+		case OMOD:
+		case ODIV:
+			if(widthreg >= 8 || (et != TUINT64 && et != TINT64))
+				goto ret;
+			if(et == TINT64)
+				strcpy(namebuf, "int64");
+			else
+				strcpy(namebuf, "uint64");
+			if(n->op == ODIV)
+				strcat(namebuf, "div");
+			else
+				strcat(namebuf, "mod");
+			n = mkcall(namebuf, n->type, init,
+				conv(n->left, types[et]), conv(n->right, types[et]));
+			break;
+		default:
+			break;
+		}
+		goto ret;
+
+	case OINDEX:
+		walkexpr(&n->left, init);
+		// save the original node for bounds checking elision.
+		// If it was a ODIV/OMOD walk might rewrite it.
+		r = n->right;
+		walkexpr(&n->right, init);
+
+		// if range of type cannot exceed static array bound,
+		// disable bounds check.
+		if(n->bounded)
+			goto ret;
+		t = n->left->type;
+		if(t != T && isptr[t->etype])
+			t = t->type;
+		if(isfixedarray(t)) {
+			n->bounded = bounded(r, t->bound);
+			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
+				warn("index bounds check elided");
+			if(smallintconst(n->right) && !n->bounded)
+				yyerror("index out of bounds");
+		} else if(isconst(n->left, CTSTR)) {
+			n->bounded = bounded(r, n->left->val.u.sval->len);
+			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
+				warn("index bounds check elided");
+			if(smallintconst(n->right)) {
+				if(!n->bounded)
+					yyerror("index out of bounds");
+				else {
+					// replace "abc"[1] with 'b'.
+					// delayed until now because "abc"[1] is not
+					// an ideal constant.
+					v = mpgetfix(n->right->val.u.xval);
+					nodconst(n, n->type, n->left->val.u.sval->s[v]);
+					n->typecheck = 1;
+				}
+			}
+		}
+
+		if(isconst(n->right, CTINT))
+		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 = nil;
+		if(t->type->width <= 128) {  // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
+			switch(simsimtype(t->down)) {
+			case TINT32:
+			case TUINT32:
+				p = "mapaccess1_fast32";
+				break;
+			case TINT64:
+			case TUINT64:
+				p = "mapaccess1_fast64";
+				break;
+			case TSTRING:
+				p = "mapaccess1_faststr";
+				break;
+			}
+		}
+		if(p != nil) {
+			// 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, N);
+			p = "mapaccess1";
+		}
+		n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, key);
+		n = nod(OIND, n, N);
+		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
+
+	case OSLICE:
+		if(n->right != N && n->right->left == N && n->right->right == N) { // noop
+			walkexpr(&n->left, init);
+			n = n->left;
+			goto ret;
+		}
+		// fallthrough
+	case OSLICEARR:
+	case OSLICESTR:
+		if(n->right == N) // 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:
+	case OSLICE3ARR:
+		if(n->right == N) // 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, N);  // zero temp
+			typecheck(&r, Etop);
+			*init = list(*init, r);
+			r = nod(OADDR, r->left, N);
+			typecheck(&r, Erv);
+			n = r;
+		} else {
+			n = callnew(n->type->type);
+		}
+		goto ret;
+
+	case OCMPSTR:
+		// If one argument to the comparison is an empty string,
+		// comparing the lengths instead will yield the same result
+		// without the function call.
+		if((isconst(n->left, CTSTR) && n->left->val.u.sval->len == 0) ||
+		   (isconst(n->right, CTSTR) && n->right->val.u.sval->len == 0)) {
+			r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N));
+			typecheck(&r, Erv);
+			walkexpr(&r, init);
+			r->type = n->type;
+			n = r;
+			goto ret;
+		}
+
+		// s + "badgerbadgerbadger" == "badgerbadgerbadger"
+		if((n->etype == OEQ || n->etype == ONE) &&
+		   isconst(n->right, CTSTR) &&
+		   n->left->op == OADDSTR && count(n->left->list) == 2 &&
+		   isconst(n->left->list->next->n, CTSTR) &&
+		   cmpslit(n->right, n->left->list->next->n) == 0) {
+			r = nod(n->etype, nod(OLEN, n->left->list->n, N), 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 !=
+			if(n->etype == OEQ) {
+				// len(left) == len(right) && eqstring(left, right)
+				r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
+			} else {
+				// len(left) != len(right) || !eqstring(left, right)
+				r = nod(ONOT, r, N);
+				r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), 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(n->etype, r, nodintconst(0));
+		}
+
+		typecheck(&r, Erv);
+		if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
+		r->type = n->type;
+		n = r;
+		goto ret;
+
+	case OADDSTR:
+		n = addstr(n, init);
+		goto ret;
+	
+	case OAPPEND:
+		if(n->isddd)
+			n = appendslice(n, init); // also works for append(slice, string).
+		else
+			n = append(n, init);
+		goto ret;
+
+	case OCOPY:
+		n = copyany(n, init, flag_race);
+		goto ret;
+
+	case OCLOSE:
+		// cannot use chanfn - closechan takes any, not chan any
+		fn = syslook("closechan", 1);
+		argtype(fn, n->left->type);
+		n = mkcall1(fn, T, 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);
+		argtype(fn, t->down);	// any-1
+		argtype(fn, t->type);	// any-2
+
+		n = mkcall1(fn, n->type, init,
+			typename(n->type),
+			conv(n->left, types[TINT64]));
+		goto ret;
+
+	case OMAKESLICE:
+		l = n->left;
+		r = n->right;
+		if(r == nil)
+			l = r = safeexpr(l, init);
+		t = n->type;
+		if(n->esc == EscNone
+			&& smallintconst(l) && smallintconst(r)
+			&& (t->type->width == 0 || mpgetfix(r->val.u.xval) < (1ULL<<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, N); // zero temp
+			typecheck(&a, Etop);
+			*init = list(*init, a);
+			r = nod(OSLICE, var, nod(OKEY, N, 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:
+		// sys_intstring(v)
+		n = mkcall("intstring", n->type, init,
+			conv(n->left, types[TINT64]));
+		goto ret;
+
+	case OARRAYBYTESTR:
+		// slicebytetostring([]byte) string;
+		n = mkcall("slicebytetostring", n->type, init, n->left);
+		goto ret;
+
+	case OARRAYBYTESTRTMP:
+		// slicebytetostringtmp([]byte) string;
+		n = mkcall("slicebytetostringtmp", n->type, init, n->left);
+		goto ret;
+
+	case OARRAYRUNESTR:
+		// slicerunetostring([]rune) string;
+		n = mkcall("slicerunetostring", n->type, init, n->left);
+		goto ret;
+
+	case OSTRARRAYBYTE:
+		// stringtoslicebyte(string) []byte;
+		n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING]));
+		goto ret;
+
+	case OSTRARRAYRUNE:
+		// stringtoslicerune(string) []rune
+		n = mkcall("stringtoslicerune", n->type, init, n->left);
+		goto ret;
+
+	case OCMPIFACE:
+		// ifaceeq(i1 any-1, i2 any-2) (ret bool);
+		if(!eqtype(n->left->type, n->right->type))
+			fatal("ifaceeq %O %T %T", n->op, n->left->type, n->right->type);
+		if(isnilinter(n->left->type))
+			fn = syslook("efaceeq", 1);
+		else
+			fn = syslook("ifaceeq", 1);
+
+		n->right = cheapexpr(n->right, init);
+		n->left = cheapexpr(n->left, init);
+		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, N);
+		
+		// check itable/type before full compare.
+		if(n->etype == OEQ)
+			r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
+		else
+			r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
+		typecheck(&r, Erv);
+		walkexpr(&r, init);
+		r->type = n->type;
+		n = r;
+		goto ret;
+
+	case OARRAYLIT:
+	case OMAPLIT:
+	case OSTRUCTLIT:
+	case 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, N);
+		n = mkcall1(chanfn("chansend1", 2, n->left->type), T, 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 %O", n->op);
+
+ret:
+	// 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.
+	t = n->type;
+	evconst(n);
+	n->type = t;
+	if(n->op == OLITERAL)
+		typecheck(&n, Erv);
+
+	ullmancalc(n);
+
+	if(debug['w'] && n != N)
+		dump("walk", n);
+
+	lineno = lno;
+	*np = n;
+}
+
+static Node*
+ascompatee1(int op, Node *l, Node *r, NodeList **init)
+{
+	Node *n;
+	USED(op);
+	
+	// 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);
+}
+
+static NodeList*
+ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
+{
+	NodeList *ll, *lr, *nn;
+
+	/*
+	 * 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; ll=ll->next)
+		ll->n = safeexpr(ll->n, init);
+	for(lr=nr; lr; lr=lr->next)
+		lr->n = safeexpr(lr->n, init);
+
+	nn = nil;
+	for(ll=nl, lr=nr; ll && lr; 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 || lr)
+		yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, 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
+ */
+static int
+fncall(Node *l, Type *rt)
+{
+	Node r;
+
+	if(l->ullman >= UINF || l->op == OINDEXMAP)
+		return 1;
+	memset(&r, 0, sizeof r);
+	if(needwritebarrier(l, &r))
+		return 1;
+	if(eqtype(l->type, rt))
+		return 0;
+	return 1;
+}
+
+static NodeList*
+ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
+{
+	Node *l, *tmp, *a;
+	NodeList *ll;
+	Type *r;
+	Iter saver;
+	int ucount;
+	NodeList *nn, *mm;
+
+	USED(op);
+
+	/*
+	 * 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; ll=ll->next) {
+		if(r == T)
+			break;
+		l = ll->n;
+		if(isblank(l)) {
+			r = structnext(&saver);
+			continue;
+		}
+
+		// any lv that causes a fn call must be
+		// deferred until all the return arguments
+		// have been pulled from the output arguments
+		if(fncall(l, r->type)) {
+			tmp = temp(r->type);
+			typecheck(&tmp, Erv);
+			a = nod(OAS, l, tmp);
+			a = convas(a, init);
+			mm = list(mm, a);
+			l = tmp;
+		}
+
+		a = nod(OAS, l, nodarg(r, fp));
+		a = convas(a, init);
+		ullmancalc(a);
+		if(a->ullman >= UINF) {
+			dump("ascompatet ucount", a);
+			ucount++;
+		}
+		nn = list(nn, a);
+		r = structnext(&saver);
+	}
+
+	if(ll != nil || r != T)
+		yyerror("ascompatet: assignment count mismatch: %d = %d",
+			count(nl), structcount(*nr));
+
+	if(ucount)
+		fatal("ascompatet: too many function calls evaluating parameters");
+	return concat(nn, mm);
+}
+
+ /*
+ * package all the arguments that match a ... T parameter into a []T.
+ */
+static NodeList*
+mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Node *ddd)
+{
+	Node *a, *n;
+	Type *tslice;
+	int esc;
+	
+	esc = EscUnknown;
+	if(ddd != nil)
+		esc = 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, N, typenod(tslice));
+		if(ddd != nil)
+			n->alloc = ddd->alloc; // temporary to use
+		n->list = lr0;
+		n->esc = esc;
+		typecheck(&n, Erv);
+		if(n->type == T)
+			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
+ */
+static char*
+dumptypes(Type **nl, char *what)
+{
+	int first;
+	Type *l;
+	Iter savel;
+	Fmt fmt;
+
+	fmtstrinit(&fmt);
+	fmtprint(&fmt, "\t");
+	first = 1;
+	for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) {
+		if(first)
+			first = 0;
+		else
+			fmtprint(&fmt, ", ");
+		fmtprint(&fmt, "%T", l);
+	}
+	if(first)
+		fmtprint(&fmt, "[no arguments %s]", what);
+	return fmtstrflush(&fmt);
+}
+
+static char*
+dumpnodetypes(NodeList *l, char *what)
+{
+	int first;
+	Node *r;
+	Fmt fmt;
+
+	fmtstrinit(&fmt);
+	fmtprint(&fmt, "\t");
+	first = 1;
+	for(; l; l=l->next) {
+		r = l->n;
+		if(first)
+			first = 0;
+		else
+			fmtprint(&fmt, ", ");
+		fmtprint(&fmt, "%T", r->type);
+	}
+	if(first)
+		fmtprint(&fmt, "[no arguments %s]", what);
+	return fmtstrflush(&fmt);
+}
+
+/*
+ * check assign expression list to
+ * a type list. called in
+ *	return expr-list
+ *	func(expr-list)
+ */
+static NodeList*
+ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init)
+{
+	Type *l, *ll;
+	Node *r, *a;
+	NodeList *nn, *lr0, *alist;
+	Iter savel;
+	char *l1, *l2;
+
+	lr0 = lr;
+	l = structfirst(&savel, nl);
+	r = N;
+	if(lr)
+		r = lr->n;
+	nn = nil;
+
+	// f(g()) where g has multiple return values
+	if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) {
+		// optimization - can do block copy
+		if(eqtypenoname(r->type, *nl)) {
+			a = nodarg(*nl, fp);
+			r = nod(OCONVNOP, r, N);
+			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; l=structnext(&savel)) {
+			a = temp(l->type);
+			alist = list(alist, a);
+		}
+		a = nod(OAS2, N, N);
+		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 != T && l->isddd) {
+		// the ddd parameter must be last
+		ll = structnext(&savel);
+		if(ll != T)
+			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 != N && lr->next == nil && isddd && eqtype(l->type, r->type)) {
+			a = nod(OAS, nodarg(l, fp), r);
+			a = convas(a, init);
+			nn = list(nn, a);
+			goto ret;
+		}
+
+		// normal case -- make a slice of all
+		// remaining arguments and pass it to
+		// the ddd parameter.
+		nn = mkdotargslice(lr, nn, l, fp, init, call->right);
+		goto ret;
+	}
+
+	if(l == T || r == N) {
+		if(l != T || r != N) {
+			l1 = dumptypes(nl, "expected");
+			l2 = dumpnodetypes(lr0, "given");
+			if(l != T)
+				yyerror("not enough arguments to %O\n%s\n%s", op, l1, l2);
+			else
+				yyerror("too many arguments to %O\n%s\n%s", op, l1, l2);
+		}
+		goto ret;
+	}
+
+	a = nod(OAS, nodarg(l, fp), r);
+	a = convas(a, init);
+	nn = list(nn, a);
+
+	l = structnext(&savel);
+	r = N;
+	lr = lr->next;
+	if(lr != nil)
+		r = lr->n;
+	goto loop;
+
+ret:
+	for(lr=nn; lr; lr=lr->next)
+		lr->n->typecheck = 1;
+	return nn;
+}
+
+// generate code for print
+static Node*
+walkprint(Node *nn, NodeList **init)
+{
+	Node *r;
+	Node *n;
+	NodeList *l, *all;
+	Node *on;
+	Type *t;
+	int notfirst, et, op;
+	NodeList *calls;
+
+	on = nil;
+	op = nn->op;
+	all = nn->list;
+	calls = nil;
+	notfirst = 0;
+
+	for(l=all; l; l=l->next) {
+		if(notfirst) {
+			calls = list(calls, mkcall("printsp", T, init));
+		}
+		notfirst = op == OPRINTN;
+
+		n = l->n;
+		if(n->op == OLITERAL) {
+			switch(n->val.ctype) {
+			case CTRUNE:
+				defaultlit(&n, runetype);
+				break;
+			case CTINT:
+				defaultlit(&n, types[TINT64]);
+				break;
+			case CTFLT:
+				defaultlit(&n, types[TFLOAT64]);
+				break;
+			}
+		}
+		if(n->op != OLITERAL && n->type && n->type->etype == TIDEAL)
+			defaultlit(&n, types[TINT64]);
+		defaultlit(&n, nil);
+		l->n = n;
+		if(n->type == T || n->type->etype == TFORW)
+			continue;
+
+		t = n->type;
+		et = n->type->etype;
+		if(isinter(n->type)) {
+			if(isnilinter(n->type))
+				on = syslook("printeface", 1);
+			else
+				on = syslook("printiface", 1);
+			argtype(on, n->type);		// any-1
+		} else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
+			on = syslook("printpointer", 1);
+			argtype(on, n->type);	// any-1
+		} else if(isslice(n->type)) {
+			on = syslook("printslice", 1);
+			argtype(on, n->type);	// any-1
+		} else if(isint[et]) {
+			if(et == TUINT64) {
+				if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0)
+					on = syslook("printhex", 0);
+				else
+					on = syslook("printuint", 0);
+			} else
+				on = syslook("printint", 0);
+		} else if(isfloat[et]) {
+			on = syslook("printfloat", 0);
+		} else if(iscomplex[et]) {
+			on = syslook("printcomplex", 0);
+		} else if(et == TBOOL) {
+			on = syslook("printbool", 0);
+		} else if(et == TSTRING) {
+			on = syslook("printstring", 0);
+		} else {
+			badtype(OPRINT, n->type, T);
+			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, N);
+			n->type = t;
+		}
+
+		r = nod(OCALL, on, N);
+		r->list = list1(n);
+		calls = list(calls, r);
+	}
+
+	if(op == OPRINTN)
+		calls = list(calls, mkcall("printnl", T, nil));
+	typechecklist(calls, Etop);
+	walkexprlist(calls, init);
+
+	r = nod(OEMPTY, N, N);
+	typecheck(&r, Etop);
+	walkexpr(&r, init);
+	r->ninit = calls;
+	return r;
+}
+
+Node*
+callnew(Type *t)
+{
+	Node *fn;
+
+	dowidth(t);
+	fn = syslook("newobject", 1);
+	argtype(fn, t);
+	return mkcall1(fn, ptrto(t), nil, typename(t));
+}
+
+static int
+isstack(Node *n)
+{
+	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
+		n = n->left;
+	
+	switch(n->op) {
+	case OINDREG:
+		// OINDREG only ends up in walk if it's indirect of SP.
+		return 1;
+
+	case ONAME:
+		switch(n->class) {
+		case PAUTO:
+		case PPARAM:
+		case PPARAMOUT:
+			return 1;
+		}
+		break;
+	}
+	
+	return 0;
+}
+
+static int
+isglobal(Node *n)
+{
+	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
+		n = n->left;
+	
+	switch(n->op) {
+	case ONAME:
+		switch(n->class) {
+		case PEXTERN:
+			return 1;
+		}
+		break;
+	}
+	
+	return 0;
+}
+
+// Do we need a write barrier for the assignment l = r?
+int
+needwritebarrier(Node *l, Node *r)
+{
+	if(!use_writebarrier)
+		return 0;
+
+	if(l == N || 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))
+		return 0;
+
+	// No write barrier for implicit or explicit zeroing.
+	if(r == N || iszero(r))
+		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 && strncmp(r->sym->name, "statictmp_", 10) == 0)
+		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))
+		return 0;
+
+	// No write barrier for storing address of global, which
+	// is live no matter what.
+	if(r->op == OADDR && isglobal(r->left))
+		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) {
+		switch(r->op) {
+		case OSLICE:
+		case OSLICE3:
+		case OSLICESTR:
+		case OAPPEND:
+			break;
+		default:
+			dump("bad reslice-l", l);
+			dump("bad reslice-r", r);
+			break;
+		}
+		return 0;
+	}
+
+	// Otherwise, be conservative and use write barrier.
+	return 1;
+}
+
+// TODO(rsc): Perhaps componentgen should run before this.
+static Node*
+applywritebarrier(Node *n, NodeList **init)
+{
+	Node *l, *r;
+	Type *t;
+
+	if(n->left && n->right && needwritebarrier(n->left, n->right)) {
+		t = n->left->type;
+		l = nod(OADDR, n->left, N);
+		l->etype = 1; // addr does not escape
+		if(t->width == widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierptr", t, n->right->type), T, init,
+				l, n->right);
+		} else if(t->etype == TSTRING) {
+			n = mkcall1(writebarrierfn("writebarrierstring", t, n->right->type), T, init,
+				l, n->right);
+		} else if(isslice(t)) {
+			n = mkcall1(writebarrierfn("writebarrierslice", t, n->right->type), T, init,
+				l, n->right);
+		} else if(isinter(t)) {
+			n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init,
+				l, n->right);
+		} else if(t->width == 2*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat2", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else if(t->width == 3*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat3", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else if(t->width == 4*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat4", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else {
+			r = n->right;
+			while(r->op == OCONVNOP)
+				r = r->left;
+			r = nod(OADDR, r, N);
+			r->etype = 1; // addr does not escape
+			//warnl(n->lineno, "writebarrierfat %T %N", t, r);
+			n = mkcall1(writebarrierfn("writebarrierfat", t, r->left->type), T, init,
+				typename(t), l, r);
+		}
+	}
+	return n;
+}
+
+static Node*
+convas(Node *n, NodeList **init)
+{
+	Type *lt, *rt;
+	Node *map, *key, *val;
+
+	if(n->op != OAS)
+		fatal("convas: not OAS %O", n->op);
+
+	n->typecheck = 1;
+
+	if(n->left == N || n->right == N)
+		goto out;
+
+	lt = n->left->type;
+	rt = n->right->type;
+	if(lt == T || rt == T)
+		goto out;
+
+	if(isblank(n->left)) {
+		defaultlit(&n->right, T);
+		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, N);
+		val = nod(OADDR, val, N);
+		n = mkcall1(mapfn("mapassign1", map->type), T, 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
+ */
+static NodeList*
+reorder1(NodeList *all)
+{
+	Node *f, *a, *n;
+	NodeList *l, *r, *g;
+	int c, d, t;
+
+	c = 0;	// function calls
+	t = 0;	// total parameters
+
+	for(l=all; l; 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 = N;	// last fncall assigned to stack
+	r = nil;	// non fncalls and tempnames assigned to stack
+	d = 0;
+	for(l=all; l; 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 != N)
+		g = list(g, f);
+	return concat(g, r);
+}
+
+static void reorder3save(Node**, NodeList*, NodeList*, NodeList**);
+static int aliased(Node*, NodeList*, NodeList*);
+
+/*
+ * from ascompat[ee]
+ *	a,b = c,d
+ * simultaneous assignment. there cannot
+ * be later use of an earlier lvalue.
+ *
+ * function calls have been removed.
+ */
+static NodeList*
+reorder3(NodeList *all)
+{
+	NodeList *list, *early, *mapinit;
+	Node *l;
+
+	// 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; list=list->next) {
+		l = list->n->left;
+
+		// Save subexpressions needed on left side.
+		// Drill through non-dereferences.
+		for(;;) {
+			if(l->op == ODOT || l->op == OPAREN) {
+				l = l->left;
+				continue;
+			}
+			if(l->op == OINDEX && isfixedarray(l->left->type)) {
+				reorder3save(&l->right, all, list, &early);
+				l = l->left;
+				continue;
+			}
+			break;
+		}
+		switch(l->op) {
+		default:
+			fatal("reorder3 unexpected lvalue %#O", l->op);
+		case ONAME:
+			break;
+		case OINDEX:
+		case OINDEXMAP:
+			reorder3save(&l->left, all, list, &early);
+			reorder3save(&l->right, all, list, &early);
+			if(l->op == OINDEXMAP)
+				list->n = convas(list->n, &mapinit);
+			break;
+		case OIND:
+		case 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);
+}
+
+static int vmatch2(Node*, Node*);
+static int varexpr(Node*);
+
+/*
+ * 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.
+ */
+static void
+reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
+{
+	Node *n, *q;
+
+	n = *np;
+	if(!aliased(n, all, stop))
+		return;
+	
+	q = temp(n->type);
+	q = nod(OAS, q, n);
+	typecheck(&q, Etop);
+	*early = list(*early, q);
+	*np = q->left;
+}
+
+/*
+ * what's the outer value that a write to n affects?
+ * outer value means containing struct or array.
+ */
+Node*
+outervalue(Node *n)
+{	
+	for(;;) {
+		if(n->op == ODOT || n->op == OPAREN) {
+			n = n->left;
+			continue;
+		}
+		if(n->op == OINDEX && isfixedarray(n->left->type)) {
+			n = n->left;
+			continue;
+		}
+		break;
+	}
+	return n;
+}
+
+/*
+ * Is it possible that the computation of n might be
+ * affected by writes in as up to but not including stop?
+ */
+static int
+aliased(Node *n, NodeList *all, NodeList *stop)
+{
+	int memwrite, varwrite;
+	Node *a;
+	NodeList *l;
+
+	if(n == N)
+		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:
+		case PPARAM:
+		case PPARAMOUT:
+			if(n->addrtaken) {
+				varwrite = 1;
+				continue;
+			}
+			if(vmatch2(a, n)) {
+				// 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 && !varwrite)
+		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))
+		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)
+ */
+static int
+varexpr(Node *n)
+{
+	if(n == N)
+		return 1;
+
+	switch(n->op) {
+	case OLITERAL:	
+		return 1;
+	case ONAME:
+		switch(n->class) {
+		case PAUTO:
+		case PPARAM:
+		case PPARAMOUT:
+			if(!n->addrtaken)
+				return 1;
+		}
+		return 0;
+
+	case OADD:
+	case OSUB:
+	case OOR:
+	case OXOR:
+	case OMUL:
+	case ODIV:
+	case OMOD:
+	case OLSH:
+	case ORSH:
+	case OAND:
+	case OANDNOT:
+	case OPLUS:
+	case OMINUS:
+	case OCOM:
+	case OPAREN:
+	case OANDAND:
+	case OOROR:
+	case ODOT:  // but not ODOTPTR
+	case OCONV:
+	case OCONVNOP:
+	case OCONVIFACE:
+	case ODOTTYPE:
+		return varexpr(n->left) && varexpr(n->right);
+	}
+
+	// Be conservative.
+	return 0;
+}
+
+/*
+ * is the name l mentioned in r?
+ */
+static int
+vmatch2(Node *l, Node *r)
+{
+	NodeList *ll;
+
+	if(r == N)
+		return 0;
+	switch(r->op) {
+	case ONAME:
+		// match each right given left
+		return l == r;
+	case OLITERAL:
+		return 0;
+	}
+	if(vmatch2(l, r->left))
+		return 1;
+	if(vmatch2(l, r->right))
+		return 1;
+	for(ll=r->list; ll; ll=ll->next)
+		if(vmatch2(l, ll->n))
+			return 1;
+	return 0;
+}
+
+/*
+ * is any name mentioned in l also mentioned in r?
+ * called by sinit.c
+ */
+int
+vmatch1(Node *l, Node *r)
+{
+	NodeList *ll;
+
+	/*
+	 * isolate all left sides
+	 */
+	if(l == N || r == N)
+		return 0;
+	switch(l->op) {
+	case ONAME:
+		switch(l->class) {
+		case PPARAM:
+		case PPARAMREF:
+		case PAUTO:
+			break;
+		default:
+			// assignment to non-stack variable
+			// must be delayed if right has function calls.
+			if(r->ullman >= UINF)
+				return 1;
+			break;
+		}
+		return vmatch2(l, r);
+	case OLITERAL:
+		return 0;
+	}
+	if(vmatch1(l->left, r))
+		return 1;
+	if(vmatch1(l->right, r))
+		return 1;
+	for(ll=l->list; ll; ll=ll->next)
+		if(vmatch1(ll->n, r))
+			return 1;
+	return 0;
+}
+
+/*
+ * walk through argin parameters.
+ * generate and return code to allocate
+ * copies of escaped parameters to the heap.
+ */
+static NodeList*
+paramstoheap(Type **argin, int out)
+{
+	Type *t;
+	Iter savet;
+	Node *v;
+	NodeList *nn;
+
+	nn = nil;
+	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
+		v = t->nname;
+		if(v && v->sym && v->sym->name[0] == '~' && v->sym->name[1] == 'r') // unnamed result
+			v = N;
+		// In precisestack mode, the garbage collector assumes results
+		// are always live, so zero them always.
+		if(out && (precisestack_enabled || (v == N && hasdefer))) {
+			// 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), N));
+		}
+		if(v == N || !(v->class & PHEAP))
+			continue;
+
+		// generate allocation & copying code
+		if(compiling_runtime)
+			yyerror("%N escapes to heap, not allowed in runtime.", v);
+		if(v->alloc == nil)
+			v->alloc = callnew(v->type);
+		nn = list(nn, nod(OAS, v->heapaddr, v->alloc));
+		if((v->class & ~PHEAP) != PPARAMOUT)
+			nn = list(nn, nod(OAS, v, v->stackparam));
+	}
+	return nn;
+}
+
+/*
+ * walk through argout parameters copying back to stack
+ */
+static NodeList*
+returnsfromheap(Type **argin)
+{
+	Type *t;
+	Iter savet;
+	Node *v;
+	NodeList *nn;
+
+	nn = nil;
+	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
+		v = t->nname;
+		if(v == N || 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.
+ */
+static void
+heapmoves(void)
+{
+	NodeList *nn;
+	int32 lno;
+
+	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;
+}
+
+static Node*
+vmkcall(Node *fn, Type *t, NodeList **init, va_list va)
+{
+	int i, n;
+	Node *r;
+	NodeList *args;
+
+	if(fn->type == T || fn->type->etype != TFUNC)
+		fatal("mkcall %N %T", fn, fn->type);
+
+	args = nil;
+	n = fn->type->intuple;
+	for(i=0; i<n; i++)
+		args = list(args, va_arg(va, Node*));
+
+	r = nod(OCALL, fn, N);
+	r->list = args;
+	if(fn->type->outtuple > 0)
+		typecheck(&r, Erv | Efnstruct);
+	else
+		typecheck(&r, Etop);
+	walkexpr(&r, init);
+	r->type = t;
+	return r;
+}
+
+Node*
+mkcall(char *name, Type *t, NodeList **init, ...)
+{
+	Node *r;
+	va_list va;
+
+	va_start(va, init);
+	r = vmkcall(syslook(name, 0), t, init, va);
+	va_end(va);
+	return r;
+}
+
+Node*
+mkcall1(Node *fn, Type *t, NodeList **init, ...)
+{
+	Node *r;
+	va_list va;
+
+	va_start(va, init);
+	r = vmkcall(fn, t, init, va);
+	va_end(va);
+	return r;
+}
+
+Node*
+conv(Node *n, Type *t)
+{
+	if(eqtype(n->type, t))
+		return n;
+	n = nod(OCONV, n, N);
+	n->type = t;
+	typecheck(&n, Erv);
+	return n;
+}
+
+Node*
+chanfn(char *name, int n, Type *t)
+{
+	Node *fn;
+	int i;
+
+	if(t->etype != TCHAN)
+		fatal("chanfn %T", t);
+	fn = syslook(name, 1);
+	for(i=0; i<n; i++)
+		argtype(fn, t->type);
+	return fn;
+}
+
+static Node*
+mapfn(char *name, Type *t)
+{
+	Node *fn;
+
+	if(t->etype != TMAP)
+		fatal("mapfn %T", t);
+	fn = syslook(name, 1);
+	argtype(fn, t->down);
+	argtype(fn, t->type);
+	argtype(fn, t->down);
+	argtype(fn, t->type);
+	return fn;
+}
+
+static Node*
+mapfndel(char *name, Type *t)
+{
+	Node *fn;
+
+	if(t->etype != TMAP)
+		fatal("mapfn %T", t);
+	fn = syslook(name, 1);
+	argtype(fn, t->down);
+	argtype(fn, t->type);
+	argtype(fn, t->down);
+	return fn;
+}
+
+static Node*
+writebarrierfn(char *name, Type *l, Type *r)
+{
+	Node *fn;
+
+	fn = syslook(name, 1);
+	argtype(fn, l);
+	argtype(fn, r);
+	return fn;
+}
+
+static Node*
+addstr(Node *n, NodeList **init)
+{
+	Node *r, *cat, *slice;
+	NodeList *args, *l;
+	int c;
+	Type *t;
+
+	// orderexpr rewrote OADDSTR to have a list of strings.
+	c = count(n->list);
+	if(c < 2)
+		yyerror("addstr count %d too small", c);
+
+	// build list of string arguments
+	args = nil;
+	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.
+		snprint(namebuf, sizeof(namebuf), "concatstring%d", c);
+	} else {
+		// large numbers of strings are passed to the runtime as a slice.
+		strcpy(namebuf, "concatstrings");
+		t = typ(TARRAY);
+		t->type = types[TSTRING];
+		t->bound = -1;
+		slice = nod(OCOMPLIT, N, typenod(t));
+		slice->alloc = n->alloc;
+		slice->list = args;
+		slice->esc = EscNone;
+		args = list1(slice);
+	}
+	cat = syslook(namebuf, 1);
+	r = nod(OCALL, cat, N);
+	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.
+static Node*
+appendslice(Node *n, NodeList **init)
+{
+	NodeList *l;
+	Node *l1, *l2, *nt, *nif, *fn;
+	Node *nptr1, *nptr2, *nwid;
+	Node *s;
+
+	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; 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, N, N);
+	// n := len(s) + len(l2) - cap(s)
+	nif->ninit = list1(nod(OAS, nt,
+		nod(OSUB, nod(OADD, nod(OLEN, s, N), nod(OLEN, l2, N)), nod(OCAP, s, N))));
+	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(flag_race) {
+		// rely on runtime to instrument copy.
+		// copy(s[len(l1):len(l1)+len(l2)], l2)
+		nptr1 = nod(OSLICE, s, nod(OKEY,
+			nod(OLEN, l1, N),
+			nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N))));
+		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, N));
+		nptr1->bounded = 1;
+		nptr1 = nod(OADDR, nptr1, N);
+
+		nptr2 = nod(OSPTR, l2, N);
+
+		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, N), types[TUINTPTR]), &l);
+		nwid = nod(OMUL, nwid, nodintconst(s->type->type->width));
+		nt = mkcall1(fn, T, &l, nptr1, nptr2, nwid);
+		l = list(l, nt);
+	}
+
+	// s = s[:len(l1)+len(l2)]
+	nt = nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N));
+	nt = nod(OSLICE, s, nod(OKEY, N, 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
+static Node*
+append(Node *n, NodeList **init)
+{
+	NodeList *l, *a;
+	Node *nsrc, *ns, *nn, *na, *nx, *fn;
+	int argc;
+
+	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; l=l->next)
+		l->n = cheapexpr(l->n, init);
+
+	nsrc = n->list->n;
+
+	// Resolve slice type of multi-valued return.
+	if(istype(nsrc->type, TSTRUCT))
+		nsrc->type = nsrc->type->type->type;
+	argc = count(n->list) - 1;
+	if (argc < 1) {
+		return nsrc;
+	}
+
+	l = nil;
+
+	ns = temp(nsrc->type);
+	l = list(l, nod(OAS, ns, nsrc));  // s = src
+
+	na = nodintconst(argc);		// const argc
+	nx = nod(OIF, N, N);		// if cap(s) - len(s) < argc
+	nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), 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, N)));	 // n = len(s)
+
+	nx = nod(OSLICE, ns, nod(OKEY, N, 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.
+//
+static Node*
+copyany(Node *n, NodeList **init, int runtimecall)
+{
+	Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
+	NodeList *l;
+
+	if(runtimecall) {
+		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, N);
+	nto = nod(OSPTR, nl, N);
+
+	nlen = temp(types[TINT]);
+	// n = len(to)
+	l = list(l, nod(OAS, nlen, nod(OLEN, nl, N)));
+	// if n > len(frm) { n = len(frm) }
+	nif = nod(OIF, N, N);
+	nif->ntest = nod(OGT, nlen, nod(OLEN, nr, N));
+	nif->nbody = list(nif->nbody,
+		nod(OAS, nlen, nod(OLEN, nr, N)));
+	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, T, init, nto, nfrm, nwid));
+
+	typechecklist(l, Etop);
+	walkstmtlist(l);
+	*init = concat(*init, l);
+	return nlen;
+}
+
+// Generate frontend part for OSLICE[3][ARR|STR]
+// 
+static	Node*
+sliceany(Node* n, NodeList **init)
+{
+	int bounded, slice3;
+	Node *src, *lb, *hb, *cb, *bound, *chk, *chk0, *chk1, *chk2;
+	int64 lbv, hbv, cbv, bv, w;
+	Type *bt;
+
+//	print("before sliceany: %+N\n", n);
+
+	src = n->left;
+	lb = n->right->left;
+	slice3 = n->op == OSLICE3 || n->op == OSLICE3ARR;
+	if(slice3) {
+		hb = n->right->right->left;
+		cb = n->right->right->right;
+	} else {
+		hb = n->right->right;
+		cb = N;
+	}
+
+	bounded = n->etype;
+	
+	if(n->op == OSLICESTR)
+		bound = nod(OLEN, src, N);
+	else
+		bound = nod(OCAP, src, N);
+
+	typecheck(&bound, Erv);
+	walkexpr(&bound, init);  // if src is an array, bound will be a const now.
+
+	// static checks if possible
+	bv = 1LL<<50;
+	if(isconst(bound, CTINT)) {
+		if(!smallintconst(bound))
+			yyerror("array len too large");
+		else
+			bv = mpgetfix(bound->val.u.xval);
+	}
+
+	if(isconst(cb, CTINT)) {
+		cbv = mpgetfix(cb->val.u.xval);
+		if(cbv < 0 || cbv > bv)
+			yyerror("slice index out of bounds");
+	}
+	if(isconst(hb, CTINT)) {
+		hbv = mpgetfix(hb->val.u.xval);
+		if(hbv < 0 || hbv > bv)
+			yyerror("slice index out of bounds");
+	}
+	if(isconst(lb, CTINT)) {
+		lbv = mpgetfix(lb->val.u.xval);
+		if(lbv < 0 || lbv > bv) {
+			yyerror("slice index out of bounds");
+			lbv = -1;
+		}
+		if(lbv == 0)
+			lb = N;
+	}
+
+	// Checking src[lb:hb:cb] or src[lb:hb].
+	// if chk0 || chk1 || chk2 { panicslice() }
+	chk = N;
+	chk0 = N; // cap(src) < cb
+	chk1 = N; // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
+	chk2 = N; // hb < lb
+
+	// All comparisons are unsigned to avoid testing < 0.
+	bt = types[simtype[TUINT]];
+	if(cb != N && cb->type->width > 4)
+		bt = types[TUINT64];
+	if(hb != N && hb->type->width > 4)
+		bt = types[TUINT64];
+	if(lb != N && lb->type->width > 4)
+		bt = types[TUINT64];
+
+	bound = cheapexpr(conv(bound, bt), init);
+
+	if(cb != N) {
+		cb = cheapexpr(conv(cb, bt), init);
+		if(!bounded)
+			chk0 = nod(OLT, bound, cb);
+	} else if(slice3) {
+		// When we figure out what this means, implement it.
+		fatal("slice3 with cb == N"); // rejected by parser
+	}
+		
+	if(hb != N) {
+		hb = cheapexpr(conv(hb, bt), init);
+		if(!bounded) {
+			if(cb != N)
+				chk1 = nod(OLT, cb, hb);
+			else
+				chk1 = nod(OLT, bound, hb);
+		}
+	} else if(slice3) {
+		// 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, N);
+		typecheck(&hb, Erv);
+		walkexpr(&hb, init);
+		hb = cheapexpr(conv(hb, bt), init);
+	}
+
+	if(lb != N) {
+		lb = cheapexpr(conv(lb, bt), init);
+		if(!bounded)
+			chk2 = nod(OLT, hb, lb);  
+	}
+
+	if(chk0 != N || chk1 != N || chk2 != N) {
+		chk = nod(OIF, N, N);
+		chk->nbody = list1(mkcall("panicslice", T, init));
+		chk->likely = -1;
+		if(chk0 != N)
+			chk->ntest = chk0;
+		if(chk1 != N) {
+			if(chk->ntest == N)
+				chk->ntest = chk1;
+			else
+				chk->ntest = nod(OOROR, chk->ntest, chk1);
+		}
+		if(chk2 != N) {
+			if(chk->ntest == N)
+				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 = N;
+	n->list = nil;
+	if(!slice3)
+		cb = bound;
+	if(lb == N)
+		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 == N)
+		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 != N) {
+		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;
+}
+
+static Node*
+eqfor(Type *t)
+{
+	int a;
+	Node *n;
+	Node *ntype;
+	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 %T", t);
+
+	if(a == AMEM) {
+		n = syslook("memequal", 1);
+		argtype(n, t);
+		argtype(n, t);
+		return n;
+	}
+
+	sym = typesymprefix(".eq", t);
+	n = newname(sym);
+	n->class = PFUNC;
+	ntype = nod(OTFUNC, N, N);
+	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL])));
+	typecheck(&ntype, Etype);
+	n->type = ntype->type;
+	return n;
+}
+
+static int
+countfield(Type *t)
+{
+	Type *t1;
+	int n;
+	
+	n = 0;
+	for(t1=t->type; t1!=T; t1=t1->down)
+		n++;
+	return n;
+}
+
+static void
+walkcompare(Node **np, NodeList **init)
+{
+	Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr;
+	int andor, i;
+	Type *t, *t1;
+	
+	n = *np;
+	
+	// Must be comparison of array or struct.
+	// Otherwise back end handles it.
+	t = n->left->type;
+	switch(t->etype) {
+	default:
+		return;
+	case TARRAY:
+		if(isslice(t))
+			return;
+		break;
+	case TSTRUCT:
+		break;
+	}
+	
+	cmpl = n->left;
+	while(cmpl != N && cmpl->op == OCONVNOP)
+		cmpl = cmpl->left;
+	cmpr = n->right;
+	while(cmpr != N && cmpr->op == OCONVNOP)
+		cmpr = cmpr->left;
+	
+	if(!islvalue(cmpl) || !islvalue(cmpr)) {
+		fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr);
+	}
+
+	l = temp(ptrto(t));
+	a = nod(OAS, l, nod(OADDR, cmpl, N));
+	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, N));
+	a->right->etype = 1;  // addr does not escape
+	typecheck(&a, Etop);
+	*init = list(*init, a);
+
+	expr = N;
+	andor = OANDAND;
+	if(n->op == ONE)
+		andor = OOROR;
+
+	if(t->etype == TARRAY &&
+		t->bound <= 4 &&
+		issimple[t->type->etype]) {
+		// Four or fewer elements of a basic type.
+		// Unroll comparisons.
+		for(i=0; i<t->bound; i++) {
+			li = nod(OINDEX, l, nodintconst(i));
+			ri = nod(OINDEX, r, nodintconst(i));
+			a = nod(n->op, li, ri);
+			if(expr == N)
+				expr = a;
+			else
+				expr = nod(andor, expr, a);
+		}
+		if(expr == N)
+			expr = nodbool(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; t1=t1->down) {
+			if(isblanksym(t1->sym))
+				continue;
+			li = nod(OXDOT, l, newname(t1->sym));
+			ri = nod(OXDOT, r, newname(t1->sym));
+			a = nod(n->op, li, ri);
+			if(expr == N)
+				expr = a;
+			else
+				expr = nod(andor, expr, a);
+		}
+		if(expr == N)
+			expr = nodbool(n->op == OEQ);
+		r = expr;
+		goto ret;
+	}
+
+	// Chose not to inline.  Call equality function directly.
+	call = nod(OCALL, eqfor(t), N);
+	call->list = list(call->list, l);
+	call->list = list(call->list, r);
+	call->list = list(call->list, nodintconst(t->width));
+	r = call;
+	if(n->op != OEQ)
+		r = nod(ONOT, r, N);
+	goto ret;
+
+ret:
+	typecheck(&r, Erv);
+	walkexpr(&r, init);
+	if(r->type != n->type) {
+		r = nod(OCONVNOP, r, N);
+		r->type = n->type;
+		r->typecheck = 1;
+	}
+	*np = r;
+	return;
+}
+
+static int
+samecheap(Node *a, Node *b)
+{
+	Node *ar, *br;
+	while(a != N && b != N && a->op == b->op) {
+		switch(a->op) {
+		default:
+			return 0;
+		case ONAME:
+			return a == b;
+		case ODOT:
+		case ODOTPTR:
+			ar = a->right;
+			br = b->right;
+			if(ar->op != ONAME || br->op != ONAME || ar->sym != br->sym)
+				return 0;
+			break;
+		case OINDEX:
+			ar = a->right;
+			br = b->right;
+			if(!isconst(ar, CTINT) || !isconst(br, CTINT) || mpcmpfixfix(ar->val.u.xval, br->val.u.xval) != 0)
+				return 0;
+			break;
+		}
+		a = a->left;
+		b = b->left;
+	}
+	return 0;
+}
+
+static void
+walkrotate(Node **np)
+{
+	int w, sl, sr, s;
+	Node *l, *r;
+	Node *n;
+	
+	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 == T || issigned[n->type->etype] ||
+	   l->op == r->op) {
+		return;
+	}
+
+	// Want same, side effect-free expression on lhs of both shifts.
+	if(!samecheap(l->left, r->left))
+		return;
+	
+	// Constants adding to width?
+	w = l->type->width * 8;
+	if(smallintconst(l->right) && smallintconst(r->right)) {
+		if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 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;
+	
+yes:
+	// Rewrite left shift half to left rotate.
+	if(l->op == OLSH)
+		n = l;
+	else
+		n = r;
+	n->op = OLROT;
+	
+	// Remove rotate 0 and rotate w.
+	s = 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.
+ */
+static void
+walkmul(Node **np, NodeList **init)
+{
+	Node *n, *nl, *nr;
+	int pow, neg, w;
+	
+	n = *np;
+	if(!isint[n->type->etype])
+		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 = 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(pow));
+
+ret:
+	if(neg)
+		n = nod(OMINUS, n, N);
+
+	typecheck(&n, Erv);
+	walkexpr(&n, init);
+	*np = n;
+}
+
+/*
+ * walkdiv rewrites division by a constant as less expensive
+ * operations.
+ */
+static void
+walkdiv(Node **np, NodeList **init)
+{
+	Node *n, *nl, *nr, *nc;
+	Node *n1, *n2, *n3, *n4;
+	int pow; // if >= 0, nr is 1<<pow
+	int s; // 1 if nr is negative.
+	int w;
+	Type *twide;
+	Magic m;
+
+	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 = 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) {
+			// divide by -1
+			n->op = OMINUS;
+			n->right = N;
+		} else {
+			// divide by 1
+			n = nl;
+		}
+		break;
+	default:
+		if(issigned[n->type->etype]) {
+			if(n->op == OMOD) {
+				// signed modulo 2^pow is like ANDing
+				// with the last pow bits, but if nl < 0,
+				// nl & (2^pow-1) is (nl+1)%2^pow - 1.
+				nc = nod(OXXX, N, N);
+				nodconst(nc, types[simtype[TUINT]], 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, N, N);
+					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, N, N);
+					nodconst(nc, nl->type, (1LL<<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, N, N);
+				nodconst(nc, types[simtype[TUINT]], 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, N, N);
+					nodconst(nc, types[simtype[TUINT]], w-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, N, N);
+				nodconst(nc, types[simtype[TUINT]], pow);
+				n->right = nc;
+				n->typecheck = 0;
+			}
+			if(s)
+				n = nod(OMINUS, n, N);
+			break;
+		}
+		nc = nod(OXXX, N, N);
+		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]], pow);
+		}
+		n->typecheck = 0;
+		n->right = nc;
+		break;
+	}
+	goto ret;
+
+divbymul:
+	// try to do division by multiply by (2^w)/d
+	// see hacker's delight chapter 10
+	// TODO: support 64-bit magic multiply here.
+	m.w = w;
+	if(issigned[nl->type->etype]) {
+		m.sd = mpgetfix(nr->val.u.xval);
+		smagic(&m);
+	} else {
+		m.ud = mpgetfix(nr->val.u.xval);
+		umagic(&m);
+	}
+	if(m.bad)
+		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;
+
+	case TUINT8:
+	case TUINT16:
+	case TUINT32:
+		// n1 = nl * magic >> w (HMUL)
+		nc = nod(OXXX, N, N);
+		nodconst(nc, nl->type, m.um);
+		n1 = nod(OMUL, nl, nc);
+		typecheck(&n1, Erv);
+		n1->op = OHMUL;
+		if(m.ua) {
+			// Select a Go type with (at least) twice the width.
+			switch(simtype[nl->type->etype]) {
+			default:
+				return;
+			case TUINT8:
+			case TUINT16:
+				twide = types[TUINT32];
+				break;
+			case TUINT32:
+				twide = types[TUINT64];
+				break;
+			case TINT8:
+			case TINT16:
+				twide = types[TINT32];
+				break;
+			case TINT32:
+				twide = types[TINT64];
+				break;
+			}
+
+			// add numerator (might overflow).
+			// n2 = (n1 + nl)
+			n2 = nod(OADD, conv(n1, twide), conv(nl, twide));
+
+			// shift by m.s
+			nc = nod(OXXX, N, N);
+			nodconst(nc, types[TUINT], m.s);
+			n = conv(nod(ORSH, n2, nc), nl->type);
+		} else {
+			// n = n1 >> m.s
+			nc = nod(OXXX, N, N);
+			nodconst(nc, types[TUINT], m.s);
+			n = nod(ORSH, n1, nc);
+		}
+		break;
+
+	case TINT8:
+	case TINT16:
+	case TINT32:
+		// n1 = nl * magic >> w
+		nc = nod(OXXX, N, N);
+		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, N, N);
+		nodconst(nc, types[TUINT], m.s);
+		n2 = conv(nod(ORSH, n1, nc), nl->type);
+		// add 1 iff n1 is negative.
+		nc = nod(OXXX, N, N);
+		nodconst(nc, types[TUINT], 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, N);
+		break;
+	}
+	goto ret;
+
+longmod:
+	// rewrite as A%B = A - (A/B*B).
+	n1 = nod(ODIV, nl, nr);
+	n2 = nod(OMUL, n1, nr);
+	n = nod(OSUB, nl, n2);
+	goto ret;
+
+ret:
+	typecheck(&n, Erv);
+	walkexpr(&n, init);
+	*np = n;
+}
+
+// return 1 if integer n must be in range [0, max), 0 otherwise
+static int
+bounded(Node *n, int64 max)
+{
+	int64 v;
+	int32 bits;
+	int sign;
+
+	if(n->type == T || !isint[n->type->etype])
+		return 0;
+
+	sign = issigned[n->type->etype];
+	bits = 8*n->type->width;
+
+	if(smallintconst(n)) {
+		v = mpgetfix(n->val.u.xval);
+		return 0 <= v && v < max;
+	}
+
+	switch(n->op) {
+	case OAND:
+		v = -1;
+		if(smallintconst(n->left)) {
+			v = mpgetfix(n->left->val.u.xval);
+		} else if(smallintconst(n->right)) {
+			v = mpgetfix(n->right->val.u.xval);
+		}
+		if(0 <= v && v < max)
+			return 1;
+		break;
+
+	case OMOD:
+		if(!sign && smallintconst(n->right)) {
+			v = mpgetfix(n->right->val.u.xval);
+			if(0 <= v && v <= max)
+				return 1;
+		}
+		break;
+	
+	case ODIV:
+		if(!sign && smallintconst(n->right)) {
+			v = mpgetfix(n->right->val.u.xval);
+			while(bits > 0 && v >= 2) {
+				bits--;
+				v >>= 1;
+			}
+		}
+		break;
+	
+	case ORSH:
+		if(!sign && smallintconst(n->right)) {
+			v = mpgetfix(n->right->val.u.xval);
+			if(v > bits)
+				return 1;
+			bits -= v;
+		}
+		break;
+	}
+	
+	if(!sign && bits <= 62 && (1LL<<bits) <= max)
+		return 1;
+	
+	return 0;
+}
+
+void
+usefield(Node *n)
+{
+	Type *field, *l;
+
+	if(!fieldtrack_enabled)
+		return;
+
+	switch(n->op) {
+	default:
+		fatal("usefield %O", n->op);
+	case ODOT:
+	case ODOTPTR:
+		break;
+	}
+	
+	field = n->paramfld;
+	if(field == T)
+		fatal("usefield %T %S without paramfld", n->left->type, n->right->sym);
+	if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil)
+		return;
+
+	// dedup on list
+	if(field->lastfn == curfn)
+		return;
+	field->lastfn = curfn;
+	field->outer = n->left->type;
+	if(isptr[field->outer->etype])
+		field->outer = field->outer->type;
+	if(field->outer->sym == S)
+		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;
+}
+
+static int
+candiscardlist(NodeList *l)
+{
+	for(; l; l=l->next)
+		if(!candiscard(l->n))
+			return 0;
+	return 1;
+}
+
+int
+candiscard(Node *n)
+{
+	if(n == N)
+		return 1;
+	
+	switch(n->op) {
+	default:
+		return 0;
+
+	case ONAME:
+	case ONONAME:
+	case OTYPE:
+	case OPACK:
+	case OLITERAL:
+	case OADD:
+	case OSUB:
+	case OOR:
+	case OXOR:
+	case OADDSTR:
+	case OADDR:
+	case OANDAND:
+	case OARRAYBYTESTR:
+	case OARRAYRUNESTR:
+	case OSTRARRAYBYTE:
+	case OSTRARRAYRUNE:
+	case OCAP:
+	case OCMPIFACE:
+	case OCMPSTR:
+	case OCOMPLIT:
+	case OMAPLIT:
+	case OSTRUCTLIT:
+	case OARRAYLIT:
+	case OPTRLIT:
+	case OCONV:
+	case OCONVIFACE:
+	case OCONVNOP:
+	case ODOT:
+	case OEQ:
+	case ONE:
+	case OLT:
+	case OLE:
+	case OGT:
+	case OGE:
+	case OKEY:
+	case OLEN:
+	case OMUL:
+	case OLSH:
+	case ORSH:
+	case OAND:
+	case OANDNOT:
+	case ONEW:
+	case ONOT:
+	case OCOM:
+	case OPLUS:
+	case OMINUS:
+	case OOROR:
+	case OPAREN:
+	case ORUNESTR:
+	case OREAL:
+	case OIMAG:
+	case OCOMPLEX:
+		// Discardable as long as the subpieces are.
+		break;
+
+	case ODIV:
+	case OMOD:
+		// Discardable as long as we know it's not division by zero.
+		if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
+			break;
+		if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
+			break;
+		return 0;
+
+	case OMAKECHAN:
+	case OMAKEMAP:
+		// Discardable as long as we know it won't fail because of a bad size.
+		if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
+			break;
+		return 0;
+	
+	case OMAKESLICE:
+		// Difficult to tell what sizes are okay.
+		return 0;		
+	}
+	
+	if(!candiscard(n->left) ||
+	   !candiscard(n->right) ||
+	   !candiscard(n->ntest) ||
+	   !candiscard(n->nincr) ||
+	   !candiscardlist(n->ninit) ||
+	   !candiscardlist(n->nbody) ||
+	   !candiscardlist(n->nelse) ||
+	   !candiscardlist(n->list) ||
+	   !candiscardlist(n->rlist)) {
+		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.
+static void
+walkprintfunc(Node **np, NodeList **init)
+{
+	Node *n;
+	Node *a, *fn, *t, *oldfn;
+	NodeList *l, *printargs;
+	int num;
+	char buf[100];
+	static int prgen;
+	
+	n = *np;
+
+	if(n->ninit != nil) {
+		walkstmtlist(n->ninit);
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+	}
+
+	t = nod(OTFUNC, N, N);
+	num = 0;
+	printargs = nil;
+	for(l=n->list; l != nil; l=l->next) {
+		snprint(buf, sizeof buf, "a%d", 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, N, N);
+	snprint(buf, sizeof buf, "print·%d", ++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(n->op, N, N);
+	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, N, N);
+	a->left = fn->nname;
+	a->list = n->list;
+	typecheck(&a, Etop);
+	walkexpr(&a, init);
+	*np = a;
+}
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
new file mode 100644
index 0000000..f464126
--- /dev/null
+++ b/src/cmd/gc/y.tab.c
@@ -0,0 +1,5132 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LLITERAL = 258,
+     LASOP = 259,
+     LCOLAS = 260,
+     LBREAK = 261,
+     LCASE = 262,
+     LCHAN = 263,
+     LCONST = 264,
+     LCONTINUE = 265,
+     LDDD = 266,
+     LDEFAULT = 267,
+     LDEFER = 268,
+     LELSE = 269,
+     LFALL = 270,
+     LFOR = 271,
+     LFUNC = 272,
+     LGO = 273,
+     LGOTO = 274,
+     LIF = 275,
+     LIMPORT = 276,
+     LINTERFACE = 277,
+     LMAP = 278,
+     LNAME = 279,
+     LPACKAGE = 280,
+     LRANGE = 281,
+     LRETURN = 282,
+     LSELECT = 283,
+     LSTRUCT = 284,
+     LSWITCH = 285,
+     LTYPE = 286,
+     LVAR = 287,
+     LANDAND = 288,
+     LANDNOT = 289,
+     LBODY = 290,
+     LCOMM = 291,
+     LDEC = 292,
+     LEQ = 293,
+     LGE = 294,
+     LGT = 295,
+     LIGNORE = 296,
+     LINC = 297,
+     LLE = 298,
+     LLSH = 299,
+     LLT = 300,
+     LNE = 301,
+     LOROR = 302,
+     LRSH = 303,
+     NotPackage = 304,
+     NotParen = 305,
+     PreferToRightParen = 306
+   };
+#endif
+/* Tokens.  */
+#define LLITERAL 258
+#define LASOP 259
+#define LCOLAS 260
+#define LBREAK 261
+#define LCASE 262
+#define LCHAN 263
+#define LCONST 264
+#define LCONTINUE 265
+#define LDDD 266
+#define LDEFAULT 267
+#define LDEFER 268
+#define LELSE 269
+#define LFALL 270
+#define LFOR 271
+#define LFUNC 272
+#define LGO 273
+#define LGOTO 274
+#define LIF 275
+#define LIMPORT 276
+#define LINTERFACE 277
+#define LMAP 278
+#define LNAME 279
+#define LPACKAGE 280
+#define LRANGE 281
+#define LRETURN 282
+#define LSELECT 283
+#define LSTRUCT 284
+#define LSWITCH 285
+#define LTYPE 286
+#define LVAR 287
+#define LANDAND 288
+#define LANDNOT 289
+#define LBODY 290
+#define LCOMM 291
+#define LDEC 292
+#define LEQ 293
+#define LGE 294
+#define LGT 295
+#define LIGNORE 296
+#define LINC 297
+#define LLE 298
+#define LLSH 299
+#define LLT 300
+#define LNE 301
+#define LOROR 302
+#define LRSH 303
+#define NotPackage 304
+#define NotParen 305
+#define PreferToRightParen 306
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 20 "go.y"
+
+#include <u.h>
+#include <stdio.h>	/* if we don't, bison will, and go.h re-#defines getc */
+#include <libc.h>
+#include "go.h"
+
+static void fixlbrace(int);
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 28 "go.y"
+{
+	Node*		node;
+	NodeList*		list;
+	Type*		type;
+	Sym*		sym;
+	struct	Val	val;
+	int		i;
+}
+/* Line 193 of yacc.c.  */
+#line 216 "y.tab.c"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 229 "y.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  4
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   2201
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  76
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  142
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  352
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  669
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   306
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    69,     2,     2,    64,    55,    56,     2,
+      59,    60,    53,    49,    75,    50,    63,    54,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    66,    62,
+       2,    65,     2,    73,    74,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    71,     2,    72,    52,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    67,    51,    68,    70,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    57,    58,    61
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     8,     9,    13,    14,    18,    19,    23,
+      26,    32,    36,    40,    43,    45,    49,    51,    54,    57,
+      62,    63,    65,    66,    71,    72,    74,    76,    78,    80,
+      83,    89,    93,    96,   102,   110,   114,   117,   123,   127,
+     129,   132,   137,   141,   146,   150,   152,   155,   157,   159,
+     162,   164,   168,   172,   176,   179,   182,   186,   192,   198,
+     201,   202,   207,   208,   212,   213,   216,   217,   222,   227,
+     232,   235,   241,   243,   245,   248,   249,   253,   255,   259,
+     260,   261,   262,   271,   272,   278,   279,   282,   283,   286,
+     287,   288,   296,   297,   303,   305,   309,   313,   317,   321,
+     325,   329,   333,   337,   341,   345,   349,   353,   357,   361,
+     365,   369,   373,   377,   381,   385,   387,   390,   393,   396,
+     399,   402,   405,   408,   411,   415,   421,   428,   430,   432,
+     436,   442,   448,   453,   460,   469,   471,   477,   483,   489,
+     497,   499,   500,   504,   506,   511,   513,   518,   520,   524,
+     526,   528,   530,   532,   534,   536,   538,   539,   541,   543,
+     545,   547,   552,   557,   559,   561,   563,   566,   568,   570,
+     572,   574,   576,   580,   582,   584,   586,   589,   591,   593,
+     595,   597,   601,   603,   605,   607,   609,   611,   613,   615,
+     617,   619,   623,   628,   633,   636,   640,   646,   648,   650,
+     653,   657,   663,   667,   673,   677,   681,   687,   696,   702,
+     711,   717,   718,   722,   723,   725,   729,   731,   736,   739,
+     740,   744,   746,   750,   752,   756,   758,   762,   764,   768,
+     770,   774,   778,   781,   786,   790,   796,   802,   804,   808,
+     810,   813,   815,   819,   824,   826,   829,   832,   834,   836,
+     840,   841,   844,   845,   847,   849,   851,   853,   855,   857,
+     859,   861,   863,   864,   869,   871,   874,   877,   880,   883,
+     886,   889,   891,   895,   897,   901,   903,   907,   909,   913,
+     915,   919,   921,   923,   927,   931,   932,   935,   936,   938,
+     939,   941,   942,   944,   945,   947,   948,   950,   951,   953,
+     954,   956,   957,   959,   960,   962,   967,   972,   978,   985,
+     990,   995,   997,   999,  1001,  1003,  1005,  1007,  1009,  1011,
+    1013,  1017,  1022,  1028,  1033,  1038,  1041,  1044,  1049,  1053,
+    1057,  1063,  1067,  1072,  1076,  1082,  1084,  1085,  1087,  1091,
+    1093,  1095,  1098,  1100,  1102,  1108,  1109,  1112,  1114,  1118,
+    1120,  1124,  1126
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+      77,     0,    -1,    79,    78,    81,   166,    -1,    -1,    25,
+     141,    62,    -1,    -1,    80,    86,    88,    -1,    -1,    81,
+      82,    62,    -1,    21,    83,    -1,    21,    59,    84,   190,
+      60,    -1,    21,    59,    60,    -1,    85,    86,    88,    -1,
+      85,    88,    -1,    83,    -1,    84,    62,    83,    -1,     3,
+      -1,   141,     3,    -1,    63,     3,    -1,    25,    24,    87,
+      62,    -1,    -1,    24,    -1,    -1,    89,   214,    64,    64,
+      -1,    -1,    91,    -1,   158,    -1,   181,    -1,     1,    -1,
+      32,    93,    -1,    32,    59,   167,   190,    60,    -1,    32,
+      59,    60,    -1,    92,    94,    -1,    92,    59,    94,   190,
+      60,    -1,    92,    59,    94,    62,   168,   190,    60,    -1,
+      92,    59,    60,    -1,    31,    97,    -1,    31,    59,   169,
+     190,    60,    -1,    31,    59,    60,    -1,     9,    -1,   185,
+     146,    -1,   185,   146,    65,   186,    -1,   185,    65,   186,
+      -1,   185,   146,    65,   186,    -1,   185,    65,   186,    -1,
+      94,    -1,   185,   146,    -1,   185,    -1,   141,    -1,    96,
+     146,    -1,   126,    -1,   126,     4,   126,    -1,   186,    65,
+     186,    -1,   186,     5,   186,    -1,   126,    42,    -1,   126,
+      37,    -1,     7,   187,    66,    -1,     7,   187,    65,   126,
+      66,    -1,     7,   187,     5,   126,    66,    -1,    12,    66,
+      -1,    -1,    67,   101,   183,    68,    -1,    -1,    99,   103,
+     183,    -1,    -1,   104,   102,    -1,    -1,    35,   106,   183,
+      68,    -1,   186,    65,    26,   126,    -1,   186,     5,    26,
+     126,    -1,    26,   126,    -1,   194,    62,   194,    62,   194,
+      -1,   194,    -1,   107,    -1,   108,   105,    -1,    -1,    16,
+     111,   109,    -1,   194,    -1,   194,    62,   194,    -1,    -1,
+      -1,    -1,    20,   114,   112,   115,   105,   116,   119,   120,
+      -1,    -1,    14,    20,   118,   112,   105,    -1,    -1,   119,
+     117,    -1,    -1,    14,   100,    -1,    -1,    -1,    30,   122,
+     112,   123,    35,   104,    68,    -1,    -1,    28,   125,    35,
+     104,    68,    -1,   127,    -1,   126,    47,   126,    -1,   126,
+      33,   126,    -1,   126,    38,   126,    -1,   126,    46,   126,
+      -1,   126,    45,   126,    -1,   126,    43,   126,    -1,   126,
+      39,   126,    -1,   126,    40,   126,    -1,   126,    49,   126,
+      -1,   126,    50,   126,    -1,   126,    51,   126,    -1,   126,
+      52,   126,    -1,   126,    53,   126,    -1,   126,    54,   126,
+      -1,   126,    55,   126,    -1,   126,    56,   126,    -1,   126,
+      34,   126,    -1,   126,    44,   126,    -1,   126,    48,   126,
+      -1,   126,    36,   126,    -1,   134,    -1,    53,   127,    -1,
+      56,   127,    -1,    49,   127,    -1,    50,   127,    -1,    69,
+     127,    -1,    70,   127,    -1,    52,   127,    -1,    36,   127,
+      -1,   134,    59,    60,    -1,   134,    59,   187,   191,    60,
+      -1,   134,    59,   187,    11,   191,    60,    -1,     3,    -1,
+     143,    -1,   134,    63,   141,    -1,   134,    63,    59,   135,
+      60,    -1,   134,    63,    59,    31,    60,    -1,   134,    71,
+     126,    72,    -1,   134,    71,   192,    66,   192,    72,    -1,
+     134,    71,   192,    66,   192,    66,   192,    72,    -1,   128,
+      -1,   149,    59,   126,   191,    60,    -1,   150,   137,   130,
+     189,    68,    -1,   129,    67,   130,   189,    68,    -1,    59,
+     135,    60,    67,   130,   189,    68,    -1,   165,    -1,    -1,
+     126,    66,   133,    -1,   126,    -1,    67,   130,   189,    68,
+      -1,   126,    -1,    67,   130,   189,    68,    -1,   129,    -1,
+      59,   135,    60,    -1,   126,    -1,   147,    -1,   146,    -1,
+      35,    -1,    67,    -1,   141,    -1,   141,    -1,    -1,   138,
+      -1,    24,    -1,   142,    -1,    73,    -1,    74,     3,    63,
+      24,    -1,    74,     3,    63,    73,    -1,   141,    -1,   138,
+      -1,    11,    -1,    11,   146,    -1,   155,    -1,   161,    -1,
+     153,    -1,   154,    -1,   152,    -1,    59,   146,    60,    -1,
+     155,    -1,   161,    -1,   153,    -1,    53,   147,    -1,   161,
+      -1,   153,    -1,   154,    -1,   152,    -1,    59,   146,    60,
+      -1,   161,    -1,   153,    -1,   153,    -1,   155,    -1,   161,
+      -1,   153,    -1,   154,    -1,   152,    -1,   143,    -1,   143,
+      63,   141,    -1,    71,   192,    72,   146,    -1,    71,    11,
+      72,   146,    -1,     8,   148,    -1,     8,    36,   146,    -1,
+      23,    71,   146,    72,   146,    -1,   156,    -1,   157,    -1,
+      53,   146,    -1,    36,     8,   146,    -1,    29,   137,   170,
+     190,    68,    -1,    29,   137,    68,    -1,    22,   137,   171,
+     190,    68,    -1,    22,   137,    68,    -1,    17,   159,   162,
+      -1,   141,    59,   179,    60,   163,    -1,    59,   179,    60,
+     141,    59,   179,    60,   163,    -1,   200,    59,   195,    60,
+     210,    -1,    59,   215,    60,   141,    59,   195,    60,   210,
+      -1,    17,    59,   179,    60,   163,    -1,    -1,    67,   183,
+      68,    -1,    -1,   151,    -1,    59,   179,    60,    -1,   161,
+      -1,   164,   137,   183,    68,    -1,   164,     1,    -1,    -1,
+     166,    90,    62,    -1,    93,    -1,   167,    62,    93,    -1,
+      95,    -1,   168,    62,    95,    -1,    97,    -1,   169,    62,
+      97,    -1,   172,    -1,   170,    62,   172,    -1,   175,    -1,
+     171,    62,   175,    -1,   184,   146,   198,    -1,   174,   198,
+      -1,    59,   174,    60,   198,    -1,    53,   174,   198,    -1,
+      59,    53,   174,    60,   198,    -1,    53,    59,   174,    60,
+     198,    -1,    24,    -1,    24,    63,   141,    -1,   173,    -1,
+     138,   176,    -1,   173,    -1,    59,   173,    60,    -1,    59,
+     179,    60,   163,    -1,   136,    -1,   141,   136,    -1,   141,
+     145,    -1,   145,    -1,   177,    -1,   178,    75,   177,    -1,
+      -1,   178,   191,    -1,    -1,   100,    -1,    91,    -1,   181,
+      -1,     1,    -1,    98,    -1,   110,    -1,   121,    -1,   124,
+      -1,   113,    -1,    -1,   144,    66,   182,   180,    -1,    15,
+      -1,     6,   140,    -1,    10,   140,    -1,    18,   128,    -1,
+      13,   128,    -1,    19,   138,    -1,    27,   193,    -1,   180,
+      -1,   183,    62,   180,    -1,   138,    -1,   184,    75,   138,
+      -1,   139,    -1,   185,    75,   139,    -1,   126,    -1,   186,
+      75,   126,    -1,   135,    -1,   187,    75,   135,    -1,   131,
+      -1,   132,    -1,   188,    75,   131,    -1,   188,    75,   132,
+      -1,    -1,   188,   191,    -1,    -1,    62,    -1,    -1,    75,
+      -1,    -1,   126,    -1,    -1,   186,    -1,    -1,    98,    -1,
+      -1,   215,    -1,    -1,   216,    -1,    -1,   217,    -1,    -1,
+       3,    -1,    21,    24,     3,    62,    -1,    32,   200,   202,
+      62,    -1,     9,   200,    65,   213,    62,    -1,     9,   200,
+     202,    65,   213,    62,    -1,    31,   201,   202,    62,    -1,
+      17,   160,   162,    62,    -1,   142,    -1,   200,    -1,   204,
+      -1,   205,    -1,   206,    -1,   204,    -1,   206,    -1,   142,
+      -1,    24,    -1,    71,    72,   202,    -1,    71,     3,    72,
+     202,    -1,    23,    71,   202,    72,   202,    -1,    29,    67,
+     196,    68,    -1,    22,    67,   197,    68,    -1,    53,   202,
+      -1,     8,   203,    -1,     8,    59,   205,    60,    -1,     8,
+      36,   202,    -1,    36,     8,   202,    -1,    17,    59,   195,
+      60,   210,    -1,   141,   202,   198,    -1,   141,    11,   202,
+     198,    -1,   141,   202,   198,    -1,   141,    59,   195,    60,
+     210,    -1,   202,    -1,    -1,   211,    -1,    59,   195,    60,
+      -1,   202,    -1,     3,    -1,    50,     3,    -1,   141,    -1,
+     212,    -1,    59,   212,    49,   212,    60,    -1,    -1,   214,
+     199,    -1,   207,    -1,   215,    75,   207,    -1,   208,    -1,
+     216,    62,   208,    -1,   209,    -1,   217,    62,   209,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   124,   124,   133,   139,   150,   150,   165,   166,   169,
+     170,   171,   174,   211,   222,   223,   226,   233,   240,   249,
+     263,   264,   271,   271,   284,   288,   289,   293,   298,   304,
+     308,   312,   316,   322,   328,   334,   339,   343,   347,   353,
+     359,   363,   367,   373,   377,   383,   384,   388,   394,   403,
+     409,   427,   432,   444,   460,   466,   474,   494,   512,   521,
+     540,   539,   554,   553,   585,   588,   595,   594,   605,   611,
+     618,   625,   636,   642,   645,   653,   652,   663,   669,   681,
+     685,   690,   680,   711,   710,   723,   726,   732,   735,   747,
+     751,   746,   769,   768,   784,   785,   789,   793,   797,   801,
+     805,   809,   813,   817,   821,   825,   829,   833,   837,   841,
+     845,   849,   853,   857,   862,   868,   869,   873,   884,   888,
+     892,   896,   901,   905,   915,   919,   924,   932,   936,   937,
+     948,   952,   956,   960,   964,   972,   973,   979,   986,   992,
+     999,  1002,  1009,  1015,  1032,  1039,  1040,  1047,  1048,  1067,
+    1068,  1071,  1074,  1078,  1089,  1098,  1104,  1107,  1110,  1117,
+    1118,  1124,  1137,  1152,  1160,  1172,  1177,  1183,  1184,  1185,
+    1186,  1187,  1188,  1194,  1195,  1196,  1197,  1203,  1204,  1205,
+    1206,  1207,  1213,  1214,  1217,  1220,  1221,  1222,  1223,  1224,
+    1227,  1228,  1241,  1245,  1250,  1255,  1260,  1264,  1265,  1268,
+    1274,  1281,  1287,  1294,  1300,  1311,  1326,  1355,  1393,  1418,
+    1436,  1445,  1448,  1456,  1460,  1464,  1471,  1477,  1482,  1494,
+    1497,  1508,  1509,  1515,  1516,  1522,  1526,  1532,  1533,  1539,
+    1543,  1549,  1572,  1577,  1583,  1589,  1596,  1605,  1614,  1629,
+    1635,  1640,  1644,  1651,  1664,  1665,  1671,  1677,  1680,  1684,
+    1690,  1693,  1702,  1705,  1706,  1710,  1711,  1717,  1718,  1719,
+    1720,  1721,  1723,  1722,  1737,  1743,  1747,  1751,  1755,  1759,
+    1764,  1783,  1789,  1797,  1801,  1807,  1811,  1817,  1821,  1827,
+    1831,  1840,  1844,  1848,  1852,  1858,  1861,  1869,  1870,  1872,
+    1873,  1876,  1879,  1882,  1885,  1888,  1891,  1894,  1897,  1900,
+    1903,  1906,  1909,  1912,  1915,  1921,  1925,  1929,  1933,  1937,
+    1941,  1961,  1968,  1979,  1980,  1981,  1984,  1985,  1988,  1992,
+    2002,  2006,  2010,  2014,  2018,  2022,  2026,  2032,  2038,  2046,
+    2054,  2060,  2067,  2083,  2105,  2109,  2115,  2118,  2121,  2125,
+    2135,  2139,  2158,  2166,  2167,  2179,  2180,  2183,  2187,  2193,
+    2197,  2203,  2207
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+const char *yytname[] =
+{
+  "$end", "error", "$undefined", "LLITERAL", "LASOP", "LCOLAS", "LBREAK",
+  "LCASE", "LCHAN", "LCONST", "LCONTINUE", "LDDD", "LDEFAULT", "LDEFER",
+  "LELSE", "LFALL", "LFOR", "LFUNC", "LGO", "LGOTO", "LIF", "LIMPORT",
+  "LINTERFACE", "LMAP", "LNAME", "LPACKAGE", "LRANGE", "LRETURN",
+  "LSELECT", "LSTRUCT", "LSWITCH", "LTYPE", "LVAR", "LANDAND", "LANDNOT",
+  "LBODY", "LCOMM", "LDEC", "LEQ", "LGE", "LGT", "LIGNORE", "LINC", "LLE",
+  "LLSH", "LLT", "LNE", "LOROR", "LRSH", "'+'", "'-'", "'|'", "'^'", "'*'",
+  "'/'", "'%'", "'&'", "NotPackage", "NotParen", "'('", "')'",
+  "PreferToRightParen", "';'", "'.'", "'$'", "'='", "':'", "'{'", "'}'",
+  "'!'", "'~'", "'['", "']'", "'?'", "'@'", "','", "$accept", "file",
+  "package", "loadsys", "@1", "imports", "import", "import_stmt",
+  "import_stmt_list", "import_here", "import_package", "import_safety",
+  "import_there", "@2", "xdcl", "common_dcl", "lconst", "vardcl",
+  "constdcl", "constdcl1", "typedclname", "typedcl", "simple_stmt", "case",
+  "compound_stmt", "@3", "caseblock", "@4", "caseblock_list", "loop_body",
+  "@5", "range_stmt", "for_header", "for_body", "for_stmt", "@6",
+  "if_header", "if_stmt", "@7", "@8", "@9", "elseif", "@10", "elseif_list",
+  "else", "switch_stmt", "@11", "@12", "select_stmt", "@13", "expr",
+  "uexpr", "pseudocall", "pexpr_no_paren", "start_complit", "keyval",
+  "bare_complitexpr", "complitexpr", "pexpr", "expr_or_type",
+  "name_or_type", "lbrace", "new_name", "dcl_name", "onew_name", "sym",
+  "hidden_importsym", "name", "labelname", "dotdotdot", "ntype",
+  "non_expr_type", "non_recvchantype", "convtype", "comptype",
+  "fnret_type", "dotname", "othertype", "ptrtype", "recvchantype",
+  "structtype", "interfacetype", "xfndcl", "fndcl", "hidden_fndcl",
+  "fntype", "fnbody", "fnres", "fnlitdcl", "fnliteral", "xdcl_list",
+  "vardcl_list", "constdcl_list", "typedcl_list", "structdcl_list",
+  "interfacedcl_list", "structdcl", "packname", "embed", "interfacedcl",
+  "indcl", "arg_type", "arg_type_list", "oarg_type_list_ocomma", "stmt",
+  "non_dcl_stmt", "@14", "stmt_list", "new_name_list", "dcl_name_list",
+  "expr_list", "expr_or_type_list", "keyval_list", "braced_keyval_list",
+  "osemi", "ocomma", "oexpr", "oexpr_list", "osimple_stmt",
+  "ohidden_funarg_list", "ohidden_structdcl_list",
+  "ohidden_interfacedcl_list", "oliteral", "hidden_import",
+  "hidden_pkg_importsym", "hidden_pkgtype", "hidden_type",
+  "hidden_type_non_recv_chan", "hidden_type_misc", "hidden_type_recv_chan",
+  "hidden_type_func", "hidden_funarg", "hidden_structdcl",
+  "hidden_interfacedcl", "ohidden_funres", "hidden_funres",
+  "hidden_literal", "hidden_constant", "hidden_import_list",
+  "hidden_funarg_list", "hidden_structdcl_list",
+  "hidden_interfacedcl_list", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,    43,
+      45,   124,    94,    42,    47,    37,    38,   304,   305,    40,
+      41,   306,    59,    46,    36,    61,    58,   123,   125,    33,
+     126,    91,    93,    63,    64,    44
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    76,    77,    78,    78,    80,    79,    81,    81,    82,
+      82,    82,    83,    83,    84,    84,    85,    85,    85,    86,
+      87,    87,    89,    88,    90,    90,    90,    90,    90,    91,
+      91,    91,    91,    91,    91,    91,    91,    91,    91,    92,
+      93,    93,    93,    94,    94,    95,    95,    95,    96,    97,
+      98,    98,    98,    98,    98,    98,    99,    99,    99,    99,
+     101,   100,   103,   102,   104,   104,   106,   105,   107,   107,
+     107,   108,   108,   108,   109,   111,   110,   112,   112,   114,
+     115,   116,   113,   118,   117,   119,   119,   120,   120,   122,
+     123,   121,   125,   124,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   127,   127,   127,   127,   127,
+     127,   127,   127,   127,   128,   128,   128,   129,   129,   129,
+     129,   129,   129,   129,   129,   129,   129,   129,   129,   129,
+     129,   130,   131,   132,   132,   133,   133,   134,   134,   135,
+     135,   136,   137,   137,   138,   139,   140,   140,   141,   141,
+     141,   142,   142,   143,   144,   145,   145,   146,   146,   146,
+     146,   146,   146,   147,   147,   147,   147,   148,   148,   148,
+     148,   148,   149,   149,   150,   151,   151,   151,   151,   151,
+     152,   152,   153,   153,   153,   153,   153,   153,   153,   154,
+     155,   156,   156,   157,   157,   158,   159,   159,   160,   160,
+     161,   162,   162,   163,   163,   163,   164,   165,   165,   166,
+     166,   167,   167,   168,   168,   169,   169,   170,   170,   171,
+     171,   172,   172,   172,   172,   172,   172,   173,   173,   174,
+     175,   175,   175,   176,   177,   177,   177,   177,   178,   178,
+     179,   179,   180,   180,   180,   180,   180,   181,   181,   181,
+     181,   181,   182,   181,   181,   181,   181,   181,   181,   181,
+     181,   183,   183,   184,   184,   185,   185,   186,   186,   187,
+     187,   188,   188,   188,   188,   189,   189,   190,   190,   191,
+     191,   192,   192,   193,   193,   194,   194,   195,   195,   196,
+     196,   197,   197,   198,   198,   199,   199,   199,   199,   199,
+     199,   200,   201,   202,   202,   202,   203,   203,   204,   204,
+     204,   204,   204,   204,   204,   204,   204,   204,   204,   205,
+     206,   207,   207,   208,   209,   209,   210,   210,   211,   211,
+     212,   212,   212,   213,   213,   214,   214,   215,   215,   216,
+     216,   217,   217
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     4,     0,     3,     0,     3,     0,     3,     2,
+       5,     3,     3,     2,     1,     3,     1,     2,     2,     4,
+       0,     1,     0,     4,     0,     1,     1,     1,     1,     2,
+       5,     3,     2,     5,     7,     3,     2,     5,     3,     1,
+       2,     4,     3,     4,     3,     1,     2,     1,     1,     2,
+       1,     3,     3,     3,     2,     2,     3,     5,     5,     2,
+       0,     4,     0,     3,     0,     2,     0,     4,     4,     4,
+       2,     5,     1,     1,     2,     0,     3,     1,     3,     0,
+       0,     0,     8,     0,     5,     0,     2,     0,     2,     0,
+       0,     7,     0,     5,     1,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     1,     2,     2,     2,     2,
+       2,     2,     2,     2,     3,     5,     6,     1,     1,     3,
+       5,     5,     4,     6,     8,     1,     5,     5,     5,     7,
+       1,     0,     3,     1,     4,     1,     4,     1,     3,     1,
+       1,     1,     1,     1,     1,     1,     0,     1,     1,     1,
+       1,     4,     4,     1,     1,     1,     2,     1,     1,     1,
+       1,     1,     3,     1,     1,     1,     2,     1,     1,     1,
+       1,     3,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     3,     4,     4,     2,     3,     5,     1,     1,     2,
+       3,     5,     3,     5,     3,     3,     5,     8,     5,     8,
+       5,     0,     3,     0,     1,     3,     1,     4,     2,     0,
+       3,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     3,     2,     4,     3,     5,     5,     1,     3,     1,
+       2,     1,     3,     4,     1,     2,     2,     1,     1,     3,
+       0,     2,     0,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     0,     4,     1,     2,     2,     2,     2,     2,
+       2,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     1,     3,     3,     0,     2,     0,     1,     0,
+       1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
+       1,     0,     1,     0,     1,     4,     4,     5,     6,     4,
+       4,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       3,     4,     5,     4,     4,     2,     2,     4,     3,     3,
+       5,     3,     4,     3,     5,     1,     0,     1,     3,     1,
+       1,     2,     1,     1,     5,     0,     2,     1,     3,     1,
+       3,     1,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint16 yydefact[] =
+{
+       5,     0,     3,     0,     1,     0,     7,     0,    22,   158,
+     160,     0,     0,   159,   219,    20,     6,   345,     0,     4,
+       0,     0,     0,    21,     0,     0,     0,    16,     0,     0,
+       9,    22,     0,     8,    28,   127,   156,     0,    39,   156,
+       0,   264,    75,     0,     0,     0,    79,     0,     0,   293,
+      92,     0,    89,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   291,     0,    25,     0,   257,   258,
+     261,   259,   260,    50,    94,   135,   147,   115,   164,   163,
+     128,     0,     0,     0,   184,   197,   198,    26,   216,     0,
+     140,    27,     0,    19,     0,     0,     0,     0,     0,     0,
+     346,   161,   162,    11,    14,   287,    18,    22,    13,    17,
+     157,   265,   154,     0,     0,     0,     0,   163,   190,   194,
+     180,   178,   179,   177,   266,   135,     0,   295,   250,     0,
+     211,   135,   269,   295,   152,   153,     0,     0,   277,   294,
+     270,     0,     0,   295,     0,     0,    36,    48,     0,    29,
+     275,   155,     0,   123,   118,   119,   122,   116,   117,     0,
+       0,   149,     0,   150,   175,   173,   174,   120,   121,     0,
+     292,     0,   220,     0,    32,     0,     0,     0,     0,     0,
+      55,     0,     0,     0,    54,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   141,
+       0,     0,   291,   262,     0,   141,   218,     0,     0,     0,
+       0,   311,     0,     0,   211,     0,     0,   312,     0,     0,
+      23,   288,     0,    12,   250,     0,     0,   195,   171,   169,
+     170,   167,   168,   199,     0,     0,     0,   296,    73,     0,
+      76,     0,    72,   165,   244,   163,   247,   151,   248,   289,
+       0,   250,     0,   205,    80,    77,   158,     0,   204,     0,
+     287,   241,   229,     0,    64,     0,     0,   202,   273,   287,
+     227,   239,   303,     0,    90,    38,   225,   287,    49,    31,
+     221,   287,     0,     0,    40,     0,   176,   148,     0,     0,
+      35,   287,     0,     0,    51,    96,   111,   114,    97,   101,
+     102,   100,   112,    99,    98,    95,   113,   103,   104,   105,
+     106,   107,   108,   109,   110,   285,   124,   279,   289,     0,
+     129,   292,     0,     0,   289,   285,   256,    60,   254,   253,
+     271,   255,     0,    53,    52,   278,     0,     0,     0,     0,
+     319,     0,     0,     0,     0,     0,   318,     0,   313,   314,
+     315,     0,   347,     0,     0,   297,     0,     0,     0,    15,
+      10,     0,     0,     0,   181,   191,    70,    66,    74,     0,
+       0,   295,   166,   245,   246,   290,   251,   213,     0,     0,
+       0,   295,     0,   237,     0,   250,   240,   288,     0,     0,
+       0,     0,   303,     0,     0,   288,     0,   304,   232,     0,
+     303,     0,   288,     0,   288,     0,    42,   276,     0,     0,
+       0,   200,   171,   169,   170,   168,   141,   193,   192,   288,
+       0,    44,     0,   141,   143,   281,   282,   289,     0,   289,
+     290,     0,     0,     0,   132,   291,   263,   290,     0,     0,
+       0,     0,   217,     0,     0,   326,   316,   317,   297,   301,
+       0,   299,     0,   325,   340,     0,     0,   342,   343,     0,
+       0,     0,     0,     0,   303,     0,     0,   310,     0,   298,
+     305,   309,   306,   213,   172,     0,     0,     0,     0,   249,
+     250,   163,   214,   189,   187,   188,   185,   186,   210,   213,
+     212,    81,    78,   238,   242,     0,   230,   203,   196,     0,
+       0,    93,    62,    65,     0,   234,     0,   303,   228,   201,
+     274,   231,    64,   226,    37,   222,    30,    41,     0,   285,
+      45,   223,   287,    47,    33,    43,   285,     0,   290,   286,
+     138,     0,   280,   125,   131,   130,     0,   136,   137,     0,
+     272,   328,     0,     0,   319,     0,   318,     0,   335,   351,
+     302,     0,     0,     0,   349,   300,   329,   341,     0,   307,
+       0,   320,     0,   303,   331,     0,   348,   336,     0,    69,
+      68,   295,     0,   250,   206,    85,   213,     0,    59,     0,
+     303,   303,   233,     0,   172,     0,   288,     0,    46,     0,
+     141,   145,   142,   283,   284,   126,   291,   133,    61,   327,
+     336,   297,   324,     0,     0,   303,   323,     0,     0,   321,
+     308,   332,   297,   297,   339,   208,   337,    67,    71,   215,
+       0,    87,   243,     0,     0,    56,     0,    63,   236,   235,
+      91,   139,   224,    34,   144,   285,     0,   330,     0,   352,
+     322,   333,   350,     0,     0,     0,   213,     0,    86,    82,
+       0,     0,     0,   134,   336,   344,   336,   338,   207,    83,
+      88,    58,    57,   146,   334,   209,   295,     0,    84
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     1,     6,     2,     3,    14,    21,    30,   105,    31,
+       8,    24,    16,    17,    65,   328,    67,   149,   520,   521,
+     145,   146,    68,   502,   329,   440,   503,   579,   390,   368,
+     475,   238,   239,   240,    69,   127,   254,    70,   133,   380,
+     575,   648,   666,   621,   649,    71,   143,   401,    72,   141,
+      73,    74,    75,    76,   315,   425,   426,   592,    77,   317,
+     244,   136,    78,   150,   111,   117,    13,    80,    81,   246,
+     247,   163,   119,    82,    83,   482,   228,    84,   230,   231,
+      85,    86,    87,   130,   214,    88,   253,   488,    89,    90,
+      22,   281,   522,   277,   269,   260,   270,   271,   272,   262,
+     386,   248,   249,   250,   330,   331,   323,   332,   273,   152,
+      92,   318,   427,   428,   222,   376,   171,   140,   255,   468,
+     553,   547,   398,   100,   212,   218,   614,   445,   348,   349,
+     350,   352,   554,   549,   615,   616,   458,   459,    25,   469,
+     555,   550
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -473
+static const yytype_int16 yypact[] =
+{
+    -473,    65,    22,    49,  -473,   261,  -473,    64,  -473,  -473,
+    -473,    95,    52,  -473,   143,   145,  -473,  -473,   104,  -473,
+      68,   128,  1049,  -473,   142,   305,    16,  -473,    56,   204,
+    -473,    49,   220,  -473,  -473,  -473,   261,   974,  -473,   261,
+     562,  -473,  -473,   288,   562,   261,  -473,    14,   147,  1615,
+    -473,    14,  -473,   395,   401,  1615,  1615,  1615,  1615,  1615,
+    1615,  1658,  1615,  1615,   737,   168,  -473,   414,  -473,  -473,
+    -473,  -473,  -473,   649,  -473,  -473,   165,   122,  -473,   169,
+    -473,   177,   218,    14,   219,  -473,  -473,  -473,   235,    89,
+    -473,  -473,    34,  -473,   206,   124,   286,   206,   206,   260,
+    -473,  -473,  -473,  -473,  -473,   265,  -473,  -473,  -473,  -473,
+    -473,  -473,  -473,   270,  1803,  1803,  1803,  -473,   269,  -473,
+    -473,  -473,  -473,  -473,  -473,    39,   122,   882,  1777,   283,
+     277,   230,  -473,  1615,  -473,  -473,   292,  1803,  2097,   280,
+    -473,   332,   315,  1615,   215,  1803,  -473,  -473,   244,  -473,
+    -473,  -473,   949,  -473,  -473,  -473,  -473,  -473,  -473,  1701,
+    1658,  2097,   298,  -473,     9,  -473,    59,  -473,  -473,   303,
+    2097,   319,  -473,   330,  -473,  1744,  1615,  1615,  1615,  1615,
+    -473,  1615,  1615,  1615,  -473,  1615,  1615,  1615,  1615,  1615,
+    1615,  1615,  1615,  1615,  1615,  1615,  1615,  1615,  1615,  -473,
+    1297,   455,  1615,  -473,  1615,  -473,  -473,  1225,  1615,  1615,
+    1615,  -473,   594,   261,   277,   328,   403,  -473,  1308,  1308,
+    -473,   152,   352,  -473,  1777,   405,  1803,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,   354,   261,  1615,  -473,  -473,   382,
+    -473,    47,   360,  1803,  -473,  1777,  -473,  -473,  -473,   351,
+     367,  1777,  1225,  -473,  -473,   366,    84,   407,  -473,   374,
+     373,  -473,  -473,   372,  -473,   138,    42,  -473,  -473,   377,
+    -473,  -473,   442,  1769,  -473,  -473,  -473,   384,  -473,  -473,
+    -473,   389,  1615,   261,   391,  1830,  -473,   394,  1803,  1803,
+    -473,   409,  1615,   411,  2097,  1935,  -473,  2121,  1080,  1080,
+    1080,  1080,  -473,  1080,  1080,  2145,  -473,   503,   503,   503,
+     503,  -473,  -473,  -473,  -473,  1352,  -473,  -473,    27,  1407,
+    -473,  1995,   412,  1147,  1962,  1352,  -473,  -473,  -473,  -473,
+    -473,  -473,     7,   280,   280,  2097,   698,   418,   415,   413,
+    -473,   416,   477,  1308,   188,    31,  -473,   425,  -473,  -473,
+    -473,  1897,  -473,   221,   433,   261,   434,   436,   439,  -473,
+    -473,   432,  1803,   452,  -473,  -473,  2097,  -473,  -473,  1462,
+    1517,  1615,  -473,  -473,  -473,  1777,  -473,  1856,   453,    91,
+     382,  1615,   261,   454,   456,  1777,  -473,   475,   451,  1803,
+     133,   407,   442,   407,   460,   326,   462,  -473,  -473,   261,
+     442,   467,   261,   478,   261,   486,   280,  -473,  1615,  1864,
+    1803,  -473,    26,   248,   264,   430,  -473,  -473,  -473,   261,
+     492,   280,  1615,  -473,  2025,  -473,  -473,   485,   493,   487,
+    1658,   504,   506,   508,  -473,  1615,  -473,  -473,   512,   505,
+    1225,  1147,  -473,  1308,   517,  -473,  -473,  -473,   261,  1889,
+    1308,   261,  1308,  -473,  -473,   571,   155,  -473,  -473,   514,
+     509,  1308,   188,  1308,   442,   261,   261,  -473,   518,   507,
+    -473,  -473,  -473,  1856,  -473,  1225,  1615,  1615,   521,  -473,
+    1777,   528,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  1856,
+    -473,  -473,  -473,  -473,  -473,   520,  -473,  -473,  -473,  1658,
+     522,  -473,  -473,  -473,   530,  -473,   532,   442,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,   280,   535,  1352,
+    -473,  -473,   536,  1744,  -473,   280,  1352,  1560,  1352,  -473,
+    -473,   539,  -473,  -473,  -473,  -473,   247,  -473,  -473,   308,
+    -473,  -473,   541,   543,   545,   546,   547,   544,  -473,  -473,
+     551,   548,  1308,   554,  -473,   557,  -473,  -473,   576,  -473,
+    1308,  -473,   564,   442,  -473,   568,  -473,  1923,   318,  2097,
+    2097,  1615,   569,  1777,  -473,  -473,  1856,   156,  -473,  1147,
+     442,   442,  -473,   243,   483,   563,   261,   577,   411,   570,
+    -473,  2097,  -473,  -473,  -473,  -473,  1615,  -473,  -473,  -473,
+    1923,   261,  -473,  1889,  1308,   442,  -473,   261,   155,  -473,
+    -473,  -473,   261,   261,  -473,  -473,  -473,  -473,  -473,  -473,
+     579,   627,  -473,  1615,  1615,  -473,  1658,   580,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  1352,   572,  -473,   583,  -473,
+    -473,  -473,  -473,   585,   586,   590,  1856,    77,  -473,  -473,
+    2049,  2073,   584,  -473,  1923,  -473,  1923,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  1615,   382,  -473
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,   -12,  -473,  -473,
+     624,  -473,    -1,  -473,  -473,   635,  -473,  -137,   -48,    74,
+    -473,  -130,  -112,  -473,    11,  -473,  -473,  -473,   149,  -372,
+    -473,  -473,  -473,  -473,  -473,  -473,  -140,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,
+     662,   448,   257,  -473,  -196,   135,   139,  -473,   262,   -59,
+     424,   -16,    -3,   387,   632,   427,   313,    20,  -473,   428,
+     -89,   524,  -473,  -473,  -473,  -473,   -36,   -37,   -31,   -49,
+    -473,  -473,  -473,  -473,  -473,   -32,   458,  -472,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,   279,  -108,  -211,   290,
+    -473,   306,  -473,  -214,  -291,   658,  -473,  -230,  -473,   -63,
+      -6,   191,  -473,  -302,  -219,  -254,  -195,  -473,  -107,  -435,
+    -473,  -473,  -347,  -473,   323,  -473,    72,  -473,   371,   268,
+     380,   242,   102,   110,  -468,  -473,  -438,   255,  -473,   515,
+    -473,  -473
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -278
+static const yytype_int16 yytable[] =
+{
+     121,   120,   162,   274,   175,   123,   122,   322,   491,   325,
+     361,   280,   165,   543,   276,   237,   104,   574,   558,   174,
+     242,   237,   379,   439,   164,   227,   233,   234,   261,   166,
+     108,   237,   436,   110,   460,   142,   110,   378,   429,   208,
+     101,   388,   132,   139,  -184,   505,  -268,     5,   263,   134,
+     396,  -268,   369,   511,   392,   394,   278,   118,   403,    27,
+    -216,  -180,   405,   284,   431,     4,   383,   205,  -183,   441,
+     438,    27,   420,   207,     7,   442,  -184,   229,   229,   229,
+       9,   135,   232,   232,   232,  -180,   293,  -237,    15,   102,
+     206,   229,     9,  -180,  -216,   393,   232,   659,    18,   209,
+     229,  -268,   430,   461,   622,   232,   223,  -268,   229,   210,
+     175,   165,   370,   232,    19,   229,   103,   564,  -182,    29,
+     232,   241,   210,   164,   134,   291,  -216,    28,   166,    10,
+      11,    29,   637,   259,   118,   118,   118,   363,   229,   268,
+     499,    10,    11,   232,   327,   500,  -237,   382,   118,   384,
+     540,   165,  -237,   441,   372,    27,   135,   118,   454,   490,
+     582,   623,   383,   164,    20,   118,   638,    26,   166,    23,
+     643,   495,   118,   529,   658,   531,     9,   644,   645,     9,
+     504,   200,   506,   213,   400,   201,   664,   229,   665,   229,
+      33,   454,   232,   202,   232,   118,   411,   391,    11,   417,
+     418,   501,   333,   334,    93,   455,   229,   106,   229,   359,
+     539,   232,     9,   232,   229,    29,   611,   585,   137,   232,
+     519,   624,   625,   109,   589,    10,    11,   526,    10,    11,
+     172,   626,   199,   628,   629,  -154,   229,  -267,   455,     9,
+     536,   232,  -267,   203,   118,   568,   118,   456,   413,   412,
+     499,   229,   229,   415,   414,   500,   232,   232,   641,   237,
+     433,    10,    11,   118,   478,   118,   572,   515,     9,   237,
+     165,   118,   513,   411,   492,   275,   406,   204,  -183,   261,
+      11,   465,   164,  -178,   347,     9,   421,   166,    10,    11,
+     357,   358,  -267,   118,  -182,   668,   466,   125,  -267,  -179,
+     498,   131,   126,   587,   279,   118,   126,  -178,   118,   118,
+     216,   630,     9,   596,    94,  -178,   256,    10,    11,   597,
+     227,   518,    95,  -179,   220,   229,    96,   221,   486,   224,
+     232,  -179,   235,   652,    10,    11,    97,    98,   229,   256,
+     484,   483,   251,   232,   252,   487,   485,   128,   229,   627,
+     256,   257,   229,   232,     9,   210,   523,   232,   287,   620,
+     258,    10,    11,   333,   334,    10,    11,   264,   265,    99,
+     441,   532,   229,   229,   266,   288,   598,   232,   232,   265,
+     441,   165,   118,   267,   259,   266,   617,   355,    10,    11,
+     290,   289,   268,   164,   635,   118,   510,   118,   166,    10,
+      11,   636,   517,    10,    11,   118,   356,   211,   211,   118,
+     211,   211,   360,   362,   364,   453,   525,   367,   215,     9,
+     217,   219,   371,   464,   486,     9,   375,   377,   381,   118,
+     118,   383,    12,   385,   588,   387,   484,   483,     9,   395,
+     486,   487,   485,   229,   389,   397,   402,    32,   232,    79,
+     165,   404,   484,   483,   144,    32,   408,   487,   485,   237,
+     148,   416,   164,   112,   618,  -177,   112,   166,    10,    11,
+     129,   419,   112,   173,    10,    11,   422,   448,   435,     9,
+     147,   151,   449,   451,   450,   452,   229,    10,    11,  -177,
+     462,   232,   473,   118,   151,   467,   470,  -177,   471,   256,
+     118,   472,   512,   153,   154,   155,   156,   157,   158,   118,
+     167,   168,   474,   489,   319,   541,   494,   382,  -181,   497,
+     507,   548,   551,   523,   556,   346,   667,   486,    10,    11,
+     509,   346,   346,   561,   257,   563,   229,   178,   514,   484,
+     483,   232,  -181,   118,   487,   485,   516,   186,    10,    11,
+    -181,   190,   524,   342,   237,   245,   195,   196,   197,   198,
+     528,   530,   437,   112,   533,    35,   534,   532,   535,   112,
+      37,   147,   537,   538,   557,   151,   559,   165,   567,   113,
+     576,   560,   466,   571,    47,    48,     9,   573,   578,   164,
+     580,    51,   581,   118,   166,   584,   118,   486,   586,   595,
+     151,   599,   336,   600,  -158,   601,  -159,   153,   157,   484,
+     483,   337,   602,   603,   487,   485,   338,   339,   340,   607,
+     604,    61,   606,   341,   605,   608,   610,   612,   320,   619,
+     342,   631,   609,    64,    79,    10,    11,   633,   634,   646,
+     351,   647,   441,   654,   653,   655,   656,   343,    32,   346,
+     657,   245,   663,   176,  -277,   107,   346,    66,   660,   344,
+     632,   583,   365,   593,   346,   345,   118,   594,    11,   373,
+     407,   124,   354,   374,   508,   548,   640,   496,   245,    79,
+      91,   479,   177,   178,   286,   179,   180,   181,   182,   183,
+     577,   184,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   198,   336,   446,   566,   642,
+     151,   138,   542,   639,  -277,   337,   447,   562,     0,     0,
+     338,   339,   340,   161,  -277,     0,   170,   341,   353,     0,
+       0,     0,     0,     0,   443,     0,     0,     0,     0,     0,
+      35,     0,     0,     0,     0,    37,     0,     0,   169,     0,
+      79,   343,     0,     0,   113,     0,   346,   444,     0,    47,
+      48,     9,   546,   346,     0,   346,    51,     0,     0,   345,
+       0,   457,    11,    55,   346,     0,   346,     0,     0,     0,
+       0,     0,   351,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,     0,    61,     0,     0,     0,
+       0,     0,   245,     0,   481,     0,    62,    63,    64,   493,
+      10,    11,   245,     0,   112,     0,     0,     0,     0,     0,
+       0,     0,   112,     0,     0,     0,   112,     0,     0,   147,
+       0,   151,     0,     0,     0,     0,     0,     0,   294,   295,
+     296,   297,     0,   298,   299,   300,   151,   301,   302,   303,
+     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
+     314,     0,   161,     0,   321,   346,   324,    79,    79,     0,
+     138,   138,   335,   346,     0,   351,   545,     0,   552,     0,
+     346,     0,     0,   457,     0,    35,     0,     0,     0,   457,
+      37,     0,   565,   351,     0,     0,     0,     0,   366,   113,
+       0,     0,    79,     0,    47,    48,     9,   245,   236,     0,
+       0,    51,     0,   346,     0,     0,   546,   346,    55,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+       0,    61,     0,     0,   138,     0,     0,     0,     0,     0,
+       0,    62,    63,    64,   138,    10,    11,    37,     0,     0,
+       0,     0,     0,     0,     0,     0,   113,   346,     0,   346,
+       0,    47,    48,     9,     0,     0,     0,   424,    51,     0,
+       0,   161,    37,     0,     0,   225,     0,   424,     0,     0,
+       0,   113,     0,     0,     0,     0,    47,    48,     9,     0,
+     245,     0,   115,    51,     0,     0,    79,     0,   226,     0,
+     114,     0,     0,   151,   282,     0,     0,     0,     0,     0,
+      64,     0,    10,    11,   283,     0,     0,   115,   351,     0,
+     545,   138,   138,   116,   552,   457,     0,     0,     0,   351,
+     351,     0,     0,     0,     0,    64,     0,    10,    11,    -2,
+      34,     0,    35,     0,     0,    36,     0,    37,    38,    39,
+       0,     0,    40,     0,    41,    42,    43,    44,    45,    46,
+     138,    47,    48,     9,     0,     0,    49,    50,    51,    52,
+      53,    54,     0,     0,   138,    55,     0,     0,     0,     0,
+       0,     0,   161,     0,     0,     0,     0,   170,    56,    57,
+       0,    58,    59,     0,     0,    60,     0,     0,    61,     0,
+       0,   -24,     0,     0,   178,     0,     0,     0,    62,    63,
+      64,     0,    10,    11,   186,     0,     0,     0,   190,   191,
+     192,   193,   194,   195,   196,   197,   198,     0,   569,   570,
+       0,     0,     0,     0,     0,     0,     0,     0,   326,     0,
+      35,     0,     0,    36,  -252,    37,    38,    39,     0,  -252,
+      40,   161,    41,    42,   113,    44,    45,    46,     0,    47,
+      48,     9,     0,     0,    49,    50,    51,    52,    53,    54,
+       0,   424,     0,    55,     0,     0,     0,     0,   424,   591,
+     424,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,     0,    61,     0,     0,  -252,
+       0,     0,     0,     0,   327,  -252,    62,    63,    64,     0,
+      10,    11,     0,     0,     0,     0,   326,     0,    35,     0,
+       0,    36,     0,    37,    38,    39,     0,     0,    40,     0,
+      41,    42,   113,    44,    45,    46,     0,    47,    48,     9,
+       0,     0,    49,    50,    51,    52,    53,    54,   170,     0,
+       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    56,    57,     0,    58,    59,     0,
+       0,    60,     0,     0,    61,   650,   651,  -252,   161,     0,
+       0,     0,   327,  -252,    62,    63,    64,   424,    10,    11,
+      35,     0,     0,     0,     0,    37,     0,     0,     0,     0,
+       0,     0,     0,     0,   113,     0,   336,     0,     0,    47,
+      48,     9,     0,     0,     0,   337,    51,     0,     0,     0,
+     338,   339,   340,   159,     0,     0,     0,   341,     0,     0,
+       0,     0,     0,     0,   342,     0,    56,    57,     0,    58,
+     160,     0,     0,    60,     0,    35,    61,   316,     0,     0,
+      37,   343,     0,     0,     0,     0,    62,    63,    64,   113,
+      10,    11,     0,     0,    47,    48,     9,     0,     0,   345,
+       0,    51,    11,     0,     0,     0,     0,     0,    55,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+      35,    61,     0,     0,     0,    37,     0,     0,     0,   423,
+       0,    62,    63,    64,   113,    10,    11,     0,     0,    47,
+      48,     9,     0,     0,     0,     0,    51,     0,   432,     0,
+       0,     0,     0,   159,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+     160,     0,     0,    60,     0,    35,    61,     0,     0,     0,
+      37,     0,     0,     0,     0,     0,    62,    63,    64,   113,
+      10,    11,     0,     0,    47,    48,     9,     0,   476,     0,
+       0,    51,     0,     0,     0,     0,     0,     0,    55,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+      35,    61,     0,     0,     0,    37,     0,     0,     0,     0,
+       0,    62,    63,    64,   113,    10,    11,     0,     0,    47,
+      48,     9,     0,   477,     0,     0,    51,     0,     0,     0,
+       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    35,     0,     0,    56,    57,    37,    58,
+      59,     0,     0,    60,     0,     0,    61,   113,     0,     0,
+       0,     0,    47,    48,     9,     0,    62,    63,    64,    51,
+      10,    11,     0,     0,     0,     0,    55,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    56,
+      57,     0,    58,    59,     0,     0,    60,     0,    35,    61,
+       0,     0,     0,    37,     0,     0,     0,   590,     0,    62,
+      63,    64,   113,    10,    11,     0,     0,    47,    48,     9,
+       0,     0,     0,     0,    51,     0,     0,     0,     0,     0,
+       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    35,     0,     0,    56,    57,    37,    58,    59,     0,
+       0,    60,     0,     0,    61,   113,     0,     0,     0,     0,
+      47,    48,     9,     0,    62,    63,    64,    51,    10,    11,
+       0,     0,     0,     0,   159,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    35,     0,     0,    56,    57,   285,
+      58,   160,     0,     0,    60,     0,     0,    61,   113,     0,
+       0,     0,     0,    47,    48,     9,     0,    62,    63,    64,
+      51,    10,    11,     0,     0,     0,     0,    55,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      56,    57,    37,    58,    59,     0,     0,    60,     0,     0,
+      61,   113,     0,     0,     0,     0,    47,    48,     9,     0,
+      62,    63,    64,    51,    10,    11,     0,    37,     0,     0,
+     225,     0,     0,     0,     0,    37,   113,     0,   243,     0,
+       0,    47,    48,     9,   113,     0,     0,   115,    51,    47,
+      48,     9,     0,   226,     0,   225,    51,     0,     0,   292,
+       0,    37,     0,   225,     0,    64,     0,    10,    11,   283,
+     113,     0,   115,     0,     0,    47,    48,     9,   226,     0,
+     115,     0,    51,     0,     0,     0,   226,     0,    37,   225,
+      64,     0,    10,    11,   399,     0,     0,   113,    64,     0,
+      10,    11,    47,    48,     9,     0,   115,     0,     0,    51,
+       0,     0,   226,     0,    37,     0,   409,     0,     0,     0,
+       0,     0,   285,   113,    64,     0,    10,    11,    47,    48,
+       9,   113,     0,   115,     0,    51,    47,    48,     9,   410,
+       0,     0,   225,    51,     0,     0,     0,   336,     0,     0,
+     225,    64,     0,    10,    11,   336,   337,     0,   463,   115,
+       0,   338,   339,   544,   337,   480,     0,   115,   341,   338,
+     339,   340,     0,   226,     0,   342,   341,    64,     0,    10,
+      11,   336,     0,   342,     0,    64,     0,    10,    11,     0,
+     337,     0,   343,     0,     0,   338,   339,   340,     0,     0,
+     343,     0,   341,     0,     0,     0,     0,     0,     0,   342,
+     345,     0,    10,    11,     0,     0,     0,     0,   345,   178,
+       0,    11,     0,   181,   182,   183,   343,     0,   185,   186,
+     187,   188,   613,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,     0,     0,   345,   177,   178,    11,   179,     0,
+     181,   182,   183,     0,     0,   185,   186,   187,   188,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   177,   178,
+       0,   179,     0,   181,   182,   183,     0,   437,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,     0,     0,     0,     0,     0,     0,   177,   178,
+       0,   179,     0,   181,   182,   183,     0,   434,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,   177,   178,     0,   179,     0,   181,   182,   183,
+       0,   527,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   198,   177,   178,     0,   179,
+       0,   181,   182,   183,     0,   661,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,   195,   196,   197,   198,
+     177,   178,     0,   179,     0,   181,   182,   183,     0,   662,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+     195,   196,   197,   198,   177,   178,     0,     0,     0,   181,
+     182,   183,     0,     0,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,   195,   196,   197,   198,   177,   178,
+       0,     0,     0,   181,   182,   183,     0,     0,   185,   186,
+     187,   188,     0,   190,   191,   192,   193,   194,   195,   196,
+     197,   198
+};
+
+static const yytype_int16 yycheck[] =
+{
+      37,    37,    61,   143,    67,    37,    37,   202,   380,   205,
+     224,   148,    61,   448,   144,   127,    28,   489,   456,    67,
+     127,   133,   252,   325,    61,   114,   115,   116,   136,    61,
+      31,   143,   323,    36,     3,    51,    39,   251,    11,     5,
+      24,   260,    45,    49,    35,   392,     7,    25,   137,    35,
+     269,    12,     5,   400,   265,   266,   145,    37,   277,     3,
+       1,    35,   281,   152,   318,     0,    24,    83,    59,    62,
+     324,     3,   291,    89,    25,    68,    67,   114,   115,   116,
+      24,    67,   114,   115,   116,    59,   175,     3,    24,    73,
+       1,   128,    24,    67,    35,    53,   128,    20,     3,    65,
+     137,    62,    75,    72,   576,   137,   107,    68,   145,    75,
+     173,   160,    65,   145,    62,   152,    60,   464,    59,    63,
+     152,   127,    75,   160,    35,   173,    67,    59,   160,    73,
+      74,    63,   600,   136,   114,   115,   116,   226,   175,   142,
+       7,    73,    74,   175,    67,    12,    62,    63,   128,   257,
+     441,   200,    68,    62,   243,     3,    67,   137,     3,    68,
+     507,     5,    24,   200,    21,   145,   601,    63,   200,    24,
+     608,   385,   152,   427,   646,   429,    24,   612,   613,    24,
+     391,    59,   393,    59,   273,    63,   654,   224,   656,   226,
+      62,     3,   224,    71,   226,   175,   285,    59,    74,   288,
+     289,    68,   208,   209,    62,    50,   243,     3,   245,   221,
+     440,   243,    24,   245,   251,    63,   563,   519,    71,   251,
+     416,    65,    66,     3,   526,    73,    74,   423,    73,    74,
+      62,    75,    67,   580,   581,    66,   273,     7,    50,    24,
+     435,   273,    12,    66,   224,   475,   226,    59,   285,   285,
+       7,   288,   289,   285,   285,    12,   288,   289,   605,   371,
+     319,    73,    74,   243,   371,   245,   480,   404,    24,   381,
+     319,   251,   402,   362,   381,    60,   282,    59,    59,   387,
+      74,    60,   319,    35,   212,    24,   292,   319,    73,    74,
+     218,   219,    62,   273,    59,   667,    75,    40,    68,    35,
+     389,    44,    40,   522,    60,   285,    44,    59,   288,   289,
+      24,    68,    24,    66,     9,    67,    24,    73,    74,    72,
+     409,   410,    17,    59,    64,   362,    21,    62,   377,    59,
+     362,    67,    63,   635,    73,    74,    31,    32,   375,    24,
+     377,   377,    59,   375,    67,   377,   377,    59,   385,   579,
+      24,    59,   389,   385,    24,    75,   419,   389,    60,   573,
+      68,    73,    74,   369,   370,    73,    74,    35,    53,    64,
+      62,   430,   409,   410,    59,    72,    68,   409,   410,    53,
+      62,   430,   362,    68,   387,    59,    68,    59,    73,    74,
+      60,    72,   395,   430,   590,   375,   399,   377,   430,    73,
+      74,   596,   408,    73,    74,   385,     3,    94,    95,   389,
+      97,    98,    60,     8,    60,   343,   422,    35,    95,    24,
+      97,    98,    62,   351,   473,    24,    75,    60,    62,   409,
+     410,    24,     5,    59,   523,    62,   473,   473,    24,    62,
+     489,   473,   473,   480,    72,     3,    62,    20,   480,    22,
+     499,    62,   489,   489,    59,    28,    65,   489,   489,   571,
+      59,    67,   499,    36,   571,    35,    39,   499,    73,    74,
+      43,    62,    45,    59,    73,    74,    65,    59,    66,    24,
+      53,    54,    67,    67,    71,     8,   523,    73,    74,    59,
+      65,   523,    60,   473,    67,    62,    62,    67,    62,    24,
+     480,    62,    35,    55,    56,    57,    58,    59,    60,   489,
+      62,    63,    60,    60,    59,   443,    60,    63,    35,    68,
+      60,   449,   450,   586,   452,   212,   666,   576,    73,    74,
+      68,   218,   219,   461,    59,   463,   573,    34,    60,   576,
+     576,   573,    59,   523,   576,   576,    60,    44,    73,    74,
+      67,    48,    60,    36,   666,   128,    53,    54,    55,    56,
+      75,    68,    75,   136,    60,     3,    60,   626,    60,   142,
+       8,   144,    60,    68,     3,   148,    62,   626,    60,    17,
+      60,    72,    75,    62,    22,    23,    24,    59,    66,   626,
+      60,    29,    60,   573,   626,    60,   576,   646,    62,    60,
+     173,    60,     8,    60,    59,    59,    59,   159,   160,   646,
+     646,    17,    68,    62,   646,   646,    22,    23,    24,    62,
+      72,    59,    68,    29,   552,    49,    62,    59,   201,    60,
+      36,    68,   560,    71,   207,    73,    74,    60,    68,    60,
+     213,    14,    62,    60,    72,    60,    60,    53,   221,   336,
+      60,   224,    68,     4,     5,    31,   343,    22,   647,    65,
+     586,   512,   235,   528,   351,    71,   646,   528,    74,   245,
+     283,    39,   214,   245,   395,   603,   604,   387,   251,   252,
+      22,   375,    33,    34,   160,    36,    37,    38,    39,    40,
+     499,    42,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,     8,   336,   466,   607,
+     283,    49,   444,   603,    65,    17,   336,   462,    -1,    -1,
+      22,    23,    24,    61,    75,    -1,    64,    29,   213,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
+       3,    -1,    -1,    -1,    -1,     8,    -1,    -1,    11,    -1,
+     323,    53,    -1,    -1,    17,    -1,   443,    59,    -1,    22,
+      23,    24,   449,   450,    -1,   452,    29,    -1,    -1,    71,
+      -1,   344,    74,    36,   461,    -1,   463,    -1,    -1,    -1,
+      -1,    -1,   355,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    -1,    -1,    -1,
+      -1,    -1,   375,    -1,   377,    -1,    69,    70,    71,   382,
+      73,    74,   385,    -1,   387,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   395,    -1,    -1,    -1,   399,    -1,    -1,   402,
+      -1,   404,    -1,    -1,    -1,    -1,    -1,    -1,   176,   177,
+     178,   179,    -1,   181,   182,   183,   419,   185,   186,   187,
+     188,   189,   190,   191,   192,   193,   194,   195,   196,   197,
+     198,    -1,   200,    -1,   202,   552,   204,   440,   441,    -1,
+     208,   209,   210,   560,    -1,   448,   449,    -1,   451,    -1,
+     567,    -1,    -1,   456,    -1,     3,    -1,    -1,    -1,   462,
+       8,    -1,   465,   466,    -1,    -1,    -1,    -1,   236,    17,
+      -1,    -1,   475,    -1,    22,    23,    24,   480,    26,    -1,
+      -1,    29,    -1,   600,    -1,    -1,   603,   604,    36,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+      -1,    59,    -1,    -1,   282,    -1,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,   292,    73,    74,     8,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    17,   654,    -1,   656,
+      -1,    22,    23,    24,    -1,    -1,    -1,   315,    29,    -1,
+      -1,   319,     8,    -1,    -1,    36,    -1,   325,    -1,    -1,
+      -1,    17,    -1,    -1,    -1,    -1,    22,    23,    24,    -1,
+     573,    -1,    53,    29,    -1,    -1,   579,    -1,    59,    -1,
+      36,    -1,    -1,   586,    65,    -1,    -1,    -1,    -1,    -1,
+      71,    -1,    73,    74,    75,    -1,    -1,    53,   601,    -1,
+     603,   369,   370,    59,   607,   608,    -1,    -1,    -1,   612,
+     613,    -1,    -1,    -1,    -1,    71,    -1,    73,    74,     0,
+       1,    -1,     3,    -1,    -1,     6,    -1,     8,     9,    10,
+      -1,    -1,    13,    -1,    15,    16,    17,    18,    19,    20,
+     408,    22,    23,    24,    -1,    -1,    27,    28,    29,    30,
+      31,    32,    -1,    -1,   422,    36,    -1,    -1,    -1,    -1,
+      -1,    -1,   430,    -1,    -1,    -1,    -1,   435,    49,    50,
+      -1,    52,    53,    -1,    -1,    56,    -1,    -1,    59,    -1,
+      -1,    62,    -1,    -1,    34,    -1,    -1,    -1,    69,    70,
+      71,    -1,    73,    74,    44,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,   476,   477,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     1,    -1,
+       3,    -1,    -1,     6,     7,     8,     9,    10,    -1,    12,
+      13,   499,    15,    16,    17,    18,    19,    20,    -1,    22,
+      23,    24,    -1,    -1,    27,    28,    29,    30,    31,    32,
+      -1,   519,    -1,    36,    -1,    -1,    -1,    -1,   526,   527,
+     528,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    -1,    -1,    62,
+      -1,    -1,    -1,    -1,    67,    68,    69,    70,    71,    -1,
+      73,    74,    -1,    -1,    -1,    -1,     1,    -1,     3,    -1,
+      -1,     6,    -1,     8,     9,    10,    -1,    -1,    13,    -1,
+      15,    16,    17,    18,    19,    20,    -1,    22,    23,    24,
+      -1,    -1,    27,    28,    29,    30,    31,    32,   596,    -1,
+      -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,
+      -1,    56,    -1,    -1,    59,   623,   624,    62,   626,    -1,
+      -1,    -1,    67,    68,    69,    70,    71,   635,    73,    74,
+       3,    -1,    -1,    -1,    -1,     8,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    17,    -1,     8,    -1,    -1,    22,
+      23,    24,    -1,    -1,    -1,    17,    29,    -1,    -1,    -1,
+      22,    23,    24,    36,    -1,    -1,    -1,    29,    -1,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    60,    -1,    -1,
+       8,    53,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    71,
+      -1,    29,    74,    -1,    -1,    -1,    -1,    -1,    36,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    -1,    -1,    -1,     8,    -1,    -1,    -1,    67,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
+      23,    24,    -1,    -1,    -1,    -1,    29,    -1,    31,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,    -1,
+       8,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    26,    -1,
+      -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    -1,    -1,    -1,     8,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
+      23,    24,    -1,    26,    -1,    -1,    29,    -1,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,     3,    -1,    -1,    49,    50,     8,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    17,    -1,    -1,
+      -1,    -1,    22,    23,    24,    -1,    69,    70,    71,    29,
+      73,    74,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,
+      50,    -1,    52,    53,    -1,    -1,    56,    -1,     3,    59,
+      -1,    -1,    -1,     8,    -1,    -1,    -1,    67,    -1,    69,
+      70,    71,    17,    73,    74,    -1,    -1,    22,    23,    24,
+      -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,
+      -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,    -1,    -1,    49,    50,     8,    52,    53,    -1,
+      -1,    56,    -1,    -1,    59,    17,    -1,    -1,    -1,    -1,
+      22,    23,    24,    -1,    69,    70,    71,    29,    73,    74,
+      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,    -1,    -1,    49,    50,     8,
+      52,    53,    -1,    -1,    56,    -1,    -1,    59,    17,    -1,
+      -1,    -1,    -1,    22,    23,    24,    -1,    69,    70,    71,
+      29,    73,    74,    -1,    -1,    -1,    -1,    36,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      49,    50,     8,    52,    53,    -1,    -1,    56,    -1,    -1,
+      59,    17,    -1,    -1,    -1,    -1,    22,    23,    24,    -1,
+      69,    70,    71,    29,    73,    74,    -1,     8,    -1,    -1,
+      36,    -1,    -1,    -1,    -1,     8,    17,    -1,    11,    -1,
+      -1,    22,    23,    24,    17,    -1,    -1,    53,    29,    22,
+      23,    24,    -1,    59,    -1,    36,    29,    -1,    -1,    65,
+      -1,     8,    -1,    36,    -1,    71,    -1,    73,    74,    75,
+      17,    -1,    53,    -1,    -1,    22,    23,    24,    59,    -1,
+      53,    -1,    29,    -1,    -1,    -1,    59,    -1,     8,    36,
+      71,    -1,    73,    74,    75,    -1,    -1,    17,    71,    -1,
+      73,    74,    22,    23,    24,    -1,    53,    -1,    -1,    29,
+      -1,    -1,    59,    -1,     8,    -1,    36,    -1,    -1,    -1,
+      -1,    -1,     8,    17,    71,    -1,    73,    74,    22,    23,
+      24,    17,    -1,    53,    -1,    29,    22,    23,    24,    59,
+      -1,    -1,    36,    29,    -1,    -1,    -1,     8,    -1,    -1,
+      36,    71,    -1,    73,    74,     8,    17,    -1,    11,    53,
+      -1,    22,    23,    24,    17,    59,    -1,    53,    29,    22,
+      23,    24,    -1,    59,    -1,    36,    29,    71,    -1,    73,
+      74,     8,    -1,    36,    -1,    71,    -1,    73,    74,    -1,
+      17,    -1,    53,    -1,    -1,    22,    23,    24,    -1,    -1,
+      53,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,
+      71,    -1,    73,    74,    -1,    -1,    -1,    -1,    71,    34,
+      -1,    74,    -1,    38,    39,    40,    53,    -1,    43,    44,
+      45,    46,    59,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    -1,    71,    33,    34,    74,    36,    -1,
+      38,    39,    40,    -1,    -1,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,
+      -1,    36,    -1,    38,    39,    40,    -1,    75,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,
+      -1,    36,    -1,    38,    39,    40,    -1,    72,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    33,    34,    -1,    36,    -1,    38,    39,    40,
+      -1,    66,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    33,    34,    -1,    36,
+      -1,    38,    39,    40,    -1,    66,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      33,    34,    -1,    36,    -1,    38,    39,    40,    -1,    66,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    33,    34,    -1,    -1,    -1,    38,
+      39,    40,    -1,    -1,    43,    44,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    33,    34,
+      -1,    -1,    -1,    38,    39,    40,    -1,    -1,    43,    44,
+      45,    46,    -1,    48,    49,    50,    51,    52,    53,    54,
+      55,    56
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    77,    79,    80,     0,    25,    78,    25,    86,    24,
+      73,    74,   141,   142,    81,    24,    88,    89,     3,    62,
+      21,    82,   166,    24,    87,   214,    63,     3,    59,    63,
+      83,    85,   141,    62,     1,     3,     6,     8,     9,    10,
+      13,    15,    16,    17,    18,    19,    20,    22,    23,    27,
+      28,    29,    30,    31,    32,    36,    49,    50,    52,    53,
+      56,    59,    69,    70,    71,    90,    91,    92,    98,   110,
+     113,   121,   124,   126,   127,   128,   129,   134,   138,   141,
+     143,   144,   149,   150,   153,   156,   157,   158,   161,   164,
+     165,   181,   186,    62,     9,    17,    21,    31,    32,    64,
+     199,    24,    73,    60,    83,    84,     3,    86,    88,     3,
+     138,   140,   141,    17,    36,    53,    59,   141,   143,   148,
+     152,   153,   154,   161,   140,   128,   134,   111,    59,   141,
+     159,   128,   138,   114,    35,    67,   137,    71,   126,   186,
+     193,   125,   137,   122,    59,    96,    97,   141,    59,    93,
+     139,   141,   185,   127,   127,   127,   127,   127,   127,    36,
+      53,   126,   135,   147,   153,   155,   161,   127,   127,    11,
+     126,   192,    62,    59,    94,   185,     4,    33,    34,    36,
+      37,    38,    39,    40,    42,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    67,
+      59,    63,    71,    66,    59,   137,     1,   137,     5,    65,
+      75,   142,   200,    59,   160,   200,    24,   200,   201,   200,
+      64,    62,   190,    88,    59,    36,    59,   146,   152,   153,
+     154,   155,   161,   146,   146,    63,    26,    98,   107,   108,
+     109,   186,   194,    11,   136,   141,   145,   146,   177,   178,
+     179,    59,    67,   162,   112,   194,    24,    59,    68,   138,
+     171,   173,   175,   146,    35,    53,    59,    68,   138,   170,
+     172,   173,   174,   184,   112,    60,    97,   169,   146,    60,
+      93,   167,    65,    75,   146,     8,   147,    60,    72,    72,
+      60,    94,    65,   146,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   130,    60,   135,   187,    59,
+     141,   126,   192,   182,   126,   130,     1,    67,    91,   100,
+     180,   181,   183,   186,   186,   126,     8,    17,    22,    23,
+      24,    29,    36,    53,    65,    71,   142,   202,   204,   205,
+     206,   141,   207,   215,   162,    59,     3,   202,   202,    83,
+      60,   179,     8,   146,    60,   141,   126,    35,   105,     5,
+      65,    62,   146,   136,   145,    75,   191,    60,   179,   183,
+     115,    62,    63,    24,   173,    59,   176,    62,   190,    72,
+     104,    59,   174,    53,   174,    62,   190,     3,   198,    75,
+     146,   123,    62,   190,    62,   190,   186,   139,    65,    36,
+      59,   146,   152,   153,   154,   161,    67,   146,   146,    62,
+     190,   186,    65,    67,   126,   131,   132,   188,   189,    11,
+      75,   191,    31,   135,    72,    66,   180,    75,   191,   189,
+     101,    62,    68,    36,    59,   203,   204,   206,    59,    67,
+      71,    67,     8,   202,     3,    50,    59,   141,   212,   213,
+       3,    72,    65,    11,   202,    60,    75,    62,   195,   215,
+      62,    62,    62,    60,    60,   106,    26,    26,   194,   177,
+      59,   141,   151,   152,   153,   154,   155,   161,   163,    60,
+      68,   105,   194,   141,    60,   179,   175,    68,   146,     7,
+      12,    68,    99,   102,   174,   198,   174,    60,   172,    68,
+     138,   198,    35,    97,    60,    93,    60,   186,   146,   130,
+      94,    95,   168,   185,    60,   186,   130,    66,    75,   191,
+      68,   191,   135,    60,    60,    60,   192,    60,    68,   183,
+     180,   202,   205,   195,    24,   141,   142,   197,   202,   209,
+     217,   202,   141,   196,   208,   216,   202,     3,   212,    62,
+      72,   202,   213,   202,   198,   141,   207,    60,   183,   126,
+     126,    62,   179,    59,   163,   116,    60,   187,    66,   103,
+      60,    60,   198,   104,    60,   189,    62,   190,   146,   189,
+      67,   126,   133,   131,   132,    60,    66,    72,    68,    60,
+      60,    59,    68,    62,    72,   202,    68,    62,    49,   202,
+      62,   198,    59,    59,   202,   210,   211,    68,   194,    60,
+     179,   119,   163,     5,    65,    66,    75,   183,   198,   198,
+      68,    68,    95,    60,    68,   130,   192,   210,   195,   209,
+     202,   198,   208,   212,   195,   195,    60,    14,   117,   120,
+     126,   126,   189,    72,    60,    60,    60,    60,   163,    20,
+     100,    66,    66,    68,   210,   210,   118,   112,   105
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar, yystate;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 128 "go.y"
+    {
+		xtop = concat(xtop, (yyvsp[(4) - (4)].list));
+	}
+    break;
+
+  case 3:
+#line 134 "go.y"
+    {
+		prevlineno = lineno;
+		yyerror("package statement must be first");
+		errorexit();
+	}
+    break;
+
+  case 4:
+#line 140 "go.y"
+    {
+		mkpackage((yyvsp[(2) - (3)].sym)->name);
+	}
+    break;
+
+  case 5:
+#line 150 "go.y"
+    {
+		importpkg = runtimepkg;
+
+		if(debug['A'])
+			cannedimports("runtime.builtin", "package runtime\n\n$$\n\n");
+		else
+			cannedimports("runtime.builtin", runtimeimport);
+		curio.importsafe = 1;
+	}
+    break;
+
+  case 6:
+#line 161 "go.y"
+    {
+		importpkg = nil;
+	}
+    break;
+
+  case 12:
+#line 175 "go.y"
+    {
+		Pkg *ipkg;
+		Sym *my;
+		Node *pack;
+		
+		ipkg = importpkg;
+		my = importmyname;
+		importpkg = nil;
+		importmyname = S;
+
+		if(my == nil)
+			my = lookup(ipkg->name);
+
+		pack = nod(OPACK, N, N);
+		pack->sym = my;
+		pack->pkg = ipkg;
+		pack->lineno = (yyvsp[(1) - (3)].i);
+
+		if(my->name[0] == '.') {
+			importdot(ipkg, pack);
+			break;
+		}
+		if(strcmp(my->name, "init") == 0) {
+			yyerror("cannot import package as init - init must be a func");
+			break;
+		}
+		if(my->name[0] == '_' && my->name[1] == '\0')
+			break;
+		if(my->def) {
+			lineno = (yyvsp[(1) - (3)].i);
+			redeclare(my, "as imported package name");
+		}
+		my->def = pack;
+		my->lastlineno = (yyvsp[(1) - (3)].i);
+		my->block = 1;	// at top level
+	}
+    break;
+
+  case 13:
+#line 212 "go.y"
+    {
+		// When an invalid import path is passed to importfile,
+		// it calls yyerror and then sets up a fake import with
+		// no package statement. This allows us to test more
+		// than one invalid import statement in a single file.
+		if(nerrors == 0)
+			fatal("phase error in import");
+	}
+    break;
+
+  case 16:
+#line 227 "go.y"
+    {
+		// import with original name
+		(yyval.i) = parserline();
+		importmyname = S;
+		importfile(&(yyvsp[(1) - (1)].val), (yyval.i));
+	}
+    break;
+
+  case 17:
+#line 234 "go.y"
+    {
+		// import with given name
+		(yyval.i) = parserline();
+		importmyname = (yyvsp[(1) - (2)].sym);
+		importfile(&(yyvsp[(2) - (2)].val), (yyval.i));
+	}
+    break;
+
+  case 18:
+#line 241 "go.y"
+    {
+		// import into my name space
+		(yyval.i) = parserline();
+		importmyname = lookup(".");
+		importfile(&(yyvsp[(2) - (2)].val), (yyval.i));
+	}
+    break;
+
+  case 19:
+#line 250 "go.y"
+    {
+		if(importpkg->name == nil) {
+			importpkg->name = (yyvsp[(2) - (4)].sym)->name;
+			pkglookup((yyvsp[(2) - (4)].sym)->name, nil)->npkg++;
+		} else if(strcmp(importpkg->name, (yyvsp[(2) - (4)].sym)->name) != 0)
+			yyerror("conflicting names %s and %s for package \"%Z\"", importpkg->name, (yyvsp[(2) - (4)].sym)->name, importpkg->path);
+		importpkg->direct = 1;
+		importpkg->safe = curio.importsafe;
+
+		if(safemode && !curio.importsafe)
+			yyerror("cannot import unsafe package \"%Z\"", importpkg->path);
+	}
+    break;
+
+  case 21:
+#line 265 "go.y"
+    {
+		if(strcmp((yyvsp[(1) - (1)].sym)->name, "safe") == 0)
+			curio.importsafe = 1;
+	}
+    break;
+
+  case 22:
+#line 271 "go.y"
+    {
+		defercheckwidth();
+	}
+    break;
+
+  case 23:
+#line 275 "go.y"
+    {
+		resumecheckwidth();
+		unimportfile();
+	}
+    break;
+
+  case 24:
+#line 284 "go.y"
+    {
+		yyerror("empty top-level declaration");
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 26:
+#line 290 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 27:
+#line 294 "go.y"
+    {
+		yyerror("non-declaration statement outside function body");
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 28:
+#line 299 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 29:
+#line 305 "go.y"
+    {
+		(yyval.list) = (yyvsp[(2) - (2)].list);
+	}
+    break;
+
+  case 30:
+#line 309 "go.y"
+    {
+		(yyval.list) = (yyvsp[(3) - (5)].list);
+	}
+    break;
+
+  case 31:
+#line 313 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 32:
+#line 317 "go.y"
+    {
+		(yyval.list) = (yyvsp[(2) - (2)].list);
+		iota = -100000;
+		lastconst = nil;
+	}
+    break;
+
+  case 33:
+#line 323 "go.y"
+    {
+		(yyval.list) = (yyvsp[(3) - (5)].list);
+		iota = -100000;
+		lastconst = nil;
+	}
+    break;
+
+  case 34:
+#line 329 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(3) - (7)].list), (yyvsp[(5) - (7)].list));
+		iota = -100000;
+		lastconst = nil;
+	}
+    break;
+
+  case 35:
+#line 335 "go.y"
+    {
+		(yyval.list) = nil;
+		iota = -100000;
+	}
+    break;
+
+  case 36:
+#line 340 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(2) - (2)].node));
+	}
+    break;
+
+  case 37:
+#line 344 "go.y"
+    {
+		(yyval.list) = (yyvsp[(3) - (5)].list);
+	}
+    break;
+
+  case 38:
+#line 348 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 39:
+#line 354 "go.y"
+    {
+		iota = 0;
+	}
+    break;
+
+  case 40:
+#line 360 "go.y"
+    {
+		(yyval.list) = variter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
+	}
+    break;
+
+  case 41:
+#line 364 "go.y"
+    {
+		(yyval.list) = variter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
+	}
+    break;
+
+  case 42:
+#line 368 "go.y"
+    {
+		(yyval.list) = variter((yyvsp[(1) - (3)].list), nil, (yyvsp[(3) - (3)].list));
+	}
+    break;
+
+  case 43:
+#line 374 "go.y"
+    {
+		(yyval.list) = constiter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
+	}
+    break;
+
+  case 44:
+#line 378 "go.y"
+    {
+		(yyval.list) = constiter((yyvsp[(1) - (3)].list), N, (yyvsp[(3) - (3)].list));
+	}
+    break;
+
+  case 46:
+#line 385 "go.y"
+    {
+		(yyval.list) = constiter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
+	}
+    break;
+
+  case 47:
+#line 389 "go.y"
+    {
+		(yyval.list) = constiter((yyvsp[(1) - (1)].list), N, nil);
+	}
+    break;
+
+  case 48:
+#line 395 "go.y"
+    {
+		// different from dclname because the name
+		// becomes visible right here, not at the end
+		// of the declaration.
+		(yyval.node) = typedcl0((yyvsp[(1) - (1)].sym));
+	}
+    break;
+
+  case 49:
+#line 404 "go.y"
+    {
+		(yyval.node) = typedcl1((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node), 1);
+	}
+    break;
+
+  case 50:
+#line 410 "go.y"
+    {
+		(yyval.node) = (yyvsp[(1) - (1)].node);
+
+		// These nodes do not carry line numbers.
+		// Since a bare name used as an expression is an error,
+		// introduce a wrapper node to give the correct line.
+		switch((yyval.node)->op) {
+		case ONAME:
+		case ONONAME:
+		case OTYPE:
+		case OPACK:
+		case OLITERAL:
+			(yyval.node) = nod(OPAREN, (yyval.node), N);
+			(yyval.node)->implicit = 1;
+			break;
+		}
+	}
+    break;
+
+  case 51:
+#line 428 "go.y"
+    {
+		(yyval.node) = nod(OASOP, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+		(yyval.node)->etype = (yyvsp[(2) - (3)].i);			// rathole to pass opcode
+	}
+    break;
+
+  case 52:
+#line 433 "go.y"
+    {
+		if((yyvsp[(1) - (3)].list)->next == nil && (yyvsp[(3) - (3)].list)->next == nil) {
+			// simple
+			(yyval.node) = nod(OAS, (yyvsp[(1) - (3)].list)->n, (yyvsp[(3) - (3)].list)->n);
+			break;
+		}
+		// multiple
+		(yyval.node) = nod(OAS2, N, N);
+		(yyval.node)->list = (yyvsp[(1) - (3)].list);
+		(yyval.node)->rlist = (yyvsp[(3) - (3)].list);
+	}
+    break;
+
+  case 53:
+#line 445 "go.y"
+    {
+		if((yyvsp[(3) - (3)].list)->n->op == OTYPESW) {
+			(yyval.node) = nod(OTYPESW, N, (yyvsp[(3) - (3)].list)->n->right);
+			if((yyvsp[(3) - (3)].list)->next != nil)
+				yyerror("expr.(type) must be alone in list");
+			if((yyvsp[(1) - (3)].list)->next != nil)
+				yyerror("argument count mismatch: %d = %d", count((yyvsp[(1) - (3)].list)), 1);
+			else if(((yyvsp[(1) - (3)].list)->n->op != ONAME && (yyvsp[(1) - (3)].list)->n->op != OTYPE && (yyvsp[(1) - (3)].list)->n->op != ONONAME) || isblank((yyvsp[(1) - (3)].list)->n))
+				yyerror("invalid variable name %N in type switch", (yyvsp[(1) - (3)].list)->n);
+			else
+				(yyval.node)->left = dclname((yyvsp[(1) - (3)].list)->n->sym);  // it's a colas, so must not re-use an oldname.
+			break;
+		}
+		(yyval.node) = colas((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list), (yyvsp[(2) - (3)].i));
+	}
+    break;
+
+  case 54:
+#line 461 "go.y"
+    {
+		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
+		(yyval.node)->implicit = 1;
+		(yyval.node)->etype = OADD;
+	}
+    break;
+
+  case 55:
+#line 467 "go.y"
+    {
+		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
+		(yyval.node)->implicit = 1;
+		(yyval.node)->etype = OSUB;
+	}
+    break;
+
+  case 56:
+#line 475 "go.y"
+    {
+		Node *n, *nn;
+
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		(yyval.node) = nod(OXCASE, N, N);
+		(yyval.node)->list = (yyvsp[(2) - (3)].list);
+		if(typesw != N && typesw->right != N && (n=typesw->right->left) != N) {
+			// type switch - declare variable
+			nn = newname(n->sym);
+			declare(nn, dclcontext);
+			(yyval.node)->nname = nn;
+
+			// keep track of the instances for reporting unused
+			nn->defn = typesw->right;
+		}
+	}
+    break;
+
+  case 57:
+#line 495 "go.y"
+    {
+		Node *n;
+
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		(yyval.node) = nod(OXCASE, N, N);
+		if((yyvsp[(2) - (5)].list)->next == nil)
+			n = nod(OAS, (yyvsp[(2) - (5)].list)->n, (yyvsp[(4) - (5)].node));
+		else {
+			n = nod(OAS2, N, N);
+			n->list = (yyvsp[(2) - (5)].list);
+			n->rlist = list1((yyvsp[(4) - (5)].node));
+		}
+		(yyval.node)->list = list1(n);
+	}
+    break;
+
+  case 58:
+#line 513 "go.y"
+    {
+		// will be converted to OCASE
+		// right will point to next case
+		// done in casebody()
+		markdcl();
+		(yyval.node) = nod(OXCASE, N, N);
+		(yyval.node)->list = list1(colas((yyvsp[(2) - (5)].list), list1((yyvsp[(4) - (5)].node)), (yyvsp[(3) - (5)].i)));
+	}
+    break;
+
+  case 59:
+#line 522 "go.y"
+    {
+		Node *n, *nn;
+
+		markdcl();
+		(yyval.node) = nod(OXCASE, N, N);
+		if(typesw != N && typesw->right != N && (n=typesw->right->left) != N) {
+			// type switch - declare variable
+			nn = newname(n->sym);
+			declare(nn, dclcontext);
+			(yyval.node)->nname = nn;
+
+			// keep track of the instances for reporting unused
+			nn->defn = typesw->right;
+		}
+	}
+    break;
+
+  case 60:
+#line 540 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 61:
+#line 544 "go.y"
+    {
+		if((yyvsp[(3) - (4)].list) == nil)
+			(yyval.node) = nod(OEMPTY, N, N);
+		else
+			(yyval.node) = liststmt((yyvsp[(3) - (4)].list));
+		popdcl();
+	}
+    break;
+
+  case 62:
+#line 554 "go.y"
+    {
+		// If the last token read by the lexer was consumed
+		// as part of the case, clear it (parser has cleared yychar).
+		// If the last token read by the lexer was the lookahead
+		// leave it alone (parser has it cached in yychar).
+		// This is so that the stmt_list action doesn't look at
+		// the case tokens if the stmt_list is empty.
+		yylast = yychar;
+		(yyvsp[(1) - (1)].node)->xoffset = block;
+	}
+    break;
+
+  case 63:
+#line 565 "go.y"
+    {
+		int last;
+
+		// This is the only place in the language where a statement
+		// list is not allowed to drop the final semicolon, because
+		// it's the only place where a statement list is not followed 
+		// by a closing brace.  Handle the error for pedantry.
+
+		// Find the final token of the statement list.
+		// yylast is lookahead; yyprev is last of stmt_list
+		last = yyprev;
+
+		if(last > 0 && last != ';' && yychar != '}')
+			yyerror("missing statement after label");
+		(yyval.node) = (yyvsp[(1) - (3)].node);
+		(yyval.node)->nbody = (yyvsp[(3) - (3)].list);
+		popdcl();
+	}
+    break;
+
+  case 64:
+#line 585 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 65:
+#line 589 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
+	}
+    break;
+
+  case 66:
+#line 595 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 67:
+#line 599 "go.y"
+    {
+		(yyval.list) = (yyvsp[(3) - (4)].list);
+		popdcl();
+	}
+    break;
+
+  case 68:
+#line 606 "go.y"
+    {
+		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
+		(yyval.node)->list = (yyvsp[(1) - (4)].list);
+		(yyval.node)->etype = 0;	// := flag
+	}
+    break;
+
+  case 69:
+#line 612 "go.y"
+    {
+		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
+		(yyval.node)->list = (yyvsp[(1) - (4)].list);
+		(yyval.node)->colas = 1;
+		colasdefn((yyvsp[(1) - (4)].list), (yyval.node));
+	}
+    break;
+
+  case 70:
+#line 619 "go.y"
+    {
+		(yyval.node) = nod(ORANGE, N, (yyvsp[(2) - (2)].node));
+		(yyval.node)->etype = 0; // := flag
+	}
+    break;
+
+  case 71:
+#line 626 "go.y"
+    {
+		// init ; test ; incr
+		if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
+			yyerror("cannot declare in the for-increment");
+		(yyval.node) = nod(OFOR, N, N);
+		if((yyvsp[(1) - (5)].node) != N)
+			(yyval.node)->ninit = list1((yyvsp[(1) - (5)].node));
+		(yyval.node)->ntest = (yyvsp[(3) - (5)].node);
+		(yyval.node)->nincr = (yyvsp[(5) - (5)].node);
+	}
+    break;
+
+  case 72:
+#line 637 "go.y"
+    {
+		// normal test
+		(yyval.node) = nod(OFOR, N, N);
+		(yyval.node)->ntest = (yyvsp[(1) - (1)].node);
+	}
+    break;
+
+  case 74:
+#line 646 "go.y"
+    {
+		(yyval.node) = (yyvsp[(1) - (2)].node);
+		(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
+	}
+    break;
+
+  case 75:
+#line 653 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 76:
+#line 657 "go.y"
+    {
+		(yyval.node) = (yyvsp[(3) - (3)].node);
+		popdcl();
+	}
+    break;
+
+  case 77:
+#line 664 "go.y"
+    {
+		// test
+		(yyval.node) = nod(OIF, N, N);
+		(yyval.node)->ntest = (yyvsp[(1) - (1)].node);
+	}
+    break;
+
+  case 78:
+#line 670 "go.y"
+    {
+		// init ; test
+		(yyval.node) = nod(OIF, N, N);
+		if((yyvsp[(1) - (3)].node) != N)
+			(yyval.node)->ninit = list1((yyvsp[(1) - (3)].node));
+		(yyval.node)->ntest = (yyvsp[(3) - (3)].node);
+	}
+    break;
+
+  case 79:
+#line 681 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 80:
+#line 685 "go.y"
+    {
+		if((yyvsp[(3) - (3)].node)->ntest == N)
+			yyerror("missing condition in if statement");
+	}
+    break;
+
+  case 81:
+#line 690 "go.y"
+    {
+		(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
+	}
+    break;
+
+  case 82:
+#line 694 "go.y"
+    {
+		Node *n;
+		NodeList *nn;
+
+		(yyval.node) = (yyvsp[(3) - (8)].node);
+		n = (yyvsp[(3) - (8)].node);
+		popdcl();
+		for(nn = concat((yyvsp[(7) - (8)].list), (yyvsp[(8) - (8)].list)); nn; nn = nn->next) {
+			if(nn->n->op == OIF)
+				popdcl();
+			n->nelse = list1(nn->n);
+			n = nn->n;
+		}
+	}
+    break;
+
+  case 83:
+#line 711 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 84:
+#line 715 "go.y"
+    {
+		if((yyvsp[(4) - (5)].node)->ntest == N)
+			yyerror("missing condition in if statement");
+		(yyvsp[(4) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
+		(yyval.list) = list1((yyvsp[(4) - (5)].node));
+	}
+    break;
+
+  case 85:
+#line 723 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 86:
+#line 727 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
+	}
+    break;
+
+  case 87:
+#line 732 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 88:
+#line 736 "go.y"
+    {
+		NodeList *node;
+		
+		node = mal(sizeof *node);
+		node->n = (yyvsp[(2) - (2)].node);
+		node->end = node;
+		(yyval.list) = node;
+	}
+    break;
+
+  case 89:
+#line 747 "go.y"
+    {
+		markdcl();
+	}
+    break;
+
+  case 90:
+#line 751 "go.y"
+    {
+		Node *n;
+		n = (yyvsp[(3) - (3)].node)->ntest;
+		if(n != N && n->op != OTYPESW)
+			n = N;
+		typesw = nod(OXXX, typesw, n);
+	}
+    break;
+
+  case 91:
+#line 759 "go.y"
+    {
+		(yyval.node) = (yyvsp[(3) - (7)].node);
+		(yyval.node)->op = OSWITCH;
+		(yyval.node)->list = (yyvsp[(6) - (7)].list);
+		typesw = typesw->left;
+		popdcl();
+	}
+    break;
+
+  case 92:
+#line 769 "go.y"
+    {
+		typesw = nod(OXXX, typesw, N);
+	}
+    break;
+
+  case 93:
+#line 773 "go.y"
+    {
+		(yyval.node) = nod(OSELECT, N, N);
+		(yyval.node)->lineno = typesw->lineno;
+		(yyval.node)->list = (yyvsp[(4) - (5)].list);
+		typesw = typesw->left;
+	}
+    break;
+
+  case 95:
+#line 786 "go.y"
+    {
+		(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 96:
+#line 790 "go.y"
+    {
+		(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 97:
+#line 794 "go.y"
+    {
+		(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 98:
+#line 798 "go.y"
+    {
+		(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 99:
+#line 802 "go.y"
+    {
+		(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 100:
+#line 806 "go.y"
+    {
+		(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 101:
+#line 810 "go.y"
+    {
+		(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 102:
+#line 814 "go.y"
+    {
+		(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 103:
+#line 818 "go.y"
+    {
+		(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 104:
+#line 822 "go.y"
+    {
+		(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 105:
+#line 826 "go.y"
+    {
+		(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 106:
+#line 830 "go.y"
+    {
+		(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 107:
+#line 834 "go.y"
+    {
+		(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 108:
+#line 838 "go.y"
+    {
+		(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 109:
+#line 842 "go.y"
+    {
+		(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 110:
+#line 846 "go.y"
+    {
+		(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 111:
+#line 850 "go.y"
+    {
+		(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 112:
+#line 854 "go.y"
+    {
+		(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 113:
+#line 858 "go.y"
+    {
+		(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 114:
+#line 863 "go.y"
+    {
+		(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 116:
+#line 870 "go.y"
+    {
+		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 117:
+#line 874 "go.y"
+    {
+		if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
+			// Special case for &T{...}: turn into (*T){...}.
+			(yyval.node) = (yyvsp[(2) - (2)].node);
+			(yyval.node)->right = nod(OIND, (yyval.node)->right, N);
+			(yyval.node)->right->implicit = 1;
+		} else {
+			(yyval.node) = nod(OADDR, (yyvsp[(2) - (2)].node), N);
+		}
+	}
+    break;
+
+  case 118:
+#line 885 "go.y"
+    {
+		(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 119:
+#line 889 "go.y"
+    {
+		(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 120:
+#line 893 "go.y"
+    {
+		(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 121:
+#line 897 "go.y"
+    {
+		yyerror("the bitwise complement operator is ^");
+		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 122:
+#line 902 "go.y"
+    {
+		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 123:
+#line 906 "go.y"
+    {
+		(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 124:
+#line 916 "go.y"
+    {
+		(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
+	}
+    break;
+
+  case 125:
+#line 920 "go.y"
+    {
+		(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
+		(yyval.node)->list = (yyvsp[(3) - (5)].list);
+	}
+    break;
+
+  case 126:
+#line 925 "go.y"
+    {
+		(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
+		(yyval.node)->list = (yyvsp[(3) - (6)].list);
+		(yyval.node)->isddd = 1;
+	}
+    break;
+
+  case 127:
+#line 933 "go.y"
+    {
+		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
+	}
+    break;
+
+  case 129:
+#line 938 "go.y"
+    {
+		if((yyvsp[(1) - (3)].node)->op == OPACK) {
+			Sym *s;
+			s = restrictlookup((yyvsp[(3) - (3)].sym)->name, (yyvsp[(1) - (3)].node)->pkg);
+			(yyvsp[(1) - (3)].node)->used = 1;
+			(yyval.node) = oldname(s);
+			break;
+		}
+		(yyval.node) = nod(OXDOT, (yyvsp[(1) - (3)].node), newname((yyvsp[(3) - (3)].sym)));
+	}
+    break;
+
+  case 130:
+#line 949 "go.y"
+    {
+		(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
+	}
+    break;
+
+  case 131:
+#line 953 "go.y"
+    {
+		(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
+	}
+    break;
+
+  case 132:
+#line 957 "go.y"
+    {
+		(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
+	}
+    break;
+
+  case 133:
+#line 961 "go.y"
+    {
+		(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
+	}
+    break;
+
+  case 134:
+#line 965 "go.y"
+    {
+		if((yyvsp[(5) - (8)].node) == N)
+			yyerror("middle index required in 3-index slice");
+		if((yyvsp[(7) - (8)].node) == N)
+			yyerror("final index required in 3-index slice");
+		(yyval.node) = nod(OSLICE3, (yyvsp[(1) - (8)].node), nod(OKEY, (yyvsp[(3) - (8)].node), nod(OKEY, (yyvsp[(5) - (8)].node), (yyvsp[(7) - (8)].node))));
+	}
+    break;
+
+  case 136:
+#line 974 "go.y"
+    {
+		// conversion
+		(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
+		(yyval.node)->list = list1((yyvsp[(3) - (5)].node));
+	}
+    break;
+
+  case 137:
+#line 980 "go.y"
+    {
+		(yyval.node) = (yyvsp[(3) - (5)].node);
+		(yyval.node)->right = (yyvsp[(1) - (5)].node);
+		(yyval.node)->list = (yyvsp[(4) - (5)].list);
+		fixlbrace((yyvsp[(2) - (5)].i));
+	}
+    break;
+
+  case 138:
+#line 987 "go.y"
+    {
+		(yyval.node) = (yyvsp[(3) - (5)].node);
+		(yyval.node)->right = (yyvsp[(1) - (5)].node);
+		(yyval.node)->list = (yyvsp[(4) - (5)].list);
+	}
+    break;
+
+  case 139:
+#line 993 "go.y"
+    {
+		yyerror("cannot parenthesize type in composite literal");
+		(yyval.node) = (yyvsp[(5) - (7)].node);
+		(yyval.node)->right = (yyvsp[(2) - (7)].node);
+		(yyval.node)->list = (yyvsp[(6) - (7)].list);
+	}
+    break;
+
+  case 141:
+#line 1002 "go.y"
+    {
+		// composite expression.
+		// make node early so we get the right line number.
+		(yyval.node) = nod(OCOMPLIT, N, N);
+	}
+    break;
+
+  case 142:
+#line 1010 "go.y"
+    {
+		(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 143:
+#line 1016 "go.y"
+    {
+		// These nodes do not carry line numbers.
+		// Since a composite literal commonly spans several lines,
+		// the line number on errors may be misleading.
+		// Introduce a wrapper node to give the correct line.
+		(yyval.node) = (yyvsp[(1) - (1)].node);
+		switch((yyval.node)->op) {
+		case ONAME:
+		case ONONAME:
+		case OTYPE:
+		case OPACK:
+		case OLITERAL:
+			(yyval.node) = nod(OPAREN, (yyval.node), N);
+			(yyval.node)->implicit = 1;
+		}
+	}
+    break;
+
+  case 144:
+#line 1033 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (4)].node);
+		(yyval.node)->list = (yyvsp[(3) - (4)].list);
+	}
+    break;
+
+  case 146:
+#line 1041 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (4)].node);
+		(yyval.node)->list = (yyvsp[(3) - (4)].list);
+	}
+    break;
+
+  case 148:
+#line 1049 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (3)].node);
+		
+		// Need to know on lhs of := whether there are ( ).
+		// Don't bother with the OPAREN in other cases:
+		// it's just a waste of memory and time.
+		switch((yyval.node)->op) {
+		case ONAME:
+		case ONONAME:
+		case OPACK:
+		case OTYPE:
+		case OLITERAL:
+		case OTYPESW:
+			(yyval.node) = nod(OPAREN, (yyval.node), N);
+		}
+	}
+    break;
+
+  case 152:
+#line 1075 "go.y"
+    {
+		(yyval.i) = LBODY;
+	}
+    break;
+
+  case 153:
+#line 1079 "go.y"
+    {
+		(yyval.i) = '{';
+	}
+    break;
+
+  case 154:
+#line 1090 "go.y"
+    {
+		if((yyvsp[(1) - (1)].sym) == S)
+			(yyval.node) = N;
+		else
+			(yyval.node) = newname((yyvsp[(1) - (1)].sym));
+	}
+    break;
+
+  case 155:
+#line 1099 "go.y"
+    {
+		(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
+	}
+    break;
+
+  case 156:
+#line 1104 "go.y"
+    {
+		(yyval.node) = N;
+	}
+    break;
+
+  case 158:
+#line 1111 "go.y"
+    {
+		(yyval.sym) = (yyvsp[(1) - (1)].sym);
+		// during imports, unqualified non-exported identifiers are from builtinpkg
+		if(importpkg != nil && !exportname((yyvsp[(1) - (1)].sym)->name))
+			(yyval.sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
+	}
+    break;
+
+  case 160:
+#line 1119 "go.y"
+    {
+		(yyval.sym) = S;
+	}
+    break;
+
+  case 161:
+#line 1125 "go.y"
+    {
+		Pkg *p;
+
+		if((yyvsp[(2) - (4)].val).u.sval->len == 0)
+			p = importpkg;
+		else {
+			if(isbadimport((yyvsp[(2) - (4)].val).u.sval))
+				errorexit();
+			p = mkpkg((yyvsp[(2) - (4)].val).u.sval);
+		}
+		(yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, p);
+	}
+    break;
+
+  case 162:
+#line 1138 "go.y"
+    {
+		Pkg *p;
+
+		if((yyvsp[(2) - (4)].val).u.sval->len == 0)
+			p = importpkg;
+		else {
+			if(isbadimport((yyvsp[(2) - (4)].val).u.sval))
+				errorexit();
+			p = mkpkg((yyvsp[(2) - (4)].val).u.sval);
+		}
+		(yyval.sym) = pkglookup("?", p);
+	}
+    break;
+
+  case 163:
+#line 1153 "go.y"
+    {
+		(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
+		if((yyval.node)->pack != N)
+			(yyval.node)->pack->used = 1;
+	}
+    break;
+
+  case 165:
+#line 1173 "go.y"
+    {
+		yyerror("final argument in variadic function missing type");
+		(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
+	}
+    break;
+
+  case 166:
+#line 1178 "go.y"
+    {
+		(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 172:
+#line 1189 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (3)].node);
+	}
+    break;
+
+  case 176:
+#line 1198 "go.y"
+    {
+		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 181:
+#line 1208 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (3)].node);
+	}
+    break;
+
+  case 191:
+#line 1229 "go.y"
+    {
+		if((yyvsp[(1) - (3)].node)->op == OPACK) {
+			Sym *s;
+			s = restrictlookup((yyvsp[(3) - (3)].sym)->name, (yyvsp[(1) - (3)].node)->pkg);
+			(yyvsp[(1) - (3)].node)->used = 1;
+			(yyval.node) = oldname(s);
+			break;
+		}
+		(yyval.node) = nod(OXDOT, (yyvsp[(1) - (3)].node), newname((yyvsp[(3) - (3)].sym)));
+	}
+    break;
+
+  case 192:
+#line 1242 "go.y"
+    {
+		(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
+	}
+    break;
+
+  case 193:
+#line 1246 "go.y"
+    {
+		// array literal of nelem
+		(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
+	}
+    break;
+
+  case 194:
+#line 1251 "go.y"
+    {
+		(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
+		(yyval.node)->etype = Cboth;
+	}
+    break;
+
+  case 195:
+#line 1256 "go.y"
+    {
+		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
+		(yyval.node)->etype = Csend;
+	}
+    break;
+
+  case 196:
+#line 1261 "go.y"
+    {
+		(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
+	}
+    break;
+
+  case 199:
+#line 1269 "go.y"
+    {
+		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 200:
+#line 1275 "go.y"
+    {
+		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
+		(yyval.node)->etype = Crecv;
+	}
+    break;
+
+  case 201:
+#line 1282 "go.y"
+    {
+		(yyval.node) = nod(OTSTRUCT, N, N);
+		(yyval.node)->list = (yyvsp[(3) - (5)].list);
+		fixlbrace((yyvsp[(2) - (5)].i));
+	}
+    break;
+
+  case 202:
+#line 1288 "go.y"
+    {
+		(yyval.node) = nod(OTSTRUCT, N, N);
+		fixlbrace((yyvsp[(2) - (3)].i));
+	}
+    break;
+
+  case 203:
+#line 1295 "go.y"
+    {
+		(yyval.node) = nod(OTINTER, N, N);
+		(yyval.node)->list = (yyvsp[(3) - (5)].list);
+		fixlbrace((yyvsp[(2) - (5)].i));
+	}
+    break;
+
+  case 204:
+#line 1301 "go.y"
+    {
+		(yyval.node) = nod(OTINTER, N, N);
+		fixlbrace((yyvsp[(2) - (3)].i));
+	}
+    break;
+
+  case 205:
+#line 1312 "go.y"
+    {
+		(yyval.node) = (yyvsp[(2) - (3)].node);
+		if((yyval.node) == N)
+			break;
+		if(noescape && (yyvsp[(3) - (3)].list) != nil)
+			yyerror("can only use //go:noescape with external func implementations");
+		(yyval.node)->nbody = (yyvsp[(3) - (3)].list);
+		(yyval.node)->endlineno = lineno;
+		(yyval.node)->noescape = noescape;
+		(yyval.node)->nosplit = nosplit;
+		funcbody((yyval.node));
+	}
+    break;
+
+  case 206:
+#line 1327 "go.y"
+    {
+		Node *t;
+
+		(yyval.node) = N;
+		(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
+
+		if(strcmp((yyvsp[(1) - (5)].sym)->name, "init") == 0) {
+			(yyvsp[(1) - (5)].sym) = renameinit();
+			if((yyvsp[(3) - (5)].list) != nil || (yyvsp[(5) - (5)].list) != nil)
+				yyerror("func init must have no arguments and no return values");
+		}
+		if(strcmp(localpkg->name, "main") == 0 && strcmp((yyvsp[(1) - (5)].sym)->name, "main") == 0) {
+			if((yyvsp[(3) - (5)].list) != nil || (yyvsp[(5) - (5)].list) != nil)
+				yyerror("func main must have no arguments and no return values");
+		}
+
+		t = nod(OTFUNC, N, N);
+		t->list = (yyvsp[(3) - (5)].list);
+		t->rlist = (yyvsp[(5) - (5)].list);
+
+		(yyval.node) = nod(ODCLFUNC, N, N);
+		(yyval.node)->nname = newname((yyvsp[(1) - (5)].sym));
+		(yyval.node)->nname->defn = (yyval.node);
+		(yyval.node)->nname->ntype = t;		// TODO: check if nname already has an ntype
+		declare((yyval.node)->nname, PFUNC);
+
+		funchdr((yyval.node));
+	}
+    break;
+
+  case 207:
+#line 1356 "go.y"
+    {
+		Node *rcvr, *t;
+
+		(yyval.node) = N;
+		(yyvsp[(2) - (8)].list) = checkarglist((yyvsp[(2) - (8)].list), 0);
+		(yyvsp[(6) - (8)].list) = checkarglist((yyvsp[(6) - (8)].list), 1);
+
+		if((yyvsp[(2) - (8)].list) == nil) {
+			yyerror("method has no receiver");
+			break;
+		}
+		if((yyvsp[(2) - (8)].list)->next != nil) {
+			yyerror("method has multiple receivers");
+			break;
+		}
+		rcvr = (yyvsp[(2) - (8)].list)->n;
+		if(rcvr->op != ODCLFIELD) {
+			yyerror("bad receiver in method");
+			break;
+		}
+
+		t = nod(OTFUNC, rcvr, N);
+		t->list = (yyvsp[(6) - (8)].list);
+		t->rlist = (yyvsp[(8) - (8)].list);
+
+		(yyval.node) = nod(ODCLFUNC, N, N);
+		(yyval.node)->shortname = newname((yyvsp[(4) - (8)].sym));
+		(yyval.node)->nname = methodname1((yyval.node)->shortname, rcvr->right);
+		(yyval.node)->nname->defn = (yyval.node);
+		(yyval.node)->nname->ntype = t;
+		(yyval.node)->nname->nointerface = nointerface;
+		declare((yyval.node)->nname, PFUNC);
+
+		funchdr((yyval.node));
+	}
+    break;
+
+  case 208:
+#line 1394 "go.y"
+    {
+		Sym *s;
+		Type *t;
+
+		(yyval.node) = N;
+
+		s = (yyvsp[(1) - (5)].sym);
+		t = functype(N, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
+
+		importsym(s, ONAME);
+		if(s->def != N && s->def->op == ONAME) {
+			if(eqtype(t, s->def->type)) {
+				dclcontext = PDISCARD;  // since we skip funchdr below
+				break;
+			}
+			yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t);
+		}
+
+		(yyval.node) = newname(s);
+		(yyval.node)->type = t;
+		declare((yyval.node), PFUNC);
+
+		funchdr((yyval.node));
+	}
+    break;
+
+  case 209:
+#line 1419 "go.y"
+    {
+		(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right); 
+		(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
+
+		checkwidth((yyval.node)->type);
+		addmethod((yyvsp[(4) - (8)].sym), (yyval.node)->type, 0, nointerface);
+		nointerface = 0;
+		funchdr((yyval.node));
+		
+		// inl.c's inlnode in on a dotmeth node expects to find the inlineable body as
+		// (dotmeth's type)->nname->inl, and dotmeth's type has been pulled
+		// out by typecheck's lookdot as this $$->ttype.  So by providing
+		// this back link here we avoid special casing there.
+		(yyval.node)->type->nname = (yyval.node);
+	}
+    break;
+
+  case 210:
+#line 1437 "go.y"
+    {
+		(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
+		(yyval.node) = nod(OTFUNC, N, N);
+		(yyval.node)->list = (yyvsp[(3) - (5)].list);
+		(yyval.node)->rlist = (yyvsp[(5) - (5)].list);
+	}
+    break;
+
+  case 211:
+#line 1445 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 212:
+#line 1449 "go.y"
+    {
+		(yyval.list) = (yyvsp[(2) - (3)].list);
+		if((yyval.list) == nil)
+			(yyval.list) = list1(nod(OEMPTY, N, N));
+	}
+    break;
+
+  case 213:
+#line 1457 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 214:
+#line 1461 "go.y"
+    {
+		(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
+	}
+    break;
+
+  case 215:
+#line 1465 "go.y"
+    {
+		(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
+		(yyval.list) = (yyvsp[(2) - (3)].list);
+	}
+    break;
+
+  case 216:
+#line 1472 "go.y"
+    {
+		closurehdr((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 217:
+#line 1478 "go.y"
+    {
+		(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
+		fixlbrace((yyvsp[(2) - (4)].i));
+	}
+    break;
+
+  case 218:
+#line 1483 "go.y"
+    {
+		(yyval.node) = closurebody(nil);
+	}
+    break;
+
+  case 219:
+#line 1494 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 220:
+#line 1498 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
+		if(nsyntaxerrors == 0)
+			testdclstack();
+		nointerface = 0;
+		noescape = 0;
+		nosplit = 0;
+	}
+    break;
+
+  case 222:
+#line 1510 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
+	}
+    break;
+
+  case 224:
+#line 1517 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
+	}
+    break;
+
+  case 225:
+#line 1523 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 226:
+#line 1527 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 228:
+#line 1534 "go.y"
+    {
+		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
+	}
+    break;
+
+  case 229:
+#line 1540 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 230:
+#line 1544 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 231:
+#line 1550 "go.y"
+    {
+		NodeList *l;
+
+		Node *n;
+		l = (yyvsp[(1) - (3)].list);
+		if(l == nil) {
+			// ? symbol, during import (list1(N) == nil)
+			n = (yyvsp[(2) - (3)].node);
+			if(n->op == OIND)
+				n = n->left;
+			n = embedded(n->sym, importpkg);
+			n->right = (yyvsp[(2) - (3)].node);
+			n->val = (yyvsp[(3) - (3)].val);
+			(yyval.list) = list1(n);
+			break;
+		}
+
+		for(l=(yyvsp[(1) - (3)].list); l; l=l->next) {
+			l->n = nod(ODCLFIELD, l->n, (yyvsp[(2) - (3)].node));
+			l->n->val = (yyvsp[(3) - (3)].val);
+		}
+	}
+    break;
+
+  case 232:
+#line 1573 "go.y"
+    {
+		(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
+		(yyval.list) = list1((yyvsp[(1) - (2)].node));
+	}
+    break;
+
+  case 233:
+#line 1578 "go.y"
+    {
+		(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
+		(yyval.list) = list1((yyvsp[(2) - (4)].node));
+		yyerror("cannot parenthesize embedded type");
+	}
+    break;
+
+  case 234:
+#line 1584 "go.y"
+    {
+		(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
+		(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
+		(yyval.list) = list1((yyvsp[(2) - (3)].node));
+	}
+    break;
+
+  case 235:
+#line 1590 "go.y"
+    {
+		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
+		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
+		(yyval.list) = list1((yyvsp[(3) - (5)].node));
+		yyerror("cannot parenthesize embedded type");
+	}
+    break;
+
+  case 236:
+#line 1597 "go.y"
+    {
+		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
+		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
+		(yyval.list) = list1((yyvsp[(3) - (5)].node));
+		yyerror("cannot parenthesize embedded type");
+	}
+    break;
+
+  case 237:
+#line 1606 "go.y"
+    {
+		Node *n;
+
+		(yyval.sym) = (yyvsp[(1) - (1)].sym);
+		n = oldname((yyvsp[(1) - (1)].sym));
+		if(n->pack != N)
+			n->pack->used = 1;
+	}
+    break;
+
+  case 238:
+#line 1615 "go.y"
+    {
+		Pkg *pkg;
+
+		if((yyvsp[(1) - (3)].sym)->def == N || (yyvsp[(1) - (3)].sym)->def->op != OPACK) {
+			yyerror("%S is not a package", (yyvsp[(1) - (3)].sym));
+			pkg = localpkg;
+		} else {
+			(yyvsp[(1) - (3)].sym)->def->used = 1;
+			pkg = (yyvsp[(1) - (3)].sym)->def->pkg;
+		}
+		(yyval.sym) = restrictlookup((yyvsp[(3) - (3)].sym)->name, pkg);
+	}
+    break;
+
+  case 239:
+#line 1630 "go.y"
+    {
+		(yyval.node) = embedded((yyvsp[(1) - (1)].sym), localpkg);
+	}
+    break;
+
+  case 240:
+#line 1636 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
+		ifacedcl((yyval.node));
+	}
+    break;
+
+  case 241:
+#line 1641 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
+	}
+    break;
+
+  case 242:
+#line 1645 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
+		yyerror("cannot parenthesize embedded type");
+	}
+    break;
+
+  case 243:
+#line 1652 "go.y"
+    {
+		// without func keyword
+		(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
+		(yyval.node) = nod(OTFUNC, fakethis(), N);
+		(yyval.node)->list = (yyvsp[(2) - (4)].list);
+		(yyval.node)->rlist = (yyvsp[(4) - (4)].list);
+	}
+    break;
+
+  case 245:
+#line 1666 "go.y"
+    {
+		(yyval.node) = nod(ONONAME, N, N);
+		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
+		(yyval.node) = nod(OKEY, (yyval.node), (yyvsp[(2) - (2)].node));
+	}
+    break;
+
+  case 246:
+#line 1672 "go.y"
+    {
+		(yyval.node) = nod(ONONAME, N, N);
+		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
+		(yyval.node) = nod(OKEY, (yyval.node), (yyvsp[(2) - (2)].node));
+	}
+    break;
+
+  case 248:
+#line 1681 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 249:
+#line 1685 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 250:
+#line 1690 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 251:
+#line 1694 "go.y"
+    {
+		(yyval.list) = (yyvsp[(1) - (2)].list);
+	}
+    break;
+
+  case 252:
+#line 1702 "go.y"
+    {
+		(yyval.node) = N;
+	}
+    break;
+
+  case 254:
+#line 1707 "go.y"
+    {
+		(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
+	}
+    break;
+
+  case 256:
+#line 1712 "go.y"
+    {
+		(yyval.node) = N;
+	}
+    break;
+
+  case 262:
+#line 1723 "go.y"
+    {
+		(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
+		(yyvsp[(1) - (2)].node)->sym = dclstack;  // context, for goto restrictions
+	}
+    break;
+
+  case 263:
+#line 1728 "go.y"
+    {
+		NodeList *l;
+
+		(yyvsp[(1) - (4)].node)->defn = (yyvsp[(4) - (4)].node);
+		l = list1((yyvsp[(1) - (4)].node));
+		if((yyvsp[(4) - (4)].node))
+			l = list(l, (yyvsp[(4) - (4)].node));
+		(yyval.node) = liststmt(l);
+	}
+    break;
+
+  case 264:
+#line 1738 "go.y"
+    {
+		// will be converted to OFALL
+		(yyval.node) = nod(OXFALL, N, N);
+		(yyval.node)->xoffset = block;
+	}
+    break;
+
+  case 265:
+#line 1744 "go.y"
+    {
+		(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 266:
+#line 1748 "go.y"
+    {
+		(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 267:
+#line 1752 "go.y"
+    {
+		(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 268:
+#line 1756 "go.y"
+    {
+		(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
+	}
+    break;
+
+  case 269:
+#line 1760 "go.y"
+    {
+		(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
+		(yyval.node)->sym = dclstack;  // context, for goto restrictions
+	}
+    break;
+
+  case 270:
+#line 1765 "go.y"
+    {
+		(yyval.node) = nod(ORETURN, N, N);
+		(yyval.node)->list = (yyvsp[(2) - (2)].list);
+		if((yyval.node)->list == nil && curfn != N) {
+			NodeList *l;
+
+			for(l=curfn->dcl; l; l=l->next) {
+				if(l->n->class == PPARAM)
+					continue;
+				if(l->n->class != PPARAMOUT)
+					break;
+				if(l->n->sym->def != l->n)
+					yyerror("%s is shadowed during return", l->n->sym->name);
+			}
+		}
+	}
+    break;
+
+  case 271:
+#line 1784 "go.y"
+    {
+		(yyval.list) = nil;
+		if((yyvsp[(1) - (1)].node) != N)
+			(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 272:
+#line 1790 "go.y"
+    {
+		(yyval.list) = (yyvsp[(1) - (3)].list);
+		if((yyvsp[(3) - (3)].node) != N)
+			(yyval.list) = list((yyval.list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 273:
+#line 1798 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 274:
+#line 1802 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 275:
+#line 1808 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 276:
+#line 1812 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 277:
+#line 1818 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 278:
+#line 1822 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 279:
+#line 1828 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 280:
+#line 1832 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 281:
+#line 1841 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 282:
+#line 1845 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 283:
+#line 1849 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 284:
+#line 1853 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 285:
+#line 1858 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 286:
+#line 1862 "go.y"
+    {
+		(yyval.list) = (yyvsp[(1) - (2)].list);
+	}
+    break;
+
+  case 291:
+#line 1876 "go.y"
+    {
+		(yyval.node) = N;
+	}
+    break;
+
+  case 293:
+#line 1882 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 295:
+#line 1888 "go.y"
+    {
+		(yyval.node) = N;
+	}
+    break;
+
+  case 297:
+#line 1894 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 299:
+#line 1900 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 301:
+#line 1906 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 303:
+#line 1912 "go.y"
+    {
+		(yyval.val).ctype = CTxxx;
+	}
+    break;
+
+  case 305:
+#line 1922 "go.y"
+    {
+		importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
+	}
+    break;
+
+  case 306:
+#line 1926 "go.y"
+    {
+		importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
+	}
+    break;
+
+  case 307:
+#line 1930 "go.y"
+    {
+		importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
+	}
+    break;
+
+  case 308:
+#line 1934 "go.y"
+    {
+		importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
+	}
+    break;
+
+  case 309:
+#line 1938 "go.y"
+    {
+		importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
+	}
+    break;
+
+  case 310:
+#line 1942 "go.y"
+    {
+		if((yyvsp[(2) - (4)].node) == N) {
+			dclcontext = PEXTERN;  // since we skip the funcbody below
+			break;
+		}
+
+		(yyvsp[(2) - (4)].node)->inl = (yyvsp[(3) - (4)].list);
+
+		funcbody((yyvsp[(2) - (4)].node));
+		importlist = list(importlist, (yyvsp[(2) - (4)].node));
+
+		if(debug['E']) {
+			print("import [%Z] func %lN \n", importpkg->path, (yyvsp[(2) - (4)].node));
+			if(debug['m'] > 2 && (yyvsp[(2) - (4)].node)->inl)
+				print("inl body:%+H\n", (yyvsp[(2) - (4)].node)->inl);
+		}
+	}
+    break;
+
+  case 311:
+#line 1962 "go.y"
+    {
+		(yyval.sym) = (yyvsp[(1) - (1)].sym);
+		structpkg = (yyval.sym)->pkg;
+	}
+    break;
+
+  case 312:
+#line 1969 "go.y"
+    {
+		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
+		importsym((yyvsp[(1) - (1)].sym), OTYPE);
+	}
+    break;
+
+  case 318:
+#line 1989 "go.y"
+    {
+		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
+	}
+    break;
+
+  case 319:
+#line 1993 "go.y"
+    {
+		// predefined name like uint8
+		(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
+		if((yyvsp[(1) - (1)].sym)->def == N || (yyvsp[(1) - (1)].sym)->def->op != OTYPE) {
+			yyerror("%s is not a type", (yyvsp[(1) - (1)].sym)->name);
+			(yyval.type) = T;
+		} else
+			(yyval.type) = (yyvsp[(1) - (1)].sym)->def->type;
+	}
+    break;
+
+  case 320:
+#line 2003 "go.y"
+    {
+		(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
+	}
+    break;
+
+  case 321:
+#line 2007 "go.y"
+    {
+		(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
+	}
+    break;
+
+  case 322:
+#line 2011 "go.y"
+    {
+		(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
+	}
+    break;
+
+  case 323:
+#line 2015 "go.y"
+    {
+		(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
+	}
+    break;
+
+  case 324:
+#line 2019 "go.y"
+    {
+		(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
+	}
+    break;
+
+  case 325:
+#line 2023 "go.y"
+    {
+		(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
+	}
+    break;
+
+  case 326:
+#line 2027 "go.y"
+    {
+		(yyval.type) = typ(TCHAN);
+		(yyval.type)->type = (yyvsp[(2) - (2)].type);
+		(yyval.type)->chan = Cboth;
+	}
+    break;
+
+  case 327:
+#line 2033 "go.y"
+    {
+		(yyval.type) = typ(TCHAN);
+		(yyval.type)->type = (yyvsp[(3) - (4)].type);
+		(yyval.type)->chan = Cboth;
+	}
+    break;
+
+  case 328:
+#line 2039 "go.y"
+    {
+		(yyval.type) = typ(TCHAN);
+		(yyval.type)->type = (yyvsp[(3) - (3)].type);
+		(yyval.type)->chan = Csend;
+	}
+    break;
+
+  case 329:
+#line 2047 "go.y"
+    {
+		(yyval.type) = typ(TCHAN);
+		(yyval.type)->type = (yyvsp[(3) - (3)].type);
+		(yyval.type)->chan = Crecv;
+	}
+    break;
+
+  case 330:
+#line 2055 "go.y"
+    {
+		(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
+	}
+    break;
+
+  case 331:
+#line 2061 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
+		if((yyvsp[(1) - (3)].sym))
+			(yyval.node)->left = newname((yyvsp[(1) - (3)].sym));
+		(yyval.node)->val = (yyvsp[(3) - (3)].val);
+	}
+    break;
+
+  case 332:
+#line 2068 "go.y"
+    {
+		Type *t;
+	
+		t = typ(TARRAY);
+		t->bound = -1;
+		t->type = (yyvsp[(3) - (4)].type);
+
+		(yyval.node) = nod(ODCLFIELD, N, typenod(t));
+		if((yyvsp[(1) - (4)].sym))
+			(yyval.node)->left = newname((yyvsp[(1) - (4)].sym));
+		(yyval.node)->isddd = 1;
+		(yyval.node)->val = (yyvsp[(4) - (4)].val);
+	}
+    break;
+
+  case 333:
+#line 2084 "go.y"
+    {
+		Sym *s;
+		Pkg *p;
+
+		if((yyvsp[(1) - (3)].sym) != S && strcmp((yyvsp[(1) - (3)].sym)->name, "?") != 0) {
+			(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (3)].sym)), typenod((yyvsp[(2) - (3)].type)));
+			(yyval.node)->val = (yyvsp[(3) - (3)].val);
+		} else {
+			s = (yyvsp[(2) - (3)].type)->sym;
+			if(s == S && isptr[(yyvsp[(2) - (3)].type)->etype])
+				s = (yyvsp[(2) - (3)].type)->type->sym;
+			p = importpkg;
+			if((yyvsp[(1) - (3)].sym) != S)
+				p = (yyvsp[(1) - (3)].sym)->pkg;
+			(yyval.node) = embedded(s, p);
+			(yyval.node)->right = typenod((yyvsp[(2) - (3)].type));
+			(yyval.node)->val = (yyvsp[(3) - (3)].val);
+		}
+	}
+    break;
+
+  case 334:
+#line 2106 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
+	}
+    break;
+
+  case 335:
+#line 2110 "go.y"
+    {
+		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
+	}
+    break;
+
+  case 336:
+#line 2115 "go.y"
+    {
+		(yyval.list) = nil;
+	}
+    break;
+
+  case 338:
+#line 2122 "go.y"
+    {
+		(yyval.list) = (yyvsp[(2) - (3)].list);
+	}
+    break;
+
+  case 339:
+#line 2126 "go.y"
+    {
+		(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
+	}
+    break;
+
+  case 340:
+#line 2136 "go.y"
+    {
+		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
+	}
+    break;
+
+  case 341:
+#line 2140 "go.y"
+    {
+		(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
+		switch((yyval.node)->val.ctype){
+		case CTINT:
+		case CTRUNE:
+			mpnegfix((yyval.node)->val.u.xval);
+			break;
+		case CTFLT:
+			mpnegflt((yyval.node)->val.u.fval);
+			break;
+		case CTCPLX:
+			mpnegflt(&(yyval.node)->val.u.cval->real);
+			mpnegflt(&(yyval.node)->val.u.cval->imag);
+			break;
+		default:
+			yyerror("bad negated constant");
+		}
+	}
+    break;
+
+  case 342:
+#line 2159 "go.y"
+    {
+		(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
+		if((yyval.node)->op != OLITERAL)
+			yyerror("bad constant %S", (yyval.node)->sym);
+	}
+    break;
+
+  case 344:
+#line 2168 "go.y"
+    {
+		if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
+			(yyval.node) = (yyvsp[(2) - (5)].node);
+			mpaddfixfix((yyvsp[(2) - (5)].node)->val.u.xval, (yyvsp[(4) - (5)].node)->val.u.xval, 0);
+			break;
+		}
+		(yyvsp[(4) - (5)].node)->val.u.cval->real = (yyvsp[(4) - (5)].node)->val.u.cval->imag;
+		mpmovecflt(&(yyvsp[(4) - (5)].node)->val.u.cval->imag, 0.0);
+		(yyval.node) = nodcplxlit((yyvsp[(2) - (5)].node)->val, (yyvsp[(4) - (5)].node)->val);
+	}
+    break;
+
+  case 347:
+#line 2184 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 348:
+#line 2188 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 349:
+#line 2194 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 350:
+#line 2198 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+  case 351:
+#line 2204 "go.y"
+    {
+		(yyval.list) = list1((yyvsp[(1) - (1)].node));
+	}
+    break;
+
+  case 352:
+#line 2208 "go.y"
+    {
+		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
+	}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 4907 "y.tab.c"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+#line 2212 "go.y"
+
+
+static void
+fixlbrace(int lbr)
+{
+	// If the opening brace was an LBODY,
+	// set up for another one now that we're done.
+	// See comment in lex.c about loophack.
+	if(lbr == LBODY)
+		loophack = 1;
+}
+
+
diff --git a/src/cmd/gc/y.tab.h b/src/cmd/gc/y.tab.h
new file mode 100644
index 0000000..d01fbe1
--- /dev/null
+++ b/src/cmd/gc/y.tab.h
@@ -0,0 +1,167 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LLITERAL = 258,
+     LASOP = 259,
+     LCOLAS = 260,
+     LBREAK = 261,
+     LCASE = 262,
+     LCHAN = 263,
+     LCONST = 264,
+     LCONTINUE = 265,
+     LDDD = 266,
+     LDEFAULT = 267,
+     LDEFER = 268,
+     LELSE = 269,
+     LFALL = 270,
+     LFOR = 271,
+     LFUNC = 272,
+     LGO = 273,
+     LGOTO = 274,
+     LIF = 275,
+     LIMPORT = 276,
+     LINTERFACE = 277,
+     LMAP = 278,
+     LNAME = 279,
+     LPACKAGE = 280,
+     LRANGE = 281,
+     LRETURN = 282,
+     LSELECT = 283,
+     LSTRUCT = 284,
+     LSWITCH = 285,
+     LTYPE = 286,
+     LVAR = 287,
+     LANDAND = 288,
+     LANDNOT = 289,
+     LBODY = 290,
+     LCOMM = 291,
+     LDEC = 292,
+     LEQ = 293,
+     LGE = 294,
+     LGT = 295,
+     LIGNORE = 296,
+     LINC = 297,
+     LLE = 298,
+     LLSH = 299,
+     LLT = 300,
+     LNE = 301,
+     LOROR = 302,
+     LRSH = 303,
+     NotPackage = 304,
+     NotParen = 305,
+     PreferToRightParen = 306
+   };
+#endif
+/* Tokens.  */
+#define LLITERAL 258
+#define LASOP 259
+#define LCOLAS 260
+#define LBREAK 261
+#define LCASE 262
+#define LCHAN 263
+#define LCONST 264
+#define LCONTINUE 265
+#define LDDD 266
+#define LDEFAULT 267
+#define LDEFER 268
+#define LELSE 269
+#define LFALL 270
+#define LFOR 271
+#define LFUNC 272
+#define LGO 273
+#define LGOTO 274
+#define LIF 275
+#define LIMPORT 276
+#define LINTERFACE 277
+#define LMAP 278
+#define LNAME 279
+#define LPACKAGE 280
+#define LRANGE 281
+#define LRETURN 282
+#define LSELECT 283
+#define LSTRUCT 284
+#define LSWITCH 285
+#define LTYPE 286
+#define LVAR 287
+#define LANDAND 288
+#define LANDNOT 289
+#define LBODY 290
+#define LCOMM 291
+#define LDEC 292
+#define LEQ 293
+#define LGE 294
+#define LGT 295
+#define LIGNORE 296
+#define LINC 297
+#define LLE 298
+#define LLSH 299
+#define LLT 300
+#define LNE 301
+#define LOROR 302
+#define LRSH 303
+#define NotPackage 304
+#define NotParen 305
+#define PreferToRightParen 306
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 28 "go.y"
+{
+	Node*		node;
+	NodeList*		list;
+	Type*		type;
+	Sym*		sym;
+	struct	Val	val;
+	int		i;
+}
+/* Line 1529 of yacc.c.  */
+#line 160 "y.tab.h"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/src/cmd/gc/yerr.h b/src/cmd/gc/yerr.h
new file mode 100644
index 0000000..d0dd639
--- /dev/null
+++ b/src/cmd/gc/yerr.h
@@ -0,0 +1,79 @@
+// Copyright 2010 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.
+
+// Example-based syntax error messages.
+// See bisonerrors, Makefile, go.y.
+
+static struct {
+	int yystate;
+	int yychar;
+	char *msg;
+} yymsg[] = {
+	// Each line of the form % token list
+	// is converted by bisonerrors into the yystate and yychar caused
+	// by that token list.
+
+	{222, ',',
+	"unexpected comma during import block"},
+
+	{32, ';',
+	"missing import path; require quoted string"},
+
+	{380, ';',
+	"missing { after if clause"},
+
+	{401, ';',
+	"missing { after switch clause"},
+
+	{239, ';',
+	"missing { after for clause"},
+
+	{478, LBODY,
+	"missing { after for clause"},
+
+	{22, '{',
+	"unexpected semicolon or newline before {"},
+
+	{145, ';',
+	"unexpected semicolon or newline in type declaration"},
+
+	{37, '}',
+	"unexpected } in channel type"},
+	
+	{37, ')',
+	"unexpected ) in channel type"},
+	
+	{37, ',',
+	"unexpected comma in channel type"},
+
+	{441, LELSE,
+	"unexpected semicolon or newline before else"},
+
+	{259, ',',
+	"name list not allowed in interface type"},
+
+	{239, LVAR,
+	"var declaration not allowed in for initializer"},
+
+	{65, '{',
+	"unexpected { at end of statement"},
+
+	{379, '{',
+	"unexpected { at end of statement"},
+	
+	{126, ';',
+	"argument to go/defer must be function call"},
+	
+	{428, ';',
+	"need trailing comma before newline in composite literal"},
+	
+	{439, ';',
+	"need trailing comma before newline in composite literal"},
+	
+	{113, LNAME,
+	"nested func not allowed"},
+
+	{647, ';',
+	"else must be followed by if or statement block"}
+};
