[dev.cc] cmd/6a, cmd/6g etc: replace C implementations with Go implementations

Change-Id: I58e00a39cf63df07813d21453f91e68eef6a413c
Reviewed-on: https://go-review.googlesource.com/5635
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/src/cmd/5a/Makefile b/src/cmd/5a/Makefile
deleted file mode 100644
index 27290dd..0000000
--- a/src/cmd/5a/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
-
-y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/5a/a.h b/src/cmd/5a/a.h
deleted file mode 100644
index 8a6764b..0000000
--- a/src/cmd/5a/a.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Inferno utils/5a/a.h
-// http://code.google.com/p/inferno-os/source/browse/utils/5a/a.h
-//
-//	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 <bio.h>
-#include <link.h>
-#include "../5l/5.out.h"
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#undef	getc
-#undef	ungetc
-#undef	BUFSIZ
-
-#define	getc	ccgetc
-#define	ungetc	ccungetc
-
-typedef	struct	Sym	Sym;
-typedef	struct	Io	Io;
-
-#define	MAXALIGN	7
-#define	FPCHIP		1
-#define	NSYMB		8192
-#define	BUFSIZ		8192
-#define	HISTSZ		20
-#ifndef	EOF
-#define	EOF		(-1)
-#endif
-#define	IGN		(-2)
-#define	GETC()		((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
-#define	NHASH		503
-#define	STRINGSZ	200
-#define	NMACRO		10
-
-struct	Sym
-{
-	Sym*	link;
-	char*	macro;
-	int32	value;
-	ushort	type;
-	char	*name;
-	char*	labelname;
-	char	sym;
-};
-#define	S	((Sym*)0)
-
-EXTERN	struct
-{
-	char*	p;
-	int	c;
-} fi;
-
-struct	Io
-{
-	Io*	link;
-	char	b[BUFSIZ];
-	char*	p;
-	short	c;
-	short	f;
-};
-#define	I	((Io*)0)
-
-enum
-{
-	CLAST,
-	CMACARG,
-	CMACRO,
-	CPREPROC,
-	
-	Always = C_SCOND_NONE,
-};
-
-EXTERN	int	debug[256];
-EXTERN	Sym*	hash[NHASH];
-EXTERN	char**	Dlist;
-EXTERN	int	nDlist;
-EXTERN	int	newflag;
-EXTERN	char*	hunk;
-EXTERN	char**	include;
-EXTERN	Io*	iofree;
-EXTERN	Io*	ionext;
-EXTERN	Io*	iostack;
-EXTERN	int32	lineno;
-EXTERN	int	nerrors;
-EXTERN	int32	nhunk;
-EXTERN	int	ninclude;
-EXTERN	int32	nsymb;
-EXTERN	Addr	nullgen;
-EXTERN	char*	outfile;
-EXTERN	int	pass;
-EXTERN	int32	pc;
-EXTERN	int	peekc;
-EXTERN	int32	stmtline;
-EXTERN	int	sym;
-EXTERN	char*	symb;
-EXTERN	int	thechar;
-EXTERN	char*	thestring;
-EXTERN	int32	thunk;
-EXTERN	Biobuf	obuf;
-EXTERN	Link*	ctxt;
-EXTERN	Biobuf	bstdout;
-EXTERN	Prog*	lastpc;
-
-void*	alloc(int32);
-void*	allocn(void*, int32, int32);
-void	ensuresymb(int32);
-void	errorexit(void);
-void	pushio(void);
-void	newio(void);
-void	newfile(char*, int);
-Sym*	slookup(char*);
-Sym*	lookup(void);
-Sym*	labellookup(Sym*);
-void	settext(LSym*);
-void	syminit(Sym*);
-int32	yylex(void);
-int	getc(void);
-int	getnsc(void);
-void	unget(int);
-int	escchar(int);
-void	cinit(void);
-void	pinit(char*);
-void	cclean(void);
-int	isreg(Addr*);
-void	outcode(int, int, Addr*, int, Addr*);
-int	filbuf(void);
-Sym*	getsym(void);
-void	domacro(void);
-void	macund(void);
-void	macdef(void);
-void	macexpand(Sym*, char*);
-void	macinc(void);
-void	maclin(void);
-void	macprag(void);
-void	macif(int);
-void	macend(void);
-void	dodefine(char*);
-void	prfile(int32);
-void	linehist(char*, int);
-void	gethunk(void);
-void	yyerror(char*, ...);
-int	yyparse(void);
-void	setinclude(char*);
-int	assemble(char*);
-void	listinit(void);
diff --git a/src/cmd/5a/a.y b/src/cmd/5a/a.y
index 10e9f6f..39fab8f 100644
--- a/src/cmd/5a/a.y
+++ b/src/cmd/5a/a.y
@@ -29,20 +29,23 @@
 // THE SOFTWARE.
 
 %{
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
+package main
+
+import (
+	"cmd/internal/asm"
+	"cmd/internal/obj"
+	. "cmd/internal/obj/arm"
+)
 %}
-%union
-{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
+
+%union {
+	sym *asm.Sym
+	lval int32
+	dval float64
+	sval string
+	addr obj.Addr
 }
+
 %left	'|'
 %left	'^'
 %left	'&'
@@ -51,12 +54,12 @@
 %left	'*' '/' '%'
 %token	<lval>	LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
 %token	<lval>	LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
-%token	<lval>	LTYPEB LGLOBL LTYPEC LTYPED LTYPEE
+%token	<lval>	LTYPEB LTYPEC LTYPED LTYPEE
 %token	<lval>	LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
 %token	<lval>	LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
 %token	<lval>	LCONST LSP LSB LFP LPC
 %token	<lval>	LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
-%token	<lval>	LCOND LS LAT
+%token	<lval>	LCOND LS LAT LGLOBL
 %token	<dval>	LFCONST
 %token	<sval>	LSCONST
 %token	<sym>	LNAME LLAB LVAR
@@ -68,30 +71,32 @@
 prog:
 |	prog
 	{
-		stmtline = lineno;
+		stmtline = asm.Lineno;
 	}
 	line
 
 line:
 	LNAME ':'
 	{
-		$1 = labellookup($1);
-		if($1->type == LLAB && $1->value != pc)
-			yyerror("redeclaration of %s", $1->labelname);
-		$1->type = LLAB;
-		$1->value = pc;
+		$1 = asm.LabelLookup($1);
+		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
+			yyerror("redeclaration of %s", $1.Labelname)
+		}
+		$1.Type = LLAB;
+		$1.Value = int64(asm.PC)
 	}
 	line
 |	LNAME '=' expr ';'
 	{
-		$1->type = LVAR;
-		$1->value = $3;
+		$1.Type = LVAR;
+		$1.Value = int64($3);
 	}
 |	LVAR '=' expr ';'
 	{
-		if($1->value != $3)
-			yyerror("redeclaration of %s", $1->name);
-		$1->value = $3;
+		if $1.Value != int64($3) {
+			yyerror("redeclaration of %s", $1.Name)
+		}
+		$1.Value = int64($3);
 	}
 |	';'
 |	inst ';'
@@ -171,20 +176,20 @@
  */
 |	LTYPE8 cond ioreg ',' '[' reglist ']'
 	{
-		Addr g;
+		var g obj.Addr
 
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = $6;
+		g.Type = obj.TYPE_CONST;
+		g.Offset = int64($6);
 		outcode($1, $2, &$3, 0, &g);
 	}
 |	LTYPE8 cond '[' reglist ']' ',' ioreg
 	{
-		Addr g;
+		var g obj.Addr
 
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = $4;
+		g.Type = obj.TYPE_CONST;
+		g.Offset = int64($4);
 		outcode($1, $2, &g, 0, &$7);
 	}
 /*
@@ -192,15 +197,15 @@
  */
 |	LTYPE9 cond reg ',' ireg ',' reg
 	{
-		outcode($1, $2, &$5, $3.reg, &$7);
+		outcode($1, $2, &$5, int32($3.Reg), &$7);
 	}
 |	LTYPE9 cond reg ',' ireg comma
 	{
-		outcode($1, $2, &$5, $3.reg, &$3);
+		outcode($1, $2, &$5, int32($3.Reg), &$3);
 	}
 |	LTYPE9 cond comma ireg ',' reg
 	{
-		outcode($1, $2, &$4, $6.reg, &$6);
+		outcode($1, $2, &$4, int32($6.Reg), &$6);
 	}
 /*
  * RET
@@ -214,16 +219,16 @@
  */
 |	LTYPEB name ',' '$' textsize
 	{
-		settext($2.sym);
+		asm.Settext($2.Sym);
 		outcode($1, Always, &$2, 0, &$5);
 	}
 |	LTYPEB name ',' con ',' '$' textsize
 	{
-		settext($2.sym);
+		asm.Settext($2.Sym);
 		outcode($1, Always, &$2, 0, &$7);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST;
+			lastpc.From3.Offset = int64($4)
 		}
 	}
 /*
@@ -231,27 +236,28 @@
  */
 |	LGLOBL name ',' imm
 	{
-		settext($2.sym);
-		outcode($1, Always, &$2, 0, &$4);
+		asm.Settext($2.Sym)
+		outcode($1, Always, &$2, 0, &$4)
 	}
 |	LGLOBL name ',' con ',' imm
 	{
-		settext($2.sym);
-		outcode($1, Always, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym)
+		outcode($1, Always, &$2, 0, &$6)
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = int64($4)
 		}
 	}
+
 /*
  * DATA
  */
 |	LTYPEC name '/' con ',' ximm
 	{
-		outcode($1, Always, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		outcode($1, Always, &$2, 0, &$6)
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = int64($4)
 		}
 	}
 /*
@@ -285,18 +291,18 @@
 	}
 |	LTYPEL cond freg ',' freg comma
 	{
-		outcode($1, $2, &$3, $5.reg, &nullgen);
+		outcode($1, $2, &$3, int32($5.Reg), &nullgen);
 	}
 /*
  * MCR MRC
  */
 |	LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
 	{
-		Addr g;
+		var g obj.Addr
 
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset =
+		g.Type = obj.TYPE_CONST;
+		g.Offset = int64(
 			(0xe << 24) |		/* opcode */
 			($1 << 20) |		/* MCR/MRC */
 			(($2^C_SCOND_XOR) << 28) |		/* scond */
@@ -306,7 +312,7 @@
 			(($9 & 15) << 16) |	/* Crn */
 			(($11 & 15) << 0) |	/* Crm */
 			(($12 & 7) << 5) |	/* coprocessor information */
-			(1<<4);			/* must be set */
+			(1<<4));			/* must be set */
 		outcode(AMRC, Always, &nullgen, 0, &g);
 	}
 /*
@@ -314,17 +320,17 @@
  */
 |	LTYPEM cond reg ',' reg ',' regreg
 	{
-		outcode($1, $2, &$3, $5.reg, &$7);
+		outcode($1, $2, &$3, int32($5.Reg), &$7);
 	}
 /*
- * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
+ * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff . r4
  * MULAW{T,B} r1,r2,r3,r4
  */
 |	LTYPEN cond reg ',' reg ',' reg ',' spreg
 	{
-		$7.type = TYPE_REGREG2;
-		$7.offset = $9;
-		outcode($1, $2, &$3, $5.reg, &$7);
+		$7.Type = obj.TYPE_REGREG2;
+		$7.Offset = int64($9);
+		outcode($1, $2, &$3, int32($5.Reg), &$7);
 	}
 /*
  * PLD
@@ -338,8 +344,9 @@
  */
 |	LTYPEPC gen ',' gen
 	{
-		if($2.type != TYPE_CONST || $4.type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
+		if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
+			yyerror("arguments to PCDATA must be integer constants")
+		}
 		outcode($1, Always, &$2, 0, &$4);
 	}
 /*
@@ -347,10 +354,12 @@
  */
 |	LTYPEF gen ',' gen
 	{
-		if($2.type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if($4.type != NAME_EXTERN && $4.type != NAME_STATIC && $4.type != TYPE_MEM)
-			yyerror("value for FUNCDATA must be symbol reference");
+		if $2.Type != obj.TYPE_CONST {
+			yyerror("index for FUNCDATA must be integer constant")
+		}
+		if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
+			yyerror("value for FUNCDATA must be symbol reference")
+		}
  		outcode($1, Always, &$2, 0, &$4);
 	}
 /*
@@ -361,13 +370,43 @@
 		outcode($1, Always, &nullgen, 0, &nullgen);
 	}
 
+textsize:
+	LCONST
+	{
+		$$ = nullgen;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = int64($1)
+		$$.U.Argsize = obj.ArgsSizeUnknown;
+	}
+|	'-' LCONST
+	{
+		$$ = nullgen;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -int64($2)
+		$$.U.Argsize = obj.ArgsSizeUnknown;
+	}
+|	LCONST '-' LCONST
+	{
+		$$ = nullgen;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = int64($1)
+		$$.U.Argsize = int32($3);
+	}
+|	'-' LCONST '-' LCONST
+	{
+		$$ = nullgen;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -int64($2)
+		$$.U.Argsize = int32($4);
+	}
+
 cond:
 	{
 		$$ = Always;
 	}
 |	cond LCOND
 	{
-		$$ = ($1 & ~C_SCOND) | $2;
+		$$ = ($1 & ^ C_SCOND) | $2;
 	}
 |	cond LS
 	{
@@ -381,65 +420,36 @@
 	con '(' LPC ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1 + pc;
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = int64($1) + int64(asm.PC);
 	}
 |	LNAME offset
 	{
-		$1 = labellookup($1);
+		$1 = asm.LabelLookup($1);
 		$$ = nullgen;
-		if(pass == 2 && $1->type != LLAB)
-			yyerror("undefined label: %s", $1->labelname);
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1->value + $2;
-	}
-
-textsize:
-	LCONST
-	{
-		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = ArgsSizeUnknown;
-	}
-|	'-' LCONST
-	{
-		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = ArgsSizeUnknown;
-	}
-|	LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = $3;
-	}
-|	'-' LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = $4;
+		if asm.Pass == 2 && $1.Type != LLAB {
+			yyerror("undefined label: %s", $1.Labelname)
+		}
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1.Value + int64($2);
 	}
 
 ximm:	'$' con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		$$.offset = $2;
+		$$.Type = obj.TYPE_CONST;
+		$$.Offset = int64($2);
 	}
 |	'$' oreg
 	{
 		$$ = $2;
-		$$.type = TYPE_ADDR;
+		$$.Type = obj.TYPE_ADDR;
 	}
 |	'$' LSCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SCONST;
-		memcpy($$.u.sval, $2, sizeof($$.u.sval));
+		$$.Type = obj.TYPE_SCONST;
+		$$.U.Sval = $2
 	}
 |	fcon
 
@@ -447,45 +457,34 @@
 	'$' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $2;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $2;
 	}
 |	'$' '-' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$3;
 	}
 
 reglist:
 	spreg
 	{
-		if($1 < REG_R0 || $1 > REG_R15)
-			yyerror("invalid register in reglist");
-
-		$$ = 1 << ($1&15);
+		$$ = 1 << uint($1&15);
 	}
 |	spreg '-' spreg
 	{
-		int i;
-
-		if($1 < REG_R0 || $1 > REG_R15)
-			yyerror("invalid register in reglist");
-		if($3 < REG_R0 || $3 > REG_R15)
-			yyerror("invalid register in reglist");
-
 		$$=0;
-		for(i=$1; i<=$3; i++)
-			$$ |= 1<<(i&15);
-		for(i=$3; i<=$1; i++)
-			$$ |= 1<<(i&15);
+		for i:=$1; i<=$3; i++ {
+			$$ |= 1<<uint(i&15)
+		}
+		for i:=$3; i<=$1; i++ {
+			$$ |= 1<<uint(i&15)
+		}
 	}
 |	spreg comma reglist
 	{
-		if($1 < REG_R0 || $1 > REG_R15)
-			yyerror("invalid register in reglist");
-
-		$$ = (1<<($1&15)) | $3;
+		$$ = (1<<uint($1&15)) | $3;
 	}
 
 gen:
@@ -495,25 +494,25 @@
 |	shift '(' spreg ')'
 	{
 		$$ = $1;
-		$$.reg = $3;
+		$$.Reg = int16($3);
 	}
 |	LPSR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LFCR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM;
+		$$.Offset = int64($1);
 	}
 |	oreg
 |	freg
@@ -523,7 +522,7 @@
 |	name
 	{
 		$$ = $1;
-		if($1.name != NAME_EXTERN && $1.name != NAME_STATIC) {
+		if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
 		}
 	}
 
@@ -531,9 +530,9 @@
 	'(' spreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
-		$$.offset = 0;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($2);
+		$$.Offset = 0;
 	}
 
 ioreg:
@@ -541,9 +540,9 @@
 |	con '(' sreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($3);
+		$$.Offset = int64($1);
 	}
 
 oreg:
@@ -551,8 +550,8 @@
 |	name '(' sreg ')'
 	{
 		$$ = $1;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($3);
 	}
 |	ioreg
 
@@ -564,64 +563,66 @@
 imm:	'$' con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		$$.offset = $2;
+		$$.Type = obj.TYPE_CONST;
+		$$.Offset = int64($2);
 	}
 
 reg:
 	spreg
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 regreg:
 	'(' spreg ',' spreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REGREG;
-		$$.reg = $2;
-		$$.offset = $4;
+		$$.Type = obj.TYPE_REGREG;
+		$$.Reg = int16($2);
+		$$.Offset = int64($4);
 	}
 
 shift:
 	spreg '<' '<' rcon
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SHIFT;
-		$$.offset = $1&15 | $4 | (0 << 5);
+		$$.Type = obj.TYPE_SHIFT;
+		$$.Offset = int64($1&15) | int64($4) | (0 << 5);
 	}
 |	spreg '>' '>' rcon
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SHIFT;
-		$$.offset = $1&15 | $4 | (1 << 5);
+		$$.Type = obj.TYPE_SHIFT;
+		$$.Offset = int64($1&15) | int64($4) | (1 << 5);
 	}
 |	spreg '-' '>' rcon
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SHIFT;
-		$$.offset = $1&15 | $4 | (2 << 5);
+		$$.Type = obj.TYPE_SHIFT;
+		$$.Offset = int64($1&15) | int64($4) | (2 << 5);
 	}
 |	spreg LAT '>' rcon
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SHIFT;
-		$$.offset = $1&15 | $4 | (3 << 5);
+		$$.Type = obj.TYPE_SHIFT;
+		$$.Offset = int64($1&15) | int64($4) | (3 << 5);
 	}
 
 rcon:
 	spreg
 	{
-		if($$ < REG_R0 || $$ > REG_R15)
-			print("register value out of range in shift\n");
+		if $$ < REG_R0 || $$ > REG_R15 {
+			print("register value out of range\n")
+		}
 		$$ = (($1&15) << 8) | (1 << 4);
 	}
 |	con
 	{
-		if($$ < 0 || $$ >= 32)
-			print("shift value out of range\n");
+		if $$ < 0 || $$ >= 32 {
+			print("shift value out of range\n")
+		}
 		$$ = ($1&31) << 7;
 	}
 
@@ -633,8 +634,9 @@
 	}
 |	LR '(' expr ')'
 	{
-		if($3 < 0 || $3 >= NREG)
-			print("register value out of range in R(...)\n");
+		if $3 < 0 || $3 >= NREG {
+			print("register value out of range\n")
+		}
 		$$ = REG_R0 + $3;
 	}
 
@@ -649,8 +651,9 @@
 	LCREG
 |	LC '(' expr ')'
 	{
-		if($3 < 0 || $3 >= NREG)
-			print("register value out of range in C(...)\n");
+		if $3 < 0 || $3 >= NREG {
+			print("register value out of range\n")
+		}
 		$$ = $3; // TODO(rsc): REG_C0+$3
 	}
 
@@ -662,40 +665,40 @@
 	LFREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 |	LF '(' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = REG_F0 + $3;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16(REG_F0 + $3);
 	}
 
 name:
 	con '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $3;
-		$$.sym = nil;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = int8($3);
+		$$.Sym = nil;
+		$$.Offset = int64($1);
 	}
 |	LNAME offset '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $4;
-		$$.sym = linklookup(ctxt, $1->name, 0);
-		$$.offset = $2;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = int8($4);
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
+		$$.Offset = int64($2);
 	}
 |	LNAME '<' '>' offset '(' LSB ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = NAME_STATIC;
-		$$.sym = linklookup(ctxt, $1->name, 1);
-		$$.offset = $4;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = obj.NAME_STATIC;
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
+		$$.Offset = int64($4);
 	}
 
 offset:
@@ -720,7 +723,7 @@
 	LCONST
 |	LVAR
 	{
-		$$ = $1->value;
+		$$ = int32($1.Value);
 	}
 |	'-' con
 	{
@@ -732,7 +735,7 @@
 	}
 |	'~' con
 	{
-		$$ = ~$2;
+		$$ = ^$2;
 	}
 |	'(' expr ')'
 	{
@@ -772,11 +775,11 @@
 	}
 |	expr '<' '<' expr
 	{
-		$$ = $1 << $4;
+		$$ = $1 << uint($4);
 	}
 |	expr '>' '>' expr
 	{
-		$$ = $1 >> $4;
+		$$ = $1 >> uint($4);
 	}
 |	expr '&' expr
 	{
diff --git a/src/cmd/5a/doc.go b/src/cmd/5a/doc.go
deleted file mode 100644
index 3e9e78f..0000000
--- a/src/cmd/5a/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
-
-/*
-
-5a is a version of the Plan 9 assembler.  The original is documented at
-
-	http://plan9.bell-labs.com/magic/man2html/1/8a
-
-Go-specific considerations are documented at
-
-	http://golang.org/doc/asm
-
-Its target architecture is the ARM, referred to by these tools as arm.
-
-*/
-package main
diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c
deleted file mode 100644
index 6f56922..0000000
--- a/src/cmd/5a/lex.c
+++ /dev/null
@@ -1,538 +0,0 @@
-// Inferno utils/5a/lex.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.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.
-
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "a.h"
-#include "y.tab.h"
-
-enum
-{
-	Plan9	= 1<<0,
-	Unix	= 1<<1,
-	Windows	= 1<<2,
-};
-
-int
-systemtype(int sys)
-{
-#ifdef _WIN32
-	return sys&Windows;
-#else
-	return sys&Plan9;
-#endif
-}
-
-int
-Lconv(Fmt *fp)
-{
-	return linklinefmt(ctxt, fp);
-}
-
-void
-dodef(char *p)
-{
-	if(nDlist%8 == 0)
-		Dlist = allocn(Dlist, nDlist*sizeof(char *),
-			8*sizeof(char *));
-	Dlist[nDlist++] = p;
-}
-
-void
-usage(void)
-{
-	print("usage: %ca [options] file.c...\n", thechar);
-	flagprint(1);
-	errorexit();
-}
-
-void
-main(int argc, char *argv[])
-{
-	char *p;
-
-	thechar = '5';
-	thestring = "arm";
-
-	ctxt = linknew(&linkarm);
-	ctxt->diag = yyerror;
-	ctxt->bso = &bstdout;
-	ctxt->enforce_data_order = 1;
-	Binit(&bstdout, 1, OWRITE);
-	listinit5();
-	fmtinstall('L', Lconv);
-
-	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
-	// but not other values.	
-	p = getgoarch();
-	if(strncmp(p, thestring, strlen(thestring)) != 0)
-		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
-
-	ensuresymb(NSYMB);
-	memset(debug, 0, sizeof(debug));
-	cinit();
-	outfile = 0;
-	setinclude(".");
-	
-	flagfn1("D", "name[=value]: add #define", dodef);
-	flagfn1("I", "dir: add dir to include path", setinclude);
-	flagcount("S", "print assembly and machine code", &debug['S']);
-	flagcount("m", "debug preprocessor macros", &debug['m']);
-	flagstr("o", "file: set output file", &outfile);
-	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
-
-	flagparse(&argc, &argv, usage);
-	ctxt->debugasm = debug['S'];
-
-	if(argc < 1)
-		usage();
-	if(argc > 1){
-		print("can't assemble multiple files\n");
-		errorexit();
-	}
-
-	if(assemble(argv[0]))
-		errorexit();
-	Bflush(&bstdout);
-	if(nerrors > 0)
-		errorexit();
-	exits(0);
-}
-
-int
-assemble(char *file)
-{
-	char *ofile, *p;
-	int i, of;
-
-	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
-	strcpy(ofile, file);
-	p = utfrrune(ofile, '/');
-	if(p) {
-		include[0] = ofile;
-		*p++ = 0;
-	} else
-		p = ofile;
-	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
-			p = utfrrune(outfile, '.');
-			if(p)
-				if(p[1] == 's' && p[2] == 0)
-					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
-		} else
-			outfile = "/dev/null";
-	}
-
-	of = create(outfile, OWRITE, 0664);
-	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
-		errorexit();
-	}
-	Binit(&obuf, of, OWRITE);
-	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
-	Bprint(&obuf, "!\n");
-
-	for(pass = 1; pass <= 2; pass++) {
-		pinit(file);
-		for(i=0; i<nDlist; i++)
-			dodefine(Dlist[i]);
-		yyparse();
-		cclean();
-		if(nerrors)
-			return nerrors;
-	}
-
-	writeobj(ctxt, &obuf);
-	Bflush(&obuf);
-	return 0;
-}
-
-struct
-{
-	char	*name;
-	ushort	type;
-	ushort	value;
-} itab[] =
-{
-	"SP",		LSP,	NAME_AUTO,
-	"SB",		LSB,	NAME_EXTERN,
-	"FP",		LFP,	NAME_PARAM,
-	"PC",		LPC,	TYPE_BRANCH,
-
-	"R",		LR,	REG_F0,
-
-	"R0",		LREG,	REG_R0,
-	"R1",		LREG,	REG_R1,
-	"R2",		LREG,	REG_R2,
-	"R3",		LREG,	REG_R3,
-	"R4",		LREG,	REG_R4,
-	"R5",		LREG,	REG_R5,
-	"R6",		LREG,	REG_R6,
-	"R7",		LREG,	REG_R7,
-	"R8",		LREG,	REG_R8,
-	"R9",		LREG,	REG_R9,
-	"g",		LREG,	REG_R10, // avoid unintentionally clobber g using R10
-	"R11",		LREG,	REG_R11,
-	"R12",		LREG,	REG_R12,
-	"R13",		LREG,	REG_R13,
-	"R14",		LREG,	REG_R14,
-	"R15",		LREG,	REG_R15,
-
-	"F",		LF,	REG_F0,
-
-	"F0",		LFREG,	REG_F0,
-	"F1",		LFREG,	REG_F1,
-	"F2",		LFREG,	REG_F2,
-	"F3",		LFREG,	REG_F3,
-	"F4",		LFREG,	REG_F4,
-	"F5",		LFREG,	REG_F5,
-	"F6",		LFREG,	REG_F6,
-	"F7",		LFREG,	REG_F7,
-	"F8",		LFREG,	REG_F8,
-	"F9",		LFREG,	REG_F9,
-	"F10",		LFREG,	REG_F10,
-	"F11",		LFREG,	REG_F11,
-	"F12",		LFREG,	REG_F12,
-	"F13",		LFREG,	REG_F13,
-	"F14",		LFREG,	REG_F14,
-	"F15",		LFREG,	REG_F15,
-
-	"C",		LC,	0,
-
-	"C0",		LCREG,	0,
-	"C1",		LCREG,	1,
-	"C2",		LCREG,	2,
-	"C3",		LCREG,	3,
-	"C4",		LCREG,	4,
-	"C5",		LCREG,	5,
-	"C6",		LCREG,	6,
-	"C7",		LCREG,	7,
-	"C8",		LCREG,	8,
-	"C9",		LCREG,	9,
-	"C10",		LCREG,	10,
-	"C11",		LCREG,	11,
-	"C12",		LCREG,	12,
-	"C13",		LCREG,	13,
-	"C14",		LCREG,	14,
-	"C15",		LCREG,	15,
-
-	"CPSR",		LPSR,	REG_CPSR,
-	"SPSR",		LPSR,	REG_SPSR,
-
-	"FPSR",		LFCR,	REG_FPSR,
-	"FPCR",		LFCR,	REG_FPCR,
-
-	".EQ",		LCOND,	C_SCOND_EQ,
-	".NE",		LCOND,	C_SCOND_NE,
-	".CS",		LCOND,	C_SCOND_HS,
-	".HS",		LCOND,	C_SCOND_HS,
-	".CC",		LCOND,	C_SCOND_LO,
-	".LO",		LCOND,	C_SCOND_LO,
-	".MI",		LCOND,	C_SCOND_MI,
-	".PL",		LCOND,	C_SCOND_PL,
-	".VS",		LCOND,	C_SCOND_VS,
-	".VC",		LCOND,	C_SCOND_VC,
-	".HI",		LCOND,	C_SCOND_HI,
-	".LS",		LCOND,	C_SCOND_LS,
-	".GE",		LCOND,	C_SCOND_GE,
-	".LT",		LCOND,	C_SCOND_LT,
-	".GT",		LCOND,	C_SCOND_GT,
-	".LE",		LCOND,	C_SCOND_LE,
-	".AL",		LCOND,	C_SCOND_NONE,
-
-	".U",		LS,	C_UBIT,
-	".S",		LS,	C_SBIT,
-	".W",		LS,	C_WBIT,
-	".P",		LS,	C_PBIT,
-	".PW",		LS,	C_WBIT|C_PBIT,
-	".WP",		LS,	C_WBIT|C_PBIT,
-
-	".F",		LS,	C_FBIT,
-
-	".IBW",		LS,	C_WBIT|C_PBIT|C_UBIT,
-	".IAW",		LS,	C_WBIT|C_UBIT,
-	".DBW",		LS,	C_WBIT|C_PBIT,
-	".DAW",		LS,	C_WBIT,
-	".IB",		LS,	C_PBIT|C_UBIT,
-	".IA",		LS,	C_UBIT,
-	".DB",		LS,	C_PBIT,
-	".DA",		LS,	0,
-
-	"@",		LAT,	0,
-
-	"AND",		LTYPE1,	AAND,
-	"EOR",		LTYPE1,	AEOR,
-	"SUB",		LTYPE1,	ASUB,
-	"RSB",		LTYPE1,	ARSB,
-	"ADD",		LTYPE1,	AADD,
-	"ADC",		LTYPE1,	AADC,
-	"SBC",		LTYPE1,	ASBC,
-	"RSC",		LTYPE1,	ARSC,
-	"ORR",		LTYPE1,	AORR,
-	"BIC",		LTYPE1,	ABIC,
-
-	"SLL",		LTYPE1,	ASLL,
-	"SRL",		LTYPE1,	ASRL,
-	"SRA",		LTYPE1,	ASRA,
-
-	"MUL",		LTYPE1, AMUL,
-	"MULA",		LTYPEN, AMULA,
-	"DIV",		LTYPE1,	ADIV,
-	"MOD",		LTYPE1,	AMOD,
-
-	"MULL",		LTYPEM, AMULL,
-	"MULAL",	LTYPEM, AMULAL,
-	"MULLU",	LTYPEM, AMULLU,
-	"MULALU",	LTYPEM, AMULALU,
-
-	"MVN",		LTYPE2, AMVN,	/* op2 ignored */
-
-	"MOVB",		LTYPE3, AMOVB,
-	"MOVBU",	LTYPE3, AMOVBU,
-	"MOVH",		LTYPE3, AMOVH,
-	"MOVHU",	LTYPE3, AMOVHU,
-	"MOVW",		LTYPE3, AMOVW,
-
-	"MOVD",		LTYPE3, AMOVD,
-	"MOVDF",		LTYPE3, AMOVDF,
-	"MOVDW",	LTYPE3, AMOVDW,
-	"MOVF",		LTYPE3, AMOVF,
-	"MOVFD",		LTYPE3, AMOVFD,
-	"MOVFW",		LTYPE3, AMOVFW,
-	"MOVWD",	LTYPE3, AMOVWD,
-	"MOVWF",		LTYPE3, AMOVWF,
-
-	"LDREX",		LTYPE3, ALDREX,
-	"LDREXD",		LTYPE3, ALDREXD,
-	"STREX",		LTYPE9, ASTREX,
-	"STREXD",		LTYPE9, ASTREXD,
-
-/*
-	"NEGF",		LTYPEI, ANEGF,
-	"NEGD",		LTYPEI, ANEGD,
-	"SQTF",		LTYPEI,	ASQTF,
-	"SQTD",		LTYPEI,	ASQTD,
-	"RNDF",		LTYPEI,	ARNDF,
-	"RNDD",		LTYPEI,	ARNDD,
-	"URDF",		LTYPEI,	AURDF,
-	"URDD",		LTYPEI,	AURDD,
-	"NRMF",		LTYPEI,	ANRMF,
-	"NRMD",		LTYPEI,	ANRMD,
-*/
-
-	"ABSF",		LTYPEI, AABSF,
-	"ABSD",		LTYPEI, AABSD,
-	"SQRTF",	LTYPEI, ASQRTF,
-	"SQRTD",	LTYPEI, ASQRTD,
-	"CMPF",		LTYPEL, ACMPF,
-	"CMPD",		LTYPEL, ACMPD,
-	"ADDF",		LTYPEK,	AADDF,
-	"ADDD",		LTYPEK,	AADDD,
-	"SUBF",		LTYPEK,	ASUBF,
-	"SUBD",		LTYPEK,	ASUBD,
-	"MULF",		LTYPEK,	AMULF,
-	"MULD",		LTYPEK,	AMULD,
-	"DIVF",		LTYPEK,	ADIVF,
-	"DIVD",		LTYPEK,	ADIVD,
-
-	"B",		LTYPE4, AB,
-	"BL",		LTYPE4, ABL,
-	"BX",		LTYPEBX,	ABX,
-
-	"BEQ",		LTYPE5,	ABEQ,
-	"BNE",		LTYPE5,	ABNE,
-	"BCS",		LTYPE5,	ABCS,
-	"BHS",		LTYPE5,	ABHS,
-	"BCC",		LTYPE5,	ABCC,
-	"BLO",		LTYPE5,	ABLO,
-	"BMI",		LTYPE5,	ABMI,
-	"BPL",		LTYPE5,	ABPL,
-	"BVS",		LTYPE5,	ABVS,
-	"BVC",		LTYPE5,	ABVC,
-	"BHI",		LTYPE5,	ABHI,
-	"BLS",		LTYPE5,	ABLS,
-	"BGE",		LTYPE5,	ABGE,
-	"BLT",		LTYPE5,	ABLT,
-	"BGT",		LTYPE5,	ABGT,
-	"BLE",		LTYPE5,	ABLE,
-	"BCASE",	LTYPE5,	ABCASE,
-
-	"SWI",		LTYPE6, ASWI,
-
-	"CMP",		LTYPE7,	ACMP,
-	"TST",		LTYPE7,	ATST,
-	"TEQ",		LTYPE7,	ATEQ,
-	"CMN",		LTYPE7,	ACMN,
-
-	"MOVM",		LTYPE8, AMOVM,
-
-	"SWPBU",	LTYPE9, ASWPBU,
-	"SWPW",		LTYPE9, ASWPW,
-
-	"RET",		LTYPEA, ARET,
-	"RFE",		LTYPEA, ARFE,
-
-	"TEXT",		LTYPEB, ATEXT,
-	"GLOBL",	LGLOBL, AGLOBL,
-	"DATA",		LTYPEC, ADATA,
-	"CASE",		LTYPED, ACASE,
-	"END",		LTYPEE, AEND,
-	"WORD",		LTYPEH, AWORD,
-	"NOP",		LTYPEI, ANOP,
-
-	"MCR",		LTYPEJ, 0,
-	"MRC",		LTYPEJ, 1,
-
-	"PLD",		LTYPEPLD, APLD,
-	"UNDEF",	LTYPEE,	AUNDEF,
-	"CLZ",		LTYPE2, ACLZ,
-
-	"MULWT",	LTYPE1, AMULWT,
-	"MULWB",	LTYPE1, AMULWB,
-	"MULAWT",	LTYPEN, AMULAWT,
-	"MULAWB",	LTYPEN, AMULAWB,
-
-	"USEFIELD",	LTYPEN, AUSEFIELD,
-	"PCDATA",	LTYPEPC,	APCDATA,
-	"FUNCDATA",	LTYPEF,	AFUNCDATA,
-
-	0
-};
-
-void
-cinit(void)
-{
-	Sym *s;
-	int i;
-
-	nullgen.type = TYPE_NONE;
-	nullgen.name = NAME_NONE;
-
-	nerrors = 0;
-	iostack = I;
-	iofree = I;
-	peekc = IGN;
-	nhunk = 0;
-	for(i=0; i<NHASH; i++)
-		hash[i] = S;
-	for(i=0; itab[i].name; i++) {
-		s = slookup(itab[i].name);
-		s->type = itab[i].type;
-		s->value = itab[i].value;
-	}
-}
-
-void
-syminit(Sym *s)
-{
-
-	s->type = LNAME;
-	s->value = 0;
-}
-
-int
-isreg(Addr *g)
-{
-
-	USED(g);
-	return 1;
-}
-
-void
-cclean(void)
-{
-	outcode(AEND, Always, &nullgen, 0, &nullgen);
-}
-
-static int bcode[] =
-{
-	ABEQ,
-	ABNE,
-	ABCS,
-	ABCC,
-	ABMI,
-	ABPL,
-	ABVS,
-	ABVC,
-	ABHI,
-	ABLS,
-	ABGE,
-	ABLT,
-	ABGT,
-	ABLE,
-	AB,
-	ANOP,
-};
-
-void
-outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
-{
-	Prog *p;
-	Plist *pl;
-
-	/* hack to make B.NE etc. work: turn it into the corresponding conditional */
-	if(a == AB){
-		a = bcode[(scond^C_SCOND_XOR)&0xf];
-		scond = (scond & ~0xf) | C_SCOND_NONE;
-	}
-
-	if(pass == 1)
-		goto out;
-	
-	p = malloc(sizeof *p);
-	memset(p, 0, sizeof *p);
-	p->as = a;
-	p->lineno = stmtline;
-	p->scond = scond;
-	p->from = *g1;
-	p->reg = reg;
-	p->to = *g2;
-	p->pc = pc;
-
-	if(lastpc == nil) {
-		pl = linknewplist(ctxt);
-		pl->firstpc = p;
-	} else
-		lastpc->link = p;
-	lastpc = p;	
-
-out:
-	if(a != AGLOBL && a != ADATA)
-		pc++;
-}
-
-#include "../cc/lexbody"
-#include "../cc/macbody"
diff --git a/src/cmd/new5a/lex.go b/src/cmd/5a/lex.go
similarity index 100%
rename from src/cmd/new5a/lex.go
rename to src/cmd/5a/lex.go
diff --git a/src/cmd/new5a/y.go b/src/cmd/5a/y.go
similarity index 100%
rename from src/cmd/new5a/y.go
rename to src/cmd/5a/y.go
diff --git a/src/cmd/5a/y.tab.c b/src/cmd/5a/y.tab.c
deleted file mode 100644
index 416af9a..0000000
--- a/src/cmd/5a/y.tab.c
+++ /dev/null
@@ -1,2855 +0,0 @@
-/* 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 {
-     LTYPE1 = 258,
-     LTYPE2 = 259,
-     LTYPE3 = 260,
-     LTYPE4 = 261,
-     LTYPE5 = 262,
-     LTYPE6 = 263,
-     LTYPE7 = 264,
-     LTYPE8 = 265,
-     LTYPE9 = 266,
-     LTYPEA = 267,
-     LTYPEB = 268,
-     LGLOBL = 269,
-     LTYPEC = 270,
-     LTYPED = 271,
-     LTYPEE = 272,
-     LTYPEG = 273,
-     LTYPEH = 274,
-     LTYPEI = 275,
-     LTYPEJ = 276,
-     LTYPEK = 277,
-     LTYPEL = 278,
-     LTYPEM = 279,
-     LTYPEN = 280,
-     LTYPEBX = 281,
-     LTYPEPLD = 282,
-     LCONST = 283,
-     LSP = 284,
-     LSB = 285,
-     LFP = 286,
-     LPC = 287,
-     LTYPEX = 288,
-     LTYPEPC = 289,
-     LTYPEF = 290,
-     LR = 291,
-     LREG = 292,
-     LF = 293,
-     LFREG = 294,
-     LC = 295,
-     LCREG = 296,
-     LPSR = 297,
-     LFCR = 298,
-     LCOND = 299,
-     LS = 300,
-     LAT = 301,
-     LFCONST = 302,
-     LSCONST = 303,
-     LNAME = 304,
-     LLAB = 305,
-     LVAR = 306
-   };
-#endif
-/* Tokens.  */
-#define LTYPE1 258
-#define LTYPE2 259
-#define LTYPE3 260
-#define LTYPE4 261
-#define LTYPE5 262
-#define LTYPE6 263
-#define LTYPE7 264
-#define LTYPE8 265
-#define LTYPE9 266
-#define LTYPEA 267
-#define LTYPEB 268
-#define LGLOBL 269
-#define LTYPEC 270
-#define LTYPED 271
-#define LTYPEE 272
-#define LTYPEG 273
-#define LTYPEH 274
-#define LTYPEI 275
-#define LTYPEJ 276
-#define LTYPEK 277
-#define LTYPEL 278
-#define LTYPEM 279
-#define LTYPEN 280
-#define LTYPEBX 281
-#define LTYPEPLD 282
-#define LCONST 283
-#define LSP 284
-#define LSB 285
-#define LFP 286
-#define LPC 287
-#define LTYPEX 288
-#define LTYPEPC 289
-#define LTYPEF 290
-#define LR 291
-#define LREG 292
-#define LF 293
-#define LFREG 294
-#define LC 295
-#define LCREG 296
-#define LPSR 297
-#define LFCR 298
-#define LCOND 299
-#define LS 300
-#define LAT 301
-#define LFCONST 302
-#define LSCONST 303
-#define LNAME 304
-#define LLAB 305
-#define LVAR 306
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
-
-
-/* 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 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 39 "a.y"
-{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-}
-/* Line 193 of yacc.c.  */
-#line 214 "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 227 "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  2
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   655
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  72
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  35
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  134
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  344
-
-/* 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,     2,     2,     2,    68,    12,     5,     2,
-      69,    70,    10,     8,    65,     9,     2,    11,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    62,    64,
-       6,    63,     7,     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,    66,     2,    67,     4,     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,     3,     2,    71,     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,    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,    49,    50,    51,    52,    53,    54,
-      55,    56,    57,    58,    59,    60,    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,     4,     5,     9,    10,    15,    20,    25,
-      27,    30,    33,    41,    48,    54,    60,    66,    71,    76,
-      80,    84,    89,    96,   104,   112,   120,   127,   134,   138,
-     144,   152,   157,   164,   171,   176,   180,   186,   192,   200,
-     207,   220,   228,   238,   241,   246,   251,   254,   255,   258,
-     261,   262,   265,   270,   273,   275,   278,   282,   287,   290,
-     293,   296,   298,   301,   305,   307,   311,   315,   317,   319,
-     321,   326,   328,   330,   332,   334,   336,   338,   340,   344,
-     346,   351,   353,   358,   360,   362,   364,   366,   369,   371,
-     377,   382,   387,   392,   397,   399,   401,   403,   405,   410,
-     412,   414,   416,   421,   423,   425,   427,   432,   437,   443,
-     451,   452,   455,   458,   460,   462,   464,   466,   468,   471,
-     474,   477,   481,   482,   485,   487,   491,   495,   499,   503,
-     507,   512,   517,   521,   525
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      73,     0,    -1,    -1,    -1,    73,    74,    75,    -1,    -1,
-      59,    62,    76,    75,    -1,    59,    63,   106,    64,    -1,
-      61,    63,   106,    64,    -1,    64,    -1,    77,    64,    -1,
-       1,    64,    -1,    13,    78,    90,    65,    97,    65,    92,
-      -1,    13,    78,    90,    65,    97,    65,    -1,    13,    78,
-      90,    65,    92,    -1,    14,    78,    90,    65,    92,    -1,
-      15,    78,    85,    65,    85,    -1,    16,    78,    79,    80,
-      -1,    16,    78,    79,    86,    -1,    36,    79,    87,    -1,
-      17,    79,    80,    -1,    18,    78,    79,    85,    -1,    19,
-      78,    90,    65,    97,    79,    -1,    20,    78,    88,    65,
-      66,    84,    67,    -1,    20,    78,    66,    84,    67,    65,
-      88,    -1,    21,    78,    92,    65,    87,    65,    92,    -1,
-      21,    78,    92,    65,    87,    79,    -1,    21,    78,    79,
-      87,    65,    92,    -1,    22,    78,    79,    -1,    23,   101,
-      65,    68,    81,    -1,    23,   101,    65,   104,    65,    68,
-      81,    -1,    24,   101,    65,    91,    -1,    24,   101,    65,
-     104,    65,    91,    -1,    25,   101,    11,   104,    65,    82,
-      -1,    26,    78,    92,    79,    -1,    29,    79,    82,    -1,
-      30,    78,   100,    65,   100,    -1,    32,    78,    99,    65,
-     100,    -1,    32,    78,    99,    65,    49,    65,   100,    -1,
-      33,    78,   100,    65,   100,    79,    -1,    31,    78,   104,
-      65,   106,    65,    97,    65,    98,    65,    98,   105,    -1,
-      34,    78,    92,    65,    92,    65,    93,    -1,    35,    78,
-      92,    65,    92,    65,    92,    65,    97,    -1,    37,    89,
-      -1,    44,    85,    65,    85,    -1,    45,    85,    65,    85,
-      -1,    27,    79,    -1,    -1,    78,    54,    -1,    78,    55,
-      -1,    -1,    65,    79,    -1,   104,    69,    42,    70,    -1,
-      59,   102,    -1,    38,    -1,     9,    38,    -1,    38,     9,
-      38,    -1,     9,    38,     9,    38,    -1,    68,   104,    -1,
-      68,    89,    -1,    68,    58,    -1,    83,    -1,    68,    57,
-      -1,    68,     9,    57,    -1,    97,    -1,    97,     9,    97,
-      -1,    97,    79,    84,    -1,    92,    -1,    82,    -1,    94,
-      -1,    94,    69,    97,    70,    -1,    52,    -1,    53,    -1,
-     104,    -1,    89,    -1,   100,    -1,    87,    -1,   101,    -1,
-      69,    97,    70,    -1,    87,    -1,   104,    69,    96,    70,
-      -1,   101,    -1,   101,    69,    96,    70,    -1,    88,    -1,
-      92,    -1,    91,    -1,    94,    -1,    68,   104,    -1,    97,
-      -1,    69,    97,    65,    97,    70,    -1,    97,     6,     6,
-      95,    -1,    97,     7,     7,    95,    -1,    97,     9,     7,
-      95,    -1,    97,    56,     7,    95,    -1,    97,    -1,   104,
-      -1,    47,    -1,    42,    -1,    46,    69,   106,    70,    -1,
-      96,    -1,    39,    -1,    51,    -1,    50,    69,   106,    70,
-      -1,   100,    -1,    83,    -1,    49,    -1,    48,    69,   104,
-      70,    -1,   104,    69,   103,    70,    -1,    59,   102,    69,
-     103,    70,    -1,    59,     6,     7,   102,    69,    40,    70,
-      -1,    -1,     8,   104,    -1,     9,   104,    -1,    40,    -1,
-      39,    -1,    41,    -1,    38,    -1,    61,    -1,     9,   104,
-      -1,     8,   104,    -1,    71,   104,    -1,    69,   106,    70,
-      -1,    -1,    65,   106,    -1,   104,    -1,   106,     8,   106,
-      -1,   106,     9,   106,    -1,   106,    10,   106,    -1,   106,
-      11,   106,    -1,   106,    12,   106,    -1,   106,     6,     6,
-     106,    -1,   106,     7,     7,   106,    -1,   106,     5,   106,
-      -1,   106,     4,   106,    -1,   106,     3,   106,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,    68,    68,    70,    69,    77,    76,    85,    90,    96,
-      97,    98,   104,   108,   112,   119,   126,   133,   137,   144,
-     151,   158,   165,   172,   181,   193,   197,   201,   208,   215,
-     220,   232,   237,   249,   260,   267,   274,   278,   282,   286,
-     293,   315,   323,   332,   339,   348,   359,   365,   368,   372,
-     377,   378,   381,   387,   398,   405,   412,   419,   427,   433,
-     438,   444,   447,   453,   461,   468,   483,   492,   493,   494,
-     495,   500,   506,   512,   518,   519,   522,   523,   531,   540,
-     541,   550,   551,   557,   560,   561,   562,   564,   572,   580,
-     589,   595,   601,   607,   615,   621,   629,   630,   634,   642,
-     643,   649,   650,   658,   659,   662,   668,   676,   684,   692,
-     702,   705,   709,   715,   716,   717,   720,   721,   725,   729,
-     733,   737,   743,   746,   752,   753,   757,   761,   765,   769,
-     773,   777,   781,   785,   789
-};
-#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.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "'|'", "'^'", "'&'", "'<'", "'>'", "'+'",
-  "'-'", "'*'", "'/'", "'%'", "LTYPE1", "LTYPE2", "LTYPE3", "LTYPE4",
-  "LTYPE5", "LTYPE6", "LTYPE7", "LTYPE8", "LTYPE9", "LTYPEA", "LTYPEB",
-  "LGLOBL", "LTYPEC", "LTYPED", "LTYPEE", "LTYPEG", "LTYPEH", "LTYPEI",
-  "LTYPEJ", "LTYPEK", "LTYPEL", "LTYPEM", "LTYPEN", "LTYPEBX", "LTYPEPLD",
-  "LCONST", "LSP", "LSB", "LFP", "LPC", "LTYPEX", "LTYPEPC", "LTYPEF",
-  "LR", "LREG", "LF", "LFREG", "LC", "LCREG", "LPSR", "LFCR", "LCOND",
-  "LS", "LAT", "LFCONST", "LSCONST", "LNAME", "LLAB", "LVAR", "':'", "'='",
-  "';'", "','", "'['", "']'", "'$'", "'('", "')'", "'~'", "$accept",
-  "prog", "@1", "line", "@2", "inst", "cond", "comma", "rel", "textsize",
-  "ximm", "fcon", "reglist", "gen", "nireg", "ireg", "ioreg", "oreg",
-  "imsr", "imm", "reg", "regreg", "shift", "rcon", "sreg", "spreg", "creg",
-  "frcon", "freg", "name", "offset", "pointer", "con", "oexpr", "expr", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   124,    94,    38,    60,    62,    43,    45,
-      42,    47,    37,   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,   304,
-     305,   306,    58,    61,    59,    44,    91,    93,    36,    40,
-      41,   126
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    72,    73,    74,    73,    76,    75,    75,    75,    75,
-      75,    75,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    78,    78,    78,
-      79,    79,    80,    80,    81,    81,    81,    81,    82,    82,
-      82,    82,    83,    83,    84,    84,    84,    85,    85,    85,
-      85,    85,    85,    85,    85,    85,    86,    86,    87,    88,
-      88,    89,    89,    89,    90,    90,    90,    91,    92,    93,
-      94,    94,    94,    94,    95,    95,    96,    96,    96,    97,
-      97,    98,    98,    99,    99,   100,   100,   101,   101,   101,
-     102,   102,   102,   103,   103,   103,   104,   104,   104,   104,
-     104,   104,   105,   105,   106,   106,   106,   106,   106,   106,
-     106,   106,   106,   106,   106
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     0,     0,     3,     0,     4,     4,     4,     1,
-       2,     2,     7,     6,     5,     5,     5,     4,     4,     3,
-       3,     4,     6,     7,     7,     7,     6,     6,     3,     5,
-       7,     4,     6,     6,     4,     3,     5,     5,     7,     6,
-      12,     7,     9,     2,     4,     4,     2,     0,     2,     2,
-       0,     2,     4,     2,     1,     2,     3,     4,     2,     2,
-       2,     1,     2,     3,     1,     3,     3,     1,     1,     1,
-       4,     1,     1,     1,     1,     1,     1,     1,     3,     1,
-       4,     1,     4,     1,     1,     1,     1,     2,     1,     5,
-       4,     4,     4,     4,     1,     1,     1,     1,     4,     1,
-       1,     1,     4,     1,     1,     1,     4,     4,     5,     7,
-       0,     2,     2,     1,     1,     1,     1,     1,     2,     2,
-       2,     3,     0,     2,     1,     3,     3,     3,     3,     3,
-       4,     4,     3,     3,     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_uint8 yydefact[] =
-{
-       2,     3,     1,     0,     0,    47,    47,    47,    47,    50,
-      47,    47,    47,    47,    47,     0,     0,     0,    47,    50,
-      50,    47,    47,    47,    47,    47,    47,    50,     0,     0,
-       0,     0,     0,     9,     4,     0,    11,     0,     0,     0,
-      50,    50,     0,    50,     0,     0,    50,    50,     0,     0,
-     116,   110,   117,     0,     0,     0,     0,     0,     0,     0,
-      46,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      79,    83,    43,    81,     0,   100,    97,     0,    96,     0,
-     105,    71,    72,     0,    68,    61,     0,    74,    67,    69,
-      99,    88,    75,    73,     0,     5,     0,     0,    10,    48,
-      49,     0,     0,    85,    84,    86,     0,     0,     0,    51,
-     110,    20,     0,     0,     0,     0,     0,     0,     0,     0,
-      88,    28,   119,   118,     0,     0,     0,     0,   124,     0,
-     120,     0,     0,     0,     0,    50,    35,     0,     0,     0,
-     104,     0,   103,     0,     0,     0,     0,    19,     0,     0,
-       0,     0,     0,     0,    62,    60,    59,    58,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    87,     0,
-       0,     0,   110,    17,    18,    76,    77,     0,    53,     0,
-      21,     0,     0,    50,     0,     0,     0,     0,   110,   111,
-     112,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   121,     0,     0,   114,   113,   115,     0,    31,
-       0,     0,    34,     0,     0,     0,     0,     0,     0,     0,
-      78,     0,     0,     0,     0,    63,    44,     0,     0,     0,
-       0,     0,    45,     6,     7,     8,    14,    88,    15,    16,
-      53,     0,     0,    50,     0,     0,     0,     0,     0,    50,
-       0,     0,   134,   133,   132,     0,     0,   125,   126,   127,
-     128,   129,     0,    54,    29,     0,   107,     0,     0,    36,
-       0,   105,    37,    50,     0,     0,    82,    80,    98,   106,
-      70,    90,    94,    95,    91,    92,    93,    13,    52,    22,
-       0,    65,    66,     0,    27,    50,    26,     0,   108,   130,
-     131,    55,     0,     0,    32,    33,     0,     0,    39,     0,
-       0,    12,    24,    23,    25,     0,     0,    56,    30,     0,
-      38,     0,    41,     0,   109,    57,     0,     0,     0,     0,
-     101,     0,     0,    42,     0,     0,     0,     0,   122,    89,
-     102,     0,    40,   123
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     1,     3,    34,   165,    35,    37,   109,   111,   264,
-      84,    85,   182,    86,   174,    70,    71,    87,   102,   103,
-      88,   322,    89,   281,    90,   120,   331,   141,    92,    73,
-     127,   208,   128,   342,   129
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -130
-static const yytype_int16 yypact[] =
-{
-    -130,    12,  -130,   305,   -35,  -130,  -130,  -130,  -130,   -33,
-    -130,  -130,  -130,  -130,  -130,   427,   427,   427,  -130,   -33,
-     -33,  -130,  -130,  -130,  -130,  -130,  -130,   -33,   445,   370,
-     370,    10,   -24,  -130,  -130,   -30,  -130,   140,   140,   335,
-     -13,   -33,   449,   -13,   140,    70,   484,   -13,   359,   359,
-    -130,   114,  -130,   359,   359,    27,   -11,    62,    76,   167,
-    -130,     7,   171,   424,    64,   171,   167,   167,    65,   405,
-    -130,  -130,  -130,    68,    74,  -130,  -130,    78,  -130,    86,
-    -130,  -130,  -130,   402,  -130,  -130,    96,  -130,  -130,   107,
-    -130,    21,  -130,    74,   118,  -130,   359,   359,  -130,  -130,
-    -130,   359,   131,  -130,  -130,  -130,   150,   158,   473,  -130,
-      98,  -130,   155,   370,   187,    43,   192,   199,    65,   205,
-    -130,  -130,  -130,  -130,   262,   359,   359,   203,  -130,    90,
-    -130,   106,   164,   233,   359,   -33,  -130,   211,   223,    -3,
-    -130,   226,  -130,   231,   235,   240,    43,  -130,   220,   122,
-     608,   359,   359,   491,  -130,  -130,  -130,    74,   370,    43,
-     287,   291,   300,   301,   370,   305,   560,   582,  -130,    43,
-      43,   370,   114,  -130,  -130,  -130,  -130,   264,  -130,   267,
-    -130,    43,   279,    -4,   281,   122,   283,    65,    98,  -130,
-    -130,   164,   359,   359,   359,   345,   356,   359,   359,   359,
-     359,   359,  -130,    15,   306,  -130,  -130,  -130,   282,  -130,
-     307,   310,  -130,    32,   359,   308,   132,    32,    43,    43,
-    -130,   315,   316,   225,   321,  -130,  -130,   322,   405,   405,
-     405,   405,  -130,  -130,  -130,  -130,  -130,   311,  -130,  -130,
-     203,   204,   323,   -33,   333,    43,    43,    43,    43,   334,
-     331,   337,   631,   611,   547,   359,   359,   228,   228,  -130,
-    -130,  -130,   332,   371,  -130,   353,  -130,   357,     7,  -130,
-     350,   336,  -130,   -33,   340,   361,  -130,  -130,  -130,  -130,
-    -130,  -130,  -130,  -130,  -130,  -130,  -130,    43,  -130,  -130,
-     513,  -130,  -130,   360,  -130,   146,  -130,   384,  -130,   303,
-     303,   425,   399,    15,  -130,  -130,    43,    32,  -130,   373,
-      43,  -130,  -130,  -130,  -130,   375,   408,  -130,  -130,   383,
-    -130,    43,  -130,   385,  -130,  -130,   120,   390,    43,   380,
-    -130,   391,    43,  -130,   359,   120,   394,   275,   403,  -130,
-    -130,   359,  -130,   622
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-    -130,  -130,  -130,   302,  -130,  -130,   589,    24,   362,   166,
-     -58,   411,   -57,    -8,  -130,   -61,   -43,    -7,    22,  -129,
-     -21,  -130,    72,    34,   -94,   -29,   137,  -130,   -51,     3,
-     -84,   286,    20,  -130,    61
-};
-
-/* 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 -65
-static const yytype_int16 yytable[] =
-{
-      91,    91,   116,   136,   209,   245,   215,   147,    91,    91,
-      91,   137,     2,   142,   143,    91,   104,   104,    55,    57,
-      58,    72,    94,   104,   262,   119,   178,   160,   161,    36,
-     162,   107,    41,    42,    98,    56,    56,    56,   135,    97,
-     148,    99,   100,    60,    61,   144,   145,   175,    74,    93,
-      93,    68,    41,   263,   154,   221,   222,   186,   132,    93,
-     106,    41,   112,   -64,   108,   117,   114,   113,   122,   123,
-     118,   121,    95,    96,   130,    83,   156,   163,    48,    49,
-      79,    80,    75,   138,    91,    76,   183,   134,   240,    77,
-      78,   222,   131,   192,   193,   194,   195,   196,   197,   198,
-     199,   200,   201,   157,   250,   180,   125,   126,    50,   105,
-     105,   176,    79,    80,    48,    49,   105,   148,    99,   100,
-     124,   168,   125,   126,    99,   100,   249,   133,   177,    91,
-     227,    52,   139,    93,   146,    91,   115,   149,   304,    69,
-     237,    54,    91,   150,    50,   189,   190,   151,   236,   238,
-     226,   204,   243,   210,   211,   152,   232,   166,   167,   212,
-     202,   158,   269,   239,    76,   272,   273,    52,    77,    78,
-     329,   330,   224,   123,   203,    53,   159,    54,    93,    75,
-      79,   271,    76,   164,    93,    75,    77,    78,    76,   292,
-     293,    93,    77,    78,    99,   100,   169,   274,   275,   282,
-     282,   282,   282,   205,   206,   207,    75,   246,   101,    76,
-     305,    41,   223,    77,    78,   170,   291,   183,   183,    79,
-      80,    99,   100,   171,   179,    99,   100,   294,   192,   193,
-     194,   195,   196,   197,   198,   199,   200,   201,   199,   200,
-     201,    48,    49,   205,   206,   207,   242,   312,   283,   283,
-     283,   283,   181,   252,   253,   254,   320,   184,   257,   258,
-     259,   260,   261,   284,   285,   286,   311,   289,   185,   188,
-     187,    50,   191,   296,   314,   270,   213,   319,   192,   193,
-     194,   195,   196,   197,   198,   199,   200,   201,   214,   323,
-     220,   216,   327,   228,    52,   278,   217,   308,   229,   333,
-     218,   101,    53,   336,    54,   219,     4,   230,   231,   242,
-     117,   197,   198,   199,   200,   201,   299,   300,     5,     6,
-       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,   241,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    48,    49,   340,   244,   247,   248,    29,
-      30,   255,   266,   192,   193,   194,   195,   196,   197,   198,
-     199,   200,   201,   256,    31,   225,    32,    48,    49,    33,
-     301,   265,   267,    50,    75,   268,   287,    76,    48,    49,
-     302,    77,    78,    79,    80,   276,   277,    81,    82,    99,
-     100,   279,   280,   288,    51,   337,    52,    50,   290,   295,
-     297,   307,   343,    83,    69,   309,    54,   298,    50,    75,
-      48,   153,    76,    48,    49,   306,    77,    78,    79,    80,
-      52,   303,    81,    82,   315,   101,   310,   313,    53,    51,
-      54,    52,    48,    49,   316,    48,    49,   317,    83,    69,
-      50,    54,   321,    50,    75,   324,   325,    76,   326,   334,
-     328,    77,    78,    48,    49,   332,   335,    48,    49,   154,
-     155,    51,    50,    52,   339,    50,    52,   233,   341,   318,
-     173,    69,   338,    54,    53,   140,    54,   251,    99,   100,
-       0,    48,    49,    50,     0,    52,    51,    50,    52,     0,
-       0,     0,     0,    53,     0,    54,    53,     0,    54,    48,
-      49,     0,     0,     0,    51,     0,    52,     0,   110,     0,
-      52,    50,     0,     0,    69,     0,    54,     0,    53,     0,
-      54,    48,    49,    75,     0,     0,    76,     0,     0,    50,
-      77,    78,   172,     0,    52,     0,     0,     0,    99,   100,
-       0,     0,    69,     0,    54,     0,     0,     0,   225,    41,
-       0,    50,    52,   195,   196,   197,   198,   199,   200,   201,
-      53,     0,    54,   192,   193,   194,   195,   196,   197,   198,
-     199,   200,   201,     0,    52,     0,     0,     0,     0,     0,
-       0,     0,    69,     0,    54,   192,   193,   194,   195,   196,
-     197,   198,   199,   200,   201,    38,    39,    40,     0,    43,
-      44,    45,    46,    47,     0,     0,     0,    59,     0,     0,
-      62,    63,    64,    65,    66,    67,   194,   195,   196,   197,
-     198,   199,   200,   201,   234,   192,   193,   194,   195,   196,
-     197,   198,   199,   200,   201,   193,   194,   195,   196,   197,
-     198,   199,   200,   201,     0,     0,   235,   205,   206,   207,
-      76,     0,     0,     0,    77,    78
-};
-
-static const yytype_int16 yycheck[] =
-{
-      29,    30,    45,    61,   133,     9,     9,    68,    37,    38,
-      39,    62,     0,    64,    65,    44,    37,    38,    15,    16,
-      17,    28,    30,    44,     9,    46,   110,     6,     7,    64,
-       9,    39,    65,     9,    64,    15,    16,    17,    59,    63,
-      69,    54,    55,    19,    20,    66,    67,   108,    28,    29,
-      30,    27,    65,    38,    57,   149,   150,   118,    69,    39,
-      38,    65,    42,    67,    40,    45,    44,    43,    48,    49,
-      46,    47,    62,    63,    54,    68,    83,    56,     8,     9,
-      48,    49,    39,    63,   113,    42,   115,    11,   172,    46,
-      47,   185,    65,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    83,   188,   113,     8,     9,    38,    37,
-      38,   108,    48,    49,     8,     9,    44,   146,    54,    55,
-       6,   101,     8,     9,    54,    55,   187,    65,   108,   158,
-     159,    61,    68,   113,    69,   164,    66,    69,   267,    69,
-     169,    71,   171,    69,    38,   125,   126,    69,   169,   170,
-     158,   131,   181,   133,   134,    69,   164,    96,    97,   135,
-      70,    65,   213,   171,    42,   216,   217,    61,    46,    47,
-      50,    51,   152,   153,    68,    69,    69,    71,   158,    39,
-      48,    49,    42,    65,   164,    39,    46,    47,    42,   246,
-     247,   171,    46,    47,    54,    55,    65,   218,   219,   228,
-     229,   230,   231,    39,    40,    41,    39,   183,    68,    42,
-     268,    65,   151,    46,    47,    65,   245,   246,   247,    48,
-      49,    54,    55,    65,    69,    54,    55,   248,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    10,    11,
-      12,     8,     9,    39,    40,    41,    42,   290,   228,   229,
-     230,   231,    65,   192,   193,   194,   307,    65,   197,   198,
-     199,   200,   201,   229,   230,   231,   287,   243,    69,     7,
-      65,    38,    69,   249,   295,   214,    65,   306,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    65,   310,
-      70,    65,   321,     6,    61,    70,    65,   273,     7,   328,
-      65,    68,    69,   332,    71,    65,     1,     7,     7,    42,
-     290,     8,     9,    10,    11,    12,   255,   256,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    69,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,     8,     9,    70,    67,    66,    65,    44,
-      45,     6,    70,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,     7,    59,    57,    61,     8,     9,    64,
-      38,    65,    65,    38,    39,    65,    65,    42,     8,     9,
-       9,    46,    47,    48,    49,    70,    70,    52,    53,    54,
-      55,    70,    70,    70,    59,   334,    61,    38,    65,    65,
-      69,    65,   341,    68,    69,    65,    71,    70,    38,    39,
-       8,     9,    42,     8,     9,    65,    46,    47,    48,    49,
-      61,    68,    52,    53,    40,    68,    65,    67,    69,    59,
-      71,    61,     8,     9,     9,     8,     9,    38,    68,    69,
-      38,    71,    69,    38,    39,    70,    38,    42,    65,    69,
-      65,    46,    47,     8,     9,    65,    65,     8,     9,    57,
-      58,    59,    38,    61,    70,    38,    61,   165,    65,   303,
-     108,    69,   335,    71,    69,    64,    71,   191,    54,    55,
-      -1,     8,     9,    38,    -1,    61,    59,    38,    61,    -1,
-      -1,    -1,    -1,    69,    -1,    71,    69,    -1,    71,     8,
-       9,    -1,    -1,    -1,    59,    -1,    61,    -1,    59,    -1,
-      61,    38,    -1,    -1,    69,    -1,    71,    -1,    69,    -1,
-      71,     8,     9,    39,    -1,    -1,    42,    -1,    -1,    38,
-      46,    47,    59,    -1,    61,    -1,    -1,    -1,    54,    55,
-      -1,    -1,    69,    -1,    71,    -1,    -1,    -1,    57,    65,
-      -1,    38,    61,     6,     7,     8,     9,    10,    11,    12,
-      69,    -1,    71,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    -1,    61,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    69,    -1,    71,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,     6,     7,     8,    -1,    10,
-      11,    12,    13,    14,    -1,    -1,    -1,    18,    -1,    -1,
-      21,    22,    23,    24,    25,    26,     5,     6,     7,     8,
-       9,    10,    11,    12,    64,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,     4,     5,     6,     7,     8,
-       9,    10,    11,    12,    -1,    -1,    64,    39,    40,    41,
-      42,    -1,    -1,    -1,    46,    47
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,    73,     0,    74,     1,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      29,    30,    31,    32,    33,    34,    35,    36,    37,    44,
-      45,    59,    61,    64,    75,    77,    64,    78,    78,    78,
-      78,    65,    79,    78,    78,    78,    78,    78,     8,     9,
-      38,    59,    61,    69,    71,   101,   104,   101,   101,    78,
-      79,    79,    78,    78,    78,    78,    78,    78,    79,    69,
-      87,    88,    89,   101,   104,    39,    42,    46,    47,    48,
-      49,    52,    53,    68,    82,    83,    85,    89,    92,    94,
-      96,    97,   100,   104,    85,    62,    63,    63,    64,    54,
-      55,    68,    90,    91,    92,    94,    90,    85,    79,    79,
-      59,    80,   104,    79,    90,    66,    88,   104,    79,    92,
-      97,    79,   104,   104,     6,     8,     9,   102,   104,   106,
-     104,    65,    69,    65,    11,    92,    82,   100,   104,    68,
-      83,    99,   100,   100,    92,    92,    69,    87,    97,    69,
-      69,    69,    69,     9,    57,    58,    89,   104,    65,    69,
-       6,     7,     9,    56,    65,    76,   106,   106,   104,    65,
-      65,    65,    59,    80,    86,    87,   101,   104,   102,    69,
-      85,    65,    84,    97,    65,    69,    87,    65,     7,   104,
-     104,    69,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,    12,    70,    68,   104,    39,    40,    41,   103,    91,
-     104,   104,    79,    65,    65,     9,    65,    65,    65,    65,
-      70,    96,    96,   106,   104,    57,    85,    97,     6,     7,
-       7,     7,    85,    75,    64,    64,    92,    97,    92,    85,
-     102,    69,    42,    97,    67,     9,    79,    66,    65,    87,
-     102,   103,   106,   106,   106,     6,     7,   106,   106,   106,
-     106,   106,     9,    38,    81,    65,    70,    65,    65,   100,
-     106,    49,   100,   100,    92,    92,    70,    70,    70,    70,
-      70,    95,    97,   104,    95,    95,    95,    65,    70,    79,
-      65,    97,    84,    84,    92,    65,    79,    69,    70,   106,
-     106,    38,     9,    68,    91,    82,    65,    65,    79,    65,
-      65,    92,    88,    67,    92,    40,     9,    38,    81,    97,
-     100,    69,    93,    92,    70,    38,    65,    97,    65,    50,
-      51,    98,    65,    97,    69,    65,    97,   106,    98,    70,
-      70,    65,   105,   106
-};
-
-#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;
-
-/* 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 yystate;
-  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 3:
-#line 70 "a.y"
-    {
-		stmtline = lineno;
-	}
-    break;
-
-  case 5:
-#line 77 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
-			yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyvsp[(1) - (2)].sym)->type = LLAB;
-		(yyvsp[(1) - (2)].sym)->value = pc;
-	}
-    break;
-
-  case 7:
-#line 86 "a.y"
-    {
-		(yyvsp[(1) - (4)].sym)->type = LVAR;
-		(yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 8:
-#line 91 "a.y"
-    {
-		if((yyvsp[(1) - (4)].sym)->value != (yyvsp[(3) - (4)].lval))
-			yyerror("redeclaration of %s", (yyvsp[(1) - (4)].sym)->name);
-		(yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 12:
-#line 105 "a.y"
-    {
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
-	}
-    break;
-
-  case 13:
-#line 109 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
-	}
-    break;
-
-  case 14:
-#line 113 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 15:
-#line 120 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 16:
-#line 127 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 17:
-#line 134 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 18:
-#line 138 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 19:
-#line 145 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 20:
-#line 152 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 21:
-#line 159 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 22:
-#line 166 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
-	}
-    break;
-
-  case 23:
-#line 173 "a.y"
-    {
-		Addr g;
-
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = (yyvsp[(6) - (7)].lval);
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), 0, &g);
-	}
-    break;
-
-  case 24:
-#line 182 "a.y"
-    {
-		Addr g;
-
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = (yyvsp[(4) - (7)].lval);
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, 0, &(yyvsp[(7) - (7)].addr));
-	}
-    break;
-
-  case 25:
-#line 194 "a.y"
-    {
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(5) - (7)].addr), (yyvsp[(3) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
-	}
-    break;
-
-  case 26:
-#line 198 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].addr), (yyvsp[(3) - (6)].addr).reg, &(yyvsp[(3) - (6)].addr));
-	}
-    break;
-
-  case 27:
-#line 202 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(4) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 28:
-#line 209 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 29:
-#line 216 "a.y"
-    {
-		settext((yyvsp[(2) - (5)].addr).sym);
-		outcode((yyvsp[(1) - (5)].lval), Always, &(yyvsp[(2) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 30:
-#line 221 "a.y"
-    {
-		settext((yyvsp[(2) - (7)].addr).sym);
-		outcode((yyvsp[(1) - (7)].lval), Always, &(yyvsp[(2) - (7)].addr), 0, &(yyvsp[(7) - (7)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (7)].lval);
-		}
-	}
-    break;
-
-  case 31:
-#line 233 "a.y"
-    {
-		settext((yyvsp[(2) - (4)].addr).sym);
-		outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 32:
-#line 238 "a.y"
-    {
-		settext((yyvsp[(2) - (6)].addr).sym);
-		outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 33:
-#line 250 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 34:
-#line 261 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 35:
-#line 268 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 36:
-#line 275 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 37:
-#line 279 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 38:
-#line 283 "a.y"
-    {
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
-	}
-    break;
-
-  case 39:
-#line 287 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr).reg, &nullgen);
-	}
-    break;
-
-  case 40:
-#line 294 "a.y"
-    {
-		Addr g;
-
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset =
-			(0xe << 24) |		/* opcode */
-			((yyvsp[(1) - (12)].lval) << 20) |		/* MCR/MRC */
-			(((yyvsp[(2) - (12)].lval)^C_SCOND_XOR) << 28) |		/* scond */
-			(((yyvsp[(3) - (12)].lval) & 15) << 8) |	/* coprocessor number */
-			(((yyvsp[(5) - (12)].lval) & 7) << 21) |	/* coprocessor operation */
-			(((yyvsp[(7) - (12)].lval) & 15) << 12) |	/* arm register */
-			(((yyvsp[(9) - (12)].lval) & 15) << 16) |	/* Crn */
-			(((yyvsp[(11) - (12)].lval) & 15) << 0) |	/* Crm */
-			(((yyvsp[(12) - (12)].lval) & 7) << 5) |	/* coprocessor information */
-			(1<<4);			/* must be set */
-		outcode(AMRC, Always, &nullgen, 0, &g);
-	}
-    break;
-
-  case 41:
-#line 316 "a.y"
-    {
-		outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
-	}
-    break;
-
-  case 42:
-#line 324 "a.y"
-    {
-		(yyvsp[(7) - (9)].addr).type = TYPE_REGREG2;
-		(yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval);
-		outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].addr), (yyvsp[(5) - (9)].addr).reg, &(yyvsp[(7) - (9)].addr));
-	}
-    break;
-
-  case 43:
-#line 333 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 44:
-#line 340 "a.y"
-    {
-		if((yyvsp[(2) - (4)].addr).type != TYPE_CONST || (yyvsp[(4) - (4)].addr).type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
-		outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 45:
-#line 349 "a.y"
-    {
-		if((yyvsp[(2) - (4)].addr).type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if((yyvsp[(4) - (4)].addr).type != NAME_EXTERN && (yyvsp[(4) - (4)].addr).type != NAME_STATIC && (yyvsp[(4) - (4)].addr).type != TYPE_MEM)
-			yyerror("value for FUNCDATA must be symbol reference");
- 		outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 46:
-#line 360 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 47:
-#line 365 "a.y"
-    {
-		(yyval.lval) = Always;
-	}
-    break;
-
-  case 48:
-#line 369 "a.y"
-    {
-		(yyval.lval) = ((yyvsp[(1) - (2)].lval) & ~C_SCOND) | (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 49:
-#line 373 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (2)].lval) | (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 52:
-#line 382 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
-	}
-    break;
-
-  case 53:
-#line 388 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		(yyval.addr) = nullgen;
-		if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
-			yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 54:
-#line 399 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 55:
-#line 406 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (2)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 56:
-#line 413 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (3)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 57:
-#line 420 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (4)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 58:
-#line 428 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 59:
-#line 434 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-		(yyval.addr).type = TYPE_ADDR;
-	}
-    break;
-
-  case 60:
-#line 439 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SCONST;
-		memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
-	}
-    break;
-
-  case 62:
-#line 448 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
-	}
-    break;
-
-  case 63:
-#line 454 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
-	}
-    break;
-
-  case 64:
-#line 462 "a.y"
-    {
-		if((yyvsp[(1) - (1)].lval) < REG_R0 || (yyvsp[(1) - (1)].lval) > REG_R15)
-			yyerror("invalid register in reglist");
-
-		(yyval.lval) = 1 << ((yyvsp[(1) - (1)].lval)&15);
-	}
-    break;
-
-  case 65:
-#line 469 "a.y"
-    {
-		int i;
-
-		if((yyvsp[(1) - (3)].lval) < REG_R0 || (yyvsp[(1) - (3)].lval) > REG_R15)
-			yyerror("invalid register in reglist");
-		if((yyvsp[(3) - (3)].lval) < REG_R0 || (yyvsp[(3) - (3)].lval) > REG_R15)
-			yyerror("invalid register in reglist");
-
-		(yyval.lval)=0;
-		for(i=(yyvsp[(1) - (3)].lval); i<=(yyvsp[(3) - (3)].lval); i++)
-			(yyval.lval) |= 1<<(i&15);
-		for(i=(yyvsp[(3) - (3)].lval); i<=(yyvsp[(1) - (3)].lval); i++)
-			(yyval.lval) |= 1<<(i&15);
-	}
-    break;
-
-  case 66:
-#line 484 "a.y"
-    {
-		if((yyvsp[(1) - (3)].lval) < REG_R0 || (yyvsp[(1) - (3)].lval) > REG_R15)
-			yyerror("invalid register in reglist");
-
-		(yyval.lval) = (1<<((yyvsp[(1) - (3)].lval)&15)) | (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 70:
-#line 496 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (4)].addr);
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 71:
-#line 501 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 72:
-#line 507 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 73:
-#line 513 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 77:
-#line 524 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (1)].addr);
-		if((yyvsp[(1) - (1)].addr).name != NAME_EXTERN && (yyvsp[(1) - (1)].addr).name != NAME_STATIC) {
-		}
-	}
-    break;
-
-  case 78:
-#line 532 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (3)].lval);
-		(yyval.addr).offset = 0;
-	}
-    break;
-
-  case 80:
-#line 542 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 82:
-#line 552 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (4)].addr);
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 87:
-#line 565 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 88:
-#line 573 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 89:
-#line 581 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REGREG;
-		(yyval.addr).reg = (yyvsp[(2) - (5)].lval);
-		(yyval.addr).offset = (yyvsp[(4) - (5)].lval);
-	}
-    break;
-
-  case 90:
-#line 590 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SHIFT;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (0 << 5);
-	}
-    break;
-
-  case 91:
-#line 596 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SHIFT;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (1 << 5);
-	}
-    break;
-
-  case 92:
-#line 602 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SHIFT;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (2 << 5);
-	}
-    break;
-
-  case 93:
-#line 608 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SHIFT;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (3 << 5);
-	}
-    break;
-
-  case 94:
-#line 616 "a.y"
-    {
-		if((yyval.lval) < REG_R0 || (yyval.lval) > REG_R15)
-			print("register value out of range in shift\n");
-		(yyval.lval) = (((yyvsp[(1) - (1)].lval)&15) << 8) | (1 << 4);
-	}
-    break;
-
-  case 95:
-#line 622 "a.y"
-    {
-		if((yyval.lval) < 0 || (yyval.lval) >= 32)
-			print("shift value out of range\n");
-		(yyval.lval) = ((yyvsp[(1) - (1)].lval)&31) << 7;
-	}
-    break;
-
-  case 97:
-#line 631 "a.y"
-    {
-		(yyval.lval) = REGPC;
-	}
-    break;
-
-  case 98:
-#line 635 "a.y"
-    {
-		if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
-			print("register value out of range in R(...)\n");
-		(yyval.lval) = REG_R0 + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 100:
-#line 644 "a.y"
-    {
-		(yyval.lval) = REGSP;
-	}
-    break;
-
-  case 102:
-#line 651 "a.y"
-    {
-		if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
-			print("register value out of range in C(...)\n");
-		(yyval.lval) = (yyvsp[(3) - (4)].lval); // TODO(rsc): REG_C0+$3
-	}
-    break;
-
-  case 105:
-#line 663 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 106:
-#line 669 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = REG_F0 + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 107:
-#line 677 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).sym = nil;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 108:
-#line 685 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(4) - (5)].lval);
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
-		(yyval.addr).offset = (yyvsp[(2) - (5)].lval);
-	}
-    break;
-
-  case 109:
-#line 693 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = NAME_STATIC;
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
-		(yyval.addr).offset = (yyvsp[(4) - (7)].lval);
-	}
-    break;
-
-  case 110:
-#line 702 "a.y"
-    {
-		(yyval.lval) = 0;
-	}
-    break;
-
-  case 111:
-#line 706 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 112:
-#line 710 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 117:
-#line 722 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
-	}
-    break;
-
-  case 118:
-#line 726 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 119:
-#line 730 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 120:
-#line 734 "a.y"
-    {
-		(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 121:
-#line 738 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 122:
-#line 743 "a.y"
-    {
-		(yyval.lval) = 0;
-	}
-    break;
-
-  case 123:
-#line 747 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 125:
-#line 754 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 126:
-#line 758 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 127:
-#line 762 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 128:
-#line 766 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 129:
-#line 770 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 130:
-#line 774 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 131:
-#line 778 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 132:
-#line 782 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 133:
-#line 786 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 134:
-#line 790 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 2642 "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);
-}
-
-
-
diff --git a/src/cmd/5a/y.tab.h b/src/cmd/5a/y.tab.h
deleted file mode 100644
index fbbdbef..0000000
--- a/src/cmd/5a/y.tab.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* 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 {
-     LTYPE1 = 258,
-     LTYPE2 = 259,
-     LTYPE3 = 260,
-     LTYPE4 = 261,
-     LTYPE5 = 262,
-     LTYPE6 = 263,
-     LTYPE7 = 264,
-     LTYPE8 = 265,
-     LTYPE9 = 266,
-     LTYPEA = 267,
-     LTYPEB = 268,
-     LGLOBL = 269,
-     LTYPEC = 270,
-     LTYPED = 271,
-     LTYPEE = 272,
-     LTYPEG = 273,
-     LTYPEH = 274,
-     LTYPEI = 275,
-     LTYPEJ = 276,
-     LTYPEK = 277,
-     LTYPEL = 278,
-     LTYPEM = 279,
-     LTYPEN = 280,
-     LTYPEBX = 281,
-     LTYPEPLD = 282,
-     LCONST = 283,
-     LSP = 284,
-     LSB = 285,
-     LFP = 286,
-     LPC = 287,
-     LTYPEX = 288,
-     LTYPEPC = 289,
-     LTYPEF = 290,
-     LR = 291,
-     LREG = 292,
-     LF = 293,
-     LFREG = 294,
-     LC = 295,
-     LCREG = 296,
-     LPSR = 297,
-     LFCR = 298,
-     LCOND = 299,
-     LS = 300,
-     LAT = 301,
-     LFCONST = 302,
-     LSCONST = 303,
-     LNAME = 304,
-     LLAB = 305,
-     LVAR = 306
-   };
-#endif
-/* Tokens.  */
-#define LTYPE1 258
-#define LTYPE2 259
-#define LTYPE3 260
-#define LTYPE4 261
-#define LTYPE5 262
-#define LTYPE6 263
-#define LTYPE7 264
-#define LTYPE8 265
-#define LTYPE9 266
-#define LTYPEA 267
-#define LTYPEB 268
-#define LGLOBL 269
-#define LTYPEC 270
-#define LTYPED 271
-#define LTYPEE 272
-#define LTYPEG 273
-#define LTYPEH 274
-#define LTYPEI 275
-#define LTYPEJ 276
-#define LTYPEK 277
-#define LTYPEL 278
-#define LTYPEM 279
-#define LTYPEN 280
-#define LTYPEBX 281
-#define LTYPEPLD 282
-#define LCONST 283
-#define LSP 284
-#define LSB 285
-#define LFP 286
-#define LPC 287
-#define LTYPEX 288
-#define LTYPEPC 289
-#define LTYPEF 290
-#define LR 291
-#define LREG 292
-#define LF 293
-#define LFREG 294
-#define LC 295
-#define LCREG 296
-#define LPSR 297
-#define LFCR 298
-#define LCOND 299
-#define LS 300
-#define LAT 301
-#define LFCONST 302
-#define LSCONST 303
-#define LNAME 304
-#define LLAB 305
-#define LVAR 306
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 39 "a.y"
-{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-}
-/* Line 1529 of yacc.c.  */
-#line 159 "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/5g/Makefile b/src/cmd/5g/Makefile
deleted file mode 100644
index 3f528d7..0000000
--- a/src/cmd/5g/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
deleted file mode 100644
index 354e0cb..0000000
--- a/src/cmd/5g/cgen.c
+++ /dev/null
@@ -1,1840 +0,0 @@
-// 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"
-
-/*
- * generate:
- *	res = n;
- * simplifies and calls gmove.
- */
-void
-cgen(Node *n, Node *res)
-{
-	Node *nl, *nr, *r;
-	Node n1, n2, f0, f1;
-	int a, w, rg;
-	Prog *p1, *p2, *p3;
-	Addr addr;
-
-	if(debug['g']) {
-		dump("\ncgen-n", n);
-		dump("cgen-res", res);
-	}
-	if(n == N || n->type == T)
-		goto ret;
-
-	if(res == N || res->type == T)
-		fatal("cgen: res nil");
-
-	switch(n->op) {
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_slice(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_slice(n, res);
-		return;
-	case OEFACE:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_eface(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_eface(n, res);
-		return;
-	}
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	if(n->ullman >= UINF) {
-		if(n->op == OINDREG)
-			fatal("cgen: this is going to misscompile");
-		if(res->ullman >= UINF) {
-			tempname(&n1, n->type);
-			cgen(n, &n1);
-			cgen(&n1, res);
-			goto ret;
-		}
-	}
-
-	if(isfat(n->type)) {
-		if(n->type->width < 0)
-			fatal("forgot to compute width for %T", n->type);
-		sgen(n, res, n->type->width);
-		goto ret;
-	}
-
-
-	// update addressability for string, slice
-	// can't do in walk because n->left->addable
-	// changes if n->left is an escaping local variable.
-	switch(n->op) {
-	case OSPTR:
-	case OLEN:
-		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
-			n->addable = n->left->addable;
-		break;
-	case OCAP:
-		if(isslice(n->left->type))
-			n->addable = n->left->addable;
-		break;
-	case OITAB:
-		n->addable = n->left->addable;
-		break;
-	}
-
-	// if both are addressable, move
-	if(n->addable && res->addable) {
-		if(is64(n->type) || is64(res->type) ||
-		   n->op == OREGISTER || res->op == OREGISTER ||
-		   iscomplex[n->type->etype] || iscomplex[res->type->etype]) {
-			gmove(n, res);
-		} else {
-			regalloc(&n1, n->type, N);
-			gmove(n, &n1);
-			cgen(&n1, res);
-			regfree(&n1);
-		}
-		goto ret;
-	}
-
-	// if both are not addressable, use a temporary.
-	if(!n->addable && !res->addable) {
-		// could use regalloc here sometimes,
-		// but have to check for ullman >= UINF.
-		tempname(&n1, n->type);
-		cgen(n, &n1);
-		cgen(&n1, res);
-		return;
-	}
-
-	// if result is not addressable directly but n is,
-	// compute its address and then store via the address.
-	if(!res->addable) {
-		igen(res, &n1, N);
-		cgen(n, &n1);
-		regfree(&n1);
-		return;
-	}
-
-	if(complexop(n, res)) {
-		complexgen(n, res);
-		return;
-	}
-
-	// if n is sudoaddable generate addr and move
-	if (!is64(n->type) && !is64(res->type) && !iscomplex[n->type->etype] && !iscomplex[res->type->etype]) {
-		a = optoas(OAS, n->type);
-		if(sudoaddable(a, n, &addr, &w)) {
-			if (res->op != OREGISTER) {
-				regalloc(&n2, res->type, N);
-				p1 = gins(a, N, &n2);
-				p1->from = addr;
-				if(debug['g'])
-					print("%P [ignore previous line]\n", p1);
-				gmove(&n2, res);
-				regfree(&n2);
-			} else {
-				p1 = gins(a, N, res);
-				p1->from = addr;
-				if(debug['g'])
-					print("%P [ignore previous line]\n", p1);
-			}
-			sudoclean();
-			goto ret;
-		}
-	}
-
-	// otherwise, the result is addressable but n is not.
-	// let's do some computation.
-
-	nl = n->left;
-	nr = n->right;
-
-	if(nl != N && nl->ullman >= UINF)
-	if(nr != N && nr->ullman >= UINF) {
-		tempname(&n1, nl->type);
-		cgen(nl, &n1);
-		n2 = *n;
-		n2.left = &n1;
-		cgen(&n2, res);
-		goto ret;
-	}
-
-	// 64-bit ops are hard on 32-bit machine.
-	if(is64(n->type) || is64(res->type) || n->left != N && is64(n->left->type)) {
-		switch(n->op) {
-		// math goes to cgen64.
-		case OMINUS:
-		case OCOM:
-		case OADD:
-		case OSUB:
-		case OMUL:
-		case OLROT:
-		case OLSH:
-		case ORSH:
-		case OAND:
-		case OOR:
-		case OXOR:
-			cgen64(n, res);
-			return;
-		}
-	}
-
-	if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype])
-		goto flt;
-	switch(n->op) {
-	default:
-		dump("cgen", n);
-		fatal("cgen: unknown op %+hN", n);
-		break;
-
-	case OREAL:
-	case OIMAG:
-	case OCOMPLEX:
-		fatal("unexpected complex");
-		break;
-
-	// these call bgen to get a bool value
-	case OOROR:
-	case OANDAND:
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OLE:
-	case OGE:
-	case OGT:
-	case ONOT:
-		p1 = gbranch(AB, T, 0);
-		p2 = pc;
-		gmove(nodbool(1), res);
-		p3 = gbranch(AB, T, 0);
-		patch(p1, pc);
-		bgen(n, 1, 0, p2);
-		gmove(nodbool(0), res);
-		patch(p3, pc);
-		goto ret;
-
-	case OPLUS:
-		cgen(nl, res);
-		goto ret;
-
-	// unary
-	case OCOM:
-		a = optoas(OXOR, nl->type);
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		nodconst(&n2, nl->type, -1);
-		gins(a, &n2, &n1);
-		goto norm;
-
-	case OMINUS:
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		nodconst(&n2, nl->type, 0);
-		gins(optoas(OMINUS, nl->type), &n2, &n1);
-		goto norm;
-
-	// symmetric binary
-	case OAND:
-	case OOR:
-	case OXOR:
-	case OADD:
-	case OMUL:
-		a = optoas(n->op, nl->type);
-		goto sbop;
-
-	// asymmetric binary
-	case OSUB:
-		a = optoas(n->op, nl->type);
-		goto abop;
-
-	case OHMUL:
-		cgen_hmul(nl, nr, res);
-		break;
-
-	case OLROT:
-	case OLSH:
-	case ORSH:
-		cgen_shift(n->op, n->bounded, nl, nr, res);
-		break;
-
-	case OCONV:
-		if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
-			cgen(nl, res);
-			break;
-		}
-		if(nl->addable && !is64(nl->type)) {
-			regalloc(&n1, nl->type, res);
-			gmove(nl, &n1);
-		} else {
-			if(n->type->width > widthptr || is64(nl->type) || isfloat[nl->type->etype])
-				tempname(&n1, nl->type);
-			else
-				regalloc(&n1, nl->type, res);
-			cgen(nl, &n1);
-		}
-		if(n->type->width > widthptr || is64(n->type) || isfloat[n->type->etype])
-			tempname(&n2, n->type);
-		else
-			regalloc(&n2, n->type, N);
-		gmove(&n1, &n2);
-		gmove(&n2, res);
-		if(n1.op == OREGISTER)
-			regfree(&n1);
-		if(n2.op == OREGISTER)
-			regfree(&n2);
-		break;
-
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OIND:
-	case ONAME:	// PHEAP or PPARAMREF var
-		igen(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OITAB:
-		// interface table is first word of interface value
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OSPTR:
-		// pointer is the first word of string or slice.
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n1, types[tptr], res);
-			p1 = gins(AMOVW, N, &n1);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OLEN:
-		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
-			// map has len in the first 32-bit word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gcmp(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.type = types[TINT32];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
-			// both slice and string have len one pointer into the struct.
-			igen(nl, &n1, res);
-			n1.type = types[TUINT32];
-			n1.xoffset += Array_nel;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OLEN: unknown type %lT", nl->type);
-		break;
-
-	case OCAP:
-		if(istype(nl->type, TCHAN)) {
-			// chan has cap in the second 32-bit word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gcmp(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.xoffset = 4;
-			n2.type = types[TINT32];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(isslice(nl->type)) {
-			igen(nl, &n1, res);
-			n1.type = types[TUINT32];
-			n1.xoffset += Array_cap;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OCAP: unknown type %lT", nl->type);
-		break;
-
-	case OADDR:
-		agen(nl, res);
-		break;
-
-	case OCALLMETH:
-	case OCALLFUNC:
-		// Release res so that it is available for cgen_call.
-		// Pick it up again after the call.
-		rg = -1;
-		if(n->ullman >= UINF) {
-			if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
-				rg = res->val.u.reg;
-				reg[rg]--;
-			}
-		}
-		if(n->op == OCALLMETH)
-			cgen_callmeth(n, 0);
-		else
-			cgen_call(n, 0);
-		if(rg >= 0)
-			reg[rg]++;
-		cgen_callret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OMOD:
-	case ODIV:
-		a = optoas(n->op, nl->type);
-		goto abop;
-	}
-	goto ret;
-
-sbop:	// symmetric binary
-	if(nl->ullman < nr->ullman) {
-		r = nl;
-		nl = nr;
-		nr = r;
-	}
-
-abop:	// asymmetric binary
-	// TODO(kaib): use fewer registers here.
-	if(nl->ullman >= nr->ullman) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-		switch(n->op) {
-		case OADD:
-		case OSUB:
-		case OAND:
-		case OOR:
-		case OXOR:
-			if(smallintconst(nr)) {
-				n2 = *nr;
-				break;
-			}
-		default:
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-		}
-	} else {
-		switch(n->op) {
-		case OADD:
-		case OSUB:
-		case OAND:
-		case OOR:
-		case OXOR:
-			if(smallintconst(nr)) {
-				n2 = *nr;
-				break;
-			}
-		default:
-			regalloc(&n2, nr->type, res);
-			cgen(nr, &n2);
-		}
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-	}
-	gins(a, &n2, &n1);
-norm:
-	// Normalize result for types smaller than word.
-	if(n->type->width < widthptr) {
-		switch(n->op) {
-		case OADD:
-		case OSUB:
-		case OMUL:
-		case OCOM:
-		case OMINUS:
-			gins(optoas(OAS, n->type), &n1, &n1);
-			break;
-		}
-	}
-	gmove(&n1, res);
-	regfree(&n1);
-	if(n2.op != OLITERAL)
-		regfree(&n2);
-	goto ret;
-
-flt:	// floating-point.
-	regalloc(&f0, nl->type, res);
-	if(nr != N)
-		goto flt2;
-
-	if(n->op == OMINUS) {
-		nr = nodintconst(-1);
-		convlit(&nr, n->type);
-		n->op = OMUL;
-		goto flt2;
-	}
-
-	// unary
-	cgen(nl, &f0);
-	if(n->op != OCONV && n->op != OPLUS)
-		gins(optoas(n->op, n->type), &f0, &f0);
-	gmove(&f0, res);
-	regfree(&f0);
-	goto ret;
-
-flt2:	// binary
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &f0);
-		regalloc(&f1, n->type, N);
-		gmove(&f0, &f1);
-		cgen(nr, &f0);
-		gins(optoas(n->op, n->type), &f0, &f1);
-	} else {
-		cgen(nr, &f0);
-		regalloc(&f1, n->type, N);
-		cgen(nl, &f1);
-		gins(optoas(n->op, n->type), &f0, &f1);
-	}
-	gmove(&f1, res);
-	regfree(&f0);
-	regfree(&f1);
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * generate array index into res.
- * n might be any size; res is 32-bit.
- * returns Prog* to patch to panic call.
- */
-Prog*
-cgenindex(Node *n, Node *res, int bounded)
-{
-	Node tmp, lo, hi, zero, n1, n2;
-
-	if(!is64(n->type)) {
-		cgen(n, res);
-		return nil;
-	}
-
-	tempname(&tmp, types[TINT64]);
-	cgen(n, &tmp);
-	split64(&tmp, &lo, &hi);
-	gmove(&lo, res);
-	if(bounded) {
-		splitclean();
-		return nil;
-	}
-	regalloc(&n1, types[TINT32], N);
-	regalloc(&n2, types[TINT32], N);
-	nodconst(&zero, types[TINT32], 0);
-	gmove(&hi, &n1);
-	gmove(&zero, &n2);
-	gcmp(ACMP, &n1, &n2);
-	regfree(&n2);
-	regfree(&n1);
-	splitclean();
-	return gbranch(ABNE, T, -1);
-}
-
-/*
- * generate:
- *	res = &n;
- * The generated code checks that the result is not nil.
- */
-void
-agen(Node *n, Node *res)
-{
-	Node *nl;
-	Node n1, n2, n3;
-	int r;
-
-	if(debug['g']) {
-		dump("\nagen-res", res);
-		dump("agen-r", n);
-	}
-	if(n == N || n->type == T || res == N || res->type == T)
-		fatal("agen");
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	if(isconst(n, CTNIL) && n->type->width > widthptr) {
-		// Use of a nil interface or nil slice.
-		// Create a temporary we can take the address of and read.
-		// The generated code is just going to panic, so it need not
-		// be terribly efficient. See issue 3670.
-		tempname(&n1, n->type);
-		gvardef(&n1);
-		clearfat(&n1);
-		regalloc(&n2, types[tptr], res);
-		gins(AMOVW, &n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		goto ret;
-	}
-		
-
-	if(n->addable) {
-		memset(&n1, 0, sizeof n1);
-		n1.op = OADDR;
-		n1.left = n;
-		regalloc(&n2, types[tptr], res);
-		gins(AMOVW, &n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		goto ret;
-	}
-
-	nl = n->left;
-
-	switch(n->op) {
-	default:
-		fatal("agen: unknown op %+hN", n);
-		break;
-
-	case OCALLMETH:
-	case OCALLFUNC:
-		// Release res so that it is available for cgen_call.
-		// Pick it up again after the call.
-		r = -1;
-		if(n->ullman >= UINF) {
-			if(res->op == OREGISTER || res->op == OINDREG) {
-				r = res->val.u.reg;
-				reg[r]--;
-			}
-		}
-		if(n->op == OCALLMETH)
-			cgen_callmeth(n, 0);
-		else
-			cgen_call(n, 0);
-		if(r >= 0)
-			reg[r]++;
-		cgen_aret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		tempname(&n1, n->type);
-		cgen_slice(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OEFACE:
-		tempname(&n1, n->type);
-		cgen_eface(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OINDEX:
-		agenr(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case ONAME:
-		// should only get here with names in this func.
-		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME funcdepth %d != %d",
-				n->funcdepth, funcdepth);
-		}
-
-		// should only get here for heap vars or paramref
-		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME class %#x", n->class);
-		}
-		cgen(n->heapaddr, res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[TINT32], n->xoffset);
-			regalloc(&n2, n1.type, N);
-			regalloc(&n3, types[TINT32], N);
-			gmove(&n1, &n2);
-			gmove(res, &n3);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			gmove(&n3, res);
-			regfree(&n2);
-			regfree(&n3);
-		}
-		break;
-
-	case OIND:
-		cgen(nl, res);
-		cgen_checknil(res);
-		break;
-
-	case ODOT:
-		agen(nl, res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[TINT32], n->xoffset);
-			regalloc(&n2, n1.type, N);
-			regalloc(&n3, types[TINT32], N);
-			gmove(&n1, &n2);
-			gmove(res, &n3);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			gmove(&n3, res);
-			regfree(&n2);
-			regfree(&n3);
-		}
-		break;
-
-	case ODOTPTR:
-		cgen(nl, res);
-		cgen_checknil(res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[TINT32], n->xoffset);
-			regalloc(&n2, n1.type, N);
-			regalloc(&n3, types[tptr], N);
-			gmove(&n1, &n2);
-			gmove(res, &n3);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			gmove(&n3, res);
-			regfree(&n2);
-			regfree(&n3);
-		}
-		break;
-	}
-
-ret:
-	;
-}
-
-/*
- * generate:
- *	newreg = &n;
- *	res = newreg
- *
- * on exit, a has been changed to be *newreg.
- * caller must regfree(a).
- * The generated code checks that the result is not *nil.
- */
-void
-igen(Node *n, Node *a, Node *res)
-{
-	Node n1;
-	int r;
-
-	if(debug['g']) {
-		dump("\nigen-n", n);
-	}
-	switch(n->op) {
-	case ONAME:
-		if((n->class&PHEAP) || n->class == PPARAMREF)
-			break;
-		*a = *n;
-		return;
-
-	case OINDREG:
-		// Increase the refcount of the register so that igen's caller
-		// has to call regfree.
-		if(n->val.u.reg != REGSP)
-			reg[n->val.u.reg]++;
-		*a = *n;
-		return;
-
-	case ODOT:
-		igen(n->left, a, res);
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		return;
-
-	case ODOTPTR:
-		if(n->left->addable
-			|| n->left->op == OCALLFUNC
-			|| n->left->op == OCALLMETH
-			|| n->left->op == OCALLINTER) {
-			// igen-able nodes.
-			igen(n->left, &n1, res);
-			regalloc(a, types[tptr], &n1);
-			gmove(&n1, a);
-			regfree(&n1);
-		} else {
-			regalloc(a, types[tptr], res);
-			cgen(n->left, a);
-		}
-		cgen_checknil(a);
-		a->op = OINDREG;
-		a->xoffset = n->xoffset;
-		a->type = n->type;
-		return;
-
-	case OCALLMETH:
-	case OCALLFUNC:
-	case OCALLINTER:
-		// Release res so that it is available for cgen_call.
-		// Pick it up again after the call.
-		r = -1;
-		if(n->ullman >= UINF) {
-			if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
-				r = res->val.u.reg;
-				reg[r]--;
-			}
-		}
-		switch(n->op) {
-		case OCALLMETH:
-			cgen_callmeth(n, 0);
-			break;
-		case OCALLFUNC:
-			cgen_call(n, 0);
-			break;
-		case OCALLINTER:
-			cgen_callinter(n, N, 0);
-			break;
-		}
-		if(r >= 0)
-			reg[r]++;
-		regalloc(a, types[tptr], res);
-		cgen_aret(n, a);
-		a->op = OINDREG;
-		a->type = n->type;
-		return;
-	}
-
-	agenr(n, a, res);
-	a->op = OINDREG;
-	a->type = n->type;
-}
-
-/*
- * allocate a register in res and generate
- *  newreg = &n
- * The caller must call regfree(a).
- */
-void
-cgenr(Node *n, Node *a, Node *res)
-{
-	Node n1;
-
-	if(debug['g'])
-		dump("cgenr-n", n);
-
-	if(isfat(n->type))
-		fatal("cgenr on fat node");
-
-	if(n->addable) {
-		regalloc(a, types[tptr], res);
-		gmove(n, a);
-		return;
-	}
-
-	switch(n->op) {
-	case ONAME:
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		gmove(&n1, a);
-		regfree(&n1);
-		break;
-	default:
-		regalloc(a, n->type, res);
-		cgen(n, a);
-		break;
-	}
-}
-
-/*
- * generate:
- *	newreg = &n;
- *
- * caller must regfree(a).
- * The generated code checks that the result is not nil.
- */
-void
-agenr(Node *n, Node *a, Node *res)
-{
-	Node *nl, *nr;
-	Node n1, n2, n3, n4, tmp;
-	Prog *p1, *p2;
-	uint32 w;
-	uint64 v;
-	int bounded;
-
-	if(debug['g'])
-		dump("agenr-n", n);
-
-	nl = n->left;
-	nr = n->right;
-
-	switch(n->op) {
-	case ODOT:
-	case ODOTPTR:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		agen(&n1, a);
-		regfree(&n1);
-		break;
-
-	case OIND:
-		cgenr(n->left, a, res);
-		cgen_checknil(a);
-		break;
-
-	case OINDEX:
-		p2 = nil;  // to be patched to panicindex.
-		w = n->type->width;
-		bounded = debug['B'] || n->bounded;
-		if(nr->addable) {
-			if(!isconst(nr, CTINT))
-				tempname(&tmp, types[TINT32]);
-			if(!isconst(nl, CTSTR))
-				agenr(nl, &n3, res);
-			if(!isconst(nr, CTINT)) {
-				p2 = cgenindex(nr, &tmp, bounded);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-		} else
-		if(nl->addable) {
-			if(!isconst(nr, CTINT)) {
-				tempname(&tmp, types[TINT32]);
-				p2 = cgenindex(nr, &tmp, bounded);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-			if(!isconst(nl, CTSTR)) {
-				agenr(nl, &n3, res);
-			}
-		} else {
-			tempname(&tmp, types[TINT32]);
-			p2 = cgenindex(nr, &tmp, bounded);
-			nr = &tmp;
-			if(!isconst(nl, CTSTR))
-				agenr(nl, &n3, res);
-			regalloc(&n1, tmp.type, N);
-			gins(optoas(OAS, tmp.type), &tmp, &n1);
-		}
-
-		// &a is in &n3 (allocated in res)
-		// i is in &n1 (if not constant)
-		// w is width
-
-		// constant index
-		if(isconst(nr, CTINT)) {
-			if(isconst(nl, CTSTR))
-				fatal("constant string constant index");
-			v = mpgetfix(nr->val.u.xval);
-			if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				if(!debug['B'] && !n->bounded) {
-					n1 = n3;
-					n1.op = OINDREG;
-					n1.type = types[tptr];
-					n1.xoffset = Array_nel;
-					regalloc(&n4, n1.type, N);
-					gmove(&n1, &n4);
-					nodconst(&n2, types[TUINT32], v);
-					gcmp(optoas(OCMP, types[TUINT32]), &n4, &n2);
-					regfree(&n4);
-					p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
-					ginscall(panicindex, 0);
-					patch(p1, pc);
-				}
-
-				n1 = n3;
-				n1.op = OINDREG;
-				n1.type = types[tptr];
-				n1.xoffset = Array_array;
-				gmove(&n1, &n3);
-			}
-
-			nodconst(&n2, types[tptr], v*w);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			*a = n3;
-			break;
-		}
-
-		regalloc(&n2, types[TINT32], &n1);			// i
-		gmove(&n1, &n2);
-		regfree(&n1);
-
-		if(!debug['B'] && !n->bounded) {
-			// check bounds
-			if(isconst(nl, CTSTR)) {
-				nodconst(&n4, types[TUINT32], nl->val.u.sval->len);
-			} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				n1 = n3;
-				n1.op = OINDREG;
-				n1.type = types[tptr];
-				n1.xoffset = Array_nel;
-				regalloc(&n4, types[TUINT32], N);
-				gmove(&n1, &n4);
-			} else {
-				nodconst(&n4, types[TUINT32], nl->type->bound);
-			}
-			gcmp(optoas(OCMP, types[TUINT32]), &n2, &n4);
-			if(n4.op == OREGISTER)
-				regfree(&n4);
-			p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-			if(p2)
-				patch(p2, pc);
-			ginscall(panicindex, 0);
-			patch(p1, pc);
-		}
-		
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n3, types[tptr], res);
-			p1 = gins(AMOVW, N, &n3);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			p1->from.type = TYPE_ADDR;
-		} else
-		if(isslice(nl->type) || nl->type->etype == TSTRING) {
-			n1 = n3;
-			n1.op = OINDREG;
-			n1.type = types[tptr];
-			n1.xoffset = Array_array;
-			gmove(&n1, &n3);
-		}
-
-		if(w == 0) {
-			// nothing to do
-		} else if(w == 1 || w == 2 || w == 4 || w == 8) {
-			memset(&n4, 0, sizeof n4);
-			n4.op = OADDR;
-			n4.left = &n2;
-			cgen(&n4, &n3);
-			if (w == 1)
-				gins(AADD, &n2, &n3);
-			else if(w == 2)
-				gshift(AADD, &n2, SHIFT_LL, 1, &n3);
-			else if(w == 4)
-				gshift(AADD, &n2, SHIFT_LL, 2, &n3);
-			else if(w == 8)
-				gshift(AADD, &n2, SHIFT_LL, 3, &n3);
-		} else {
-			regalloc(&n4, types[TUINT32], N);
-			nodconst(&n1, types[TUINT32], w);
-			gmove(&n1, &n4);
-			gins(optoas(OMUL, types[TUINT32]), &n4, &n2);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			regfree(&n4);
-		}
-
-		*a = n3;
-		regfree(&n2);
-		break;
-
-	default:
-		regalloc(a, types[tptr], res);
-		agen(n, a);
-		break;
-	}
-}
-
-void
-gencmp0(Node *n, Type *t, int o, int likely, Prog *to)
-{
-	Node n1, n2, n3;
-	int a;
-
-	regalloc(&n1, t, N);
-	cgen(n, &n1);
-	a = optoas(OCMP, t);
-	if(a != ACMP) {
-		nodconst(&n2, t, 0);
-		regalloc(&n3, t, N);
-		gmove(&n2, &n3);
-		gcmp(a, &n1, &n3);
-		regfree(&n3);
-	} else
-		gins(ATST, &n1, N);
-	a = optoas(o, t);
-	patch(gbranch(a, t, likely), to);
-	regfree(&n1);
-}
-
-/*
- * generate:
- *	if(n == true) goto to;
- */
-void
-bgen(Node *n, int true, int likely, Prog *to)
-{
-	int et, a;
-	Node *nl, *nr, *r;
-	Node n1, n2, n3, tmp;
-	NodeList *ll;
-	Prog *p1, *p2;
-
-	if(debug['g']) {
-		dump("\nbgen", n);
-	}
-
-	if(n == N)
-		n = nodbool(1);
-
-	if(n->ninit != nil)
-		genlist(n->ninit);
-
-	if(n->type == T) {
-		convlit(&n, types[TBOOL]);
-		if(n->type == T)
-			goto ret;
-	}
-
-	et = n->type->etype;
-	if(et != TBOOL) {
-		yyerror("cgen: bad type %T for %O", n->type, n->op);
-		patch(gins(AEND, N, N), to);
-		goto ret;
-	}
-	nr = N;
-
-	switch(n->op) {
-	default:
-		a = ONE;
-		if(!true)
-			a = OEQ;
-		gencmp0(n, n->type, a, likely, to);
-		goto ret;
-
-	case OLITERAL:
-		// need to ask if it is bool?
-		if(!true == !n->val.u.bval)
-			patch(gbranch(AB, T, 0), to);
-		goto ret;
-
-	case OANDAND:
-	case OOROR:
-		if((n->op == OANDAND) == true) {
-			p1 = gbranch(AJMP, T, 0);
-			p2 = gbranch(AJMP, T, 0);
-			patch(p1, pc);
-			bgen(n->left, !true, -likely, p2);
-			bgen(n->right, !true, -likely, p2);
-			p1 = gbranch(AJMP, T, 0);
-			patch(p1, to);
-			patch(p2, pc);
-		} else {
-			bgen(n->left, true, likely, to);
-			bgen(n->right, true, likely, to);
-		}
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		nr = n->right;
-		if(nr == N || nr->type == T)
-			goto ret;
-
-	case ONOT:	// unary
-		nl = n->left;
-		if(nl == N || nl->type == T)
-			goto ret;
-	}
-
-	switch(n->op) {
-
-	case ONOT:
-		bgen(nl, !true, likely, to);
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		a = n->op;
-		if(!true) {
-			if(isfloat[nl->type->etype]) {
-				// brcom is not valid on floats when NaN is involved.
-				p1 = gbranch(AB, T, 0);
-				p2 = gbranch(AB, T, 0);
-				patch(p1, pc);
-				ll = n->ninit;
-				n->ninit = nil;
-				bgen(n, 1, -likely, p2);
-				n->ninit = ll;
-				patch(gbranch(AB, T, 0), to);
-				patch(p2, pc);
-				goto ret;
-			}				
-			a = brcom(a);
-			true = !true;
-		}
-
-		// make simplest on right
-		if(nl->op == OLITERAL || (nl->ullman < UINF && nl->ullman < nr->ullman)) {
-			a = brrev(a);
-			r = nl;
-			nl = nr;
-			nr = r;
-		}
-
-		if(isslice(nl->type)) {
-			// only valid to cmp darray to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal array comparison");
-				break;
-			}
-
-			igen(nl, &n1, N);
-			n1.xoffset += Array_array;
-			n1.type = types[tptr];
-			gencmp0(&n1, types[tptr], a, likely, to);
-			regfree(&n1);
-			break;
-		}
-
-		if(isinter(nl->type)) {
-			// front end shold only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal interface comparison");
-				break;
-			}
-
-			igen(nl, &n1, N);
-			n1.type = types[tptr];
-			n1.xoffset += 0;
-			gencmp0(&n1, types[tptr], a, likely, to);
-			regfree(&n1);
-			break;
-		}
-
-		if(iscomplex[nl->type->etype]) {
-			complexbool(a, nl, nr, true, likely, to);
-			break;
-		}
-
-		if(is64(nr->type)) {
-			if(!nl->addable) {
-				tempname(&n1, nl->type);
-				cgen(nl, &n1);
-				nl = &n1;
-			}
-			if(!nr->addable) {
-				tempname(&n2, nr->type);
-				cgen(nr, &n2);
-				nr = &n2;
-			}
-			cmp64(nl, nr, a, likely, to);
-			break;
-		}
-
-		if(nr->op == OLITERAL) {
-			if(isconst(nr, CTINT) &&  mpgetfix(nr->val.u.xval) == 0) {
-				gencmp0(nl, nl->type, a, likely, to);
-				break;
-			}
-			if(nr->val.ctype == CTNIL) {
-				gencmp0(nl, nl->type, a, likely, to);
-				break;
-			}
-		}
-
-		a = optoas(a, nr->type);
-
-		if(nr->ullman >= UINF) {
-			regalloc(&n1, nl->type, N);
-			cgen(nl, &n1);
-
-			tempname(&tmp, nl->type);
-			gmove(&n1, &tmp);
-			regfree(&n1);
-
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-
-			regalloc(&n1, nl->type, N);
-			cgen(&tmp, &n1);
-
-			gcmp(optoas(OCMP, nr->type), &n1, &n2);
-			patch(gbranch(a, nr->type, likely), to);
-
-			regfree(&n1);
-			regfree(&n2);
-			break;
-		}
-
-		tempname(&n3, nl->type);
-		cgen(nl, &n3);
-
-		tempname(&tmp, nr->type);
-		cgen(nr, &tmp);
-
-		regalloc(&n1, nl->type, N);
-		gmove(&n3, &n1);
-
-		regalloc(&n2, nr->type, N);
-		gmove(&tmp, &n2);
-
-		gcmp(optoas(OCMP, nr->type), &n1, &n2);
-		if(isfloat[nl->type->etype]) {
-			if(n->op == ONE) {
-				p1 = gbranch(ABVS, nr->type, likely);
-				patch(gbranch(a, nr->type, likely), to);
-				patch(p1, to);
-			} else {
-				p1 = gbranch(ABVS, nr->type, -likely);
-				patch(gbranch(a, nr->type, likely), to);
-				patch(p1, pc);
-			}
-		} else {
-			patch(gbranch(a, nr->type, likely), to);
-		}
-		regfree(&n1);
-		regfree(&n2);
-		break;
-	}
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * n is on stack, either local variable
- * or return value from function call.
- * return n's offset from SP.
- */
-int32
-stkof(Node *n)
-{
-	Type *t;
-	Iter flist;
-	int32 off;
-
-	switch(n->op) {
-	case OINDREG:
-		return n->xoffset;
-
-	case ODOT:
-		t = n->left->type;
-		if(isptr[t->etype])
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		return off + n->xoffset;
-
-	case OINDEX:
-		t = n->left->type;
-		if(!isfixedarray(t))
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		if(isconst(n->right, CTINT))
-			return off + t->type->width * mpgetfix(n->right->val.u.xval);
-		return 1000;
-		
-	case OCALLMETH:
-	case OCALLINTER:
-	case OCALLFUNC:
-		t = n->left->type;
-		if(isptr[t->etype])
-			t = t->type;
-
-		t = structfirst(&flist, getoutarg(t));
-		if(t != T)
-			return t->width + 4;	// correct for LR
-		break;
-	}
-
-	// botch - probably failing to recognize address
-	// arithmetic on the above. eg INDEX and DOT
-	return -1000;
-}
-
-/*
- * block copy:
- *	memmove(&res, &n, w);
- * NB: character copy assumed little endian architecture
- */
-void
-sgen(Node *n, Node *res, int64 w)
-{
-	Node dst, src, tmp, nend, r0, r1, r2, *f;
-	int32 c, odst, osrc;
-	int dir, align, op;
-	Prog *p, *ploop;
-	NodeList *l;
-
-	if(debug['g']) {
-		print("\nsgen w=%lld\n", w);
-		dump("r", n);
-		dump("res", res);
-	}
-
-	if(n->ullman >= UINF && res->ullman >= UINF)
-		fatal("sgen UINF");
-
-	if(w < 0 || (int32)w != w)
-		fatal("sgen copy %lld", w);
-
-	if(n->type == T)
-		fatal("sgen: missing type");
-
-	if(w == 0) {
-		// evaluate side effects only.
-		regalloc(&dst, types[tptr], N);
-		agen(res, &dst);
-		agen(n, &dst);
-		regfree(&dst);
-		return;
-	}
-
-	// If copying .args, that's all the results, so record definition sites
-	// for them for the liveness analysis.
-	if(res->op == ONAME && strcmp(res->sym->name, ".args") == 0)
-		for(l = curfn->dcl; l != nil; l = l->next)
-			if(l->n->class == PPARAMOUT)
-				gvardef(l->n);
-
-	// Avoid taking the address for simple enough types.
-	if(componentgen(n, res))
-		return;
-	
-	// determine alignment.
-	// want to avoid unaligned access, so have to use
-	// smaller operations for less aligned types.
-	// for example moving [4]byte must use 4 MOVB not 1 MOVW.
-	align = n->type->align;
-	switch(align) {
-	default:
-		fatal("sgen: invalid alignment %d for %T", align, n->type);
-	case 1:
-		op = AMOVB;
-		break;
-	case 2:
-		op = AMOVH;
-		break;
-	case 4:
-		op = AMOVW;
-		break;
-	}
-	if(w%align)
-		fatal("sgen: unaligned size %lld (align=%d) for %T", w, align, n->type);
-	c = w / align;
-
-	// offset on the stack
-	osrc = stkof(n);
-	odst = stkof(res);
-	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
-		// osrc and odst both on stack, and at least one is in
-		// an unknown position.  Could generate code to test
-		// for forward/backward copy, but instead just copy
-		// to a temporary location first.
-		tempname(&tmp, n->type);
-		sgen(n, &tmp, w);
-		sgen(&tmp, res, w);
-		return;
-	}
-	if(osrc%align != 0 || odst%align != 0)
-		fatal("sgen: unaligned offset src %d or dst %d (align %d)", osrc, odst, align);
-
-	// if we are copying forward on the stack and
-	// the src and dst overlap, then reverse direction
-	dir = align;
-	if(osrc < odst && odst < osrc+w)
-		dir = -dir;
-
-	if(op == AMOVW && !nacl && dir > 0 && c >= 4 && c <= 128) {
-		r0.op = OREGISTER;
-		r0.val.u.reg = REGALLOC_R0;
-		r1.op = OREGISTER;
-		r1.val.u.reg = REGALLOC_R0 + 1;
-		r2.op = OREGISTER;
-		r2.val.u.reg = REGALLOC_R0 + 2;
-
-		regalloc(&src, types[tptr], &r1);
-		regalloc(&dst, types[tptr], &r2);
-		if(n->ullman >= res->ullman) {
-			// eval n first
-			agen(n, &src);
-			if(res->op == ONAME)
-				gvardef(res);
-			agen(res, &dst);
-		} else {
-			// eval res first
-			if(res->op == ONAME)
-				gvardef(res);
-			agen(res, &dst);
-			agen(n, &src);
-		}
-		regalloc(&tmp, types[tptr], &r0);
-		f = sysfunc("duffcopy");
-		p = gins(ADUFFCOPY, N, f);
-		afunclit(&p->to, f);
-		// 8 and 128 = magic constants: see ../../runtime/asm_arm.s
-		p->to.offset = 8*(128-c);
-
-		regfree(&tmp);
-		regfree(&src);
-		regfree(&dst);
-		return;
-	}
-	
-	if(n->ullman >= res->ullman) {
-		agenr(n, &dst, res);	// temporarily use dst
-		regalloc(&src, types[tptr], N);
-		gins(AMOVW, &dst, &src);
-		if(res->op == ONAME)
-			gvardef(res);
-		agen(res, &dst);
-	} else {
-		if(res->op == ONAME)
-			gvardef(res);
-		agenr(res, &dst, res);
-		agenr(n, &src, N);
-	}
-
-	regalloc(&tmp, types[TUINT32], N);
-
-	// set up end marker
-	memset(&nend, 0, sizeof nend);
-	if(c >= 4) {
-		regalloc(&nend, types[TUINT32], N);
-
-		p = gins(AMOVW, &src, &nend);
-		p->from.type = TYPE_ADDR;
-		if(dir < 0)
-			p->from.offset = dir;
-		else
-			p->from.offset = w;
-	}
-
-	// move src and dest to the end of block if necessary
-	if(dir < 0) {
-		p = gins(AMOVW, &src, &src);
-		p->from.type = TYPE_ADDR;
-		p->from.offset = w + dir;
-
-		p = gins(AMOVW, &dst, &dst);
-		p->from.type = TYPE_ADDR;
-		p->from.offset = w + dir;
-	}
-	
-	// move
-	if(c >= 4) {
-		p = gins(op, &src, &tmp);
-		p->from.type = TYPE_MEM;
-		p->from.offset = dir;
-		p->scond |= C_PBIT;
-		ploop = p;
-
-		p = gins(op, &tmp, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = dir;
-		p->scond |= C_PBIT;
-
-		p = gins(ACMP, &src, N);
-		raddr(&nend, p);
-
-		patch(gbranch(ABNE, T, 0), ploop);
- 		regfree(&nend);
-	} else {
-		while(c-- > 0) {
-			p = gins(op, &src, &tmp);
-			p->from.type = TYPE_MEM;
-			p->from.offset = dir;
-			p->scond |= C_PBIT;
-	
-			p = gins(op, &tmp, &dst);
-			p->to.type = TYPE_MEM;
-			p->to.offset = dir;
-			p->scond |= C_PBIT;
-		}
-	}
-
-	regfree(&dst);
-	regfree(&src);
-	regfree(&tmp);
-}
-
-static int
-cadable(Node *n)
-{
-	if(!n->addable) {
-		// dont know how it happens,
-		// but it does
-		return 0;
-	}
-
-	switch(n->op) {
-	case ONAME:
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if cant.
- */
-int
-componentgen(Node *nr, Node *nl)
-{
-	Node nodl, nodr, tmp;
-	Type *t;
-	int freel, freer;
-	vlong fldcount;
-	vlong loffset, roffset;
-
-	freel = 0;
-	freer = 0;
-
-	switch(nl->type->etype) {
-	default:
-		goto no;
-
-	case TARRAY:
-		t = nl->type;
-
-		// Slices are ok.
-		if(isslice(t))
-			break;
-		// Small arrays are ok.
-		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
-			break;
-
-		goto no;
-
-	case TSTRUCT:
-		// Small structs with non-fat types are ok.
-		// Zero-sized structs are treated separately elsewhere.
-		fldcount = 0;
-		for(t=nl->type->type; t; t=t->down) {
-			if(isfat(t->type))
-				goto no;
-			if(t->etype != TFIELD)
-				fatal("componentgen: not a TFIELD: %lT", t);
-			fldcount++;
-		}
-		if(fldcount == 0 || fldcount > 4)
-			goto no;
-
-		break;
-
-	case TSTRING:
-	case TINTER:
-		break;
-	}
-
-	nodl = *nl;
-	if(!cadable(nl)) {
-		if(nr != N && !cadable(nr))
-			goto no;
-		igen(nl, &nodl, N);
-		freel = 1;
-	}
-
-	if(nr != N) {
-		nodr = *nr;
-		if(!cadable(nr)) {
-			igen(nr, &nodr, N);
-			freer = 1;
-		}
-	} else {
-		// When zeroing, prepare a register containing zero.
-		nodconst(&tmp, nl->type, 0);
-		regalloc(&nodr, types[TUINT], N);
-		gmove(&tmp, &nodr);
-		freer = 1;
-	}
-
-	// nl and nr are 'cadable' which basically means they are names (variables) now.
-	// If they are the same variable, don't generate any code, because the
-	// VARDEF we generate will mark the old value as dead incorrectly.
-	// (And also the assignments are useless.)
-	if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
-		goto yes;
-
-	switch(nl->type->etype) {
-	case TARRAY:
-		// componentgen for arrays.
-		if(nl->op == ONAME)
-			gvardef(nl);
-		t = nl->type;
-		if(!isslice(t)) {
-			nodl.type = t->type;
-			nodr.type = nodl.type;
-			for(fldcount=0; fldcount < t->bound; fldcount++) {
-				if(nr == N)
-					clearslim(&nodl);
-				else
-					gmove(&nodr, &nodl);
-				nodl.xoffset += t->type->width;
-				nodr.xoffset += t->type->width;
-			}
-			goto yes;
-		}
-
-		// componentgen for slices.
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(nl->type->type);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_cap-Array_nel;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_cap-Array_nel;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRING:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TINTER:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRUCT:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		loffset = nodl.xoffset;
-		roffset = nodr.xoffset;
-		// funarg structs may not begin at offset zero.
-		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
-			loffset -= nl->type->type->width;
-		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
-			roffset -= nr->type->type->width;
-
-		for(t=nl->type->type; t; t=t->down) {
-			nodl.xoffset = loffset + t->width;
-			nodl.type = t->type;
-
-			if(nr == N)
-				clearslim(&nodl);
-			else {
-				nodr.xoffset = roffset + t->width;
-				nodr.type = nodl.type;
-				gmove(&nodr, &nodl);
-			}
-		}
-		goto yes;
-	}
-
-no:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 0;
-
-yes:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 1;
-}
diff --git a/src/cmd/new5g/cgen.go b/src/cmd/5g/cgen.go
similarity index 100%
rename from src/cmd/new5g/cgen.go
rename to src/cmd/5g/cgen.go
diff --git a/src/cmd/5g/cgen64.c b/src/cmd/5g/cgen64.c
deleted file mode 100644
index 9abab4c..0000000
--- a/src/cmd/5g/cgen64.c
+++ /dev/null
@@ -1,760 +0,0 @@
-// 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"
-
-/*
- * attempt to generate 64-bit
- *	res = n
- * return 1 on success, 0 if op not handled.
- */
-void
-cgen64(Node *n, Node *res)
-{
-	Node t1, t2, *l, *r;
-	Node lo1, lo2, hi1, hi2;
-	Node al, ah, bl, bh, cl, ch, s, n1, creg;
-	Prog *p1, *p2, *p3, *p4, *p5, *p6;
-
-	uint64 v;
-
-	if(res->op != OINDREG && res->op != ONAME) {
-		dump("n", n);
-		dump("res", res);
-		fatal("cgen64 %O of %O", n->op, res->op);
-	}
-
-	l = n->left;
-	if(!l->addable) {
-		tempname(&t1, l->type);
-		cgen(l, &t1);
-		l = &t1;
-	}
-
-	split64(l, &lo1, &hi1);
-	switch(n->op) {
-	default:
-		fatal("cgen64 %O", n->op);
-
-	case OMINUS:
-		split64(res, &lo2, &hi2);
-
-		regalloc(&t1, lo1.type, N);
-		regalloc(&al, lo1.type, N);
-		regalloc(&ah, hi1.type, N);
-
-		gins(AMOVW, &lo1, &al);
-		gins(AMOVW, &hi1, &ah);
-
-		gmove(ncon(0), &t1);
-		p1 = gins(ASUB, &al, &t1);
-		p1->scond |= C_SBIT;
-		gins(AMOVW, &t1, &lo2);
-
-		gmove(ncon(0), &t1);
-		gins(ASBC, &ah, &t1);
-		gins(AMOVW, &t1, &hi2);
-
-		regfree(&t1);
-		regfree(&al);
-		regfree(&ah);
-		splitclean();
-		splitclean();
-		return;
-
-	case OCOM:
-		regalloc(&t1, lo1.type, N);
-		gmove(ncon(-1), &t1);
-
-		split64(res, &lo2, &hi2);
-		regalloc(&n1, lo1.type, N);
-
-		gins(AMOVW, &lo1, &n1);
-		gins(AEOR, &t1, &n1);
-		gins(AMOVW, &n1, &lo2);
-
-		gins(AMOVW, &hi1, &n1);
-		gins(AEOR, &t1, &n1);
-		gins(AMOVW, &n1, &hi2);
-
-		regfree(&t1);
-		regfree(&n1);
-		splitclean();
-		splitclean();
-		return;
-
-	case OADD:
-	case OSUB:
-	case OMUL:
-	case OLSH:
-	case ORSH:
-	case OAND:
-	case OOR:
-	case OXOR:
-	case OLROT:
-		// binary operators.
-		// common setup below.
-		break;
-	}
-
-	// setup for binary operators
-	r = n->right;
-	if(r != N && !r->addable) {
-		tempname(&t2, r->type);
-		cgen(r, &t2);
-		r = &t2;
-	}
-	if(is64(r->type))
-		split64(r, &lo2, &hi2);
-
-	regalloc(&al, lo1.type, N);
-	regalloc(&ah, hi1.type, N);
-
-	// Do op.  Leave result in ah:al.
-	switch(n->op) {
-	default:
-		fatal("cgen64: not implemented: %N\n", n);
-
-	case OADD:
-		// TODO: Constants
-		regalloc(&bl, types[TPTR32], N);
-		regalloc(&bh, types[TPTR32], N);
-		gins(AMOVW, &hi1, &ah);
-		gins(AMOVW, &lo1, &al);
-		gins(AMOVW, &hi2, &bh);
-		gins(AMOVW, &lo2, &bl);
-		p1 = gins(AADD, &bl, &al);
-		p1->scond |= C_SBIT;
-		gins(AADC, &bh, &ah);
-		regfree(&bl);
-		regfree(&bh);
-		break;
-
-	case OSUB:
-		// TODO: Constants.
-		regalloc(&bl, types[TPTR32], N);
-		regalloc(&bh, types[TPTR32], N);
-		gins(AMOVW, &lo1, &al);
-		gins(AMOVW, &hi1, &ah);
-		gins(AMOVW, &lo2, &bl);
-		gins(AMOVW, &hi2, &bh);
-		p1 = gins(ASUB, &bl, &al);
-		p1->scond |= C_SBIT;
-		gins(ASBC, &bh, &ah);
-		regfree(&bl);
-		regfree(&bh);
-		break;
-
-	case OMUL:
-		// TODO(kaib): this can be done with 4 regs and does not need 6
-		regalloc(&bl, types[TPTR32], N);
-		regalloc(&bh, types[TPTR32], N);
-		regalloc(&cl, types[TPTR32], N);
-		regalloc(&ch, types[TPTR32], N);
-
-		// load args into bh:bl and bh:bl.
-		gins(AMOVW, &hi1, &bh);
-		gins(AMOVW, &lo1, &bl);
-		gins(AMOVW, &hi2, &ch);
-		gins(AMOVW, &lo2, &cl);
-
-		// bl * cl -> ah al
-		p1 = gins(AMULLU, N, N);
-		p1->from.type = TYPE_REG;
-		p1->from.reg = bl.val.u.reg;
-		p1->reg = cl.val.u.reg;
-		p1->to.type = TYPE_REGREG;
-		p1->to.reg = ah.val.u.reg;
-		p1->to.offset = al.val.u.reg;
-//print("%P\n", p1);
-
-		// bl * ch + ah -> ah
-		p1 = gins(AMULA, N, N);
-		p1->from.type = TYPE_REG;
-		p1->from.reg = bl.val.u.reg;
-		p1->reg = ch.val.u.reg;
-		p1->to.type = TYPE_REGREG2;
-		p1->to.reg = ah.val.u.reg;
-		p1->to.offset = ah.val.u.reg;
-//print("%P\n", p1);
-
-		// bh * cl + ah -> ah
-		p1 = gins(AMULA, N, N);
-		p1->from.type = TYPE_REG;
-		p1->from.reg = bh.val.u.reg;
-		p1->reg = cl.val.u.reg;
-		p1->to.type = TYPE_REGREG2;
-		p1->to.reg = ah.val.u.reg;
-		p1->to.offset = ah.val.u.reg;
-//print("%P\n", p1);
-
-		regfree(&bh);
-		regfree(&bl);
-		regfree(&ch);
-		regfree(&cl);
-
-		break;
-
-	case OLROT:
-		// We only rotate by a constant c in [0,64).
-		// if c >= 32:
-		//	lo, hi = hi, lo
-		//	c -= 32
-		// if c == 0:
-		//	no-op
-		// else:
-		//	t = hi
-		//	shld hi:lo, c
-		//	shld lo:t, c
-		v = mpgetfix(r->val.u.xval);
-		regalloc(&bl, lo1.type, N);
-		regalloc(&bh, hi1.type, N);
-		if(v >= 32) {
-			// reverse during load to do the first 32 bits of rotate
-			v -= 32;
-			gins(AMOVW, &hi1, &bl);
-			gins(AMOVW, &lo1, &bh);
-		} else {
-			gins(AMOVW, &hi1, &bh);
-			gins(AMOVW, &lo1, &bl);
-		}
-		if(v == 0) {
-			gins(AMOVW, &bh, &ah);
-			gins(AMOVW, &bl, &al);
-		} else {
-			// rotate by 1 <= v <= 31
-			//	MOVW	bl<<v, al
-			//	MOVW	bh<<v, ah
-			//	OR		bl>>(32-v), ah
-			//	OR		bh>>(32-v), al
-			gshift(AMOVW, &bl, SHIFT_LL, v, &al);
-			gshift(AMOVW, &bh, SHIFT_LL, v, &ah);
-			gshift(AORR, &bl, SHIFT_LR, 32-v, &ah);
-			gshift(AORR, &bh, SHIFT_LR, 32-v, &al);
-		}
-		regfree(&bl);
-		regfree(&bh);
-		break;
-
-	case OLSH:
-		regalloc(&bl, lo1.type, N);
-		regalloc(&bh, hi1.type, N);
-		gins(AMOVW, &hi1, &bh);
-		gins(AMOVW, &lo1, &bl);
-
-		if(r->op == OLITERAL) {
-			v = mpgetfix(r->val.u.xval);
-			if(v >= 64) {
-				// TODO(kaib): replace with gins(AMOVW, nodintconst(0), &al)
-				// here and below (verify it optimizes to EOR)
-				gins(AEOR, &al, &al);
-				gins(AEOR, &ah, &ah);
-			} else
-			if(v > 32) {
-				gins(AEOR, &al, &al);
-				//	MOVW	bl<<(v-32), ah
-				gshift(AMOVW, &bl, SHIFT_LL, (v-32), &ah);
-			} else
-			if(v == 32) {
-				gins(AEOR, &al, &al);
-				gins(AMOVW, &bl, &ah);
-			} else
-			if(v > 0) {
-				//	MOVW	bl<<v, al
-				gshift(AMOVW, &bl, SHIFT_LL, v, &al);
-
-				//	MOVW	bh<<v, ah
-				gshift(AMOVW, &bh, SHIFT_LL, v, &ah);
-
-				//	OR		bl>>(32-v), ah
-				gshift(AORR, &bl, SHIFT_LR, 32-v, &ah);
-			} else {
-				gins(AMOVW, &bl, &al);
-				gins(AMOVW, &bh, &ah);
-			}
-			goto olsh_break;
-		}
-
-		regalloc(&s, types[TUINT32], N);
-		regalloc(&creg, types[TUINT32], N);
-		if (is64(r->type)) {
-			// shift is >= 1<<32
-			split64(r, &cl, &ch);
-			gmove(&ch, &s);
-			gins(ATST, &s, N);
-			p6 = gbranch(ABNE, T, 0);
-			gmove(&cl, &s);
-			splitclean();
-		} else {
-			gmove(r, &s);
-			p6 = P;
-		}
-		gins(ATST, &s, N);
-
-		// shift == 0
-		p1 = gins(AMOVW, &bl, &al);
-		p1->scond = C_SCOND_EQ;
-		p1 = gins(AMOVW, &bh, &ah);
-		p1->scond = C_SCOND_EQ;
-		p2 = gbranch(ABEQ, T, 0);
-
-		// shift is < 32
-		nodconst(&n1, types[TUINT32], 32);
-		gmove(&n1, &creg);
-		gcmp(ACMP, &s, &creg);
-
-		//	MOVW.LO		bl<<s, al
-		p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &al);
-		p1->scond = C_SCOND_LO;
-
-		//	MOVW.LO		bh<<s, ah
-		p1 = gregshift(AMOVW, &bh, SHIFT_LL, &s, &ah);
-		p1->scond = C_SCOND_LO;
-
-		//	SUB.LO		s, creg
-		p1 = gins(ASUB, &s, &creg);
-		p1->scond = C_SCOND_LO;
-
-		//	OR.LO		bl>>creg, ah
-		p1 = gregshift(AORR, &bl, SHIFT_LR, &creg, &ah);
-		p1->scond = C_SCOND_LO;
-
-		//	BLO	end
-		p3 = gbranch(ABLO, T, 0);
-
-		// shift == 32
-		p1 = gins(AEOR, &al, &al);
-		p1->scond = C_SCOND_EQ;
-		p1 = gins(AMOVW, &bl, &ah);
-		p1->scond = C_SCOND_EQ;
-		p4 = gbranch(ABEQ, T, 0);
-
-		// shift is < 64
-		nodconst(&n1, types[TUINT32], 64);
-		gmove(&n1, &creg);
-		gcmp(ACMP, &s, &creg);
-
-		//	EOR.LO	al, al
-		p1 = gins(AEOR, &al, &al);
-		p1->scond = C_SCOND_LO;
-
-		//	MOVW.LO		creg>>1, creg
-		p1 = gshift(AMOVW, &creg, SHIFT_LR, 1, &creg);
-		p1->scond = C_SCOND_LO;
-
-		//	SUB.LO		creg, s
-		p1 = gins(ASUB, &creg, &s);
-		p1->scond = C_SCOND_LO;
-
-		//	MOVW	bl<<s, ah
-		p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &ah);
-		p1->scond = C_SCOND_LO;
-
-		p5 = gbranch(ABLO, T, 0);
-
-		// shift >= 64
-		if (p6 != P) patch(p6, pc);
-		gins(AEOR, &al, &al);
-		gins(AEOR, &ah, &ah);
-
-		patch(p2, pc);
-		patch(p3, pc);
-		patch(p4, pc);
-		patch(p5, pc);
-		regfree(&s);
-		regfree(&creg);
-
-olsh_break:
-		regfree(&bl);
-		regfree(&bh);
-		break;
-
-
-	case ORSH:
-		regalloc(&bl, lo1.type, N);
-		regalloc(&bh, hi1.type, N);
-		gins(AMOVW, &hi1, &bh);
-		gins(AMOVW, &lo1, &bl);
-
-		if(r->op == OLITERAL) {
-			v = mpgetfix(r->val.u.xval);
-			if(v >= 64) {
-				if(bh.type->etype == TINT32) {
-					//	MOVW	bh->31, al
-					gshift(AMOVW, &bh, SHIFT_AR, 31, &al);
-
-					//	MOVW	bh->31, ah
-					gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
-				} else {
-					gins(AEOR, &al, &al);
-					gins(AEOR, &ah, &ah);
-				}
-			} else
-			if(v > 32) {
-				if(bh.type->etype == TINT32) {
-					//	MOVW	bh->(v-32), al
-					gshift(AMOVW, &bh, SHIFT_AR, v-32, &al);
-
-					//	MOVW	bh->31, ah
-					gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
-				} else {
-					//	MOVW	bh>>(v-32), al
-					gshift(AMOVW, &bh, SHIFT_LR, v-32, &al);
-					gins(AEOR, &ah, &ah);
-				}
-			} else
-			if(v == 32) {
-				gins(AMOVW, &bh, &al);
-				if(bh.type->etype == TINT32) {
-					//	MOVW	bh->31, ah
-					gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
-				} else {
-					gins(AEOR, &ah, &ah);
-				}
-			} else
-			if( v > 0) {
-				//	MOVW	bl>>v, al
-				gshift(AMOVW, &bl, SHIFT_LR, v, &al);
-	
-				//	OR		bh<<(32-v), al
-				gshift(AORR, &bh, SHIFT_LL, 32-v, &al);
-
-				if(bh.type->etype == TINT32) {
-					//	MOVW	bh->v, ah
-					gshift(AMOVW, &bh, SHIFT_AR, v, &ah);
-				} else {
-					//	MOVW	bh>>v, ah
-					gshift(AMOVW, &bh, SHIFT_LR, v, &ah);
-				}
-			} else {
-				gins(AMOVW, &bl, &al);
-				gins(AMOVW, &bh, &ah);
-			}
-			goto orsh_break;
-		}
-
-		regalloc(&s, types[TUINT32], N);
-		regalloc(&creg, types[TUINT32], N);
-		if(is64(r->type)) {
-			// shift is >= 1<<32
-			split64(r, &cl, &ch);
-			gmove(&ch, &s);
-			gins(ATST, &s, N);
-			if(bh.type->etype == TINT32)
-				p1 = gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
-			else
-				p1 = gins(AEOR, &ah, &ah);
-			p1->scond = C_SCOND_NE;
-			p6 = gbranch(ABNE, T, 0);
-			gmove(&cl, &s);
-			splitclean();
-		} else {
-			gmove(r, &s);
-			p6 = P;
-		}
-		gins(ATST, &s, N);
-
-		// shift == 0
-		p1 = gins(AMOVW, &bl, &al);
-		p1->scond = C_SCOND_EQ;
-		p1 = gins(AMOVW, &bh, &ah);
-		p1->scond = C_SCOND_EQ;
-		p2 = gbranch(ABEQ, T, 0);
-
-		// check if shift is < 32
-		nodconst(&n1, types[TUINT32], 32);
-		gmove(&n1, &creg);
-		gcmp(ACMP, &s, &creg);
-
-		//	MOVW.LO		bl>>s, al
-		p1 = gregshift(AMOVW, &bl, SHIFT_LR, &s, &al);
-		p1->scond = C_SCOND_LO;
-
-		//	SUB.LO		s,creg
-		p1 = gins(ASUB, &s, &creg);
-		p1->scond = C_SCOND_LO;
-
-		//	OR.LO		bh<<(32-s), al
-		p1 = gregshift(AORR, &bh, SHIFT_LL, &creg, &al);
-		p1->scond = C_SCOND_LO;
-
-		if(bh.type->etype == TINT32) {
-			//	MOVW	bh->s, ah
-			p1 = gregshift(AMOVW, &bh, SHIFT_AR, &s, &ah);
-		} else {
-			//	MOVW	bh>>s, ah
-			p1 = gregshift(AMOVW, &bh, SHIFT_LR, &s, &ah);
-		}
-		p1->scond = C_SCOND_LO;
-
-		//	BLO	end
-		p3 = gbranch(ABLO, T, 0);
-
-		// shift == 32
-		p1 = gins(AMOVW, &bh, &al);
-		p1->scond = C_SCOND_EQ;
-		if(bh.type->etype == TINT32)
-			gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
-		else
-			gins(AEOR, &ah, &ah);
-		p4 = gbranch(ABEQ, T, 0);
-
-		// check if shift is < 64
-		nodconst(&n1, types[TUINT32], 64);
-		gmove(&n1, &creg);
-		gcmp(ACMP, &s, &creg);
-
-		//	MOVW.LO		creg>>1, creg
-		p1 = gshift(AMOVW, &creg, SHIFT_LR, 1, &creg);
-		p1->scond = C_SCOND_LO;
-
-		//	SUB.LO		creg, s
-		p1 = gins(ASUB, &creg, &s);
-		p1->scond = C_SCOND_LO;
-
-		if(bh.type->etype == TINT32) {
-			//	MOVW	bh->(s-32), al
-			p1 = gregshift(AMOVW, &bh, SHIFT_AR, &s, &al);
-			p1->scond = C_SCOND_LO;
-		} else {
-			//	MOVW	bh>>(v-32), al
-			p1 = gregshift(AMOVW, &bh, SHIFT_LR, &s, &al);
-			p1->scond = C_SCOND_LO;
-		}
-
-		//	BLO	end
-		p5 = gbranch(ABLO, T, 0);
-
-		// s >= 64
-		if(p6 != P)
-			patch(p6, pc);
-		if(bh.type->etype == TINT32) {
-			//	MOVW	bh->31, al
-			gshift(AMOVW, &bh, SHIFT_AR, 31, &al);
-		} else {
-			gins(AEOR, &al, &al);
-		}
-
-		patch(p2, pc);
-		patch(p3, pc);
-		patch(p4, pc);
-		patch(p5, pc);
-		regfree(&s);
-		regfree(&creg);
-
-
-orsh_break:
-		regfree(&bl);
-		regfree(&bh);
-		break;
-
-	case OXOR:
-	case OAND:
-	case OOR:
-		// TODO(kaib): literal optimizations
-		// make constant the right side (it usually is anyway).
-//		if(lo1.op == OLITERAL) {
-//			nswap(&lo1, &lo2);
-//			nswap(&hi1, &hi2);
-//		}
-//		if(lo2.op == OLITERAL) {
-//			// special cases for constants.
-//			lv = mpgetfix(lo2.val.u.xval);
-//			hv = mpgetfix(hi2.val.u.xval);
-//			splitclean();	// right side
-//			split64(res, &lo2, &hi2);
-//			switch(n->op) {
-//			case OXOR:
-//				gmove(&lo1, &lo2);
-//				gmove(&hi1, &hi2);
-//				switch(lv) {
-//				case 0:
-//					break;
-//				case 0xffffffffu:
-//					gins(ANOTL, N, &lo2);
-//					break;
-//				default:
-//					gins(AXORL, ncon(lv), &lo2);
-//					break;
-//				}
-//				switch(hv) {
-//				case 0:
-//					break;
-//				case 0xffffffffu:
-//					gins(ANOTL, N, &hi2);
-//					break;
-//				default:
-//					gins(AXORL, ncon(hv), &hi2);
-//					break;
-//				}
-//				break;
-
-//			case OAND:
-//				switch(lv) {
-//				case 0:
-//					gins(AMOVL, ncon(0), &lo2);
-//					break;
-//				default:
-//					gmove(&lo1, &lo2);
-//					if(lv != 0xffffffffu)
-//						gins(AANDL, ncon(lv), &lo2);
-//					break;
-//				}
-//				switch(hv) {
-//				case 0:
-//					gins(AMOVL, ncon(0), &hi2);
-//					break;
-//				default:
-//					gmove(&hi1, &hi2);
-//					if(hv != 0xffffffffu)
-//						gins(AANDL, ncon(hv), &hi2);
-//					break;
-//				}
-//				break;
-
-//			case OOR:
-//				switch(lv) {
-//				case 0:
-//					gmove(&lo1, &lo2);
-//					break;
-//				case 0xffffffffu:
-//					gins(AMOVL, ncon(0xffffffffu), &lo2);
-//					break;
-//				default:
-//					gmove(&lo1, &lo2);
-//					gins(AORL, ncon(lv), &lo2);
-//					break;
-//				}
-//				switch(hv) {
-//				case 0:
-//					gmove(&hi1, &hi2);
-//					break;
-//				case 0xffffffffu:
-//					gins(AMOVL, ncon(0xffffffffu), &hi2);
-//					break;
-//				default:
-//					gmove(&hi1, &hi2);
-//					gins(AORL, ncon(hv), &hi2);
-//					break;
-//				}
-//				break;
-//			}
-//			splitclean();
-//			splitclean();
-//			goto out;
-//		}
-		regalloc(&n1, lo1.type, N);
-		gins(AMOVW, &lo1, &al);
-		gins(AMOVW, &hi1, &ah);
-		gins(AMOVW, &lo2, &n1);
-		gins(optoas(n->op, lo1.type), &n1, &al);
-		gins(AMOVW, &hi2, &n1);
-		gins(optoas(n->op, lo1.type), &n1, &ah);
-		regfree(&n1);
-		break;
-	}
-	if(is64(r->type))
-		splitclean();
-	splitclean();
-
-	split64(res, &lo1, &hi1);
-	gins(AMOVW, &al, &lo1);
-	gins(AMOVW, &ah, &hi1);
-	splitclean();
-
-//out:
-	regfree(&al);
-	regfree(&ah);
-}
-
-/*
- * generate comparison of nl, nr, both 64-bit.
- * nl is memory; nr is constant or memory.
- */
-void
-cmp64(Node *nl, Node *nr, int op, int likely, Prog *to)
-{
-	Node lo1, hi1, lo2, hi2, r1, r2;
-	Prog *br;
-	Type *t;
-
-	split64(nl, &lo1, &hi1);
-	split64(nr, &lo2, &hi2);
-
-	// compare most significant word;
-	// if they differ, we're done.
-	t = hi1.type;
-	regalloc(&r1, types[TINT32], N);
-	regalloc(&r2, types[TINT32], N);
-	gins(AMOVW, &hi1, &r1);
-	gins(AMOVW, &hi2, &r2);
-	gcmp(ACMP, &r1, &r2);
-	regfree(&r1);
-	regfree(&r2);
-
-	br = P;
-	switch(op) {
-	default:
-		fatal("cmp64 %O %T", op, t);
-	case OEQ:
-		// cmp hi
-		// bne L
-		// cmp lo
-		// beq to
-		// L:
-		br = gbranch(ABNE, T, -likely);
-		break;
-	case ONE:
-		// cmp hi
-		// bne to
-		// cmp lo
-		// bne to
-		patch(gbranch(ABNE, T, likely), to);
-		break;
-	case OGE:
-	case OGT:
-		// cmp hi
-		// bgt to
-		// blt L
-		// cmp lo
-		// bge to (or bgt to)
-		// L:
-		patch(gbranch(optoas(OGT, t), T, likely), to);
-		br = gbranch(optoas(OLT, t), T, -likely);
-		break;
-	case OLE:
-	case OLT:
-		// cmp hi
-		// blt to
-		// bgt L
-		// cmp lo
-		// ble to (or jlt to)
-		// L:
-		patch(gbranch(optoas(OLT, t), T, likely), to);
-		br = gbranch(optoas(OGT, t), T, -likely);
-		break;
-	}
-
-	// compare least significant word
-	t = lo1.type;
-	regalloc(&r1, types[TINT32], N);
-	regalloc(&r2, types[TINT32], N);
-	gins(AMOVW, &lo1, &r1);
-	gins(AMOVW, &lo2, &r2);
-	gcmp(ACMP, &r1, &r2);
-	regfree(&r1);
-	regfree(&r2);
-
-	// jump again
-	patch(gbranch(optoas(op, t), T, likely), to);
-
-	// point first branch down here if appropriate
-	if(br != P)
-		patch(br, pc);
-
-	splitclean();
-	splitclean();
-}
diff --git a/src/cmd/new5g/cgen64.go b/src/cmd/5g/cgen64.go
similarity index 100%
rename from src/cmd/new5g/cgen64.go
rename to src/cmd/5g/cgen64.go
diff --git a/src/cmd/5g/doc.go b/src/cmd/5g/doc.go
deleted file mode 100644
index aebdcab..0000000
--- a/src/cmd/5g/doc.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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
-
-/*
-
-5g is the version of the gc compiler for the ARM.
-The $GOARCH for these tools is arm.
-
-It reads .go files and outputs .5 files. The flags are documented in ../gc/doc.go.
-
-*/
-package main
diff --git a/src/cmd/5g/galign.c b/src/cmd/5g/galign.c
deleted file mode 100644
index c4d74f0..0000000
--- a/src/cmd/5g/galign.c
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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"
-
-int	thechar	= '5';
-char*	thestring	= "arm";
-LinkArch*	thelinkarch = &linkarm;
-
-void
-linkarchinit(void)
-{
-}
-
-vlong MAXWIDTH = (1LL<<32) - 1;
-
-/*
- * go declares several platform-specific type aliases:
- * int, uint, float, and uintptr
- */
-Typedef	typedefs[] =
-{
-	{"int",		TINT,		TINT32},
-	{"uint",		TUINT,		TUINT32},
-	{"uintptr",	TUINTPTR,	TUINT32},
-	{0}
-};
-
-void
-betypeinit(void)
-{
-	widthptr = 4;
-	widthint = 4;
-	widthreg = 4;
-
-	listinit5();
-}
-
-void
-main(int argc, char **argv)
-{
-	thearch.thechar = thechar;
-	thearch.thestring = thestring;
-	thearch.thelinkarch = thelinkarch;
-	thearch.typedefs = typedefs;
-	thearch.REGSP = REGSP;
-	thearch.REGCTXT = REGCTXT;
-	thearch.MAXWIDTH = MAXWIDTH;
-	thearch.anyregalloc = anyregalloc;
-	thearch.betypeinit = betypeinit;
-	thearch.bgen = bgen;
-	thearch.cgen = cgen;
-	thearch.cgen_call = cgen_call;
-	thearch.cgen_callinter = cgen_callinter;
-	thearch.cgen_ret = cgen_ret;
-	thearch.clearfat = clearfat;
-	thearch.defframe = defframe;
-	thearch.excise = excise;
-	thearch.expandchecks = expandchecks;
-	thearch.gclean = gclean;
-	thearch.ginit = ginit;
-	thearch.gins = gins;
-	thearch.ginscall = ginscall;
-	thearch.igen = igen;
-	thearch.linkarchinit = linkarchinit;
-	thearch.peep = peep;
-	thearch.proginfo = proginfo;
-	thearch.regalloc = regalloc;
-	thearch.regfree = regfree;
-	thearch.regtyp = regtyp;
-	thearch.sameaddr = sameaddr;
-	thearch.smallindir = smallindir;
-	thearch.stackaddr = stackaddr;
-	thearch.excludedregs = excludedregs;
-	thearch.RtoB = RtoB;
-	thearch.FtoB = RtoB;
-	thearch.BtoR = BtoR;
-	thearch.BtoF = BtoF;
-	thearch.optoas = optoas;
-	thearch.doregbits = doregbits;
-	thearch.regnames = regnames;
-	
-	gcmain(argc, argv);
-}
diff --git a/src/cmd/new5g/galign.go b/src/cmd/5g/galign.go
similarity index 100%
rename from src/cmd/new5g/galign.go
rename to src/cmd/5g/galign.go
diff --git a/src/cmd/new5g/gg.go b/src/cmd/5g/gg.go
similarity index 100%
rename from src/cmd/new5g/gg.go
rename to src/cmd/5g/gg.go
diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h
deleted file mode 100644
index b12c7e2..0000000
--- a/src/cmd/5g/gg.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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.
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#include "../gc/go.h"
-#include "../5l/5.out.h"
-
-enum
-{
-	REGALLOC_R0 = REG_R0,
-	REGALLOC_RMAX = REGEXT,
-	REGALLOC_F0 = REG_F0,
-	REGALLOC_FMAX = FREGEXT,
-};
-
-EXTERN	uchar	reg[REGALLOC_FMAX+1];
-extern	long	unmappedzero;
-
-/*
- * gen.c
- */
-void	compile(Node*);
-void	gen(Node*);
-Node*	lookdot(Node*, Node*, int);
-void	cgen_as(Node*, Node*);
-void	cgen_callmeth(Node*, int);
-void	cgen_callinter(Node*, Node*, int);
-void	cgen_proc(Node*, int);
-void	cgen_callret(Node*, Node*);
-void	cgen_dcl(Node*);
-int	needconvert(Type*, Type*);
-void	genconv(Type*, Type*);
-void	allocparams(void);
-void	checklabels(void);
-void	ginscall(Node*, int);
-
-/*
- * cgen
- */
-void	agen(Node*, Node*);
-Prog* cgenindex(Node *, Node *, int);
-void	igen(Node*, Node*, Node*);
-void agenr(Node *n, Node *a, Node *res);
-vlong	fieldoffset(Type*, Node*);
-void	sgen(Node*, Node*, int64);
-void	gmove(Node*, Node*);
-Prog*	gins(int, Node*, Node*);
-int	samaddr(Node*, Node*);
-void	raddr(Node *n, Prog *p);
-Prog*	gcmp(int, Node*, Node*);
-Prog*	gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs);
-Prog *	gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs);
-void	naddr(Node*, Addr*, int);
-void	cgen_aret(Node*, Node*);
-void	cgen_hmul(Node*, Node*, Node*);
-void	cgen_shift(int, int, Node*, Node*, Node*);
-int	componentgen(Node*, Node*);
-
-/*
- * cgen64.c
- */
-void	cmp64(Node*, Node*, int, int, Prog*);
-void	cgen64(Node*, Node*);
-
-/*
- * gsubr.c
- */
-void	clearp(Prog*);
-Prog*	gbranch(int, Type*, int);
-Prog*	prog(int);
-void	gconv(int, int);
-int	conv2pt(Type*);
-vlong	convvtox(vlong, int);
-void	fnparam(Type*, int, int);
-Prog*	gop(int, Node*, Node*, Node*);
-int	optoas(int, Type*);
-void	ginit(void);
-void	gclean(void);
-void	regalloc(Node*, Type*, Node*);
-void	regfree(Node*);
-Node*	nodarg(Type*, int);
-void	nodreg(Node*, Type*, int);
-void	nodindreg(Node*, Type*, int);
-void	buildtxt(void);
-Plist*	newplist(void);
-int	isfat(Type*);
-int	dotaddable(Node*, Node*);
-void	sudoclean(void);
-int	sudoaddable(int, Node*, Addr*, int*);
-void	afunclit(Addr*, Node*);
-void	datagostring(Strlit*, Addr*);
-void	split64(Node*, Node*, Node*);
-void	splitclean(void);
-Node*	ncon(uint32 i);
-void	gtrack(Sym*);
-
-/*
- * obj.c
- */
-void	datastring(char*, int, Addr*);
-
-/*
- * list.c
- */
-void	listinit(void);
-
-void	zaddr(Biobuf*, Addr*, int, int);
-
-void afunclit(Addr*, Node*);
-int anyregalloc(void);
-void betypeinit(void);
-void bgen(Node*, int, int, Prog*);
-void cgen(Node*, Node*);
-void cgen_call(Node*, int);
-void cgen_callinter(Node*, Node*, int);
-void cgen_ret(Node*);
-void clearfat(Node*);
-void clearp(Prog*);
-void defframe(Prog*);
-int dgostringptr(Sym*, int, char*);
-int dgostrlitptr(Sym*, int, Strlit*);
-int dsname(Sym*, int, char*, int);
-int dsymptr(Sym*, int, Sym*, int);
-void dumpdata(void);
-void dumpit(char*, Flow*, int);
-void excise(Flow*);
-void expandchecks(Prog*);
-void fixautoused(Prog*);
-void gclean(void);
-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 ginit(void);
-Prog*	gins(int, Node*, Node*);
-void	ginscall(Node*, int);
-Prog*	gjmp(Prog*);
-void gtrack(Sym*);
-void	gused(Node*);
-void	igen(Node*, Node*, Node*);
-int isfat(Type*);
-void linkarchinit(void);
-void markautoused(Prog*);
-void naddr(Node*, Addr*, int);
-Plist* newplist(void);
-Node* nodarg(Type*, int);
-void patch(Prog*, Prog*);
-void proginfo(ProgInfo*, Prog*);
-void regalloc(Node*, Type*, Node*);
-void regfree(Node*);
-void regopt(Prog*);
-int regtyp(Addr*);
-int sameaddr(Addr*, Addr*);
-int smallindir(Addr*, Addr*);
-int stackaddr(Addr*);
-Prog* unpatch(Prog*);
-
-/*
- * reg.c
- */
-uint64 excludedregs(void);
-uint64 RtoB(int);
-uint64 FtoB(int);
-int BtoR(uint64);
-int BtoF(uint64);
-uint64 doregbits(int);
-char** regnames(int*);
-
-/*
- * peep.c
- */
-void peep(Prog*);
diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c
deleted file mode 100644
index 62b9bea..0000000
--- a/src/cmd/5g/ggen.c
+++ /dev/null
@@ -1,751 +0,0 @@
-// 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.
-
-#undef	EXTERN
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32);
-static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0);
-
-void
-defframe(Prog *ptxt)
-{
-	uint32 frame, r0;
-	Prog *p;
-	vlong hi, lo;
-	NodeList *l;
-	Node *n;
-
-	// fill in argument size, stack size
-	ptxt->to.type = TYPE_TEXTSIZE;
-	ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
-	frame = rnd(stksize+maxarg, widthreg);
-	ptxt->to.offset = frame;
-	
-	// insert code to contain ambiguously live variables
-	// so that garbage collector only sees initialized values
-	// when it looks for pointers.
-	p = ptxt;
-	lo = hi = 0;
-	r0 = 0;
-	for(l=curfn->dcl; l != nil; l = l->next) {
-		n = l->n;
-		if(!n->needzero)
-			continue;
-		if(n->class != PAUTO)
-			fatal("needzero class %d", n->class);
-		if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
-			fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
-		if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthptr) {
-			// merge with range we already have
-			lo = rnd(n->xoffset, widthptr);
-			continue;
-		}
-		// zero old range
-		p = zerorange(p, frame, lo, hi, &r0);
-
-		// set new range
-		hi = n->xoffset + n->type->width;
-		lo = n->xoffset;
-	}
-	// zero final range
-	zerorange(p, frame, lo, hi, &r0);
-}
-
-static Prog*
-zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
-{
-	vlong cnt, i;
-	Prog *p1;
-	Node *f;
-
-	cnt = hi - lo;
-	if(cnt == 0)
-		return p;
-	if(*r0 == 0) {
-		p = appendpp(p, AMOVW, TYPE_CONST, 0, 0, TYPE_REG, REG_R0, 0);
-		*r0 = 1;
-	}
-	if(cnt < 4*widthptr) {
-		for(i = 0; i < cnt; i += widthptr) 
-			p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REGSP, 4+frame+lo+i);
-	} else if(!nacl && (cnt <= 128*widthptr)) {
-		p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
-		p->reg = REGSP;
-		p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_MEM, 0, 0);
-		f = sysfunc("duffzero");
-		naddr(f, &p->to, 1);
-		afunclit(&p->to, f);
-		p->to.offset = 4*(128-cnt/widthptr);
-	} else {
-		p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
-		p->reg = REGSP;
-		p = appendpp(p, AADD, TYPE_CONST, 0, cnt, TYPE_REG, REG_R2, 0);
-		p->reg = REG_R1;
-		p1 = p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REG_R1, 4);
-		p->scond |= C_PBIT;
-		p = appendpp(p, ACMP, TYPE_REG, REG_R1, 0, TYPE_NONE, 0, 0);
-		p->reg = REG_R2;
-		p = appendpp(p, ABNE, TYPE_NONE, 0, 0, TYPE_BRANCH, 0, 0);
-		patch(p, p1);
-	}
-	return p;
-}
-
-static Prog*	
-appendpp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int treg, int32 toffset)	
-{	
-	Prog *q;	
-		
-	q = mal(sizeof(*q));	
-	clearp(q);	
-	q->as = as;	
-	q->lineno = p->lineno;	
-	q->from.type = ftype;	
-	q->from.reg = freg;	
-	q->from.offset = foffset;	
-	q->to.type = ttype;	
-	q->to.reg = treg;	
-	q->to.offset = toffset;	
-	q->link = p->link;	
-	p->link = q;	
-	return q;	
-}
-
-/*
- * generate:
- *	call f
- *	proc=-1	normal call but no return
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
-  *	proc=3	normal call to C pointer (not Go func value)
- */
-void
-ginscall(Node *f, int proc)
-{
-	Prog *p;
-	Node r, r1, con;
-	int32 extra;
-
-	if(f->type != T) {
-		extra = 0;
-		if(proc == 1 || proc == 2)
-			extra = 2 * widthptr;
-		setmaxarg(f->type, extra);
-	}
-
-	switch(proc) {
-	default:
-		fatal("ginscall: bad proc %d", proc);
-		break;
-
-	case 0:	// normal call
-	case -1:	// normal call but no return
-		if(f->op == ONAME && f->class == PFUNC) {
-			if(f == deferreturn) {
-				// Deferred calls will appear to be returning to
-				// the BL deferreturn(SB) that we are about to emit.
-				// However, the stack trace code will show the line
-				// of the instruction before that return PC. 
-				// To avoid that instruction being an unrelated instruction,
-				// insert a NOP so that we will have the right line number.
-				// ARM NOP 0x00000000 is really AND.EQ R0, R0, R0.
-				// Use the latter form because the NOP pseudo-instruction
-				// would be removed by the linker.
-				nodreg(&r, types[TINT], REG_R0);
-				p = gins(AAND, &r, &r);
-				p->scond = C_SCOND_EQ;
-			}
-			p = gins(ABL, N, f);
-			afunclit(&p->to, f);
-			if(proc == -1 || noreturn(p))
-				gins(AUNDEF, N, N);
-			break;
-		}
-		nodreg(&r, types[tptr], REG_R7);
-		nodreg(&r1, types[tptr], REG_R1);
-		gmove(f, &r);
-		r.op = OINDREG;
-		gmove(&r, &r1);
-		r.op = OREGISTER;
-		r1.op = OINDREG;
-		gins(ABL, &r, &r1);
-		break;
-
-	case 3:	// normal call of c function pointer
-		gins(ABL, N, f);
-		break;
-
-	case 1:	// call in new proc (go)
-	case 2:	// deferred call (defer)
-		regalloc(&r, types[tptr], N);
-		nodconst(&con, types[TINT32], argsize(f->type));
-		gins(AMOVW, &con, &r);
-		p = gins(AMOVW, &r, N);
-		p->to.type = TYPE_MEM;
-		p->to.reg = REGSP;
-		p->to.offset = 4;
-
-		gins(AMOVW, f, &r);
-		p = gins(AMOVW, &r, N);
-		p->to.type = TYPE_MEM;
-		p->to.reg = REGSP;
-		p->to.offset = 8;
-
-		regfree(&r);
-
-		if(proc == 1)
-			ginscall(newproc, 0);
-		else
-			ginscall(deferproc, 0);
-
-		if(proc == 2) {
-			nodconst(&con, types[TINT32], 0);
-			p = gins(ACMP, &con, N);
-			p->reg = REG_R0;
-			p = gbranch(ABEQ, T, +1);
-			cgen_ret(N);
-			patch(p, pc);
-		}
-		break;
-	}
-}
-
-/*
- * n is call to interface method.
- * generate res = n.
- */
-void
-cgen_callinter(Node *n, Node *res, int proc)
-{
-	int r;
-	Node *i, *f;
-	Node tmpi, nodo, nodr, nodsp;
-	Prog *p;
-
-	i = n->left;
-	if(i->op != ODOTINTER)
-		fatal("cgen_callinter: not ODOTINTER %O", i->op);
-
-	f = i->right;		// field
-	if(f->op != ONAME)
-		fatal("cgen_callinter: not ONAME %O", f->op);
-
-	i = i->left;		// interface
-
-	// Release res register during genlist and cgen,
-	// which might have their own function calls.
-	r = -1;
-	if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
-		r = res->val.u.reg;
-		reg[r]--;
-	}
-
-	if(!i->addable) {
-		tempname(&tmpi, i->type);
-		cgen(i, &tmpi);
-		i = &tmpi;
-	}
-
-	genlist(n->list);			// args
-	if(r >= 0)
-		reg[r]++;
-
-	regalloc(&nodr, types[tptr], res);
-	regalloc(&nodo, types[tptr], &nodr);
-	nodo.op = OINDREG;
-
-	agen(i, &nodr);		// REG = &inter
-
-	nodindreg(&nodsp, types[tptr], REGSP);
-	nodsp.xoffset = widthptr;
-	if(proc != 0)
-		nodsp.xoffset += 2 * widthptr; // leave room for size & fn
-	nodo.xoffset += widthptr;
-	cgen(&nodo, &nodsp);	// {4 or 12}(SP) = 4(REG) -- i.data
-
-	nodo.xoffset -= widthptr;
-	cgen(&nodo, &nodr);	// REG = 0(REG) -- i.tab
-	cgen_checknil(&nodr); // in case offset is huge
-
-	nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
-	
-	if(proc == 0) {
-		// plain call: use direct c function pointer - more efficient
-		cgen(&nodo, &nodr);	// REG = 20+offset(REG) -- i.tab->fun[f]
-		nodr.op = OINDREG;
-		proc = 3;
-	} else {
-		// go/defer. generate go func value.
-		p = gins(AMOVW, &nodo, &nodr);
-		p->from.type = TYPE_ADDR;	// REG = &(20+offset(REG)) -- i.tab->fun[f]
-	}
-
-	nodr.type = n->left->type;
-	ginscall(&nodr, proc);
-
-	regfree(&nodr);
-	regfree(&nodo);
-}
-
-/*
- * generate function call;
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
- */
-void
-cgen_call(Node *n, int proc)
-{
-	Type *t;
-	Node nod, afun;
-
-	if(n == N)
-		return;
-
-	if(n->left->ullman >= UINF) {
-		// if name involves a fn call
-		// precompute the address of the fn
-		tempname(&afun, types[tptr]);
-		cgen(n->left, &afun);
-	}
-
-	genlist(n->list);		// assign the args
-	t = n->left->type;
-
-	// call tempname pointer
-	if(n->left->ullman >= UINF) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, &afun);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		goto ret;
-	}
-
-	// call pointer
-	if(n->left->op != ONAME || n->left->class != PFUNC) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, n->left);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		goto ret;
-	}
-
-	// call direct
-	n->left->method = 1;
-	ginscall(n->left, proc);
-
-
-ret:
-	;
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = return value from call.
- */
-void
-cgen_callret(Node *n, Node *res)
-{
-	Node nod;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(t->etype == TPTR32 || t->etype == TPTR64)
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_callret: nil");
-
-	memset(&nod, 0, sizeof(nod));
-	nod.op = OINDREG;
-	nod.val.u.reg = REGSP;
-	nod.addable = 1;
-
-	nod.xoffset = fp->width + 4; // +4: saved lr at 0(SP)
-	nod.type = fp->type;
-	cgen_as(res, &nod);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = &return value from call.
- */
-void
-cgen_aret(Node *n, Node *res)
-{
-	Node nod1, nod2;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(isptr[t->etype])
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_aret: nil");
-
-	memset(&nod1, 0, sizeof(nod1));
-	nod1.op = OINDREG;
-	nod1.val.u.reg = REGSP;
-	nod1.addable = 1;
-
-	nod1.xoffset = fp->width + 4; // +4: saved lr at 0(SP)
-	nod1.type = fp->type;
-
-	if(res->op != OREGISTER) {
-		regalloc(&nod2, types[tptr], res);
-		agen(&nod1, &nod2);
-		gins(AMOVW, &nod2, res);
-		regfree(&nod2);
-	} else
-		agen(&nod1, res);
-}
-
-/*
- * generate return.
- * n->left is assignments to return values.
- */
-void
-cgen_ret(Node *n)
-{
-	Prog *p;
-
-	if(n != N)
-		genlist(n->list);		// copy out args
-	if(hasdefer)
-		ginscall(deferreturn, 0);
-	genlist(curfn->exit);
-	p = gins(ARET, N, N);
-	if(n != N && n->op == ORETJMP) {
-		p->to.name = NAME_EXTERN;
-		p->to.type = TYPE_ADDR;
-		p->to.sym = linksym(n->left->sym);
-	}
-}
-
-/*
- * generate high multiply
- *  res = (nl * nr) >> wordsize
- */
-void
-cgen_hmul(Node *nl, Node *nr, Node *res)
-{
-	int w;
-	Node n1, n2, *tmp;
-	Type *t;
-	Prog *p;
-
-	if(nl->ullman < nr->ullman) {
-		tmp = nl;
-		nl = nr;
-		nr = tmp;
-	}
-	t = nl->type;
-	w = t->width * 8;
-	regalloc(&n1, t, res);
-	cgen(nl, &n1);
-	regalloc(&n2, t, N);
-	cgen(nr, &n2);
-	switch(simtype[t->etype]) {
-	case TINT8:
-	case TINT16:
-		gins(optoas(OMUL, t), &n2, &n1);
-		gshift(AMOVW, &n1, SHIFT_AR, w, &n1);
-		break;
-	case TUINT8:
-	case TUINT16:
-		gins(optoas(OMUL, t), &n2, &n1);
-		gshift(AMOVW, &n1, SHIFT_LR, w, &n1);
-		break;
-	case TINT32:
-	case TUINT32:
-		// perform a long multiplication.
-		if(issigned[t->etype])
-			p = gins(AMULL, &n2, N);
-		else
-			p = gins(AMULLU, &n2, N);
-		// n2 * n1 -> (n1 n2)
-		p->reg = n1.val.u.reg;
-		p->to.type = TYPE_REGREG;
-		p->to.reg = n1.val.u.reg;
-		p->to.offset = n2.val.u.reg;
-		break;
-	default:
-		fatal("cgen_hmul %T", t);
-		break;
-	}
-	cgen(&n1, res);
-	regfree(&n1);
-	regfree(&n2);
-}
-
-/*
- * generate shift according to op, one of:
- *	res = nl << nr
- *	res = nl >> nr
- */
-void
-cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n3, nt, t, lo, hi;
-	int w, v;
-	Prog *p1, *p2, *p3;
-	Type *tr;
-	uvlong sc;
-
-	USED(bounded);
-	if(nl->type->width > 4)
-		fatal("cgen_shift %T", nl->type);
-
-	w = nl->type->width * 8;
-
-	if(op == OLROT) {
-		v = mpgetfix(nr->val.u.xval);
-		regalloc(&n1, nl->type, res);
-		if(w == 32) {
-			cgen(nl, &n1);
-			gshift(AMOVW, &n1, SHIFT_RR, w-v, &n1);
-		} else {
-			regalloc(&n2, nl->type, N);
-			cgen(nl, &n2);
-			gshift(AMOVW, &n2, SHIFT_LL, v, &n1);
-			gshift(AORR, &n2, SHIFT_LR, w-v, &n1);
-			regfree(&n2);
-			// Ensure sign/zero-extended result.
-			gins(optoas(OAS, nl->type), &n1, &n1);
-		}
-		gmove(&n1, res);
-		regfree(&n1);
-		return;
-	}
-
-	if(nr->op == OLITERAL) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-		sc = mpgetfix(nr->val.u.xval);
-		if(sc == 0) {
-			// nothing to do
-		} else if(sc >= nl->type->width*8) {
-			if(op == ORSH && issigned[nl->type->etype])
-				gshift(AMOVW, &n1, SHIFT_AR, w, &n1);
-			else
-				gins(AEOR, &n1, &n1);
-		} else {
-			if(op == ORSH && issigned[nl->type->etype])
-				gshift(AMOVW, &n1, SHIFT_AR, sc, &n1);
-			else if(op == ORSH)
-				gshift(AMOVW, &n1, SHIFT_LR, sc, &n1);
-			else // OLSH
-				gshift(AMOVW, &n1, SHIFT_LL, sc, &n1);
-		}
-		if(w < 32 && op == OLSH)
-			gins(optoas(OAS, nl->type), &n1, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		return;
-	}
-
-	tr = nr->type;
-	if(tr->width > 4) {
-		tempname(&nt, nr->type);
-		if(nl->ullman >= nr->ullman) {
-			regalloc(&n2, nl->type, res);
-			cgen(nl, &n2);
-			cgen(nr, &nt);
-			n1 = nt;
-		} else {
-			cgen(nr, &nt);
-			regalloc(&n2, nl->type, res);
-			cgen(nl, &n2);
-		}
-		split64(&nt, &lo, &hi);
-		regalloc(&n1, types[TUINT32], N);
-		regalloc(&n3, types[TUINT32], N);
-		gmove(&lo, &n1);
-		gmove(&hi, &n3);
-		splitclean();
-		gins(ATST, &n3, N);
-		nodconst(&t, types[TUINT32], w);
-		p1 = gins(AMOVW, &t, &n1);
-		p1->scond = C_SCOND_NE;
-		tr = types[TUINT32];
-		regfree(&n3);
-	} else {
-		if(nl->ullman >= nr->ullman) {
-			regalloc(&n2, nl->type, res);
-			cgen(nl, &n2);
-			regalloc(&n1, nr->type, N);
-			cgen(nr, &n1);
-		} else {
-			regalloc(&n1, nr->type, N);
-			cgen(nr, &n1);
-			regalloc(&n2, nl->type, res);
-			cgen(nl, &n2);
-		}
-	}
-
-	// test for shift being 0
-	gins(ATST, &n1, N);
-	p3 = gbranch(ABEQ, T, -1);
-
-	// test and fix up large shifts
-	// TODO: if(!bounded), don't emit some of this.
-	regalloc(&n3, tr, N);
-	nodconst(&t, types[TUINT32], w);
-	gmove(&t, &n3);
-	gcmp(ACMP, &n1, &n3);
-	if(op == ORSH) {
-		if(issigned[nl->type->etype]) {
-			p1 = gshift(AMOVW, &n2, SHIFT_AR, w-1, &n2);
-			p2 = gregshift(AMOVW, &n2, SHIFT_AR, &n1, &n2);
-		} else {
-			p1 = gins(AEOR, &n2, &n2);
-			p2 = gregshift(AMOVW, &n2, SHIFT_LR, &n1, &n2);
-		}
-		p1->scond = C_SCOND_HS;
-		p2->scond = C_SCOND_LO;
-	} else {
-		p1 = gins(AEOR, &n2, &n2);
-		p2 = gregshift(AMOVW, &n2, SHIFT_LL, &n1, &n2);
-		p1->scond = C_SCOND_HS;
-		p2->scond = C_SCOND_LO;
-	}
-	regfree(&n3);
-
-	patch(p3, pc);
-	// Left-shift of smaller word must be sign/zero-extended.
-	if(w < 32 && op == OLSH)
-		gins(optoas(OAS, nl->type), &n2, &n2);
-	gmove(&n2, res);
-
-	regfree(&n1);
-	regfree(&n2);
-}
-
-void
-clearfat(Node *nl)
-{
-	uint32 w, c, q;
-	Node dst, nc, nz, end, r0, r1, *f;
-	Prog *p, *pl;
-
-	/* clear a fat object */
-	if(debug['g'])
-		dump("\nclearfat", nl);
-
-	w = nl->type->width;
-	// Avoid taking the address for simple enough types.
-	if(componentgen(N, nl))
-		return;
-
-	c = w % 4;	// bytes
-	q = w / 4;	// quads
-
-	r0.op = OREGISTER;
-	r0.val.u.reg = REGALLOC_R0;
-	r1.op = OREGISTER;
-	r1.val.u.reg = REGALLOC_R0 + 1;
-	regalloc(&dst, types[tptr], &r1);
-	agen(nl, &dst);
-	nodconst(&nc, types[TUINT32], 0);
-	regalloc(&nz, types[TUINT32], &r0);
-	cgen(&nc, &nz);
-
-	if(q > 128) {
-		regalloc(&end, types[tptr], N);
-		p = gins(AMOVW, &dst, &end);
-		p->from.type = TYPE_ADDR;
-		p->from.offset = q*4;
-
-		p = gins(AMOVW, &nz, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = 4;
-		p->scond |= C_PBIT;
-		pl = p;
-
-		p = gins(ACMP, &dst, N);
-		raddr(&end, p);
-		patch(gbranch(ABNE, T, 0), pl);
-
-		regfree(&end);
-	} else if(q >= 4 && !nacl) {
-		f = sysfunc("duffzero");
-		p = gins(ADUFFZERO, N, f);
-		afunclit(&p->to, f);
-		// 4 and 128 = magic constants: see ../../runtime/asm_arm.s
-		p->to.offset = 4*(128-q);
-	} else
-	while(q > 0) {
-		p = gins(AMOVW, &nz, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = 4;
- 		p->scond |= C_PBIT;
-//print("1. %P\n", p);
-		q--;
-	}
-
-	while(c > 0) {
-		p = gins(AMOVB, &nz, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = 1;
- 		p->scond |= C_PBIT;
-//print("2. %P\n", p);
-		c--;
-	}
-	regfree(&dst);
-	regfree(&nz);
-}
-
-// Called after regopt and peep have run.
-// Expand CHECKNIL pseudo-op into actual nil pointer check.
-void
-expandchecks(Prog *firstp)
-{
-	int reg;
-	Prog *p, *p1;
-
-	for(p = firstp; p != P; p = p->link) {
-		if(p->as != ACHECKNIL)
-			continue;
-		if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
-			warnl(p->lineno, "generated nil check");
-		if(p->from.type != TYPE_REG)
-			fatal("invalid nil check %P", p);
-		reg = p->from.reg;
-		// check is
-		//	CMP arg, $0
-		//	MOV.EQ arg, 0(arg)
-		p1 = mal(sizeof *p1);
-		clearp(p1);
-		p1->link = p->link;
-		p->link = p1;
-		p1->lineno = p->lineno;
-		p1->pc = 9999;
-		p1->as = AMOVW;
-		p1->from.type = TYPE_REG;
-		p1->from.reg = reg;
-		p1->to.type = TYPE_MEM;
-		p1->to.reg = reg;
-		p1->to.offset = 0;
-		p1->scond = C_SCOND_EQ;
-		p->as = ACMP;
-		p->from.type = TYPE_CONST;
-		p->from.reg = 0;
-		p->from.offset = 0;
-		p->reg = reg;
-	}
-}
diff --git a/src/cmd/new5g/ggen.go b/src/cmd/5g/ggen.go
similarity index 100%
rename from src/cmd/new5g/ggen.go
rename to src/cmd/5g/ggen.go
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
deleted file mode 100644
index bdb7027..0000000
--- a/src/cmd/5g/gsubr.c
+++ /dev/null
@@ -1,1527 +0,0 @@
-// Derived from Inferno utils/5c/txt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/txt.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 "gg.h"
-#include "../../runtime/funcdata.h"
-
-// TODO(rsc): Can make this bigger if we move
-// the text segment up higher in 5l for all GOOS.
-// At the same time, can raise StackBig in ../../runtime/stack.h.
-long unmappedzero = 4096;
-
-static	int	resvd[] =
-{
-	9,     // reserved for m
-	10,    // reserved for g
-	REGSP, // reserved for SP
-};
-
-void
-ginit(void)
-{
-	int i;
-
-	for(i=0; i<nelem(reg); i++)
-		reg[i] = 0;
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]++;
-}
-
-void
-gclean(void)
-{
-	int i;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]--;
-
-	for(i=0; i<nelem(reg); i++)
-		if(reg[i])
-			yyerror("reg %R left allocated\n", i);
-}
-
-int
-anyregalloc(void)
-{
-	int i, j;
-
-	for(i=0; i<nelem(reg); i++) {
-		if(reg[i] == 0)
-			goto ok;
-		for(j=0; j<nelem(resvd); j++)
-			if(resvd[j] == i)
-				goto ok;
-		return 1;
-	ok:;
-	}
-	return 0;
-}
-
-uintptr regpc[REGALLOC_FMAX+1];
-
-/*
- * allocate register of type t, leave in n.
- * if o != N, o is desired fixed register.
- * caller must regfree(n).
- */
-void
-regalloc(Node *n, Type *t, Node *o)
-{
-	int i, et, fixfree, floatfree;
-
-	if(0 && debug['r']) {
-		fixfree = 0;
-		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
-			if(reg[i] == 0)
-				fixfree++;
-		floatfree = 0;
-		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
-			if(reg[i] == 0)
-				floatfree++;
-		print("regalloc fix %d float %d\n", fixfree, floatfree);
-	}
-
-	if(t == T)
-		fatal("regalloc: t nil");
-	et = simtype[t->etype];
-	if(is64(t))
-		fatal("regalloc: 64 bit type %T");
-
-	switch(et) {
-	case TINT8:
-	case TUINT8:
-	case TINT16:
-	case TUINT16:
-	case TINT32:
-	case TUINT32:
-	case TPTR32:
-	case TBOOL:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REGALLOC_R0 && i <= REGALLOC_RMAX)
-				goto out;
-		}
-		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
-			if(reg[i] == 0) {
-				regpc[i] = (uintptr)getcallerpc(&n);
-				goto out;
-			}
-		print("registers allocated at\n");
-		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
-			print("%d %p\n", i, regpc[i]);
-		fatal("out of fixed registers");
-		goto err;
-
-	case TFLOAT32:
-	case TFLOAT64:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX)
-				goto out;
-		}
-		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
-			if(reg[i] == 0)
-				goto out;
-		fatal("out of floating point registers");
-		goto err;
-
-	case TCOMPLEX64:
-	case TCOMPLEX128:
-		tempname(n, t);
-		return;
-	}
-	yyerror("regalloc: unknown type %T", t);
-
-err:
-	nodreg(n, t, REG_R0);
-	return;
-
-out:
-	reg[i]++;
-	nodreg(n, t, i);
-}
-
-void
-regfree(Node *n)
-{
-	int i, fixfree, floatfree;
-
-	if(0 && debug['r']) {
-		fixfree = 0;
-		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
-			if(reg[i] == 0)
-				fixfree++;
-		floatfree = 0;
-		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
-			if(reg[i] == 0)
-				floatfree++;
-		print("regalloc fix %d float %d\n", fixfree, floatfree);
-	}
-
-	if(n->op == ONAME)
-		return;
-	if(n->op != OREGISTER && n->op != OINDREG)
-		fatal("regfree: not a register");
-	i = n->val.u.reg;
-	if(i == REGSP)
-		return;
-	if(i < 0 || i >= nelem(reg) || i >= nelem(regpc))
-		fatal("regfree: reg out of range");
-	if(reg[i] <= 0)
-		fatal("regfree: reg %R not allocated", i);
-	reg[i]--;
-	if(reg[i] == 0)
-		regpc[i] = 0;
-}
-
-/*
- * return constant i node.
- * overwritten by next call, but useful in calls to gins.
- */
-Node*
-ncon(uint32 i)
-{
-	static Node n;
-
-	if(n.type == T)
-		nodconst(&n, types[TUINT32], 0);
-	mpmovecfix(n.val.u.xval, i);
-	return &n;
-}
-
-Node sclean[10];
-int nsclean;
-
-/*
- * n is a 64-bit value.  fill in lo and hi to refer to its 32-bit halves.
- */
-void
-split64(Node *n, Node *lo, Node *hi)
-{
-	Node n1;
-	int64 i;
-
-	if(!is64(n->type))
-		fatal("split64 %T", n->type);
-
-	if(nsclean >= nelem(sclean))
-		fatal("split64 clean");
-	sclean[nsclean].op = OEMPTY;
-	nsclean++;
-	switch(n->op) {
-	default:
-		switch(n->op) {
-		default:
-			if(!dotaddable(n, &n1)) {
-				igen(n, &n1, N);
-				sclean[nsclean-1] = n1;
-			}
-			n = &n1;
-			break;
-		case ONAME:
-			if(n->class == PPARAMREF) {
-				cgen(n->heapaddr, &n1);
-				sclean[nsclean-1] = n1;
-				n = &n1;
-			}
-			break;
-		case OINDREG:
-			// nothing
-			break;
-		}
-		*lo = *n;
-		*hi = *n;
-		lo->type = types[TUINT32];
-		if(n->type->etype == TINT64)
-			hi->type = types[TINT32];
-		else
-			hi->type = types[TUINT32];
-		hi->xoffset += 4;
-		break;
-
-	case OLITERAL:
-		convconst(&n1, n->type, &n->val);
-		i = mpgetfix(n1.val.u.xval);
-		nodconst(lo, types[TUINT32], (uint32)i);
-		i >>= 32;
-		if(n->type->etype == TINT64)
-			nodconst(hi, types[TINT32], (int32)i);
-		else
-			nodconst(hi, types[TUINT32], (uint32)i);
-		break;
-	}
-}
-
-void
-splitclean(void)
-{
-	if(nsclean <= 0)
-		fatal("splitclean");
-	nsclean--;
-	if(sclean[nsclean].op != OEMPTY)
-		regfree(&sclean[nsclean]);
-}
-
-#define	CASE(a,b)	(((a)<<16)|((b)<<0))
-/*c2go int CASE(int, int); */
-
-void
-gmove(Node *f, Node *t)
-{
-	int a, ft, tt, fa, ta;
-	Type *cvt;
-	Node r1, r2, flo, fhi, tlo, thi, con;
-	Prog *p1;
-
-	if(debug['M'])
-		print("gmove %N -> %N\n", f, t);
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-
-	if(iscomplex[ft] || iscomplex[tt]) {
-		complexmove(f, t);
-		return;
-	}
-
-	// cannot have two memory operands;
-	// except 64-bit, which always copies via registers anyway.
-	if(!is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
-		goto hard;
-
-	// convert constant to desired type
-	if(f->op == OLITERAL) {
-		switch(tt) {
-		default:
-			convconst(&con, t->type, &f->val);
-			break;
-
-		case TINT16:
-		case TINT8:
-			convconst(&con, types[TINT32], &f->val);
-			regalloc(&r1, con.type, t);
-			gins(AMOVW, &con, &r1);
-			gmove(&r1, t);
-			regfree(&r1);
-			return;
-
-		case TUINT16:
-		case TUINT8:
-			convconst(&con, types[TUINT32], &f->val);
-			regalloc(&r1, con.type, t);
-			gins(AMOVW, &con, &r1);
-			gmove(&r1, t);
-			regfree(&r1);
-			return;
-		}
-
-		f = &con;
-		ft = simsimtype(con.type);
-
-		// constants can't move directly to memory
-		if(ismem(t) && !is64(t->type)) goto hard;
-	}
-
-	// value -> value copy, only one memory operand.
-	// figure out the instruction to use.
-	// break out of switch for one-instruction gins.
-	// goto rdst for "destination must be register".
-	// goto hard for "convert to cvt type first".
-	// otherwise handle and return.
-
-	switch(CASE(ft, tt)) {
-	default:
-		goto fatal;
-
-	/*
-	 * integer copy and truncate
-	 */
-	case CASE(TINT8, TINT8):	// same size
-		if(!ismem(f)) {
-			a = AMOVB;
-			break;
-		}
-	case CASE(TUINT8, TINT8):
-	case CASE(TINT16, TINT8):	// truncate
-	case CASE(TUINT16, TINT8):
-	case CASE(TINT32, TINT8):
-	case CASE(TUINT32, TINT8):
-		a = AMOVBS;
-		break;
-
-	case CASE(TUINT8, TUINT8):
-		if(!ismem(f)) {
-			a = AMOVB;
-			break;
-		}
-	case CASE(TINT8, TUINT8):
-	case CASE(TINT16, TUINT8):
-	case CASE(TUINT16, TUINT8):
-	case CASE(TINT32, TUINT8):
-	case CASE(TUINT32, TUINT8):
-		a = AMOVBU;
-		break;
-
-	case CASE(TINT64, TINT8):	// truncate low word
-	case CASE(TUINT64, TINT8):
-		a = AMOVBS;
-		goto trunc64;
-
-	case CASE(TINT64, TUINT8):
-	case CASE(TUINT64, TUINT8):
-		a = AMOVBU;
-		goto trunc64;
-
-	case CASE(TINT16, TINT16):	// same size
-		if(!ismem(f)) {
-			a = AMOVH;
-			break;
-		}
-	case CASE(TUINT16, TINT16):
-	case CASE(TINT32, TINT16):	// truncate
-	case CASE(TUINT32, TINT16):
-		a = AMOVHS;
-		break;
-
-	case CASE(TUINT16, TUINT16):
-		if(!ismem(f)) {
-			a = AMOVH;
-			break;
-		}
-	case CASE(TINT16, TUINT16):
-	case CASE(TINT32, TUINT16):
-	case CASE(TUINT32, TUINT16):
-		a = AMOVHU;
-		break;
-
-	case CASE(TINT64, TINT16):	// truncate low word
-	case CASE(TUINT64, TINT16):
-		a = AMOVHS;
-		goto trunc64;
-
-	case CASE(TINT64, TUINT16):
-	case CASE(TUINT64, TUINT16):
-		a = AMOVHU;
-		goto trunc64;
-
-	case CASE(TINT32, TINT32):	// same size
-	case CASE(TINT32, TUINT32):
-	case CASE(TUINT32, TINT32):
-	case CASE(TUINT32, TUINT32):
-		a = AMOVW;
-		break;
-
-	case CASE(TINT64, TINT32):	// truncate
-	case CASE(TUINT64, TINT32):
-	case CASE(TINT64, TUINT32):
-	case CASE(TUINT64, TUINT32):
-		split64(f, &flo, &fhi);
-		regalloc(&r1, t->type, N);
-		gins(AMOVW, &flo, &r1);
-		gins(AMOVW, &r1, t);
-		regfree(&r1);
-		splitclean();
-		return;
-
-	case CASE(TINT64, TINT64):	// same size
-	case CASE(TINT64, TUINT64):
-	case CASE(TUINT64, TINT64):
-	case CASE(TUINT64, TUINT64):
-		split64(f, &flo, &fhi);
-		split64(t, &tlo, &thi);
-		regalloc(&r1, flo.type, N);
-		regalloc(&r2, fhi.type, N);
-		gins(AMOVW, &flo, &r1);
-		gins(AMOVW, &fhi, &r2);
-		gins(AMOVW, &r1, &tlo);
-		gins(AMOVW, &r2, &thi);
-		regfree(&r1);
-		regfree(&r2);
-		splitclean();
-		splitclean();
-		return;
-
-	/*
-	 * integer up-conversions
-	 */
-	case CASE(TINT8, TINT16):	// sign extend int8
-	case CASE(TINT8, TUINT16):
-	case CASE(TINT8, TINT32):
-	case CASE(TINT8, TUINT32):
-		a = AMOVBS;
-		goto rdst;
-	case CASE(TINT8, TINT64):	// convert via int32
-	case CASE(TINT8, TUINT64):
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT8, TINT16):	// zero extend uint8
-	case CASE(TUINT8, TUINT16):
-	case CASE(TUINT8, TINT32):
-	case CASE(TUINT8, TUINT32):
-		a = AMOVBU;
-		goto rdst;
-	case CASE(TUINT8, TINT64):	// convert via uint32
-	case CASE(TUINT8, TUINT64):
-		cvt = types[TUINT32];
-		goto hard;
-
-	case CASE(TINT16, TINT32):	// sign extend int16
-	case CASE(TINT16, TUINT32):
-		a = AMOVHS;
-		goto rdst;
-	case CASE(TINT16, TINT64):	// convert via int32
-	case CASE(TINT16, TUINT64):
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT16, TINT32):	// zero extend uint16
-	case CASE(TUINT16, TUINT32):
-		a = AMOVHU;
-		goto rdst;
-	case CASE(TUINT16, TINT64):	// convert via uint32
-	case CASE(TUINT16, TUINT64):
-		cvt = types[TUINT32];
-		goto hard;
-
-	case CASE(TINT32, TINT64):	// sign extend int32
-	case CASE(TINT32, TUINT64):
-		split64(t, &tlo, &thi);
-		regalloc(&r1, tlo.type, N);
-		regalloc(&r2, thi.type, N);
-		gmove(f, &r1);
-		p1 = gins(AMOVW, &r1, &r2);
-		p1->from.type = TYPE_SHIFT;
-		p1->from.offset = 2 << 5 | 31 << 7 | (r1.val.u.reg&15); // r1->31
-		p1->from.reg = 0;
-//print("gmove: %P\n", p1);
-		gins(AMOVW, &r1, &tlo);
-		gins(AMOVW, &r2, &thi);
-		regfree(&r1);
-		regfree(&r2);
-		splitclean();
-		return;
-
-	case CASE(TUINT32, TINT64):	// zero extend uint32
-	case CASE(TUINT32, TUINT64):
-		split64(t, &tlo, &thi);
-		gmove(f, &tlo);
-		regalloc(&r1, thi.type, N);
-		gins(AMOVW, ncon(0), &r1);
-		gins(AMOVW, &r1, &thi);
-		regfree(&r1);
-		splitclean();
-		return;
-
-	/*
-	* float to integer
-	*/
-	case CASE(TFLOAT32, TINT8):
-	case CASE(TFLOAT32, TUINT8):
-	case CASE(TFLOAT32, TINT16):
-	case CASE(TFLOAT32, TUINT16):
-	case CASE(TFLOAT32, TINT32):
-	case CASE(TFLOAT32, TUINT32):
-//	case CASE(TFLOAT32, TUINT64):
-
-	case CASE(TFLOAT64, TINT8):
-	case CASE(TFLOAT64, TUINT8):
-	case CASE(TFLOAT64, TINT16):
-	case CASE(TFLOAT64, TUINT16):
-	case CASE(TFLOAT64, TINT32):
-	case CASE(TFLOAT64, TUINT32):
-//	case CASE(TFLOAT64, TUINT64):
-		fa = AMOVF;
-		a = AMOVFW;
-		if(ft == TFLOAT64) {
-			fa = AMOVD;
-			a = AMOVDW;
-		}
-		ta = AMOVW;
-		switch(tt) {
-		case TINT8:
-			ta = AMOVBS;
-			break;
-		case TUINT8:
-			ta = AMOVBU;
-			break;
-		case TINT16:
-			ta = AMOVHS;
-			break;
-		case TUINT16:
-			ta = AMOVHU;
-			break;
-		}
-
-		regalloc(&r1, types[ft], f);
-		regalloc(&r2, types[tt], t);
-		gins(fa, f, &r1);	// load to fpu
-		p1 = gins(a, &r1, &r1);	// convert to w
-		switch(tt) {
-		case TUINT8:
-		case TUINT16:
-		case TUINT32:
-			p1->scond |= C_UBIT;
-		}
-		gins(AMOVW, &r1, &r2);	// copy to cpu
-		gins(ta, &r2, t);	// store
-		regfree(&r1);
-		regfree(&r2);
-		return;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT8, TFLOAT32):
-	case CASE(TUINT8, TFLOAT32):
-	case CASE(TINT16, TFLOAT32):
-	case CASE(TUINT16, TFLOAT32):
-	case CASE(TINT32, TFLOAT32):
-	case CASE(TUINT32, TFLOAT32):
-	case CASE(TINT8, TFLOAT64):
-	case CASE(TUINT8, TFLOAT64):
-	case CASE(TINT16, TFLOAT64):
-	case CASE(TUINT16, TFLOAT64):
-	case CASE(TINT32, TFLOAT64):
-	case CASE(TUINT32, TFLOAT64):
-		fa = AMOVW;
-		switch(ft) {
-		case TINT8:
-			fa = AMOVBS;
-			break;
-		case TUINT8:
-			fa = AMOVBU;
-			break;
-		case TINT16:
-			fa = AMOVHS;
-			break;
-		case TUINT16:
-			fa = AMOVHU;
-			break;
-		}
-		a = AMOVWF;
-		ta = AMOVF;
-		if(tt == TFLOAT64) {
-			a = AMOVWD;
-			ta = AMOVD;
-		}
-		regalloc(&r1, types[ft], f);
-		regalloc(&r2, types[tt], t);
-		gins(fa, f, &r1);	// load to cpu
-		gins(AMOVW, &r1, &r2);	// copy to fpu
-		p1 = gins(a, &r2, &r2);	// convert
-		switch(ft) {
-		case TUINT8:
-		case TUINT16:
-		case TUINT32:
-			p1->scond |= C_UBIT;
-		}
-		gins(ta, &r2, t);	// store
-		regfree(&r1);
-		regfree(&r2);
-		return;
-
-	case CASE(TUINT64, TFLOAT32):
-	case CASE(TUINT64, TFLOAT64):
-		fatal("gmove UINT64, TFLOAT not implemented");
-		return;
-
-
-	/*
-	 * float to float
-	 */
-	case CASE(TFLOAT32, TFLOAT32):
-		a = AMOVF;
-		break;
-
-	case CASE(TFLOAT64, TFLOAT64):
-		a = AMOVD;
-		break;
-
-	case CASE(TFLOAT32, TFLOAT64):
-		regalloc(&r1, types[TFLOAT64], t);
-		gins(AMOVF, f, &r1);
-		gins(AMOVFD, &r1, &r1);
-		gins(AMOVD, &r1, t);
-		regfree(&r1);
-		return;
-
-	case CASE(TFLOAT64, TFLOAT32):
-		regalloc(&r1, types[TFLOAT64], t);
-		gins(AMOVD, f, &r1);
-		gins(AMOVDF, &r1, &r1);
-		gins(AMOVF, &r1, t);
-		regfree(&r1);
-		return;
-	}
-
-	gins(a, f, t);
-	return;
-
-rdst:
-	// TODO(kaib): we almost always require a register dest anyway, this can probably be
-	// removed.
-	// requires register destination
-	regalloc(&r1, t->type, t);
-	gins(a, f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-trunc64:
-	// truncate 64 bit integer
-	split64(f, &flo, &fhi);
-	regalloc(&r1, t->type, N);
-	gins(a, &flo, &r1);
-	gins(a, &r1, t);
-	regfree(&r1);
-	splitclean();
-	return;
-
-fatal:
-	// should not happen
-	fatal("gmove %N -> %N", f, t);
-}
-
-int
-samaddr(Node *f, Node *t)
-{
-
-	if(f->op != t->op)
-		return 0;
-
-	switch(f->op) {
-	case OREGISTER:
-		if(f->val.u.reg != t->val.u.reg)
-			break;
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * generate one instruction:
- *	as f, t
- */
-Prog*
-gins(int as, Node *f, Node *t)
-{
-//	Node nod;
-//	int32 v;
-	Prog *p;
-	Addr af, at;
-
-	if(f != N && f->op == OINDEX) {
-		fatal("gins OINDEX not implemented");
-//		regalloc(&nod, &regnode, Z);
-//		v = constnode.vconst;
-//		cgen(f->right, &nod);
-//		constnode.vconst = v;
-//		idx.reg = nod.reg;
-//		regfree(&nod);
-	}
-	if(t != N && t->op == OINDEX) {
-		fatal("gins OINDEX not implemented");
-//		regalloc(&nod, &regnode, Z);
-//		v = constnode.vconst;
-//		cgen(t->right, &nod);
-//		constnode.vconst = v;
-//		idx.reg = nod.reg;
-//		regfree(&nod);
-	}
-
-	memset(&af, 0, sizeof af);
-	memset(&at, 0, sizeof at);
-	if(f != N)
-		naddr(f, &af, 1);
-	if(t != N)
-		naddr(t, &at, 1);
-	p = prog(as);
-	if(f != N)
-		p->from = af;
-	if(t != N)
-		p->to = at;
-	if(debug['g'])
-		print("%P\n", p);
-	return p;
-}
-
-/*
- * insert n into reg slot of p
- */
-void
-raddr(Node *n, Prog *p)
-{
-	Addr a;
-
-	naddr(n, &a, 1);
-	if(a.type != TYPE_REG) {
-		if(n)
-			fatal("bad in raddr: %O", n->op);
-		else
-			fatal("bad in raddr: <null>");
-		p->reg = 0;
-	} else
-		p->reg = a.reg;
-}
-
-/* generate a comparison
-TODO(kaib): one of the args can actually be a small constant. relax the constraint and fix call sites.
- */
-Prog*
-gcmp(int as, Node *lhs, Node *rhs)
-{
-	Prog *p;
-
-	if(lhs->op != OREGISTER)
-		fatal("bad operands to gcmp: %O %O", lhs->op, rhs->op);
-
-	p = gins(as, rhs, N);
-	raddr(lhs, p);
-	return p;
-}
-
-/* generate a constant shift
- * arm encodes a shift by 32 as 0, thus asking for 0 shift is illegal.
-*/
-Prog*
-gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
-{
-	Prog *p;
-
-	if(sval <= 0 || sval > 32)
-		fatal("bad shift value: %d", sval);
-
-	sval = sval&0x1f;
-
-	p = gins(as, N, rhs);
-	p->from.type = TYPE_SHIFT;
-	p->from.offset = stype | sval<<7 | (lhs->val.u.reg&15);
-	return p;
-}
-
-/* generate a register shift
-*/
-Prog *
-gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
-{
-	Prog *p;
-	p = gins(as, N, rhs);
-	p->from.type = TYPE_SHIFT;
-	p->from.offset = stype | (reg->val.u.reg&15) << 8 | 1<<4 | (lhs->val.u.reg&15);
-	return p;
-}
-
-/*
- * return Axxx for Oxxx on type t.
- */
-int
-optoas(int op, Type *t)
-{
-	int a;
-
-	if(t == T)
-		fatal("optoas: t is nil");
-
-	a = AXXX;
-	switch(CASE(op, simtype[t->etype])) {
-	default:
-		fatal("optoas: no entry %O-%T etype %T simtype %T", op, t, types[t->etype], types[simtype[t->etype]]);
-		break;
-
-/*	case CASE(OADDR, TPTR32):
-		a = ALEAL;
-		break;
-
-	case CASE(OADDR, TPTR64):
-		a = ALEAQ;
-		break;
-*/
-	// TODO(kaib): make sure the conditional branches work on all edge cases
-	case CASE(OEQ, TBOOL):
-	case CASE(OEQ, TINT8):
-	case CASE(OEQ, TUINT8):
-	case CASE(OEQ, TINT16):
-	case CASE(OEQ, TUINT16):
-	case CASE(OEQ, TINT32):
-	case CASE(OEQ, TUINT32):
-	case CASE(OEQ, TINT64):
-	case CASE(OEQ, TUINT64):
-	case CASE(OEQ, TPTR32):
-	case CASE(OEQ, TPTR64):
-	case CASE(OEQ, TFLOAT32):
-	case CASE(OEQ, TFLOAT64):
-		a = ABEQ;
-		break;
-
-	case CASE(ONE, TBOOL):
-	case CASE(ONE, TINT8):
-	case CASE(ONE, TUINT8):
-	case CASE(ONE, TINT16):
-	case CASE(ONE, TUINT16):
-	case CASE(ONE, TINT32):
-	case CASE(ONE, TUINT32):
-	case CASE(ONE, TINT64):
-	case CASE(ONE, TUINT64):
-	case CASE(ONE, TPTR32):
-	case CASE(ONE, TPTR64):
-	case CASE(ONE, TFLOAT32):
-	case CASE(ONE, TFLOAT64):
-		a = ABNE;
-		break;
-
-	case CASE(OLT, TINT8):
-	case CASE(OLT, TINT16):
-	case CASE(OLT, TINT32):
-	case CASE(OLT, TINT64):
-	case CASE(OLT, TFLOAT32):
-	case CASE(OLT, TFLOAT64):
-		a = ABLT;
-		break;
-
-	case CASE(OLT, TUINT8):
-	case CASE(OLT, TUINT16):
-	case CASE(OLT, TUINT32):
-	case CASE(OLT, TUINT64):
-		a = ABLO;
-		break;
-
-	case CASE(OLE, TINT8):
-	case CASE(OLE, TINT16):
-	case CASE(OLE, TINT32):
-	case CASE(OLE, TINT64):
-	case CASE(OLE, TFLOAT32):
-	case CASE(OLE, TFLOAT64):
-		a = ABLE;
-		break;
-
-	case CASE(OLE, TUINT8):
-	case CASE(OLE, TUINT16):
-	case CASE(OLE, TUINT32):
-	case CASE(OLE, TUINT64):
-		a = ABLS;
-		break;
-
-	case CASE(OGT, TINT8):
-	case CASE(OGT, TINT16):
-	case CASE(OGT, TINT32):
-	case CASE(OGT, TINT64):
-	case CASE(OGT, TFLOAT32):
-	case CASE(OGT, TFLOAT64):
-		a = ABGT;
-		break;
-
-	case CASE(OGT, TUINT8):
-	case CASE(OGT, TUINT16):
-	case CASE(OGT, TUINT32):
-	case CASE(OGT, TUINT64):
-		a = ABHI;
-		break;
-
-	case CASE(OGE, TINT8):
-	case CASE(OGE, TINT16):
-	case CASE(OGE, TINT32):
-	case CASE(OGE, TINT64):
-	case CASE(OGE, TFLOAT32):
-	case CASE(OGE, TFLOAT64):
-		a = ABGE;
-		break;
-
-	case CASE(OGE, TUINT8):
-	case CASE(OGE, TUINT16):
-	case CASE(OGE, TUINT32):
-	case CASE(OGE, TUINT64):
-		a = ABHS;
-		break;
-
-	case CASE(OCMP, TBOOL):
-	case CASE(OCMP, TINT8):
-	case CASE(OCMP, TUINT8):
-	case CASE(OCMP, TINT16):
-	case CASE(OCMP, TUINT16):
-	case CASE(OCMP, TINT32):
-	case CASE(OCMP, TUINT32):
-	case CASE(OCMP, TPTR32):
-		a = ACMP;
-		break;
-
-	case CASE(OCMP, TFLOAT32):
-		a = ACMPF;
-		break;
-
-	case CASE(OCMP, TFLOAT64):
-		a = ACMPD;
-		break;
-
-	case CASE(OAS, TBOOL):
-		a = AMOVB;
-		break;
-
-	case CASE(OAS, TINT8):
-		a = AMOVBS;
-		break;
-
-	case CASE(OAS, TUINT8):
-		a = AMOVBU;
-		break;
-
-	case CASE(OAS, TINT16):
-		a = AMOVHS;
-		break;
-
-	case CASE(OAS, TUINT16):
-		a = AMOVHU;
-		break;
-
-	case CASE(OAS, TINT32):
-	case CASE(OAS, TUINT32):
-	case CASE(OAS, TPTR32):
-		a = AMOVW;
-		break;
-
-	case CASE(OAS, TFLOAT32):
-		a = AMOVF;
-		break;
-
-	case CASE(OAS, TFLOAT64):
-		a = AMOVD;
-		break;
-
-	case CASE(OADD, TINT8):
-	case CASE(OADD, TUINT8):
-	case CASE(OADD, TINT16):
-	case CASE(OADD, TUINT16):
-	case CASE(OADD, TINT32):
-	case CASE(OADD, TUINT32):
-	case CASE(OADD, TPTR32):
-		a = AADD;
-		break;
-
-	case CASE(OADD, TFLOAT32):
-		a = AADDF;
-		break;
-
-	case CASE(OADD, TFLOAT64):
-		a = AADDD;
-		break;
-
-	case CASE(OSUB, TINT8):
-	case CASE(OSUB, TUINT8):
-	case CASE(OSUB, TINT16):
-	case CASE(OSUB, TUINT16):
-	case CASE(OSUB, TINT32):
-	case CASE(OSUB, TUINT32):
-	case CASE(OSUB, TPTR32):
-		a = ASUB;
-		break;
-
-	case CASE(OSUB, TFLOAT32):
-		a = ASUBF;
-		break;
-
-	case CASE(OSUB, TFLOAT64):
-		a = ASUBD;
-		break;
-
-	case CASE(OMINUS, TINT8):
-	case CASE(OMINUS, TUINT8):
-	case CASE(OMINUS, TINT16):
-	case CASE(OMINUS, TUINT16):
-	case CASE(OMINUS, TINT32):
-	case CASE(OMINUS, TUINT32):
-	case CASE(OMINUS, TPTR32):
-		a = ARSB;
-		break;
-
-	case CASE(OAND, TINT8):
-	case CASE(OAND, TUINT8):
-	case CASE(OAND, TINT16):
-	case CASE(OAND, TUINT16):
-	case CASE(OAND, TINT32):
-	case CASE(OAND, TUINT32):
-	case CASE(OAND, TPTR32):
-		a = AAND;
-		break;
-
-	case CASE(OOR, TINT8):
-	case CASE(OOR, TUINT8):
-	case CASE(OOR, TINT16):
-	case CASE(OOR, TUINT16):
-	case CASE(OOR, TINT32):
-	case CASE(OOR, TUINT32):
-	case CASE(OOR, TPTR32):
-		a = AORR;
-		break;
-
-	case CASE(OXOR, TINT8):
-	case CASE(OXOR, TUINT8):
-	case CASE(OXOR, TINT16):
-	case CASE(OXOR, TUINT16):
-	case CASE(OXOR, TINT32):
-	case CASE(OXOR, TUINT32):
-	case CASE(OXOR, TPTR32):
-		a = AEOR;
-		break;
-
-	case CASE(OLSH, TINT8):
-	case CASE(OLSH, TUINT8):
-	case CASE(OLSH, TINT16):
-	case CASE(OLSH, TUINT16):
-	case CASE(OLSH, TINT32):
-	case CASE(OLSH, TUINT32):
-	case CASE(OLSH, TPTR32):
-		a = ASLL;
-		break;
-
-	case CASE(ORSH, TUINT8):
-	case CASE(ORSH, TUINT16):
-	case CASE(ORSH, TUINT32):
-	case CASE(ORSH, TPTR32):
-		a = ASRL;
-		break;
-
-	case CASE(ORSH, TINT8):
-	case CASE(ORSH, TINT16):
-	case CASE(ORSH, TINT32):
-		a = ASRA;
-		break;
-
-	case CASE(OMUL, TUINT8):
-	case CASE(OMUL, TUINT16):
-	case CASE(OMUL, TUINT32):
-	case CASE(OMUL, TPTR32):
-		a = AMULU;
-		break;
-
-	case CASE(OMUL, TINT8):
-	case CASE(OMUL, TINT16):
-	case CASE(OMUL, TINT32):
-		a = AMUL;
-		break;
-
-	case CASE(OMUL, TFLOAT32):
-		a = AMULF;
-		break;
-
-	case CASE(OMUL, TFLOAT64):
-		a = AMULD;
-		break;
-
-	case CASE(ODIV, TUINT8):
-	case CASE(ODIV, TUINT16):
-	case CASE(ODIV, TUINT32):
-	case CASE(ODIV, TPTR32):
-		a = ADIVU;
-		break;
-
-	case CASE(ODIV, TINT8):
-	case CASE(ODIV, TINT16):
-	case CASE(ODIV, TINT32):
-		a = ADIV;
-		break;
-
-	case CASE(OMOD, TUINT8):
-	case CASE(OMOD, TUINT16):
-	case CASE(OMOD, TUINT32):
-	case CASE(OMOD, TPTR32):
-		a = AMODU;
-		break;
-
-	case CASE(OMOD, TINT8):
-	case CASE(OMOD, TINT16):
-	case CASE(OMOD, TINT32):
-		a = AMOD;
-		break;
-
-//	case CASE(OEXTEND, TINT16):
-//		a = ACWD;
-//		break;
-
-//	case CASE(OEXTEND, TINT32):
-//		a = ACDQ;
-//		break;
-
-//	case CASE(OEXTEND, TINT64):
-//		a = ACQO;
-//		break;
-
-	case CASE(ODIV, TFLOAT32):
-		a = ADIVF;
-		break;
-
-	case CASE(ODIV, TFLOAT64):
-		a = ADIVD;
-		break;
-
-	}
-	return a;
-}
-
-enum
-{
-	ODynam	= 1<<0,
-	OPtrto	= 1<<1,
-};
-
-static	Node	clean[20];
-static	int	cleani = 0;
-
-void
-sudoclean(void)
-{
-	if(clean[cleani-1].op != OEMPTY)
-		regfree(&clean[cleani-1]);
-	if(clean[cleani-2].op != OEMPTY)
-		regfree(&clean[cleani-2]);
-	cleani -= 2;
-}
-
-int
-dotaddable(Node *n, Node *n1)
-{
-	int o;
-	int64 oary[10];
-	Node *nn;
-
-	if(n->op != ODOT)
-		return 0;
-
-	o = dotoffset(n, oary, &nn);
-	if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
-		*n1 = *nn;
-		n1->type = n->type;
-		n1->xoffset += oary[0];
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * generate code to compute address of n,
- * a reference to a (perhaps nested) field inside
- * an array or struct.
- * return 0 on failure, 1 on success.
- * on success, leaves usable address in a.
- *
- * caller is responsible for calling sudoclean
- * after successful sudoaddable,
- * to release the register used for a.
- */
-int
-sudoaddable(int as, Node *n, Addr *a, int *w)
-{
-	int o, i;
-	int64 oary[10];
-	int64 v;
-	Node n1, n2, n3, n4, *nn, *l, *r;
-	Node *reg, *reg1;
-	Prog *p1, *p2;
-	Type *t;
-
-	if(n->type == T)
-		return 0;
-
-	memset(a, 0, sizeof *a);
-
-	switch(n->op) {
-	case OLITERAL:
-		if(!isconst(n, CTINT))
-			break;
-		v = mpgetfix(n->val.u.xval);
-		if(v >= 32000 || v <= -32000)
-			break;
-		goto lit;
-
-	case ODOT:
-	case ODOTPTR:
-		cleani += 2;
-		reg = &clean[cleani-1];
-		reg1 = &clean[cleani-2];
-		reg->op = OEMPTY;
-		reg1->op = OEMPTY;
-		goto odot;
-
-	case OINDEX:
-		return 0;
-		// disabled: OINDEX case is now covered by agenr
-		// for a more suitable register allocation pattern.
-		if(n->left->type->etype == TSTRING)
-			return 0;
-		cleani += 2;
-		reg = &clean[cleani-1];
-		reg1 = &clean[cleani-2];
-		reg->op = OEMPTY;
-		reg1->op = OEMPTY;
-		goto oindex;
-	}
-	return 0;
-
-lit:
-	switch(as) {
-	default:
-		return 0;
-	case AADD: case ASUB: case AAND: case AORR: case AEOR:
-	case AMOVB: case AMOVBS: case AMOVBU:
-	case AMOVH: case AMOVHS: case AMOVHU:
-	case AMOVW:
-		break;
-	}
-
-	cleani += 2;
-	reg = &clean[cleani-1];
-	reg1 = &clean[cleani-2];
-	reg->op = OEMPTY;
-	reg1->op = OEMPTY;
-	naddr(n, a, 1);
-	goto yes;
-
-odot:
-	o = dotoffset(n, oary, &nn);
-	if(nn == N)
-		goto no;
-
-	if(nn->addable && o == 1 && oary[0] >= 0) {
-		// directly addressable set of DOTs
-		n1 = *nn;
-		n1.type = n->type;
-		n1.xoffset += oary[0];
-		naddr(&n1, a, 1);
-		goto yes;
-	}
-
-	regalloc(reg, types[tptr], N);
-	n1 = *reg;
-	n1.op = OINDREG;
-	if(oary[0] >= 0) {
-		agen(nn, reg);
-		n1.xoffset = oary[0];
-	} else {
-		cgen(nn, reg);
-		cgen_checknil(reg);
-		n1.xoffset = -(oary[0]+1);
-	}
-
-	for(i=1; i<o; i++) {
-		if(oary[i] >= 0)
-			fatal("can't happen");
-		gins(AMOVW, &n1, reg);
-		cgen_checknil(reg);
-		n1.xoffset = -(oary[i]+1);
-	}
-
-	a->type = TYPE_NONE;
-	a->name = NAME_NONE;
-	n1.type = n->type;
-	naddr(&n1, a, 1);
-	goto yes;
-
-oindex:
-	l = n->left;
-	r = n->right;
-	if(l->ullman >= UINF && r->ullman >= UINF)
-		goto no;
-
-	// set o to type of array
-	o = 0;
-	if(isptr[l->type->etype]) {
-		o += OPtrto;
-		if(l->type->type->etype != TARRAY)
-			fatal("not ptr ary");
-		if(l->type->type->bound < 0)
-			o += ODynam;
-	} else {
-		if(l->type->etype != TARRAY)
-			fatal("not ary");
-		if(l->type->bound < 0)
-			o += ODynam;
-	}
-
-	*w = n->type->width;
-	if(isconst(r, CTINT))
-		goto oindex_const;
-
-	switch(*w) {
-	default:
-		goto no;
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		break;
-	}
-
-	// load the array (reg)
-	if(l->ullman > r->ullman) {
-		regalloc(reg, types[tptr], N);
-		if(o & OPtrto) {
-			cgen(l, reg);
-			cgen_checknil(reg);
-		} else
-			agen(l, reg);
-	}
-
-	// load the index (reg1)
-	t = types[TUINT32];
-	if(issigned[r->type->etype])
-		t = types[TINT32];
-	regalloc(reg1, t, N);
-	regalloc(&n3, types[TINT32], reg1);
-	p2 = cgenindex(r, &n3, debug['B'] || n->bounded);
-	gmove(&n3, reg1);
-	regfree(&n3);
-
-	// load the array (reg)
-	if(l->ullman <= r->ullman) {
-		regalloc(reg, types[tptr], N);
-		if(o & OPtrto) {
-			cgen(l, reg);
-			cgen_checknil(reg);
-		} else
-			agen(l, reg);
-	}
-
-	// check bounds
-	if(!debug['B']) {
-		if(o & ODynam) {
-			n2 = *reg;
-			n2.op = OINDREG;
-			n2.type = types[tptr];
-			n2.xoffset = Array_nel;
-		} else {
-			if(o & OPtrto)
-				nodconst(&n2, types[TUINT32], l->type->type->bound);
-			else
-				nodconst(&n2, types[TUINT32], l->type->bound);
-		}
-		regalloc(&n3, n2.type, N);
-		cgen(&n2, &n3);
-		gcmp(optoas(OCMP, types[TUINT32]), reg1, &n3);
-		regfree(&n3);
-		p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		if(p2)
-			patch(p2, pc);
-		ginscall(panicindex, 0);
-		patch(p1, pc);
-	}
-
-	if(o & ODynam) {
-		n2 = *reg;
-		n2.op = OINDREG;
-		n2.type = types[tptr];
-		n2.xoffset = Array_array;
-		gmove(&n2, reg);
-	}
-
-	switch(*w) {
-	case 1:
-		gins(AADD, reg1, reg);
-		break;
-	case 2:
-		gshift(AADD, reg1, SHIFT_LL, 1, reg);
-		break;
-	case 4:
-		gshift(AADD, reg1, SHIFT_LL, 2, reg);
-		break;
-	case 8:
-		gshift(AADD, reg1, SHIFT_LL, 3, reg);
-		break;
-	}
-
-	naddr(reg1, a, 1);
-	a->type = TYPE_MEM;
-	a->reg = reg->val.u.reg;
-	a->offset = 0;
-	goto yes;
-
-oindex_const:
-	// index is constant
-	// can check statically and
-	// can multiply by width statically
-
-	regalloc(reg, types[tptr], N);
-	if(o & OPtrto) {
-		cgen(l, reg);
-		cgen_checknil(reg);
-	} else
-		agen(l, reg);
-
-	v = mpgetfix(r->val.u.xval);
-	if(o & ODynam) {
-		if(!debug['B'] && !n->bounded) {
-			n1 = *reg;
-			n1.op = OINDREG;
-			n1.type = types[tptr];
-			n1.xoffset = Array_nel;
-			nodconst(&n2, types[TUINT32], v);
-			regalloc(&n3, types[TUINT32], N);
-			cgen(&n2, &n3);
-			regalloc(&n4, n1.type, N);
-			cgen(&n1, &n4);
-			gcmp(optoas(OCMP, types[TUINT32]), &n4, &n3);
-			regfree(&n4);
-			regfree(&n3);
-			p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
-			ginscall(panicindex, 0);
-			patch(p1, pc);
-		}
-
-		n1 = *reg;
-		n1.op = OINDREG;
-		n1.type = types[tptr];
-		n1.xoffset = Array_array;
-		gmove(&n1, reg);
-	}
-
-	n2 = *reg;
-	n2.op = OINDREG;
-	n2.xoffset = v * (*w);
-	a->type = TYPE_NONE;
-	a->name = NAME_NONE;
-	naddr(&n2, a, 1);
-	goto yes;
-
-yes:
-	return 1;
-
-no:
-	sudoclean();
-	return 0;
-}
diff --git a/src/cmd/new5g/gsubr.go b/src/cmd/5g/gsubr.go
similarity index 100%
rename from src/cmd/new5g/gsubr.go
rename to src/cmd/5g/gsubr.go
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
deleted file mode 100644
index 7fe3e10..0000000
--- a/src/cmd/5g/peep.c
+++ /dev/null
@@ -1,1619 +0,0 @@
-// Inferno utils/5c/peep.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/peep.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 "gg.h"
-#include "../gc/popt.h"
-
-static int	xtramodes(Graph*, Flow*, Adr*);
-static int	shortprop(Flow *r);
-static int	subprop(Flow*);
-static int	copyprop(Graph*, Flow*);
-static int	copy1(Adr*, Adr*, Flow*, int);
-static int	copyas(Adr*, Adr*);
-static int	copyau(Adr*, Adr*);
-static int	copysub(Adr*, Adr*, Adr*, int);
-static int	copysub1(Prog*, Adr*, Adr*, int);
-static Flow*	findpre(Flow *r, Adr *v);
-static int	copyau1(Prog *p, Adr *v);
-static int	isdconst(Addr *a);
-static int	isfloatreg(Addr*);
-static int	copyu(Prog *p, Adr *v, Adr *s);
-
-static uint32	gactive;
-
-// UNUSED
-int	shiftprop(Flow *r);
-void	constprop(Adr *c1, Adr *v1, Flow *r);
-void	predicate(Graph*);
-
-
-void
-peep(Prog *firstp)
-{
-	Flow *r;
-	Graph *g;
-	Prog *p;
-	int t;
-
-	g = flowstart(firstp, 0);
-	if(g == nil)
-		return;
-	gactive = 0;
-
-loop1:
-	if(debug['P'] && debug['v'])
-		dumpit("loop1", g->start, 0);
-
-	t = 0;
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case ASLL:
-		case ASRL:
-		case ASRA:
-			/*
-			 * elide shift into TYPE_SHIFT operand of subsequent instruction
-			 */
-//			if(shiftprop(r)) {
-//				excise(r);
-//				t++;
-//				break;
-//			}
-			break;
-
-		case AMOVB:
-		case AMOVH:
-		case AMOVW:
-		case AMOVF:
-		case AMOVD:
-			if(regtyp(&p->from))
-			if(p->from.type == p->to.type && isfloatreg(&p->from) == isfloatreg(&p->to))
-			if(p->scond == C_SCOND_NONE) {
-				if(copyprop(g, r)) {
-					excise(r);
-					t++;
-					break;
-				}
-				if(subprop(r) && copyprop(g, r)) {
-					excise(r);
-					t++;
-					break;
-				}
-			}
-			break;
-
-		case AMOVHS:
-		case AMOVHU:
-		case AMOVBS:
-		case AMOVBU:
-			if(p->from.type == TYPE_REG) {
-				if(shortprop(r))
-					t++;
-			}
-			break;
-
-			/*
-			if(p->scond == C_SCOND_NONE)
-			if(regtyp(&p->to))
-			if(isdconst(&p->from)) {
-				constprop(&p->from, &p->to, r->s1);
-			}
-			break;
-			*/
-		}
-	}
-	if(t)
-		goto loop1;
-
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case AEOR:
-			/*
-			 * EOR -1,x,y => MVN x,y
-			 */
-			if(isdconst(&p->from) && p->from.offset == -1) {
-				p->as = AMVN;
-				p->from.type = TYPE_REG;
-				if(p->reg != 0)
-					p->from.reg = p->reg;
-				else
-					p->from.reg = p->to.reg;
-				p->reg = 0;
-			}
-			break;
-		}
-	}
-
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case AMOVW:
-		case AMOVB:
-		case AMOVBS:
-		case AMOVBU:
-			if(p->from.type == TYPE_MEM && p->from.offset == 0)
-				xtramodes(g, r, &p->from);
-			else
-			if(p->to.type == TYPE_MEM && p->to.offset == 0)
-				xtramodes(g, r, &p->to);
-			else
-				continue;
-			break;
-//		case ACMP:
-//			/*
-//			 * elide CMP $0,x if calculation of x can set condition codes
-//			 */
-//			if(isdconst(&p->from) || p->from.offset != 0)
-//				continue;
-//			r2 = r->s1;
-//			if(r2 == nil)
-//				continue;
-//			t = r2->prog->as;
-//			switch(t) {
-//			default:
-//				continue;
-//			case ABEQ:
-//			case ABNE:
-//			case ABMI:
-//			case ABPL:
-//				break;
-//			case ABGE:
-//				t = ABPL;
-//				break;
-//			case ABLT:
-//				t = ABMI;
-//				break;
-//			case ABHI:
-//				t = ABNE;
-//				break;
-//			case ABLS:
-//				t = ABEQ;
-//				break;
-//			}
-//			r1 = r;
-//			do
-//				r1 = uniqp(r1);
-//			while (r1 != nil && r1->prog->as == ANOP);
-//			if(r1 == nil)
-//				continue;
-//			p1 = r1->prog;
-//			if(p1->to.type != TYPE_REG)
-//				continue;
-//			if(p1->to.reg != p->reg)
-//			if(!(p1->as == AMOVW && p1->from.type == TYPE_REG && p1->from.reg == p->reg))
-//				continue;
-//
-//			switch(p1->as) {
-//			default:
-//				continue;
-//			case AMOVW:
-//				if(p1->from.type != TYPE_REG)
-//					continue;
-//			case AAND:
-//			case AEOR:
-//			case AORR:
-//			case ABIC:
-//			case AMVN:
-//			case ASUB:
-//			case ARSB:
-//			case AADD:
-//			case AADC:
-//			case ASBC:
-//			case ARSC:
-//				break;
-//			}
-//			p1->scond |= C_SBIT;
-//			r2->prog->as = t;
-//			excise(r);
-//			continue;
-		}
-	}
-
-//	predicate(g);
-
-	flowend(g);
-}
-
-int
-regtyp(Adr *a)
-{
-	return a->type == TYPE_REG && (REG_R0 <= a->reg && a->reg <= REG_R15 || REG_F0 <= a->reg && a->reg <= REG_F15);
-}
-
-/*
- * the idea is to substitute
- * one register for another
- * from one MOV to another
- *	MOV	a, R0
- *	ADD	b, R0	/ no use of R1
- *	MOV	R0, R1
- * would be converted to
- *	MOV	a, R1
- *	ADD	b, R1
- *	MOV	R1, R0
- * hopefully, then the former or latter MOV
- * will be eliminated by copy propagation.
- */
-static int
-subprop(Flow *r0)
-{
-	Prog *p;
-	Adr *v1, *v2;
-	Flow *r;
-	int t;
-	ProgInfo info;
-
-	p = r0->prog;
-	v1 = &p->from;
-	if(!regtyp(v1))
-		return 0;
-	v2 = &p->to;
-	if(!regtyp(v2))
-		return 0;
-	for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
-		if(uniqs(r) == nil)
-			break;
-		p = r->prog;
-		if(p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-		proginfo(&info, p);
-		if(info.flags & Call)
-			return 0;
-
-		if((info.flags & CanRegRead) && p->to.type == TYPE_REG) {
-			info.flags |= RegRead;
-			info.flags &= ~(CanRegRead | RightRead);
-			p->reg = p->to.reg;
-		}
-
-		switch(p->as) {
-		case AMULLU:
-		case AMULA:
-		case AMVN:
-			return 0;
-		}
-		
-		if((info.flags & (RightRead|RightWrite)) == RightWrite) {
-			if(p->to.type == v1->type)
-			if(p->to.reg == v1->reg)
-			if(p->scond == C_SCOND_NONE)
-				goto gotit;
-		}
-
-		if(copyau(&p->from, v2) ||
-		   copyau1(p, v2) ||
-		   copyau(&p->to, v2))
-			break;
-		if(copysub(&p->from, v1, v2, 0) ||
-		   copysub1(p, v1, v2, 0) ||
-		   copysub(&p->to, v1, v2, 0))
-			break;
-	}
-	return 0;
-
-gotit:
-	copysub(&p->to, v1, v2, 1);
-	if(debug['P']) {
-		print("gotit: %D->%D\n%P", v1, v2, r->prog);
-		if(p->from.type == v2->type)
-			print(" excise");
-		print("\n");
-	}
-	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
-		p = r->prog;
-		copysub(&p->from, v1, v2, 1);
-		copysub1(p, v1, v2, 1);
-		copysub(&p->to, v1, v2, 1);
-		if(debug['P'])
-			print("%P\n", r->prog);
-	}
-	t = v1->reg;
-	v1->reg = v2->reg;
-	v2->reg = t;
-	if(debug['P'])
-		print("%P last\n", r->prog);
-	return 1;
-}
-
-/*
- * The idea is to remove redundant copies.
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	use v2	return fail
- *	-----------------
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	set v2	return success
- */
-static int
-copyprop(Graph *g, Flow *r0)
-{
-	Prog *p;
-	Adr *v1, *v2;
-
-	USED(g);
-	p = r0->prog;
-	v1 = &p->from;
-	v2 = &p->to;
-	if(copyas(v1, v2))
-		return 1;
-	gactive++;
-	return copy1(v1, v2, r0->s1, 0);
-}
-
-static int
-copy1(Adr *v1, Adr *v2, Flow *r, int f)
-{
-	int t;
-	Prog *p;
-
-	if(r->active == gactive) {
-		if(debug['P'])
-			print("act set; return 1\n");
-		return 1;
-	}
-	r->active = gactive;
-	if(debug['P'])
-		print("copy %D->%D f=%d\n", v1, v2, f);
-	for(; r != nil; r = r->s1) {
-		p = r->prog;
-		if(debug['P'])
-			print("%P", p);
-		if(!f && uniqp(r) == nil) {
-			f = 1;
-			if(debug['P'])
-				print("; merge; f=%d", f);
-		}
-		t = copyu(p, v2, nil);
-		switch(t) {
-		case 2:	/* rar, can't split */
-			if(debug['P'])
-				print("; %Drar; return 0\n", v2);
-			return 0;
-
-		case 3:	/* set */
-			if(debug['P'])
-				print("; %Dset; return 1\n", v2);
-			return 1;
-
-		case 1:	/* used, substitute */
-		case 4:	/* use and set */
-			if(f) {
-				if(!debug['P'])
-					return 0;
-				if(t == 4)
-					print("; %Dused+set and f=%d; return 0\n", v2, f);
-				else
-					print("; %Dused and f=%d; return 0\n", v2, f);
-				return 0;
-			}
-			if(copyu(p, v2, v1)) {
-				if(debug['P'])
-					print("; sub fail; return 0\n");
-				return 0;
-			}
-			if(debug['P'])
-				print("; sub%D/%D", v2, v1);
-			if(t == 4) {
-				if(debug['P'])
-					print("; %Dused+set; return 1\n", v2);
-				return 1;
-			}
-			break;
-		}
-		if(!f) {
-			t = copyu(p, v1, nil);
-			if(!f && (t == 2 || t == 3 || t == 4)) {
-				f = 1;
-				if(debug['P'])
-					print("; %Dset and !f; f=%d", v1, f);
-			}
-		}
-		if(debug['P'])
-			print("\n");
-		if(r->s2)
-			if(!copy1(v1, v2, r->s2, f))
-				return 0;
-	}
-	return 1;
-}
-
-// UNUSED
-/*
- * The idea is to remove redundant constants.
- *	$c1->v1
- *	($c1->v2 s/$c1/v1)*
- *	set v1  return
- * The v1->v2 should be eliminated by copy propagation.
- */
-void
-constprop(Adr *c1, Adr *v1, Flow *r)
-{
-	Prog *p;
-
-	if(debug['P'])
-		print("constprop %D->%D\n", c1, v1);
-	for(; r != nil; r = r->s1) {
-		p = r->prog;
-		if(debug['P'])
-			print("%P", p);
-		if(uniqp(r) == nil) {
-			if(debug['P'])
-				print("; merge; return\n");
-			return;
-		}
-		if(p->as == AMOVW && copyas(&p->from, c1)) {
-				if(debug['P'])
-					print("; sub%D/%D", &p->from, v1);
-				p->from = *v1;
-		} else if(copyu(p, v1, nil) > 1) {
-			if(debug['P'])
-				print("; %Dset; return\n", v1);
-			return;
-		}
-		if(debug['P'])
-			print("\n");
-		if(r->s2)
-			constprop(c1, v1, r->s2);
-	}
-}
-
-/*
- * shortprop eliminates redundant zero/sign extensions.
- *
- *   MOVBS x, R
- *   <no use R>
- *   MOVBS R, R'
- *
- * changed to
- *
- *   MOVBS x, R
- *   ...
- *   MOVB  R, R' (compiled to mov)
- *
- * MOVBS above can be a MOVBS, MOVBU, MOVHS or MOVHU.
- */
-static int
-shortprop(Flow *r)
-{
-	Prog *p, *p1;
-	Flow *r1;
-
-	p = r->prog;
-	r1 = findpre(r, &p->from);
-	if(r1 == nil)
-		return 0;
-
-	p1 = r1->prog;
-	if(p1->as == p->as) {
-		// Two consecutive extensions.
-		goto gotit;
-	}
-
-	if(p1->as == AMOVW && isdconst(&p1->from)
-	   && p1->from.offset >= 0 && p1->from.offset < 128) {
-		// Loaded an immediate.
-		goto gotit;
-	}
-
-	return 0;
-
-gotit:
-	if(debug['P'])
-		print("shortprop\n%P\n%P", p1, p);
-	switch(p->as) {
-	case AMOVBS:
-	case AMOVBU:
-		p->as = AMOVB;
-		break;
-	case AMOVHS:
-	case AMOVHU:
-		p->as = AMOVH;
-		break;
-	}
-	if(debug['P'])
-		print(" => %A\n", p->as);
-	return 1;
-}
-
-// UNUSED
-/*
- * ASLL x,y,w
- * .. (not use w, not set x y w)
- * AXXX w,a,b (a != w)
- * .. (not use w)
- * (set w)
- * ----------- changed to
- * ..
- * AXXX (x<<y),a,b
- * ..
- */
-
-int
-shiftprop(Flow *r)
-{
-	Flow *r1;
-	Prog *p, *p1, *p2;
-	int n, o;
-	Adr a;
-
-	p = r->prog;
-	if(p->to.type != TYPE_REG) {
-		if(debug['P'])
-			print("\tBOTCH: result not reg; FAILURE\n");
-		return 0;
-	}
-	n = p->to.reg;
-	a = zprog.from;
-	if(p->reg != 0 && p->reg != p->to.reg) {
-		a.type = TYPE_REG;
-		a.reg = p->reg;
-	}
-	if(debug['P'])
-		print("shiftprop\n%P", p);
-	r1 = r;
-	for(;;) {
-		/* find first use of shift result; abort if shift operands or result are changed */
-		r1 = uniqs(r1);
-		if(r1 == nil) {
-			if(debug['P'])
-				print("\tbranch; FAILURE\n");
-			return 0;
-		}
-		if(uniqp(r1) == nil) {
-			if(debug['P'])
-				print("\tmerge; FAILURE\n");
-			return 0;
-		}
-		p1 = r1->prog;
-		if(debug['P'])
-			print("\n%P", p1);
-		switch(copyu(p1, &p->to, nil)) {
-		case 0:	/* not used or set */
-			if((p->from.type == TYPE_REG && copyu(p1, &p->from, nil) > 1) ||
-			   (a.type == TYPE_REG && copyu(p1, &a, nil) > 1)) {
-				if(debug['P'])
-					print("\targs modified; FAILURE\n");
-				return 0;
-			}
-			continue;
-		case 3:	/* set, not used */ {
-			if(debug['P'])
-				print("\tBOTCH: noref; FAILURE\n");
-			return 0;
-		}
-		}
-		break;
-	}
-	/* check whether substitution can be done */
-	switch(p1->as) {
-	default:
-		if(debug['P'])
-			print("\tnon-dpi; FAILURE\n");
-		return 0;
-
-	case AAND:
-	case AEOR:
-	case AADD:
-	case AADC:
-	case AORR:
-	case ASUB:
-	case ASBC:
-	case ARSB:
-	case ARSC:
-		if(p1->reg == n || (p1->reg == 0 && p1->to.type == TYPE_REG && p1->to.reg == n)) {
-			if(p1->from.type != TYPE_REG) {
-				if(debug['P'])
-					print("\tcan't swap; FAILURE\n");
-				return 0;
-			}
-			p1->reg = p1->from.reg;
-			p1->from.reg = n;
-			switch(p1->as) {
-			case ASUB:
-				p1->as = ARSB;
-				break;
-			case ARSB:
-				p1->as = ASUB;
-				break;
-			case ASBC:
-				p1->as = ARSC;
-				break;
-			case ARSC:
-				p1->as = ASBC;
-				break;
-			}
-			if(debug['P'])
-				print("\t=>%P", p1);
-		}
-	case ABIC:
-	case ATST:
-	case ACMP:
-	case ACMN:
-		if(p1->reg == n) {
-			if(debug['P'])
-				print("\tcan't swap; FAILURE\n");
-			return 0;
-		}
-		if(p1->reg == 0 && p1->to.reg == n) {
-			if(debug['P'])
-				print("\tshift result used twice; FAILURE\n");
-			return 0;
-		}
-//	case AMVN:
-		if(p1->from.type == TYPE_SHIFT) {
-			if(debug['P'])
-				print("\tshift result used in shift; FAILURE\n");
-			return 0;
-		}
-		if(p1->from.type != TYPE_REG || p1->from.reg != n) {
-			if(debug['P'])
-				print("\tBOTCH: where is it used?; FAILURE\n");
-			return 0;
-		}
-		break;
-	}
-	/* check whether shift result is used subsequently */
-	p2 = p1;
-	if(p1->to.reg != n)
-	for (;;) {
-		r1 = uniqs(r1);
-		if(r1 == nil) {
-			if(debug['P'])
-				print("\tinconclusive; FAILURE\n");
-			return 0;
-		}
-		p1 = r1->prog;
-		if(debug['P'])
-			print("\n%P", p1);
-		switch(copyu(p1, &p->to, nil)) {
-		case 0:	/* not used or set */
-			continue;
-		case 3: /* set, not used */
-			break;
-		default:/* used */
-			if(debug['P'])
-				print("\treused; FAILURE\n");
-			return 0;
-		}
-		break;
-	}
-
-	/* make the substitution */
-	p2->from.reg = 0;
-	o = p->reg;
-	if(o == 0)
-		o = p->to.reg;
-	o &= 15;
-
-	switch(p->from.type){
-	case TYPE_CONST:
-		o |= (p->from.offset&0x1f)<<7;
-		break;
-	case TYPE_REG:
-		o |= (1<<4) | ((p->from.reg&15)<<8);
-		break;
-	}
-	switch(p->as){
-	case ASLL:
-		o |= 0<<5;
-		break;
-	case ASRL:
-		o |= 1<<5;
-		break;
-	case ASRA:
-		o |= 2<<5;
-		break;
-	}
-	p2->from = zprog.from;
-	p2->from.type = TYPE_SHIFT;
-	p2->from.offset = o;
-	if(debug['P'])
-		print("\t=>%P\tSUCCEED\n", p2);
-	return 1;
-}
-
-/*
- * findpre returns the last instruction mentioning v
- * before r. It must be a set, and there must be
- * a unique path from that instruction to r.
- */
-static Flow*
-findpre(Flow *r, Adr *v)
-{
-	Flow *r1;
-
-	for(r1=uniqp(r); r1!=nil; r=r1,r1=uniqp(r)) {
-		if(uniqs(r1) != r)
-			return nil;
-		switch(copyu(r1->prog, v, nil)) {
-		case 1: /* used */
-		case 2: /* read-alter-rewrite */
-			return nil;
-		case 3: /* set */
-		case 4: /* set and used */
-			return r1;
-		}
-	}
-	return nil;
-}
-
-/*
- * findinc finds ADD instructions with a constant
- * argument which falls within the immed_12 range.
- */
-static Flow*
-findinc(Flow *r, Flow *r2, Adr *v)
-{
-	Flow *r1;
-	Prog *p;
-
-
-	for(r1=uniqs(r); r1!=nil && r1!=r2; r=r1,r1=uniqs(r)) {
-		if(uniqp(r1) != r)
-			return nil;
-		switch(copyu(r1->prog, v, nil)) {
-		case 0: /* not touched */
-			continue;
-		case 4: /* set and used */
-			p = r1->prog;
-			if(p->as == AADD)
-			if(isdconst(&p->from))
-			if(p->from.offset > -4096 && p->from.offset < 4096)
-				return r1;
-		default:
-			return nil;
-		}
-	}
-	return nil;
-}
-
-static int
-nochange(Flow *r, Flow *r2, Prog *p)
-{
-	Adr a[3];
-	int i, n;
-
-	if(r == r2)
-		return 1;
-	n = 0;
-	if(p->reg != 0 && p->reg != p->to.reg) {
-		a[n].type = TYPE_REG;
-		a[n++].reg = p->reg;
-	}
-	switch(p->from.type) {
-	case TYPE_SHIFT:
-		a[n].type = TYPE_REG;
-		a[n++].reg = REG_R0 + (p->from.offset&0xf);
-	case TYPE_REG:
-		a[n].type = TYPE_REG;
-		a[n++].reg = p->from.reg;
-	}
-	if(n == 0)
-		return 1;
-	for(; r!=nil && r!=r2; r=uniqs(r)) {
-		p = r->prog;
-		for(i=0; i<n; i++)
-			if(copyu(p, &a[i], nil) > 1)
-				return 0;
-	}
-	return 1;
-}
-
-static int
-findu1(Flow *r, Adr *v)
-{
-	for(; r != nil; r = r->s1) {
-		if(r->active)
-			return 0;
-		r->active = 1;
-		switch(copyu(r->prog, v, nil)) {
-		case 1: /* used */
-		case 2: /* read-alter-rewrite */
-		case 4: /* set and used */
-			return 1;
-		case 3: /* set */
-			return 0;
-		}
-		if(r->s2)
-			if (findu1(r->s2, v))
-				return 1;
-	}
-	return 0;
-}
-
-static int
-finduse(Graph *g, Flow *r, Adr *v)
-{
-	Flow *r1;
-
-	for(r1=g->start; r1!=nil; r1=r1->link)
-		r1->active = 0;
-	return findu1(r, v);
-}
-
-/*
- * xtramodes enables the ARM post increment and
- * shift offset addressing modes to transform
- *   MOVW   0(R3),R1
- *   ADD    $4,R3,R3
- * into
- *   MOVW.P 4(R3),R1
- * and 
- *   ADD    R0,R1
- *   MOVBU  0(R1),R0
- * into 
- *   MOVBU  R0<<0(R1),R0
- */
-static int
-xtramodes(Graph *g, Flow *r, Adr *a)
-{
-	Flow *r1, *r2, *r3;
-	Prog *p, *p1;
-	Adr v;
-
-	p = r->prog;
-	v = *a;
-	v.type = TYPE_REG;
-	r1 = findpre(r, &v);
-	if(r1 != nil) {
-		p1 = r1->prog;
-		if(p1->to.type == TYPE_REG && p1->to.reg == v.reg)
-		switch(p1->as) {
-		case AADD:
-			if(p1->scond & C_SBIT)
-				// avoid altering ADD.S/ADC sequences.
-				break;
-			if(p1->from.type == TYPE_REG ||
-			   (p1->from.type == TYPE_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
-			    ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
-			   ((p1->from.type == TYPE_ADDR || p1->from.type == TYPE_CONST) &&
-			    p1->from.offset > -4096 && p1->from.offset < 4096))
-			if(nochange(uniqs(r1), r, p1)) {
-				if(a != &p->from || v.reg != p->to.reg)
-				if (finduse(g, r->s1, &v)) {
-					if(p1->reg == 0 || p1->reg == v.reg)
-						/* pre-indexing */
-						p->scond |= C_WBIT;
-					else return 0;
-				}
-				switch (p1->from.type) {
-				case TYPE_REG:
-					/* register offset */
-					if(nacl)
-						return 0;
-					*a = zprog.from;
-					a->type = TYPE_SHIFT;
-					a->offset = p1->from.reg&15;
-					break;
-				case TYPE_SHIFT:
-					/* scaled register offset */
-					if(nacl)
-						return 0;
-					*a = zprog.from;
-					a->type = TYPE_SHIFT;
-				case TYPE_CONST:
-				case TYPE_ADDR:
-					/* immediate offset */
-					a->offset = p1->from.offset;
-					break;
-				}
-				if(p1->reg != 0)
-					a->reg = p1->reg;
-				excise(r1);
-				return 1;
-			}
-			break;
-		case AMOVW:
-			if(p1->from.type == TYPE_REG)
-			if((r2 = findinc(r1, r, &p1->from)) != nil) {
-			for(r3=uniqs(r2); r3->prog->as==ANOP; r3=uniqs(r3))
-				;
-			if(r3 == r) {
-				/* post-indexing */
-				p1 = r2->prog;
-				a->reg = p1->to.reg;
-				a->offset = p1->from.offset;
-				p->scond |= C_PBIT;
-				if(!finduse(g, r, &r1->prog->to))
-					excise(r1);
-				excise(r2);
-				return 1;
-			}
-			}
-			break;
-		}
-	}
-	if(a != &p->from || a->reg != p->to.reg)
-	if((r1 = findinc(r, nil, &v)) != nil) {
-		/* post-indexing */
-		p1 = r1->prog;
-		a->offset = p1->from.offset;
-		p->scond |= C_PBIT;
-		excise(r1);
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * return
- * 1 if v only used (and substitute),
- * 2 if read-alter-rewrite
- * 3 if set
- * 4 if set and used
- * 0 otherwise (not touched)
- */
-static int
-copyu(Prog *p, Adr *v, Adr *s)
-{
-	switch(p->as) {
-
-	default:
-		print("copyu: can't find %A\n", p->as);
-		return 2;
-
-	case AMOVM:
-		if(v->type != TYPE_REG)
-			return 0;
-		if(p->from.type == TYPE_CONST) {	/* read reglist, read/rar */
-			if(s != nil) {
-				if(p->from.offset&(1<<v->reg))
-					return 1;
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-				return 0;
-			}
-			if(copyau(&p->to, v)) {
-				if(p->scond&C_WBIT)
-					return 2;
-				return 1;
-			}
-			if(p->from.offset&(1<<v->reg))
-				return 1;
-		} else {			/* read/rar, write reglist */
-			if(s != nil) {
-				if(p->to.offset&(1<<v->reg))
-					return 1;
-				if(copysub(&p->from, v, s, 1))
-					return 1;
-				return 0;
-			}
-			if(copyau(&p->from, v)) {
-				if(p->scond&C_WBIT)
-					return 2;
-				if(p->to.offset&(1<<v->reg))
-					return 4;
-				return 1;
-			}
-			if(p->to.offset&(1<<v->reg))
-				return 3;
-		}
-		return 0;
-
-	case ANOP:	/* read,, write */
-	case AMOVW:
-	case AMOVF:
-	case AMOVD:
-	case AMOVH:
-	case AMOVHS:
-	case AMOVHU:
-	case AMOVB:
-	case AMOVBS:
-	case AMOVBU:
-	case AMOVFW:
-	case AMOVWF:
-	case AMOVDW:
-	case AMOVWD:
-	case AMOVFD:
-	case AMOVDF:
-		if(p->scond&(C_WBIT|C_PBIT))
-		if(v->type == TYPE_REG) {
-			if(p->from.type == TYPE_MEM || p->from.type == TYPE_SHIFT) {
-				if(p->from.reg == v->reg)
-					return 2;
-			} else {
-		  		if(p->to.reg == v->reg)
-					return 2;
-			}
-		}
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			if(!copyas(&p->to, v))
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-			return 0;
-		}
-		if(copyas(&p->to, v)) {
-			if(p->scond != C_SCOND_NONE)
-				return 2;
-			if(copyau(&p->from, v))
-				return 4;
-			return 3;
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case AMULLU:	/* read, read, write, write */
-	case AMULL:
-	case AMULA:
-	case AMVN:
-		return 2;
-
-	case AADD:	/* read, read, write */
-	case AADC:
-	case ASUB:
-	case ASBC:
-	case ARSB:
-	case ASLL:
-	case ASRL:
-	case ASRA:
-	case AORR:
-	case AAND:
-	case AEOR:
-	case AMUL:
-	case AMULU:
-	case ADIV:
-	case ADIVU:
-	case AMOD:
-	case AMODU:
-	case AADDF:
-	case AADDD:
-	case ASUBF:
-	case ASUBD:
-	case AMULF:
-	case AMULD:
-	case ADIVF:
-	case ADIVD:
-
-	case ACHECKNIL: /* read */
-	case ACMPF:	/* read, read, */
-	case ACMPD:
-	case ACMP:
-	case ACMN:
-	case ACASE:
-	case ATST:	/* read,, */
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			if(copysub1(p, v, s, 1))
-				return 1;
-			if(!copyas(&p->to, v))
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-			return 0;
-		}
-		if(copyas(&p->to, v)) {
-			if(p->scond != C_SCOND_NONE)
-				return 2;
-			if(p->reg == 0)
-				p->reg = p->to.reg;
-			if(copyau(&p->from, v))
-				return 4;
-			if(copyau1(p, v))
-				return 4;
-			return 3;
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau1(p, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ABEQ:	/* read, read */
-	case ABNE:
-	case ABCS:
-	case ABHS:
-	case ABCC:
-	case ABLO:
-	case ABMI:
-	case ABPL:
-	case ABVS:
-	case ABVC:
-	case ABHI:
-	case ABLS:
-	case ABGE:
-	case ABLT:
-	case ABGT:
-	case ABLE:
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			return copysub1(p, v, s, 1);
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau1(p, v))
-			return 1;
-		return 0;
-
-	case AB:	/* funny */
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ARET:	/* funny */
-		if(s != nil)
-			return 1;
-		return 3;
-
-	case ABL:	/* funny */
-		if(v->type == TYPE_REG) {
-			// TODO(rsc): REG_R0 and REG_F0 used to be
-			// (when register numbers started at 0) exregoffset and exfregoffset,
-			// which are unset entirely. 
-			// It's strange that this handles R0 and F0 differently from the other
-			// registers. Possible failure to optimize?
-			if(REG_R0 < v->reg && v->reg <= REGEXT)
-				return 2;
-			if(v->reg == REGARG)
-				return 2;
-			if(REG_F0 < v->reg && v->reg <= FREGEXT)
-				return 2;
-		}
-		if(p->from.type == TYPE_REG && v->type == TYPE_REG && p->from.reg == v->reg)
-			return 2;
-
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 4;
-		return 3;
-	case ADUFFZERO:
-		// R0 is zero, used by DUFFZERO, cannot be substituted.
-		// R1 is ptr to memory, used and set, cannot be substituted.
-		if(v->type == TYPE_REG) {
-			if(v->reg == REGALLOC_R0)
-				return 1;
-			if(v->reg == REGALLOC_R0+1)
-				return 2;
-		}
-		return 0;
-	case ADUFFCOPY:
-		// R0 is scratch, set by DUFFCOPY, cannot be substituted.
-		// R1, R2 areptr to src, dst, used and set, cannot be substituted.
-		if(v->type == TYPE_REG) {
-			if(v->reg == REGALLOC_R0)
-				return 3;
-			if(v->reg == REGALLOC_R0+1 || v->reg == REGALLOC_R0+2)
-				return 2;
-		}
-		return 0;
-			
-	case ATEXT:	/* funny */
-		if(v->type == TYPE_REG)
-			if(v->reg == REGARG)
-				return 3;
-		return 0;
-
-	case APCDATA:
-	case AFUNCDATA:
-	case AVARDEF:
-	case AVARKILL:
-		return 0;
-	}
-}
-
-/*
- * direct reference,
- * could be set/use depending on
- * semantics
- */
-static int
-copyas(Adr *a, Adr *v)
-{
-
-	if(regtyp(v)) {
-		if(a->type == v->type)
-		if(a->reg == v->reg)
-			return 1;
-	} else
-	if(v->type == TYPE_CONST) {		/* for constprop */
-		if(a->type == v->type)
-		if(a->name == v->name)
-		if(a->sym == v->sym)
-		if(a->reg == v->reg)
-		if(a->offset == v->offset)
-			return 1;
-	}
-	return 0;
-}
-
-int
-sameaddr(Adr *a, Adr *v)
-{
-	if(a->type != v->type)
-		return 0;
-	if(regtyp(v) && a->reg == v->reg)
-		return 1;
-	// TODO(rsc): Change v->type to v->name and enable.
-	//if(v->type == NAME_AUTO || v->type == NAME_PARAM) {
-	//	if(v->offset == a->offset)
-	//		return 1;
-	//}
-	return 0;
-}
-
-/*
- * either direct or indirect
- */
-static int
-copyau(Adr *a, Adr *v)
-{
-
-	if(copyas(a, v))
-		return 1;
-	if(v->type == TYPE_REG) {
-		if(a->type == TYPE_ADDR && a->reg != 0) {
-			if(a->reg == v->reg)
-				return 1;
-		} else
-		if(a->type == TYPE_MEM) {
-			if(a->reg == v->reg)
-				return 1;
-		} else
-		if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
-			if(a->reg == v->reg)
-				return 1;
-			if(a->offset == v->reg)
-				return 1;
-		} else
-		if(a->type == TYPE_SHIFT) {
-			if((a->offset&0xf) == v->reg - REG_R0)
-				return 1;
-			if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
-				return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * compare v to the center
- * register in p (p->reg)
- */
-static int
-copyau1(Prog *p, Adr *v)
-{
-	if(v->type == TYPE_REG && v->reg == 0)
-		return 0;
-	return p->reg == v->reg;
-}
-
-/*
- * substitute s for v in a
- * return failure to substitute
- */
-static int
-copysub(Adr *a, Adr *v, Adr *s, int f)
-{
-
-	if(f)
-	if(copyau(a, v)) {
-		if(a->type == TYPE_SHIFT) {
-			if((a->offset&0xf) == v->reg - REG_R0)
-				a->offset = (a->offset&~0xf)|(s->reg&0xf);
-			if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
-				a->offset = (a->offset&~(0xf<<8))|((s->reg&0xf)<<8);
-		} else
-		if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
-			if(a->offset == v->reg)
-				a->offset = s->reg;
-			if(a->reg == v->reg)
-				a->reg = s->reg;
-		} else
-			a->reg = s->reg;
-	}
-	return 0;
-}
-
-static int
-copysub1(Prog *p1, Adr *v, Adr *s, int f)
-{
-
-	if(f)
-	if(copyau1(p1, v))
-		p1->reg = s->reg;
-	return 0;
-}
-
-struct {
-	int opcode;
-	int notopcode;
-	int scond;
-	int notscond;
-} predinfo[]  = {
-	{ ABEQ,	ABNE,	0x0,	0x1, },
-	{ ABNE,	ABEQ,	0x1,	0x0, },
-	{ ABCS,	ABCC,	0x2,	0x3, },
-	{ ABHS,	ABLO,	0x2,	0x3, },
-	{ ABCC,	ABCS,	0x3,	0x2, },
-	{ ABLO,	ABHS,	0x3,	0x2, },
-	{ ABMI,	ABPL,	0x4,	0x5, },
-	{ ABPL,	ABMI,	0x5,	0x4, },
-	{ ABVS,	ABVC,	0x6,	0x7, },
-	{ ABVC,	ABVS,	0x7,	0x6, },
-	{ ABHI,	ABLS,	0x8,	0x9, },
-	{ ABLS,	ABHI,	0x9,	0x8, },
-	{ ABGE,	ABLT,	0xA,	0xB, },
-	{ ABLT,	ABGE,	0xB,	0xA, },
-	{ ABGT,	ABLE,	0xC,	0xD, },
-	{ ABLE,	ABGT,	0xD,	0xC, },
-};
-
-typedef struct {
-	Flow *start;
-	Flow *last;
-	Flow *end;
-	int len;
-} Joininfo;
-
-enum {
-	Join,
-	Split,
-	End,
-	Branch,
-	Setcond,
-	Toolong
-};
-
-enum {
-	Falsecond,
-	Truecond,
-	Delbranch,
-	Keepbranch
-};
-
-static int
-isbranch(Prog *p)
-{
-	return (ABEQ <= p->as) && (p->as <= ABLE);
-}
-
-static int
-predicable(Prog *p)
-{
-	switch(p->as) {
-	case ANOP:
-	case AXXX:
-	case ADATA:
-	case AGLOBL:
-	case ATEXT:
-	case AWORD:
-	case ABCASE:
-	case ACASE:
-		return 0;
-	}
-	if(isbranch(p))
-		return 0;
-	return 1;
-}
-
-/*
- * Depends on an analysis of the encodings performed by 5l.
- * These seem to be all of the opcodes that lead to the "S" bit
- * being set in the instruction encodings.
- *
- * C_SBIT may also have been set explicitly in p->scond.
- */
-static int
-modifiescpsr(Prog *p)
-{
-	switch(p->as) {
-	case AMULLU:
-	case AMULA:
-	case AMULU:
-	case ADIVU:
-
-	case ATEQ:
-	case ACMN:
-	case ATST:
-	case ACMP:
-	case AMUL:
-	case ADIV:
-	case AMOD:
-	case AMODU:
-	case ABL:
-		return 1;
-	}
-	if(p->scond & C_SBIT)
-		return 1;
-	return 0;
-}
-
-/*
- * Find the maximal chain of instructions starting with r which could
- * be executed conditionally
- */
-static int
-joinsplit(Flow *r, Joininfo *j)
-{
-	j->start = r;
-	j->last = r;
-	j->len = 0;
-	do {
-		if (r->p2 && (r->p1 || r->p2->p2link)) {
-			j->end = r;
-			return Join;
-		}
-		if (r->s1 && r->s2) {
-			j->end = r;
-			return Split;
-		}
-		j->last = r;
-		if (r->prog->as != ANOP)
-			j->len++;
-		if (!r->s1 && !r->s2) {
-			j->end = r->link;
-			return End;
-		}
-		if (r->s2) {
-			j->end = r->s2;
-			return Branch;
-		}
-		if (modifiescpsr(r->prog)) {
-			j->end = r->s1;
-			return Setcond;
-		}
-		r = r->s1;
-	} while (j->len < 4);
-	j->end = r;
-	return Toolong;
-}
-
-static Flow*
-successor(Flow *r)
-{
-	if(r->s1)
-		return r->s1;
-	else
-		return r->s2;
-}
-
-static void
-applypred(Flow *rstart, Joininfo *j, int cond, int branch)
-{
-	int pred;
-	Flow *r;
-
-	if(j->len == 0)
-		return;
-	if(cond == Truecond)
-		pred = predinfo[rstart->prog->as - ABEQ].scond;
-	else
-		pred = predinfo[rstart->prog->as - ABEQ].notscond;
-
-	for(r = j->start;; r = successor(r)) {
-		if(r->prog->as == AB) {
-			if(r != j->last || branch == Delbranch)
-				excise(r);
-			else {
-				if(cond == Truecond)
-					r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
-				else
-					r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
-			}
-		}
-		else
-		if(predicable(r->prog))
-			r->prog->scond = (r->prog->scond&~C_SCOND)|pred;
-		if(r->s1 != r->link) {
-			r->s1 = r->link;
-			r->link->p1 = r;
-		}
-		if(r == j->last)
-			break;
-	}
-}
-
-void
-predicate(Graph *g)
-{
-	Flow *r;
-	int t1, t2;
-	Joininfo j1, j2;
-
-	for(r=g->start; r!=nil; r=r->link) {
-		if (isbranch(r->prog)) {
-			t1 = joinsplit(r->s1, &j1);
-			t2 = joinsplit(r->s2, &j2);
-			if(j1.last->link != j2.start)
-				continue;
-			if(j1.end == j2.end)
-			if((t1 == Branch && (t2 == Join || t2 == Setcond)) ||
-			   (t2 == Join && (t1 == Join || t1 == Setcond))) {
-				applypred(r, &j1, Falsecond, Delbranch);
-				applypred(r, &j2, Truecond, Delbranch);
-				excise(r);
-				continue;
-			}
-			if(t1 == End || t1 == Branch) {
-				applypred(r, &j1, Falsecond, Keepbranch);
-				excise(r);
-				continue;
-			}
-		}
-	}
-}
-
-static int
-isdconst(Addr *a)
-{
-	return a->type == TYPE_CONST;
-}
-
-static int
-isfloatreg(Addr *a)
-{
-	return REG_F0 <= a->reg && a->reg <= REG_F15;
-}
-
-int
-stackaddr(Addr *a)
-{
-	return regtyp(a) && a->reg == REGSP;
-}
-
-int
-smallindir(Addr *a, Addr *reg)
-{
-	return reg->type == TYPE_REG && a->type == TYPE_MEM &&
-		a->reg == reg->reg &&
-		0 <= a->offset && a->offset < 4096;
-}
-
-void
-excise(Flow *r)
-{
-	Prog *p;
-
-	p = r->prog;
-	nopout(p);
-}
diff --git a/src/cmd/new5g/peep.go b/src/cmd/5g/peep.go
similarity index 100%
rename from src/cmd/new5g/peep.go
rename to src/cmd/5g/peep.go
diff --git a/src/cmd/5g/prog.c b/src/cmd/5g/prog.c
deleted file mode 100644
index 9d5adef..0000000
--- a/src/cmd/5g/prog.c
+++ /dev/null
@@ -1,160 +0,0 @@
-// 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 "gg.h"
-#include "../gc/popt.h"
-
-enum
-{
-	RightRdwr = RightRead | RightWrite,
-};
-
-// This table gives the basic information about instruction
-// generated by the compiler and processed in the optimizer.
-// See opt.h for bit definitions.
-//
-// Instructions not generated need not be listed.
-// As an exception to that rule, we typically write down all the
-// size variants of an operation even if we just use a subset.
-//
-// The table is formatted for 8-space tabs.
-static ProgInfo progtable[ALAST] = {
-	[ATYPE]=	{Pseudo | Skip},
-	[ATEXT]=	{Pseudo},
-	[AFUNCDATA]=	{Pseudo},
-	[APCDATA]=	{Pseudo},
-	[AUNDEF]=	{Break},
-	[AUSEFIELD]=	{OK},
-	[ACHECKNIL]=	{LeftRead},
-	[AVARDEF]=	{Pseudo | RightWrite},
-	[AVARKILL]=	{Pseudo | RightWrite},
-
-	// NOP is an internal no-op that also stands
-	// for USED and SET annotations, not the Intel opcode.
-	[ANOP]=		{LeftRead | RightWrite},
-	
-	// Integer.
-	[AADC]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AADD]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AAND]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ABIC]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ACMN]=		{SizeL | LeftRead | RightRead},
-	[ACMP]=		{SizeL | LeftRead | RightRead},
-	[ADIVU]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[ADIV]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AEOR]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AMODU]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMOD]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AMULALU]=	{SizeL | LeftRead | RegRead | RightRdwr},
-	[AMULAL]=	{SizeL | LeftRead | RegRead | RightRdwr},
-	[AMULA]=	{SizeL | LeftRead | RegRead | RightRdwr},
-	[AMULU]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMUL]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[AMULL]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMULLU]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMVN]=		{SizeL | LeftRead | RightWrite},
-	[AORR]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ARSB]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ARSC]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ASBC]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ASLL]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ASRA]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ASRL]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ASUB]=		{SizeL | LeftRead | RegRead | RightWrite},
-	[ATEQ]=		{SizeL | LeftRead | RightRead},
-	[ATST]=		{SizeL | LeftRead | RightRead},
-
-	// Floating point.
-	[AADDD]=	{SizeD | LeftRead | RightRdwr},
-	[AADDF]=	{SizeF | LeftRead | RightRdwr},
-	[ACMPD]=	{SizeD | LeftRead | RightRead},
-	[ACMPF]=	{SizeF | LeftRead | RightRead},
-	[ADIVD]=	{SizeD | LeftRead | RightRdwr},
-	[ADIVF]=	{SizeF | LeftRead | RightRdwr},
-	[AMULD]=	{SizeD | LeftRead | RightRdwr},
-	[AMULF]=	{SizeF | LeftRead | RightRdwr},
-	[ASUBD]=	{SizeD | LeftRead | RightRdwr},
-	[ASUBF]=	{SizeF | LeftRead | RightRdwr},
-
-	// Conversions.
-	[AMOVWD]=		{SizeD | LeftRead | RightWrite | Conv},
-	[AMOVWF]=		{SizeF | LeftRead | RightWrite | Conv},
-	[AMOVDF]=		{SizeF | LeftRead | RightWrite | Conv},
-	[AMOVDW]=		{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVFD]=		{SizeD | LeftRead | RightWrite | Conv},
-	[AMOVFW]=		{SizeL | LeftRead | RightWrite | Conv},
-
-	// Moves.
-	[AMOVB]=		{SizeB | LeftRead | RightWrite | Move},
-	[AMOVD]=		{SizeD | LeftRead | RightWrite | Move},
-	[AMOVF]=		{SizeF | LeftRead | RightWrite | Move},
-	[AMOVH]=		{SizeW | LeftRead | RightWrite | Move},
-	[AMOVW]=		{SizeL | LeftRead | RightWrite | Move},
-	// In addtion, duffzero reads R0,R1 and writes R1.  This fact is
-	// encoded in peep.c
-	[ADUFFZERO]=		{Call},
-	// In addtion, duffcopy reads R1,R2 and writes R0,R1,R2.  This fact is
-	// encoded in peep.c
-	[ADUFFCOPY]=		{Call},
-
-	// These should be split into the two different conversions instead
-	// of overloading the one.
-	[AMOVBS]=		{SizeB | LeftRead | RightWrite | Conv},
-	[AMOVBU]=		{SizeB | LeftRead | RightWrite | Conv},
-	[AMOVHS]=		{SizeW | LeftRead | RightWrite | Conv},
-	[AMOVHU]=		{SizeW | LeftRead | RightWrite | Conv},
-	
-	// Jumps.
-	[AB]=		{Jump | Break},
-	[ABL]=		{Call},
-	[ABEQ]=		{Cjmp},
-	[ABNE]=		{Cjmp},
-	[ABCS]=		{Cjmp},
-	[ABHS]=		{Cjmp},
-	[ABCC]=		{Cjmp},
-	[ABLO]=		{Cjmp},
-	[ABMI]=		{Cjmp},
-	[ABPL]=		{Cjmp},
-	[ABVS]=		{Cjmp},
-	[ABVC]=		{Cjmp},
-	[ABHI]=		{Cjmp},
-	[ABLS]=		{Cjmp},
-	[ABGE]=		{Cjmp},
-	[ABLT]=		{Cjmp},
-	[ABGT]=		{Cjmp},
-	[ABLE]=		{Cjmp},
-	[ARET]=		{Break},
-};
-
-void
-proginfo(ProgInfo *info, Prog *p)
-{
-	*info = progtable[p->as];
-	if(info->flags == 0)
-		fatal("unknown instruction %P", p);
-
-	if(p->from.type == TYPE_ADDR && p->from.sym != nil && (info->flags & LeftRead)) {
-		info->flags &= ~LeftRead;
-		info->flags |= LeftAddr;
-	}
-
-	if((info->flags & RegRead) && p->reg == 0) {
-		info->flags &= ~RegRead;
-		info->flags |= CanRegRead | RightRead;
-	}
-	
-	if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite))
-		info->flags |= RightRead;
-	
-	switch(p->as) {
-	case ADIV:
-	case ADIVU:
-	case AMOD:
-	case AMODU:
-		info->regset |= RtoB(REG_R12);
-		break;
-	}
-}
diff --git a/src/cmd/new5g/prog.go b/src/cmd/5g/prog.go
similarity index 100%
rename from src/cmd/new5g/prog.go
rename to src/cmd/5g/prog.go
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c
deleted file mode 100644
index 1216e01..0000000
--- a/src/cmd/5g/reg.c
+++ /dev/null
@@ -1,146 +0,0 @@
-// Inferno utils/5c/reg.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/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.
-
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-enum {
-	NREGVAR = 32,
-};
-
-static char* regname[] = {
-	".R0",
-	".R1",
-	".R2",
-	".R3",
-	".R4",
-	".R5",
-	".R6",
-	".R7",
-	".R8",
-	".R9",
-	".R10",
-	".R11",
-	".R12",
-	".R13",
-	".R14",
-	".R15",
-	".F0",
-	".F1",
-	".F2",
-	".F3",
-	".F4",
-	".F5",
-	".F6",
-	".F7",
-	".F8",
-	".F9",
-	".F10",
-	".F11",
-	".F12",
-	".F13",
-	".F14",
-	".F15",
-};
-
-char**
-regnames(int *n)
-{
-	*n = NREGVAR;
-	return regname;
-}
-
-uint64
-excludedregs(void)
-{
-	return RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC);
-}
-
-uint64
-doregbits(int r)
-{
-	USED(r);
-	return 0;
-}
-
-/*
- *	bit	reg
- *	0	R0
- *	1	R1
- *	...	...
- *	10	R10
- *	12  R12
- *
- *	bit	reg
- *	18	F2
- *	19	F3
- *	...	...
- *	31	F15
- */
-uint64
-RtoB(int r)
-{
-	if(REG_R0 <= r && r <= REG_R15) {
-		if(r >= REGTMP-2 && r != REG_R12)	// excluded R9 and R10 for m and g, but not R12
-			return 0;
-		return 1ULL << (r - REG_R0);
-	}
-	
-	if(REG_F0 <= r && r <= REG_F15) {
-		if(r < REG_F2 || r > REG_F0+NFREG-1)
-			return 0;
-		return 1ULL << ((r - REG_F0) + 16);
-	}
-	
-	return 0;
-}
-
-int
-BtoR(uint64 b)
-{
-	// TODO Allow R0 and R1, but be careful with a 0 return
-	// TODO Allow R9. Only R10 is reserved now (just g, not m).
-	b &= 0x11fcL;	// excluded R9 and R10 for m and g, but not R12
-	if(b == 0)
-		return 0;
-	return bitno(b) + REG_R0;
-}
-
-int
-BtoF(uint64 b)
-{
-	b &= 0xfffc0000L;
-	if(b == 0)
-		return 0;
-	return bitno(b) - 16 + REG_F0;
-}
diff --git a/src/cmd/new5g/reg.go b/src/cmd/5g/reg.go
similarity index 100%
rename from src/cmd/new5g/reg.go
rename to src/cmd/5g/reg.go
diff --git a/src/cmd/new5g/util.go b/src/cmd/5g/util.go
similarity index 100%
rename from src/cmd/new5g/util.go
rename to src/cmd/5g/util.go
diff --git a/src/cmd/6a/Makefile b/src/cmd/6a/Makefile
deleted file mode 100644
index 27290dd..0000000
--- a/src/cmd/6a/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
-
-y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/6a/a.h b/src/cmd/6a/a.h
deleted file mode 100644
index 95c4bab..0000000
--- a/src/cmd/6a/a.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// Inferno utils/6a/a.h
-// http://code.google.com/p/inferno-os/source/browse/utils/6a/a.h
-//
-//	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 <bio.h>
-#include <link.h>
-#include "../6l/6.out.h"
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#undef	getc
-#undef	ungetc
-#undef	BUFSIZ
-
-#define	getc	ccgetc
-#define	ungetc	ccungetc
-
-typedef	struct	Sym	Sym;
-typedef	struct	Ref	Ref;
-typedef	struct	Io	Io;
-typedef	struct	Addr2	Addr2;
-
-#define	MAXALIGN	7
-#define	FPCHIP		1
-#define	NSYMB		500
-#define	BUFSIZ		8192
-#define	HISTSZ		20
-#ifndef	EOF
-#define	EOF		(-1)
-#endif
-#define	IGN		(-2)
-#define	GETC()		((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
-#define	NHASH		503
-#define	STRINGSZ	200
-#define	NMACRO		10
-
-struct	Sym
-{
-	Sym*	link;
-	Ref*	ref;
-	char*	macro;
-	vlong	value;
-	ushort	type;
-	char	*name;
-	char*	labelname;
-	char	sym;
-};
-#define	S	((Sym*)0)
-
-struct	Ref
-{
-	int	class;
-};
-
-EXTERN struct
-{
-	char*	p;
-	int	c;
-} fi;
-
-struct	Io
-{
-	Io*	link;
-	char	b[BUFSIZ];
-	char*	p;
-	short	c;
-	short	f;
-};
-#define	I	((Io*)0)
-
-struct	Addr2
-{
-	Addr	from;
-	Addr	to;
-};
-
-enum
-{
-	CLAST,
-	CMACARG,
-	CMACRO,
-	CPREPROC,
-};
-
-EXTERN	int	debug[256];
-EXTERN	Sym*	hash[NHASH];
-EXTERN	char**	Dlist;
-EXTERN	int	nDlist;
-EXTERN	int	newflag;
-EXTERN	char*	hunk;
-EXTERN	char**	include;
-EXTERN	Io*	iofree;
-EXTERN	Io*	ionext;
-EXTERN	Io*	iostack;
-EXTERN	int32	lineno;
-EXTERN	int	nerrors;
-EXTERN	int32	nhunk;
-EXTERN	int	ninclude;
-EXTERN	int32	nsymb;
-EXTERN	Addr	nullgen;
-EXTERN	char*	outfile;
-EXTERN	int	pass;
-EXTERN	int32	pc;
-EXTERN	int	peekc;
-EXTERN	int32	stmtline;
-EXTERN	int	sym;
-EXTERN	char*	symb;
-EXTERN	int	thechar;
-EXTERN	char*	thestring;
-EXTERN	int32	thunk;
-EXTERN	Biobuf	obuf;
-EXTERN	Link*	ctxt;
-EXTERN	Biobuf	bstdout;
-EXTERN	Prog*	lastpc;
-
-void*	alloc(int32);
-void*	allocn(void*, int32, int32);
-void	ensuresymb(int32);
-void	errorexit(void);
-void	pushio(void);
-void	newio(void);
-void	newfile(char*, int);
-Sym*	slookup(char*);
-Sym*	lookup(void);
-Sym*	labellookup(Sym*);
-void	settext(LSym*);
-void	syminit(Sym*);
-int32	yylex(void);
-int	getc(void);
-int	getnsc(void);
-void	unget(int);
-int	escchar(int);
-void	cinit(void);
-void	checkscale(int);
-void	pinit(char*);
-void	cclean(void);
-int	isreg(Addr*);
-void	outcode(int, Addr2*);
-void	outhist(void);
-void	zaddr(Addr*, int);
-void	zname(char*, int, int);
-int	filbuf(void);
-Sym*	getsym(void);
-void	domacro(void);
-void	macund(void);
-void	macdef(void);
-void	macexpand(Sym*, char*);
-void	macinc(void);
-void	macprag(void);
-void	maclin(void);
-void	macif(int);
-void	macend(void);
-void	dodefine(char*);
-void	prfile(int32);
-void	linehist(char*, int);
-void	gethunk(void);
-void	yyerror(char*, ...);
-int	yyparse(void);
-void	setinclude(char*);
-int	assemble(char*);
diff --git a/src/cmd/6a/a.y b/src/cmd/6a/a.y
index df3ca40..bd59a1f 100644
--- a/src/cmd/6a/a.y
+++ b/src/cmd/6a/a.y
@@ -29,20 +29,24 @@
 // THE SOFTWARE.
 
 %{
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
+package main
+
+import (
+	"cmd/internal/asm"
+	"cmd/internal/obj"
+	"cmd/internal/obj/x86"
+)
 %}
-%union	{
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
+
+%union {
+	sym *asm.Sym
+	lval int64
+	dval float64
+	sval string
+	addr obj.Addr
+	addr2 Addr2
 }
+
 %left	'|'
 %left	'^'
 %left	'&'
@@ -58,7 +62,7 @@
 %token	<sval>	LSCONST LSP
 %token	<sym>	LNAME LLAB LVAR
 %type	<lval>	con expr pointer offset
-%type	<addr>	mem imm reg nam rel rem rim rom omem nmem textsize
+%type	<addr>	mem imm textsize reg nam rel rem rim rom omem nmem
 %type	<addr2>	nonnon nonrel nonrem rimnon rimrem remrim
 %type	<addr2>	spec3 spec4 spec5 spec6 spec7 spec8 spec9
 %type	<addr2>	spec10 spec12 spec13
@@ -66,18 +70,19 @@
 prog:
 |	prog 
 	{
-		stmtline = lineno;
+		stmtline = asm.Lineno;
 	}
 	line
 
 line:
 	LNAME ':'
 	{
-		$1 = labellookup($1);
-		if($1->type == LLAB && $1->value != pc)
-			yyerror("redeclaration of %s (%s)", $1->labelname, $1->name);
-		$1->type = LLAB;
-		$1->value = pc;
+		$1 = asm.LabelLookup($1);
+		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
+			yyerror("redeclaration of %s (%s)", $1.Labelname, $1.Name);
+		}
+		$1.Type = LLAB;
+		$1.Value = int64(asm.PC)
 	}
 	line
 |	';'
@@ -87,34 +92,35 @@
 inst:
 	LNAME '=' expr
 	{
-		$1->type = LVAR;
-		$1->value = $3;
+		$1.Type = LVAR;
+		$1.Value = $3;
 	}
 |	LVAR '=' expr
 	{
-		if($1->value != $3)
-			yyerror("redeclaration of %s", $1->name);
-		$1->value = $3;
+		if $1.Value != $3 {
+			yyerror("redeclaration of %s", $1.Name);
+		}
+		$1.Value = $3;
 	}
-|	LTYPE0 nonnon	{ outcode($1, &$2); }
-|	LTYPE1 nonrem	{ outcode($1, &$2); }
-|	LTYPE2 rimnon	{ outcode($1, &$2); }
-|	LTYPE3 rimrem	{ outcode($1, &$2); }
-|	LTYPE4 remrim	{ outcode($1, &$2); }
-|	LTYPER nonrel	{ outcode($1, &$2); }
+|	LTYPE0 nonnon	{ outcode(int($1), &$2); }
+|	LTYPE1 nonrem	{ outcode(int($1), &$2); }
+|	LTYPE2 rimnon	{ outcode(int($1), &$2); }
+|	LTYPE3 rimrem	{ outcode(int($1), &$2); }
+|	LTYPE4 remrim	{ outcode(int($1), &$2); }
+|	LTYPER nonrel	{ outcode(int($1), &$2); }
 |	spec1
 |	spec2
-|	LTYPEC spec3	{ outcode($1, &$2); }
-|	LTYPEN spec4	{ outcode($1, &$2); }
-|	LTYPES spec5	{ outcode($1, &$2); }
-|	LTYPEM spec6	{ outcode($1, &$2); }
-|	LTYPEI spec7	{ outcode($1, &$2); }
-|	LTYPEXC spec8	{ outcode($1, &$2); }
-|	LTYPEX spec9	{ outcode($1, &$2); }
-|	LTYPERT spec10	{ outcode($1, &$2); }
+|	LTYPEC spec3	{ outcode(int($1), &$2); }
+|	LTYPEN spec4	{ outcode(int($1), &$2); }
+|	LTYPES spec5	{ outcode(int($1), &$2); }
+|	LTYPEM spec6	{ outcode(int($1), &$2); }
+|	LTYPEI spec7	{ outcode(int($1), &$2); }
+|	LTYPEXC spec8	{ outcode(int($1), &$2); }
+|	LTYPEX spec9	{ outcode(int($1), &$2); }
+|	LTYPERT spec10	{ outcode(int($1), &$2); }
 |	spec11
-|	LTYPEPC spec12	{ outcode($1, &$2); }
-|	LTYPEF spec13	{ outcode($1, &$2); }
+|	LTYPEPC spec12	{ outcode(int($1), &$2); }
+|	LTYPEF spec13	{ outcode(int($1), &$2); }
 
 nonnon:
 	{
@@ -185,57 +191,45 @@
 spec1:	/* DATA */
 	LTYPED nam '/' con ',' imm
 	{
-		Addr2 a;
-		a.from = $2;
-		a.to = $6;
-		outcode(ADATA, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		var a Addr2
+		a.from = $2
+		a.to = $6
+		outcode(obj.ADATA, &a)
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
 spec2:	/* TEXT */
 	LTYPET mem ',' '$' textsize
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $5;
-		outcode(ATEXT, &a);
+		asm.Settext($2.Sym);
+		outcode(obj.ATEXT, &Addr2{$2, $5})
 	}
 |	LTYPET mem ',' con ',' '$' textsize
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $7;
-		outcode(ATEXT, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym);
+		outcode(obj.ATEXT, &Addr2{$2, $7})
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
 spec11:	/* GLOBL */
 	LTYPEG mem ',' imm
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $4;
-		outcode(AGLOBL, &a);
+		asm.Settext($2.Sym)
+		outcode(obj.AGLOBL, &Addr2{$2, $4})
 	}
 |	LTYPEG mem ',' con ',' imm
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $6;
-		outcode(AGLOBL, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym)
+		outcode(obj.AGLOBL, &Addr2{$2, $6})
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
@@ -265,9 +259,10 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		if($$.from.index != TYPE_NONE)
+		if $$.from.Index != obj.TYPE_NONE {
 			yyerror("dp shift with lhs index");
-		$$.from.index = $5;
+		}
+		$$.from.Index = int16($5);
 	}
 
 spec6:	/* MOVW/MOVL */
@@ -280,9 +275,10 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		if($$.to.index != TYPE_NONE)
+		if $$.to.Index != obj.TYPE_NONE {
 			yyerror("dp move with lhs index");
-		$$.to.index = $5;
+		}
+		$$.to.Index = int16($5);
 	}
 
 spec7:
@@ -307,7 +303,7 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		$$.to.offset = $5;
+		$$.to.Offset = $5;
 	}
 
 spec9:	/* shufl */
@@ -315,9 +311,10 @@
 	{
 		$$.from = $3;
 		$$.to = $5;
-		if($1.type != TYPE_CONST)
+		if $1.Type != obj.TYPE_CONST {
 			yyerror("illegal constant");
-		$$.to.offset = $1.offset;
+		}
+		$$.to.Offset = $1.Offset;
 	}
 
 spec10:	/* RET/RETF */
@@ -331,11 +328,12 @@
 		$$.to = nullgen;
 	}
 
-spec12:	/* PCDATA */
+spec12:	/* asm.PCDATA */
 	rim ',' rim
 	{
-		if($1.type != TYPE_CONST || $3.type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
+		if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
+			yyerror("arguments to asm.PCDATA must be integer constants");
+		}
 		$$.from = $1;
 		$$.to = $3;
 	}
@@ -343,10 +341,12 @@
 spec13:	/* FUNCDATA */
 	rim ',' rim
 	{
-		if($1.type != TYPE_CONST)
+		if $1.Type != obj.TYPE_CONST {
 			yyerror("index for FUNCDATA must be integer constant");
-		if($3.type != TYPE_MEM || ($3.name != NAME_EXTERN && $3.name != NAME_STATIC))
+		}
+		if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
 			yyerror("value for FUNCDATA must be symbol reference");
+		}
 		$$.from = $1;
 		$$.to = $3;
 	}
@@ -377,109 +377,110 @@
 	con '(' LPC ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1 + pc;
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1 + int64(asm.PC);
 	}
 |	LNAME offset
 	{
-		$1 = labellookup($1);
+		$1 = asm.LabelLookup($1);
 		$$ = nullgen;
-		if(pass == 2 && $1->type != LLAB)
-			yyerror("undefined label: %s", $1->labelname);
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1->value + $2;
+		if asm.Pass == 2 && $1.Type != LLAB {
+			yyerror("undefined label: %s", $1.Labelname);
+		}
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1.Value + $2;
 	}
 
 reg:
 	LBREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LFREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LLREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LMREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LSP
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = REG_SP;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = x86.REG_SP;
 	}
 |	LSREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LXREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 
 imm:
 	'$' con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		$$.offset = $2;
+		$$.Type = obj.TYPE_CONST;
+		$$.Offset = $2;
 	}
 |	'$' nam
 	{
 		$$ = $2;
-		$$.type = TYPE_ADDR;
+		$$.Type = obj.TYPE_ADDR;
 		/*
-		if($2.type == D_AUTO || $2.type == D_PARAM)
+		if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
 			yyerror("constant cannot be automatic: %s",
-				$2.sym->name);
+				$2.sym.Name);
 		 */
 	}
 |	'$' LSCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SCONST;
-		memcpy($$.u.sval, $2, sizeof($$.u.sval));
+		$$.Type = obj.TYPE_SCONST;
+		$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
 	}
 |	'$' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $2;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $2;
 	}
 |	'$' '(' LFCONST ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $3;
 	}
 |	'$' '(' '-' LFCONST ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$4;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$4;
 	}
 |	'$' '-' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$3;
 	}
 
 mem:
@@ -490,87 +491,87 @@
 	con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Offset = $1;
 	}
 |	con '(' LLREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
 	}
 |	con '(' LSP ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_SP;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = x86.REG_SP
+		$$.Offset = $1;
 	}
 |	con '(' LSREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
 	}
 |	con '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.offset = $1;
-		$$.index = $3;
-		$$.scale = $5;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Offset = $1;
+		$$.Index = int16($3);
+		$$.Scale = int8($5);
+		checkscale($$.Scale);
 	}
 |	con '(' LLREG ')' '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
-		$$.index = $6;
-		$$.scale = $8;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
+		$$.Index = int16($6);
+		$$.Scale = int8($8);
+		checkscale($$.Scale);
 	}
 |	con '(' LLREG ')' '(' LSREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
-		$$.index = $6;
-		$$.scale = $8;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
+		$$.Index = int16($6);
+		$$.Scale = int8($8);
+		checkscale($$.Scale);
 	}
 |	'(' LLREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($2)
 	}
 |	'(' LSP ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_SP;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = x86.REG_SP
 	}
 |	'(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.index = $2;
-		$$.scale = $4;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Index = int16($2);
+		$$.Scale = int8($4);
+		checkscale($$.Scale);
 	}
 |	'(' LLREG ')' '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
-		$$.index = $5;
-		$$.scale = $7;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($2)
+		$$.Index = int16($5);
+		$$.Scale = int8($7);
+		checkscale($$.Scale);
 	}
 
 nmem:
@@ -581,27 +582,27 @@
 |	nam '(' LLREG '*' con ')'
 	{
 		$$ = $1;
-		$$.index = $3;
-		$$.scale = $5;
-		checkscale($$.scale);
+		$$.Index = int16($3);
+		$$.Scale = int8($5);
+		checkscale($$.Scale);
 	}
 
 nam:
 	LNAME offset '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $4;
-		$$.sym = linklookup(ctxt, $1->name, 0);
-		$$.offset = $2;
+		$$.Type = obj.TYPE_MEM
+		$$.Name = int8($4)
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
+		$$.Offset = $2;
 	}
 |	LNAME '<' '>' offset '(' LSB ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = NAME_STATIC;
-		$$.sym = linklookup(ctxt, $1->name, 1);
-		$$.offset = $4;
+		$$.Type = obj.TYPE_MEM
+		$$.Name = obj.NAME_STATIC
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
+		$$.Offset = $4;
 	}
 
 offset:
@@ -621,7 +622,7 @@
 	LSB
 |	LSP
 	{
-		$$ = NAME_AUTO;
+		$$ = obj.NAME_AUTO;
 	}
 |	LFP
 
@@ -629,7 +630,7 @@
 	LCONST
 |	LVAR
 	{
-		$$ = $1->value;
+		$$ = $1.Value;
 	}
 |	'-' con
 	{
@@ -641,7 +642,7 @@
 	}
 |	'~' con
 	{
-		$$ = ~$2;
+		$$ = ^$2;
 	}
 |	'(' expr ')'
 	{
@@ -652,30 +653,30 @@
 	LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = $1;
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	'-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -$2;
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = $3;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = $1;
+		$$.U.Argsize = int32($3);
 	}
 |	'-' LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = $4;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -$2;
+		$$.U.Argsize = int32($4);
 	}
 
 expr:
@@ -702,11 +703,11 @@
 	}
 |	expr '<' '<' expr
 	{
-		$$ = $1 << $4;
+		$$ = $1 << uint($4);
 	}
 |	expr '>' '>' expr
 	{
-		$$ = $1 >> $4;
+		$$ = $1 >> uint($4);
 	}
 |	expr '&' expr
 	{
diff --git a/src/cmd/6a/doc.go b/src/cmd/6a/doc.go
deleted file mode 100644
index 9f14cc0..0000000
--- a/src/cmd/6a/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
-
-/*
-
-6a is a version of the Plan 9 assembler.  The original is documented at
-
-	http://plan9.bell-labs.com/magic/man2html/1/8a
-
-Go-specific considerations are documented at
-
-	http://golang.org/doc/asm
-
-Its target architecture is the x86-64, referred to by these tools as amd64.
-
-*/
-package main
diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c
deleted file mode 100644
index c600796..0000000
--- a/src/cmd/6a/lex.c
+++ /dev/null
@@ -1,1137 +0,0 @@
-// Inferno utils/6a/lex.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6a/lex.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.
-
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "a.h"
-#include "y.tab.h"
-
-enum
-{
-	Plan9	= 1<<0,
-	Unix	= 1<<1,
-	Windows	= 1<<2,
-};
-
-int
-systemtype(int sys)
-{
-#ifdef _WIN32
-	return sys&Windows;
-#else
-	return sys&Plan9;
-#endif
-}
-
-int
-pathchar(void)
-{
-	return '/';
-}
-
-int
-Lconv(Fmt *fp)
-{
-	return linklinefmt(ctxt, fp);
-}
-
-void
-dodef(char *p)
-{
-	if(nDlist%8 == 0)
-		Dlist = allocn(Dlist, nDlist*sizeof(char *),
-			8*sizeof(char *));
-	Dlist[nDlist++] = p;
-}
-
-LinkArch*       thelinkarch = &linkamd64;
-
-void
-usage(void)
-{
-	print("usage: %ca [options] file.c...\n", thechar);
-	flagprint(1);
-	errorexit();
-}
-
-void
-main(int argc, char *argv[])
-{
-	char *p;
-
-	thechar = '6';
-	thestring = "amd64";
-
-	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
-	// but not other values.	
-	p = getgoarch();
-	if(strncmp(p, thestring, strlen(thestring)) != 0)
-		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
-	if(strcmp(p, "amd64p32") == 0)
-		thelinkarch = &linkamd64p32;
-
-	ctxt = linknew(thelinkarch);
-	ctxt->diag = yyerror;
-	ctxt->bso = &bstdout;
-	ctxt->enforce_data_order = 1;
-	Binit(&bstdout, 1, OWRITE);
-	listinit6();
-	fmtinstall('L', Lconv);
-
-	ensuresymb(NSYMB);
-	memset(debug, 0, sizeof(debug));
-	cinit();
-	outfile = 0;
-	setinclude(".");
-	
-	flagfn1("D", "name[=value]: add #define", dodef);
-	flagfn1("I", "dir: add dir to include path", setinclude);
-	flagcount("S", "print assembly and machine code", &debug['S']);
-	flagcount("m", "debug preprocessor macros", &debug['m']);
-	flagstr("o", "file: set output file", &outfile);
-	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
-
-	flagparse(&argc, &argv, usage);
-	ctxt->debugasm = debug['S'];
-
-	if(argc < 1)
-		usage();
-	if(argc > 1){
-		print("can't assemble multiple files\n");
-		errorexit();
-	}
-
-	if(assemble(argv[0]))
-		errorexit();
-	Bflush(&bstdout);
-	if(nerrors > 0)
-		errorexit();
-	exits(0);
-}
-
-int
-assemble(char *file)
-{
-	char *ofile, *p;
-	int i, of;
-
-	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
-	strcpy(ofile, file);
-	p = utfrrune(ofile, pathchar());
-	if(p) {
-		include[0] = ofile;
-		*p++ = 0;
-	} else
-		p = ofile;
-	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
-			p = utfrrune(outfile, '.');
-			if(p)
-				if(p[1] == 's' && p[2] == 0)
-					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
-		} else
-			outfile = "/dev/null";
-	}
-
-	of = create(outfile, OWRITE, 0664);
-	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
-		errorexit();
-	}
-	Binit(&obuf, of, OWRITE);
-	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
-	Bprint(&obuf, "!\n");
-
-	for(pass = 1; pass <= 2; pass++) {
-		pinit(file);
-		for(i=0; i<nDlist; i++)
-			dodefine(Dlist[i]);
-		yyparse();
-		cclean();
-		if(nerrors)
-			return nerrors;
-	}
-
-	writeobj(ctxt, &obuf);
-	Bflush(&obuf);
-	return 0;
-}
-
-struct
-{
-	char	*name;
-	/*
-	 * type is the lexical type to return.  It dictates what kind of
-	 * operands 6a allows to follow it (in a.y) as the possible operand
-	 * types are handled by a grammar.  How do you know which LTYPE?
-	 * Either read a.y or think of an instruction that has the same
-	 * possible operands and look up what it takes.
-	 */
-	ushort	type;
-	ushort	value;
-} itab[] =
-{
-	"SP",		LSP,	NAME_AUTO,
-	"SB",		LSB,	NAME_EXTERN,
-	"FP",		LFP,	NAME_PARAM,
-
-	"PC",		LPC,	TYPE_BRANCH,
-
-	"AL",		LBREG,	REG_AL,
-	"CL",		LBREG,	REG_CL,
-	"DL",		LBREG,	REG_DL,
-	"BL",		LBREG,	REG_BL,
-/*	"SPB",		LBREG,	REG_SPB,	*/
-	"SIB",		LBREG,	REG_SIB,
-	"DIB",		LBREG,	REG_DIB,
-	"BPB",		LBREG,	REG_BPB,
-	"R8B",		LBREG,	REG_R8B,
-	"R9B",		LBREG,	REG_R9B,
-	"R10B",		LBREG,	REG_R10B,
-	"R11B",		LBREG,	REG_R11B,
-	"R12B",		LBREG,	REG_R12B,
-	"R13B",		LBREG,	REG_R13B,
-	"R14B",		LBREG,	REG_R14B,
-	"R15B",		LBREG,	REG_R15B,
-
-	"AH",		LBREG,	REG_AH,
-	"CH",		LBREG,	REG_CH,
-	"DH",		LBREG,	REG_DH,
-	"BH",		LBREG,	REG_BH,
-
-	"AX",		LLREG,	REG_AX,
-	"CX",		LLREG,	REG_CX,
-	"DX",		LLREG,	REG_DX,
-	"BX",		LLREG,	REG_BX,
-/*	"SP",		LLREG,	REG_SP,	*/
-	"BP",		LLREG,	REG_BP,
-	"SI",		LLREG,	REG_SI,
-	"DI",		LLREG,	REG_DI,
-	"R8",		LLREG,	REG_R8,
-	"R9",		LLREG,	REG_R9,
-	"R10",		LLREG,	REG_R10,
-	"R11",		LLREG,	REG_R11,
-	"R12",		LLREG,	REG_R12,
-	"R13",		LLREG,	REG_R13,
-	"R14",		LLREG,	REG_R14,
-	"R15",		LLREG,	REG_R15,
-
-	"RARG",		LLREG,	REGARG,
-
-	"F0",		LFREG,	REG_F0+0,
-	"F1",		LFREG,	REG_F0+1,
-	"F2",		LFREG,	REG_F0+2,
-	"F3",		LFREG,	REG_F0+3,
-	"F4",		LFREG,	REG_F0+4,
-	"F5",		LFREG,	REG_F0+5,
-	"F6",		LFREG,	REG_F0+6,
-	"F7",		LFREG,	REG_F0+7,
-
-	"M0",		LMREG,	REG_M0+0,
-	"M1",		LMREG,	REG_M0+1,
-	"M2",		LMREG,	REG_M0+2,
-	"M3",		LMREG,	REG_M0+3,
-	"M4",		LMREG,	REG_M0+4,
-	"M5",		LMREG,	REG_M0+5,
-	"M6",		LMREG,	REG_M0+6,
-	"M7",		LMREG,	REG_M0+7,
-
-	"X0",		LXREG,	REG_X0+0,
-	"X1",		LXREG,	REG_X0+1,
-	"X2",		LXREG,	REG_X0+2,
-	"X3",		LXREG,	REG_X0+3,
-	"X4",		LXREG,	REG_X0+4,
-	"X5",		LXREG,	REG_X0+5,
-	"X6",		LXREG,	REG_X0+6,
-	"X7",		LXREG,	REG_X0+7,
-	"X8",		LXREG,	REG_X0+8,
-	"X9",		LXREG,	REG_X0+9,
-	"X10",		LXREG,	REG_X0+10,
-	"X11",		LXREG,	REG_X0+11,
-	"X12",		LXREG,	REG_X0+12,
-	"X13",		LXREG,	REG_X0+13,
-	"X14",		LXREG,	REG_X0+14,
-	"X15",		LXREG,	REG_X0+15,
-
-	"CS",		LSREG,	REG_CS,
-	"SS",		LSREG,	REG_SS,
-	"DS",		LSREG,	REG_DS,
-	"ES",		LSREG,	REG_ES,
-	"FS",		LSREG,	REG_FS,
-	"GS",		LSREG,	REG_GS,
-
-	"GDTR",		LBREG,	REG_GDTR,
-	"IDTR",		LBREG,	REG_IDTR,
-	"LDTR",		LBREG,	REG_LDTR,
-	"MSW",		LBREG,	REG_MSW,
-	"TASK",		LBREG,	REG_TASK,
-
-	"CR0",		LBREG,	REG_CR+0,
-	"CR1",		LBREG,	REG_CR+1,
-	"CR2",		LBREG,	REG_CR+2,
-	"CR3",		LBREG,	REG_CR+3,
-	"CR4",		LBREG,	REG_CR+4,
-	"CR5",		LBREG,	REG_CR+5,
-	"CR6",		LBREG,	REG_CR+6,
-	"CR7",		LBREG,	REG_CR+7,
-	"CR8",		LBREG,	REG_CR+8,
-	"CR9",		LBREG,	REG_CR+9,
-	"CR10",		LBREG,	REG_CR+10,
-	"CR11",		LBREG,	REG_CR+11,
-	"CR12",		LBREG,	REG_CR+12,
-	"CR13",		LBREG,	REG_CR+13,
-	"CR14",		LBREG,	REG_CR+14,
-	"CR15",		LBREG,	REG_CR+15,
-
-	"DR0",		LBREG,	REG_DR+0,
-	"DR1",		LBREG,	REG_DR+1,
-	"DR2",		LBREG,	REG_DR+2,
-	"DR3",		LBREG,	REG_DR+3,
-	"DR4",		LBREG,	REG_DR+4,
-	"DR5",		LBREG,	REG_DR+5,
-	"DR6",		LBREG,	REG_DR+6,
-	"DR7",		LBREG,	REG_DR+7,
-
-	"TR0",		LBREG,	REG_TR+0,
-	"TR1",		LBREG,	REG_TR+1,
-	"TR2",		LBREG,	REG_TR+2,
-	"TR3",		LBREG,	REG_TR+3,
-	"TR4",		LBREG,	REG_TR+4,
-	"TR5",		LBREG,	REG_TR+5,
-	"TR6",		LBREG,	REG_TR+6,
-	"TR7",		LBREG,	REG_TR+7,
-	"TLS",		LSREG,	REG_TLS,
-
-	"AAA",		LTYPE0,	AAAA,
-	"AAD",		LTYPE0,	AAAD,
-	"AAM",		LTYPE0,	AAAM,
-	"AAS",		LTYPE0,	AAAS,
-	"ADCB",		LTYPE3,	AADCB,
-	"ADCL",		LTYPE3,	AADCL,
-	"ADCQ",		LTYPE3,	AADCQ,
-	"ADCW",		LTYPE3,	AADCW,
-	"ADDB",		LTYPE3,	AADDB,
-	"ADDL",		LTYPE3,	AADDL,
-	"ADDQ",		LTYPE3,	AADDQ,
-	"ADDW",		LTYPE3,	AADDW,
-	"ADJSP",	LTYPE2,	AADJSP,
-	"ANDB",		LTYPE3,	AANDB,
-	"ANDL",		LTYPE3,	AANDL,
-	"ANDQ",		LTYPE3,	AANDQ,
-	"ANDW",		LTYPE3,	AANDW,
-	"ARPL",		LTYPE3,	AARPL,
-	"BOUNDL",	LTYPE3,	ABOUNDL,
-	"BOUNDW",	LTYPE3,	ABOUNDW,
-	"BSFL",		LTYPE3,	ABSFL,
-	"BSFQ",		LTYPE3,	ABSFQ,
-	"BSFW",		LTYPE3,	ABSFW,
-	"BSRL",		LTYPE3,	ABSRL,
-	"BSRQ",		LTYPE3,	ABSRQ,
-	"BSRW",		LTYPE3,	ABSRW,
-	"BSWAPL",	LTYPE1,	ABSWAPL,
-	"BSWAPQ",	LTYPE1,	ABSWAPQ,
-	"BTCL",		LTYPE3,	ABTCL,
-	"BTCQ",		LTYPE3,	ABTCQ,
-	"BTCW",		LTYPE3,	ABTCW,
-	"BTL",		LTYPE3,	ABTL,
-	"BTQ",		LTYPE3,	ABTQ,
-	"BTRL",		LTYPE3,	ABTRL,
-	"BTRQ",		LTYPE3,	ABTRQ,
-	"BTRW",		LTYPE3,	ABTRW,
-	"BTSL",		LTYPE3,	ABTSL,
-	"BTSQ",		LTYPE3,	ABTSQ,
-	"BTSW",		LTYPE3,	ABTSW,
-	"BTW",		LTYPE3,	ABTW,
-	"BYTE",		LTYPE2,	ABYTE,
-	"CALL",		LTYPEC,	ACALL,
-	"CLC",		LTYPE0,	ACLC,
-	"CLD",		LTYPE0,	ACLD,
-	"CLI",		LTYPE0,	ACLI,
-	"CLTS",		LTYPE0,	ACLTS,
-	"CMC",		LTYPE0,	ACMC,
-	"CMPB",		LTYPE4,	ACMPB,
-	"CMPL",		LTYPE4,	ACMPL,
-	"CMPQ",		LTYPE4,	ACMPQ,
-	"CMPW",		LTYPE4,	ACMPW,
-	"CMPSB",	LTYPE0,	ACMPSB,
-	"CMPSL",	LTYPE0,	ACMPSL,
-	"CMPSQ",	LTYPE0,	ACMPSQ,
-	"CMPSW",	LTYPE0,	ACMPSW,
-	"CMPXCHG8B",	LTYPE1,	ACMPXCHG8B,
-	"CMPXCHGB",	LTYPE3,	ACMPXCHGB,	/* LTYPE3? */
-	"CMPXCHGL",	LTYPE3,	ACMPXCHGL,
-	"CMPXCHGQ",	LTYPE3,	ACMPXCHGQ,
-	"CMPXCHGW",	LTYPE3,	ACMPXCHGW,
-	"CPUID",	LTYPE0,	ACPUID,
-	"DAA",		LTYPE0,	ADAA,
-	"DAS",		LTYPE0,	ADAS,
-	"DATA",		LTYPED,	ADATA,
-	"DECB",		LTYPE1,	ADECB,
-	"DECL",		LTYPE1,	ADECL,
-	"DECQ",		LTYPE1,	ADECQ,
-	"DECW",		LTYPE1,	ADECW,
-	"DIVB",		LTYPE2,	ADIVB,
-	"DIVL",		LTYPE2,	ADIVL,
-	"DIVQ",		LTYPE2,	ADIVQ,
-	"DIVW",		LTYPE2,	ADIVW,
-	"EMMS",		LTYPE0,	AEMMS,
-	"END",		LTYPE0,	AEND,
-	"ENTER",	LTYPE2,	AENTER,
-	"GLOBL",	LTYPEG,	AGLOBL,
-	"HLT",		LTYPE0,	AHLT,
-	"IDIVB",	LTYPE2,	AIDIVB,
-	"IDIVL",	LTYPE2,	AIDIVL,
-	"IDIVQ",	LTYPE2,	AIDIVQ,
-	"IDIVW",	LTYPE2,	AIDIVW,
-	"IMULB",	LTYPEI,	AIMULB,
-	"IMULL",	LTYPEI,	AIMULL,
-	"IMULQ",	LTYPEI,	AIMULQ,
-	"IMUL3Q",	LTYPEX,	AIMUL3Q,
-	"IMULW",	LTYPEI,	AIMULW,
-	"INB",		LTYPE0,	AINB,
-	"INL",		LTYPE0,	AINL,
-	"INW",		LTYPE0,	AINW,
-	"INCB",		LTYPE1,	AINCB,
-	"INCL",		LTYPE1,	AINCL,
-	"INCQ",		LTYPE1,	AINCQ,
-	"INCW",		LTYPE1,	AINCW,
-	"INSB",		LTYPE0,	AINSB,
-	"INSL",		LTYPE0,	AINSL,
-	"INSW",		LTYPE0,	AINSW,
-	"INT",		LTYPE2,	AINT,
-	"INTO",		LTYPE0,	AINTO,
-	"INVD",		LTYPE0,	AINVD,
-	"INVLPG",	LTYPE2,	AINVLPG,
-	"IRETL",	LTYPE0,	AIRETL,
-	"IRETQ",	LTYPE0,	AIRETQ,
-	"IRETW",	LTYPE0,	AIRETW,
-
-	"JOS",		LTYPER,	AJOS,	/* overflow set (OF = 1) */
-	"JO",		LTYPER,	AJOS,	/* alternate */
-	"JOC",		LTYPER,	AJOC,	/* overflow clear (OF = 0) */
-	"JNO",		LTYPER,	AJOC,	/* alternate */
-	"JCS",		LTYPER,	AJCS,	/* carry set (CF = 1) */
-	"JB",		LTYPER,	AJCS,	/* alternate */
-	"JC",		LTYPER,	AJCS,	/* alternate */
-	"JNAE",		LTYPER,	AJCS,	/* alternate */
-	"JLO",		LTYPER,	AJCS,	/* alternate */
-	"JCC",		LTYPER,	AJCC,	/* carry clear (CF = 0) */
-	"JAE",		LTYPER,	AJCC,	/* alternate */
-	"JNB",		LTYPER,	AJCC,	/* alternate */
-	"JNC",		LTYPER,	AJCC,	/* alternate */
-	"JHS",		LTYPER,	AJCC,	/* alternate */
-	"JEQ",		LTYPER,	AJEQ,	/* equal (ZF = 1) */
-	"JE",		LTYPER,	AJEQ,	/* alternate */
-	"JZ",		LTYPER,	AJEQ,	/* alternate */
-	"JNE",		LTYPER,	AJNE,	/* not equal (ZF = 0) */
-	"JNZ",		LTYPER,	AJNE,	/* alternate */
-	"JLS",		LTYPER,	AJLS,	/* lower or same (unsigned) (CF = 1 || ZF = 1) */
-	"JBE",		LTYPER,	AJLS,	/* alternate */
-	"JNA",		LTYPER,	AJLS,	/* alternate */
-	"JHI",		LTYPER,	AJHI,	/* higher (unsigned) (CF = 0 && ZF = 0) */
-	"JA",		LTYPER,	AJHI,	/* alternate */
-	"JNBE",		LTYPER,	AJHI,	/* alternate */
-	"JMI",		LTYPER,	AJMI,	/* negative (minus) (SF = 1) */
-	"JS",		LTYPER,	AJMI,	/* alternate */
-	"JPL",		LTYPER,	AJPL,	/* non-negative (plus) (SF = 0) */
-	"JNS",		LTYPER,	AJPL,	/* alternate */
-	"JPS",		LTYPER,	AJPS,	/* parity set (PF = 1) */
-	"JP",		LTYPER,	AJPS,	/* alternate */
-	"JPE",		LTYPER,	AJPS,	/* alternate */
-	"JPC",		LTYPER,	AJPC,	/* parity clear (PF = 0) */
-	"JNP",		LTYPER,	AJPC,	/* alternate */
-	"JPO",		LTYPER,	AJPC,	/* alternate */
-	"JLT",		LTYPER,	AJLT,	/* less than (signed) (SF != OF) */
-	"JL",		LTYPER,	AJLT,	/* alternate */
-	"JNGE",		LTYPER,	AJLT,	/* alternate */
-	"JGE",		LTYPER,	AJGE,	/* greater than or equal (signed) (SF = OF) */
-	"JNL",		LTYPER,	AJGE,	/* alternate */
-	"JLE",		LTYPER,	AJLE,	/* less than or equal (signed) (ZF = 1 || SF != OF) */
-	"JNG",		LTYPER,	AJLE,	/* alternate */
-	"JGT",		LTYPER,	AJGT,	/* greater than (signed) (ZF = 0 && SF = OF) */
-	"JG",		LTYPER,	AJGT,	/* alternate */
-	"JNLE",		LTYPER,	AJGT,	/* alternate */
-	"JCXZL",	LTYPER,	AJCXZL,
-	"JCXZQ",	LTYPER,	AJCXZQ,
-	"JMP",		LTYPEC,	AJMP,
-	"LAHF",		LTYPE0,	ALAHF,
-	"LARL",		LTYPE3,	ALARL,
-	"LARW",		LTYPE3,	ALARW,
-	"LEAL",		LTYPE3,	ALEAL,
-	"LEAQ",		LTYPE3,	ALEAQ,
-	"LEAW",		LTYPE3,	ALEAW,
-	"LEAVEL",	LTYPE0,	ALEAVEL,
-	"LEAVEQ",	LTYPE0,	ALEAVEQ,
-	"LEAVEW",	LTYPE0,	ALEAVEW,
-	"LFENCE",	LTYPE0,	ALFENCE,
-	"LOCK",		LTYPE0,	ALOCK,
-	"LODSB",	LTYPE0,	ALODSB,
-	"LODSL",	LTYPE0,	ALODSL,
-	"LODSQ",	LTYPE0,	ALODSQ,
-	"LODSW",	LTYPE0,	ALODSW,
-	"LONG",		LTYPE2,	ALONG,
-	"LOOP",		LTYPER,	ALOOP,
-	"LOOPEQ",	LTYPER,	ALOOPEQ,
-	"LOOPNE",	LTYPER,	ALOOPNE,
-	"LSLL",		LTYPE3,	ALSLL,
-	"LSLW",		LTYPE3,	ALSLW,
-	"MFENCE",	LTYPE0,	AMFENCE,
-	"MODE",		LTYPE2,	AMODE,
-	"MOVB",		LTYPE3,	AMOVB,
-	"MOVL",		LTYPEM,	AMOVL,
-	"MOVQ",		LTYPEM,	AMOVQ,
-	"MOVW",		LTYPEM,	AMOVW,
-	"MOVBLSX",	LTYPE3, AMOVBLSX,
-	"MOVBLZX",	LTYPE3, AMOVBLZX,
-	"MOVBQSX",	LTYPE3,	AMOVBQSX,
-	"MOVBQZX",	LTYPE3,	AMOVBQZX,
-	"MOVBWSX",	LTYPE3, AMOVBWSX,
-	"MOVBWZX",	LTYPE3, AMOVBWZX,
-	"MOVLQSX",	LTYPE3, AMOVLQSX,
-	"MOVLQZX",	LTYPE3, AMOVLQZX,
-	"MOVNTIL",	LTYPE3,	AMOVNTIL,
-	"MOVNTIQ",	LTYPE3,	AMOVNTIQ,
-	"MOVQL",	LTYPE3, AMOVQL,
-	"MOVWLSX",	LTYPE3, AMOVWLSX,
-	"MOVWLZX",	LTYPE3, AMOVWLZX,
-	"MOVWQSX",	LTYPE3,	AMOVWQSX,
-	"MOVWQZX",	LTYPE3,	AMOVWQZX,
-	"MOVSB",	LTYPE0,	AMOVSB,
-	"MOVSL",	LTYPE0,	AMOVSL,
-	"MOVSQ",	LTYPE0,	AMOVSQ,
-	"MOVSW",	LTYPE0,	AMOVSW,
-	"MULB",		LTYPE2,	AMULB,
-	"MULL",		LTYPE2,	AMULL,
-	"MULQ",		LTYPE2,	AMULQ,
-	"MULW",		LTYPE2,	AMULW,
-	"NEGB",		LTYPE1,	ANEGB,
-	"NEGL",		LTYPE1,	ANEGL,
-	"NEGQ",		LTYPE1,	ANEGQ,
-	"NEGW",		LTYPE1,	ANEGW,
-	"NOP",		LTYPEN,	ANOP,
-	"NOTB",		LTYPE1,	ANOTB,
-	"NOTL",		LTYPE1,	ANOTL,
-	"NOTQ",		LTYPE1,	ANOTQ,
-	"NOTW",		LTYPE1,	ANOTW,
-	"ORB",		LTYPE3,	AORB,
-	"ORL",		LTYPE3,	AORL,
-	"ORQ",		LTYPE3,	AORQ,
-	"ORW",		LTYPE3,	AORW,
-	"OUTB",		LTYPE0,	AOUTB,
-	"OUTL",		LTYPE0,	AOUTL,
-	"OUTW",		LTYPE0,	AOUTW,
-	"OUTSB",	LTYPE0,	AOUTSB,
-	"OUTSL",	LTYPE0,	AOUTSL,
-	"OUTSW",	LTYPE0,	AOUTSW,
-	"PAUSE",	LTYPEN,	APAUSE,
-	"POPAL",	LTYPE0,	APOPAL,
-	"POPAW",	LTYPE0,	APOPAW,
-	"POPFL",	LTYPE0,	APOPFL,
-	"POPFQ",	LTYPE0,	APOPFQ,
-	"POPFW",	LTYPE0,	APOPFW,
-	"POPL",		LTYPE1,	APOPL,
-	"POPQ",		LTYPE1,	APOPQ,
-	"POPW",		LTYPE1,	APOPW,
-	"PUSHAL",	LTYPE0,	APUSHAL,
-	"PUSHAW",	LTYPE0,	APUSHAW,
-	"PUSHFL",	LTYPE0,	APUSHFL,
-	"PUSHFQ",	LTYPE0,	APUSHFQ,
-	"PUSHFW",	LTYPE0,	APUSHFW,
-	"PUSHL",	LTYPE2,	APUSHL,
-	"PUSHQ",	LTYPE2,	APUSHQ,
-	"PUSHW",	LTYPE2,	APUSHW,
-	"RCLB",		LTYPE3,	ARCLB,
-	"RCLL",		LTYPE3,	ARCLL,
-	"RCLQ",		LTYPE3,	ARCLQ,
-	"RCLW",		LTYPE3,	ARCLW,
-	"RCRB",		LTYPE3,	ARCRB,
-	"RCRL",		LTYPE3,	ARCRL,
-	"RCRQ",		LTYPE3,	ARCRQ,
-	"RCRW",		LTYPE3,	ARCRW,
-	"RDMSR",	LTYPE0,	ARDMSR,
-	"RDPMC",	LTYPE0,	ARDPMC,
-	"RDTSC",	LTYPE0,	ARDTSC,
-	"REP",		LTYPE0,	AREP,
-	"REPN",		LTYPE0,	AREPN,
-	"RET",		LTYPE0,	ARET,
-	"RETFL",	LTYPERT,ARETFL,
-	"RETFW",	LTYPERT,ARETFW,
-	"RETFQ",	LTYPERT,ARETFQ,
-	"ROLB",		LTYPE3,	AROLB,
-	"ROLL",		LTYPE3,	AROLL,
-	"ROLQ",		LTYPE3,	AROLQ,
-	"ROLW",		LTYPE3,	AROLW,
-	"RORB",		LTYPE3,	ARORB,
-	"RORL",		LTYPE3,	ARORL,
-	"RORQ",		LTYPE3,	ARORQ,
-	"RORW",		LTYPE3,	ARORW,
-	"RSM",		LTYPE0,	ARSM,
-	"SAHF",		LTYPE0,	ASAHF,
-	"SALB",		LTYPE3,	ASALB,
-	"SALL",		LTYPE3,	ASALL,
-	"SALQ",		LTYPE3,	ASALQ,
-	"SALW",		LTYPE3,	ASALW,
-	"SARB",		LTYPE3,	ASARB,
-	"SARL",		LTYPE3,	ASARL,
-	"SARQ",		LTYPE3,	ASARQ,
-	"SARW",		LTYPE3,	ASARW,
-	"SBBB",		LTYPE3,	ASBBB,
-	"SBBL",		LTYPE3,	ASBBL,
-	"SBBQ",		LTYPE3,	ASBBQ,
-	"SBBW",		LTYPE3,	ASBBW,
-	"SCASB",	LTYPE0,	ASCASB,
-	"SCASL",	LTYPE0,	ASCASL,
-	"SCASQ",	LTYPE0,	ASCASQ,
-	"SCASW",	LTYPE0,	ASCASW,
-	"SETCC",	LTYPE1,	ASETCC,	/* see JCC etc above for condition codes */
-	"SETCS",	LTYPE1,	ASETCS,
-	"SETEQ",	LTYPE1,	ASETEQ,
-	"SETGE",	LTYPE1,	ASETGE,
-	"SETGT",	LTYPE1,	ASETGT,
-	"SETHI",	LTYPE1,	ASETHI,
-	"SETLE",	LTYPE1,	ASETLE,
-	"SETLS",	LTYPE1,	ASETLS,
-	"SETLT",	LTYPE1,	ASETLT,
-	"SETMI",	LTYPE1,	ASETMI,
-	"SETNE",	LTYPE1,	ASETNE,
-	"SETOC",	LTYPE1,	ASETOC,
-	"SETOS",	LTYPE1,	ASETOS,
-	"SETPC",	LTYPE1,	ASETPC,
-	"SETPL",	LTYPE1,	ASETPL,
-	"SETPS",	LTYPE1,	ASETPS,
-	"SFENCE",	LTYPE0,	ASFENCE,
-	"CDQ",		LTYPE0,	ACDQ,
-	"CWD",		LTYPE0,	ACWD,
-	"CQO",		LTYPE0,	ACQO,
-	"SHLB",		LTYPE3,	ASHLB,
-	"SHLL",		LTYPES,	ASHLL,
-	"SHLQ",		LTYPES,	ASHLQ,
-	"SHLW",		LTYPES,	ASHLW,
-	"SHRB",		LTYPE3,	ASHRB,
-	"SHRL",		LTYPES,	ASHRL,
-	"SHRQ",		LTYPES,	ASHRQ,
-	"SHRW",		LTYPES,	ASHRW,
-	"STC",		LTYPE0,	ASTC,
-	"STD",		LTYPE0,	ASTD,
-	"STI",		LTYPE0,	ASTI,
-	"STOSB",	LTYPE0,	ASTOSB,
-	"STOSL",	LTYPE0,	ASTOSL,
-	"STOSQ",	LTYPE0,	ASTOSQ,
-	"STOSW",	LTYPE0,	ASTOSW,
-	"SUBB",		LTYPE3,	ASUBB,
-	"SUBL",		LTYPE3,	ASUBL,
-	"SUBQ",		LTYPE3,	ASUBQ,
-	"SUBW",		LTYPE3,	ASUBW,
-	"SYSCALL",	LTYPE0,	ASYSCALL,
-	"SYSRET",	LTYPE0,	ASYSRET,
-	"SWAPGS",	LTYPE0,	ASWAPGS,
-	"TESTB",	LTYPE3,	ATESTB,
-	"TESTL",	LTYPE3,	ATESTL,
-	"TESTQ",	LTYPE3,	ATESTQ,
-	"TESTW",	LTYPE3,	ATESTW,
-	"TEXT",		LTYPET,	ATEXT,
-	"VERR",		LTYPE2,	AVERR,
-	"VERW",		LTYPE2,	AVERW,
-	"QUAD",		LTYPE2,	AQUAD,
-	"WAIT",		LTYPE0,	AWAIT,
-	"WBINVD",	LTYPE0,	AWBINVD,
-	"WRMSR",	LTYPE0,	AWRMSR,
-	"WORD",		LTYPE2,	AWORD,
-	"XADDB",	LTYPE3,	AXADDB,
-	"XADDL",	LTYPE3,	AXADDL,
-	"XADDQ",	LTYPE3,	AXADDQ,
-	"XADDW",	LTYPE3,	AXADDW,
-	"XCHGB",	LTYPE3,	AXCHGB,
-	"XCHGL",	LTYPE3,	AXCHGL,
-	"XCHGQ",	LTYPE3,	AXCHGQ,
-	"XCHGW",	LTYPE3,	AXCHGW,
-	"XLAT",		LTYPE2,	AXLAT,
-	"XORB",		LTYPE3,	AXORB,
-	"XORL",		LTYPE3,	AXORL,
-	"XORQ",		LTYPE3,	AXORQ,
-	"XORW",		LTYPE3,	AXORW,
-
-	"CMOVLCC",	LTYPE3,	ACMOVLCC,
-	"CMOVLCS",	LTYPE3,	ACMOVLCS,
-	"CMOVLEQ",	LTYPE3,	ACMOVLEQ,
-	"CMOVLGE",	LTYPE3,	ACMOVLGE,
-	"CMOVLGT",	LTYPE3,	ACMOVLGT,
-	"CMOVLHI",	LTYPE3,	ACMOVLHI,
-	"CMOVLLE",	LTYPE3,	ACMOVLLE,
-	"CMOVLLS",	LTYPE3,	ACMOVLLS,
-	"CMOVLLT",	LTYPE3,	ACMOVLLT,
-	"CMOVLMI",	LTYPE3,	ACMOVLMI,
-	"CMOVLNE",	LTYPE3,	ACMOVLNE,
-	"CMOVLOC",	LTYPE3,	ACMOVLOC,
-	"CMOVLOS",	LTYPE3,	ACMOVLOS,
-	"CMOVLPC",	LTYPE3,	ACMOVLPC,
-	"CMOVLPL",	LTYPE3,	ACMOVLPL,
-	"CMOVLPS",	LTYPE3,	ACMOVLPS,
-	"CMOVQCC",	LTYPE3,	ACMOVQCC,
-	"CMOVQCS",	LTYPE3,	ACMOVQCS,
-	"CMOVQEQ",	LTYPE3,	ACMOVQEQ,
-	"CMOVQGE",	LTYPE3,	ACMOVQGE,
-	"CMOVQGT",	LTYPE3,	ACMOVQGT,
-	"CMOVQHI",	LTYPE3,	ACMOVQHI,
-	"CMOVQLE",	LTYPE3,	ACMOVQLE,
-	"CMOVQLS",	LTYPE3,	ACMOVQLS,
-	"CMOVQLT",	LTYPE3,	ACMOVQLT,
-	"CMOVQMI",	LTYPE3,	ACMOVQMI,
-	"CMOVQNE",	LTYPE3,	ACMOVQNE,
-	"CMOVQOC",	LTYPE3,	ACMOVQOC,
-	"CMOVQOS",	LTYPE3,	ACMOVQOS,
-	"CMOVQPC",	LTYPE3,	ACMOVQPC,
-	"CMOVQPL",	LTYPE3,	ACMOVQPL,
-	"CMOVQPS",	LTYPE3,	ACMOVQPS,
-	"CMOVWCC",	LTYPE3,	ACMOVWCC,
-	"CMOVWCS",	LTYPE3,	ACMOVWCS,
-	"CMOVWEQ",	LTYPE3,	ACMOVWEQ,
-	"CMOVWGE",	LTYPE3,	ACMOVWGE,
-	"CMOVWGT",	LTYPE3,	ACMOVWGT,
-	"CMOVWHI",	LTYPE3,	ACMOVWHI,
-	"CMOVWLE",	LTYPE3,	ACMOVWLE,
-	"CMOVWLS",	LTYPE3,	ACMOVWLS,
-	"CMOVWLT",	LTYPE3,	ACMOVWLT,
-	"CMOVWMI",	LTYPE3,	ACMOVWMI,
-	"CMOVWNE",	LTYPE3,	ACMOVWNE,
-	"CMOVWOC",	LTYPE3,	ACMOVWOC,
-	"CMOVWOS",	LTYPE3,	ACMOVWOS,
-	"CMOVWPC",	LTYPE3,	ACMOVWPC,
-	"CMOVWPL",	LTYPE3,	ACMOVWPL,
-	"CMOVWPS",	LTYPE3,	ACMOVWPS,
-
-	"FMOVB",	LTYPE3, AFMOVB,
-	"FMOVBP",	LTYPE3, AFMOVBP,
-	"FMOVD",	LTYPE3, AFMOVD,
-	"FMOVDP",	LTYPE3, AFMOVDP,
-	"FMOVF",	LTYPE3, AFMOVF,
-	"FMOVFP",	LTYPE3, AFMOVFP,
-	"FMOVL",	LTYPE3, AFMOVL,
-	"FMOVLP",	LTYPE3, AFMOVLP,
-	"FMOVV",	LTYPE3, AFMOVV,
-	"FMOVVP",	LTYPE3, AFMOVVP,
-	"FMOVW",	LTYPE3, AFMOVW,
-	"FMOVWP",	LTYPE3, AFMOVWP,
-	"FMOVX",	LTYPE3, AFMOVX,
-	"FMOVXP",	LTYPE3, AFMOVXP,
-	"FCOMB",	LTYPE3, AFCOMB,
-	"FCOMBP",	LTYPE3, AFCOMBP,
-	"FCOMD",	LTYPE3, AFCOMD,
-	"FCOMDP",	LTYPE3, AFCOMDP,
-	"FCOMDPP",	LTYPE3, AFCOMDPP,
-	"FCOMF",	LTYPE3, AFCOMF,
-	"FCOMFP",	LTYPE3, AFCOMFP,
-	"FCOML",	LTYPE3, AFCOML,
-	"FCOMLP",	LTYPE3, AFCOMLP,
-	"FCOMW",	LTYPE3, AFCOMW,
-	"FCOMWP",	LTYPE3, AFCOMWP,
-	"FUCOM",	LTYPE3, AFUCOM,
-	"FUCOMP",	LTYPE3, AFUCOMP,
-	"FUCOMPP",	LTYPE3, AFUCOMPP,
-	"FADDW",	LTYPE3, AFADDW,
-	"FADDL",	LTYPE3, AFADDL,
-	"FADDF",	LTYPE3, AFADDF,
-	"FADDD",	LTYPE3, AFADDD,
-	"FADDDP",	LTYPE3, AFADDDP,
-	"FSUBDP",	LTYPE3, AFSUBDP,
-	"FSUBW",	LTYPE3, AFSUBW,
-	"FSUBL",	LTYPE3, AFSUBL,
-	"FSUBF",	LTYPE3, AFSUBF,
-	"FSUBD",	LTYPE3, AFSUBD,
-	"FSUBRDP",	LTYPE3, AFSUBRDP,
-	"FSUBRW",	LTYPE3, AFSUBRW,
-	"FSUBRL",	LTYPE3, AFSUBRL,
-	"FSUBRF",	LTYPE3, AFSUBRF,
-	"FSUBRD",	LTYPE3, AFSUBRD,
-	"FMULDP",	LTYPE3, AFMULDP,
-	"FMULW",	LTYPE3, AFMULW,
-	"FMULL",	LTYPE3, AFMULL,
-	"FMULF",	LTYPE3, AFMULF,
-	"FMULD",	LTYPE3, AFMULD,
-	"FDIVDP",	LTYPE3, AFDIVDP,
-	"FDIVW",	LTYPE3, AFDIVW,
-	"FDIVL",	LTYPE3, AFDIVL,
-	"FDIVF",	LTYPE3, AFDIVF,
-	"FDIVD",	LTYPE3, AFDIVD,
-	"FDIVRDP",	LTYPE3, AFDIVRDP,
-	"FDIVRW",	LTYPE3, AFDIVRW,
-	"FDIVRL",	LTYPE3, AFDIVRL,
-	"FDIVRF",	LTYPE3, AFDIVRF,
-	"FDIVRD",	LTYPE3, AFDIVRD,
-	"FXCHD",	LTYPE3, AFXCHD,
-	"FFREE",	LTYPE1, AFFREE,
-	"FLDCW",	LTYPE2, AFLDCW,
-	"FLDENV",	LTYPE1, AFLDENV,
-	"FRSTOR",	LTYPE2, AFRSTOR,
-	"FSAVE",	LTYPE1, AFSAVE,
-	"FSTCW",	LTYPE1, AFSTCW,
-	"FSTENV",	LTYPE1, AFSTENV,
-	"FSTSW",	LTYPE1, AFSTSW,
-	"F2XM1",	LTYPE0, AF2XM1,
-	"FABS",		LTYPE0, AFABS,
-	"FCHS",		LTYPE0, AFCHS,
-	"FCLEX",	LTYPE0, AFCLEX,
-	"FCOS",		LTYPE0, AFCOS,
-	"FDECSTP",	LTYPE0, AFDECSTP,
-	"FINCSTP",	LTYPE0, AFINCSTP,
-	"FINIT",	LTYPE0, AFINIT,
-	"FLD1",		LTYPE0, AFLD1,
-	"FLDL2E",	LTYPE0, AFLDL2E,
-	"FLDL2T",	LTYPE0, AFLDL2T,
-	"FLDLG2",	LTYPE0, AFLDLG2,
-	"FLDLN2",	LTYPE0, AFLDLN2,
-	"FLDPI",	LTYPE0, AFLDPI,
-	"FLDZ",		LTYPE0, AFLDZ,
-	"FNOP",		LTYPE0, AFNOP,
-	"FPATAN",	LTYPE0, AFPATAN,
-	"FPREM",	LTYPE0, AFPREM,
-	"FPREM1",	LTYPE0, AFPREM1,
-	"FPTAN",	LTYPE0, AFPTAN,
-	"FRNDINT",	LTYPE0, AFRNDINT,
-	"FSCALE",	LTYPE0, AFSCALE,
-	"FSIN",		LTYPE0, AFSIN,
-	"FSINCOS",	LTYPE0, AFSINCOS,
-	"FSQRT",	LTYPE0, AFSQRT,
-	"FTST",		LTYPE0, AFTST,
-	"FXAM",		LTYPE0, AFXAM,
-	"FXTRACT",	LTYPE0, AFXTRACT,
-	"FYL2X",	LTYPE0, AFYL2X,
-	"FYL2XP1",	LTYPE0, AFYL2XP1,
-
-	"ADDPD",	LTYPE3,	AADDPD,
-	"ADDPS",	LTYPE3,	AADDPS,
-	"ADDSD",	LTYPE3,	AADDSD,
-	"ADDSS",	LTYPE3,	AADDSS,
-	"ANDNPD",	LTYPE3,	AANDNPD,
-	"ANDNPS",	LTYPE3,	AANDNPS,
-	"ANDPD",	LTYPE3,	AANDPD,
-	"ANDPS",	LTYPE3,	AANDPS,
-	"CMPPD",	LTYPEXC,ACMPPD,
-	"CMPPS",	LTYPEXC,ACMPPS,
-	"CMPSD",	LTYPEXC,ACMPSD,
-	"CMPSS",	LTYPEXC,ACMPSS,
-	"COMISD",	LTYPE3,	ACOMISD,
-	"COMISS",	LTYPE3,	ACOMISS,
-	"CVTPL2PD",	LTYPE3,	ACVTPL2PD,
-	"CVTPL2PS",	LTYPE3,	ACVTPL2PS,
-	"CVTPD2PL",	LTYPE3,	ACVTPD2PL,
-	"CVTPD2PS",	LTYPE3,	ACVTPD2PS,
-	"CVTPS2PL",	LTYPE3,	ACVTPS2PL,
-	"PF2IW",	LTYPE3,	APF2IW,
-	"PF2IL",	LTYPE3,	APF2IL,
-	"PF2ID",	LTYPE3,	APF2IL,	/* syn */
-	"PI2FL",	LTYPE3,	API2FL,
-	"PI2FD",	LTYPE3,	API2FL,	/* syn */
-	"PI2FW",	LTYPE3,	API2FW,
-	"CVTPS2PD",	LTYPE3,	ACVTPS2PD,
-	"CVTSD2SL",	LTYPE3,	ACVTSD2SL,
-	"CVTSD2SQ",	LTYPE3,	ACVTSD2SQ,
-	"CVTSD2SS",	LTYPE3,	ACVTSD2SS,
-	"CVTSL2SD",	LTYPE3,	ACVTSL2SD,
-	"CVTSQ2SD",	LTYPE3,	ACVTSQ2SD,
-	"CVTSL2SS",	LTYPE3,	ACVTSL2SS,
-	"CVTSQ2SS",	LTYPE3,	ACVTSQ2SS,
-	"CVTSS2SD",	LTYPE3,	ACVTSS2SD,
-	"CVTSS2SL",	LTYPE3,	ACVTSS2SL,
-	"CVTSS2SQ",	LTYPE3,	ACVTSS2SQ,
-	"CVTTPD2PL",	LTYPE3,	ACVTTPD2PL,
-	"CVTTPS2PL",	LTYPE3,	ACVTTPS2PL,
-	"CVTTSD2SL",	LTYPE3,	ACVTTSD2SL,
-	"CVTTSD2SQ",	LTYPE3,	ACVTTSD2SQ,
-	"CVTTSS2SL",	LTYPE3,	ACVTTSS2SL,
-	"CVTTSS2SQ",	LTYPE3,	ACVTTSS2SQ,
-	"DIVPD",	LTYPE3,	ADIVPD,
-	"DIVPS",	LTYPE3,	ADIVPS,
-	"DIVSD",	LTYPE3,	ADIVSD,
-	"DIVSS",	LTYPE3,	ADIVSS,
-	"FXRSTOR",	LTYPE2,	AFXRSTOR,
-	"FXRSTOR64",	LTYPE2,	AFXRSTOR64,
-	"FXSAVE",	LTYPE1,	AFXSAVE,
-	"FXSAVE64",	LTYPE1,	AFXSAVE64,
-	"LDMXCSR",	LTYPE2,	ALDMXCSR,
-	"MASKMOVOU",	LTYPE3,	AMASKMOVOU,
-	"MASKMOVDQU",	LTYPE3,	AMASKMOVOU,	/* syn */
-	"MASKMOVQ",	LTYPE3,	AMASKMOVQ,
-	"MAXPD",	LTYPE3,	AMAXPD,
-	"MAXPS",	LTYPE3,	AMAXPS,
-	"MAXSD",	LTYPE3,	AMAXSD,
-	"MAXSS",	LTYPE3,	AMAXSS,
-	"MINPD",	LTYPE3,	AMINPD,
-	"MINPS",	LTYPE3,	AMINPS,
-	"MINSD",	LTYPE3,	AMINSD,
-	"MINSS",	LTYPE3,	AMINSS,
-	"MOVAPD",	LTYPE3,	AMOVAPD,
-	"MOVAPS",	LTYPE3,	AMOVAPS,
-	"MOVD",		LTYPE3,	AMOVQ,	/* syn */
-	"MOVDQ2Q",	LTYPE3,	AMOVQ,	/* syn */
-	"MOVO",		LTYPE3,	AMOVO,
-	"MOVOA",	LTYPE3,	AMOVO,	/* syn */
-	"MOVOU",	LTYPE3,	AMOVOU,
-	"MOVHLPS",	LTYPE3,	AMOVHLPS,
-	"MOVHPD",	LTYPE3,	AMOVHPD,
-	"MOVHPS",	LTYPE3,	AMOVHPS,
-	"MOVLHPS",	LTYPE3,	AMOVLHPS,
-	"MOVLPD",	LTYPE3,	AMOVLPD,
-	"MOVLPS",	LTYPE3,	AMOVLPS,
-	"MOVMSKPD",	LTYPE3,	AMOVMSKPD,
-	"MOVMSKPS",	LTYPE3,	AMOVMSKPS,
-	"MOVNTO",	LTYPE3,	AMOVNTO,
-	"MOVNTDQ",	LTYPE3,	AMOVNTO,	/* syn */
-	"MOVNTPD",	LTYPE3,	AMOVNTPD,
-	"MOVNTPS",	LTYPE3,	AMOVNTPS,
-	"MOVNTQ",	LTYPE3,	AMOVNTQ,
-	"MOVQOZX",	LTYPE3,	AMOVQOZX,
-	"MOVSD",	LTYPE3,	AMOVSD,
-	"MOVSS",	LTYPE3,	AMOVSS,
-	"MOVUPD",	LTYPE3,	AMOVUPD,
-	"MOVUPS",	LTYPE3,	AMOVUPS,
-	"MULPD",	LTYPE3,	AMULPD,
-	"MULPS",	LTYPE3,	AMULPS,
-	"MULSD",	LTYPE3,	AMULSD,
-	"MULSS",	LTYPE3,	AMULSS,
-	"ORPD",		LTYPE3,	AORPD,
-	"ORPS",		LTYPE3,	AORPS,
-	"PACKSSLW",	LTYPE3,	APACKSSLW,
-	"PACKSSWB",	LTYPE3,	APACKSSWB,
-	"PACKUSWB",	LTYPE3,	APACKUSWB,
-	"PADDB",	LTYPE3,	APADDB,
-	"PADDL",	LTYPE3,	APADDL,
-	"PADDQ",	LTYPE3,	APADDQ,
-	"PADDSB",	LTYPE3,	APADDSB,
-	"PADDSW",	LTYPE3,	APADDSW,
-	"PADDUSB",	LTYPE3,	APADDUSB,
-	"PADDUSW",	LTYPE3,	APADDUSW,
-	"PADDW",	LTYPE3,	APADDW,
-	"PAND",		LTYPE3, APAND,
-	"PANDB",	LTYPE3,	APANDB,
-	"PANDL",	LTYPE3,	APANDL,
-	"PANDSB",	LTYPE3,	APANDSB,
-	"PANDSW",	LTYPE3,	APANDSW,
-	"PANDUSB",	LTYPE3,	APANDUSB,
-	"PANDUSW",	LTYPE3,	APANDUSW,
-	"PANDW",	LTYPE3,	APANDW,
-	"PANDN",	LTYPE3, APANDN,
-	"PAVGB",	LTYPE3,	APAVGB,
-	"PAVGW",	LTYPE3,	APAVGW,
-	"PCMPEQB",	LTYPE3,	APCMPEQB,
-	"PCMPEQL",	LTYPE3,	APCMPEQL,
-	"PCMPEQW",	LTYPE3,	APCMPEQW,
-	"PCMPGTB",	LTYPE3,	APCMPGTB,
-	"PCMPGTL",	LTYPE3,	APCMPGTL,	
-	"PCMPGTW",	LTYPE3,	APCMPGTW,
-	"PEXTRW",	LTYPEX,	APEXTRW,
-	"PINSRW",	LTYPEX,	APINSRW,
-	"PINSRD",	LTYPEX,	APINSRD,
-	"PINSRQ",	LTYPEX,	APINSRQ,
-	"PMADDWL",	LTYPE3,	APMADDWL,
-	"PMAXSW",	LTYPE3,	APMAXSW,
-	"PMAXUB",	LTYPE3,	APMAXUB,
-	"PMINSW",	LTYPE3,	APMINSW,
-	"PMINUB",	LTYPE3,	APMINUB,
-	"PMOVMSKB",	LTYPE3,	APMOVMSKB,
-	"PMULHRW",	LTYPE3,	APMULHRW,
-	"PMULHUW",	LTYPE3,	APMULHUW,
-	"PMULHW",	LTYPE3,	APMULHW,
-	"PMULLW",	LTYPE3,	APMULLW,
-	"PMULULQ",	LTYPE3,	APMULULQ,
-	"POR",		LTYPE3,	APOR,
-	"PSADBW",	LTYPE3,	APSADBW,
-	"PSHUFHW",	LTYPEX,	APSHUFHW,
-	"PSHUFL",	LTYPEX,	APSHUFL,
-	"PSHUFLW",	LTYPEX,	APSHUFLW,
-	"PSHUFW",	LTYPEX, APSHUFW,
-	"PSHUFB",	LTYPEM, APSHUFB,
-	"PSLLO",	LTYPE3,	APSLLO,
-	"PSLLDQ",	LTYPE3,	APSLLO,	/* syn */
-	"PSLLL",	LTYPE3,	APSLLL,
-	"PSLLQ",	LTYPE3,	APSLLQ,
-	"PSLLW",	LTYPE3,	APSLLW,
-	"PSRAL",	LTYPE3,	APSRAL,
-	"PSRAW",	LTYPE3,	APSRAW,
-	"PSRLO",	LTYPE3,	APSRLO,
-	"PSRLDQ",	LTYPE3,	APSRLO,	/* syn */
-	"PSRLL",	LTYPE3,	APSRLL,
-	"PSRLQ",	LTYPE3,	APSRLQ,
-	"PSRLW",	LTYPE3,	APSRLW,
-	"PSUBB",	LTYPE3,	APSUBB,
-	"PSUBL",	LTYPE3,	APSUBL,
-	"PSUBQ",	LTYPE3,	APSUBQ,
-	"PSUBSB",	LTYPE3,	APSUBSB,
-	"PSUBSW",	LTYPE3,	APSUBSW,
-	"PSUBUSB",	LTYPE3,	APSUBUSB,
-	"PSUBUSW",	LTYPE3,	APSUBUSW,
-	"PSUBW",	LTYPE3,	APSUBW,
-	"PUNPCKHBW",	LTYPE3,	APUNPCKHBW,
-	"PUNPCKHLQ",	LTYPE3,	APUNPCKHLQ,
-	"PUNPCKHQDQ",	LTYPE3,	APUNPCKHQDQ,
-	"PUNPCKHWL",	LTYPE3,	APUNPCKHWL,
-	"PUNPCKLBW",	LTYPE3,	APUNPCKLBW,
-	"PUNPCKLLQ",	LTYPE3,	APUNPCKLLQ,
-	"PUNPCKLQDQ",	LTYPE3,	APUNPCKLQDQ,
-	"PUNPCKLWL",	LTYPE3,	APUNPCKLWL,
-	"PXOR",		LTYPE3,	APXOR,
-	"RCPPS",	LTYPE3,	ARCPPS,
-	"RCPSS",	LTYPE3,	ARCPSS,
-	"RSQRTPS",	LTYPE3,	ARSQRTPS,
-	"RSQRTSS",	LTYPE3,	ARSQRTSS,
-	"SHUFPD",	LTYPEX,	ASHUFPD,
-	"SHUFPS",	LTYPEX,	ASHUFPS,
-	"SQRTPD",	LTYPE3,	ASQRTPD,
-	"SQRTPS",	LTYPE3,	ASQRTPS,
-	"SQRTSD",	LTYPE3,	ASQRTSD,
-	"SQRTSS",	LTYPE3,	ASQRTSS,
-	"STMXCSR",	LTYPE1,	ASTMXCSR,
-	"SUBPD",	LTYPE3,	ASUBPD,
-	"SUBPS",	LTYPE3,	ASUBPS,
-	"SUBSD",	LTYPE3,	ASUBSD,
-	"SUBSS",	LTYPE3,	ASUBSS,
-	"UCOMISD",	LTYPE3,	AUCOMISD,
-	"UCOMISS",	LTYPE3,	AUCOMISS,
-	"UNPCKHPD",	LTYPE3,	AUNPCKHPD,
-	"UNPCKHPS",	LTYPE3,	AUNPCKHPS,
-	"UNPCKLPD",	LTYPE3,	AUNPCKLPD,
-	"UNPCKLPS",	LTYPE3,	AUNPCKLPS,
-	"XORPD",	LTYPE3,	AXORPD,
-	"XORPS",	LTYPE3,	AXORPS,
-	"CRC32B",	LTYPE4, ACRC32B,
-	"CRC32Q",	LTYPE4, ACRC32Q,
-	"PREFETCHT0",		LTYPE2,	APREFETCHT0,
-	"PREFETCHT1",		LTYPE2,	APREFETCHT1,
-	"PREFETCHT2",		LTYPE2,	APREFETCHT2,
-	"PREFETCHNTA",		LTYPE2,	APREFETCHNTA,
-	"UNDEF",	LTYPE0,	AUNDEF,
-	"AESENC",	LTYPE3,	AAESENC,
-	"AESENCLAST",	LTYPE3, AAESENCLAST,
-	"AESDEC",	LTYPE3, AAESDEC,
-	"AESDECLAST",	LTYPE3, AAESDECLAST,
-	"AESIMC",	LTYPE3, AAESIMC,
-	"AESKEYGENASSIST", LTYPEX, AAESKEYGENASSIST,
-	"PSHUFD",	LTYPEX, APSHUFD,
-	"USEFIELD",	LTYPEN, AUSEFIELD,
-	"PCLMULQDQ",	LTYPEX, APCLMULQDQ,
-	"PCDATA",	LTYPEPC,	APCDATA,
-	"FUNCDATA",	LTYPEF,	AFUNCDATA,
-	0
-};
-
-void
-cinit(void)
-{
-	Sym *s;
-	int i;
-
-	nullgen.type = TYPE_NONE;
-	nullgen.index = TYPE_NONE;
-
-	nerrors = 0;
-	iostack = I;
-	iofree = I;
-	peekc = IGN;
-	nhunk = 0;
-	for(i=0; i<NHASH; i++)
-		hash[i] = S;
-	for(i=0; itab[i].name; i++) {
-		s = slookup(itab[i].name);
-		if(s->type != LNAME)
-			yyerror("double initialization %s", itab[i].name);
-		s->type = itab[i].type;
-		s->value = itab[i].value;
-	}
-}
-
-void
-checkscale(int scale)
-{
-
-	switch(scale) {
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		return;
-	}
-	yyerror("scale must be 1248: %d", scale);
-}
-
-void
-syminit(Sym *s)
-{
-
-	s->type = LNAME;
-	s->value = 0;
-}
-
-void
-cclean(void)
-{
-	Addr2 g2;
-
-	g2.from = nullgen;
-	g2.to = nullgen;
-	outcode(AEND, &g2);
-}
-
-void
-outcode(int a, Addr2 *g2)
-{
-	Prog *p;
-	Plist *pl;
-	
-	if(pass == 1)
-		goto out;
-
-	p = malloc(sizeof *p);
-	memset(p, 0, sizeof *p);
-	p->as = a;
-	p->lineno = stmtline;
-	p->from = g2->from;
-	p->to = g2->to;
-	p->pc = pc;
-
-	if(lastpc == nil) {
-		pl = linknewplist(ctxt);
-		pl->firstpc = p;
-	} else
-		lastpc->link = p;
-	lastpc = p;	
-
-out:
-	if(a != AGLOBL && a != ADATA)
-		pc++;
-}
-
-#include "../cc/lexbody"
-#include "../cc/macbody"
diff --git a/src/cmd/new6a/lex.go b/src/cmd/6a/lex.go
similarity index 100%
rename from src/cmd/new6a/lex.go
rename to src/cmd/6a/lex.go
diff --git a/src/cmd/new6a/y.go b/src/cmd/6a/y.go
similarity index 100%
rename from src/cmd/new6a/y.go
rename to src/cmd/6a/y.go
diff --git a/src/cmd/6a/y.tab.c b/src/cmd/6a/y.tab.c
deleted file mode 100644
index a3ee581..0000000
--- a/src/cmd/6a/y.tab.c
+++ /dev/null
@@ -1,2800 +0,0 @@
-/* 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 {
-     LTYPE0 = 258,
-     LTYPE1 = 259,
-     LTYPE2 = 260,
-     LTYPE3 = 261,
-     LTYPE4 = 262,
-     LTYPEC = 263,
-     LTYPED = 264,
-     LTYPEN = 265,
-     LTYPER = 266,
-     LTYPET = 267,
-     LTYPEG = 268,
-     LTYPEPC = 269,
-     LTYPES = 270,
-     LTYPEM = 271,
-     LTYPEI = 272,
-     LTYPEXC = 273,
-     LTYPEX = 274,
-     LTYPERT = 275,
-     LTYPEF = 276,
-     LCONST = 277,
-     LFP = 278,
-     LPC = 279,
-     LSB = 280,
-     LBREG = 281,
-     LLREG = 282,
-     LSREG = 283,
-     LFREG = 284,
-     LMREG = 285,
-     LXREG = 286,
-     LFCONST = 287,
-     LSCONST = 288,
-     LSP = 289,
-     LNAME = 290,
-     LLAB = 291,
-     LVAR = 292
-   };
-#endif
-/* Tokens.  */
-#define LTYPE0 258
-#define LTYPE1 259
-#define LTYPE2 260
-#define LTYPE3 261
-#define LTYPE4 262
-#define LTYPEC 263
-#define LTYPED 264
-#define LTYPEN 265
-#define LTYPER 266
-#define LTYPET 267
-#define LTYPEG 268
-#define LTYPEPC 269
-#define LTYPES 270
-#define LTYPEM 271
-#define LTYPEI 272
-#define LTYPEXC 273
-#define LTYPEX 274
-#define LTYPERT 275
-#define LTYPEF 276
-#define LCONST 277
-#define LFP 278
-#define LPC 279
-#define LSB 280
-#define LBREG 281
-#define LLREG 282
-#define LSREG 283
-#define LFREG 284
-#define LMREG 285
-#define LXREG 286
-#define LFCONST 287
-#define LSCONST 288
-#define LSP 289
-#define LNAME 290
-#define LLAB 291
-#define LVAR 292
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
-
-
-/* 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 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
-}
-/* Line 193 of yacc.c.  */
-#line 187 "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 200 "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  2
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   524
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  56
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  40
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  133
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  271
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   292
-
-#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,     2,     2,     2,    52,    12,     5,     2,
-      53,    54,    10,     8,    51,     9,     2,    11,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    48,    49,
-       6,    50,     7,     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,     4,     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,     3,     2,    55,     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,    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
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint16 yyprhs[] =
-{
-       0,     0,     3,     4,     5,     9,    10,    15,    17,    20,
-      23,    27,    31,    34,    37,    40,    43,    46,    49,    51,
-      53,    56,    59,    62,    65,    68,    71,    74,    77,    79,
-      82,    85,    86,    88,    92,    96,    99,   101,   104,   106,
-     109,   111,   115,   122,   128,   136,   141,   148,   151,   153,
-     155,   157,   161,   167,   171,   177,   180,   182,   186,   192,
-     198,   199,   201,   205,   209,   211,   213,   215,   217,   220,
-     223,   225,   227,   229,   231,   236,   239,   241,   243,   245,
-     247,   249,   251,   253,   256,   259,   262,   265,   270,   276,
-     280,   282,   284,   286,   291,   296,   301,   308,   318,   328,
-     332,   336,   342,   351,   353,   360,   366,   374,   375,   378,
-     381,   383,   385,   387,   389,   391,   394,   397,   400,   404,
-     406,   409,   413,   418,   420,   424,   428,   432,   436,   440,
-     445,   450,   454,   458
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      57,     0,    -1,    -1,    -1,    57,    58,    59,    -1,    -1,
-      45,    48,    60,    59,    -1,    49,    -1,    61,    49,    -1,
-       1,    49,    -1,    45,    50,    95,    -1,    47,    50,    95,
-      -1,    13,    62,    -1,    14,    66,    -1,    15,    65,    -1,
-      16,    63,    -1,    17,    64,    -1,    21,    67,    -1,    68,
-      -1,    69,    -1,    18,    71,    -1,    20,    72,    -1,    25,
-      73,    -1,    26,    74,    -1,    27,    75,    -1,    28,    76,
-      -1,    29,    77,    -1,    30,    78,    -1,    70,    -1,    24,
-      79,    -1,    31,    80,    -1,    -1,    51,    -1,    83,    51,
-      81,    -1,    81,    51,    83,    -1,    83,    51,    -1,    83,
-      -1,    51,    81,    -1,    81,    -1,    51,    84,    -1,    84,
-      -1,    86,    51,    84,    -1,    19,    90,    11,    93,    51,
-      86,    -1,    22,    87,    51,    52,    94,    -1,    22,    87,
-      51,    93,    51,    52,    94,    -1,    23,    87,    51,    86,
-      -1,    23,    87,    51,    93,    51,    86,    -1,    51,    82,
-      -1,    82,    -1,    62,    -1,    66,    -1,    83,    51,    81,
-      -1,    83,    51,    81,    48,    37,    -1,    83,    51,    81,
-      -1,    83,    51,    81,    48,    38,    -1,    83,    51,    -1,
-      83,    -1,    83,    51,    81,    -1,    85,    51,    81,    51,
-      93,    -1,    86,    51,    81,    51,    85,    -1,    -1,    86,
-      -1,    83,    51,    83,    -1,    83,    51,    83,    -1,    85,
-      -1,    87,    -1,    84,    -1,    89,    -1,    10,    85,    -1,
-      10,    88,    -1,    85,    -1,    88,    -1,    81,    -1,    86,
-      -1,    93,    53,    34,    54,    -1,    45,    91,    -1,    36,
-      -1,    39,    -1,    37,    -1,    40,    -1,    44,    -1,    38,
-      -1,    41,    -1,    52,    93,    -1,    52,    90,    -1,    52,
-      43,    -1,    52,    42,    -1,    52,    53,    42,    54,    -1,
-      52,    53,     9,    42,    54,    -1,    52,     9,    42,    -1,
-      88,    -1,    89,    -1,    93,    -1,    93,    53,    37,    54,
-      -1,    93,    53,    44,    54,    -1,    93,    53,    38,    54,
-      -1,    93,    53,    37,    10,    93,    54,    -1,    93,    53,
-      37,    54,    53,    37,    10,    93,    54,    -1,    93,    53,
-      37,    54,    53,    38,    10,    93,    54,    -1,    53,    37,
-      54,    -1,    53,    44,    54,    -1,    53,    37,    10,    93,
-      54,    -1,    53,    37,    54,    53,    37,    10,    93,    54,
-      -1,    90,    -1,    90,    53,    37,    10,    93,    54,    -1,
-      45,    91,    53,    92,    54,    -1,    45,     6,     7,    91,
-      53,    35,    54,    -1,    -1,     8,    93,    -1,     9,    93,
-      -1,    35,    -1,    44,    -1,    33,    -1,    32,    -1,    47,
-      -1,     9,    93,    -1,     8,    93,    -1,    55,    93,    -1,
-      53,    95,    54,    -1,    32,    -1,     9,    32,    -1,    32,
-       9,    32,    -1,     9,    32,     9,    32,    -1,    93,    -1,
-      95,     8,    95,    -1,    95,     9,    95,    -1,    95,    10,
-      95,    -1,    95,    11,    95,    -1,    95,    12,    95,    -1,
-      95,     6,     6,    95,    -1,    95,     7,     7,    95,    -1,
-      95,     5,    95,    -1,    95,     4,    95,    -1,    95,     3,
-      95,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,    66,    66,    68,    67,    75,    74,    83,    84,    85,
-      88,    93,    99,   100,   101,   102,   103,   104,   105,   106,
-     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,
-     117,   120,   124,   131,   138,   145,   150,   157,   162,   169,
-     174,   179,   186,   199,   207,   221,   229,   243,   248,   255,
-     256,   259,   264,   274,   279,   289,   294,   299,   306,   314,
-     324,   328,   335,   344,   355,   356,   359,   360,   361,   365,
-     369,   370,   373,   374,   377,   383,   394,   400,   406,   412,
-     418,   424,   430,   438,   444,   454,   460,   466,   472,   478,
-     486,   487,   490,   496,   503,   510,   517,   526,   536,   546,
-     552,   558,   566,   577,   581,   590,   598,   608,   611,   615,
-     621,   622,   626,   629,   630,   634,   638,   642,   646,   652,
-     659,   666,   673,   682,   683,   687,   691,   695,   699,   703,
-     707,   711,   715,   719
-};
-#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.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "'|'", "'^'", "'&'", "'<'", "'>'", "'+'",
-  "'-'", "'*'", "'/'", "'%'", "LTYPE0", "LTYPE1", "LTYPE2", "LTYPE3",
-  "LTYPE4", "LTYPEC", "LTYPED", "LTYPEN", "LTYPER", "LTYPET", "LTYPEG",
-  "LTYPEPC", "LTYPES", "LTYPEM", "LTYPEI", "LTYPEXC", "LTYPEX", "LTYPERT",
-  "LTYPEF", "LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG",
-  "LFREG", "LMREG", "LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB",
-  "LVAR", "':'", "';'", "'='", "','", "'$'", "'('", "')'", "'~'",
-  "$accept", "prog", "@1", "line", "@2", "inst", "nonnon", "rimrem",
-  "remrim", "rimnon", "nonrem", "nonrel", "spec1", "spec2", "spec11",
-  "spec3", "spec4", "spec5", "spec6", "spec7", "spec8", "spec9", "spec10",
-  "spec12", "spec13", "rem", "rom", "rim", "rel", "reg", "imm", "mem",
-  "omem", "nmem", "nam", "offset", "pointer", "con", "textsize", "expr", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   124,    94,    38,    60,    62,    43,    45,
-      42,    47,    37,   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,    58,    59,
-      61,    44,    36,    40,    41,   126
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    56,    57,    58,    57,    60,    59,    59,    59,    59,
-      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
-      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
-      61,    62,    62,    63,    64,    65,    65,    66,    66,    67,
-      67,    67,    68,    69,    69,    70,    70,    71,    71,    72,
-      72,    73,    73,    74,    74,    75,    75,    75,    76,    77,
-      78,    78,    79,    80,    81,    81,    82,    82,    82,    82,
-      82,    82,    83,    83,    84,    84,    85,    85,    85,    85,
-      85,    85,    85,    86,    86,    86,    86,    86,    86,    86,
-      87,    87,    88,    88,    88,    88,    88,    88,    88,    88,
-      88,    88,    88,    89,    89,    90,    90,    91,    91,    91,
-      92,    92,    92,    93,    93,    93,    93,    93,    93,    94,
-      94,    94,    94,    95,    95,    95,    95,    95,    95,    95,
-      95,    95,    95,    95
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     0,     0,     3,     0,     4,     1,     2,     2,
-       3,     3,     2,     2,     2,     2,     2,     2,     1,     1,
-       2,     2,     2,     2,     2,     2,     2,     2,     1,     2,
-       2,     0,     1,     3,     3,     2,     1,     2,     1,     2,
-       1,     3,     6,     5,     7,     4,     6,     2,     1,     1,
-       1,     3,     5,     3,     5,     2,     1,     3,     5,     5,
-       0,     1,     3,     3,     1,     1,     1,     1,     2,     2,
-       1,     1,     1,     1,     4,     2,     1,     1,     1,     1,
-       1,     1,     1,     2,     2,     2,     2,     4,     5,     3,
-       1,     1,     1,     4,     4,     4,     6,     9,     9,     3,
-       3,     5,     8,     1,     6,     5,     7,     0,     2,     2,
-       1,     1,     1,     1,     1,     2,     2,     2,     3,     1,
-       2,     3,     4,     1,     3,     3,     3,     3,     3,     4,
-       4,     3,     3,     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_uint8 yydefact[] =
-{
-       2,     3,     1,     0,     0,    31,     0,     0,     0,     0,
-       0,     0,    31,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    60,     0,     0,     0,     7,     4,     0,    18,
-      19,    28,     9,    32,    12,     0,     0,   113,    76,    78,
-      81,    77,    79,    82,    80,   107,   114,     0,     0,     0,
-      13,    38,    64,    65,    90,    91,   103,    92,     0,    14,
-      72,    36,    73,    15,     0,    16,     0,     0,   107,     0,
-      20,    48,    66,    70,    71,    67,    92,     0,    32,    49,
-      50,    21,   107,     0,     0,    17,    40,     0,     0,     0,
-       0,    29,     0,    22,     0,    23,     0,    24,    56,    25,
-       0,    26,     0,    27,    61,    30,     0,     5,     0,     0,
-       8,   116,   115,     0,     0,     0,     0,    37,     0,     0,
-     123,     0,   117,     0,     0,     0,    86,    85,     0,    84,
-      83,    35,     0,     0,    68,    69,    75,    47,     0,     0,
-      75,    39,     0,     0,     0,     0,     0,     0,     0,    55,
-       0,     0,     0,     0,    10,    11,   107,   108,   109,     0,
-       0,    99,   100,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   118,     0,     0,     0,     0,    89,     0,
-       0,    33,    34,     0,     0,    41,     0,     0,    45,     0,
-      62,    51,    53,    57,     0,     0,    63,     6,     0,   112,
-     110,   111,     0,     0,     0,   133,   132,   131,     0,     0,
-     124,   125,   126,   127,   128,     0,     0,    93,    95,    94,
-       0,    87,    74,     0,     0,   119,    43,     0,     0,     0,
-       0,     0,     0,     0,   105,   101,     0,   129,   130,     0,
-       0,     0,    88,    42,   120,     0,     0,    46,    52,    54,
-      58,    59,     0,     0,   104,    96,     0,     0,     0,   121,
-      44,   106,     0,     0,     0,   122,   102,     0,     0,    97,
-      98
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     1,     3,    27,   153,    28,    34,    63,    65,    59,
-      50,    85,    29,    30,    31,    70,    81,    93,    95,    97,
-      99,   101,   103,    91,   105,    60,    71,    61,    72,    52,
-      62,    53,    54,    55,    56,   116,   202,    57,   226,   121
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -87
-static const yytype_int16 yypact[] =
-{
-     -87,    24,   -87,   211,    20,    -5,   236,   256,   256,   330,
-     156,    25,   290,    55,   364,   364,   256,   256,   256,   256,
-     145,    29,    29,   256,    17,    46,   -87,   -87,    26,   -87,
-     -87,   -87,   -87,   -87,   -87,   451,   451,   -87,   -87,   -87,
-     -87,   -87,   -87,   -87,   -87,    27,   -87,   330,   270,   451,
-     -87,   -87,   -87,   -87,   -87,   -87,    39,    44,    48,   -87,
-     -87,    65,   -87,   -87,    66,   -87,    68,   350,    27,   310,
-     -87,   -87,   -87,   -87,   -87,   -87,    71,   110,   330,   -87,
-     -87,   -87,    23,   384,   451,   -87,   -87,    75,    72,    77,
-      82,   -87,    85,   -87,    87,   -87,    88,   -87,    89,   -87,
-      90,   -87,    91,   -87,   -87,   -87,    92,   -87,   451,   451,
-     -87,   -87,   -87,   120,   451,   451,    98,   -87,     7,   113,
-     -87,   168,   -87,   115,     5,   391,   -87,   -87,   398,   -87,
-     -87,   -87,   330,   256,   -87,   -87,    98,   -87,     3,   451,
-     -87,   -87,   384,   122,   416,   426,   256,   330,   330,   330,
-     330,   330,   256,   211,   504,   504,    23,   -87,   -87,    76,
-     451,   117,   -87,   451,   451,   451,   162,   180,   451,   451,
-     451,   451,   451,   -87,   181,     8,   136,   148,   -87,   433,
-     150,   -87,   -87,   154,   159,   -87,    12,   163,   -87,   165,
-     -87,   169,   170,   -87,   204,   206,   -87,   -87,   160,   -87,
-     -87,   -87,   205,   207,   182,   485,   512,   240,   451,   451,
-     102,   102,   -87,   -87,   -87,   451,   451,   209,   -87,   -87,
-     212,   -87,   -87,    29,   231,   258,   -87,   217,    29,   233,
-     244,   451,   145,   249,   -87,   -87,   261,    42,    42,   232,
-     250,   -22,   -87,   -87,   276,   273,    12,   -87,   -87,   -87,
-     -87,   -87,   252,   451,   -87,   -87,   280,   300,   281,   -87,
-     -87,   -87,   262,   451,   451,   -87,   -87,   267,   278,   -87,
-     -87
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-     -87,   -87,   -87,   171,   -87,   -87,   303,   -87,   -87,   -87,
-     321,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   -87,
-     -87,   -87,   -87,   -87,   -87,    -2,   243,    11,   -11,    -9,
-      -8,    74,    -1,     2,    -3,   -62,   -87,   -10,    94,   -86
-};
-
-/* 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 -1
-static const yytype_uint16 yytable[] =
-{
-      76,    73,    86,    88,    51,    87,   136,    66,    77,    74,
-      51,   100,    75,   102,   104,   256,   257,   160,   216,    64,
-     140,   224,   154,   155,     2,   111,   112,    92,    94,    96,
-      98,   114,   115,   113,   106,   114,   115,   183,   120,   122,
-     175,   176,   175,   176,   225,   117,    33,   177,   130,   177,
-     168,   169,   170,   171,   172,   129,    35,   125,   134,    76,
-      73,   161,   217,    35,    36,   107,   135,   108,    74,    32,
-      45,    75,   141,    88,   120,   110,   117,   205,   206,   207,
-      37,    58,   210,   211,   212,   213,   214,    37,    89,    90,
-     126,   127,   123,    45,   198,    46,   109,   124,   120,   120,
-      82,   128,    46,    49,   157,   158,    83,    58,    84,   199,
-      49,   200,   170,   171,   172,   112,   131,   132,   120,   133,
-     201,   139,   237,   238,   138,   143,   142,   156,   144,   184,
-     181,   185,    88,   145,   187,   189,   146,   188,   147,   148,
-     149,   150,   151,   152,   182,   191,   192,   193,   194,   195,
-     203,   159,   174,   120,   120,   120,   183,   190,   120,   120,
-     120,   120,   120,   196,    35,    36,    67,   162,   208,   112,
-     204,   163,   164,   165,   166,   167,   168,   169,   170,   171,
-     172,    38,    39,    40,    41,    42,    43,   209,    37,    44,
-     218,   215,    38,    39,    40,    41,    42,    43,   120,   120,
-      44,    68,   219,    46,   221,   239,   240,    69,   222,    48,
-     223,    49,     4,   233,   227,   243,   228,   229,   230,   236,
-     247,   250,   173,   251,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,    23,   262,    35,    36,   166,   167,   168,   169,
-     170,   171,   172,   267,   268,   231,    24,   232,    25,   234,
-      26,   235,   241,   244,    35,    36,   242,   245,    37,   246,
-     248,   253,    38,    39,    40,    41,    42,    43,    35,    36,
-      44,    45,   249,    46,   252,   258,   254,    47,    37,    48,
-     263,    49,    38,    39,    40,    41,    42,    43,    35,    36,
-      44,    45,    37,    46,   255,   259,   261,   118,    58,    48,
-     264,    49,   137,   265,   119,    79,   266,    46,    35,    36,
-      67,   269,    37,    84,   197,    49,    38,    39,    40,    41,
-      42,    43,   270,    80,    44,    45,     0,    46,    35,    36,
-     260,    78,    37,    48,     0,    49,    38,    39,    40,    41,
-      42,    43,     0,     0,    44,    68,     0,    46,    35,    36,
-       0,     0,    37,    48,     0,    49,    38,    39,    40,    41,
-      42,    43,    35,    36,    44,    45,     0,    46,     0,     0,
-       0,     0,    37,    48,     0,    49,    38,    39,    40,    41,
-      42,    43,    35,    36,    44,     0,    37,    46,     0,    35,
-      36,     0,     0,    48,     0,    49,    35,   179,     0,    45,
-       0,    46,     0,     0,     0,     0,    37,    48,     0,    49,
-       0,     0,     0,    37,    35,    36,     0,     0,     0,    82,
-      37,    46,     0,   178,    35,    36,     0,    84,    46,    49,
-     180,    35,    36,     0,    84,    46,    49,     0,    37,     0,
-       0,    84,     0,    49,     0,     0,     0,     0,    37,    35,
-      36,     0,     0,    46,     0,    37,     0,     0,   186,    84,
-       0,    49,     0,    46,     0,   220,     0,     0,    58,    84,
-      46,    49,     0,    37,     0,     0,    84,     0,    49,   164,
-     165,   166,   167,   168,   169,   170,   171,   172,    46,     0,
-       0,     0,     0,     0,    84,     0,    49,   163,   164,   165,
-     166,   167,   168,   169,   170,   171,   172,   165,   166,   167,
-     168,   169,   170,   171,   172
-};
-
-static const yytype_int16 yycheck[] =
-{
-      10,    10,    13,    13,     6,    13,    68,     9,    11,    10,
-      12,    20,    10,    21,    22,    37,    38,    10,    10,     8,
-      82,     9,   108,   109,     0,    35,    36,    16,    17,    18,
-      19,     8,     9,     6,    23,     8,     9,    34,    48,    49,
-      37,    38,    37,    38,    32,    47,    51,    44,    58,    44,
-       8,     9,    10,    11,    12,    58,     8,     9,    67,    69,
-      69,    54,    54,     8,     9,    48,    67,    50,    69,    49,
-      45,    69,    83,    83,    84,    49,    78,   163,   164,   165,
-      32,    52,   168,   169,   170,   171,   172,    32,    14,    15,
-      42,    43,    53,    45,   156,    47,    50,    53,   108,   109,
-      45,    53,    47,    55,   114,   115,    51,    52,    53,    33,
-      55,    35,    10,    11,    12,   125,    51,    51,   128,    51,
-      44,    11,   208,   209,    53,    53,    51,     7,    51,   139,
-     132,   142,   142,    51,   144,   145,    51,   145,    51,    51,
-      51,    51,    51,    51,   133,   147,   148,   149,   150,   151,
-     160,    53,    37,   163,   164,   165,    34,   146,   168,   169,
-     170,   171,   172,   152,     8,     9,    10,    54,     6,   179,
-      53,     3,     4,     5,     6,     7,     8,     9,    10,    11,
-      12,    36,    37,    38,    39,    40,    41,     7,    32,    44,
-      54,    10,    36,    37,    38,    39,    40,    41,   208,   209,
-      44,    45,    54,    47,    54,   215,   216,    51,    54,    53,
-      51,    55,     1,    53,    51,   223,    51,    48,    48,    37,
-     228,   231,    54,   232,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,   253,     8,     9,     6,     7,     8,     9,
-      10,    11,    12,   263,   264,    51,    45,    51,    47,    54,
-      49,    54,    53,    32,     8,     9,    54,     9,    32,    52,
-      37,    10,    36,    37,    38,    39,    40,    41,     8,     9,
-      44,    45,    38,    47,    35,     9,    54,    51,    32,    53,
-      10,    55,    36,    37,    38,    39,    40,    41,     8,     9,
-      44,    45,    32,    47,    54,    32,    54,    37,    52,    53,
-      10,    55,    69,    32,    44,    12,    54,    47,     8,     9,
-      10,    54,    32,    53,   153,    55,    36,    37,    38,    39,
-      40,    41,    54,    12,    44,    45,    -1,    47,     8,     9,
-     246,    51,    32,    53,    -1,    55,    36,    37,    38,    39,
-      40,    41,    -1,    -1,    44,    45,    -1,    47,     8,     9,
-      -1,    -1,    32,    53,    -1,    55,    36,    37,    38,    39,
-      40,    41,     8,     9,    44,    45,    -1,    47,    -1,    -1,
-      -1,    -1,    32,    53,    -1,    55,    36,    37,    38,    39,
-      40,    41,     8,     9,    44,    -1,    32,    47,    -1,     8,
-       9,    -1,    -1,    53,    -1,    55,     8,     9,    -1,    45,
-      -1,    47,    -1,    -1,    -1,    -1,    32,    53,    -1,    55,
-      -1,    -1,    -1,    32,     8,     9,    -1,    -1,    -1,    45,
-      32,    47,    -1,    42,     8,     9,    -1,    53,    47,    55,
-      42,     8,     9,    -1,    53,    47,    55,    -1,    32,    -1,
-      -1,    53,    -1,    55,    -1,    -1,    -1,    -1,    32,     8,
-       9,    -1,    -1,    47,    -1,    32,    -1,    -1,    52,    53,
-      -1,    55,    -1,    47,    -1,    42,    -1,    -1,    52,    53,
-      47,    55,    -1,    32,    -1,    -1,    53,    -1,    55,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    47,    -1,
-      -1,    -1,    -1,    -1,    53,    -1,    55,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,     5,     6,     7,
-       8,     9,    10,    11,    12
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,    57,     0,    58,     1,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    45,    47,    49,    59,    61,    68,
-      69,    70,    49,    51,    62,     8,     9,    32,    36,    37,
-      38,    39,    40,    41,    44,    45,    47,    51,    53,    55,
-      66,    81,    85,    87,    88,    89,    90,    93,    52,    65,
-      81,    83,    86,    63,    83,    64,    81,    10,    45,    51,
-      71,    82,    84,    85,    88,    89,    93,    90,    51,    62,
-      66,    72,    45,    51,    53,    67,    84,    86,    93,    87,
-      87,    79,    83,    73,    83,    74,    83,    75,    83,    76,
-      85,    77,    86,    78,    86,    80,    83,    48,    50,    50,
-      49,    93,    93,     6,     8,     9,    91,    81,    37,    44,
-      93,    95,    93,    53,    53,     9,    42,    43,    53,    90,
-      93,    51,    51,    51,    85,    88,    91,    82,    53,    11,
-      91,    84,    51,    53,    51,    51,    51,    51,    51,    51,
-      51,    51,    51,    60,    95,    95,     7,    93,    93,    53,
-      10,    54,    54,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    54,    37,    37,    38,    44,    42,     9,
-      42,    81,    83,    34,    93,    84,    52,    93,    86,    93,
-      83,    81,    81,    81,    81,    81,    83,    59,    91,    33,
-      35,    44,    92,    93,    53,    95,    95,    95,     6,     7,
-      95,    95,    95,    95,    95,    10,    10,    54,    54,    54,
-      42,    54,    54,    51,     9,    32,    94,    51,    51,    48,
-      48,    51,    51,    53,    54,    54,    37,    95,    95,    93,
-      93,    53,    54,    86,    32,     9,    52,    86,    37,    38,
-      93,    85,    35,    10,    54,    54,    37,    38,     9,    32,
-      94,    54,    93,    10,    10,    32,    54,    93,    93,    54,
-      54
-};
-
-#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;
-
-/* 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 yystate;
-  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 3:
-#line 68 "a.y"
-    {
-		stmtline = lineno;
-	}
-    break;
-
-  case 5:
-#line 75 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
-			yyerror("redeclaration of %s (%s)", (yyvsp[(1) - (2)].sym)->labelname, (yyvsp[(1) - (2)].sym)->name);
-		(yyvsp[(1) - (2)].sym)->type = LLAB;
-		(yyvsp[(1) - (2)].sym)->value = pc;
-	}
-    break;
-
-  case 10:
-#line 89 "a.y"
-    {
-		(yyvsp[(1) - (3)].sym)->type = LVAR;
-		(yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 11:
-#line 94 "a.y"
-    {
-		if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
-			yyerror("redeclaration of %s", (yyvsp[(1) - (3)].sym)->name);
-		(yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 12:
-#line 99 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 13:
-#line 100 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 14:
-#line 101 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 15:
-#line 102 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 16:
-#line 103 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 17:
-#line 104 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 20:
-#line 107 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 21:
-#line 108 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 22:
-#line 109 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 23:
-#line 110 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 24:
-#line 111 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 25:
-#line 112 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 26:
-#line 113 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 27:
-#line 114 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 29:
-#line 116 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 30:
-#line 117 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 31:
-#line 120 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 32:
-#line 125 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 33:
-#line 132 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 34:
-#line 139 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 35:
-#line 146 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (2)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 36:
-#line 151 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 37:
-#line 158 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 38:
-#line 163 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 39:
-#line 170 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 40:
-#line 175 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 41:
-#line 180 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 42:
-#line 187 "a.y"
-    {
-		Addr2 a;
-		a.from = (yyvsp[(2) - (6)].addr);
-		a.to = (yyvsp[(6) - (6)].addr);
-		outcode(ADATA, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 43:
-#line 200 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (5)].addr).sym);
-		a.from = (yyvsp[(2) - (5)].addr);
-		a.to = (yyvsp[(5) - (5)].addr);
-		outcode(ATEXT, &a);
-	}
-    break;
-
-  case 44:
-#line 208 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (7)].addr).sym);
-		a.from = (yyvsp[(2) - (7)].addr);
-		a.to = (yyvsp[(7) - (7)].addr);
-		outcode(ATEXT, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (7)].lval);
-		}
-	}
-    break;
-
-  case 45:
-#line 222 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (4)].addr).sym);
-		a.from = (yyvsp[(2) - (4)].addr);
-		a.to = (yyvsp[(4) - (4)].addr);
-		outcode(AGLOBL, &a);
-	}
-    break;
-
-  case 46:
-#line 230 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (6)].addr).sym);
-		a.from = (yyvsp[(2) - (6)].addr);
-		a.to = (yyvsp[(6) - (6)].addr);
-		outcode(AGLOBL, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 47:
-#line 244 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 48:
-#line 249 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 51:
-#line 260 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 52:
-#line 265 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		if((yyval.addr2).from.index != TYPE_NONE)
-			yyerror("dp shift with lhs index");
-		(yyval.addr2).from.index = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 53:
-#line 275 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 54:
-#line 280 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		if((yyval.addr2).to.index != TYPE_NONE)
-			yyerror("dp move with lhs index");
-		(yyval.addr2).to.index = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 55:
-#line 290 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (2)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 56:
-#line 295 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 57:
-#line 300 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 58:
-#line 307 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		(yyval.addr2).to.offset = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 59:
-#line 315 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(3) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(5) - (5)].addr);
-		if((yyvsp[(1) - (5)].addr).type != TYPE_CONST)
-			yyerror("illegal constant");
-		(yyval.addr2).to.offset = (yyvsp[(1) - (5)].addr).offset;
-	}
-    break;
-
-  case 60:
-#line 324 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 61:
-#line 329 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 62:
-#line 336 "a.y"
-    {
-		if((yyvsp[(1) - (3)].addr).type != TYPE_CONST || (yyvsp[(3) - (3)].addr).type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 63:
-#line 345 "a.y"
-    {
-		if((yyvsp[(1) - (3)].addr).type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if((yyvsp[(3) - (3)].addr).type != TYPE_MEM || ((yyvsp[(3) - (3)].addr).name != NAME_EXTERN && (yyvsp[(3) - (3)].addr).name != NAME_STATIC))
-			yyerror("value for FUNCDATA must be symbol reference");
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 68:
-#line 362 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 69:
-#line 366 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 74:
-#line 378 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
-	}
-    break;
-
-  case 75:
-#line 384 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		(yyval.addr) = nullgen;
-		if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
-			yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 76:
-#line 395 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 77:
-#line 401 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 78:
-#line 407 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 79:
-#line 413 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 80:
-#line 419 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = REG_SP;
-	}
-    break;
-
-  case 81:
-#line 425 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 82:
-#line 431 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 83:
-#line 439 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 84:
-#line 445 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-		(yyval.addr).type = TYPE_ADDR;
-		/*
-		if($2.type == D_AUTO || $2.type == D_PARAM)
-			yyerror("constant cannot be automatic: %s",
-				$2.sym->name);
-		 */
-	}
-    break;
-
-  case 85:
-#line 455 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SCONST;
-		memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
-	}
-    break;
-
-  case 86:
-#line 461 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
-	}
-    break;
-
-  case 87:
-#line 467 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(3) - (4)].dval);
-	}
-    break;
-
-  case 88:
-#line 473 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(4) - (5)].dval);
-	}
-    break;
-
-  case 89:
-#line 479 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
-	}
-    break;
-
-  case 92:
-#line 491 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 93:
-#line 497 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 94:
-#line 504 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_SP;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 95:
-#line 511 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 96:
-#line 518 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).offset = (yyvsp[(1) - (6)].lval);
-		(yyval.addr).index = (yyvsp[(3) - (6)].lval);
-		(yyval.addr).scale = (yyvsp[(5) - (6)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 97:
-#line 527 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
-		(yyval.addr).index = (yyvsp[(6) - (9)].lval);
-		(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 98:
-#line 537 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
-		(yyval.addr).index = (yyvsp[(6) - (9)].lval);
-		(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 99:
-#line 547 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 100:
-#line 553 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_SP;
-	}
-    break;
-
-  case 101:
-#line 559 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).index = (yyvsp[(2) - (5)].lval);
-		(yyval.addr).scale = (yyvsp[(4) - (5)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 102:
-#line 567 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (8)].lval);
-		(yyval.addr).index = (yyvsp[(5) - (8)].lval);
-		(yyval.addr).scale = (yyvsp[(7) - (8)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 103:
-#line 578 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 104:
-#line 582 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (6)].addr);
-		(yyval.addr).index = (yyvsp[(3) - (6)].lval);
-		(yyval.addr).scale = (yyvsp[(5) - (6)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 105:
-#line 591 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(4) - (5)].lval);
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
-		(yyval.addr).offset = (yyvsp[(2) - (5)].lval);
-	}
-    break;
-
-  case 106:
-#line 599 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = NAME_STATIC;
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
-		(yyval.addr).offset = (yyvsp[(4) - (7)].lval);
-	}
-    break;
-
-  case 107:
-#line 608 "a.y"
-    {
-		(yyval.lval) = 0;
-	}
-    break;
-
-  case 108:
-#line 612 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 109:
-#line 616 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 111:
-#line 623 "a.y"
-    {
-		(yyval.lval) = NAME_AUTO;
-	}
-    break;
-
-  case 114:
-#line 631 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
-	}
-    break;
-
-  case 115:
-#line 635 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 116:
-#line 639 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 117:
-#line 643 "a.y"
-    {
-		(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 118:
-#line 647 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 119:
-#line 653 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 120:
-#line 660 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (2)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 121:
-#line 667 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (3)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 122:
-#line 674 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (4)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 124:
-#line 684 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 125:
-#line 688 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 126:
-#line 692 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 127:
-#line 696 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 128:
-#line 700 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 129:
-#line 704 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 130:
-#line 708 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 131:
-#line 712 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 132:
-#line 716 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 133:
-#line 720 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 2587 "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);
-}
-
-
-
diff --git a/src/cmd/6a/y.tab.h b/src/cmd/6a/y.tab.h
deleted file mode 100644
index e0eb5e1..0000000
--- a/src/cmd/6a/y.tab.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* 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 {
-     LTYPE0 = 258,
-     LTYPE1 = 259,
-     LTYPE2 = 260,
-     LTYPE3 = 261,
-     LTYPE4 = 262,
-     LTYPEC = 263,
-     LTYPED = 264,
-     LTYPEN = 265,
-     LTYPER = 266,
-     LTYPET = 267,
-     LTYPEG = 268,
-     LTYPEPC = 269,
-     LTYPES = 270,
-     LTYPEM = 271,
-     LTYPEI = 272,
-     LTYPEXC = 273,
-     LTYPEX = 274,
-     LTYPERT = 275,
-     LTYPEF = 276,
-     LCONST = 277,
-     LFP = 278,
-     LPC = 279,
-     LSB = 280,
-     LBREG = 281,
-     LLREG = 282,
-     LSREG = 283,
-     LFREG = 284,
-     LMREG = 285,
-     LXREG = 286,
-     LFCONST = 287,
-     LSCONST = 288,
-     LSP = 289,
-     LNAME = 290,
-     LLAB = 291,
-     LVAR = 292
-   };
-#endif
-/* Tokens.  */
-#define LTYPE0 258
-#define LTYPE1 259
-#define LTYPE2 260
-#define LTYPE3 261
-#define LTYPE4 262
-#define LTYPEC 263
-#define LTYPED 264
-#define LTYPEN 265
-#define LTYPER 266
-#define LTYPET 267
-#define LTYPEG 268
-#define LTYPEPC 269
-#define LTYPES 270
-#define LTYPEM 271
-#define LTYPEI 272
-#define LTYPEXC 273
-#define LTYPEX 274
-#define LTYPERT 275
-#define LTYPEF 276
-#define LCONST 277
-#define LFP 278
-#define LPC 279
-#define LSB 280
-#define LBREG 281
-#define LLREG 282
-#define LSREG 283
-#define LFREG 284
-#define LMREG 285
-#define LXREG 286
-#define LFCONST 287
-#define LSCONST 288
-#define LSP 289
-#define LNAME 290
-#define LLAB 291
-#define LVAR 292
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
-}
-/* Line 1529 of yacc.c.  */
-#line 132 "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/6g/Makefile b/src/cmd/6g/Makefile
deleted file mode 100644
index 3f528d7..0000000
--- a/src/cmd/6g/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
deleted file mode 100644
index 77ab2d2..0000000
--- a/src/cmd/6g/cgen.c
+++ /dev/null
@@ -1,1745 +0,0 @@
-// 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"
-
-/*
- * generate:
- *	res = n;
- * simplifies and calls gmove.
- */
-void
-cgen(Node *n, Node *res)
-{
-	Node *nl, *nr, *r;
-	Node n1, n2;
-	int a, f;
-	Prog *p1, *p2, *p3;
-	Addr addr;
-
-	if(debug['g']) {
-		dump("\ncgen-n", n);
-		dump("cgen-res", res);
-	}
-	if(n == N || n->type == T)
-		goto ret;
-
-	if(res == N || res->type == T)
-		fatal("cgen: res nil");
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	switch(n->op) {
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_slice(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_slice(n, res);
-		goto ret;
-	case OEFACE:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_eface(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_eface(n, res);
-		goto ret;
-	}
-
-	if(n->ullman >= UINF) {
-		if(n->op == OINDREG)
-			fatal("cgen: this is going to misscompile");
-		if(res->ullman >= UINF) {
-			tempname(&n1, n->type);
-			cgen(n, &n1);
-			cgen(&n1, res);
-			goto ret;
-		}
-	}
-
-	if(isfat(n->type)) {
-		if(n->type->width < 0)
-			fatal("forgot to compute width for %T", n->type);
-		sgen(n, res, n->type->width);
-		goto ret;
-	}
-
-	if(!res->addable) {
-		if(n->ullman > res->ullman) {
-			regalloc(&n1, n->type, res);
-			cgen(n, &n1);
-			if(n1.ullman > res->ullman) {
-				dump("n1", &n1);
-				dump("res", res);
-				fatal("loop in cgen");
-			}
-			cgen(&n1, res);
-			regfree(&n1);
-			goto ret;
-		}
-
-		if(res->ullman >= UINF)
-			goto gen;
-
-		if(complexop(n, res)) {
-			complexgen(n, res);
-			goto ret;
-		}
-
-		f = 1;	// gen thru register
-		switch(n->op) {
-		case OLITERAL:
-			if(smallintconst(n))
-				f = 0;
-			break;
-		case OREGISTER:
-			f = 0;
-			break;
-		}
-
-		if(!iscomplex[n->type->etype]) {
-			a = optoas(OAS, res->type);
-			if(sudoaddable(a, res, &addr)) {
-				if(f) {
-					regalloc(&n2, res->type, N);
-					cgen(n, &n2);
-					p1 = gins(a, &n2, N);
-					regfree(&n2);
-				} else
-					p1 = gins(a, n, N);
-				p1->to = addr;
-				if(debug['g'])
-					print("%P [ignore previous line]\n", p1);
-				sudoclean();
-				goto ret;
-			}
-		}
-
-	gen:
-		igen(res, &n1, N);
-		cgen(n, &n1);
-		regfree(&n1);
-		goto ret;
-	}
-
-	// update addressability for string, slice
-	// can't do in walk because n->left->addable
-	// changes if n->left is an escaping local variable.
-	switch(n->op) {
-	case OSPTR:
-	case OLEN:
-		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
-			n->addable = n->left->addable;
-		break;
-	case OCAP:
-		if(isslice(n->left->type))
-			n->addable = n->left->addable;
-		break;
-	case OITAB:
-		n->addable = n->left->addable;
-		break;
-	}
-
-	if(complexop(n, res)) {
-		complexgen(n, res);
-		goto ret;
-	}
-
-	if(n->addable) {
-		gmove(n, res);
-		goto ret;
-	}
-
-	nl = n->left;
-	nr = n->right;
-
-	if(nl != N && nl->ullman >= UINF)
-	if(nr != N && nr->ullman >= UINF) {
-		tempname(&n1, nl->type);
-		cgen(nl, &n1);
-		n2 = *n;
-		n2.left = &n1;
-		cgen(&n2, res);
-		goto ret;
-	}
-
-	if(!iscomplex[n->type->etype]) {
-		a = optoas(OAS, n->type);
-		if(sudoaddable(a, n, &addr)) {
-			if(res->op == OREGISTER) {
-				p1 = gins(a, N, res);
-				p1->from = addr;
-			} else {
-				regalloc(&n2, n->type, N);
-				p1 = gins(a, N, &n2);
-				p1->from = addr;
-				gins(a, &n2, res);
-				regfree(&n2);
-			}
-			sudoclean();
-			goto ret;
-		}
-	}
-
-	switch(n->op) {
-	default:
-		dump("cgen", n);
-		fatal("cgen: unknown op %+hN", n);
-		break;
-
-	// these call bgen to get a bool value
-	case OOROR:
-	case OANDAND:
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OLE:
-	case OGE:
-	case OGT:
-	case ONOT:
-		p1 = gbranch(AJMP, T, 0);
-		p2 = pc;
-		gmove(nodbool(1), res);
-		p3 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		bgen(n, 1, 0, p2);
-		gmove(nodbool(0), res);
-		patch(p3, pc);
-		goto ret;
-
-	case OPLUS:
-		cgen(nl, res);
-		goto ret;
-
-	// unary
-	case OCOM:
-		a = optoas(OXOR, nl->type);
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		nodconst(&n2, nl->type, -1);
-		gins(a, &n2, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		goto ret;
-
-	case OMINUS:
-		if(isfloat[nl->type->etype]) {
-			nr = nodintconst(-1);
-			convlit(&nr, n->type);
-			a = optoas(OMUL, nl->type);
-			goto sbop;
-		}
-		a = optoas(n->op, nl->type);
-		goto uop;
-
-	// symmetric binary
-	case OAND:
-	case OOR:
-	case OXOR:
-	case OADD:
-	case OMUL:
-		a = optoas(n->op, nl->type);
-		if(a == AIMULB) {
-			cgen_bmul(n->op, nl, nr, res);
-			break;
-		}
-		goto sbop;
-
-	// asymmetric binary
-	case OSUB:
-		a = optoas(n->op, nl->type);
-		goto abop;
-
-	case OHMUL:
-		cgen_hmul(nl, nr, res);
-		break;
-
-	case OCONV:
-		if(n->type->width > nl->type->width) {
-			// If loading from memory, do conversion during load,
-			// so as to avoid use of 8-bit register in, say, int(*byteptr).
-			switch(nl->op) {
-			case ODOT:
-			case ODOTPTR:
-			case OINDEX:
-			case OIND:
-			case ONAME:
-				igen(nl, &n1, res);
-				regalloc(&n2, n->type, res);
-				gmove(&n1, &n2);
-				gmove(&n2, res);
-				regfree(&n2);
-				regfree(&n1);
-				goto ret;
-			}
-		}
-
-		regalloc(&n1, nl->type, res);
-		regalloc(&n2, n->type, &n1);
-		cgen(nl, &n1);
-
-		// if we do the conversion n1 -> n2 here
-		// reusing the register, then gmove won't
-		// have to allocate its own register.
-		gmove(&n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		regfree(&n1);
-		break;
-
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OIND:
-	case ONAME:	// PHEAP or PPARAMREF var
-		igen(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-	
-	case OITAB:
-		// interface table is first word of interface value
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OSPTR:
-		// pointer is the first word of string or slice.
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n1, types[tptr], res);
-			p1 = gins(ALEAQ, N, &n1);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OLEN:
-		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
-			// map and chan have len in the first int-sized word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.type = types[simtype[TINT]];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
-			// both slice and string have len one pointer into the struct.
-			// a zero pointer means zero length
-			igen(nl, &n1, res);
-			n1.type = types[simtype[TUINT]];
-			n1.xoffset += Array_nel;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OLEN: unknown type %lT", nl->type);
-		break;
-
-	case OCAP:
-		if(istype(nl->type, TCHAN)) {
-			// chan has cap in the second int-sized word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.xoffset = widthint;
-			n2.type = types[simtype[TINT]];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(isslice(nl->type)) {
-			igen(nl, &n1, res);
-			n1.type = types[simtype[TUINT]];
-			n1.xoffset += Array_cap;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OCAP: unknown type %lT", nl->type);
-		break;
-
-	case OADDR:
-		if(n->bounded) // let race detector avoid nil checks
-			disable_checknil++;
-		agen(nl, res);
-		if(n->bounded)
-			disable_checknil--;
-		break;
-
-	case OCALLMETH:
-		cgen_callmeth(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OMOD:
-	case ODIV:
-		if(isfloat[n->type->etype]) {
-			a = optoas(n->op, nl->type);
-			goto abop;
-		}
-
-		if(nl->ullman >= nr->ullman) {
-			regalloc(&n1, nl->type, res);
-			cgen(nl, &n1);
-			cgen_div(n->op, &n1, nr, res);
-			regfree(&n1);
-		} else {
-			if(!smallintconst(nr)) {
-				regalloc(&n2, nr->type, res);
-				cgen(nr, &n2);
-			} else {
-				n2 = *nr;
-			}
-			cgen_div(n->op, nl, &n2, res);
-			if(n2.op != OLITERAL)
-				regfree(&n2);
-		}
-		break;
-
-	case OLSH:
-	case ORSH:
-	case OLROT:
-		cgen_shift(n->op, n->bounded, nl, nr, res);
-		break;
-	}
-	goto ret;
-
-sbop:	// symmetric binary
-	/*
-	 * put simplest on right - we'll generate into left
-	 * and then adjust it using the computation of right.
-	 * constants and variables have the same ullman
-	 * count, so look for constants specially.
-	 *
-	 * an integer constant we can use as an immediate
-	 * is simpler than a variable - we can use the immediate
-	 * in the adjustment instruction directly - so it goes
-	 * on the right.
-	 *
-	 * other constants, like big integers or floating point
-	 * constants, require a mov into a register, so those
-	 * might as well go on the left, so we can reuse that
-	 * register for the computation.
-	 */
-	if(nl->ullman < nr->ullman ||
-	   (nl->ullman == nr->ullman &&
-	    (smallintconst(nl) || (nr->op == OLITERAL && !smallintconst(nr))))) {
-		r = nl;
-		nl = nr;
-		nr = r;
-	}
-
-abop:	// asymmetric binary
-	if(nl->ullman >= nr->ullman) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-	/*
-	 * This generates smaller code - it avoids a MOV - but it's
-	 * easily 10% slower due to not being able to
-	 * optimize/manipulate the move.
-	 * To see, run: go test -bench . crypto/md5
-	 * with and without.
-	 *
-		if(sudoaddable(a, nr, &addr)) {
-			p1 = gins(a, N, &n1);
-			p1->from = addr;
-			gmove(&n1, res);
-			sudoclean();
-			regfree(&n1);
-			goto ret;
-		}
-	 *
-	 */
-
-		if(smallintconst(nr))
-			n2 = *nr;
-		else {
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-		}
-	} else {
-		if(smallintconst(nr))
-			n2 = *nr;
-		else {
-			regalloc(&n2, nr->type, res);
-			cgen(nr, &n2);
-		}
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-	}
-	gins(a, &n2, &n1);
-	gmove(&n1, res);
-	regfree(&n1);
-	if(n2.op != OLITERAL)
-		regfree(&n2);
-	goto ret;
-
-uop:	// unary
-	regalloc(&n1, nl->type, res);
-	cgen(nl, &n1);
-	gins(a, N, &n1);
-	gmove(&n1, res);
-	regfree(&n1);
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * allocate a register (reusing res if possible) and generate
- *  a = n
- * The caller must call regfree(a).
- */
-void
-cgenr(Node *n, Node *a, Node *res)
-{
-	Node n1;
-
-	if(debug['g'])
-		dump("cgenr-n", n);
-
-	if(isfat(n->type))
-		fatal("cgenr on fat node");
-
-	if(n->addable) {
-		regalloc(a, n->type, res);
-		gmove(n, a);
-		return;
-	}
-
-	switch(n->op) {
-	case ONAME:
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		gmove(&n1, a);
-		regfree(&n1);
-		break;
-	default:
-		regalloc(a, n->type, res);
-		cgen(n, a);
-		break;
-	}
-}
-
-/*
- * allocate a register (reusing res if possible) and generate
- * a = &n
- * The caller must call regfree(a).
- * The generated code checks that the result is not nil.
- */
-void
-agenr(Node *n, Node *a, Node *res)
-{
-	Node *nl, *nr;
-	Node n1, n2, n3, n5, tmp, tmp2, nlen;
-	Prog *p1;
-	Type *t;
-	uint64 w;
-	uint64 v;
-	int freelen;
-
-	if(debug['g']) {
-		dump("\nagenr-n", n);
-	}
-
-	nl = n->left;
-	nr = n->right;
-
-	switch(n->op) {
-	case ODOT:
-	case ODOTPTR:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		agen(&n1, a);
-		regfree(&n1);
-		break;
-
-	case OIND:
-		cgenr(n->left, a, res);
-		cgen_checknil(a);
-		break;
-
-	case OINDEX:
-		freelen = 0;
-		w = n->type->width;
-		// Generate the non-addressable child first.
-		if(nr->addable)
-			goto irad;
-		if(nl->addable) {
-			cgenr(nr, &n1, N);
-			if(!isconst(nl, CTSTR)) {
-				if(isfixedarray(nl->type)) {
-					agenr(nl, &n3, res);
-				} else {
-					igen(nl, &nlen, res);
-					freelen = 1;
-					nlen.type = types[tptr];
-					nlen.xoffset += Array_array;
-					regalloc(&n3, types[tptr], res);
-					gmove(&nlen, &n3);
-					nlen.type = types[simtype[TUINT]];
-					nlen.xoffset += Array_nel-Array_array;
-				}
-			}
-			goto index;
-		}
-		tempname(&tmp, nr->type);
-		cgen(nr, &tmp);
-		nr = &tmp;
-	irad:
-		if(!isconst(nl, CTSTR)) {
-			if(isfixedarray(nl->type)) {
-				agenr(nl, &n3, res);
-			} else {
-				if(!nl->addable) {
-					// igen will need an addressable node.
-					tempname(&tmp2, nl->type);
-					cgen(nl, &tmp2);
-					nl = &tmp2;
-				}
-				igen(nl, &nlen, res);
-				freelen = 1;
-				nlen.type = types[tptr];
-				nlen.xoffset += Array_array;
-				regalloc(&n3, types[tptr], res);
-				gmove(&nlen, &n3);
-				nlen.type = types[simtype[TUINT]];
-				nlen.xoffset += Array_nel-Array_array;
-			}
-		}
-		if(!isconst(nr, CTINT)) {
-			cgenr(nr, &n1, N);
-		}
-		goto index;
-
-	index:
-		// &a is in &n3 (allocated in res)
-		// i is in &n1 (if not constant)
-		// len(a) is in nlen (if needed)
-		// w is width
-
-		// constant index
-		if(isconst(nr, CTINT)) {
-			if(isconst(nl, CTSTR))
-				fatal("constant string constant index");	// front end should handle
-			v = mpgetfix(nr->val.u.xval);
-			if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				if(!debug['B'] && !n->bounded) {
-					nodconst(&n2, types[simtype[TUINT]], v);
-					if(smallintconst(nr)) {
-						gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &n2);
-					} else {
-						regalloc(&tmp, types[simtype[TUINT]], N);
-						gmove(&n2, &tmp);
-						gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &tmp);
-						regfree(&tmp);
-					}
-					p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1);
-					ginscall(panicindex, -1);
-					patch(p1, pc);
-				}
-				regfree(&nlen);
-			}
-
-			if (v*w != 0)
-				ginscon(optoas(OADD, types[tptr]), v*w, &n3);
-			*a = n3;
-			break;
-		}
-
-		// type of the index
-		t = types[TUINT64];
-		if(issigned[n1.type->etype])
-			t = types[TINT64];
-
-		regalloc(&n2, t, &n1);			// i
-		gmove(&n1, &n2);
-		regfree(&n1);
-
-		if(!debug['B'] && !n->bounded) {
-			// check bounds
-			t = types[simtype[TUINT]];
-			if(is64(nr->type))
-				t = types[TUINT64];
-			if(isconst(nl, CTSTR)) {
-				nodconst(&nlen, t, nl->val.u.sval->len);
-			} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				if(is64(nr->type)) {
-					regalloc(&n5, t, N);
-					gmove(&nlen, &n5);
-					regfree(&nlen);
-					nlen = n5;
-				}
-			} else {
-				nodconst(&nlen, t, nl->type->bound);
-				if(!smallintconst(&nlen)) {
-					regalloc(&n5, t, N);
-					gmove(&nlen, &n5);
-					nlen = n5;
-					freelen = 1;
-				}
-			}
-			gins(optoas(OCMP, t), &n2, &nlen);
-			p1 = gbranch(optoas(OLT, t), T, +1);
-			ginscall(panicindex, -1);
-			patch(p1, pc);
-		}
-
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n3, types[tptr], res);
-			p1 = gins(ALEAQ, N, &n3);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			gins(AADDQ, &n2, &n3);
-			goto indexdone;
-		}
-
-		if(w == 0) {
-			// nothing to do
-		} else if(w == 1 || w == 2 || w == 4 || w == 8) {
-			p1 = gins(ALEAQ, &n2, &n3);
-			p1->from.type = TYPE_MEM;
-			p1->from.scale = w;
-			p1->from.index = p1->from.reg;
-			p1->from.reg = p1->to.reg;
-		} else {
-			ginscon(optoas(OMUL, t), w, &n2);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-		}
-
-	indexdone:
-		*a = n3;
-		regfree(&n2);
-		if(freelen)
-			regfree(&nlen);
-		break;
-
-	default:
-		regalloc(a, types[tptr], res);
-		agen(n, a);
-		break;
-	}
-}
-
-/*
- * generate:
- *	res = &n;
- * The generated code checks that the result is not nil.
- */
-void
-agen(Node *n, Node *res)
-{
-	Node *nl;
-	Node n1, n2;
-
-	if(debug['g']) {
-		dump("\nagen-res", res);
-		dump("agen-r", n);
-	}
-	if(n == N || n->type == T)
-		return;
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	if(isconst(n, CTNIL) && n->type->width > widthptr) {
-		// Use of a nil interface or nil slice.
-		// Create a temporary we can take the address of and read.
-		// The generated code is just going to panic, so it need not
-		// be terribly efficient. See issue 3670.
-		tempname(&n1, n->type);
-		gvardef(&n1);
-		clearfat(&n1);
-		regalloc(&n2, types[tptr], res);
-		gins(ALEAQ, &n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		goto ret;
-	}
-		
-	if(n->addable) {
-		regalloc(&n1, types[tptr], res);
-		gins(ALEAQ, n, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		goto ret;
-	}
-
-	nl = n->left;
-
-	switch(n->op) {
-	default:
-		fatal("agen: unknown op %+hN", n);
-		break;
-
-	case OCALLMETH:
-		cgen_callmeth(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		tempname(&n1, n->type);
-		cgen_slice(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OEFACE:
-		tempname(&n1, n->type);
-		cgen_eface(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OINDEX:
-		agenr(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case ONAME:
-		// should only get here with names in this func.
-		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME funcdepth %d != %d",
-				n->funcdepth, funcdepth);
-		}
-
-		// should only get here for heap vars or paramref
-		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME class %#x", n->class);
-		}
-		cgen(n->heapaddr, res);
-		if(n->xoffset != 0)
-			ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
-		break;
-
-	case OIND:
-		cgen(nl, res);
-		cgen_checknil(res);
-		break;
-
-	case ODOT:
-		agen(nl, res);
-		if(n->xoffset != 0)
-			ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
-		break;
-
-	case ODOTPTR:
-		cgen(nl, res);
-		cgen_checknil(res);
-		if(n->xoffset != 0)
-			ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
-		break;
-	}
-
-ret:
-	;
-}
-
-/*
- * generate:
- *	newreg = &n;
- *	res = newreg
- *
- * on exit, a has been changed to be *newreg.
- * caller must regfree(a).
- * The generated code checks that the result is not *nil.
- */
-void
-igen(Node *n, Node *a, Node *res)
-{
-	Type *fp;
-	Iter flist;
-	Node n1;
-
-	if(debug['g']) {
-		dump("\nigen-n", n);
-	}
-	switch(n->op) {
-	case ONAME:
-		if((n->class&PHEAP) || n->class == PPARAMREF)
-			break;
-		*a = *n;
-		return;
-
-	case OINDREG:
-		// Increase the refcount of the register so that igen's caller
-		// has to call regfree.
-		if(n->val.u.reg != REG_SP)
-			reg[n->val.u.reg]++;
-		*a = *n;
-		return;
-
-	case ODOT:
-		igen(n->left, a, res);
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		fixlargeoffset(a);
-		return;
-
-	case ODOTPTR:
-		cgenr(n->left, a, res);
-		cgen_checknil(a);
-		a->op = OINDREG;
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		fixlargeoffset(a);
-		return;
-
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		switch(n->op) {
-		case OCALLFUNC:
-			cgen_call(n, 0);
-			break;
-		case OCALLMETH:
-			cgen_callmeth(n, 0);
-			break;
-		case OCALLINTER:
-			cgen_callinter(n, N, 0);
-			break;
-		}
-		fp = structfirst(&flist, getoutarg(n->left->type));
-		memset(a, 0, sizeof *a);
-		a->op = OINDREG;
-		a->val.u.reg = REG_SP;
-		a->addable = 1;
-		a->xoffset = fp->width;
-		a->type = n->type;
-		return;
-
-	case OINDEX:
-		// Index of fixed-size array by constant can
-		// put the offset in the addressing.
-		// Could do the same for slice except that we need
-		// to use the real index for the bounds checking.
-		if(isfixedarray(n->left->type) ||
-		   (isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
-		if(isconst(n->right, CTINT)) {
-			// Compute &a.
-			if(!isptr[n->left->type->etype])
-				igen(n->left, a, res);
-			else {
-				igen(n->left, &n1, res);
-				cgen_checknil(&n1);
-				regalloc(a, types[tptr], res);
-				gmove(&n1, a);
-				regfree(&n1);
-				a->op = OINDREG;
-			}
-
-			// Compute &a[i] as &a + i*width.
-			a->type = n->type;
-			a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
-			fixlargeoffset(a);
-			return;
-		}
-		break;
-	}
-
-	agenr(n, a, res);
-	a->op = OINDREG;
-	a->type = n->type;
-}
-
-/*
- * generate:
- *	if(n == true) goto to;
- */
-void
-bgen(Node *n, int true, int likely, Prog *to)
-{
-	int et, a;
-	Node *nl, *nr, *l, *r;
-	Node n1, n2, tmp;
-	NodeList *ll;
-	Prog *p1, *p2;
-
-	if(debug['g']) {
-		dump("\nbgen", n);
-	}
-
-	if(n == N)
-		n = nodbool(1);
-
-	if(n->ninit != nil)
-		genlist(n->ninit);
-
-	if(n->type == T) {
-		convlit(&n, types[TBOOL]);
-		if(n->type == T)
-			goto ret;
-	}
-
-	et = n->type->etype;
-	if(et != TBOOL) {
-		yyerror("cgen: bad type %T for %O", n->type, n->op);
-		patch(gins(AEND, N, N), to);
-		goto ret;
-	}
-	nr = N;
-
-	while(n->op == OCONVNOP) {
-		n = n->left;
-		if(n->ninit != nil)
-			genlist(n->ninit);
-	}
-
-	switch(n->op) {
-	default:
-		goto def;
-
-	case OLITERAL:
-		// need to ask if it is bool?
-		if(!true == !n->val.u.bval)
-			patch(gbranch(AJMP, T, likely), to);
-		goto ret;
-
-	case ONAME:
-		if(n->addable == 0)
-			goto def;
-		nodconst(&n1, n->type, 0);
-		gins(optoas(OCMP, n->type), n, &n1);
-		a = AJNE;
-		if(!true)
-			a = AJEQ;
-		patch(gbranch(a, n->type, likely), to);
-		goto ret;
-
-	case OANDAND:
-	case OOROR:
-		if((n->op == OANDAND) == true) {
-			p1 = gbranch(AJMP, T, 0);
-			p2 = gbranch(AJMP, T, 0);
-			patch(p1, pc);
-			bgen(n->left, !true, -likely, p2);
-			bgen(n->right, !true, -likely, p2);
-			p1 = gbranch(AJMP, T, 0);
-			patch(p1, to);
-			patch(p2, pc);
-		} else {
-			bgen(n->left, true, likely, to);
-			bgen(n->right, true, likely, to);
-		}
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		nr = n->right;
-		if(nr == N || nr->type == T)
-			goto ret;
-
-	case ONOT:	// unary
-		nl = n->left;
-		if(nl == N || nl->type == T)
-			goto ret;
-		break;
-	}
-
-	switch(n->op) {
-
-	case ONOT:
-		bgen(nl, !true, likely, to);
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		a = n->op;
-		if(!true) {
-			if(isfloat[nr->type->etype]) {
-				// brcom is not valid on floats when NaN is involved.
-				p1 = gbranch(AJMP, T, 0);
-				p2 = gbranch(AJMP, T, 0);
-				patch(p1, pc);
-				ll = n->ninit;   // avoid re-genning ninit
-				n->ninit = nil;
-				bgen(n, 1, -likely, p2);
-				n->ninit = ll;
-				patch(gbranch(AJMP, T, 0), to);
-				patch(p2, pc);
-				goto ret;
-			}				
-			a = brcom(a);
-			true = !true;
-		}
-
-		// make simplest on right
-		if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
-			a = brrev(a);
-			r = nl;
-			nl = nr;
-			nr = r;
-		}
-
-		if(isslice(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal slice comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.xoffset += Array_array;
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-
-		if(isinter(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal interface comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-		if(iscomplex[nl->type->etype]) {
-			complexbool(a, nl, nr, true, likely, to);
-			break;
-		}
-
-		if(nr->ullman >= UINF) {
-			regalloc(&n1, nl->type, N);
-			cgen(nl, &n1);
-
-			tempname(&tmp, nl->type);
-			gmove(&n1, &tmp);
-			regfree(&n1);
-
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-
-			regalloc(&n1, nl->type, N);
-			cgen(&tmp, &n1);
-
-			goto cmp;
-		}
-
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-
-		if(smallintconst(nr)) {
-			gins(optoas(OCMP, nr->type), &n1, nr);
-			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-			regfree(&n1);
-			break;
-		}
-
-		regalloc(&n2, nr->type, N);
-		cgen(nr, &n2);
-	cmp:
-		// only < and <= work right with NaN; reverse if needed
-		l = &n1;
-		r = &n2;
-		if(isfloat[nl->type->etype] && (a == OGT || a == OGE)) {
-			l = &n2;
-			r = &n1;
-			a = brrev(a);
-		}
-
-		gins(optoas(OCMP, nr->type), l, r);
-
-		if(isfloat[nr->type->etype] && (n->op == OEQ || n->op == ONE)) {
-			if(n->op == OEQ) {
-				// neither NE nor P
-				p1 = gbranch(AJNE, T, -likely);
-				p2 = gbranch(AJPS, T, -likely);
-				patch(gbranch(AJMP, T, 0), to);
-				patch(p1, pc);
-				patch(p2, pc);
-			} else {
-				// either NE or P
-				patch(gbranch(AJNE, T, likely), to);
-				patch(gbranch(AJPS, T, likely), to);
-			}
-		} else
-			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-		regfree(&n1);
-		regfree(&n2);
-		break;
-	}
-	goto ret;
-
-def:
-	regalloc(&n1, n->type, N);
-	cgen(n, &n1);
-	nodconst(&n2, n->type, 0);
-	gins(optoas(OCMP, n->type), &n1, &n2);
-	a = AJNE;
-	if(!true)
-		a = AJEQ;
-	patch(gbranch(a, n->type, likely), to);
-	regfree(&n1);
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * n is on stack, either local variable
- * or return value from function call.
- * return n's offset from SP.
- */
-int64
-stkof(Node *n)
-{
-	Type *t;
-	Iter flist;
-	int64 off;
-
-	switch(n->op) {
-	case OINDREG:
-		return n->xoffset;
-
-	case ODOT:
-		t = n->left->type;
-		if(isptr[t->etype])
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		return off + n->xoffset;
-
-	case OINDEX:
-		t = n->left->type;
-		if(!isfixedarray(t))
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		if(isconst(n->right, CTINT))
-			return off + t->type->width * mpgetfix(n->right->val.u.xval);
-		return 1000;
-		
-	case OCALLMETH:
-	case OCALLINTER:
-	case OCALLFUNC:
-		t = n->left->type;
-		if(isptr[t->etype])
-			t = t->type;
-
-		t = structfirst(&flist, getoutarg(t));
-		if(t != T)
-			return t->width;
-		break;
-	}
-
-	// botch - probably failing to recognize address
-	// arithmetic on the above. eg INDEX and DOT
-	return -1000;
-}
-
-/*
- * block copy:
- *	memmove(&ns, &n, w);
- */
-void
-sgen(Node *n, Node *ns, int64 w)
-{
-	Node nodl, nodr, nodsi, noddi, cx, oldcx, tmp;
-	vlong c, q, odst, osrc;
-	NodeList *l;
-	Prog *p;
-
-	if(debug['g']) {
-		print("\nsgen w=%lld\n", w);
-		dump("r", n);
-		dump("res", ns);
-	}
-
-	if(n->ullman >= UINF && ns->ullman >= UINF)
-		fatal("sgen UINF");
-
-	if(w < 0)
-		fatal("sgen copy %lld", w);
-	
-	// If copying .args, that's all the results, so record definition sites
-	// for them for the liveness analysis.
-	if(ns->op == ONAME && strcmp(ns->sym->name, ".args") == 0)
-		for(l = curfn->dcl; l != nil; l = l->next)
-			if(l->n->class == PPARAMOUT)
-				gvardef(l->n);
-
-	// Avoid taking the address for simple enough types.
-	if(componentgen(n, ns))
-		return;
-	
-	if(w == 0) {
-		// evaluate side effects only
-		regalloc(&nodr, types[tptr], N);
-		agen(ns, &nodr);
-		agen(n, &nodr);
-		regfree(&nodr);
-		return;
-	}
-
-	// offset on the stack
-	osrc = stkof(n);
-	odst = stkof(ns);
-
-	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
-		// osrc and odst both on stack, and at least one is in
-		// an unknown position.  Could generate code to test
-		// for forward/backward copy, but instead just copy
-		// to a temporary location first.
-		tempname(&tmp, n->type);
-		sgen(n, &tmp, w);
-		sgen(&tmp, ns, w);
-		return;
-	}
-
-	nodreg(&noddi, types[tptr], REG_DI);
-	nodreg(&nodsi, types[tptr], REG_SI);
-
-	if(n->ullman >= ns->ullman) {
-		agenr(n, &nodr, &nodsi);
-		if(ns->op == ONAME)
-			gvardef(ns);
-		agenr(ns, &nodl, &noddi);
-	} else {
-		if(ns->op == ONAME)
-			gvardef(ns);
-		agenr(ns, &nodl, &noddi);
-		agenr(n, &nodr, &nodsi);
-	}
-	
-	if(nodl.val.u.reg != REG_DI)
-		gmove(&nodl, &noddi);
-	if(nodr.val.u.reg != REG_SI)
-		gmove(&nodr, &nodsi);
-	regfree(&nodl);
-	regfree(&nodr);
-
-	c = w % 8;	// bytes
-	q = w / 8;	// quads
-
-	savex(REG_CX, &cx, &oldcx, N, types[TINT64]);
-
-	// if we are copying forward on the stack and
-	// the src and dst overlap, then reverse direction
-	if(osrc < odst && odst < osrc+w) {
-		// reverse direction
-		gins(ASTD, N, N);		// set direction flag
-		if(c > 0) {
-			gconreg(addptr, w-1, REG_SI);
-			gconreg(addptr, w-1, REG_DI);
-
-			gconreg(movptr, c, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSB, N, N);	// MOVB *(SI)-,*(DI)-
-		}
-
-		if(q > 0) {
-			if(c > 0) {
-				gconreg(addptr, -7, REG_SI);
-				gconreg(addptr, -7, REG_DI);
-			} else {
-				gconreg(addptr, w-8, REG_SI);
-				gconreg(addptr, w-8, REG_DI);
-			}
-			gconreg(movptr, q, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSQ, N, N);	// MOVQ *(SI)-,*(DI)-
-		}
-		// we leave with the flag clear
-		gins(ACLD, N, N);
-	} else {
-		// normal direction
-		if(q > 128 || (nacl && q >= 4)) {
-			gconreg(movptr, q, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSQ, N, N);	// MOVQ *(SI)+,*(DI)+
-		} else if (q >= 4) {
-			p = gins(ADUFFCOPY, N, N);
-			p->to.type = TYPE_ADDR;
-			p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
-			// 14 and 128 = magic constants: see ../../runtime/asm_amd64.s
-			p->to.offset = 14*(128-q);
-		} else if(!nacl && c == 0) {
-			// We don't need the MOVSQ side-effect of updating SI and DI,
-			// and issuing a sequence of MOVQs directly is faster.
-			nodsi.op = OINDREG;
-			noddi.op = OINDREG;
-			while(q > 0) {
-				gmove(&nodsi, &cx); // MOVQ x+(SI),CX
-				gmove(&cx, &noddi); // MOVQ CX,x+(DI)
-				nodsi.xoffset += 8;
-				noddi.xoffset += 8;
-				q--;
-			}
-		} else
-		while(q > 0) {
-			gins(AMOVSQ, N, N);	// MOVQ *(SI)+,*(DI)+
-			q--;
-		}
-		// copy the remaining c bytes
-		if(w < 4 || c <= 1 || (odst < osrc && osrc < odst+w)) {
-			while(c > 0) {
-				gins(AMOVSB, N, N);	// MOVB *(SI)+,*(DI)+
-				c--;
-			}
-		} else if(w < 8 || c <= 4) {
-			nodsi.op = OINDREG;
-			noddi.op = OINDREG;
-			cx.type = types[TINT32];
-			nodsi.type = types[TINT32];
-			noddi.type = types[TINT32];
-			if(c > 4) {
-				nodsi.xoffset = 0;
-				noddi.xoffset = 0;
-				gmove(&nodsi, &cx);
-				gmove(&cx, &noddi);
-			}
-			nodsi.xoffset = c-4;
-			noddi.xoffset = c-4;
-			gmove(&nodsi, &cx);
-			gmove(&cx, &noddi);
-		} else {
-			nodsi.op = OINDREG;
-			noddi.op = OINDREG;
-			cx.type = types[TINT64];
-			nodsi.type = types[TINT64];
-			noddi.type = types[TINT64];
-			nodsi.xoffset = c-8;
-			noddi.xoffset = c-8;
-			gmove(&nodsi, &cx);
-			gmove(&cx, &noddi);
-		}
-	}
-
-	restx(&cx, &oldcx);
-}
-
-static int
-cadable(Node *n)
-{
-	if(!n->addable) {
-		// dont know how it happens,
-		// but it does
-		return 0;
-	}
-
-	switch(n->op) {
-	case ONAME:
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-int
-componentgen(Node *nr, Node *nl)
-{
-	Node nodl, nodr, tmp;
-	Type *t;
-	int freel, freer;
-	vlong fldcount;
-	vlong loffset, roffset;
-
-	freel = 0;
-	freer = 0;
-
-	switch(nl->type->etype) {
-	default:
-		goto no;
-
-	case TARRAY:
-		t = nl->type;
-
-		// Slices are ok.
-		if(isslice(t))
-			break;
-		// Small arrays are ok.
-		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
-			break;
-
-		goto no;
-
-	case TSTRUCT:
-		// Small structs with non-fat types are ok.
-		// Zero-sized structs are treated separately elsewhere.
-		fldcount = 0;
-		for(t=nl->type->type; t; t=t->down) {
-			if(isfat(t->type))
-				goto no;
-			if(t->etype != TFIELD)
-				fatal("componentgen: not a TFIELD: %lT", t);
-			fldcount++;
-		}
-		if(fldcount == 0 || fldcount > 4)
-			goto no;
-
-		break;
-
-	case TSTRING:
-	case TINTER:
-		break;
-	}
-
-	nodl = *nl;
-	if(!cadable(nl)) {
-		if(nr != N && !cadable(nr))
-			goto no;
-		igen(nl, &nodl, N);
-		freel = 1;
-	}
-
-	if(nr != N) {
-		nodr = *nr;
-		if(!cadable(nr)) {
-			igen(nr, &nodr, N);
-			freer = 1;
-		}
-	} else {
-		// When zeroing, prepare a register containing zero.
-		nodconst(&tmp, nl->type, 0);
-		regalloc(&nodr, types[TUINT], N);
-		gmove(&tmp, &nodr);
-		freer = 1;
-	}
-	
-	// nl and nr are 'cadable' which basically means they are names (variables) now.
-	// If they are the same variable, don't generate any code, because the
-	// VARDEF we generate will mark the old value as dead incorrectly.
-	// (And also the assignments are useless.)
-	if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
-		goto yes;
-
-	switch(nl->type->etype) {
-	case TARRAY:
-		// componentgen for arrays.
-		if(nl->op == ONAME)
-			gvardef(nl);
-		t = nl->type;
-		if(!isslice(t)) {
-			nodl.type = t->type;
-			nodr.type = nodl.type;
-			for(fldcount=0; fldcount < t->bound; fldcount++) {
-				if(nr == N)
-					clearslim(&nodl);
-				else
-					gmove(&nodr, &nodl);
-				nodl.xoffset += t->type->width;
-				nodr.xoffset += t->type->width;
-			}
-			goto yes;
-		}
-
-		// componentgen for slices.
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(nl->type->type);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_cap-Array_nel;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_cap-Array_nel;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRING:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TINTER:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRUCT:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		loffset = nodl.xoffset;
-		roffset = nodr.xoffset;
-		// funarg structs may not begin at offset zero.
-		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
-			loffset -= nl->type->type->width;
-		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
-			roffset -= nr->type->type->width;
-
-		for(t=nl->type->type; t; t=t->down) {
-			nodl.xoffset = loffset + t->width;
-			nodl.type = t->type;
-
-			if(nr == N)
-				clearslim(&nodl);
-			else {
-				nodr.xoffset = roffset + t->width;
-				nodr.type = nodl.type;
-				gmove(&nodr, &nodl);
-			}
-		}
-		goto yes;
-	}
-
-no:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 0;
-
-yes:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 1;
-}
diff --git a/src/cmd/new6g/cgen.go b/src/cmd/6g/cgen.go
similarity index 100%
rename from src/cmd/new6g/cgen.go
rename to src/cmd/6g/cgen.go
diff --git a/src/cmd/6g/doc.go b/src/cmd/6g/doc.go
deleted file mode 100644
index 07b2818..0000000
--- a/src/cmd/6g/doc.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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
-
-/*
-
-6g is the version of the gc compiler for the x86-64.
-The $GOARCH for these tools is amd64.
-
-It reads .go files and outputs .6 files. The flags are documented in ../gc/doc.go.
-
-*/
-package main
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
deleted file mode 100644
index fa9998b..0000000
--- a/src/cmd/6g/galign.c
+++ /dev/null
@@ -1,110 +0,0 @@
-// 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"
-
-int	thechar	= '6';
-char*	thestring	= "amd64";
-LinkArch*	thelinkarch = &linkamd64;
-
-void
-linkarchinit(void)
-{
-	if(strcmp(getgoarch(), "amd64p32") == 0) {
-		thelinkarch = &linkamd64p32;
-		thearch.thelinkarch = thelinkarch;
-		thestring = "amd64p32";
-		thearch.thestring = "amd64p32";
-	}
-}
-
-vlong MAXWIDTH = 1LL<<50;
-
-int	addptr = AADDQ;
-int	movptr = AMOVQ;
-int	leaptr = ALEAQ;
-int	cmpptr = ACMPQ;
-
-/*
- * go declares several platform-specific type aliases:
- * int, uint, float, and uintptr
- */
-Typedef	typedefs[] =
-{
-	{"int",		TINT,		TINT64},
-	{"uint",		TUINT,		TUINT64},
-	{"uintptr",	TUINTPTR,	TUINT64},
-	{0}
-};
-
-void
-betypeinit(void)
-{
-	widthptr = 8;
-	widthint = 8;
-	widthreg = 8;
-	if(strcmp(getgoarch(), "amd64p32") == 0) {
-		widthptr = 4;
-		widthint = 4;
-		addptr = AADDL;
-		movptr = AMOVL;
-		leaptr = ALEAL;
-		cmpptr = ACMPL;
-		typedefs[0].sameas = TINT32;
-		typedefs[1].sameas = TUINT32;
-		typedefs[2].sameas = TUINT32;
-		
-	}
-
-	listinit6();
-}
-
-void
-main(int argc, char **argv)
-{
-	thearch.thechar = thechar;
-	thearch.thestring = thestring;
-	thearch.thelinkarch = thelinkarch;
-	thearch.typedefs = typedefs;
-	thearch.REGSP = REGSP;
-	thearch.REGCTXT = REGCTXT;
-	thearch.MAXWIDTH = MAXWIDTH;
-	thearch.anyregalloc = anyregalloc;
-	thearch.betypeinit = betypeinit;
-	thearch.bgen = bgen;
-	thearch.cgen = cgen;
-	thearch.cgen_call = cgen_call;
-	thearch.cgen_callinter = cgen_callinter;
-	thearch.cgen_ret = cgen_ret;
-	thearch.clearfat = clearfat;
-	thearch.defframe = defframe;
-	thearch.excise = excise;
-	thearch.expandchecks = expandchecks;
-	thearch.gclean = gclean;
-	thearch.ginit = ginit;
-	thearch.gins = gins;
-	thearch.ginscall = ginscall;
-	thearch.igen = igen;
-	thearch.linkarchinit = linkarchinit;
-	thearch.peep = peep;
-	thearch.proginfo = proginfo;
-	thearch.regalloc = regalloc;
-	thearch.regfree = regfree;
-	thearch.regtyp = regtyp;
-	thearch.sameaddr = sameaddr;
-	thearch.smallindir = smallindir;
-	thearch.stackaddr = stackaddr;
-	thearch.excludedregs = excludedregs;
-	thearch.RtoB = RtoB;
-	thearch.FtoB = FtoB;
-	thearch.BtoR = BtoR;
-	thearch.BtoF = BtoF;
-	thearch.optoas = optoas;
-	thearch.doregbits = doregbits;
-	thearch.regnames = regnames;
-	
-	gcmain(argc, argv);
-}
diff --git a/src/cmd/new6g/galign.go b/src/cmd/6g/galign.go
similarity index 100%
rename from src/cmd/new6g/galign.go
rename to src/cmd/6g/galign.go
diff --git a/src/cmd/new6g/gg.go b/src/cmd/6g/gg.go
similarity index 100%
rename from src/cmd/new6g/gg.go
rename to src/cmd/6g/gg.go
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
deleted file mode 100644
index a6dfad9..0000000
--- a/src/cmd/6g/gg.h
+++ /dev/null
@@ -1,176 +0,0 @@
-// 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.
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#include "../gc/go.h"
-#include "../6l/6.out.h"
-
-EXTERN	uchar	reg[MAXREG];
-EXTERN	Node*	panicdiv;
-extern	vlong	unmappedzero;
-extern	int	addptr;
-extern	int	cmpptr;
-extern	int	movptr;
-extern	int	leaptr;
-
-/*
- * ggen.c
- */
-void	compile(Node*);
-void	gen(Node*);
-Node*	lookdot(Node*, Node*, int);
-void	cgen_as(Node*, Node*);
-void	cgen_callmeth(Node*, int);
-void	cgen_callinter(Node*, Node*, int);
-void	cgen_proc(Node*, int);
-void	cgen_callret(Node*, Node*);
-void	cgen_div(int, Node*, Node*, Node*);
-void	cgen_bmul(int, Node*, Node*, Node*);
-void	cgen_hmul(Node*, Node*, Node*);
-void	cgen_shift(int, int, Node*, Node*, Node*);
-void	cgen_dcl(Node*);
-int	needconvert(Type*, Type*);
-void	genconv(Type*, Type*);
-void	allocparams(void);
-void	checklabels(void);
-void	ginscall(Node*, int);
-int	gen_as_init(Node*);
-
-/*
- * cgen.c
- */
-void	agen(Node*, Node*);
-void	agenr(Node*, Node*, Node*);
-void	cgenr(Node*, Node*, Node*);
-void	igen(Node*, Node*, Node*);
-vlong	fieldoffset(Type*, Node*);
-void	sgen(Node*, Node*, int64);
-void	gmove(Node*, Node*);
-Prog*	gins(int, Node*, Node*);
-int	samaddr(Node*, Node*);
-void	naddr(Node*, Addr*, int);
-void	cgen_aret(Node*, Node*);
-void	restx(Node*, Node*);
-void	savex(int, Node*, Node*, Node*, Type*);
-int	componentgen(Node*, Node*);
-
-/*
- * gsubr.c
- */
-void	clearp(Prog*);
-Prog*	gbranch(int, Type*, int);
-Prog*	prog(int);
-void	gconv(int, int);
-int	conv2pt(Type*);
-vlong	convvtox(vlong, int);
-void	fnparam(Type*, int, int);
-Prog*	gop(int, Node*, Node*, Node*);
-int	optoas(int, Type*);
-void	ginit(void);
-void	gclean(void);
-void	regalloc(Node*, Type*, Node*);
-void	regfree(Node*);
-Node*	nodarg(Type*, int);
-void	nodreg(Node*, Type*, int);
-void	nodindreg(Node*, Type*, int);
-void	gconreg(int, vlong, int);
-void	ginscon(int, vlong, Node*);
-void	buildtxt(void);
-Plist*	newplist(void);
-int	isfat(Type*);
-void	sudoclean(void);
-int	sudoaddable(int, Node*, Addr*);
-void	afunclit(Addr*, Node*);
-void	nodfconst(Node*, Type*, Mpflt*);
-void	gtrack(Sym*);
-void	fixlargeoffset(Node *n);
-
-/*
- * cplx.c
- */
-int	complexop(Node*, Node*);
-void	complexmove(Node*, Node*);
-void	complexgen(Node*, Node*);
-
-/*
- * gobj.c
- */
-void	datastring(char*, int, Addr*);
-void	datagostring(Strlit*, Addr*);
-
-/*
- * list.c
- */
-void	listinit(void);
-
-void	zaddr(Biobuf*, Addr*, int, int);
-
-void afunclit(Addr*, Node*);
-int anyregalloc(void);
-void betypeinit(void);
-void bgen(Node*, int, int, Prog*);
-void cgen(Node*, Node*);
-void cgen_call(Node*, int);
-void cgen_callinter(Node*, Node*, int);
-void cgen_ret(Node*);
-void clearfat(Node*);
-void clearp(Prog*);
-void defframe(Prog*);
-int dgostringptr(Sym*, int, char*);
-int dgostrlitptr(Sym*, int, Strlit*);
-int dsname(Sym*, int, char*, int);
-int dsymptr(Sym*, int, Sym*, int);
-void dumpdata(void);
-void dumpit(char*, Flow*, int);
-void excise(Flow*);
-void expandchecks(Prog*);
-void fixautoused(Prog*);
-void gclean(void);
-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 ginit(void);
-Prog*	gins(int, Node*, Node*);
-void	ginscall(Node*, int);
-Prog*	gjmp(Prog*);
-void gtrack(Sym*);
-void	gused(Node*);
-void	igen(Node*, Node*, Node*);
-int isfat(Type*);
-void linkarchinit(void);
-void markautoused(Prog*);
-void naddr(Node*, Addr*, int);
-Plist* newplist(void);
-Node* nodarg(Type*, int);
-void patch(Prog*, Prog*);
-void proginfo(ProgInfo*, Prog*);
-void regalloc(Node*, Type*, Node*);
-void regfree(Node*);
-void regopt(Prog*);
-int regtyp(Addr*);
-int sameaddr(Addr*, Addr*);
-int smallindir(Addr*, Addr*);
-int stackaddr(Addr*);
-Prog* unpatch(Prog*);
-
-/*
- * reg.c
- */
-uint64 excludedregs(void);
-uint64 RtoB(int);
-uint64 FtoB(int);
-int BtoR(uint64);
-int BtoF(uint64);
-uint64 doregbits(int);
-char** regnames(int*);
-
-/*
- * peep.c
- */
-void peep(Prog*);
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
deleted file mode 100644
index 7210458..0000000
--- a/src/cmd/6g/ggen.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-// 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.
-
-#undef	EXTERN
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
-static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
-
-void
-defframe(Prog *ptxt)
-{
-	uint32 frame, ax;
-	Prog *p;
-	vlong hi, lo;
-	NodeList *l;
-	Node *n;
-
-	// fill in argument size, stack size
-	ptxt->to.type = TYPE_TEXTSIZE;
-	ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
-	frame = rnd(stksize+maxarg, widthreg);
-	ptxt->to.offset = frame;
-	
-	// insert code to zero ambiguously live variables
-	// so that the garbage collector only sees initialized values
-	// when it looks for pointers.
-	p = ptxt;
-	lo = hi = 0;
-	ax = 0;
-	// iterate through declarations - they are sorted in decreasing xoffset order.
-	for(l=curfn->dcl; l != nil; l = l->next) {
-		n = l->n;
-		if(!n->needzero)
-			continue;
-		if(n->class != PAUTO)
-			fatal("needzero class %d", n->class);
-		if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
-			fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
-
-		if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthreg) {
-			// merge with range we already have
-			lo = n->xoffset;
-			continue;
-		}
-		// zero old range
-		p = zerorange(p, frame, lo, hi, &ax);
-
-		// set new range
-		hi = n->xoffset + n->type->width;
-		lo = n->xoffset;
-	}
-	// zero final range
-	zerorange(p, frame, lo, hi, &ax);
-}
-
-static Prog*
-zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
-{
-	vlong cnt, i;
-
-	cnt = hi - lo;
-	if(cnt == 0)
-		return p;
-	if(*ax == 0) {
-		p = appendpp(p, AMOVQ, TYPE_CONST, 0, 0, TYPE_REG, REG_AX, 0);
-		*ax = 1;
-	}
-	if(cnt % widthreg != 0) {
-		// should only happen with nacl
-		if(cnt % widthptr != 0)
-			fatal("zerorange count not a multiple of widthptr %d", cnt);
-		p = appendpp(p, AMOVL, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo);
-		lo += widthptr;
-		cnt -= widthptr;
-	}
-	if(cnt <= 4*widthreg) {
-		for(i = 0; i < cnt; i += widthreg) {
-			p = appendpp(p, AMOVQ, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo+i);
-		}
-	} else if(!nacl && (cnt <= 128*widthreg)) {
-		p = appendpp(p, leaptr, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
-		p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_ADDR, 0, 2*(128-cnt/widthreg));
-		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-	} else {
-		p = appendpp(p, AMOVQ, TYPE_CONST, 0, cnt/widthreg, TYPE_REG, REG_CX, 0);
-		p = appendpp(p, leaptr, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
-		p = appendpp(p, AREP, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
-		p = appendpp(p, ASTOSQ, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
-	}
-	return p;
-}
-
-static Prog*	
-appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)	
-{
-	Prog *q;
-	q = mal(sizeof(*q));	
-	clearp(q);	
-	q->as = as;	
-	q->lineno = p->lineno;	
-	q->from.type = ftype;
-	q->from.reg = freg;
-	q->from.offset = foffset;	
-	q->to.type = ttype;	
-	q->to.reg = treg;
-	q->to.offset = toffset;	
-	q->link = p->link;	
-	p->link = q;	
-	return q;	
-}
-
-/*
- * generate:
- *	call f
- *	proc=-1	normal call but no return
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
-  *	proc=3	normal call to C pointer (not Go func value)
- */
-void
-ginscall(Node *f, int proc)
-{
-	Prog *p;
-	Node reg, stk;
-	Node r1;
-	int32 extra;
-
-	if(f->type != T) {
-		extra = 0;
-		if(proc == 1 || proc == 2)
-			extra = 2 * widthptr;
-		setmaxarg(f->type, extra);
-	}
-
-	switch(proc) {
-	default:
-		fatal("ginscall: bad proc %d", proc);
-		break;
-
-	case 0:	// normal call
-	case -1:	// normal call but no return
-		if(f->op == ONAME && f->class == PFUNC) {
-			if(f == deferreturn) {
-				// Deferred calls will appear to be returning to
-				// the CALL deferreturn(SB) that we are about to emit.
-				// However, the stack trace code will show the line
-				// of the instruction byte before the return PC. 
-				// To avoid that being an unrelated instruction,
-				// insert an x86 NOP that we will have the right line number.
-				// x86 NOP 0x90 is really XCHG AX, AX; use that description
-				// because the NOP pseudo-instruction would be removed by
-				// the linker.
-				nodreg(&reg, types[TINT], REG_AX);
-				gins(AXCHGL, &reg, &reg);
-			}
-			p = gins(ACALL, N, f);
-			afunclit(&p->to, f);
-			if(proc == -1 || noreturn(p))
-				gins(AUNDEF, N, N);
-			break;
-		}
-		nodreg(&reg, types[tptr], REG_DX);
-		nodreg(&r1, types[tptr], REG_BX);
-		gmove(f, &reg);
-		reg.op = OINDREG;
-		gmove(&reg, &r1);
-		reg.op = OREGISTER;
-		gins(ACALL, &reg, &r1);
-		break;
-	
-	case 3:	// normal call of c function pointer
-		gins(ACALL, N, f);
-		break;
-
-	case 1:	// call in new proc (go)
-	case 2:	// deferred call (defer)
-		memset(&stk, 0, sizeof(stk));
-		stk.op = OINDREG;
-		stk.val.u.reg = REG_SP;
-		stk.xoffset = 0;
-
-		if(widthptr == 8) {
-			// size of arguments at 0(SP)
-			ginscon(AMOVQ, argsize(f->type), &stk);
-
-			// FuncVal* at 8(SP)
-			stk.xoffset = widthptr;
-			nodreg(&reg, types[TINT64], REG_AX);
-			gmove(f, &reg);
-			gins(AMOVQ, &reg, &stk);
-		} else {
-			// size of arguments at 0(SP)
-			ginscon(AMOVL, argsize(f->type), &stk);
-
-			// FuncVal* at 4(SP)
-			stk.xoffset = widthptr;
-			nodreg(&reg, types[TINT32], REG_AX);
-			gmove(f, &reg);
-			gins(AMOVL, &reg, &stk);
-		}
-
-		if(proc == 1)
-			ginscall(newproc, 0);
-		else {
-			if(!hasdefer)
-				fatal("hasdefer=0 but has defer");
-			ginscall(deferproc, 0);
-		}
-		if(proc == 2) {
-			nodreg(&reg, types[TINT32], REG_AX);
-			gins(ATESTL, &reg, &reg);
-			p = gbranch(AJEQ, T, +1);
-			cgen_ret(N);
-			patch(p, pc);
-		}
-		break;
-	}
-}
-
-/*
- * n is call to interface method.
- * generate res = n.
- */
-void
-cgen_callinter(Node *n, Node *res, int proc)
-{
-	Node *i, *f;
-	Node tmpi, nodi, nodo, nodr, nodsp;
-
-	i = n->left;
-	if(i->op != ODOTINTER)
-		fatal("cgen_callinter: not ODOTINTER %O", i->op);
-
-	f = i->right;		// field
-	if(f->op != ONAME)
-		fatal("cgen_callinter: not ONAME %O", f->op);
-
-	i = i->left;		// interface
-
-	if(!i->addable) {
-		tempname(&tmpi, i->type);
-		cgen(i, &tmpi);
-		i = &tmpi;
-	}
-
-	genlist(n->list);		// assign the args
-
-	// i is now addable, prepare an indirected
-	// register to hold its address.
-	igen(i, &nodi, res);		// REG = &inter
-
-	nodindreg(&nodsp, types[tptr], REG_SP);
-	nodsp.xoffset = 0;
-	if(proc != 0)
-		nodsp.xoffset += 2 * widthptr; // leave room for size & fn
-	nodi.type = types[tptr];
-	nodi.xoffset += widthptr;
-	cgen(&nodi, &nodsp);	// {0, 8(nacl), or 16}(SP) = 8(REG) -- i.data
-
-	regalloc(&nodo, types[tptr], res);
-	nodi.type = types[tptr];
-	nodi.xoffset -= widthptr;
-	cgen(&nodi, &nodo);	// REG = 0(REG) -- i.tab
-	regfree(&nodi);
-
-	regalloc(&nodr, types[tptr], &nodo);
-	if(n->left->xoffset == BADWIDTH)
-		fatal("cgen_callinter: badwidth");
-	cgen_checknil(&nodo); // in case offset is huge
-	nodo.op = OINDREG;
-	nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
-	if(proc == 0) {
-		// plain call: use direct c function pointer - more efficient
-		cgen(&nodo, &nodr);	// REG = 32+offset(REG) -- i.tab->fun[f]
-		proc = 3;
-	} else {
-		// go/defer. generate go func value.
-		gins(ALEAQ, &nodo, &nodr);	// REG = &(32+offset(REG)) -- i.tab->fun[f]
-	}
-
-	nodr.type = n->left->type;
-	ginscall(&nodr, proc);
-
-	regfree(&nodr);
-	regfree(&nodo);
-}
-
-/*
- * generate function call;
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
- */
-void
-cgen_call(Node *n, int proc)
-{
-	Type *t;
-	Node nod, afun;
-
-	if(n == N)
-		return;
-
-	if(n->left->ullman >= UINF) {
-		// if name involves a fn call
-		// precompute the address of the fn
-		tempname(&afun, types[tptr]);
-		cgen(n->left, &afun);
-	}
-
-	genlist(n->list);		// assign the args
-	t = n->left->type;
-
-	// call tempname pointer
-	if(n->left->ullman >= UINF) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, &afun);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call pointer
-	if(n->left->op != ONAME || n->left->class != PFUNC) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, n->left);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call direct
-	n->left->method = 1;
-	ginscall(n->left, proc);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = return value from call.
- */
-void
-cgen_callret(Node *n, Node *res)
-{
-	Node nod;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(t->etype == TPTR32 || t->etype == TPTR64)
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_callret: nil");
-
-	memset(&nod, 0, sizeof(nod));
-	nod.op = OINDREG;
-	nod.val.u.reg = REG_SP;
-	nod.addable = 1;
-
-	nod.xoffset = fp->width;
-	nod.type = fp->type;
-	cgen_as(res, &nod);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = &return value from call.
- */
-void
-cgen_aret(Node *n, Node *res)
-{
-	Node nod1, nod2;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(isptr[t->etype])
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_aret: nil");
-
-	memset(&nod1, 0, sizeof(nod1));
-	nod1.op = OINDREG;
-	nod1.val.u.reg = REG_SP;
-	nod1.addable = 1;
-
-	nod1.xoffset = fp->width;
-	nod1.type = fp->type;
-
-	if(res->op != OREGISTER) {
-		regalloc(&nod2, types[tptr], res);
-		gins(leaptr, &nod1, &nod2);
-		gins(movptr, &nod2, res);
-		regfree(&nod2);
-	} else
-		gins(leaptr, &nod1, res);
-}
-
-/*
- * generate return.
- * n->left is assignments to return values.
- */
-void
-cgen_ret(Node *n)
-{
-	Prog *p;
-
-	if(n != N)
-		genlist(n->list);		// copy out args
-	if(hasdefer)
-		ginscall(deferreturn, 0);
-	genlist(curfn->exit);
-	p = gins(ARET, N, N);
-	if(n != N && n->op == ORETJMP) {
-		p->to.type = TYPE_MEM;
-		p->to.name = NAME_EXTERN;
-		p->to.sym = linksym(n->left->sym);
-	}
-}
-
-/*
- * generate division.
- * generates one of:
- *	res = nl / nr
- *	res = nl % nr
- * according to op.
- */
-void
-dodiv(int op, Node *nl, Node *nr, Node *res)
-{
-	int a, check;
-	Node n3, n4;
-	Type *t, *t0;
-	Node ax, dx, ax1, n31, oldax, olddx;
-	Prog *p1, *p2;
-
-	// Have to be careful about handling
-	// most negative int divided by -1 correctly.
-	// The hardware will trap.
-	// Also the byte divide instruction needs AH,
-	// which we otherwise don't have to deal with.
-	// Easiest way to avoid for int8, int16: use int32.
-	// For int32 and int64, use explicit test.
-	// Could use int64 hw for int32.
-	t = nl->type;
-	t0 = t;
-	check = 0;
-	if(issigned[t->etype]) {
-		check = 1;
-		if(isconst(nl, CTINT) && mpgetfix(nl->val.u.xval) != -(1ULL<<(t->width*8-1)))
-			check = 0;
-		else if(isconst(nr, CTINT) && mpgetfix(nr->val.u.xval) != -1)
-			check = 0;
-	}
-	if(t->width < 4) {
-		if(issigned[t->etype])
-			t = types[TINT32];
-		else
-			t = types[TUINT32];
-		check = 0;
-	}
-	a = optoas(op, t);
-
-	regalloc(&n3, t0, N);
-	if(nl->ullman >= nr->ullman) {
-		savex(REG_AX, &ax, &oldax, res, t0);
-		cgen(nl, &ax);
-		regalloc(&ax, t0, &ax);	// mark ax live during cgen
-		cgen(nr, &n3);
-		regfree(&ax);
-	} else {
-		cgen(nr, &n3);
-		savex(REG_AX, &ax, &oldax, res, t0);
-		cgen(nl, &ax);
-	}
-	if(t != t0) {
-		// Convert
-		ax1 = ax;
-		n31 = n3;
-		ax.type = t;
-		n3.type = t;
-		gmove(&ax1, &ax);
-		gmove(&n31, &n3);
-	}
-
-	p2 = P;
-	if(nacl) {
-		// Native Client does not relay the divide-by-zero trap
-		// to the executing program, so we must insert a check
-		// for ourselves.
-		nodconst(&n4, t, 0);
-		gins(optoas(OCMP, t), &n3, &n4);
-		p1 = gbranch(optoas(ONE, t), T, +1);
-		if(panicdiv == N)
-			panicdiv = sysfunc("panicdivide");
-		ginscall(panicdiv, -1);
-		patch(p1, pc);
-	}
-	if(check) {
-		nodconst(&n4, t, -1);
-		gins(optoas(OCMP, t), &n3, &n4);
-		p1 = gbranch(optoas(ONE, t), T, +1);
-		if(op == ODIV) {
-			// a / (-1) is -a.
-			gins(optoas(OMINUS, t), N, &ax);
-			gmove(&ax, res);
-		} else {
-			// a % (-1) is 0.
-			nodconst(&n4, t, 0);
-			gmove(&n4, res);
-		}
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-	}
-	savex(REG_DX, &dx, &olddx, res, t);
-	if(!issigned[t->etype]) {
-		nodconst(&n4, t, 0);
-		gmove(&n4, &dx);
-	} else
-		gins(optoas(OEXTEND, t), N, N);
-	gins(a, &n3, N);
-	regfree(&n3);
-	if(op == ODIV)
-		gmove(&ax, res);
-	else
-		gmove(&dx, res);
-	restx(&dx, &olddx);
-	if(check)
-		patch(p2, pc);
-	restx(&ax, &oldax);
-}
-
-/*
- * register dr is one of the special ones (AX, CX, DI, SI, etc.).
- * we need to use it.  if it is already allocated as a temporary
- * (r > 1; can only happen if a routine like sgen passed a
- * special as cgen's res and then cgen used regalloc to reuse
- * it as its own temporary), then move it for now to another
- * register.  caller must call restx to move it back.
- * the move is not necessary if dr == res, because res is
- * known to be dead.
- */
-void
-savex(int dr, Node *x, Node *oldx, Node *res, Type *t)
-{
-	int r;
-
-	r = reg[dr];
-
-	// save current ax and dx if they are live
-	// and not the destination
-	memset(oldx, 0, sizeof *oldx);
-	nodreg(x, t, dr);
-	if(r > 1 && !samereg(x, res)) {
-		regalloc(oldx, types[TINT64], N);
-		x->type = types[TINT64];
-		gmove(x, oldx);
-		x->type = t;
-		oldx->ostk = r;	// squirrel away old r value
-		reg[dr] = 1;
-	}
-}
-
-void
-restx(Node *x, Node *oldx)
-{
-	if(oldx->op != 0) {
-		x->type = types[TINT64];
-		reg[x->val.u.reg] = oldx->ostk;
-		gmove(oldx, x);
-		regfree(oldx);
-	}
-}
-
-/*
- * generate division according to op, one of:
- *	res = nl / nr
- *	res = nl % nr
- */
-void
-cgen_div(int op, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n3;
-	int w, a;
-	Magic m;
-
-	if(nr->op != OLITERAL)
-		goto longdiv;
-	w = nl->type->width*8;
-
-	// Front end handled 32-bit division. We only need to handle 64-bit.
-	// try to do division by multiply by (2^w)/d
-	// see hacker's delight chapter 10
-	switch(simtype[nl->type->etype]) {
-	default:
-		goto longdiv;
-
-	case TUINT64:
-		m.w = w;
-		m.ud = mpgetfix(nr->val.u.xval);
-		umagic(&m);
-		if(m.bad)
-			break;
-		if(op == OMOD)
-			goto longmod;
-
-		cgenr(nl, &n1, N);
-		nodconst(&n2, nl->type, m.um);
-		regalloc(&n3, nl->type, res);
-		cgen_hmul(&n1, &n2, &n3);
-
-		if(m.ua) {
-			// need to add numerator accounting for overflow
-			gins(optoas(OADD, nl->type), &n1, &n3);
-			nodconst(&n2, nl->type, 1);
-			gins(optoas(ORROTC, nl->type), &n2, &n3);
-			nodconst(&n2, nl->type, m.s-1);
-			gins(optoas(ORSH, nl->type), &n2, &n3);
-		} else {
-			nodconst(&n2, nl->type, m.s);
-			gins(optoas(ORSH, nl->type), &n2, &n3);	// shift dx
-		}
-
-		gmove(&n3, res);
-		regfree(&n1);
-		regfree(&n3);
-		return;
-
-	case TINT64:
-		m.w = w;
-		m.sd = mpgetfix(nr->val.u.xval);
-		smagic(&m);
-		if(m.bad)
-			break;
-		if(op == OMOD)
-			goto longmod;
-
-		cgenr(nl, &n1, res);
-		nodconst(&n2, nl->type, m.sm);
-		regalloc(&n3, nl->type, N);
-		cgen_hmul(&n1, &n2, &n3);
-
-		if(m.sm < 0) {
-			// need to add numerator
-			gins(optoas(OADD, nl->type), &n1, &n3);
-		}
-
-		nodconst(&n2, nl->type, m.s);
-		gins(optoas(ORSH, nl->type), &n2, &n3);	// shift n3
-
-		nodconst(&n2, nl->type, w-1);
-		gins(optoas(ORSH, nl->type), &n2, &n1);	// -1 iff num is neg
-		gins(optoas(OSUB, nl->type), &n1, &n3);	// added
-
-		if(m.sd < 0) {
-			// this could probably be removed
-			// by factoring it into the multiplier
-			gins(optoas(OMINUS, nl->type), N, &n3);
-		}
-
-		gmove(&n3, res);
-		regfree(&n1);
-		regfree(&n3);
-		return;
-	}
-	goto longdiv;
-
-longdiv:
-	// division and mod using (slow) hardware instruction
-	dodiv(op, nl, nr, res);
-	return;
-
-longmod:
-	// mod using formula A%B = A-(A/B*B) but
-	// we know that there is a fast algorithm for A/B
-	regalloc(&n1, nl->type, res);
-	cgen(nl, &n1);
-	regalloc(&n2, nl->type, N);
-	cgen_div(ODIV, &n1, nr, &n2);
-	a = optoas(OMUL, nl->type);
-	if(w == 8) {
-		// use 2-operand 16-bit multiply
-		// because there is no 2-operand 8-bit multiply
-		a = AIMULW;
-	}
-	if(!smallintconst(nr)) {
-		regalloc(&n3, nl->type, N);
-		cgen(nr, &n3);
-		gins(a, &n3, &n2);
-		regfree(&n3);
-	} else
-		gins(a, nr, &n2);
-	gins(optoas(OSUB, nl->type), &n2, &n1);
-	gmove(&n1, res);
-	regfree(&n1);
-	regfree(&n2);
-}
-
-/*
- * generate high multiply:
- *   res = (nl*nr) >> width
- */
-void
-cgen_hmul(Node *nl, Node *nr, Node *res)
-{
-	Type *t;
-	int a;
-	Node n1, n2, ax, dx, *tmp;
-
-	t = nl->type;
-	a = optoas(OHMUL, t);
-	if(nl->ullman < nr->ullman) {
-		tmp = nl;
-		nl = nr;
-		nr = tmp;
-	}
-	cgenr(nl, &n1, res);
-	cgenr(nr, &n2, N);
-	nodreg(&ax, t, REG_AX);
-	gmove(&n1, &ax);
-	gins(a, &n2, N);
-	regfree(&n2);
-	regfree(&n1);
-
-	if(t->width == 1) {
-		// byte multiply behaves differently.
-		nodreg(&ax, t, REG_AH);
-		nodreg(&dx, t, REG_DX);
-		gmove(&ax, &dx);
-	}
-	nodreg(&dx, t, REG_DX);
-	gmove(&dx, res);
-}
-
-/*
- * generate shift according to op, one of:
- *	res = nl << nr
- *	res = nl >> nr
- */
-void
-cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n3, n4, n5, cx, oldcx;
-	int a, rcx;
-	Prog *p1;
-	uvlong sc;
-	Type *tcount;
-
-	a = optoas(op, nl->type);
-
-	if(nr->op == OLITERAL) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-		sc = mpgetfix(nr->val.u.xval);
-		if(sc >= nl->type->width*8) {
-			// large shift gets 2 shifts by width-1
-			nodconst(&n3, types[TUINT32], nl->type->width*8-1);
-			gins(a, &n3, &n1);
-			gins(a, &n3, &n1);
-		} else
-			gins(a, nr, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		goto ret;
-	}
-
-	if(nl->ullman >= UINF) {
-		tempname(&n4, nl->type);
-		cgen(nl, &n4);
-		nl = &n4;
-	}
-	if(nr->ullman >= UINF) {
-		tempname(&n5, nr->type);
-		cgen(nr, &n5);
-		nr = &n5;
-	}
-
-	rcx = reg[REG_CX];
-	nodreg(&n1, types[TUINT32], REG_CX);
-	
-	// Allow either uint32 or uint64 as shift type,
-	// to avoid unnecessary conversion from uint32 to uint64
-	// just to do the comparison.
-	tcount = types[simtype[nr->type->etype]];
-	if(tcount->etype < TUINT32)
-		tcount = types[TUINT32];
-
-	regalloc(&n1, nr->type, &n1);		// to hold the shift type in CX
-	regalloc(&n3, tcount, &n1);	// to clear high bits of CX
-
-	nodreg(&cx, types[TUINT64], REG_CX);
-	memset(&oldcx, 0, sizeof oldcx);
-	if(rcx > 0 && !samereg(&cx, res)) {
-		regalloc(&oldcx, types[TUINT64], N);
-		gmove(&cx, &oldcx);
-	}
-	cx.type = tcount;
-
-	if(samereg(&cx, res))
-		regalloc(&n2, nl->type, N);
-	else
-		regalloc(&n2, nl->type, res);
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &n2);
-		cgen(nr, &n1);
-		gmove(&n1, &n3);
-	} else {
-		cgen(nr, &n1);
-		gmove(&n1, &n3);
-		cgen(nl, &n2);
-	}
-	regfree(&n3);
-
-	// test and fix up large shifts
-	if(!bounded) {
-		nodconst(&n3, tcount, nl->type->width*8);
-		gins(optoas(OCMP, tcount), &n1, &n3);
-		p1 = gbranch(optoas(OLT, tcount), T, +1);
-		if(op == ORSH && issigned[nl->type->etype]) {
-			nodconst(&n3, types[TUINT32], nl->type->width*8-1);
-			gins(a, &n3, &n2);
-		} else {
-			nodconst(&n3, nl->type, 0);
-			gmove(&n3, &n2);
-		}
-		patch(p1, pc);
-	}
-
-	gins(a, &n1, &n2);
-
-	if(oldcx.op != 0) {
-		cx.type = types[TUINT64];
-		gmove(&oldcx, &cx);
-		regfree(&oldcx);
-	}
-
-	gmove(&n2, res);
-
-	regfree(&n1);
-	regfree(&n2);
-
-ret:
-	;
-}
-
-/*
- * generate byte multiply:
- *	res = nl * nr
- * there is no 2-operand byte multiply instruction so
- * we do a full-width multiplication and truncate afterwards.
- */
-void
-cgen_bmul(int op, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n1b, n2b, *tmp;
-	Type *t;
-	int a;
-
-	// largest ullman on left.
-	if(nl->ullman < nr->ullman) {
-		tmp = nl;
-		nl = nr;
-		nr = tmp;
-	}
-
-	// generate operands in "8-bit" registers.
-	regalloc(&n1b, nl->type, res);
-	cgen(nl, &n1b);
-	regalloc(&n2b, nr->type, N);
-	cgen(nr, &n2b);
-
-	// perform full-width multiplication.
-	t = types[TUINT64];
-	if(issigned[nl->type->etype])
-		t = types[TINT64];
-	nodreg(&n1, t, n1b.val.u.reg);
-	nodreg(&n2, t, n2b.val.u.reg);
-	a = optoas(op, t);
-	gins(a, &n2, &n1);
-
-	// truncate.
-	gmove(&n1, res);
-	regfree(&n1b);
-	regfree(&n2b);
-}
-
-void
-clearfat(Node *nl)
-{
-	int64 w, c, q;
-	Node n1, oldn1, ax, oldax, di, z;
-	Prog *p;
-
-	/* clear a fat object */
-	if(debug['g'])
-		dump("\nclearfat", nl);
-
-	w = nl->type->width;
-	// Avoid taking the address for simple enough types.
-	if(componentgen(N, nl))
-		return;
-
-	c = w % 8;	// bytes
-	q = w / 8;	// quads
-
-	if(q < 4) {
-		// Write sequence of MOV 0, off(base) instead of using STOSQ.
-		// The hope is that although the code will be slightly longer,
-		// the MOVs will have no dependencies and pipeline better
-		// than the unrolled STOSQ loop.
-		// NOTE: Must use agen, not igen, so that optimizer sees address
-		// being taken. We are not writing on field boundaries.
-		agenr(nl, &n1, N);
-		n1.op = OINDREG;
-		nodconst(&z, types[TUINT64], 0);
-		while(q-- > 0) {
-			n1.type = z.type;
-			gins(AMOVQ, &z, &n1);
-			n1.xoffset += 8;
-		}
-		if(c >= 4) {
-			nodconst(&z, types[TUINT32], 0);
-			n1.type = z.type;
-			gins(AMOVL, &z, &n1);
-			n1.xoffset += 4;
-			c -= 4;
-		}
-		nodconst(&z, types[TUINT8], 0);
-		while(c-- > 0) {
-			n1.type = z.type;
-			gins(AMOVB, &z, &n1);
-			n1.xoffset++;
-		}
-		regfree(&n1);
-		return;
-	}
-
-	savex(REG_DI, &n1, &oldn1, N, types[tptr]);
-	agen(nl, &n1);
-
-	savex(REG_AX, &ax, &oldax, N, types[tptr]);
-	gconreg(AMOVL, 0, REG_AX);
-
-	if(q > 128 || nacl) {
-		gconreg(movptr, q, REG_CX);
-		gins(AREP, N, N);	// repeat
-		gins(ASTOSQ, N, N);	// STOQ AL,*(DI)+
-	} else {
-		p = gins(ADUFFZERO, N, N);
-		p->to.type = TYPE_ADDR;
-		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-		// 2 and 128 = magic constants: see ../../runtime/asm_amd64.s
-		p->to.offset = 2*(128-q);
-	}
-
-	z = ax;
-	di = n1;
-	if(w >= 8 && c >= 4) {
-		di.op = OINDREG;
-		di.type = z.type = types[TINT64];
-		p = gins(AMOVQ, &z, &di);
-		p->to.scale = 1;
-		p->to.offset = c-8;
-	} else if(c >= 4) {
-		di.op = OINDREG;
-		di.type = z.type = types[TINT32];
-		p = gins(AMOVL, &z, &di);
-		if(c > 4) {
-			p = gins(AMOVL, &z, &di);
-			p->to.scale = 1;
-			p->to.offset = c-4;
-		}
-	} else
-	while(c > 0) {
-		gins(ASTOSB, N, N);	// STOB AL,*(DI)+
-		c--;
-	}
-
-	restx(&n1, &oldn1);
-	restx(&ax, &oldax);
-}
-
-// Called after regopt and peep have run.
-// Expand CHECKNIL pseudo-op into actual nil pointer check.
-void
-expandchecks(Prog *firstp)
-{
-	Prog *p, *p1, *p2;
-
-	for(p = firstp; p != P; p = p->link) {
-		if(p->as != ACHECKNIL)
-			continue;
-		if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
-			warnl(p->lineno, "generated nil check");
-		// check is
-		//	CMP arg, $0
-		//	JNE 2(PC) (likely)
-		//	MOV AX, 0
-		p1 = mal(sizeof *p1);
-		p2 = mal(sizeof *p2);
-		clearp(p1);
-		clearp(p2);
-		p1->link = p2;
-		p2->link = p->link;
-		p->link = p1;
-		p1->lineno = p->lineno;
-		p2->lineno = p->lineno;
-		p1->pc = 9999;
-		p2->pc = 9999;
-		p->as = cmpptr;
-		p->to.type = TYPE_CONST;
-		p->to.offset = 0;
-		p1->as = AJNE;
-		p1->from.type = TYPE_CONST;
-		p1->from.offset = 1; // likely
-		p1->to.type = TYPE_BRANCH;
-		p1->to.u.branch = p2->link;
-		// crash by write to memory address 0.
-		// if possible, since we know arg is 0, use 0(arg),
-		// which will be shorter to encode than plain 0.
-		p2->as = AMOVL;
-		p2->from.type = TYPE_REG;
-		p2->from.reg = REG_AX;
-		if(regtyp(&p->from)) {
-			p2->to.type = TYPE_MEM;
-			p2->to.reg = p->from.reg;
-		} else {
-			p2->to.type = TYPE_MEM;
-			p2->to.reg = REG_NONE;
-		}
-		p2->to.offset = 0;
-	}
-}
diff --git a/src/cmd/new6g/ggen.go b/src/cmd/6g/ggen.go
similarity index 100%
rename from src/cmd/new6g/ggen.go
rename to src/cmd/6g/ggen.go
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
deleted file mode 100644
index 55d3425..0000000
--- a/src/cmd/6g/gsubr.c
+++ /dev/null
@@ -1,1737 +0,0 @@
-// Derived from Inferno utils/6c/txt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.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 "gg.h"
-#include "../../runtime/funcdata.h"
-
-// TODO(rsc): Can make this bigger if we move
-// the text segment up higher in 6l for all GOOS.
-// At the same time, can raise StackBig in ../../runtime/stack.h.
-vlong unmappedzero = 4096;
-static	int	resvd[] =
-{
-	REG_DI,	// for movstring
-	REG_SI,	// for movstring
-
-	REG_AX,	// for divide
-	REG_CX,	// for shift
-	REG_DX,	// for divide
-	REG_SP,	// for stack
-};
-
-void
-ginit(void)
-{
-	int i;
-
-	for(i=0; i<nelem(reg); i++)
-		reg[i] = 1;
-	for(i=REG_AX; i<=REG_R15; i++)
-		reg[i] = 0;
-	for(i=REG_X0; i<=REG_X15; i++)
-		reg[i] = 0;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]++;
-	
-	if(nacl) {
-		reg[REG_BP]++;
-		reg[REG_R15]++;
-	} else if(framepointer_enabled) {
-		// BP is part of the calling convention of framepointer_enabled.
-		reg[REG_BP]++;
-	}
-}
-
-void
-gclean(void)
-{
-	int i;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]--;
-	if(nacl) {
-		reg[REG_BP]--;
-		reg[REG_R15]--;
-	} else if(framepointer_enabled) {
-		reg[REG_BP]--;
-	}
-
-
-	for(i=REG_AX; i<=REG_R15; i++)
-		if(reg[i])
-			yyerror("reg %R left allocated\n", i);
-	for(i=REG_X0; i<=REG_X15; i++)
-		if(reg[i])
-			yyerror("reg %R left allocated\n", i);
-}
-
-int
-anyregalloc(void)
-{
-	int i, j;
-
-	for(i=REG_AX; i<=REG_R15; i++) {
-		if(reg[i] == 0)
-			goto ok;
-		for(j=0; j<nelem(resvd); j++)
-			if(resvd[j] == i)
-				goto ok;
-		return 1;
-	ok:;
-	}
-	return 0;
-}
-
-static	uintptr	regpc[REG_R15+1 - REG_AX];
-
-/*
- * allocate register of type t, leave in n.
- * if o != N, o is desired fixed register.
- * caller must regfree(n).
- */
-void
-regalloc(Node *n, Type *t, Node *o)
-{
-	int i, et;
-
-	if(t == T)
-		fatal("regalloc: t nil");
-	et = simtype[t->etype];
-
-	switch(et) {
-	case TINT8:
-	case TUINT8:
-	case TINT16:
-	case TUINT16:
-	case TINT32:
-	case TUINT32:
-	case TINT64:
-	case TUINT64:
-	case TPTR32:
-	case TPTR64:
-	case TBOOL:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REG_AX && i <= REG_R15)
-				goto out;
-		}
-		for(i=REG_AX; i<=REG_R15; i++)
-			if(reg[i] == 0) {
-				regpc[i-REG_AX] = (uintptr)getcallerpc(&n);
-				goto out;
-			}
-
-		flusherrors();
-		for(i=0; i+REG_AX<=REG_R15; i++)
-			print("%d %p\n", i, regpc[i]);
-		fatal("out of fixed registers");
-
-	case TFLOAT32:
-	case TFLOAT64:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REG_X0 && i <= REG_X15)
-				goto out;
-		}
-		for(i=REG_X0; i<=REG_X15; i++)
-			if(reg[i] == 0)
-				goto out;
-		fatal("out of floating registers");
-
-	case TCOMPLEX64:
-	case TCOMPLEX128:
-		tempname(n, t);
-		return;
-	}
-	fatal("regalloc: unknown type %T", t);
-	return;
-
-out:
-	reg[i]++;
-	nodreg(n, t, i);
-}
-
-void
-regfree(Node *n)
-{
-	int i;
-
-	if(n->op == ONAME)
-		return;
-	if(n->op != OREGISTER && n->op != OINDREG)
-		fatal("regfree: not a register");
-	i = n->val.u.reg;
-	if(i == REG_SP)
-		return;
-	if(i < 0 || i >= nelem(reg))
-		fatal("regfree: reg out of range");
-	if(reg[i] <= 0)
-		fatal("regfree: reg not allocated");
-	reg[i]--;
-	if(reg[i] == 0 && REG_AX <= i && i <= REG_R15)
-		regpc[i - REG_AX] = 0;
-}
-
-/*
- * generate
- *	as $c, reg
- */
-void
-gconreg(int as, vlong c, int reg)
-{
-	Node nr;
-
-	switch(as) {
-	case AADDL:
-	case AMOVL:
-	case ALEAL:
-		nodreg(&nr, types[TINT32], reg);
-		break;
-	default:
-		nodreg(&nr, types[TINT64], reg);
-	}
-
-	ginscon(as, c, &nr);
-}
-
-/*
- * generate
- *	as $c, n
- */
-void
-ginscon(int as, vlong c, Node *n2)
-{
-	Node n1, ntmp;
-
-	switch(as) {
-	case AADDL:
-	case AMOVL:
-	case ALEAL:
-		nodconst(&n1, types[TINT32], c);
-		break;
-	default:
-		nodconst(&n1, types[TINT64], c);
-	}
-
-	if(as != AMOVQ && (c < -(1LL<<31) || c >= 1LL<<31)) {
-		// cannot have 64-bit immediate in ADD, etc.
-		// instead, MOV into register first.
-		regalloc(&ntmp, types[TINT64], N);
-		gins(AMOVQ, &n1, &ntmp);
-		gins(as, &ntmp, n2);
-		regfree(&ntmp);
-		return;
-	}
-	gins(as, &n1, n2);
-}
-
-#define	CASE(a,b)	(((a)<<16)|((b)<<0))
-/*c2go int CASE(int, int); */
-
-/*
- * set up nodes representing 2^63
- */
-Node bigi;
-Node bigf;
-
-void
-bignodes(void)
-{
-	static int did;
-
-	if(did)
-		return;
-	did = 1;
-
-	nodconst(&bigi, types[TUINT64], 1);
-	mpshiftfix(bigi.val.u.xval, 63);
-
-	bigf = bigi;
-	bigf.type = types[TFLOAT64];
-	bigf.val.ctype = CTFLT;
-	bigf.val.u.fval = mal(sizeof *bigf.val.u.fval);
-	mpmovefixflt(bigf.val.u.fval, bigi.val.u.xval);
-}
-
-/*
- * generate move:
- *	t = f
- * hard part is conversions.
- */
-void
-gmove(Node *f, Node *t)
-{
-	int a, ft, tt;
-	Type *cvt;
-	Node r1, r2, r3, r4, zero, one, con;
-	Prog *p1, *p2;
-
-	if(debug['M'])
-		print("gmove %lN -> %lN\n", f, t);
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-
-	if(iscomplex[ft] || iscomplex[tt]) {
-		complexmove(f, t);
-		return;
-	}
-
-	// cannot have two memory operands
-	if(ismem(f) && ismem(t))
-		goto hard;
-
-	// convert constant to desired type
-	if(f->op == OLITERAL) {
-		convconst(&con, t->type, &f->val);
-		f = &con;
-		ft = tt;	// so big switch will choose a simple mov
-
-		// some constants can't move directly to memory.
-		if(ismem(t)) {
-			// float constants come from memory.
-			if(isfloat[tt])
-				goto hard;
-
-			// 64-bit immediates are really 32-bit sign-extended
-			// unless moving into a register.
-			if(isint[tt]) {
-				if(mpcmpfixfix(con.val.u.xval, minintval[TINT32]) < 0)
-					goto hard;
-				if(mpcmpfixfix(con.val.u.xval, maxintval[TINT32]) > 0)
-					goto hard;
-			}
-		}
-	}
-
-	// value -> value copy, only one memory operand.
-	// figure out the instruction to use.
-	// break out of switch for one-instruction gins.
-	// goto rdst for "destination must be register".
-	// goto hard for "convert to cvt type first".
-	// otherwise handle and return.
-
-	switch(CASE(ft, tt)) {
-	default:
-		fatal("gmove %lT -> %lT", f->type, t->type);
-
-	/*
-	 * integer copy and truncate
-	 */
-	case CASE(TINT8, TINT8):	// same size
-	case CASE(TINT8, TUINT8):
-	case CASE(TUINT8, TINT8):
-	case CASE(TUINT8, TUINT8):
-	case CASE(TINT16, TINT8):	// truncate
-	case CASE(TUINT16, TINT8):
-	case CASE(TINT32, TINT8):
-	case CASE(TUINT32, TINT8):
-	case CASE(TINT64, TINT8):
-	case CASE(TUINT64, TINT8):
-	case CASE(TINT16, TUINT8):
-	case CASE(TUINT16, TUINT8):
-	case CASE(TINT32, TUINT8):
-	case CASE(TUINT32, TUINT8):
-	case CASE(TINT64, TUINT8):
-	case CASE(TUINT64, TUINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(TINT16, TINT16):	// same size
-	case CASE(TINT16, TUINT16):
-	case CASE(TUINT16, TINT16):
-	case CASE(TUINT16, TUINT16):
-	case CASE(TINT32, TINT16):	// truncate
-	case CASE(TUINT32, TINT16):
-	case CASE(TINT64, TINT16):
-	case CASE(TUINT64, TINT16):
-	case CASE(TINT32, TUINT16):
-	case CASE(TUINT32, TUINT16):
-	case CASE(TINT64, TUINT16):
-	case CASE(TUINT64, TUINT16):
-		a = AMOVW;
-		break;
-
-	case CASE(TINT32, TINT32):	// same size
-	case CASE(TINT32, TUINT32):
-	case CASE(TUINT32, TINT32):
-	case CASE(TUINT32, TUINT32):
-		a = AMOVL;
-		break;
-
-	case CASE(TINT64, TINT32):	// truncate
-	case CASE(TUINT64, TINT32):
-	case CASE(TINT64, TUINT32):
-	case CASE(TUINT64, TUINT32):
-		a = AMOVQL;
-		break;
-
-	case CASE(TINT64, TINT64):	// same size
-	case CASE(TINT64, TUINT64):
-	case CASE(TUINT64, TINT64):
-	case CASE(TUINT64, TUINT64):
-		a = AMOVQ;
-		break;
-
-	/*
-	 * integer up-conversions
-	 */
-	case CASE(TINT8, TINT16):	// sign extend int8
-	case CASE(TINT8, TUINT16):
-		a = AMOVBWSX;
-		goto rdst;
-	case CASE(TINT8, TINT32):
-	case CASE(TINT8, TUINT32):
-		a = AMOVBLSX;
-		goto rdst;
-	case CASE(TINT8, TINT64):
-	case CASE(TINT8, TUINT64):
-		a = AMOVBQSX;
-		goto rdst;
-
-	case CASE(TUINT8, TINT16):	// zero extend uint8
-	case CASE(TUINT8, TUINT16):
-		a = AMOVBWZX;
-		goto rdst;
-	case CASE(TUINT8, TINT32):
-	case CASE(TUINT8, TUINT32):
-		a = AMOVBLZX;
-		goto rdst;
-	case CASE(TUINT8, TINT64):
-	case CASE(TUINT8, TUINT64):
-		a = AMOVBQZX;
-		goto rdst;
-
-	case CASE(TINT16, TINT32):	// sign extend int16
-	case CASE(TINT16, TUINT32):
-		a = AMOVWLSX;
-		goto rdst;
-	case CASE(TINT16, TINT64):
-	case CASE(TINT16, TUINT64):
-		a = AMOVWQSX;
-		goto rdst;
-
-	case CASE(TUINT16, TINT32):	// zero extend uint16
-	case CASE(TUINT16, TUINT32):
-		a = AMOVWLZX;
-		goto rdst;
-	case CASE(TUINT16, TINT64):
-	case CASE(TUINT16, TUINT64):
-		a = AMOVWQZX;
-		goto rdst;
-
-	case CASE(TINT32, TINT64):	// sign extend int32
-	case CASE(TINT32, TUINT64):
-		a = AMOVLQSX;
-		goto rdst;
-
-	case CASE(TUINT32, TINT64):	// zero extend uint32
-	case CASE(TUINT32, TUINT64):
-		// AMOVL into a register zeros the top of the register,
-		// so this is not always necessary, but if we rely on AMOVL
-		// the optimizer is almost certain to screw with us.
-		a = AMOVLQZX;
-		goto rdst;
-
-	/*
-	* float to integer
-	*/
-	case CASE(TFLOAT32, TINT32):
-		a = ACVTTSS2SL;
-		goto rdst;
-
-	case CASE(TFLOAT64, TINT32):
-		a = ACVTTSD2SL;
-		goto rdst;
-
-	case CASE(TFLOAT32, TINT64):
-		a = ACVTTSS2SQ;
-		goto rdst;
-
-	case CASE(TFLOAT64, TINT64):
-		a = ACVTTSD2SQ;
-		goto rdst;
-
-	case CASE(TFLOAT32, TINT16):
-	case CASE(TFLOAT32, TINT8):
-	case CASE(TFLOAT32, TUINT16):
-	case CASE(TFLOAT32, TUINT8):
-	case CASE(TFLOAT64, TINT16):
-	case CASE(TFLOAT64, TINT8):
-	case CASE(TFLOAT64, TUINT16):
-	case CASE(TFLOAT64, TUINT8):
-		// convert via int32.
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TFLOAT32, TUINT32):
-	case CASE(TFLOAT64, TUINT32):
-		// convert via int64.
-		cvt = types[TINT64];
-		goto hard;
-
-	case CASE(TFLOAT32, TUINT64):
-	case CASE(TFLOAT64, TUINT64):
-		// algorithm is:
-		//	if small enough, use native float64 -> int64 conversion.
-		//	otherwise, subtract 2^63, convert, and add it back.
-		a = ACVTTSS2SQ;
-		if(ft == TFLOAT64)
-			a = ACVTTSD2SQ;
-		bignodes();
-		regalloc(&r1, types[ft], N);
-		regalloc(&r2, types[tt], t);
-		regalloc(&r3, types[ft], N);
-		regalloc(&r4, types[tt], N);
-		gins(optoas(OAS, f->type), f, &r1);
-		gins(optoas(OCMP, f->type), &bigf, &r1);
-		p1 = gbranch(optoas(OLE, f->type), T, +1);
-		gins(a, &r1, &r2);
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		gins(optoas(OAS, f->type), &bigf, &r3);
-		gins(optoas(OSUB, f->type), &r3, &r1);
-		gins(a, &r1, &r2);
-		gins(AMOVQ, &bigi, &r4);
-		gins(AXORQ, &r4, &r2);
-		patch(p2, pc);
-		gmove(&r2, t);
-		regfree(&r4);
-		regfree(&r3);
-		regfree(&r2);
-		regfree(&r1);
-		return;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT32, TFLOAT32):
-		a = ACVTSL2SS;
-		goto rdst;
-
-
-	case CASE(TINT32, TFLOAT64):
-		a = ACVTSL2SD;
-		goto rdst;
-
-	case CASE(TINT64, TFLOAT32):
-		a = ACVTSQ2SS;
-		goto rdst;
-
-	case CASE(TINT64, TFLOAT64):
-		a = ACVTSQ2SD;
-		goto rdst;
-
-	case CASE(TINT16, TFLOAT32):
-	case CASE(TINT16, TFLOAT64):
-	case CASE(TINT8, TFLOAT32):
-	case CASE(TINT8, TFLOAT64):
-	case CASE(TUINT16, TFLOAT32):
-	case CASE(TUINT16, TFLOAT64):
-	case CASE(TUINT8, TFLOAT32):
-	case CASE(TUINT8, TFLOAT64):
-		// convert via int32
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT32, TFLOAT32):
-	case CASE(TUINT32, TFLOAT64):
-		// convert via int64.
-		cvt = types[TINT64];
-		goto hard;
-
-	case CASE(TUINT64, TFLOAT32):
-	case CASE(TUINT64, TFLOAT64):
-		// algorithm is:
-		//	if small enough, use native int64 -> uint64 conversion.
-		//	otherwise, halve (rounding to odd?), convert, and double.
-		a = ACVTSQ2SS;
-		if(tt == TFLOAT64)
-			a = ACVTSQ2SD;
-		nodconst(&zero, types[TUINT64], 0);
-		nodconst(&one, types[TUINT64], 1);
-		regalloc(&r1, f->type, f);
-		regalloc(&r2, t->type, t);
-		regalloc(&r3, f->type, N);
-		regalloc(&r4, f->type, N);
-		gmove(f, &r1);
-		gins(ACMPQ, &r1, &zero);
-		p1 = gbranch(AJLT, T, +1);
-		gins(a, &r1, &r2);
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		gmove(&r1, &r3);
-		gins(ASHRQ, &one, &r3);
-		gmove(&r1, &r4);
-		gins(AANDL, &one, &r4);
-		gins(AORQ, &r4, &r3);
-		gins(a, &r3, &r2);
-		gins(optoas(OADD, t->type), &r2, &r2);
-		patch(p2, pc);
-		gmove(&r2, t);
-		regfree(&r4);
-		regfree(&r3);
-		regfree(&r2);
-		regfree(&r1);
-		return;
-
-	/*
-	 * float to float
-	 */
-	case CASE(TFLOAT32, TFLOAT32):
-		a = AMOVSS;
-		break;
-
-	case CASE(TFLOAT64, TFLOAT64):
-		a = AMOVSD;
-		break;
-
-	case CASE(TFLOAT32, TFLOAT64):
-		a = ACVTSS2SD;
-		goto rdst;
-
-	case CASE(TFLOAT64, TFLOAT32):
-		a = ACVTSD2SS;
-		goto rdst;
-	}
-
-	gins(a, f, t);
-	return;
-
-rdst:
-	// requires register destination
-	regalloc(&r1, t->type, t);
-	gins(a, f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-}
-
-int
-samaddr(Node *f, Node *t)
-{
-
-	if(f->op != t->op)
-		return 0;
-
-	switch(f->op) {
-	case OREGISTER:
-		if(f->val.u.reg != t->val.u.reg)
-			break;
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * generate one instruction:
- *	as f, t
- */
-Prog*
-gins(int as, Node *f, Node *t)
-{
-//	Node nod;
-	int32 w;
-	Prog *p;
-	Addr af, at;
-
-//	if(f != N && f->op == OINDEX) {
-//		regalloc(&nod, &regnode, Z);
-//		v = constnode.vconst;
-//		cgen(f->right, &nod);
-//		constnode.vconst = v;
-//		idx.reg = nod.reg;
-//		regfree(&nod);
-//	}
-//	if(t != N && t->op == OINDEX) {
-//		regalloc(&nod, &regnode, Z);
-//		v = constnode.vconst;
-//		cgen(t->right, &nod);
-//		constnode.vconst = v;
-//		idx.reg = nod.reg;
-//		regfree(&nod);
-//	}
-
-	switch(as) {
-	case AMOVB:
-	case AMOVW:
-	case AMOVL:
-	case AMOVQ:
-	case AMOVSS:
-	case AMOVSD:
-		if(f != N && t != N && samaddr(f, t))
-			return nil;
-		break;
-	
-	case ALEAQ:
-		if(f != N && isconst(f, CTNIL)) {
-			fatal("gins LEAQ nil %T", f->type);
-		}
-		break;
-	}
-
-	memset(&af, 0, sizeof af);
-	memset(&at, 0, sizeof at);
-	if(f != N)
-		naddr(f, &af, 1);
-	if(t != N)
-		naddr(t, &at, 1);
-	p = prog(as);
-	if(f != N)
-		p->from = af;
-	if(t != N)
-		p->to = at;
-	if(debug['g'])
-		print("%P\n", p);
-
-	w = 0;
-	switch(as) {
-	case AMOVB:
-		w = 1;
-		break;
-	case AMOVW:
-		w = 2;
-		break;
-	case AMOVL:
-		w = 4;
-		break;
-	case AMOVQ:
-		w = 8;
-		break;
-	}
-	if(w != 0 && ((f != N && af.width < w) || (t != N && at.width > w))) {
-		dump("f", f);
-		dump("t", t);
-		fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
-	}
-	if(p->to.type == TYPE_ADDR && w > 0)
-		fatal("bad use of addr: %P", p);
-
-	return p;
-}
-
-void
-fixlargeoffset(Node *n)
-{
-	Node a;
-
-	if(n == N)
-		return;
-	if(n->op != OINDREG)
-		return;
-	if(n->val.u.reg == REG_SP) // stack offset cannot be large
-		return;
-	if(n->xoffset != (int32)n->xoffset) {
-		// offset too large, add to register instead.
-		a = *n;
-		a.op = OREGISTER;
-		a.type = types[tptr];
-		a.xoffset = 0;
-		cgen_checknil(&a);
-		ginscon(optoas(OADD, types[tptr]), n->xoffset, &a);
-		n->xoffset = 0;
-	}
-}
-
-/*
- * return Axxx for Oxxx on type t.
- */
-int
-optoas(int op, Type *t)
-{
-	int a;
-
-	if(t == T)
-		fatal("optoas: t is nil");
-
-	a = AXXX;
-	switch(CASE(op, simtype[t->etype])) {
-	default:
-		fatal("optoas: no entry %O-%T", op, t);
-		break;
-
-	case CASE(OADDR, TPTR32):
-		a = ALEAL;
-		break;
-
-	case CASE(OADDR, TPTR64):
-		a = ALEAQ;
-		break;
-
-	case CASE(OEQ, TBOOL):
-	case CASE(OEQ, TINT8):
-	case CASE(OEQ, TUINT8):
-	case CASE(OEQ, TINT16):
-	case CASE(OEQ, TUINT16):
-	case CASE(OEQ, TINT32):
-	case CASE(OEQ, TUINT32):
-	case CASE(OEQ, TINT64):
-	case CASE(OEQ, TUINT64):
-	case CASE(OEQ, TPTR32):
-	case CASE(OEQ, TPTR64):
-	case CASE(OEQ, TFLOAT32):
-	case CASE(OEQ, TFLOAT64):
-		a = AJEQ;
-		break;
-
-	case CASE(ONE, TBOOL):
-	case CASE(ONE, TINT8):
-	case CASE(ONE, TUINT8):
-	case CASE(ONE, TINT16):
-	case CASE(ONE, TUINT16):
-	case CASE(ONE, TINT32):
-	case CASE(ONE, TUINT32):
-	case CASE(ONE, TINT64):
-	case CASE(ONE, TUINT64):
-	case CASE(ONE, TPTR32):
-	case CASE(ONE, TPTR64):
-	case CASE(ONE, TFLOAT32):
-	case CASE(ONE, TFLOAT64):
-		a = AJNE;
-		break;
-
-	case CASE(OLT, TINT8):
-	case CASE(OLT, TINT16):
-	case CASE(OLT, TINT32):
-	case CASE(OLT, TINT64):
-		a = AJLT;
-		break;
-
-	case CASE(OLT, TUINT8):
-	case CASE(OLT, TUINT16):
-	case CASE(OLT, TUINT32):
-	case CASE(OLT, TUINT64):
-		a = AJCS;
-		break;
-
-	case CASE(OLE, TINT8):
-	case CASE(OLE, TINT16):
-	case CASE(OLE, TINT32):
-	case CASE(OLE, TINT64):
-		a = AJLE;
-		break;
-
-	case CASE(OLE, TUINT8):
-	case CASE(OLE, TUINT16):
-	case CASE(OLE, TUINT32):
-	case CASE(OLE, TUINT64):
-		a = AJLS;
-		break;
-
-	case CASE(OGT, TINT8):
-	case CASE(OGT, TINT16):
-	case CASE(OGT, TINT32):
-	case CASE(OGT, TINT64):
-		a = AJGT;
-		break;
-
-	case CASE(OGT, TUINT8):
-	case CASE(OGT, TUINT16):
-	case CASE(OGT, TUINT32):
-	case CASE(OGT, TUINT64):
-	case CASE(OLT, TFLOAT32):
-	case CASE(OLT, TFLOAT64):
-		a = AJHI;
-		break;
-
-	case CASE(OGE, TINT8):
-	case CASE(OGE, TINT16):
-	case CASE(OGE, TINT32):
-	case CASE(OGE, TINT64):
-		a = AJGE;
-		break;
-
-	case CASE(OGE, TUINT8):
-	case CASE(OGE, TUINT16):
-	case CASE(OGE, TUINT32):
-	case CASE(OGE, TUINT64):
-	case CASE(OLE, TFLOAT32):
-	case CASE(OLE, TFLOAT64):
-		a = AJCC;
-		break;
-
-	case CASE(OCMP, TBOOL):
-	case CASE(OCMP, TINT8):
-	case CASE(OCMP, TUINT8):
-		a = ACMPB;
-		break;
-
-	case CASE(OCMP, TINT16):
-	case CASE(OCMP, TUINT16):
-		a = ACMPW;
-		break;
-
-	case CASE(OCMP, TINT32):
-	case CASE(OCMP, TUINT32):
-	case CASE(OCMP, TPTR32):
-		a = ACMPL;
-		break;
-
-	case CASE(OCMP, TINT64):
-	case CASE(OCMP, TUINT64):
-	case CASE(OCMP, TPTR64):
-		a = ACMPQ;
-		break;
-
-	case CASE(OCMP, TFLOAT32):
-		a = AUCOMISS;
-		break;
-
-	case CASE(OCMP, TFLOAT64):
-		a = AUCOMISD;
-		break;
-
-	case CASE(OAS, TBOOL):
-	case CASE(OAS, TINT8):
-	case CASE(OAS, TUINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(OAS, TINT16):
-	case CASE(OAS, TUINT16):
-		a = AMOVW;
-		break;
-
-	case CASE(OAS, TINT32):
-	case CASE(OAS, TUINT32):
-	case CASE(OAS, TPTR32):
-		a = AMOVL;
-		break;
-
-	case CASE(OAS, TINT64):
-	case CASE(OAS, TUINT64):
-	case CASE(OAS, TPTR64):
-		a = AMOVQ;
-		break;
-
-	case CASE(OAS, TFLOAT32):
-		a = AMOVSS;
-		break;
-
-	case CASE(OAS, TFLOAT64):
-		a = AMOVSD;
-		break;
-
-	case CASE(OADD, TINT8):
-	case CASE(OADD, TUINT8):
-		a = AADDB;
-		break;
-
-	case CASE(OADD, TINT16):
-	case CASE(OADD, TUINT16):
-		a = AADDW;
-		break;
-
-	case CASE(OADD, TINT32):
-	case CASE(OADD, TUINT32):
-	case CASE(OADD, TPTR32):
-		a = AADDL;
-		break;
-
-	case CASE(OADD, TINT64):
-	case CASE(OADD, TUINT64):
-	case CASE(OADD, TPTR64):
-		a = AADDQ;
-		break;
-
-	case CASE(OADD, TFLOAT32):
-		a = AADDSS;
-		break;
-
-	case CASE(OADD, TFLOAT64):
-		a = AADDSD;
-		break;
-
-	case CASE(OSUB, TINT8):
-	case CASE(OSUB, TUINT8):
-		a = ASUBB;
-		break;
-
-	case CASE(OSUB, TINT16):
-	case CASE(OSUB, TUINT16):
-		a = ASUBW;
-		break;
-
-	case CASE(OSUB, TINT32):
-	case CASE(OSUB, TUINT32):
-	case CASE(OSUB, TPTR32):
-		a = ASUBL;
-		break;
-
-	case CASE(OSUB, TINT64):
-	case CASE(OSUB, TUINT64):
-	case CASE(OSUB, TPTR64):
-		a = ASUBQ;
-		break;
-
-	case CASE(OSUB, TFLOAT32):
-		a = ASUBSS;
-		break;
-
-	case CASE(OSUB, TFLOAT64):
-		a = ASUBSD;
-		break;
-
-	case CASE(OINC, TINT8):
-	case CASE(OINC, TUINT8):
-		a = AINCB;
-		break;
-
-	case CASE(OINC, TINT16):
-	case CASE(OINC, TUINT16):
-		a = AINCW;
-		break;
-
-	case CASE(OINC, TINT32):
-	case CASE(OINC, TUINT32):
-	case CASE(OINC, TPTR32):
-		a = AINCL;
-		break;
-
-	case CASE(OINC, TINT64):
-	case CASE(OINC, TUINT64):
-	case CASE(OINC, TPTR64):
-		a = AINCQ;
-		break;
-
-	case CASE(ODEC, TINT8):
-	case CASE(ODEC, TUINT8):
-		a = ADECB;
-		break;
-
-	case CASE(ODEC, TINT16):
-	case CASE(ODEC, TUINT16):
-		a = ADECW;
-		break;
-
-	case CASE(ODEC, TINT32):
-	case CASE(ODEC, TUINT32):
-	case CASE(ODEC, TPTR32):
-		a = ADECL;
-		break;
-
-	case CASE(ODEC, TINT64):
-	case CASE(ODEC, TUINT64):
-	case CASE(ODEC, TPTR64):
-		a = ADECQ;
-		break;
-
-	case CASE(OMINUS, TINT8):
-	case CASE(OMINUS, TUINT8):
-		a = ANEGB;
-		break;
-
-	case CASE(OMINUS, TINT16):
-	case CASE(OMINUS, TUINT16):
-		a = ANEGW;
-		break;
-
-	case CASE(OMINUS, TINT32):
-	case CASE(OMINUS, TUINT32):
-	case CASE(OMINUS, TPTR32):
-		a = ANEGL;
-		break;
-
-	case CASE(OMINUS, TINT64):
-	case CASE(OMINUS, TUINT64):
-	case CASE(OMINUS, TPTR64):
-		a = ANEGQ;
-		break;
-
-	case CASE(OAND, TINT8):
-	case CASE(OAND, TUINT8):
-		a = AANDB;
-		break;
-
-	case CASE(OAND, TINT16):
-	case CASE(OAND, TUINT16):
-		a = AANDW;
-		break;
-
-	case CASE(OAND, TINT32):
-	case CASE(OAND, TUINT32):
-	case CASE(OAND, TPTR32):
-		a = AANDL;
-		break;
-
-	case CASE(OAND, TINT64):
-	case CASE(OAND, TUINT64):
-	case CASE(OAND, TPTR64):
-		a = AANDQ;
-		break;
-
-	case CASE(OOR, TINT8):
-	case CASE(OOR, TUINT8):
-		a = AORB;
-		break;
-
-	case CASE(OOR, TINT16):
-	case CASE(OOR, TUINT16):
-		a = AORW;
-		break;
-
-	case CASE(OOR, TINT32):
-	case CASE(OOR, TUINT32):
-	case CASE(OOR, TPTR32):
-		a = AORL;
-		break;
-
-	case CASE(OOR, TINT64):
-	case CASE(OOR, TUINT64):
-	case CASE(OOR, TPTR64):
-		a = AORQ;
-		break;
-
-	case CASE(OXOR, TINT8):
-	case CASE(OXOR, TUINT8):
-		a = AXORB;
-		break;
-
-	case CASE(OXOR, TINT16):
-	case CASE(OXOR, TUINT16):
-		a = AXORW;
-		break;
-
-	case CASE(OXOR, TINT32):
-	case CASE(OXOR, TUINT32):
-	case CASE(OXOR, TPTR32):
-		a = AXORL;
-		break;
-
-	case CASE(OXOR, TINT64):
-	case CASE(OXOR, TUINT64):
-	case CASE(OXOR, TPTR64):
-		a = AXORQ;
-		break;
-
-	case CASE(OLROT, TINT8):
-	case CASE(OLROT, TUINT8):
-		a = AROLB;
-		break;
-
-	case CASE(OLROT, TINT16):
-	case CASE(OLROT, TUINT16):
-		a = AROLW;
-		break;
-
-	case CASE(OLROT, TINT32):
-	case CASE(OLROT, TUINT32):
-	case CASE(OLROT, TPTR32):
-		a = AROLL;
-		break;
-
-	case CASE(OLROT, TINT64):
-	case CASE(OLROT, TUINT64):
-	case CASE(OLROT, TPTR64):
-		a = AROLQ;
-		break;
-
-	case CASE(OLSH, TINT8):
-	case CASE(OLSH, TUINT8):
-		a = ASHLB;
-		break;
-
-	case CASE(OLSH, TINT16):
-	case CASE(OLSH, TUINT16):
-		a = ASHLW;
-		break;
-
-	case CASE(OLSH, TINT32):
-	case CASE(OLSH, TUINT32):
-	case CASE(OLSH, TPTR32):
-		a = ASHLL;
-		break;
-
-	case CASE(OLSH, TINT64):
-	case CASE(OLSH, TUINT64):
-	case CASE(OLSH, TPTR64):
-		a = ASHLQ;
-		break;
-
-	case CASE(ORSH, TUINT8):
-		a = ASHRB;
-		break;
-
-	case CASE(ORSH, TUINT16):
-		a = ASHRW;
-		break;
-
-	case CASE(ORSH, TUINT32):
-	case CASE(ORSH, TPTR32):
-		a = ASHRL;
-		break;
-
-	case CASE(ORSH, TUINT64):
-	case CASE(ORSH, TPTR64):
-		a = ASHRQ;
-		break;
-
-	case CASE(ORSH, TINT8):
-		a = ASARB;
-		break;
-
-	case CASE(ORSH, TINT16):
-		a = ASARW;
-		break;
-
-	case CASE(ORSH, TINT32):
-		a = ASARL;
-		break;
-
-	case CASE(ORSH, TINT64):
-		a = ASARQ;
-		break;
-
-	case CASE(ORROTC, TINT8):
-	case CASE(ORROTC, TUINT8):
-		a = ARCRB;
-		break;
-
-	case CASE(ORROTC, TINT16):
-	case CASE(ORROTC, TUINT16):
-		a = ARCRW;
-		break;
-
-	case CASE(ORROTC, TINT32):
-	case CASE(ORROTC, TUINT32):
-		a = ARCRL;
-		break;
-
-	case CASE(ORROTC, TINT64):
-	case CASE(ORROTC, TUINT64):
-		a = ARCRQ;
-		break;
-
-	case CASE(OHMUL, TINT8):
-	case CASE(OMUL, TINT8):
-	case CASE(OMUL, TUINT8):
-		a = AIMULB;
-		break;
-
-	case CASE(OHMUL, TINT16):
-	case CASE(OMUL, TINT16):
-	case CASE(OMUL, TUINT16):
-		a = AIMULW;
-		break;
-
-	case CASE(OHMUL, TINT32):
-	case CASE(OMUL, TINT32):
-	case CASE(OMUL, TUINT32):
-	case CASE(OMUL, TPTR32):
-		a = AIMULL;
-		break;
-
-	case CASE(OHMUL, TINT64):
-	case CASE(OMUL, TINT64):
-	case CASE(OMUL, TUINT64):
-	case CASE(OMUL, TPTR64):
-		a = AIMULQ;
-		break;
-
-	case CASE(OHMUL, TUINT8):
-		a = AMULB;
-		break;
-
-	case CASE(OHMUL, TUINT16):
-		a = AMULW;
-		break;
-
-	case CASE(OHMUL, TUINT32):
-	case CASE(OHMUL, TPTR32):
-		a = AMULL;
-		break;
-
-	case CASE(OHMUL, TUINT64):
-	case CASE(OHMUL, TPTR64):
-		a = AMULQ;
-		break;
-
-	case CASE(OMUL, TFLOAT32):
-		a = AMULSS;
-		break;
-
-	case CASE(OMUL, TFLOAT64):
-		a = AMULSD;
-		break;
-
-	case CASE(ODIV, TINT8):
-	case CASE(OMOD, TINT8):
-		a = AIDIVB;
-		break;
-
-	case CASE(ODIV, TUINT8):
-	case CASE(OMOD, TUINT8):
-		a = ADIVB;
-		break;
-
-	case CASE(ODIV, TINT16):
-	case CASE(OMOD, TINT16):
-		a = AIDIVW;
-		break;
-
-	case CASE(ODIV, TUINT16):
-	case CASE(OMOD, TUINT16):
-		a = ADIVW;
-		break;
-
-	case CASE(ODIV, TINT32):
-	case CASE(OMOD, TINT32):
-		a = AIDIVL;
-		break;
-
-	case CASE(ODIV, TUINT32):
-	case CASE(ODIV, TPTR32):
-	case CASE(OMOD, TUINT32):
-	case CASE(OMOD, TPTR32):
-		a = ADIVL;
-		break;
-
-	case CASE(ODIV, TINT64):
-	case CASE(OMOD, TINT64):
-		a = AIDIVQ;
-		break;
-
-	case CASE(ODIV, TUINT64):
-	case CASE(ODIV, TPTR64):
-	case CASE(OMOD, TUINT64):
-	case CASE(OMOD, TPTR64):
-		a = ADIVQ;
-		break;
-
-	case CASE(OEXTEND, TINT16):
-		a = ACWD;
-		break;
-
-	case CASE(OEXTEND, TINT32):
-		a = ACDQ;
-		break;
-
-	case CASE(OEXTEND, TINT64):
-		a = ACQO;
-		break;
-
-	case CASE(ODIV, TFLOAT32):
-		a = ADIVSS;
-		break;
-
-	case CASE(ODIV, TFLOAT64):
-		a = ADIVSD;
-		break;
-
-	}
-	return a;
-}
-
-enum
-{
-	ODynam		= 1<<0,
-	OAddable	= 1<<1,
-};
-
-static	Node	clean[20];
-static	int	cleani = 0;
-
-int
-xgen(Node *n, Node *a, int o)
-{
-	regalloc(a, types[tptr], N);
-
-	if(o & ODynam)
-	if(n->addable)
-	if(n->op != OINDREG)
-	if(n->op != OREGISTER)
-		return 1;
-
-	agen(n, a);
-	return 0;
-}
-
-void
-sudoclean(void)
-{
-	if(clean[cleani-1].op != OEMPTY)
-		regfree(&clean[cleani-1]);
-	if(clean[cleani-2].op != OEMPTY)
-		regfree(&clean[cleani-2]);
-	cleani -= 2;
-}
-
-/*
- * generate code to compute address of n,
- * a reference to a (perhaps nested) field inside
- * an array or struct.
- * return 0 on failure, 1 on success.
- * on success, leaves usable address in a.
- *
- * caller is responsible for calling sudoclean
- * after successful sudoaddable,
- * to release the register used for a.
- */
-int
-sudoaddable(int as, Node *n, Addr *a)
-{
-	int o, i;
-	int64 oary[10];
-	int64 v, w;
-	Node n1, n2, n3, n4, *nn, *l, *r;
-	Node *reg, *reg1;
-	Prog *p1;
-	Type *t;
-
-	if(n->type == T)
-		return 0;
-
-	memset(a, 0, sizeof *a);
-
-	switch(n->op) {
-	case OLITERAL:
-		if(!isconst(n, CTINT))
-			break;
-		v = mpgetfix(n->val.u.xval);
-		if(v >= 32000 || v <= -32000)
-			break;
-		goto lit;
-
-	case ODOT:
-	case ODOTPTR:
-		cleani += 2;
-		reg = &clean[cleani-1];
-		reg1 = &clean[cleani-2];
-		reg->op = OEMPTY;
-		reg1->op = OEMPTY;
-		goto odot;
-
-	case OINDEX:
-		return 0;
-		// disabled: OINDEX case is now covered by agenr
-		// for a more suitable register allocation pattern.
-		if(n->left->type->etype == TSTRING)
-			return 0;
-		goto oindex;
-	}
-	return 0;
-
-lit:
-	switch(as) {
-	default:
-		return 0;
-	case AADDB: case AADDW: case AADDL: case AADDQ:
-	case ASUBB: case ASUBW: case ASUBL: case ASUBQ:
-	case AANDB: case AANDW: case AANDL: case AANDQ:
-	case AORB:  case AORW:  case AORL:  case AORQ:
-	case AXORB: case AXORW: case AXORL: case AXORQ:
-	case AINCB: case AINCW: case AINCL: case AINCQ:
-	case ADECB: case ADECW: case ADECL: case ADECQ:
-	case AMOVB: case AMOVW: case AMOVL: case AMOVQ:
-		break;
-	}
-
-	cleani += 2;
-	reg = &clean[cleani-1];
-	reg1 = &clean[cleani-2];
-	reg->op = OEMPTY;
-	reg1->op = OEMPTY;
-	naddr(n, a, 1);
-	goto yes;
-
-odot:
-	o = dotoffset(n, oary, &nn);
-	if(nn == N)
-		goto no;
-
-	if(nn->addable && o == 1 && oary[0] >= 0) {
-		// directly addressable set of DOTs
-		n1 = *nn;
-		n1.type = n->type;
-		n1.xoffset += oary[0];
-		naddr(&n1, a, 1);
-		goto yes;
-	}
-
-	regalloc(reg, types[tptr], N);
-	n1 = *reg;
-	n1.op = OINDREG;
-	if(oary[0] >= 0) {
-		agen(nn, reg);
-		n1.xoffset = oary[0];
-	} else {
-		cgen(nn, reg);
-		cgen_checknil(reg);
-		n1.xoffset = -(oary[0]+1);
-	}
-
-	for(i=1; i<o; i++) {
-		if(oary[i] >= 0)
-			fatal("can't happen");
-		gins(movptr, &n1, reg);
-		cgen_checknil(reg);
-		n1.xoffset = -(oary[i]+1);
-	}
-
-	a->type = TYPE_NONE;
-	a->index = TYPE_NONE;
-	fixlargeoffset(&n1);
-	naddr(&n1, a, 1);
-	goto yes;
-
-oindex:
-	l = n->left;
-	r = n->right;
-	if(l->ullman >= UINF && r->ullman >= UINF)
-		return 0;
-
-	// set o to type of array
-	o = 0;
-	if(isptr[l->type->etype])
-		fatal("ptr ary");
-	if(l->type->etype != TARRAY)
-		fatal("not ary");
-	if(l->type->bound < 0)
-		o |= ODynam;
-
-	w = n->type->width;
-	if(isconst(r, CTINT))
-		goto oindex_const;
-
-	switch(w) {
-	default:
-		return 0;
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		break;
-	}
-
-	cleani += 2;
-	reg = &clean[cleani-1];
-	reg1 = &clean[cleani-2];
-	reg->op = OEMPTY;
-	reg1->op = OEMPTY;
-
-	// load the array (reg)
-	if(l->ullman > r->ullman) {
-		if(xgen(l, reg, o))
-			o |= OAddable;
-	}
-
-	// load the index (reg1)
-	t = types[TUINT64];
-	if(issigned[r->type->etype])
-		t = types[TINT64];
-	regalloc(reg1, t, N);
-	regalloc(&n3, r->type, reg1);
-	cgen(r, &n3);
-	gmove(&n3, reg1);
-	regfree(&n3);
-
-	// load the array (reg)
-	if(l->ullman <= r->ullman) {
-		if(xgen(l, reg, o))
-			o |= OAddable;
-	}
-
-	// check bounds
-	if(!debug['B'] && !n->bounded) {
-		// check bounds
-		n4.op = OXXX;
-		t = types[simtype[TUINT]];
-		if(o & ODynam) {
-			if(o & OAddable) {
-				n2 = *l;
-				n2.xoffset += Array_nel;
-				n2.type = types[simtype[TUINT]];
-			} else {
-				n2 = *reg;
-				n2.xoffset = Array_nel;
-				n2.op = OINDREG;
-				n2.type = types[simtype[TUINT]];
-			}
-		} else {
-			if(is64(r->type))
-				t = types[TUINT64];
-			nodconst(&n2, types[TUINT64], l->type->bound);
-		}
-		gins(optoas(OCMP, t), reg1, &n2);
-		p1 = gbranch(optoas(OLT, t), T, +1);
-		if(n4.op != OXXX)
-			regfree(&n4);
-		ginscall(panicindex, -1);
-		patch(p1, pc);
-	}
-
-	if(o & ODynam) {
-		if(o & OAddable) {
-			n2 = *l;
-			n2.xoffset += Array_array;
-			n2.type = types[tptr];
-			gmove(&n2, reg);
-		} else {
-			n2 = *reg;
-			n2.op = OINDREG;
-			n2.xoffset = Array_array;
-			n2.type = types[tptr];
-			gmove(&n2, reg);
-		}
-	}
-
-	if(o & OAddable) {
-		naddr(reg1, a, 1);
-		a->offset = 0;
-		a->scale = w;
-		a->index = a->reg;
-		a->type = TYPE_MEM;
-		a->reg = reg->val.u.reg;
-	} else {
-		naddr(reg1, a, 1);
-		a->offset = 0;
-		a->scale = w;
-		a->index = a->reg;
-		a->type = TYPE_MEM;
-		a->reg = reg->val.u.reg;
-	}
-
-	goto yes;
-
-oindex_const:
-	// index is constant
-	// can check statically and
-	// can multiply by width statically
-
-	v = mpgetfix(r->val.u.xval);
-
-	if(sudoaddable(as, l, a))
-		goto oindex_const_sudo;
-
-	cleani += 2;
-	reg = &clean[cleani-1];
-	reg1 = &clean[cleani-2];
-	reg->op = OEMPTY;
-	reg1->op = OEMPTY;
-
-	if(o & ODynam) {
-		regalloc(reg, types[tptr], N);
-		agen(l, reg);
-	
-		if(!debug['B'] && !n->bounded) {
-			n1 = *reg;
-			n1.op = OINDREG;
-			n1.type = types[tptr];
-			n1.xoffset = Array_nel;
-			nodconst(&n2, types[TUINT64], v);
-			gins(optoas(OCMP, types[simtype[TUINT]]), &n1, &n2);
-			p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1);
-			ginscall(panicindex, -1);
-			patch(p1, pc);
-		}
-
-		n1 = *reg;
-		n1.op = OINDREG;
-		n1.type = types[tptr];
-		n1.xoffset = Array_array;
-		gmove(&n1, reg);
-
-		n2 = *reg;
-		n2.op = OINDREG;
-		n2.xoffset = v*w;
-		fixlargeoffset(&n2);
-		a->type = TYPE_NONE;
-		a->index = TYPE_NONE;
-		naddr(&n2, a, 1);
-		goto yes;
-	}
-	
-	igen(l, &n1, N);
-	if(n1.op == OINDREG) {
-		*reg = n1;
-		reg->op = OREGISTER;
-	}
-	n1.xoffset += v*w;
-	fixlargeoffset(&n1);
-	a->type = TYPE_NONE;
-	a->index= TYPE_NONE;
-	naddr(&n1, a, 1);
-	goto yes;
-
-oindex_const_sudo:
-	if((o & ODynam) == 0) {
-		// array indexed by a constant
-		a->offset += v*w;
-		goto yes;
-	}
-
-	// slice indexed by a constant
-	if(!debug['B'] && !n->bounded) {
-		a->offset += Array_nel;
-		nodconst(&n2, types[TUINT64], v);
-		p1 = gins(optoas(OCMP, types[simtype[TUINT]]), N, &n2);
-		p1->from = *a;
-		p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1);
-		ginscall(panicindex, -1);
-		patch(p1, pc);
-		a->offset -= Array_nel;
-	}
-
-	a->offset += Array_array;
-	reg = &clean[cleani-1];
-	if(reg->op == OEMPTY)
-		regalloc(reg, types[tptr], N);
-
-	p1 = gins(movptr, N, reg);
-	p1->from = *a;
-
-	n2 = *reg;
-	n2.op = OINDREG;
-	n2.xoffset = v*w;
-	fixlargeoffset(&n2);
-	a->type = TYPE_NONE;
-	a->index = TYPE_NONE;
-	naddr(&n2, a, 1);
-	goto yes;
-
-yes:
-	return 1;
-
-no:
-	sudoclean();
-	return 0;
-}
diff --git a/src/cmd/new6g/gsubr.go b/src/cmd/6g/gsubr.go
similarity index 100%
rename from src/cmd/new6g/gsubr.go
rename to src/cmd/6g/gsubr.go
diff --git a/src/cmd/6g/peep.c b/src/cmd/6g/peep.c
deleted file mode 100644
index 261cb6e..0000000
--- a/src/cmd/6g/peep.c
+++ /dev/null
@@ -1,988 +0,0 @@
-// Derived from Inferno utils/6c/peep.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.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 "gg.h"
-#include "../gc/popt.h"
-
-static void	conprop(Flow *r);
-static void	elimshortmov(Graph *g);
-static int	prevl(Flow *r, int reg);
-static void	pushback(Flow *r);
-static int	regconsttyp(Adr*);
-static int	subprop(Flow*);
-static int	copyprop(Graph*, Flow*);
-static int	copy1(Adr*, Adr*, Flow*, int);
-static int	copyas(Adr*, Adr*);
-static int	copyau(Adr*, Adr*);
-static int	copysub(Adr*, Adr*, Adr*, int);
-static int	copyu(Prog*, Adr*, Adr*);
-
-static uint32	gactive;
-
-enum
-{
-	exregoffset = REG_R15,
-};
-
-// do we need the carry bit
-static int
-needc(Prog *p)
-{
-	ProgInfo info;
-
-	while(p != P) {
-		proginfo(&info, p);
-		if(info.flags & UseCarry)
-			return 1;
-		if(info.flags & (SetCarry|KillCarry))
-			return 0;
-		p = p->link;
-	}
-	return 0;
-}
-
-static Flow*
-rnops(Flow *r)
-{
-	Prog *p;
-	Flow *r1;
-
-	if(r != nil)
-	for(;;) {
-		p = r->prog;
-		if(p->as != ANOP || p->from.type != TYPE_NONE || p->to.type != TYPE_NONE)
-			break;
-		r1 = uniqs(r);
-		if(r1 == nil)
-			break;
-		r = r1;
-	}
-	return r;
-}
-
-void
-peep(Prog *firstp)
-{
-	Flow *r, *r1;
-	Graph *g;
-	Prog *p, *p1;
-	int t;
-
-	g = flowstart(firstp, 0);
-	if(g == nil)
-		return;
-	gactive = 0;
-
-	// byte, word arithmetic elimination.
-	elimshortmov(g);
-
-	// constant propagation
-	// find MOV $con,R followed by
-	// another MOV $con,R without
-	// setting R in the interim
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case ALEAL:
-		case ALEAQ:
-			if(regtyp(&p->to))
-			if(p->from.sym != nil)
-			if(p->from.index == REG_NONE)
-				conprop(r);
-			break;
-
-		case AMOVB:
-		case AMOVW:
-		case AMOVL:
-		case AMOVQ:
-		case AMOVSS:
-		case AMOVSD:
-			if(regtyp(&p->to))
-			if(p->from.type == TYPE_CONST || p->from.type == TYPE_FCONST)
-				conprop(r);
-			break;
-		}
-	}
-
-loop1:
-	if(debug['P'] && debug['v'])
-		dumpit("loop1", g->start, 0);
-
-	t = 0;
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case AMOVL:
-		case AMOVQ:
-		case AMOVSS:
-		case AMOVSD:
-			if(regtyp(&p->to))
-			if(regtyp(&p->from)) {
-				if(copyprop(g, r)) {
-					excise(r);
-					t++;
-				} else
-				if(subprop(r) && copyprop(g, r)) {
-					excise(r);
-					t++;
-				}
-			}
-			break;
-
-		case AMOVBLZX:
-		case AMOVWLZX:
-		case AMOVBLSX:
-		case AMOVWLSX:
-			if(regtyp(&p->to)) {
-				r1 = rnops(uniqs(r));
-				if(r1 != nil) {
-					p1 = r1->prog;
-					if(p->as == p1->as && p->to.type == p1->from.type && p->to.reg == p1->from.reg){
-						p1->as = AMOVL;
-						t++;
-					}
-				}
-			}
-			break;
-
-		case AMOVBQSX:
-		case AMOVBQZX:
-		case AMOVWQSX:
-		case AMOVWQZX:
-		case AMOVLQSX:
-		case AMOVLQZX:
-		case AMOVQL:
-			if(regtyp(&p->to)) {
-				r1 = rnops(uniqs(r));
-				if(r1 != nil) {
-					p1 = r1->prog;
-					if(p->as == p1->as && p->to.type == p1->from.type && p->to.reg == p1->from.reg){
-						p1->as = AMOVQ;
-						t++;
-					}
-				}
-			}
-			break;
-
-		case AADDL:
-		case AADDQ:
-		case AADDW:
-			if(p->from.type != TYPE_CONST || needc(p->link))
-				break;
-			if(p->from.offset == -1){
-				if(p->as == AADDQ)
-					p->as = ADECQ;
-				else
-				if(p->as == AADDL)
-					p->as = ADECL;
-				else
-					p->as = ADECW;
-				p->from = zprog.from;
-				break;
-			}
-			if(p->from.offset == 1){
-				if(p->as == AADDQ)
-					p->as = AINCQ;
-				else if(p->as == AADDL)
-					p->as = AINCL;
-				else
-					p->as = AINCW;
-				p->from = zprog.from;
-				break;
-			}
-			break;
-
-		case ASUBL:
-		case ASUBQ:
-		case ASUBW:
-			if(p->from.type != TYPE_CONST || needc(p->link))
-				break;
-			if(p->from.offset == -1) {
-				if(p->as == ASUBQ)
-					p->as = AINCQ;
-				else
-				if(p->as == ASUBL)
-					p->as = AINCL;
-				else
-					p->as = AINCW;
-				p->from = zprog.from;
-				break;
-			}
-			if(p->from.offset == 1){
-				if(p->as == ASUBQ)
-					p->as = ADECQ;
-				else
-				if(p->as == ASUBL)
-					p->as = ADECL;
-				else
-					p->as = ADECW;
-				p->from = zprog.from;
-				break;
-			}
-			break;
-		}
-	}
-	if(t)
-		goto loop1;
-
-	// MOVLQZX removal.
-	// The MOVLQZX exists to avoid being confused for a
-	// MOVL that is just copying 32-bit data around during
-	// copyprop.  Now that copyprop is done, remov MOVLQZX R1, R2
-	// if it is dominated by an earlier ADDL/MOVL/etc into R1 that
-	// will have already cleared the high bits.
-	//
-	// MOVSD removal.
-	// We never use packed registers, so a MOVSD between registers
-	// can be replaced by MOVAPD, which moves the pair of float64s
-	// instead of just the lower one.  We only use the lower one, but
-	// the processor can do better if we do moves using both.
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		if(p->as == AMOVLQZX)
-		if(regtyp(&p->from))
-		if(p->from.type == p->to.type && p->from.reg == p->to.reg)
-		if(prevl(r, p->from.reg))
-			excise(r);
-		
-		if(p->as == AMOVSD)
-		if(regtyp(&p->from))
-		if(regtyp(&p->to))
-			p->as = AMOVAPD;
-	}
-
-	// load pipelining
-	// push any load from memory as early as possible
-	// to give it time to complete before use.
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case AMOVB:
-		case AMOVW:
-		case AMOVL:
-		case AMOVQ:
-		case AMOVLQZX:
-			if(regtyp(&p->to) && !regconsttyp(&p->from))
-				pushback(r);
-		}
-	}
-	
-	flowend(g);
-}
-
-static void
-pushback(Flow *r0)
-{
-	Flow *r, *b;
-	Prog *p0, *p, t;
-	
-	b = nil;
-	p0 = r0->prog;
-	for(r=uniqp(r0); r!=nil && uniqs(r)!=nil; r=uniqp(r)) {
-		p = r->prog;
-		if(p->as != ANOP) {
-			if(!regconsttyp(&p->from) || !regtyp(&p->to))
-				break;
-			if(copyu(p, &p0->to, nil) || copyu(p0, &p->to, nil))
-				break;
-		}
-		if(p->as == ACALL)
-			break;
-		b = r;
-	}
-	
-	if(b == nil) {
-		if(debug['v']) {
-			print("no pushback: %P\n", r0->prog);
-			if(r)
-				print("\t%P [%d]\n", r->prog, uniqs(r)!=nil);
-		}
-		return;
-	}
-
-	if(debug['v']) {
-		print("pushback\n");
-		for(r=b;; r=r->link) {
-			print("\t%P\n", r->prog);
-			if(r == r0)
-				break;
-		}
-	}
-
-	t = *r0->prog;
-	for(r=uniqp(r0);; r=uniqp(r)) {
-		p0 = r->link->prog;
-		p = r->prog;
-		p0->as = p->as;
-		p0->lineno = p->lineno;
-		p0->from = p->from;
-		p0->to = p->to;
-
-		if(r == b)
-			break;
-	}
-	p0 = r->prog;
-	p0->as = t.as;
-	p0->lineno = t.lineno;
-	p0->from = t.from;
-	p0->to = t.to;
-
-	if(debug['v']) {
-		print("\tafter\n");
-		for(r=b;; r=r->link) {
-			print("\t%P\n", r->prog);
-			if(r == r0)
-				break;
-		}
-	}
-}
-
-void
-excise(Flow *r)
-{
-	Prog *p;
-
-	p = r->prog;
-	if(debug['P'] && debug['v'])
-		print("%P ===delete===\n", p);
-
-	nopout(p);
-
-	ostats.ndelmov++;
-}
-
-int
-regtyp(Adr *a)
-{
-	return a->type == TYPE_REG && (REG_AX <= a->reg && a->reg <= REG_R15 || REG_X0 <= a->reg && a->reg <= REG_X15);
-}
-
-// movb elimination.
-// movb is simulated by the linker
-// when a register other than ax, bx, cx, dx
-// is used, so rewrite to other instructions
-// when possible.  a movb into a register
-// can smash the entire 32-bit register without
-// causing any trouble.
-//
-// TODO: Using the Q forms here instead of the L forms
-// seems unnecessary, and it makes the instructions longer.
-static void
-elimshortmov(Graph *g)
-{
-	Prog *p;
-	Flow *r;
-
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		if(regtyp(&p->to)) {
-			switch(p->as) {
-			case AINCB:
-			case AINCW:
-				p->as = AINCQ;
-				break;
-			case ADECB:
-			case ADECW:
-				p->as = ADECQ;
-				break;
-			case ANEGB:
-			case ANEGW:
-				p->as = ANEGQ;
-				break;
-			case ANOTB:
-			case ANOTW:
-				p->as = ANOTQ;
-				break;
-			}
-			if(regtyp(&p->from) || p->from.type == TYPE_CONST) {
-				// move or artihmetic into partial register.
-				// from another register or constant can be movl.
-				// we don't switch to 64-bit arithmetic if it can
-				// change how the carry bit is set (and the carry bit is needed).
-				switch(p->as) {
-				case AMOVB:
-				case AMOVW:
-					p->as = AMOVQ;
-					break;
-				case AADDB:
-				case AADDW:
-					if(!needc(p->link))
-						p->as = AADDQ;
-					break;
-				case ASUBB:
-				case ASUBW:
-					if(!needc(p->link))
-						p->as = ASUBQ;
-					break;
-				case AMULB:
-				case AMULW:
-					p->as = AMULQ;
-					break;
-				case AIMULB:
-				case AIMULW:
-					p->as = AIMULQ;
-					break;
-				case AANDB:
-				case AANDW:
-					p->as = AANDQ;
-					break;
-				case AORB:
-				case AORW:
-					p->as = AORQ;
-					break;
-				case AXORB:
-				case AXORW:
-					p->as = AXORQ;
-					break;
-				case ASHLB:
-				case ASHLW:
-					p->as = ASHLQ;
-					break;
-				}
-			} else if(p->from.type != TYPE_REG) {
-				// explicit zero extension, but don't
-				// do that if source is a byte register
-				// (only AH can occur and it's forbidden).
-				switch(p->as) {
-				case AMOVB:
-					p->as = AMOVBQZX;
-					break;
-				case AMOVW:
-					p->as = AMOVWQZX;
-					break;
-				}
-			}
-		}
-	}
-}
-
-// is 'a' a register or constant?
-static int
-regconsttyp(Adr *a)
-{
-	if(regtyp(a))
-		return 1;
-	switch(a->type) {
-	case TYPE_CONST:
-	case TYPE_FCONST:
-	case TYPE_SCONST:
-	case TYPE_ADDR: // TODO(rsc): Not all TYPE_ADDRs are constants.
-		return 1;
-	}
-	return 0;
-}
-
-// is reg guaranteed to be truncated by a previous L instruction?
-static int
-prevl(Flow *r0, int reg)
-{
-	Prog *p;
-	Flow *r;
-	ProgInfo info;
-
-	for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
-		p = r->prog;
-		if(p->to.type == TYPE_REG && p->to.reg == reg) {
-			proginfo(&info, p);
-			if(info.flags & RightWrite) {
-				if(info.flags & SizeL)
-					return 1;
-				return 0;
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * the idea is to substitute
- * one register for another
- * from one MOV to another
- *	MOV	a, R0
- *	ADD	b, R0	/ no use of R1
- *	MOV	R0, R1
- * would be converted to
- *	MOV	a, R1
- *	ADD	b, R1
- *	MOV	R1, R0
- * hopefully, then the former or latter MOV
- * will be eliminated by copy propagation.
- */
-static int
-subprop(Flow *r0)
-{
-	Prog *p;
-	ProgInfo info;
-	Adr *v1, *v2;
-	Flow *r;
-	int t;
-
-	if(debug['P'] && debug['v'])
-		print("subprop %P\n", r0->prog);
-	p = r0->prog;
-	v1 = &p->from;
-	if(!regtyp(v1)) {
-		if(debug['P'] && debug['v'])
-			print("\tnot regtype %D; return 0\n", v1);
-		return 0;
-	}
-	v2 = &p->to;
-	if(!regtyp(v2)) {
-		if(debug['P'] && debug['v'])
-			print("\tnot regtype %D; return 0\n", v2);
-		return 0;
-	}
-	for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
-		if(debug['P'] && debug['v'])
-			print("\t? %P\n", r->prog);
-		if(uniqs(r) == nil) {
-			if(debug['P'] && debug['v'])
-				print("\tno unique successor\n");
-			break;
-		}
-		p = r->prog;
-		if(p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-		proginfo(&info, p);
-		if(info.flags & Call) {
-			if(debug['P'] && debug['v'])
-				print("\tfound %P; return 0\n", p);
-			return 0;
-		}
-
-		if(info.reguse | info.regset) {
-			if(debug['P'] && debug['v'])
-				print("\tfound %P; return 0\n", p);
-			return 0;
-		}
-
-		if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type && p->to.reg == v1->reg)
-			goto gotit;
-
-		if(copyau(&p->from, v2) ||
-		   copyau(&p->to, v2)) {
-		   	if(debug['P'] && debug['v'])
-		   		print("\tcopyau %D failed\n", v2);
-			break;
-		}
-		if(copysub(&p->from, v1, v2, 0) ||
-		   copysub(&p->to, v1, v2, 0)) {
-		   	if(debug['P'] && debug['v'])
-		   		print("\tcopysub failed\n");
-			break;
-		}
-	}
-	if(debug['P'] && debug['v'])
-		print("\tran off end; return 0\n");
-	return 0;
-
-gotit:
-	copysub(&p->to, v1, v2, 1);
-	if(debug['P']) {
-		print("gotit: %D->%D\n%P", v1, v2, r->prog);
-		if(p->from.type == v2->type && p->from.reg == v2->reg)
-			print(" excise");
-		print("\n");
-	}
-	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
-		p = r->prog;
-		copysub(&p->from, v1, v2, 1);
-		copysub(&p->to, v1, v2, 1);
-		if(debug['P'])
-			print("%P\n", r->prog);
-	}
-	t = v1->reg;
-	v1->reg = v2->reg;
-	v2->reg = t;
-	if(debug['P'])
-		print("%P last\n", r->prog);
-	return 1;
-}
-
-/*
- * The idea is to remove redundant copies.
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	use v2	return fail
- *	-----------------
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	set v2	return success
- */
-static int
-copyprop(Graph *g, Flow *r0)
-{
-	Prog *p;
-	Adr *v1, *v2;
-
-	USED(g);
-	if(debug['P'] && debug['v'])
-		print("copyprop %P\n", r0->prog);
-	p = r0->prog;
-	v1 = &p->from;
-	v2 = &p->to;
-	if(copyas(v1, v2))
-		return 1;
-	gactive++;
-	return copy1(v1, v2, r0->s1, 0);
-}
-
-static int
-copy1(Adr *v1, Adr *v2, Flow *r, int f)
-{
-	int t;
-	Prog *p;
-
-	if(r->active == gactive) {
-		if(debug['P'])
-			print("act set; return 1\n");
-		return 1;
-	}
-	r->active = gactive;
-	if(debug['P'])
-		print("copy %D->%D f=%d\n", v1, v2, f);
-	for(; r != nil; r = r->s1) {
-		p = r->prog;
-		if(debug['P'])
-			print("%P", p);
-		if(!f && uniqp(r) == nil) {
-			f = 1;
-			if(debug['P'])
-				print("; merge; f=%d", f);
-		}
-		t = copyu(p, v2, nil);
-		switch(t) {
-		case 2:	/* rar, can't split */
-			if(debug['P'])
-				print("; %D rar; return 0\n", v2);
-			return 0;
-
-		case 3:	/* set */
-			if(debug['P'])
-				print("; %D set; return 1\n", v2);
-			return 1;
-
-		case 1:	/* used, substitute */
-		case 4:	/* use and set */
-			if(f) {
-				if(!debug['P'])
-					return 0;
-				if(t == 4)
-					print("; %D used+set and f=%d; return 0\n", v2, f);
-				else
-					print("; %D used and f=%d; return 0\n", v2, f);
-				return 0;
-			}
-			if(copyu(p, v2, v1)) {
-				if(debug['P'])
-					print("; sub fail; return 0\n");
-				return 0;
-			}
-			if(debug['P'])
-				print("; sub %D/%D", v2, v1);
-			if(t == 4) {
-				if(debug['P'])
-					print("; %D used+set; return 1\n", v2);
-				return 1;
-			}
-			break;
-		}
-		if(!f) {
-			t = copyu(p, v1, nil);
-			if(!f && (t == 2 || t == 3 || t == 4)) {
-				f = 1;
-				if(debug['P'])
-					print("; %D set and !f; f=%d", v1, f);
-			}
-		}
-		if(debug['P'])
-			print("\n");
-		if(r->s2)
-			if(!copy1(v1, v2, r->s2, f))
-				return 0;
-	}
-	return 1;
-}
-
-/*
- * return
- * 1 if v only used (and substitute),
- * 2 if read-alter-rewrite
- * 3 if set
- * 4 if set and used
- * 0 otherwise (not touched)
- */
-static int
-copyu(Prog *p, Adr *v, Adr *s)
-{
-	ProgInfo info;
-
-	switch(p->as) {
-	case AJMP:
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ARET:
-		if(s != nil)
-			return 1;
-		return 3;
-
-	case ACALL:
-		if(REGEXT && v->type == TYPE_REG && v->reg <= REGEXT && v->reg > exregoffset)
-			return 2;
-		if(REGARG >= 0 && v->type == TYPE_REG && v->reg == REGARG)
-			return 2;
-		if(v->type == p->from.type && v->reg == p->from.reg)
-			return 2;
-
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 4;
-		return 3;
-
-	case ATEXT:
-		if(REGARG >= 0 && v->type == TYPE_REG && v->reg == REGARG)
-			return 3;
-		return 0;
-	}
-
-	if(p->as == AVARDEF || p->as == AVARKILL)
-		return 0;
-	proginfo(&info, p);
-
-	if((info.reguse|info.regset) & RtoB(v->reg))
-		return 2;
-		
-	if(info.flags & LeftAddr)
-		if(copyas(&p->from, v))
-			return 2;
-
-	if((info.flags & (RightRead|RightWrite)) == (RightRead|RightWrite))
-		if(copyas(&p->to, v))
-			return 2;
-	
-	if(info.flags & RightWrite) {
-		if(copyas(&p->to, v)) {
-			if(s != nil)
-				return copysub(&p->from, v, s, 1);
-			if(copyau(&p->from, v))
-				return 4;
-			return 3;
-		}
-	}
-	
-	if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			return copysub(&p->to, v, s, 1);
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * direct reference,
- * could be set/use depending on
- * semantics
- */
-static int
-copyas(Adr *a, Adr *v)
-{
-	if(REG_AL <= a->reg && a->reg <= REG_R15B)
-		fatal("use of byte register");
-	if(REG_AL <= v->reg && v->reg <= REG_R15B)
-		fatal("use of byte register");
-
-	if(a->type != v->type || a->name != v->name || a->reg != v->reg)
-		return 0;
-	if(regtyp(v))
-		return 1;
-	if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
-		if(v->offset == a->offset)
-			return 1;
-	return 0;
-}
-
-int
-sameaddr(Addr *a, Addr *v)
-{
-	if(a->type != v->type || a->name != v->name || a->reg != v->reg)
-		return 0;
-	if(regtyp(v))
-		return 1;
-	if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
-		if(v->offset == a->offset)
-			return 1;
-	return 0;
-}
-
-/*
- * either direct or indirect
- */
-static int
-copyau(Adr *a, Adr *v)
-{
-
-	if(copyas(a, v)) {
-		if(debug['P'] && debug['v'])
-			print("\tcopyau: copyas returned 1\n");
-		return 1;
-	}
-	if(regtyp(v)) {
-		if(a->type == TYPE_MEM && a->reg == v->reg) {
-			if(debug['P'] && debug['v'])
-				print("\tcopyau: found indir use - return 1\n");
-			return 1;
-		}
-		if(a->index == v->reg) {
-			if(debug['P'] && debug['v'])
-				print("\tcopyau: found index use - return 1\n");
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * substitute s for v in a
- * return failure to substitute
- */
-static int
-copysub(Adr *a, Adr *v, Adr *s, int f)
-{
-	int reg;
-
-	if(copyas(a, v)) {
-		reg = s->reg;
-		if(reg >= REG_AX && reg <= REG_R15 || reg >= REG_X0 && reg <= REG_X0+15) {
-			if(f)
-				a->reg = reg;
-		}
-		return 0;
-	}
-	if(regtyp(v)) {
-		reg = v->reg;
-		if(a->type == TYPE_MEM && a->reg == reg) {
-			if((s->reg == REG_BP || s->reg == REG_R13) && a->index != REG_NONE)
-				return 1;	/* can't use BP-base with index */
-			if(f)
-				a->reg = s->reg;
-//			return 0;
-		}
-		if(a->index == reg) {
-			if(f)
-				a->index = s->reg;
-			return 0;
-		}
-		return 0;
-	}
-	return 0;
-}
-
-static void
-conprop(Flow *r0)
-{
-	Flow *r;
-	Prog *p, *p0;
-	int t;
-	Adr *v0;
-
-	p0 = r0->prog;
-	v0 = &p0->to;
-	r = r0;
-
-loop:
-	r = uniqs(r);
-	if(r == nil || r == r0)
-		return;
-	if(uniqp(r) == nil)
-		return;
-
-	p = r->prog;
-	t = copyu(p, v0, nil);
-	switch(t) {
-	case 0:	// miss
-	case 1:	// use
-		goto loop;
-
-	case 2:	// rar
-	case 4:	// use and set
-		break;
-
-	case 3:	// set
-		if(p->as == p0->as)
-		if(p->from.type == p0->from.type)
-		if(p->from.reg == p0->from.reg)
-		if(p->from.node == p0->from.node)
-		if(p->from.offset == p0->from.offset)
-		if(p->from.scale == p0->from.scale)
-		if(p->from.type == TYPE_FCONST && p->from.u.dval == p0->from.u.dval)
-		if(p->from.index == p0->from.index) {
-			excise(r);
-			goto loop;
-		}
-		break;
-	}
-}
-
-int
-smallindir(Addr *a, Addr *reg)
-{
-	return regtyp(reg) &&
-		a->type == TYPE_MEM && a->reg == reg->reg &&
-		a->index == REG_NONE &&
-		0 <= a->offset && a->offset < 4096;
-}
-
-int
-stackaddr(Addr *a)
-{
-	return a->type == TYPE_REG && a->reg == REG_SP;
-}
diff --git a/src/cmd/new6g/peep.go b/src/cmd/6g/peep.go
similarity index 100%
rename from src/cmd/new6g/peep.go
rename to src/cmd/6g/peep.go
diff --git a/src/cmd/6g/prog.c b/src/cmd/6g/prog.c
deleted file mode 100644
index 79b7911..0000000
--- a/src/cmd/6g/prog.c
+++ /dev/null
@@ -1,318 +0,0 @@
-// 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 "gg.h"
-#include "../gc/popt.h"
-
-// Matches real RtoB but can be used in global initializer.
-#define RtoB(r) (1<<((r)-REG_AX))
-
-enum {
-	AX = RtoB(REG_AX),
-	BX = RtoB(REG_BX),
-	CX = RtoB(REG_CX),
-	DX = RtoB(REG_DX),
-	DI = RtoB(REG_DI),
-	SI = RtoB(REG_SI),
-	
-	LeftRdwr = LeftRead | LeftWrite,
-	RightRdwr = RightRead | RightWrite,
-};
-
-#undef RtoB
-
-// This table gives the basic information about instruction
-// generated by the compiler and processed in the optimizer.
-// See opt.h for bit definitions.
-//
-// Instructions not generated need not be listed.
-// As an exception to that rule, we typically write down all the
-// size variants of an operation even if we just use a subset.
-//
-// The table is formatted for 8-space tabs.
-static ProgInfo progtable[ALAST] = {
-	[ATYPE]=	{Pseudo | Skip},
-	[ATEXT]=	{Pseudo},
-	[AFUNCDATA]=	{Pseudo},
-	[APCDATA]=	{Pseudo},
-	[AUNDEF]=	{Break},
-	[AUSEFIELD]=	{OK},
-	[ACHECKNIL]=	{LeftRead},
-	[AVARDEF]=	{Pseudo | RightWrite},
-	[AVARKILL]=	{Pseudo | RightWrite},
-
-	// NOP is an internal no-op that also stands
-	// for USED and SET annotations, not the Intel opcode.
-	[ANOP]=		{LeftRead | RightWrite},
-
-	[AADCL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[AADCQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[AADCW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
-
-	[AADDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AADDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AADDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-	[AADDQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry},
-	
-	[AADDSD]=	{SizeD | LeftRead | RightRdwr},
-	[AADDSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[AANDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AANDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AANDQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry},
-	[AANDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[ACALL]=	{RightAddr | Call | KillCarry},
-
-	[ACDQ]=		{OK, AX, AX | DX},
-	[ACQO]=		{OK, AX, AX | DX},
-	[ACWD]=		{OK, AX, AX | DX},
-
-	[ACLD]=		{OK},
-	[ASTD]=		{OK},
-
-	[ACMPB]=	{SizeB | LeftRead | RightRead | SetCarry},
-	[ACMPL]=	{SizeL | LeftRead | RightRead | SetCarry},
-	[ACMPQ]=	{SizeQ | LeftRead | RightRead | SetCarry},
-	[ACMPW]=	{SizeW | LeftRead | RightRead | SetCarry},
-
-	[ACOMISD]=	{SizeD | LeftRead | RightRead | SetCarry},
-	[ACOMISS]=	{SizeF | LeftRead | RightRead | SetCarry},
-
-	[ACVTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTSD2SQ]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[ACVTSD2SS]=	{SizeF | LeftRead | RightWrite | Conv},
-	[ACVTSL2SD]=	{SizeD | LeftRead | RightWrite | Conv},
-	[ACVTSL2SS]=	{SizeF | LeftRead | RightWrite | Conv},
-	[ACVTSQ2SD]=	{SizeD | LeftRead | RightWrite | Conv},
-	[ACVTSQ2SS]=	{SizeF | LeftRead | RightWrite | Conv},
-	[ACVTSS2SD]=	{SizeD | LeftRead | RightWrite | Conv},
-	[ACVTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTSS2SQ]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[ACVTTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTTSD2SQ]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[ACVTTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTTSS2SQ]=	{SizeQ | LeftRead | RightWrite | Conv},
-
-	[ADECB]=	{SizeB | RightRdwr},
-	[ADECL]=	{SizeL | RightRdwr},
-	[ADECQ]=	{SizeQ | RightRdwr},
-	[ADECW]=	{SizeW | RightRdwr},
-
-	[ADIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[ADIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
-	[ADIVQ]=	{SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
-	[ADIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
-
-	[ADIVSD]=	{SizeD | LeftRead | RightRdwr},
-	[ADIVSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[AIDIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AIDIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
-	[AIDIVQ]=	{SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
-	[AIDIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
-
-	[AIMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AIMULL]=	{SizeL | LeftRead | ImulAXDX | SetCarry},
-	[AIMULQ]=	{SizeQ | LeftRead | ImulAXDX | SetCarry},
-	[AIMULW]=	{SizeW | LeftRead | ImulAXDX | SetCarry},
-
-	[AINCB]=	{SizeB | RightRdwr},
-	[AINCL]=	{SizeL | RightRdwr},
-	[AINCQ]=	{SizeQ | RightRdwr},
-	[AINCW]=	{SizeW | RightRdwr},
-
-	[AJCC]=		{Cjmp | UseCarry},
-	[AJCS]=		{Cjmp | UseCarry},
-	[AJEQ]=		{Cjmp | UseCarry},
-	[AJGE]=		{Cjmp | UseCarry},
-	[AJGT]=		{Cjmp | UseCarry},
-	[AJHI]=		{Cjmp | UseCarry},
-	[AJLE]=		{Cjmp | UseCarry},
-	[AJLS]=		{Cjmp | UseCarry},
-	[AJLT]=		{Cjmp | UseCarry},
-	[AJMI]=		{Cjmp | UseCarry},
-	[AJNE]=		{Cjmp | UseCarry},
-	[AJOC]=		{Cjmp | UseCarry},
-	[AJOS]=		{Cjmp | UseCarry},
-	[AJPC]=		{Cjmp | UseCarry},
-	[AJPL]=		{Cjmp | UseCarry},
-	[AJPS]=		{Cjmp | UseCarry},
-
-	[AJMP]=		{Jump | Break | KillCarry},
-
-	[ALEAL]=	{LeftAddr | RightWrite},
-	[ALEAQ]=	{LeftAddr | RightWrite},
-
-	[AMOVBLSX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVBLZX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVBQSX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVBQZX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVBWSX]=	{SizeW | LeftRead | RightWrite | Conv},
-	[AMOVBWZX]=	{SizeW | LeftRead | RightWrite | Conv},
-	[AMOVLQSX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVLQZX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVWLSX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVWLZX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVWQSX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVWQZX]=	{SizeQ | LeftRead | RightWrite | Conv},
-	[AMOVQL]=	{SizeL | LeftRead | RightWrite | Conv},
-
-	[AMOVB]=	{SizeB | LeftRead | RightWrite | Move},
-	[AMOVL]=	{SizeL | LeftRead | RightWrite | Move},
-	[AMOVQ]=	{SizeQ | LeftRead | RightWrite | Move},
-	[AMOVW]=	{SizeW | LeftRead | RightWrite | Move},
-
-	[AMOVSB]=	{OK, DI|SI, DI|SI},
-	[AMOVSL]=	{OK, DI|SI, DI|SI},
-	[AMOVSQ]=	{OK, DI|SI, DI|SI},
-	[AMOVSW]=	{OK, DI|SI, DI|SI},
-	[ADUFFCOPY]=	{OK, DI|SI, DI|SI|CX},
-
-	[AMOVSD]=	{SizeD | LeftRead | RightWrite | Move},
-	[AMOVSS]=	{SizeF | LeftRead | RightWrite | Move},
-
-	// We use MOVAPD as a faster synonym for MOVSD.
-	[AMOVAPD]=	{SizeD | LeftRead | RightWrite | Move},
-
-	[AMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AMULL]=	{SizeL | LeftRead | SetCarry, AX, AX|DX},
-	[AMULQ]=	{SizeQ | LeftRead | SetCarry, AX, AX|DX},
-	[AMULW]=	{SizeW | LeftRead | SetCarry, AX, AX|DX},
-	
-	[AMULSD]=	{SizeD | LeftRead | RightRdwr},
-	[AMULSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[ANEGB]=	{SizeB | RightRdwr | SetCarry},
-	[ANEGL]=	{SizeL | RightRdwr | SetCarry},
-	[ANEGQ]=	{SizeQ | RightRdwr | SetCarry},
-	[ANEGW]=	{SizeW | RightRdwr | SetCarry},
-
-	[ANOTB]=	{SizeB | RightRdwr},
-	[ANOTL]=	{SizeL | RightRdwr},
-	[ANOTQ]=	{SizeQ | RightRdwr},
-	[ANOTW]=	{SizeW | RightRdwr},
-
-	[AORB]=		{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AORL]=		{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AORQ]=		{SizeQ | LeftRead | RightRdwr | SetCarry},
-	[AORW]=		{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[APOPQ]=	{SizeQ | RightWrite},
-	[APUSHQ]=	{SizeQ | LeftRead},
-
-	[ARCLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCLQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-
-	[ARCRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCRQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-
-	[AREP]=		{OK, CX, CX},
-	[AREPN]=	{OK, CX, CX},
-
-	[ARET]=		{Break | KillCarry},
-
-	[AROLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[AROLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[AROLQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[AROLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ARORB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ARORL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ARORQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ARORW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASALB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASALL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASALQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASALW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASARB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASARL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASARQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASARW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASBBB]=	{SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[ASBBL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[ASBBQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[ASBBW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
-
-	[ASHLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHLQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASHRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHRQ]=	{SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASTOSB]=	{OK, AX|DI, DI},
-	[ASTOSL]=	{OK, AX|DI, DI},
-	[ASTOSQ]=	{OK, AX|DI, DI},
-	[ASTOSW]=	{OK, AX|DI, DI},
-	[ADUFFZERO]=	{OK, AX|DI, DI},
-
-	[ASUBB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[ASUBL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[ASUBQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry},
-	[ASUBW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[ASUBSD]=	{SizeD | LeftRead | RightRdwr},
-	[ASUBSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[ATESTB]=	{SizeB | LeftRead | RightRead | SetCarry},
-	[ATESTL]=	{SizeL | LeftRead | RightRead | SetCarry},
-	[ATESTQ]=	{SizeQ | LeftRead | RightRead | SetCarry},
-	[ATESTW]=	{SizeW | LeftRead | RightRead | SetCarry},
-
-	[AUCOMISD]=	{SizeD | LeftRead | RightRead},
-	[AUCOMISS]=	{SizeF | LeftRead | RightRead},
-
-	[AXCHGB]=	{SizeB | LeftRdwr | RightRdwr},
-	[AXCHGL]=	{SizeL | LeftRdwr | RightRdwr},
-	[AXCHGQ]=	{SizeQ | LeftRdwr | RightRdwr},
-	[AXCHGW]=	{SizeW | LeftRdwr | RightRdwr},
-
-	[AXORB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AXORL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AXORQ]=	{SizeQ | LeftRead | RightRdwr | SetCarry},
-	[AXORW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-};
-
-void
-proginfo(ProgInfo *info, Prog *p)
-{
-	*info = progtable[p->as];
-	if(info->flags == 0)
-		fatal("unknown instruction %P", p);
-
-	if((info->flags & ShiftCX) && p->from.type != TYPE_CONST)
-		info->reguse |= CX;
-
-	if(info->flags & ImulAXDX) {
-		if(p->to.type == TYPE_NONE) {
-			info->reguse |= AX;
-			info->regset |= AX | DX;
-		} else {
-			info->flags |= RightRdwr;
-		}
-	}
-
-	// Addressing makes some registers used.
-	if(p->from.type == TYPE_MEM && p->from.name == NAME_NONE)
-		info->regindex |= RtoB(p->from.reg);
-	if(p->from.index != REG_NONE)
-		info->regindex |= RtoB(p->from.index);
-	if(p->to.type == TYPE_MEM && p->to.name == NAME_NONE)
-		info->regindex |= RtoB(p->to.reg);
-	if(p->to.index != REG_NONE)
-		info->regindex |= RtoB(p->to.index);
-}
diff --git a/src/cmd/new6g/prog.go b/src/cmd/6g/prog.go
similarity index 100%
rename from src/cmd/new6g/prog.go
rename to src/cmd/6g/prog.go
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
deleted file mode 100644
index e01f265..0000000
--- a/src/cmd/6g/reg.c
+++ /dev/null
@@ -1,153 +0,0 @@
-// 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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-enum {
-	NREGVAR = 32,
-};
-
-static char* regname[] = {
-	".AX",
-	".CX",
-	".DX",
-	".BX",
-	".SP",
-	".BP",
-	".SI",
-	".DI",
-	".R8",
-	".R9",
-	".R10",
-	".R11",
-	".R12",
-	".R13",
-	".R14",
-	".R15",
-	".X0",
-	".X1",
-	".X2",
-	".X3",
-	".X4",
-	".X5",
-	".X6",
-	".X7",
-	".X8",
-	".X9",
-	".X10",
-	".X11",
-	".X12",
-	".X13",
-	".X14",
-	".X15",
-};
-
-char**
-regnames(int *n)
-{
-	*n = NREGVAR;
-	return regname;
-}
-
-uint64
-excludedregs(void)
-{
-	return RtoB(REG_SP);
-}
-
-uint64
-doregbits(int r)
-{
-	uint64 b;
-
-	b = 0;
-	if(r >= REG_AX && r <= REG_R15)
-		b |= RtoB(r);
-	else
-	if(r >= REG_AL && r <= REG_R15B)
-		b |= RtoB(r-REG_AL+REG_AX);
-	else
-	if(r >= REG_AH && r <= REG_BH)
-		b |= RtoB(r-REG_AH+REG_AX);
-	else
-	if(r >= REG_X0 && r <= REG_X0+15)
-		b |= FtoB(r);
-	return b;
-}
-
-uint64
-RtoB(int r)
-{
-
-	if(r < REG_AX || r > REG_R15)
-		return 0;
-	return 1ULL << (r-REG_AX);
-}
-
-int
-BtoR(uint64 b)
-{
-	b &= 0xffffULL;
-	if(nacl)
-		b &= ~((1<<(REG_BP-REG_AX)) | (1<<(REG_R15-REG_AX)));
-	else if(framepointer_enabled)
-		// BP is part of the calling convention if framepointer_enabled.
-		b &= ~(1<<(REG_BP-REG_AX));
-	if(b == 0)
-		return 0;
-	return bitno(b) + REG_AX;
-}
-
-/*
- *	bit	reg
- *	16	X0
- *	...
- *	31	X15
- */
-uint64
-FtoB(int f)
-{
-	if(f < REG_X0 || f > REG_X15)
-		return 0;
-	return 1ULL << (f - REG_X0 + 16);
-}
-
-int
-BtoF(uint64 b)
-{
-
-	b &= 0xFFFF0000L;
-	if(b == 0)
-		return 0;
-	return bitno(b) - 16 + REG_X0;
-}
diff --git a/src/cmd/new6g/reg.go b/src/cmd/6g/reg.go
similarity index 100%
rename from src/cmd/new6g/reg.go
rename to src/cmd/6g/reg.go
diff --git a/src/cmd/new6g/util.go b/src/cmd/6g/util.go
similarity index 100%
rename from src/cmd/new6g/util.go
rename to src/cmd/6g/util.go
diff --git a/src/cmd/8a/Makefile b/src/cmd/8a/Makefile
deleted file mode 100644
index 27290dd..0000000
--- a/src/cmd/8a/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
-
-y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/8a/a.h b/src/cmd/8a/a.h
deleted file mode 100644
index 24654b0..0000000
--- a/src/cmd/8a/a.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Inferno utils/8a/a.h
-// http://code.google.com/p/inferno-os/source/browse/utils/8a/a.h
-//
-//	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 <bio.h>
-#include <link.h>
-#include "../8l/8.out.h"
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#undef	getc
-#undef	ungetc
-#undef	BUFSIZ
-
-#define	getc	ccgetc
-#define	ungetc	ccungetc
-
-typedef	struct	Sym	Sym;
-typedef	struct	Ref	Ref;
-typedef	struct	Io	Io;
-typedef	struct	Addr2	Addr2;
-
-#define	MAXALIGN	7
-#define	FPCHIP		1
-#define	NSYMB		500
-#define	BUFSIZ		8192
-#define	HISTSZ		20
-#ifndef	EOF
-#define	EOF		(-1)
-#endif
-#define	IGN		(-2)
-#define	GETC()		((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
-#define	NHASH		503
-#define	STRINGSZ	200
-#define	NMACRO		10
-
-struct	Sym
-{
-	Sym*	link;
-	Ref*	ref;
-	char*	macro;
-	int32	value;
-	ushort	type;
-	char	*name;
-	char*	labelname;
-	char	sym;
-};
-#define	S	((Sym*)0)
-
-struct	Ref
-{
-	int	class;
-};
-
-EXTERN struct
-{
-	char*	p;
-	int	c;
-} fi;
-
-struct	Io
-{
-	Io*	link;
-	char	b[BUFSIZ];
-	char*	p;
-	short	c;
-	short	f;
-};
-#define	I	((Io*)0)
-
-struct	Addr2
-{
-	Addr	from;
-	Addr	to;
-};
-
-enum
-{
-	CLAST,
-	CMACARG,
-	CMACRO,
-	CPREPROC,
-};
-
-EXTERN	int	debug[256];
-EXTERN	Sym*	hash[NHASH];
-EXTERN	char**	Dlist;
-EXTERN	int	nDlist;
-EXTERN	int	newflag;
-EXTERN	char*	hunk;
-EXTERN	char**	include;
-EXTERN	Io*	iofree;
-EXTERN	Io*	ionext;
-EXTERN	Io*	iostack;
-EXTERN	int32	lineno;
-EXTERN	int	nerrors;
-EXTERN	int32	nhunk;
-EXTERN	int	ninclude;
-EXTERN	int32	nsymb;
-EXTERN	Addr	nullgen;
-EXTERN	char*	outfile;
-EXTERN	int	pass;
-EXTERN	int32	pc;
-EXTERN	int	peekc;
-EXTERN	int32	stmtline;
-EXTERN	int	sym;
-EXTERN	char*	symb;
-EXTERN	int	thechar;
-EXTERN	char*	thestring;
-EXTERN	int32	thunk;
-EXTERN	Biobuf	obuf;
-EXTERN	Link*	ctxt;
-EXTERN	Biobuf	bstdout;
-EXTERN	Prog*	lastpc;
-
-void*	alloc(int32);
-void*	allocn(void*, int32, int32);
-void	ensuresymb(int32);
-void	errorexit(void);
-void	pushio(void);
-void	newio(void);
-void	newfile(char*, int);
-Sym*	slookup(char*);
-Sym*	lookup(void);
-Sym*	labellookup(Sym*);
-void	settext(LSym*);
-void	syminit(Sym*);
-int32	yylex(void);
-int	getc(void);
-int	getnsc(void);
-void	unget(int);
-int	escchar(int);
-void	cinit(void);
-void	checkscale(int);
-void	pinit(char*);
-void	cclean(void);
-int	isreg(Addr*);
-void	outcode(int, Addr2*);
-void	outhist(void);
-int	filbuf(void);
-Sym*	getsym(void);
-void	domacro(void);
-void	macund(void);
-void	macdef(void);
-void	macexpand(Sym*, char*);
-void	macinc(void);
-void	macprag(void);
-void	maclin(void);
-void	macif(int);
-void	macend(void);
-void	dodefine(char*);
-void	prfile(int32);
-void	linehist(char*, int);
-void	gethunk(void);
-void	yyerror(char*, ...);
-int	yyparse(void);
-void	setinclude(char*);
-int	assemble(char*);
diff --git a/src/cmd/8a/a.y b/src/cmd/8a/a.y
index 1a3ab72..906ad33 100644
--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -29,20 +29,28 @@
 // THE SOFTWARE.
 
 %{
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
+package main
+
+import (
+	"cmd/internal/asm"
+	"cmd/internal/obj"
+	. "cmd/internal/obj/i386"
+)
 %}
-%union	{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
+
+%union {
+	sym *asm.Sym
+	lval int64
+	con2 struct {
+		v1 int32
+		v2 int32
+	}
+	dval float64
+	sval string
+	addr obj.Addr
+	addr2 Addr2
 }
+
 %left	'|'
 %left	'^'
 %left	'&'
@@ -64,18 +72,19 @@
 prog:
 |	prog
 	{
-		stmtline = lineno;
+		stmtline = asm.Lineno;
 	}
 	line
 
 line:
 	LNAME ':'
 	{
-		$1 = labellookup($1);
-		if($1->type == LLAB && $1->value != pc)
-			yyerror("redeclaration of %s", $1->labelname);
-		$1->type = LLAB;
-		$1->value = pc;
+		$1 = asm.LabelLookup($1);
+		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
+			yyerror("redeclaration of %s", $1.Labelname)
+		}
+		$1.Type = LLAB;
+		$1.Value = int64(asm.PC)
 	}
 	line
 |	';'
@@ -85,33 +94,34 @@
 inst:
 	LNAME '=' expr
 	{
-		$1->type = LVAR;
-		$1->value = $3;
+		$1.Type = LVAR;
+		$1.Value = $3;
 	}
 |	LVAR '=' expr
 	{
-		if($1->value != $3)
-			yyerror("redeclaration of %s", $1->name);
-		$1->value = $3;
+		if $1.Value != int64($3) {
+			yyerror("redeclaration of %s", $1.Name);
+		}
+		$1.Value = $3;
 	}
-|	LTYPE0 nonnon	{ outcode($1, &$2); }
-|	LTYPE1 nonrem	{ outcode($1, &$2); }
-|	LTYPE2 rimnon	{ outcode($1, &$2); }
-|	LTYPE3 rimrem	{ outcode($1, &$2); }
-|	LTYPE4 remrim	{ outcode($1, &$2); }
-|	LTYPER nonrel	{ outcode($1, &$2); }
+|	LTYPE0 nonnon	{ outcode(int($1), &$2); }
+|	LTYPE1 nonrem	{ outcode(int($1), &$2); }
+|	LTYPE2 rimnon	{ outcode(int($1), &$2); }
+|	LTYPE3 rimrem	{ outcode(int($1), &$2); }
+|	LTYPE4 remrim	{ outcode(int($1), &$2); }
+|	LTYPER nonrel	{ outcode(int($1), &$2); }
 |	spec1
 |	spec2
-|	LTYPEC spec3	{ outcode($1, &$2); }
-|	LTYPEN spec4	{ outcode($1, &$2); }
-|	LTYPES spec5	{ outcode($1, &$2); }
-|	LTYPEM spec6	{ outcode($1, &$2); }
-|	LTYPEI spec7	{ outcode($1, &$2); }
+|	LTYPEC spec3	{ outcode(int($1), &$2); }
+|	LTYPEN spec4	{ outcode(int($1), &$2); }
+|	LTYPES spec5	{ outcode(int($1), &$2); }
+|	LTYPEM spec6	{ outcode(int($1), &$2); }
+|	LTYPEI spec7	{ outcode(int($1), &$2); }
 |	spec8
-|	LTYPEXC spec9	{ outcode($1, &$2); }
-|	LTYPEX spec10	{ outcode($1, &$2); }
-|	LTYPEPC spec11	{ outcode($1, &$2); }
-|	LTYPEF spec12	{ outcode($1, &$2); }
+|	LTYPEXC spec9	{ outcode(int($1), &$2); }
+|	LTYPEX spec10	{ outcode(int($1), &$2); }
+|	LTYPEPC spec11	{ outcode(int($1), &$2); }
+|	LTYPEF spec12	{ outcode(int($1), &$2); }
 
 nonnon:
 	{
@@ -182,60 +192,46 @@
 spec1:	/* DATA */
 	LTYPED nam '/' con ',' imm
 	{
-		Addr2 a;
-		a.from = $2;
-		a.to = $6;
-		outcode(ADATA, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		outcode(obj.ADATA, &Addr2{$2, $6})
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
 spec2:	/* TEXT */
 	LTYPET mem ',' '$' textsize
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $5;
-		outcode(ATEXT, &a);
+		asm.Settext($2.Sym);
+		outcode(obj.ATEXT, &Addr2{$2, $5})
 	}
 |	LTYPET mem ',' con ',' '$' textsize
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $7;
-		outcode(ATEXT, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym);
+		outcode(obj.ATEXT, &Addr2{$2, $7})
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
 spec8:	/* GLOBL */
 	LTYPEG mem ',' imm
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $4;
-		outcode(AGLOBL, &a);
+		asm.Settext($2.Sym);
+		outcode(obj.AGLOBL, &Addr2{$2, $4})
 	}
 |	LTYPEG mem ',' con ',' imm
 	{
-		Addr2 a;
-		settext($2.sym);
-		a.from = $2;
-		a.to = $6;
-		outcode(AGLOBL, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym);
+		outcode(obj.AGLOBL, &Addr2{$2, $6})
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
+
 spec3:	/* JMP/CALL */
 	',' rom
 	{
@@ -251,7 +247,7 @@
 	{
 		$$.from = nullgen;
 		$$.to = $2;
-		$$.to.type = TYPE_INDIR;
+		$$.to.Type = obj.TYPE_INDIR
 	}
 
 spec4:	/* NOP */
@@ -268,9 +264,10 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		if($$.from.index != TYPE_NONE)
+		if $$.from.Index != obj.TYPE_NONE {
 			yyerror("dp shift with lhs index");
-		$$.from.index = $5;
+		}
+		$$.from.Index = int16($5);
 	}
 
 spec6:	/* MOVW/MOVL */
@@ -283,9 +280,10 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		if($$.to.index != TYPE_NONE)
+		if $$.to.Index != obj.TYPE_NONE {
 			yyerror("dp move with lhs index");
-		$$.to.index = $5;
+		}
+		$$.to.Index = int16($5);
 	}
 
 spec7:
@@ -310,7 +308,7 @@
 	{
 		$$.from = $1;
 		$$.to = $3;
-		$$.to.offset = $5;
+		$$.to.Offset = $5;
 	}
 
 spec10:	/* PINSRD */
@@ -318,16 +316,18 @@
 	{
 		$$.from = $3;
 		$$.to = $5;
-		if($1.type != TYPE_CONST)
-			yyerror("illegal constant");
-		$$.to.offset = $1.offset;
+		if $1.Type != obj.TYPE_CONST {
+			yyerror("illegal constant")
+		}
+		$$.to.Offset = $1.Offset;
 	}
 
 spec11:	/* PCDATA */
 	rim ',' rim
 	{
-		if($1.type != TYPE_CONST || $3.type != TYPE_CONST)
+		if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
 			yyerror("arguments to PCDATA must be integer constants");
+		}
 		$$.from = $1;
 		$$.to = $3;
 	}
@@ -335,10 +335,12 @@
 spec12:	/* FUNCDATA */
 	rim ',' rim
 	{
-		if($1.type != TYPE_CONST)
+		if $1.Type != obj.TYPE_CONST {
 			yyerror("index for FUNCDATA must be integer constant");
-		if($3.type != TYPE_MEM || ($3.name != NAME_EXTERN && $3.name != NAME_STATIC))
+		}
+		if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
 			yyerror("value for FUNCDATA must be symbol reference");
+		}
  		$$.from = $1;
  		$$.to = $3;
  	}
@@ -370,135 +372,137 @@
 	con '(' LPC ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1 + pc;
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1 + int64(asm.PC);
 	}
 |	LNAME offset
 	{
-		$1 = labellookup($1);
+		$1 = asm.LabelLookup($1);
 		$$ = nullgen;
-		if(pass == 2 && $1->type != LLAB)
-			yyerror("undefined label: %s", $1->labelname);
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1->value + $2;
+		if asm.Pass == 2 && $1.Type != LLAB {
+			yyerror("undefined label: %s", $1.Labelname);
+		}
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1.Value + $2;
 	}
 
 reg:
 	LBREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LFREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LLREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LXREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 |	LSP
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = REG_SP;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = REG_SP;
 	}
 |	LSREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1);
 	}
 
 imm:
 	'$' con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		$$.offset = $2;
+		$$.Type = obj.TYPE_CONST;
+		$$.Offset = $2;
 	}
 |	'$' nam
 	{
 		$$ = $2;
-		$$.type = TYPE_ADDR;
+		$$.Type = obj.TYPE_ADDR
 		/*
-		if($2.name == NAME_AUTO || $2.name == NAME_PARAM)
+		if($2.Type == D_AUTO || $2.Type == D_PARAM)
 			yyerror("constant cannot be automatic: %s",
-				$2.sym->name);
+				$2.Sym.name);
 		 */
 	}
 |	'$' LSCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SCONST;
-		memcpy($$.u.sval, $2, sizeof($$.u.sval));
+		$$.Type = obj.TYPE_SCONST;
+		$$.U.Sval = $2
 	}
 |	'$' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $2;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $2;
 	}
 |	'$' '(' LFCONST ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $3;
 	}
 |	'$' '(' '-' LFCONST ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$4;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$4;
 	}
 |	'$' '-' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$3;
 	}
 
 textsize:
 	LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = $1;
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	'-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -$2;
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = $3;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = $1;
+		$$.U.Argsize = int32($3);
 	}
 |	'-' LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = $4;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -$2;
+		$$.U.Argsize = int32($4);
 	}
 
+
 mem:
 	omem
 |	nmem
@@ -507,90 +511,87 @@
 	con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_NONE;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Offset = $1;
 	}
 |	con '(' LLREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
 	}
 |	con '(' LSP ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_SP;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = REG_SP
+		$$.Offset = $1;
 	}
 |	con '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_NONE;
-		$$.offset = $1;
-		$$.index = $3;
-		$$.scale = $5;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Offset = $1;
+		$$.Index = int16($3);
+		$$.Scale = int8($5);
+		checkscale($$.Scale);
 	}
 |	con '(' LLREG ')' '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
-		$$.index = $6;
-		$$.scale = $8;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
+		$$.Index = int16($6);
+		$$.Scale = int8($8);
+		checkscale($$.Scale);
 	}
 |	con '(' LLREG ')' '(' LSREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
-		$$.index = $6;
-		$$.scale = $8;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
+		$$.Index = int16($6);
+		$$.Scale = int8($8);
+		checkscale($$.Scale);
 	}
 |	'(' LLREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($2);
 	}
 |	'(' LSP ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_SP;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = REG_SP
 	}
 |	con '(' LSREG ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($3)
+		$$.Offset = $1;
 	}
 |	'(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = REG_NONE;
-		$$.index = $2;
-		$$.scale = $4;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Index = int16($2);
+		$$.Scale = int8($4);
+		checkscale($$.Scale);
 	}
 |	'(' LLREG ')' '(' LLREG '*' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
-		$$.index = $5;
-		$$.scale = $7;
-		checkscale($$.scale);
+		$$.Type = obj.TYPE_MEM
+		$$.Reg = int16($2)
+		$$.Index = int16($5);
+		$$.Scale = int8($7);
+		checkscale($$.Scale);
 	}
 
 nmem:
@@ -601,27 +602,27 @@
 |	nam '(' LLREG '*' con ')'
 	{
 		$$ = $1;
-		$$.index = $3;
-		$$.scale = $5;
-		checkscale($$.scale);
+		$$.Index = int16($3);
+		$$.Scale = int8($5);
+		checkscale($$.Scale);
 	}
 
 nam:
 	LNAME offset '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $4;
-		$$.sym = linklookup(ctxt, $1->name, 0);
-		$$.offset = $2;
+		$$.Type = obj.TYPE_MEM
+		$$.Name = int8($4);
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
+		$$.Offset = $2;
 	}
 |	LNAME '<' '>' offset '(' LSB ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = NAME_STATIC;
-		$$.sym = linklookup(ctxt, $1->name, 1);
-		$$.offset = $4;
+		$$.Type = obj.TYPE_MEM
+		$$.Name = obj.NAME_STATIC
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
+		$$.Offset = $4;
 	}
 
 offset:
@@ -641,7 +642,7 @@
 	LSB
 |	LSP
 	{
-		$$ = NAME_AUTO;
+		$$ = obj.NAME_AUTO;
 	}
 |	LFP
 
@@ -649,7 +650,7 @@
 	LCONST
 |	LVAR
 	{
-		$$ = $1->value;
+		$$ = $1.Value;
 	}
 |	'-' con
 	{
@@ -661,7 +662,7 @@
 	}
 |	'~' con
 	{
-		$$ = ~$2;
+		$$ = ^$2;
 	}
 |	'(' expr ')'
 	{
@@ -692,11 +693,11 @@
 	}
 |	expr '<' '<' expr
 	{
-		$$ = $1 << $4;
+		$$ = $1 << uint($4);
 	}
 |	expr '>' '>' expr
 	{
-		$$ = $1 >> $4;
+		$$ = $1 >> uint($4);
 	}
 |	expr '&' expr
 	{
diff --git a/src/cmd/8a/doc.go b/src/cmd/8a/doc.go
deleted file mode 100644
index 84c7254..0000000
--- a/src/cmd/8a/doc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
-
-/*
-
-8a is a version of the Plan 9 assembler.  The original is documented at
-
-	http://plan9.bell-labs.com/magic/man2html/1/8a
-
-Go-specific considerations are documented at
-
-	http://golang.org/doc/asm
-
-I
-Its target architecture is the x86, referred to by these tools for historical reasons as 386.
-
-*/
-package main
diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c
deleted file mode 100644
index 846f6c6..0000000
--- a/src/cmd/8a/lex.c
+++ /dev/null
@@ -1,914 +0,0 @@
-// Inferno utils/8a/lex.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8a/lex.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.
-
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "a.h"
-#include "y.tab.h"
-
-enum
-{
-	Plan9	= 1<<0,
-	Unix	= 1<<1,
-	Windows	= 1<<2,
-};
-
-int
-systemtype(int sys)
-{
-#ifdef _WIN32
-	return sys&Windows;
-#else
-	return sys&Plan9;
-#endif
-}
-
-int
-pathchar(void)
-{
-	return '/';
-}
-
-int
-Lconv(Fmt *fp)
-{
-	return linklinefmt(ctxt, fp);
-}
-
-void
-dodef(char *p)
-{
-	if(nDlist%8 == 0)
-		Dlist = allocn(Dlist, nDlist*sizeof(char *),
-			8*sizeof(char *));
-	Dlist[nDlist++] = p;
-}
-
-void
-usage(void)
-{
-	print("usage: %ca [options] file.c...\n", thechar);
-	flagprint(1);
-	errorexit();
-}
-void
-main(int argc, char *argv[])
-{
-	char *p;
-
-	thechar = '8';
-	thestring = "386";
-
-	ctxt = linknew(&link386);
-	ctxt->diag = yyerror;
-	ctxt->bso = &bstdout;
-	ctxt->enforce_data_order = 1;
-	Binit(&bstdout, 1, OWRITE);
-	listinit8();
-	fmtinstall('L', Lconv);
-
-	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
-	// but not other values.	
-	p = getgoarch();
-	if(strncmp(p, thestring, strlen(thestring)) != 0)
-		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
-
-	ensuresymb(NSYMB);
-	memset(debug, 0, sizeof(debug));
-	cinit();
-	outfile = 0;
-	setinclude(".");
-	
-	flagfn1("D", "name[=value]: add #define", dodef);
-	flagfn1("I", "dir: add dir to include path", setinclude);
-	flagcount("S", "print assembly and machine code", &debug['S']);
-	flagcount("m", "debug preprocessor macros", &debug['m']);
-	flagstr("o", "file: set output file", &outfile);
-	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
-
-	flagparse(&argc, &argv, usage);
-	ctxt->debugasm = debug['S'];
-
-	if(argc < 1)
-		usage();
-	if(argc > 1){
-		print("can't assemble multiple files\n");
-		errorexit();
-	}
-
-	if(assemble(argv[0]))
-		errorexit();
-	Bflush(&bstdout);
-	if(nerrors > 0)
-		errorexit();
-	exits(0);
-}
-
-int
-assemble(char *file)
-{
-	char *ofile, *p;
-	int i, of;
-
-	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
-	strcpy(ofile, file);
-	p = utfrrune(ofile, pathchar());
-	if(p) {
-		include[0] = ofile;
-		*p++ = 0;
-	} else
-		p = ofile;
-	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
-			p = utfrrune(outfile, '.');
-			if(p)
-				if(p[1] == 's' && p[2] == 0)
-					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
-		} else
-			outfile = "/dev/null";
-	}
-
-	of = create(outfile, OWRITE, 0664);
-	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
-		errorexit();
-	}
-	Binit(&obuf, of, OWRITE);
-	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
-	Bprint(&obuf, "!\n");
-
-	for(pass = 1; pass <= 2; pass++) {
-		pinit(file);
-		for(i=0; i<nDlist; i++)
-			dodefine(Dlist[i]);
-		yyparse();
-		cclean();
-		if(nerrors)
-			return nerrors;
-	}
-
-	writeobj(ctxt, &obuf);
-	Bflush(&obuf);
-	return 0;
-}
-
-struct
-{
-	char	*name;
-	ushort	type;
-	ushort	value;
-} itab[] =
-{
-	"SP",		LSP,	NAME_AUTO,
-	"SB",		LSB,	NAME_EXTERN,
-	"FP",		LFP,	NAME_PARAM,
-
-	"PC",		LPC,	TYPE_BRANCH,
-
-	"AL",		LBREG,	REG_AL,
-	"CL",		LBREG,	REG_CL,
-	"DL",		LBREG,	REG_DL,
-	"BL",		LBREG,	REG_BL,
-	"AH",		LBREG,	REG_AH,
-	"CH",		LBREG,	REG_CH,
-	"DH",		LBREG,	REG_DH,
-	"BH",		LBREG,	REG_BH,
-
-	"AX",		LLREG,	REG_AX,
-	"CX",		LLREG,	REG_CX,
-	"DX",		LLREG,	REG_DX,
-	"BX",		LLREG,	REG_BX,
-/*	"SP",		LLREG,	REG_SP,	*/
-	"BP",		LLREG,	REG_BP,
-	"SI",		LLREG,	REG_SI,
-	"DI",		LLREG,	REG_DI,
-
-	"F0",		LFREG,	REG_F0+0,
-	"F1",		LFREG,	REG_F0+1,
-	"F2",		LFREG,	REG_F0+2,
-	"F3",		LFREG,	REG_F0+3,
-	"F4",		LFREG,	REG_F0+4,
-	"F5",		LFREG,	REG_F0+5,
-	"F6",		LFREG,	REG_F0+6,
-	"F7",		LFREG,	REG_F0+7,
-
-	"X0",		LXREG,	REG_X0+0,
-	"X1",		LXREG,	REG_X0+1,
-	"X2",		LXREG,	REG_X0+2,
-	"X3",		LXREG,	REG_X0+3,
-	"X4",		LXREG,	REG_X0+4,
-	"X5",		LXREG,	REG_X0+5,
-	"X6",		LXREG,	REG_X0+6,
-	"X7",		LXREG,	REG_X0+7,
-
-	"CS",		LSREG,	REG_CS,
-	"SS",		LSREG,	REG_SS,
-	"DS",		LSREG,	REG_DS,
-	"ES",		LSREG,	REG_ES,
-	"FS",		LSREG,	REG_FS,
-	"GS",		LSREG,	REG_GS,
-	"TLS",		LSREG,	REG_TLS,
-
-	"GDTR",		LBREG,	REG_GDTR,
-	"IDTR",		LBREG,	REG_IDTR,
-	"LDTR",		LBREG,	REG_LDTR,
-	"MSW",		LBREG,	REG_MSW,
-	"TASK",		LBREG,	REG_TASK,
-
-	"CR0",		LBREG,	REG_CR+0,
-	"CR1",		LBREG,	REG_CR+1,
-	"CR2",		LBREG,	REG_CR+2,
-	"CR3",		LBREG,	REG_CR+3,
-	"CR4",		LBREG,	REG_CR+4,
-	"CR5",		LBREG,	REG_CR+5,
-	"CR6",		LBREG,	REG_CR+6,
-	"CR7",		LBREG,	REG_CR+7,
-
-	"DR0",		LBREG,	REG_DR+0,
-	"DR1",		LBREG,	REG_DR+1,
-	"DR2",		LBREG,	REG_DR+2,
-	"DR3",		LBREG,	REG_DR+3,
-	"DR4",		LBREG,	REG_DR+4,
-	"DR5",		LBREG,	REG_DR+5,
-	"DR6",		LBREG,	REG_DR+6,
-	"DR7",		LBREG,	REG_DR+7,
-
-	"TR0",		LBREG,	REG_TR+0,
-	"TR1",		LBREG,	REG_TR+1,
-	"TR2",		LBREG,	REG_TR+2,
-	"TR3",		LBREG,	REG_TR+3,
-	"TR4",		LBREG,	REG_TR+4,
-	"TR5",		LBREG,	REG_TR+5,
-	"TR6",		LBREG,	REG_TR+6,
-	"TR7",		LBREG,	REG_TR+7,
-
-	"AAA",		LTYPE0,	AAAA,
-	"AAD",		LTYPE0,	AAAD,
-	"AAM",		LTYPE0,	AAAM,
-	"AAS",		LTYPE0,	AAAS,
-	"ADCB",		LTYPE3,	AADCB,
-	"ADCL",		LTYPE3,	AADCL,
-	"ADCW",		LTYPE3,	AADCW,
-	"ADDB",		LTYPE3,	AADDB,
-	"ADDL",		LTYPE3,	AADDL,
-	"ADDW",		LTYPE3,	AADDW,
-	"ADJSP",	LTYPE2,	AADJSP,
-	"ANDB",		LTYPE3,	AANDB,
-	"ANDL",		LTYPE3,	AANDL,
-	"ANDW",		LTYPE3,	AANDW,
-	"ARPL",		LTYPE3,	AARPL,
-	"BOUNDL",	LTYPE3,	ABOUNDL,
-	"BOUNDW",	LTYPE3,	ABOUNDW,
-	"BSFL",		LTYPE3,	ABSFL,
-	"BSFW",		LTYPE3,	ABSFW,
-	"BSRL",		LTYPE3,	ABSRL,
-	"BSRW",		LTYPE3,	ABSRW,
-	"BSWAPL",	LTYPE1,	ABSWAPL,
-	"BTCL",		LTYPE3,	ABTCL,
-	"BTCW",		LTYPE3,	ABTCW,
-	"BTL",		LTYPE3,	ABTL,
-	"BTRL",		LTYPE3,	ABTRL,
-	"BTRW",		LTYPE3,	ABTRW,
-	"BTSL",		LTYPE3,	ABTSL,
-	"BTSW",		LTYPE3,	ABTSW,
-	"BTW",		LTYPE3,	ABTW,
-	"BYTE",		LTYPE2,	ABYTE,
-	"CALL",		LTYPEC,	ACALL,
-	"CLC",		LTYPE0,	ACLC,
-	"CLD",		LTYPE0,	ACLD,
-	"CLI",		LTYPE0,	ACLI,
-	"CLTS",		LTYPE0,	ACLTS,
-	"CMC",		LTYPE0,	ACMC,
-	"CMPB",		LTYPE4,	ACMPB,
-	"CMPL",		LTYPE4,	ACMPL,
-	"CMPW",		LTYPE4,	ACMPW,
-	"CMPSB",	LTYPE0,	ACMPSB,
-	"CMPSL",	LTYPE0,	ACMPSL,
-	"CMPSW",	LTYPE0,	ACMPSW,
-	"CMPXCHG8B",	LTYPE1,	ACMPXCHG8B,
-	"CMPXCHGB",	LTYPE3,	ACMPXCHGB,
-	"CMPXCHGL",	LTYPE3,	ACMPXCHGL,
-	"CMPXCHGW",	LTYPE3,	ACMPXCHGW,
-	"CPUID",	LTYPE0,	ACPUID,
-	"DAA",		LTYPE0,	ADAA,
-	"DAS",		LTYPE0,	ADAS,
-	"DATA",		LTYPED,	ADATA,
-	"DECB",		LTYPE1,	ADECB,
-	"DECL",		LTYPE1,	ADECL,
-	"DECW",		LTYPE1,	ADECW,
-	"DIVB",		LTYPE2,	ADIVB,
-	"DIVL",		LTYPE2,	ADIVL,
-	"DIVW",		LTYPE2,	ADIVW,
-	"END",		LTYPE0,	AEND,
-	"ENTER",	LTYPE2,	AENTER,
-	"GLOBL",	LTYPEG,	AGLOBL,
-	"HLT",		LTYPE0,	AHLT,
-	"IDIVB",	LTYPE2,	AIDIVB,
-	"IDIVL",	LTYPE2,	AIDIVL,
-	"IDIVW",	LTYPE2,	AIDIVW,
-	"IMULB",	LTYPE2,	AIMULB,
-	"IMULL",	LTYPEI,	AIMULL,
-	"IMULW",	LTYPEI,	AIMULW,
-	"INB",		LTYPE0,	AINB,
-	"INL",		LTYPE0,	AINL,
-	"INW",		LTYPE0,	AINW,
-	"INCB",		LTYPE1,	AINCB,
-	"INCL",		LTYPE1,	AINCL,
-	"INCW",		LTYPE1,	AINCW,
-	"INSB",		LTYPE0,	AINSB,
-	"INSL",		LTYPE0,	AINSL,
-	"INSW",		LTYPE0,	AINSW,
-	"INT",		LTYPE2,	AINT,
-	"INTO",		LTYPE0,	AINTO,
-	"IRETL",	LTYPE0,	AIRETL,
-	"IRETW",	LTYPE0,	AIRETW,
-
-	"JOS",		LTYPER,	AJOS,	/* overflow set (OF = 1) */
-	"JO",		LTYPER,	AJOS,	/* alternate */
-	"JOC",		LTYPER,	AJOC,	/* overflow clear (OF = 0) */
-	"JNO",		LTYPER,	AJOC,	/* alternate */
-	"JCS",		LTYPER,	AJCS,	/* carry set (CF = 1) */
-	"JB",		LTYPER,	AJCS,	/* alternate */
-	"JC",		LTYPER,	AJCS,	/* alternate */
-	"JNAE",		LTYPER,	AJCS,	/* alternate */
-	"JLO",		LTYPER,	AJCS,	/* alternate */
-	"JCC",		LTYPER,	AJCC,	/* carry clear (CF = 0) */
-	"JAE",		LTYPER,	AJCC,	/* alternate */
-	"JNB",		LTYPER,	AJCC,	/* alternate */
-	"JNC",		LTYPER,	AJCC,	/* alternate */
-	"JHS",		LTYPER,	AJCC,	/* alternate */
-	"JEQ",		LTYPER,	AJEQ,	/* equal (ZF = 1) */
-	"JE",		LTYPER,	AJEQ,	/* alternate */
-	"JZ",		LTYPER,	AJEQ,	/* alternate */
-	"JNE",		LTYPER,	AJNE,	/* not equal (ZF = 0) */
-	"JNZ",		LTYPER,	AJNE,	/* alternate */
-	"JLS",		LTYPER,	AJLS,	/* lower or same (unsigned) (CF = 1 || ZF = 1) */
-	"JBE",		LTYPER,	AJLS,	/* alternate */
-	"JNA",		LTYPER,	AJLS,	/* alternate */
-	"JHI",		LTYPER,	AJHI,	/* higher (unsigned) (CF = 0 && ZF = 0) */
-	"JA",		LTYPER,	AJHI,	/* alternate */
-	"JNBE",		LTYPER,	AJHI,	/* alternate */
-	"JMI",		LTYPER,	AJMI,	/* negative (minus) (SF = 1) */
-	"JS",		LTYPER,	AJMI,	/* alternate */
-	"JPL",		LTYPER,	AJPL,	/* non-negative (plus) (SF = 0) */
-	"JNS",		LTYPER,	AJPL,	/* alternate */
-	"JPS",		LTYPER,	AJPS,	/* parity set (PF = 1) */
-	"JP",		LTYPER,	AJPS,	/* alternate */
-	"JPE",		LTYPER,	AJPS,	/* alternate */
-	"JPC",		LTYPER,	AJPC,	/* parity clear (PF = 0) */
-	"JNP",		LTYPER,	AJPC,	/* alternate */
-	"JPO",		LTYPER,	AJPC,	/* alternate */
-	"JLT",		LTYPER,	AJLT,	/* less than (signed) (SF != OF) */
-	"JL",		LTYPER,	AJLT,	/* alternate */
-	"JNGE",		LTYPER,	AJLT,	/* alternate */
-	"JGE",		LTYPER,	AJGE,	/* greater than or equal (signed) (SF = OF) */
-	"JNL",		LTYPER,	AJGE,	/* alternate */
-	"JLE",		LTYPER,	AJLE,	/* less than or equal (signed) (ZF = 1 || SF != OF) */
-	"JNG",		LTYPER,	AJLE,	/* alternate */
-	"JGT",		LTYPER,	AJGT,	/* greater than (signed) (ZF = 0 && SF = OF) */
-	"JG",		LTYPER,	AJGT,	/* alternate */
-	"JNLE",		LTYPER,	AJGT,	/* alternate */
-
-	"JCXZL",	LTYPER,	AJCXZL,
-	"JCXZW",	LTYPER,	AJCXZW,
-	"JMP",		LTYPEC,	AJMP,
-	"LAHF",		LTYPE0,	ALAHF,
-	"LARL",		LTYPE3,	ALARL,
-	"LARW",		LTYPE3,	ALARW,
-	"LEAL",		LTYPE3,	ALEAL,
-	"LEAW",		LTYPE3,	ALEAW,
-	"LEAVEL",	LTYPE0,	ALEAVEL,
-	"LEAVEW",	LTYPE0,	ALEAVEW,
-	"LOCK",		LTYPE0,	ALOCK,
-	"LODSB",	LTYPE0,	ALODSB,
-	"LODSL",	LTYPE0,	ALODSL,
-	"LODSW",	LTYPE0,	ALODSW,
-	"LONG",		LTYPE2,	ALONG,
-	"LOOP",		LTYPER,	ALOOP,
-	"LOOPEQ",	LTYPER,	ALOOPEQ,
-	"LOOPNE",	LTYPER,	ALOOPNE,
-	"LSLL",		LTYPE3,	ALSLL,
-	"LSLW",		LTYPE3,	ALSLW,
-	"MOVB",		LTYPE3,	AMOVB,
-	"MOVL",		LTYPEM,	AMOVL,
-	"MOVW",		LTYPEM,	AMOVW,
-	"MOVQ",		LTYPEM, AMOVQ,
-	"MOVBLSX",	LTYPE3, AMOVBLSX,
-	"MOVBLZX",	LTYPE3, AMOVBLZX,
-	"MOVBWSX",	LTYPE3, AMOVBWSX,
-	"MOVBWZX",	LTYPE3, AMOVBWZX,
-	"MOVWLSX",	LTYPE3, AMOVWLSX,
-	"MOVWLZX",	LTYPE3, AMOVWLZX,
-	"MOVSB",	LTYPE0,	AMOVSB,
-	"MOVSL",	LTYPE0,	AMOVSL,
-	"MOVSW",	LTYPE0,	AMOVSW,
-	"MULB",		LTYPE2,	AMULB,
-	"MULL",		LTYPE2,	AMULL,
-	"MULW",		LTYPE2,	AMULW,
-	"NEGB",		LTYPE1,	ANEGB,
-	"NEGL",		LTYPE1,	ANEGL,
-	"NEGW",		LTYPE1,	ANEGW,
-	"NOP",		LTYPEN,	ANOP,
-	"NOTB",		LTYPE1,	ANOTB,
-	"NOTL",		LTYPE1,	ANOTL,
-	"NOTW",		LTYPE1,	ANOTW,
-	"ORB",		LTYPE3,	AORB,
-	"ORL",		LTYPE3,	AORL,
-	"ORW",		LTYPE3,	AORW,
-	"OUTB",		LTYPE0,	AOUTB,
-	"OUTL",		LTYPE0,	AOUTL,
-	"OUTW",		LTYPE0,	AOUTW,
-	"OUTSB",	LTYPE0,	AOUTSB,
-	"OUTSL",	LTYPE0,	AOUTSL,
-	"OUTSW",	LTYPE0,	AOUTSW,
-	"PAUSE",	LTYPEN,	APAUSE,
-	"PINSRD",	LTYPEX,	APINSRD,
-	"POPAL",	LTYPE0,	APOPAL,
-	"POPAW",	LTYPE0,	APOPAW,
-	"POPFL",	LTYPE0,	APOPFL,
-	"POPFW",	LTYPE0,	APOPFW,
-	"POPL",		LTYPE1,	APOPL,
-	"POPW",		LTYPE1,	APOPW,
-	"PUSHAL",	LTYPE0,	APUSHAL,
-	"PUSHAW",	LTYPE0,	APUSHAW,
-	"PUSHFL",	LTYPE0,	APUSHFL,
-	"PUSHFW",	LTYPE0,	APUSHFW,
-	"PUSHL",	LTYPE2,	APUSHL,
-	"PUSHW",	LTYPE2,	APUSHW,
-	"RCLB",		LTYPE3,	ARCLB,
-	"RCLL",		LTYPE3,	ARCLL,
-	"RCLW",		LTYPE3,	ARCLW,
-	"RCRB",		LTYPE3,	ARCRB,
-	"RCRL",		LTYPE3,	ARCRL,
-	"RCRW",		LTYPE3,	ARCRW,
-	"RDTSC",	LTYPE0,	ARDTSC,
-	"REP",		LTYPE0,	AREP,
-	"REPN",		LTYPE0,	AREPN,
-	"RET",		LTYPE0,	ARET,
-	"ROLB",		LTYPE3,	AROLB,
-	"ROLL",		LTYPE3,	AROLL,
-	"ROLW",		LTYPE3,	AROLW,
-	"RORB",		LTYPE3,	ARORB,
-	"RORL",		LTYPE3,	ARORL,
-	"RORW",		LTYPE3,	ARORW,
-	"SAHF",		LTYPE0,	ASAHF,
-	"SALB",		LTYPE3,	ASALB,
-	"SALL",		LTYPE3,	ASALL,
-	"SALW",		LTYPE3,	ASALW,
-	"SARB",		LTYPE3,	ASARB,
-	"SARL",		LTYPE3,	ASARL,
-	"SARW",		LTYPE3,	ASARW,
-	"SBBB",		LTYPE3,	ASBBB,
-	"SBBL",		LTYPE3,	ASBBL,
-	"SBBW",		LTYPE3,	ASBBW,
-	"SCASB",	LTYPE0,	ASCASB,
-	"SCASL",	LTYPE0,	ASCASL,
-	"SCASW",	LTYPE0,	ASCASW,
-	"SETCC",	LTYPE1,	ASETCC,	/* see JCC etc above for condition codes */
-	"SETCS",	LTYPE1,	ASETCS,
-	"SETEQ",	LTYPE1,	ASETEQ,
-	"SETGE",	LTYPE1,	ASETGE,
-	"SETGT",	LTYPE1,	ASETGT,
-	"SETHI",	LTYPE1,	ASETHI,
-	"SETLE",	LTYPE1,	ASETLE,
-	"SETLS",	LTYPE1,	ASETLS,
-	"SETLT",	LTYPE1,	ASETLT,
-	"SETMI",	LTYPE1,	ASETMI,
-	"SETNE",	LTYPE1,	ASETNE,
-	"SETOC",	LTYPE1,	ASETOC,
-	"SETOS",	LTYPE1,	ASETOS,
-	"SETPC",	LTYPE1,	ASETPC,
-	"SETPL",	LTYPE1,	ASETPL,
-	"SETPS",	LTYPE1,	ASETPS,
-	"CDQ",		LTYPE0,	ACDQ,
-	"CWD",		LTYPE0,	ACWD,
-	"SHLB",		LTYPE3,	ASHLB,
-	"SHLL",		LTYPES,	ASHLL,
-	"SHLW",		LTYPES,	ASHLW,
-	"SHRB",		LTYPE3,	ASHRB,
-	"SHRL",		LTYPES,	ASHRL,
-	"SHRW",		LTYPES,	ASHRW,
-	"STC",		LTYPE0,	ASTC,
-	"STD",		LTYPE0,	ASTD,
-	"STI",		LTYPE0,	ASTI,
-	"STOSB",	LTYPE0,	ASTOSB,
-	"STOSL",	LTYPE0,	ASTOSL,
-	"STOSW",	LTYPE0,	ASTOSW,
-	"SUBB",		LTYPE3,	ASUBB,
-	"SUBL",		LTYPE3,	ASUBL,
-	"SUBW",		LTYPE3,	ASUBW,
-	"SYSCALL",	LTYPE0,	ASYSCALL,
-	"TESTB",	LTYPE3,	ATESTB,
-	"TESTL",	LTYPE3,	ATESTL,
-	"TESTW",	LTYPE3,	ATESTW,
-	"TEXT",		LTYPET,	ATEXT,
-	"VERR",		LTYPE2,	AVERR,
-	"VERW",		LTYPE2,	AVERW,
-	"WAIT",		LTYPE0,	AWAIT,
-	"WORD",		LTYPE2,	AWORD,
-	"XADDB",	LTYPE3,	AXADDB,
-	"XADDL",	LTYPE3,	AXADDL,
-	"XADDW",	LTYPE3,	AXADDW,
-	"XCHGB",	LTYPE3,	AXCHGB,
-	"XCHGL",	LTYPE3,	AXCHGL,
-	"XCHGW",	LTYPE3,	AXCHGW,
-	"XLAT",		LTYPE2,	AXLAT,
-	"XORB",		LTYPE3,	AXORB,
-	"XORL",		LTYPE3,	AXORL,
-	"XORW",		LTYPE3,	AXORW,
-
-	"CMOVLCC",	LTYPE3,	ACMOVLCC,
-	"CMOVLCS",	LTYPE3,	ACMOVLCS,
-	"CMOVLEQ",	LTYPE3,	ACMOVLEQ,
-	"CMOVLGE",	LTYPE3,	ACMOVLGE,
-	"CMOVLGT",	LTYPE3,	ACMOVLGT,
-	"CMOVLHI",	LTYPE3,	ACMOVLHI,
-	"CMOVLLE",	LTYPE3,	ACMOVLLE,
-	"CMOVLLS",	LTYPE3,	ACMOVLLS,
-	"CMOVLLT",	LTYPE3,	ACMOVLLT,
-	"CMOVLMI",	LTYPE3,	ACMOVLMI,
-	"CMOVLNE",	LTYPE3,	ACMOVLNE,
-	"CMOVLOC",	LTYPE3,	ACMOVLOC,
-	"CMOVLOS",	LTYPE3,	ACMOVLOS,
-	"CMOVLPC",	LTYPE3,	ACMOVLPC,
-	"CMOVLPL",	LTYPE3,	ACMOVLPL,
-	"CMOVLPS",	LTYPE3,	ACMOVLPS,
-	"CMOVWCC",	LTYPE3,	ACMOVWCC,
-	"CMOVWCS",	LTYPE3,	ACMOVWCS,
-	"CMOVWEQ",	LTYPE3,	ACMOVWEQ,
-	"CMOVWGE",	LTYPE3,	ACMOVWGE,
-	"CMOVWGT",	LTYPE3,	ACMOVWGT,
-	"CMOVWHI",	LTYPE3,	ACMOVWHI,
-	"CMOVWLE",	LTYPE3,	ACMOVWLE,
-	"CMOVWLS",	LTYPE3,	ACMOVWLS,
-	"CMOVWLT",	LTYPE3,	ACMOVWLT,
-	"CMOVWMI",	LTYPE3,	ACMOVWMI,
-	"CMOVWNE",	LTYPE3,	ACMOVWNE,
-	"CMOVWOC",	LTYPE3,	ACMOVWOC,
-	"CMOVWOS",	LTYPE3,	ACMOVWOS,
-	"CMOVWPC",	LTYPE3,	ACMOVWPC,
-	"CMOVWPL",	LTYPE3,	ACMOVWPL,
-	"CMOVWPS",	LTYPE3,	ACMOVWPS,
-
-	"FMOVB",	LTYPE3, AFMOVB,
-	"FMOVBP",	LTYPE3, AFMOVBP,
-	"FMOVD",	LTYPE3, AFMOVD,
-	"FMOVDP",	LTYPE3, AFMOVDP,
-	"FMOVF",	LTYPE3, AFMOVF,
-	"FMOVFP",	LTYPE3, AFMOVFP,
-	"FMOVL",	LTYPE3, AFMOVL,
-	"FMOVLP",	LTYPE3, AFMOVLP,
-	"FMOVV",	LTYPE3, AFMOVV,
-	"FMOVVP",	LTYPE3, AFMOVVP,
-	"FMOVW",	LTYPE3, AFMOVW,
-	"FMOVWP",	LTYPE3, AFMOVWP,
-	"FMOVX",	LTYPE3, AFMOVX,
-	"FMOVXP",	LTYPE3, AFMOVXP,
-	"FCMOVCC",	LTYPE3, AFCMOVCC,
-	"FCMOVCS",	LTYPE3, AFCMOVCS,
-	"FCMOVEQ",	LTYPE3, AFCMOVEQ,
-	"FCMOVHI",	LTYPE3, AFCMOVHI,
-	"FCMOVLS",	LTYPE3, AFCMOVLS,
-	"FCMOVNE",	LTYPE3, AFCMOVNE,
-	"FCMOVNU",	LTYPE3, AFCMOVNU,
-	"FCMOVUN",	LTYPE3, AFCMOVUN,
-	"FCOMB",	LTYPE3, AFCOMB,
-	"FCOMBP",	LTYPE3, AFCOMBP,
-	"FCOMD",	LTYPE3, AFCOMD,
-	"FCOMDP",	LTYPE3, AFCOMDP,
-	"FCOMDPP",	LTYPE3, AFCOMDPP,
-	"FCOMF",	LTYPE3, AFCOMF,
-	"FCOMFP",	LTYPE3, AFCOMFP,
-	"FCOMI",	LTYPE3, AFCOMI,
-	"FCOMIP",	LTYPE3, AFCOMIP,
-	"FCOML",	LTYPE3, AFCOML,
-	"FCOMLP",	LTYPE3, AFCOMLP,
-	"FCOMW",	LTYPE3, AFCOMW,
-	"FCOMWP",	LTYPE3, AFCOMWP,
-	"FUCOM",	LTYPE3, AFUCOM,
-	"FUCOMI",	LTYPE3, AFUCOMI,
-	"FUCOMIP",	LTYPE3, AFUCOMIP,
-	"FUCOMP",	LTYPE3, AFUCOMP,
-	"FUCOMPP",	LTYPE3, AFUCOMPP,
-	"FADDW",	LTYPE3, AFADDW,
-	"FADDL",	LTYPE3, AFADDL,
-	"FADDF",	LTYPE3, AFADDF,
-	"FADDD",	LTYPE3, AFADDD,
-	"FADDDP",	LTYPE3, AFADDDP,
-	"FSUBDP",	LTYPE3, AFSUBDP,
-	"FSUBW",	LTYPE3, AFSUBW,
-	"FSUBL",	LTYPE3, AFSUBL,
-	"FSUBF",	LTYPE3, AFSUBF,
-	"FSUBD",	LTYPE3, AFSUBD,
-	"FSUBRDP",	LTYPE3, AFSUBRDP,
-	"FSUBRW",	LTYPE3, AFSUBRW,
-	"FSUBRL",	LTYPE3, AFSUBRL,
-	"FSUBRF",	LTYPE3, AFSUBRF,
-	"FSUBRD",	LTYPE3, AFSUBRD,
-	"FMULDP",	LTYPE3, AFMULDP,
-	"FMULW",	LTYPE3, AFMULW,
-	"FMULL",	LTYPE3, AFMULL,
-	"FMULF",	LTYPE3, AFMULF,
-	"FMULD",	LTYPE3, AFMULD,
-	"FDIVDP",	LTYPE3, AFDIVDP,
-	"FDIVW",	LTYPE3, AFDIVW,
-	"FDIVL",	LTYPE3, AFDIVL,
-	"FDIVF",	LTYPE3, AFDIVF,
-	"FDIVD",	LTYPE3, AFDIVD,
-	"FDIVRDP",	LTYPE3, AFDIVRDP,
-	"FDIVRW",	LTYPE3, AFDIVRW,
-	"FDIVRL",	LTYPE3, AFDIVRL,
-	"FDIVRF",	LTYPE3, AFDIVRF,
-	"FDIVRD",	LTYPE3, AFDIVRD,
-	"FXCHD",	LTYPE3, AFXCHD,
-	"FFREE",	LTYPE1, AFFREE,
-	"FLDCW",	LTYPE2, AFLDCW,
-	"FLDENV",	LTYPE1, AFLDENV,
-	"FRSTOR",	LTYPE2, AFRSTOR,
-	"FSAVE",	LTYPE1, AFSAVE,
-	"FSTCW",	LTYPE1, AFSTCW,
-	"FSTENV",	LTYPE1, AFSTENV,
-	"FSTSW",	LTYPE1, AFSTSW,
-	"F2XM1",	LTYPE0, AF2XM1,
-	"FABS",		LTYPE0, AFABS,
-	"FCHS",		LTYPE0, AFCHS,
-	"FCLEX",	LTYPE0, AFCLEX,
-	"FCOS",		LTYPE0, AFCOS,
-	"FDECSTP",	LTYPE0, AFDECSTP,
-	"FINCSTP",	LTYPE0, AFINCSTP,
-	"FINIT",	LTYPE0, AFINIT,
-	"FLD1",		LTYPE0, AFLD1,
-	"FLDL2E",	LTYPE0, AFLDL2E,
-	"FLDL2T",	LTYPE0, AFLDL2T,
-	"FLDLG2",	LTYPE0, AFLDLG2,
-	"FLDLN2",	LTYPE0, AFLDLN2,
-	"FLDPI",	LTYPE0, AFLDPI,
-	"FLDZ",		LTYPE0, AFLDZ,
-	"FNOP",		LTYPE0, AFNOP,
-	"FPATAN",	LTYPE0, AFPATAN,
-	"FPREM",	LTYPE0, AFPREM,
-	"FPREM1",	LTYPE0, AFPREM1,
-	"FPTAN",	LTYPE0, AFPTAN,
-	"FRNDINT",	LTYPE0, AFRNDINT,
-	"FSCALE",	LTYPE0, AFSCALE,
-	"FSIN",		LTYPE0, AFSIN,
-	"FSINCOS",	LTYPE0, AFSINCOS,
-	"FSQRT",	LTYPE0, AFSQRT,
-	"FTST",		LTYPE0, AFTST,
-	"FXAM",		LTYPE0, AFXAM,
-	"FXTRACT",	LTYPE0, AFXTRACT,
-	"FYL2X",	LTYPE0, AFYL2X,
-	"FYL2XP1",	LTYPE0, AFYL2XP1,
-	"LFENCE",	LTYPE0, ALFENCE,
-	"MFENCE",	LTYPE0, AMFENCE,
-	"SFENCE",	LTYPE0, ASFENCE,
-	"EMMS",		LTYPE0, AEMMS,
-	"PREFETCHT0",		LTYPE2,	APREFETCHT0,
-	"PREFETCHT1",		LTYPE2,	APREFETCHT1,
-	"PREFETCHT2",		LTYPE2,	APREFETCHT2,
-	"PREFETCHNTA",		LTYPE2,	APREFETCHNTA,
-	"UNDEF",	LTYPE0,	AUNDEF,
-
-	"ADDPD",	LTYPE3,	AADDPD,
-	"ADDPS",	LTYPE3,	AADDPS,
-	"ADDSD",	LTYPE3,	AADDSD,
-	"ADDSS",	LTYPE3,	AADDSS,
-	"AESENC",	LTYPE3,	AAESENC,
-	"ANDNPD",	LTYPE3,	AANDNPD,
-	"ANDNPS",	LTYPE3,	AANDNPS,
-	"ANDPD",	LTYPE3,	AANDPD,
-	"ANDPS",	LTYPE3,	AANDPS,
-	"CMPPD",	LTYPEXC,ACMPPD,
-	"CMPPS",	LTYPEXC,ACMPPS,
-	"CMPSD",	LTYPEXC,ACMPSD,
-	"CMPSS",	LTYPEXC,ACMPSS,
-	"COMISD",	LTYPE3,	ACOMISD,
-	"COMISS",	LTYPE3,	ACOMISS,
-	"CVTPL2PD",	LTYPE3,	ACVTPL2PD,
-	"CVTPL2PS",	LTYPE3,	ACVTPL2PS,
-	"CVTPD2PL",	LTYPE3,	ACVTPD2PL,
-	"CVTPD2PS",	LTYPE3,	ACVTPD2PS,
-	"CVTPS2PL",	LTYPE3,	ACVTPS2PL,
-	"CVTPS2PD",	LTYPE3,	ACVTPS2PD,
-	"CVTSD2SL",	LTYPE3,	ACVTSD2SL,
-	"CVTSD2SS",	LTYPE3,	ACVTSD2SS,
-	"CVTSL2SD",	LTYPE3,	ACVTSL2SD,
-	"CVTSL2SS",	LTYPE3,	ACVTSL2SS,
-	"CVTSS2SD",	LTYPE3,	ACVTSS2SD,
-	"CVTSS2SL",	LTYPE3,	ACVTSS2SL,
-	"CVTTPD2PL",	LTYPE3,	ACVTTPD2PL,
-	"CVTTPS2PL",	LTYPE3,	ACVTTPS2PL,
-	"CVTTSD2SL",	LTYPE3,	ACVTTSD2SL,
-	"CVTTSS2SL",	LTYPE3,	ACVTTSS2SL,
-	"DIVPD",	LTYPE3,	ADIVPD,
-	"DIVPS",	LTYPE3,	ADIVPS,
-	"DIVSD",	LTYPE3,	ADIVSD,
-	"DIVSS",	LTYPE3,	ADIVSS,
-	"MASKMOVOU",	LTYPE3,	AMASKMOVOU,
-	"MASKMOVDQU",	LTYPE3,	AMASKMOVOU,	/* syn */
-	"MAXPD",	LTYPE3,	AMAXPD,
-	"MAXPS",	LTYPE3,	AMAXPS,
-	"MAXSD",	LTYPE3,	AMAXSD,
-	"MAXSS",	LTYPE3,	AMAXSS,
-	"MINPD",	LTYPE3,	AMINPD,
-	"MINPS",	LTYPE3,	AMINPS,
-	"MINSD",	LTYPE3,	AMINSD,
-	"MINSS",	LTYPE3,	AMINSS,
-	"MOVAPD",	LTYPE3,	AMOVAPD,
-	"MOVAPS",	LTYPE3,	AMOVAPS,
-	"MOVO",		LTYPE3,	AMOVO,
-	"MOVOA",	LTYPE3,	AMOVO,	/* syn */
-	"MOVOU",	LTYPE3,	AMOVOU,
-	"MOVHLPS",	LTYPE3,	AMOVHLPS,
-	"MOVHPD",	LTYPE3,	AMOVHPD,
-	"MOVHPS",	LTYPE3,	AMOVHPS,
-	"MOVLHPS",	LTYPE3,	AMOVLHPS,
-	"MOVLPD",	LTYPE3,	AMOVLPD,
-	"MOVLPS",	LTYPE3,	AMOVLPS,
-	"MOVMSKPD",	LTYPE3,	AMOVMSKPD,
-	"MOVMSKPS",	LTYPE3,	AMOVMSKPS,
-	"MOVNTO",	LTYPE3,	AMOVNTO,
-	"MOVNTDQ",	LTYPE3,	AMOVNTO,	/* syn */
-	"MOVNTPD",	LTYPE3,	AMOVNTPD,
-	"MOVNTPS",	LTYPE3,	AMOVNTPS,
-	"MOVSD",	LTYPE3,	AMOVSD,
-	"MOVSS",	LTYPE3,	AMOVSS,
-	"MOVUPD",	LTYPE3,	AMOVUPD,
-	"MOVUPS",	LTYPE3,	AMOVUPS,
-	"MULPD",	LTYPE3,	AMULPD,
-	"MULPS",	LTYPE3,	AMULPS,
-	"MULSD",	LTYPE3,	AMULSD,
-	"MULSS",	LTYPE3,	AMULSS,
-	"ORPD",		LTYPE3,	AORPD,
-	"ORPS",		LTYPE3,	AORPS,
-	"PADDQ",	LTYPE3,	APADDQ,
-	"PAND",		LTYPE3,	APAND,
-	"PCMPEQB",	LTYPE3,	APCMPEQB,
-	"PMAXSW",	LTYPE3,	APMAXSW,
-	"PMAXUB",	LTYPE3,	APMAXUB,
-	"PMINSW",	LTYPE3,	APMINSW,
-	"PMINUB",	LTYPE3,	APMINUB,
-	"PMOVMSKB",	LTYPE3,	APMOVMSKB,
-	"PSADBW",	LTYPE3,	APSADBW,
-	"PSHUFB",	LTYPE3, APSHUFB,
-	"PSHUFHW",      LTYPEX, APSHUFHW,
-	"PSHUFL",       LTYPEX, APSHUFL,
-	"PSHUFLW",      LTYPEX, APSHUFLW,
-	"PSUBB",	LTYPE3,	APSUBB,
-	"PSUBL",	LTYPE3,	APSUBL,
-	"PSUBQ",	LTYPE3,	APSUBQ,
-	"PSUBSB",	LTYPE3,	APSUBSB,
-	"PSUBSW",	LTYPE3,	APSUBSW,
-	"PSUBUSB",	LTYPE3,	APSUBUSB,
-	"PSUBUSW",	LTYPE3,	APSUBUSW,
-	"PSUBW",	LTYPE3,	APSUBW,
-	"PUNPCKHQDQ",	LTYPE3,	APUNPCKHQDQ,
-	"PUNPCKLQDQ",	LTYPE3,	APUNPCKLQDQ,
-	"PXOR",		LTYPE3, APXOR,
-	"RCPPS",	LTYPE3,	ARCPPS,
-	"RCPSS",	LTYPE3,	ARCPSS,
-	"RSQRTPS",	LTYPE3,	ARSQRTPS,
-	"RSQRTSS",	LTYPE3,	ARSQRTSS,
-	"SQRTPD",	LTYPE3,	ASQRTPD,
-	"SQRTPS",	LTYPE3,	ASQRTPS,
-	"SQRTSD",	LTYPE3,	ASQRTSD,
-	"SQRTSS",	LTYPE3,	ASQRTSS,
-	"SUBPD",	LTYPE3,	ASUBPD,
-	"SUBPS",	LTYPE3,	ASUBPS,
-	"SUBSD",	LTYPE3,	ASUBSD,
-	"SUBSS",	LTYPE3,	ASUBSS,
-	"UCOMISD",	LTYPE3,	AUCOMISD,
-	"UCOMISS",	LTYPE3,	AUCOMISS,
-	"UNPCKHPD",	LTYPE3,	AUNPCKHPD,
-	"UNPCKHPS",	LTYPE3,	AUNPCKHPS,
-	"UNPCKLPD",	LTYPE3,	AUNPCKLPD,
-	"UNPCKLPS",	LTYPE3,	AUNPCKLPS,
-	"XORPD",	LTYPE3,	AXORPD,
-	"XORPS",	LTYPE3,	AXORPS,
-	"USEFIELD",	LTYPEN, AUSEFIELD,
-	"PCDATA",	LTYPEPC,	APCDATA,
-	"FUNCDATA",	LTYPEF,	AFUNCDATA,
-	0
-};
-
-void
-cinit(void)
-{
-	Sym *s;
-	int i;
-
-	nullgen.type = TYPE_NONE;
-	nullgen.index = TYPE_NONE;
-
-	nerrors = 0;
-	iostack = I;
-	iofree = I;
-	peekc = IGN;
-	nhunk = 0;
-	for(i=0; i<NHASH; i++)
-		hash[i] = S;
-	for(i=0; itab[i].name; i++) {
-		s = slookup(itab[i].name);
-		if(s->type != LNAME)
-			yyerror("double initialization %s", itab[i].name);
-		s->type = itab[i].type;
-		s->value = itab[i].value;
-	}
-}
-
-void
-checkscale(int scale)
-{
-
-	switch(scale) {
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		return;
-	}
-	yyerror("scale must be 1248: %d", scale);
-}
-
-void
-syminit(Sym *s)
-{
-
-	s->type = LNAME;
-	s->value = 0;
-}
-
-void
-cclean(void)
-{
-	Addr2 g2;
-
-	g2.from = nullgen;
-	g2.to = nullgen;
-	outcode(AEND, &g2);
-}
-
-void
-outcode(int a, Addr2 *g2)
-{
-	Prog *p;
-	Plist *pl;
-	
-	if(pass == 1)
-		goto out;
-
-	p = malloc(sizeof *p);
-	memset(p, 0, sizeof *p);
-	p->as = a;
-	p->lineno = stmtline;
-	p->from = g2->from;
-	p->to = g2->to;
-	p->pc = pc;
-
-	if(lastpc == nil) {
-		pl = linknewplist(ctxt);
-		pl->firstpc = p;
-	} else
-		lastpc->link = p;
-	lastpc = p;	
-
-out:
-	if(a != AGLOBL && a != ADATA)
-		pc++;
-}
-
-#include "../cc/lexbody"
-#include "../cc/macbody"
diff --git a/src/cmd/new8a/lex.go b/src/cmd/8a/lex.go
similarity index 100%
rename from src/cmd/new8a/lex.go
rename to src/cmd/8a/lex.go
diff --git a/src/cmd/new8a/y.go b/src/cmd/8a/y.go
similarity index 100%
rename from src/cmd/new8a/y.go
rename to src/cmd/8a/y.go
diff --git a/src/cmd/8a/y.tab.c b/src/cmd/8a/y.tab.c
deleted file mode 100644
index d80f0ee..0000000
--- a/src/cmd/8a/y.tab.c
+++ /dev/null
@@ -1,2778 +0,0 @@
-/* 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 {
-     LTYPE0 = 258,
-     LTYPE1 = 259,
-     LTYPE2 = 260,
-     LTYPE3 = 261,
-     LTYPE4 = 262,
-     LTYPEC = 263,
-     LTYPED = 264,
-     LTYPEN = 265,
-     LTYPER = 266,
-     LTYPET = 267,
-     LTYPES = 268,
-     LTYPEM = 269,
-     LTYPEI = 270,
-     LTYPEG = 271,
-     LTYPEXC = 272,
-     LTYPEX = 273,
-     LTYPEPC = 274,
-     LTYPEF = 275,
-     LCONST = 276,
-     LFP = 277,
-     LPC = 278,
-     LSB = 279,
-     LBREG = 280,
-     LLREG = 281,
-     LSREG = 282,
-     LFREG = 283,
-     LXREG = 284,
-     LFCONST = 285,
-     LSCONST = 286,
-     LSP = 287,
-     LNAME = 288,
-     LLAB = 289,
-     LVAR = 290
-   };
-#endif
-/* Tokens.  */
-#define LTYPE0 258
-#define LTYPE1 259
-#define LTYPE2 260
-#define LTYPE3 261
-#define LTYPE4 262
-#define LTYPEC 263
-#define LTYPED 264
-#define LTYPEN 265
-#define LTYPER 266
-#define LTYPET 267
-#define LTYPES 268
-#define LTYPEM 269
-#define LTYPEI 270
-#define LTYPEG 271
-#define LTYPEXC 272
-#define LTYPEX 273
-#define LTYPEPC 274
-#define LTYPEF 275
-#define LCONST 276
-#define LFP 277
-#define LPC 278
-#define LSB 279
-#define LBREG 280
-#define LLREG 281
-#define LSREG 282
-#define LFREG 283
-#define LXREG 284
-#define LFCONST 285
-#define LSCONST 286
-#define LSP 287
-#define LNAME 288
-#define LLAB 289
-#define LVAR 290
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
-
-
-/* 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 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
-}
-/* Line 193 of yacc.c.  */
-#line 183 "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 196 "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  2
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   544
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  54
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  39
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  131
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  270
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   290
-
-#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,     2,     2,     2,    50,    12,     5,     2,
-      51,    52,    10,     8,    49,     9,     2,    11,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    46,    47,
-       6,    48,     7,     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,     4,     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,     3,     2,    53,     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,    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
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint16 yyprhs[] =
-{
-       0,     0,     3,     4,     5,     9,    10,    15,    17,    20,
-      23,    27,    31,    34,    37,    40,    43,    46,    49,    51,
-      53,    56,    59,    62,    65,    68,    70,    73,    76,    79,
-      82,    83,    85,    89,    93,    96,    98,   101,   103,   106,
-     108,   112,   119,   125,   133,   138,   145,   148,   150,   153,
-     155,   157,   161,   167,   171,   177,   180,   182,   186,   192,
-     198,   202,   206,   208,   210,   212,   214,   217,   220,   222,
-     224,   226,   228,   230,   235,   238,   240,   242,   244,   246,
-     248,   250,   253,   256,   259,   262,   267,   273,   277,   279,
-     282,   286,   291,   293,   295,   297,   302,   307,   314,   324,
-     334,   338,   342,   347,   353,   362,   364,   371,   377,   385,
-     386,   389,   392,   394,   396,   398,   400,   402,   405,   408,
-     411,   415,   417,   421,   425,   429,   433,   437,   442,   447,
-     451,   455
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      55,     0,    -1,    -1,    -1,    55,    56,    57,    -1,    -1,
-      43,    46,    58,    57,    -1,    47,    -1,    59,    47,    -1,
-       1,    47,    -1,    43,    48,    92,    -1,    45,    48,    92,
-      -1,    13,    60,    -1,    14,    64,    -1,    15,    63,    -1,
-      16,    61,    -1,    17,    62,    -1,    21,    65,    -1,    66,
-      -1,    67,    -1,    18,    69,    -1,    20,    70,    -1,    23,
-      71,    -1,    24,    72,    -1,    25,    73,    -1,    68,    -1,
-      27,    74,    -1,    28,    75,    -1,    29,    76,    -1,    30,
-      77,    -1,    -1,    49,    -1,    80,    49,    78,    -1,    78,
-      49,    80,    -1,    80,    49,    -1,    80,    -1,    49,    78,
-      -1,    78,    -1,    49,    81,    -1,    81,    -1,    83,    49,
-      81,    -1,    19,    88,    11,    91,    49,    83,    -1,    22,
-      85,    49,    50,    84,    -1,    22,    85,    49,    91,    49,
-      50,    84,    -1,    26,    85,    49,    83,    -1,    26,    85,
-      49,    91,    49,    83,    -1,    49,    79,    -1,    79,    -1,
-      10,    88,    -1,    60,    -1,    64,    -1,    80,    49,    78,
-      -1,    80,    49,    78,    46,    36,    -1,    80,    49,    78,
-      -1,    80,    49,    78,    46,    37,    -1,    80,    49,    -1,
-      80,    -1,    80,    49,    78,    -1,    82,    49,    78,    49,
-      91,    -1,    83,    49,    78,    49,    82,    -1,    80,    49,
-      80,    -1,    80,    49,    80,    -1,    82,    -1,    85,    -1,
-      81,    -1,    87,    -1,    10,    82,    -1,    10,    86,    -1,
-      82,    -1,    86,    -1,    83,    -1,    78,    -1,    83,    -1,
-      91,    51,    33,    52,    -1,    43,    89,    -1,    35,    -1,
-      38,    -1,    36,    -1,    39,    -1,    42,    -1,    37,    -1,
-      50,    91,    -1,    50,    88,    -1,    50,    41,    -1,    50,
-      40,    -1,    50,    51,    40,    52,    -1,    50,    51,     9,
-      40,    52,    -1,    50,     9,    40,    -1,    31,    -1,     9,
-      31,    -1,    31,     9,    31,    -1,     9,    31,     9,    31,
-      -1,    86,    -1,    87,    -1,    91,    -1,    91,    51,    36,
-      52,    -1,    91,    51,    42,    52,    -1,    91,    51,    36,
-      10,    91,    52,    -1,    91,    51,    36,    52,    51,    36,
-      10,    91,    52,    -1,    91,    51,    36,    52,    51,    37,
-      10,    91,    52,    -1,    51,    36,    52,    -1,    51,    42,
-      52,    -1,    91,    51,    37,    52,    -1,    51,    36,    10,
-      91,    52,    -1,    51,    36,    52,    51,    36,    10,    91,
-      52,    -1,    88,    -1,    88,    51,    36,    10,    91,    52,
-      -1,    43,    89,    51,    90,    52,    -1,    43,     6,     7,
-      89,    51,    34,    52,    -1,    -1,     8,    91,    -1,     9,
-      91,    -1,    34,    -1,    42,    -1,    32,    -1,    31,    -1,
-      45,    -1,     9,    91,    -1,     8,    91,    -1,    53,    91,
-      -1,    51,    92,    52,    -1,    91,    -1,    92,     8,    92,
-      -1,    92,     9,    92,    -1,    92,    10,    92,    -1,    92,
-      11,    92,    -1,    92,    12,    92,    -1,    92,     6,     6,
-      92,    -1,    92,     7,     7,    92,    -1,    92,     5,    92,
-      -1,    92,     4,    92,    -1,    92,     3,    92,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,    64,    64,    66,    65,    73,    72,    81,    82,    83,
-      86,    91,    97,    98,    99,   100,   101,   102,   103,   104,
-     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
-     117,   121,   128,   135,   142,   147,   154,   159,   166,   171,
-     176,   183,   196,   204,   218,   226,   240,   245,   250,   258,
-     259,   262,   267,   277,   282,   292,   297,   302,   309,   317,
-     327,   336,   347,   348,   351,   352,   353,   357,   361,   362,
-     363,   366,   367,   370,   376,   387,   393,   399,   405,   411,
-     417,   425,   431,   441,   447,   453,   459,   465,   473,   480,
-     487,   494,   503,   504,   507,   514,   521,   528,   538,   548,
-     558,   564,   570,   577,   586,   597,   601,   610,   618,   628,
-     631,   635,   641,   642,   646,   649,   650,   654,   658,   662,
-     666,   672,   673,   677,   681,   685,   689,   693,   697,   701,
-     705,   709
-};
-#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.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "'|'", "'^'", "'&'", "'<'", "'>'", "'+'",
-  "'-'", "'*'", "'/'", "'%'", "LTYPE0", "LTYPE1", "LTYPE2", "LTYPE3",
-  "LTYPE4", "LTYPEC", "LTYPED", "LTYPEN", "LTYPER", "LTYPET", "LTYPES",
-  "LTYPEM", "LTYPEI", "LTYPEG", "LTYPEXC", "LTYPEX", "LTYPEPC", "LTYPEF",
-  "LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG", "LFREG",
-  "LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB", "LVAR", "':'",
-  "';'", "'='", "','", "'$'", "'('", "')'", "'~'", "$accept", "prog", "@1",
-  "line", "@2", "inst", "nonnon", "rimrem", "remrim", "rimnon", "nonrem",
-  "nonrel", "spec1", "spec2", "spec8", "spec3", "spec4", "spec5", "spec6",
-  "spec7", "spec9", "spec10", "spec11", "spec12", "rem", "rom", "rim",
-  "rel", "reg", "imm", "textsize", "mem", "omem", "nmem", "nam", "offset",
-  "pointer", "con", "expr", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   124,    94,    38,    60,    62,    43,    45,
-      42,    47,    37,   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,    58,    59,    61,    44,
-      36,    40,    41,   126
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    54,    55,    56,    55,    58,    57,    57,    57,    57,
-      59,    59,    59,    59,    59,    59,    59,    59,    59,    59,
-      59,    59,    59,    59,    59,    59,    59,    59,    59,    59,
-      60,    60,    61,    62,    63,    63,    64,    64,    65,    65,
-      65,    66,    67,    67,    68,    68,    69,    69,    69,    70,
-      70,    71,    71,    72,    72,    73,    73,    73,    74,    75,
-      76,    77,    78,    78,    79,    79,    79,    79,    79,    79,
-      79,    80,    80,    81,    81,    82,    82,    82,    82,    82,
-      82,    83,    83,    83,    83,    83,    83,    83,    84,    84,
-      84,    84,    85,    85,    86,    86,    86,    86,    86,    86,
-      86,    86,    86,    86,    86,    87,    87,    88,    88,    89,
-      89,    89,    90,    90,    90,    91,    91,    91,    91,    91,
-      91,    92,    92,    92,    92,    92,    92,    92,    92,    92,
-      92,    92
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     0,     0,     3,     0,     4,     1,     2,     2,
-       3,     3,     2,     2,     2,     2,     2,     2,     1,     1,
-       2,     2,     2,     2,     2,     1,     2,     2,     2,     2,
-       0,     1,     3,     3,     2,     1,     2,     1,     2,     1,
-       3,     6,     5,     7,     4,     6,     2,     1,     2,     1,
-       1,     3,     5,     3,     5,     2,     1,     3,     5,     5,
-       3,     3,     1,     1,     1,     1,     2,     2,     1,     1,
-       1,     1,     1,     4,     2,     1,     1,     1,     1,     1,
-       1,     2,     2,     2,     2,     4,     5,     3,     1,     2,
-       3,     4,     1,     1,     1,     4,     4,     6,     9,     9,
-       3,     3,     4,     5,     8,     1,     6,     5,     7,     0,
-       2,     2,     1,     1,     1,     1,     1,     2,     2,     2,
-       3,     1,     3,     3,     3,     3,     3,     4,     4,     3,
-       3,     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_uint8 yydefact[] =
-{
-       2,     3,     1,     0,     0,    30,     0,     0,     0,     0,
-       0,     0,    30,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     7,     4,     0,    18,    19,
-      25,     9,    31,    12,     0,     0,   115,    75,    77,    80,
-      76,    78,    79,   109,   116,     0,     0,     0,    13,    37,
-      62,    63,    92,    93,   105,    94,     0,    14,    71,    35,
-      72,    15,     0,    16,     0,     0,   109,     0,    20,    47,
-      64,    68,    70,    69,    65,    94,     0,    31,    49,    50,
-      21,   109,     0,     0,    17,    39,     0,     0,     0,    22,
-       0,    23,     0,    24,    56,     0,    26,     0,    27,     0,
-      28,     0,    29,     0,     5,     0,     0,     8,   118,   117,
-       0,     0,     0,     0,    36,     0,     0,   121,     0,   119,
-       0,     0,     0,    84,    83,     0,    82,    81,    34,     0,
-       0,    66,    67,    48,    74,     0,    46,     0,     0,    74,
-      38,     0,     0,     0,     0,     0,    55,     0,     0,     0,
-       0,     0,     0,    10,    11,   109,   110,   111,     0,     0,
-     100,   101,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   120,     0,     0,     0,     0,    87,     0,     0,
-      32,    33,     0,     0,    40,     0,     0,    51,    53,    57,
-      44,     0,     0,     0,    60,    61,     6,     0,   114,   112,
-     113,     0,     0,     0,   131,   130,   129,     0,     0,   122,
-     123,   124,   125,   126,     0,     0,    95,   102,    96,     0,
-      85,    73,     0,     0,    88,    42,     0,     0,     0,     0,
-       0,     0,     0,   107,   103,     0,   127,   128,     0,     0,
-       0,    86,    41,    89,     0,     0,    52,    54,    45,    58,
-      59,     0,     0,   106,    97,     0,     0,     0,    90,    43,
-     108,     0,     0,     0,    91,   104,     0,     0,    98,    99
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     1,     3,    26,   152,    27,    33,    61,    63,    57,
-      48,    84,    28,    29,    30,    68,    80,    89,    91,    93,
-      96,    98,   100,   102,    58,    69,    59,    70,    50,    60,
-     225,    51,    52,    53,    54,   113,   201,    55,   118
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -87
-static const yytype_int16 yypact[] =
-{
-     -87,    35,   -87,   242,     2,    -4,   164,   313,   313,   361,
-     265,     8,   337,    60,   410,   313,   313,   313,   410,   241,
-     -11,   313,   313,   -31,    17,   -87,   -87,    23,   -87,   -87,
-     -87,   -87,   -87,   -87,   474,   474,   -87,   -87,   -87,   -87,
-     -87,   -87,   -87,    20,   -87,   361,   401,   474,   -87,   -87,
-     -87,   -87,   -87,   -87,    16,    28,   185,   -87,   -87,    22,
-     -87,   -87,    25,   -87,    31,   361,    20,   289,   -87,   -87,
-     -87,   -87,   -87,   -87,   -87,    48,    29,   361,   -87,   -87,
-     -87,    13,   417,   474,   -87,   -87,    51,    53,    57,   -87,
-      58,   -87,    59,   -87,    70,    71,   -87,    75,   -87,    80,
-     -87,    86,   -87,   102,   -87,   474,   474,   -87,   -87,   -87,
-      37,   474,   474,    76,   -87,     1,   103,   -87,   175,   -87,
-     126,    50,    85,   -87,   -87,   426,   -87,   -87,   -87,   361,
-     313,   -87,   -87,   -87,    76,   385,   -87,    81,   474,   -87,
-     -87,   417,   130,   436,   361,   361,   361,   464,   361,   361,
-     313,   313,   242,   525,   525,    13,   -87,   -87,    18,   474,
-     113,   -87,   474,   474,   474,   165,   167,   474,   474,   474,
-     474,   474,   -87,   186,     3,   123,   156,   -87,   467,   158,
-     -87,   -87,   159,   163,   -87,     7,   169,   173,   177,   -87,
-     -87,   182,   183,   184,   -87,   -87,   -87,   178,   -87,   -87,
-     -87,   172,   187,   198,   136,   239,   532,   474,   474,    78,
-      78,   -87,   -87,   -87,   474,   474,   189,   -87,   -87,   202,
-     -87,   -87,   -11,   204,   228,   -87,   191,   245,   247,   -11,
-     474,   241,   248,   -87,   -87,   276,   180,   180,   236,   238,
-      -5,   -87,   -87,   282,   261,     7,   -87,   -87,   -87,   -87,
-     -87,   243,   474,   -87,   -87,   283,   284,   274,   -87,   -87,
-     -87,   254,   474,   474,   -87,   -87,   257,   259,   -87,   -87
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-     -87,   -87,   -87,   160,   -87,   -87,   301,   -87,   -87,   -87,
-     305,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   -87,
-     -87,   -87,   -87,   -87,    21,   252,    26,    -7,    -9,    -8,
-      84,     0,    -3,    -6,    -2,   -58,   -87,   -10,   -86
-};
-
-/* 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 -1
-static const yytype_uint16 yytable[] =
-{
-      75,    71,    72,    87,    74,    86,    85,    73,   134,    76,
-      97,   159,    99,   215,    88,   104,   223,   105,    95,   153,
-     154,   111,   112,   139,   108,   109,   110,    49,   111,   112,
-      64,   255,   256,    49,    62,     2,   117,   119,   224,    56,
-     138,    90,    92,    94,   155,    32,   127,   101,   103,    31,
-     198,    43,   199,   160,   126,   216,   131,    75,    71,    72,
-     200,    74,   132,   133,    73,   106,   114,   120,    34,    35,
-     107,   128,    87,   117,   129,   140,   204,   205,   206,   121,
-     130,   209,   210,   211,   212,   213,   174,   175,   169,   170,
-     171,    36,   176,    34,    35,   117,   117,   197,   114,   137,
-     141,   156,   157,    81,   142,    44,   143,   144,   145,    82,
-      56,    83,   109,    47,   182,   117,    36,   174,   175,   146,
-     147,   236,   237,   176,   148,   177,   131,   158,   183,   149,
-      44,    87,   132,   186,   184,   150,    83,   191,    47,   190,
-     163,   164,   165,   166,   167,   168,   169,   170,   171,   202,
-     180,   151,   117,   117,   117,   161,   181,   117,   117,   117,
-     117,   117,   173,   182,   203,   187,   188,   189,   109,   192,
-     193,   207,    34,    35,   208,   217,   194,   195,   162,   163,
-     164,   165,   166,   167,   168,   169,   170,   171,   167,   168,
-     169,   170,   171,    34,   122,    36,   214,   117,   117,    37,
-      38,    39,    40,    41,   238,   239,    42,    43,   218,    44,
-     220,   221,   222,    45,   242,    46,    36,    47,   226,   227,
-     249,   248,   250,   228,   233,   123,   124,   172,    43,   232,
-      44,   229,   230,   231,   235,   243,   125,   244,    47,   234,
-     240,   245,   261,     4,   164,   165,   166,   167,   168,   169,
-     170,   171,   266,   267,   241,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    34,    35,    65,    37,    38,    39,    40,
-      41,   246,   251,    42,   247,    23,   252,    24,   253,    25,
-     254,   257,   258,   262,   263,   260,    36,    34,    35,   135,
-      37,    38,    39,    40,    41,   264,   265,    42,    66,   268,
-      44,   269,   196,    78,    67,    56,    46,    79,    47,   136,
-      36,    34,    35,     0,    37,    38,    39,    40,    41,   259,
-       0,    42,    66,     0,    44,     0,     0,     0,     0,    56,
-      46,     0,    47,     0,    36,    34,    35,     0,    37,    38,
-      39,    40,    41,     0,     0,    42,    43,     0,    44,     0,
-       0,     0,     0,    56,    46,     0,    47,     0,    36,    34,
-      35,     0,    37,    38,    39,    40,    41,     0,     0,    42,
-      43,     0,    44,     0,     0,     0,    77,     0,    46,     0,
-      47,     0,    36,    34,    35,     0,    37,    38,    39,    40,
-      41,     0,     0,    42,    43,     0,    44,     0,     0,    34,
-      35,     0,    46,     0,    47,     0,    36,     0,    34,    35,
-      37,    38,    39,    40,    41,    34,    35,    42,     0,     0,
-      44,     0,    36,     0,    34,   178,    46,   115,    47,     0,
-       0,    36,     0,   116,    34,    35,    44,     0,    36,     0,
-       0,     0,    83,    43,    47,    44,     0,    36,     0,     0,
-      81,    46,    44,    47,     0,     0,   179,    36,    83,     0,
-      47,    44,    34,    35,     0,    34,    35,    83,     0,    47,
-       0,    44,    34,    35,     0,     0,   185,    83,     0,    47,
-       0,     0,     0,     0,     0,    36,     0,     0,    36,     0,
-       0,     0,     0,     0,     0,    36,     0,   219,     0,    44,
-       0,     0,    44,     0,    56,    83,     0,    47,    83,    44,
-      47,     0,     0,     0,     0,    83,     0,    47,   162,   163,
-     164,   165,   166,   167,   168,   169,   170,   171,   165,   166,
-     167,   168,   169,   170,   171
-};
-
-static const yytype_int16 yycheck[] =
-{
-      10,    10,    10,    13,    10,    13,    13,    10,    66,    11,
-      19,    10,    20,    10,    14,    46,     9,    48,    18,   105,
-     106,     8,     9,    81,    34,    35,     6,     6,     8,     9,
-       9,    36,    37,    12,     8,     0,    46,    47,    31,    50,
-      11,    15,    16,    17,     7,    49,    56,    21,    22,    47,
-      32,    43,    34,    52,    56,    52,    65,    67,    67,    67,
-      42,    67,    65,    65,    67,    48,    45,    51,     8,     9,
-      47,    49,    82,    83,    49,    82,   162,   163,   164,    51,
-      49,   167,   168,   169,   170,   171,    36,    37,    10,    11,
-      12,    31,    42,     8,     9,   105,   106,   155,    77,    51,
-      49,   111,   112,    43,    51,    45,    49,    49,    49,    49,
-      50,    51,   122,    53,    33,   125,    31,    36,    37,    49,
-      49,   207,   208,    42,    49,    40,   135,    51,   138,    49,
-      45,   141,   135,   143,   141,    49,    51,   147,    53,   147,
-       4,     5,     6,     7,     8,     9,    10,    11,    12,   159,
-     129,    49,   162,   163,   164,    52,   130,   167,   168,   169,
-     170,   171,    36,    33,    51,   144,   145,   146,   178,   148,
-     149,     6,     8,     9,     7,    52,   150,   151,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,     8,     9,
-      10,    11,    12,     8,     9,    31,    10,   207,   208,    35,
-      36,    37,    38,    39,   214,   215,    42,    43,    52,    45,
-      52,    52,    49,    49,   222,    51,    31,    53,    49,    46,
-     230,   229,   231,    46,    52,    40,    41,    52,    43,    51,
-      45,    49,    49,    49,    36,    31,    51,     9,    53,    52,
-      51,    50,   252,     1,     5,     6,     7,     8,     9,    10,
-      11,    12,   262,   263,    52,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,     8,     9,    10,    35,    36,    37,    38,
-      39,    36,    34,    42,    37,    43,    10,    45,    52,    47,
-      52,     9,    31,    10,    10,    52,    31,     8,     9,    10,
-      35,    36,    37,    38,    39,    31,    52,    42,    43,    52,
-      45,    52,   152,    12,    49,    50,    51,    12,    53,    67,
-      31,     8,     9,    -1,    35,    36,    37,    38,    39,   245,
-      -1,    42,    43,    -1,    45,    -1,    -1,    -1,    -1,    50,
-      51,    -1,    53,    -1,    31,     8,     9,    -1,    35,    36,
-      37,    38,    39,    -1,    -1,    42,    43,    -1,    45,    -1,
-      -1,    -1,    -1,    50,    51,    -1,    53,    -1,    31,     8,
-       9,    -1,    35,    36,    37,    38,    39,    -1,    -1,    42,
-      43,    -1,    45,    -1,    -1,    -1,    49,    -1,    51,    -1,
-      53,    -1,    31,     8,     9,    -1,    35,    36,    37,    38,
-      39,    -1,    -1,    42,    43,    -1,    45,    -1,    -1,     8,
-       9,    -1,    51,    -1,    53,    -1,    31,    -1,     8,     9,
-      35,    36,    37,    38,    39,     8,     9,    42,    -1,    -1,
-      45,    -1,    31,    -1,     8,     9,    51,    36,    53,    -1,
-      -1,    31,    -1,    42,     8,     9,    45,    -1,    31,    -1,
-      -1,    -1,    51,    43,    53,    45,    -1,    31,    -1,    -1,
-      43,    51,    45,    53,    -1,    -1,    40,    31,    51,    -1,
-      53,    45,     8,     9,    -1,     8,     9,    51,    -1,    53,
-      -1,    45,     8,     9,    -1,    -1,    50,    51,    -1,    53,
-      -1,    -1,    -1,    -1,    -1,    31,    -1,    -1,    31,    -1,
-      -1,    -1,    -1,    -1,    -1,    31,    -1,    40,    -1,    45,
-      -1,    -1,    45,    -1,    50,    51,    -1,    53,    51,    45,
-      53,    -1,    -1,    -1,    -1,    51,    -1,    53,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,     6,     7,
-       8,     9,    10,    11,    12
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,    55,     0,    56,     1,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    43,    45,    47,    57,    59,    66,    67,
-      68,    47,    49,    60,     8,     9,    31,    35,    36,    37,
-      38,    39,    42,    43,    45,    49,    51,    53,    64,    78,
-      82,    85,    86,    87,    88,    91,    50,    63,    78,    80,
-      83,    61,    80,    62,    78,    10,    43,    49,    69,    79,
-      81,    82,    83,    86,    87,    91,    88,    49,    60,    64,
-      70,    43,    49,    51,    65,    81,    83,    91,    85,    71,
-      80,    72,    80,    73,    80,    85,    74,    82,    75,    83,
-      76,    80,    77,    80,    46,    48,    48,    47,    91,    91,
-       6,     8,     9,    89,    78,    36,    42,    91,    92,    91,
-      51,    51,     9,    40,    41,    51,    88,    91,    49,    49,
-      49,    82,    86,    88,    89,    10,    79,    51,    11,    89,
-      81,    49,    51,    49,    49,    49,    49,    49,    49,    49,
-      49,    49,    58,    92,    92,     7,    91,    91,    51,    10,
-      52,    52,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,    12,    52,    36,    36,    37,    42,    40,     9,    40,
-      78,    80,    33,    91,    81,    50,    91,    78,    78,    78,
-      83,    91,    78,    78,    80,    80,    57,    89,    32,    34,
-      42,    90,    91,    51,    92,    92,    92,     6,     7,    92,
-      92,    92,    92,    92,    10,    10,    52,    52,    52,    40,
-      52,    52,    49,     9,    31,    84,    49,    46,    46,    49,
-      49,    49,    51,    52,    52,    36,    92,    92,    91,    91,
-      51,    52,    83,    31,     9,    50,    36,    37,    83,    91,
-      82,    34,    10,    52,    52,    36,    37,     9,    31,    84,
-      52,    91,    10,    10,    31,    52,    91,    91,    52,    52
-};
-
-#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;
-
-/* 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 yystate;
-  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 3:
-#line 66 "a.y"
-    {
-		stmtline = lineno;
-	}
-    break;
-
-  case 5:
-#line 73 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
-			yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyvsp[(1) - (2)].sym)->type = LLAB;
-		(yyvsp[(1) - (2)].sym)->value = pc;
-	}
-    break;
-
-  case 10:
-#line 87 "a.y"
-    {
-		(yyvsp[(1) - (3)].sym)->type = LVAR;
-		(yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 11:
-#line 92 "a.y"
-    {
-		if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
-			yyerror("redeclaration of %s", (yyvsp[(1) - (3)].sym)->name);
-		(yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 12:
-#line 97 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 13:
-#line 98 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 14:
-#line 99 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 15:
-#line 100 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 16:
-#line 101 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 17:
-#line 102 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 20:
-#line 105 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 21:
-#line 106 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 22:
-#line 107 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 23:
-#line 108 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 24:
-#line 109 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 26:
-#line 111 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 27:
-#line 112 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 28:
-#line 113 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 29:
-#line 114 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 30:
-#line 117 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 31:
-#line 122 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 32:
-#line 129 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 33:
-#line 136 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 34:
-#line 143 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (2)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 35:
-#line 148 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 36:
-#line 155 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 37:
-#line 160 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 38:
-#line 167 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 39:
-#line 172 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 40:
-#line 177 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 41:
-#line 184 "a.y"
-    {
-		Addr2 a;
-		a.from = (yyvsp[(2) - (6)].addr);
-		a.to = (yyvsp[(6) - (6)].addr);
-		outcode(ADATA, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 42:
-#line 197 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (5)].addr).sym);
-		a.from = (yyvsp[(2) - (5)].addr);
-		a.to = (yyvsp[(5) - (5)].addr);
-		outcode(ATEXT, &a);
-	}
-    break;
-
-  case 43:
-#line 205 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (7)].addr).sym);
-		a.from = (yyvsp[(2) - (7)].addr);
-		a.to = (yyvsp[(7) - (7)].addr);
-		outcode(ATEXT, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (7)].lval);
-		}
-	}
-    break;
-
-  case 44:
-#line 219 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (4)].addr).sym);
-		a.from = (yyvsp[(2) - (4)].addr);
-		a.to = (yyvsp[(4) - (4)].addr);
-		outcode(AGLOBL, &a);
-	}
-    break;
-
-  case 45:
-#line 227 "a.y"
-    {
-		Addr2 a;
-		settext((yyvsp[(2) - (6)].addr).sym);
-		a.from = (yyvsp[(2) - (6)].addr);
-		a.to = (yyvsp[(6) - (6)].addr);
-		outcode(AGLOBL, &a);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 46:
-#line 241 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 47:
-#line 246 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 48:
-#line 251 "a.y"
-    {
-		(yyval.addr2).from = nullgen;
-		(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
-		(yyval.addr2).to.type = TYPE_INDIR;
-	}
-    break;
-
-  case 51:
-#line 263 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 52:
-#line 268 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		if((yyval.addr2).from.index != TYPE_NONE)
-			yyerror("dp shift with lhs index");
-		(yyval.addr2).from.index = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 53:
-#line 278 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 54:
-#line 283 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		if((yyval.addr2).to.index != TYPE_NONE)
-			yyerror("dp move with lhs index");
-		(yyval.addr2).to.index = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 55:
-#line 293 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (2)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 56:
-#line 298 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
-		(yyval.addr2).to = nullgen;
-	}
-    break;
-
-  case 57:
-#line 303 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 58:
-#line 310 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
-		(yyval.addr2).to.offset = (yyvsp[(5) - (5)].lval);
-	}
-    break;
-
-  case 59:
-#line 318 "a.y"
-    {
-		(yyval.addr2).from = (yyvsp[(3) - (5)].addr);
-		(yyval.addr2).to = (yyvsp[(5) - (5)].addr);
-		if((yyvsp[(1) - (5)].addr).type != TYPE_CONST)
-			yyerror("illegal constant");
-		(yyval.addr2).to.offset = (yyvsp[(1) - (5)].addr).offset;
-	}
-    break;
-
-  case 60:
-#line 328 "a.y"
-    {
-		if((yyvsp[(1) - (3)].addr).type != TYPE_CONST || (yyvsp[(3) - (3)].addr).type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
-		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
-		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
-	}
-    break;
-
-  case 61:
-#line 337 "a.y"
-    {
-		if((yyvsp[(1) - (3)].addr).type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if((yyvsp[(3) - (3)].addr).type != TYPE_MEM || ((yyvsp[(3) - (3)].addr).name != NAME_EXTERN && (yyvsp[(3) - (3)].addr).name != NAME_STATIC))
-			yyerror("value for FUNCDATA must be symbol reference");
- 		(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
- 		(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
- 	}
-    break;
-
-  case 66:
-#line 354 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 67:
-#line 358 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-	}
-    break;
-
-  case 73:
-#line 371 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
-	}
-    break;
-
-  case 74:
-#line 377 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		(yyval.addr) = nullgen;
-		if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
-			yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 75:
-#line 388 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 76:
-#line 394 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 77:
-#line 400 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 78:
-#line 406 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 79:
-#line 412 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = REG_SP;
-	}
-    break;
-
-  case 80:
-#line 418 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 81:
-#line 426 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 82:
-#line 432 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-		(yyval.addr).type = TYPE_ADDR;
-		/*
-		if($2.name == NAME_AUTO || $2.name == NAME_PARAM)
-			yyerror("constant cannot be automatic: %s",
-				$2.sym->name);
-		 */
-	}
-    break;
-
-  case 83:
-#line 442 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SCONST;
-		memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
-	}
-    break;
-
-  case 84:
-#line 448 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
-	}
-    break;
-
-  case 85:
-#line 454 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(3) - (4)].dval);
-	}
-    break;
-
-  case 86:
-#line 460 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(4) - (5)].dval);
-	}
-    break;
-
-  case 87:
-#line 466 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
-	}
-    break;
-
-  case 88:
-#line 474 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 89:
-#line 481 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (2)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 90:
-#line 488 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (3)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 91:
-#line 495 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (4)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 94:
-#line 508 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_NONE;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 95:
-#line 515 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 96:
-#line 522 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_SP;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 97:
-#line 529 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_NONE;
-		(yyval.addr).offset = (yyvsp[(1) - (6)].lval);
-		(yyval.addr).index = (yyvsp[(3) - (6)].lval);
-		(yyval.addr).scale = (yyvsp[(5) - (6)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 98:
-#line 539 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
-		(yyval.addr).index = (yyvsp[(6) - (9)].lval);
-		(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 99:
-#line 549 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
-		(yyval.addr).index = (yyvsp[(6) - (9)].lval);
-		(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 100:
-#line 559 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 101:
-#line 565 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_SP;
-	}
-    break;
-
-  case 102:
-#line 571 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 103:
-#line 578 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = REG_NONE;
-		(yyval.addr).index = (yyvsp[(2) - (5)].lval);
-		(yyval.addr).scale = (yyvsp[(4) - (5)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 104:
-#line 587 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (8)].lval);
-		(yyval.addr).index = (yyvsp[(5) - (8)].lval);
-		(yyval.addr).scale = (yyvsp[(7) - (8)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 105:
-#line 598 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (1)].addr);
-	}
-    break;
-
-  case 106:
-#line 602 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(1) - (6)].addr);
-		(yyval.addr).index = (yyvsp[(3) - (6)].lval);
-		(yyval.addr).scale = (yyvsp[(5) - (6)].lval);
-		checkscale((yyval.addr).scale);
-	}
-    break;
-
-  case 107:
-#line 611 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(4) - (5)].lval);
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
-		(yyval.addr).offset = (yyvsp[(2) - (5)].lval);
-	}
-    break;
-
-  case 108:
-#line 619 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = NAME_STATIC;
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
-		(yyval.addr).offset = (yyvsp[(4) - (7)].lval);
-	}
-    break;
-
-  case 109:
-#line 628 "a.y"
-    {
-		(yyval.lval) = 0;
-	}
-    break;
-
-  case 110:
-#line 632 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 111:
-#line 636 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 113:
-#line 643 "a.y"
-    {
-		(yyval.lval) = NAME_AUTO;
-	}
-    break;
-
-  case 116:
-#line 651 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
-	}
-    break;
-
-  case 117:
-#line 655 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 118:
-#line 659 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 119:
-#line 663 "a.y"
-    {
-		(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 120:
-#line 667 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 122:
-#line 674 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 123:
-#line 678 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 124:
-#line 682 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 125:
-#line 686 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 126:
-#line 690 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 127:
-#line 694 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 128:
-#line 698 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 129:
-#line 702 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 130:
-#line 706 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 131:
-#line 710 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 2565 "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);
-}
-
-
-
diff --git a/src/cmd/8a/y.tab.h b/src/cmd/8a/y.tab.h
deleted file mode 100644
index 3ab1bfa..0000000
--- a/src/cmd/8a/y.tab.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* 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 {
-     LTYPE0 = 258,
-     LTYPE1 = 259,
-     LTYPE2 = 260,
-     LTYPE3 = 261,
-     LTYPE4 = 262,
-     LTYPEC = 263,
-     LTYPED = 264,
-     LTYPEN = 265,
-     LTYPER = 266,
-     LTYPET = 267,
-     LTYPES = 268,
-     LTYPEM = 269,
-     LTYPEI = 270,
-     LTYPEG = 271,
-     LTYPEXC = 272,
-     LTYPEX = 273,
-     LTYPEPC = 274,
-     LTYPEF = 275,
-     LCONST = 276,
-     LFP = 277,
-     LPC = 278,
-     LSB = 279,
-     LBREG = 280,
-     LLREG = 281,
-     LSREG = 282,
-     LFREG = 283,
-     LXREG = 284,
-     LFCONST = 285,
-     LSCONST = 286,
-     LSP = 287,
-     LNAME = 288,
-     LLAB = 289,
-     LVAR = 290
-   };
-#endif
-/* Tokens.  */
-#define LTYPE0 258
-#define LTYPE1 259
-#define LTYPE2 260
-#define LTYPE3 261
-#define LTYPE4 262
-#define LTYPEC 263
-#define LTYPED 264
-#define LTYPEN 265
-#define LTYPER 266
-#define LTYPET 267
-#define LTYPES 268
-#define LTYPEM 269
-#define LTYPEI 270
-#define LTYPEG 271
-#define LTYPEXC 272
-#define LTYPEX 273
-#define LTYPEPC 274
-#define LTYPEF 275
-#define LCONST 276
-#define LFP 277
-#define LPC 278
-#define LSB 279
-#define LBREG 280
-#define LLREG 281
-#define LSREG 282
-#define LFREG 283
-#define LXREG 284
-#define LFCONST 285
-#define LSCONST 286
-#define LSP 287
-#define LNAME 288
-#define LLAB 289
-#define LVAR 290
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	int32	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-	Addr2	addr2;
-}
-/* Line 1529 of yacc.c.  */
-#line 128 "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/8g/Makefile b/src/cmd/8g/Makefile
deleted file mode 100644
index 3f528d7..0000000
--- a/src/cmd/8g/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
deleted file mode 100644
index f06927c..0000000
--- a/src/cmd/8g/cgen.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-// 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.
-
-// TODO(rsc):
-//	assume CLD?
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-void
-mgen(Node *n, Node *n1, Node *rg)
-{
-	Node n2;
-
-	n1->op = OEMPTY;
-
-	if(n->addable) {
-		*n1 = *n;
-		if(n1->op == OREGISTER || n1->op == OINDREG)
-			reg[n->val.u.reg]++;
-		return;
-	}
-	tempname(n1, n->type);
-	cgen(n, n1);
-	if(n->type->width <= widthptr || isfloat[n->type->etype]) {
-		n2 = *n1;
-		regalloc(n1, n->type, rg);
-		gmove(&n2, n1);
-	}
-}
-
-void
-mfree(Node *n)
-{
-	if(n->op == OREGISTER)
-		regfree(n);
-}
-
-/*
- * generate:
- *	res = n;
- * simplifies and calls gmove.
- *
- * TODO:
- *	sudoaddable
- */
-void
-cgen(Node *n, Node *res)
-{
-	Node *nl, *nr, *r, n1, n2, nt;
-	Prog *p1, *p2, *p3;
-	int a;
-
-	if(debug['g']) {
-		dump("\ncgen-n", n);
-		dump("cgen-res", res);
-	}
-
-	if(n == N || n->type == T)
-		fatal("cgen: n nil");
-	if(res == N || res->type == T)
-		fatal("cgen: res nil");
-
-	switch(n->op) {
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_slice(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_slice(n, res);
-		return;
-	case OEFACE:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_eface(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_eface(n, res);
-		return;
-	}
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	// function calls on both sides?  introduce temporary
-	if(n->ullman >= UINF && res->ullman >= UINF) {
-		tempname(&n1, n->type);
-		cgen(n, &n1);
-		cgen(&n1, res);
-		return;
-	}
-
-	// structs etc get handled specially
-	if(isfat(n->type)) {
-		if(n->type->width < 0)
-			fatal("forgot to compute width for %T", n->type);
-		sgen(n, res, n->type->width);
-		return;
-	}
-
-	// update addressability for string, slice
-	// can't do in walk because n->left->addable
-	// changes if n->left is an escaping local variable.
-	switch(n->op) {
-	case OSPTR:
-	case OLEN:
-		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
-			n->addable = n->left->addable;
-		break;
-	case OCAP:
-		if(isslice(n->left->type))
-			n->addable = n->left->addable;
-		break;
-	case OITAB:
-		n->addable = n->left->addable;
-		break;
-	}
-
-	// if both are addressable, move
-	if(n->addable && res->addable) {
-		gmove(n, res);
-		return;
-	}
-
-	// if both are not addressable, use a temporary.
-	if(!n->addable && !res->addable) {
-		// could use regalloc here sometimes,
-		// but have to check for ullman >= UINF.
-		tempname(&n1, n->type);
-		cgen(n, &n1);
-		cgen(&n1, res);
-		return;
-	}
-
-	// if result is not addressable directly but n is,
-	// compute its address and then store via the address.
-	if(!res->addable) {
-		igen(res, &n1, N);
-		cgen(n, &n1);
-		regfree(&n1);
-		return;
-	}
-
-	// complex types
-	if(complexop(n, res)) {
-		complexgen(n, res);
-		return;
-	}
-
-	// otherwise, the result is addressable but n is not.
-	// let's do some computation.
-
-	// use ullman to pick operand to eval first.
-	nl = n->left;
-	nr = n->right;
-	if(nl != N && nl->ullman >= UINF)
-	if(nr != N && nr->ullman >= UINF) {
-		// both are hard
-		tempname(&n1, nl->type);
-		cgen(nl, &n1);
-		n2 = *n;
-		n2.left = &n1;
-		cgen(&n2, res);
-		return;
-	}
-
-	// 64-bit ops are hard on 32-bit machine.
-	if(is64(n->type) || is64(res->type) || n->left != N && is64(n->left->type)) {
-		switch(n->op) {
-		// math goes to cgen64.
-		case OMINUS:
-		case OCOM:
-		case OADD:
-		case OSUB:
-		case OMUL:
-		case OLROT:
-		case OLSH:
-		case ORSH:
-		case OAND:
-		case OOR:
-		case OXOR:
-			cgen64(n, res);
-			return;
-		}
-	}
-
-	if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) {
-		cgen_float(n, res);
-		return;
-	}
-
-	switch(n->op) {
-	default:
-		dump("cgen", n);
-		fatal("cgen %O", n->op);
-		break;
-
-	case OREAL:
-	case OIMAG:
-	case OCOMPLEX:
-		fatal("unexpected complex");
-		return;
-
-	// these call bgen to get a bool value
-	case OOROR:
-	case OANDAND:
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OLE:
-	case OGE:
-	case OGT:
-	case ONOT:
-		p1 = gbranch(AJMP, T, 0);
-		p2 = pc;
-		gmove(nodbool(1), res);
-		p3 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		bgen(n, 1, 0, p2);
-		gmove(nodbool(0), res);
-		patch(p3, pc);
-		return;
-
-	case OPLUS:
-		cgen(nl, res);
-		return;
-
-	case OMINUS:
-	case OCOM:
-		a = optoas(n->op, nl->type);
-		goto uop;
-
-	// symmetric binary
-	case OAND:
-	case OOR:
-	case OXOR:
-	case OADD:
-	case OMUL:
-		a = optoas(n->op, nl->type);
-		if(a == AIMULB) {
-			cgen_bmul(n->op, nl, nr, res);
-			break;
-		}
-		goto sbop;
-
-	// asymmetric binary
-	case OSUB:
-		a = optoas(n->op, nl->type);
-		goto abop;
-
-	case OHMUL:
-		cgen_hmul(nl, nr, res);
-		break;
-
-	case OCONV:
-		if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
-			cgen(nl, res);
-			break;
-		}
-
-		tempname(&n2, n->type);
-		mgen(nl, &n1, res);
-		gmove(&n1, &n2);
-		gmove(&n2, res);
-		mfree(&n1);
-		break;
-
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OIND:
-	case ONAME:	// PHEAP or PPARAMREF var
-		igen(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OITAB:
-		igen(nl, &n1, res);
-		n1.type = ptrto(types[TUINTPTR]);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OSPTR:
-		// pointer is the first word of string or slice.
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n1, types[tptr], res);
-			p1 = gins(ALEAL, N, &n1);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OLEN:
-		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
-			// map has len in the first 32-bit word.
-			// a zero pointer means zero length
-			tempname(&n1, types[tptr]);
-			cgen(nl, &n1);
-			regalloc(&n2, types[tptr], N);
-			gmove(&n1, &n2);
-			n1 = n2;
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.type = types[TINT32];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
-			// both slice and string have len one pointer into the struct.
-			igen(nl, &n1, res);
-			n1.type = types[TUINT32];
-			n1.xoffset += Array_nel;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OLEN: unknown type %lT", nl->type);
-		break;
-
-	case OCAP:
-		if(istype(nl->type, TCHAN)) {
-			// chan has cap in the second 32-bit word.
-			// a zero pointer means zero length
-			tempname(&n1, types[tptr]);
-			cgen(nl, &n1);
-			regalloc(&n2, types[tptr], N);
-			gmove(&n1, &n2);
-			n1 = n2;
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.xoffset = 4;
-			n2.type = types[TINT32];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(isslice(nl->type)) {
-			igen(nl, &n1, res);
-			n1.type = types[TUINT32];
-			n1.xoffset += Array_cap;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OCAP: unknown type %lT", nl->type);
-		break;
-
-	case OADDR:
-		agen(nl, res);
-		break;
-
-	case OCALLMETH:
-		cgen_callmeth(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OMOD:
-	case ODIV:
-		cgen_div(n->op, nl, nr, res);
-		break;
-
-	case OLSH:
-	case ORSH:
-	case OLROT:
-		cgen_shift(n->op, n->bounded, nl, nr, res);
-		break;
-	}
-	return;
-
-sbop:	// symmetric binary
-	if(nl->ullman < nr->ullman || nl->op == OLITERAL) {
-		r = nl;
-		nl = nr;
-		nr = r;
-	}
-
-abop:	// asymmetric binary
-	if(smallintconst(nr)) {
-		mgen(nl, &n1, res);
-		regalloc(&n2, nl->type, &n1);
-		gmove(&n1, &n2);
-		gins(a, nr, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		mfree(&n1);
-	} else if(nl->ullman >= nr->ullman) {
-		tempname(&nt, nl->type);
-		cgen(nl, &nt);
-		mgen(nr, &n2, N);
-		regalloc(&n1, nl->type, res);
-		gmove(&nt, &n1);
-		gins(a, &n2, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		mfree(&n2);
-	} else {
-		regalloc(&n2, nr->type, res);
-		cgen(nr, &n2);
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		gins(a, &n2, &n1);
-		regfree(&n2);
-		gmove(&n1, res);
-		regfree(&n1);
-	}
-	return;
-
-uop:	// unary
-	tempname(&n1, nl->type);
-	cgen(nl, &n1);
-	gins(a, N, &n1);
-	gmove(&n1, res);
-	return;
-}
-
-/*
- * generate an addressable node in res, containing the value of n.
- * n is an array index, and might be any size; res width is <= 32-bit.
- * returns Prog* to patch to panic call.
- */
-static Prog*
-igenindex(Node *n, Node *res, int bounded)
-{
-	Node tmp, lo, hi, zero;
-
-	if(!is64(n->type)) {
-		if(n->addable) {
-			// nothing to do.
-			*res = *n;
-		} else {
-			tempname(res, types[TUINT32]);
-			cgen(n, res);
-		}
-		return nil;
-	}
-
-	tempname(&tmp, types[TINT64]);
-	cgen(n, &tmp);
-	split64(&tmp, &lo, &hi);
-	tempname(res, types[TUINT32]);
-	gmove(&lo, res);
-	if(bounded) {
-		splitclean();
-		return nil;
-	}
-	nodconst(&zero, types[TINT32], 0);
-	gins(ACMPL, &hi, &zero);
-	splitclean();
-	return gbranch(AJNE, T, +1);
-}
-		
-/*
- * address gen
- *	res = &n;
- * The generated code checks that the result is not nil.
- */
-void
-agen(Node *n, Node *res)
-{
-	Node *nl, *nr;
-	Node n1, n2, n3, tmp, nlen;
-	Type *t;
-	uint32 w;
-	uint64 v;
-	Prog *p1, *p2;
-	int bounded;
-
-	if(debug['g']) {
-		dump("\nagen-res", res);
-		dump("agen-r", n);
-	}
-	if(n == N || n->type == T || res == N || res->type == T)
-		fatal("agen");
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	if(isconst(n, CTNIL) && n->type->width > widthptr) {
-		// Use of a nil interface or nil slice.
-		// Create a temporary we can take the address of and read.
-		// The generated code is just going to panic, so it need not
-		// be terribly efficient. See issue 3670.
-		tempname(&n1, n->type);
-		gvardef(&n1);
-		clearfat(&n1);
-		regalloc(&n2, types[tptr], res);
-		gins(ALEAL, &n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		return;
-	}
-		
-	// addressable var is easy
-	if(n->addable) {
-		if(n->op == OREGISTER)
-			fatal("agen OREGISTER");
-		regalloc(&n1, types[tptr], res);
-		gins(ALEAL, n, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		return;
-	}
-
-	// let's compute
-	nl = n->left;
-	nr = n->right;
-
-	switch(n->op) {
-	default:
-		fatal("agen %O", n->op);
-
-	case OCALLMETH:
-		cgen_callmeth(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		tempname(&n1, n->type);
-		cgen_slice(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OEFACE:
-		tempname(&n1, n->type);
-		cgen_eface(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OINDEX:
-		p2 = nil;  // to be patched to panicindex.
-		w = n->type->width;
-		bounded = debug['B'] || n->bounded;
-		if(nr->addable) {
-			// Generate &nl first, and move nr into register.
-			if(!isconst(nl, CTSTR))
-				igen(nl, &n3, res);
-			if(!isconst(nr, CTINT)) {
-				p2 = igenindex(nr, &tmp, bounded);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-		} else if(nl->addable) {
-			// Generate nr first, and move &nl into register.
-			if(!isconst(nr, CTINT)) {
-				p2 = igenindex(nr, &tmp, bounded);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-			if(!isconst(nl, CTSTR))
-				igen(nl, &n3, res);
-		} else {
-			p2 = igenindex(nr, &tmp, bounded);
-			nr = &tmp;
-			if(!isconst(nl, CTSTR))
-				igen(nl, &n3, res);
-			regalloc(&n1, tmp.type, N);
-			gins(optoas(OAS, tmp.type), &tmp, &n1);
-		}
-
-		// For fixed array we really want the pointer in n3.
-		if(isfixedarray(nl->type)) {
-			regalloc(&n2, types[tptr], &n3);
-			agen(&n3, &n2);
-			regfree(&n3);
-			n3 = n2;
-		}
-
-		// &a[0] is in n3 (allocated in res)
-		// i is in n1 (if not constant)
-		// len(a) is in nlen (if needed)
-		// w is width
-
-		// constant index
-		if(isconst(nr, CTINT)) {
-			if(isconst(nl, CTSTR))
-				fatal("constant string constant index");  // front end should handle
-			v = mpgetfix(nr->val.u.xval);
-			if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				if(!debug['B'] && !n->bounded) {
-					nlen = n3;
-					nlen.type = types[TUINT32];
-					nlen.xoffset += Array_nel;
-					nodconst(&n2, types[TUINT32], v);
-					gins(optoas(OCMP, types[TUINT32]), &nlen, &n2);
-					p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
-					ginscall(panicindex, -1);
-					patch(p1, pc);
-				}
-			}
-
-			// Load base pointer in n2 = n3.
-			regalloc(&n2, types[tptr], &n3);
-			n3.type = types[tptr];
-			n3.xoffset += Array_array;
-			gmove(&n3, &n2);
-			regfree(&n3);
-			if (v*w != 0) {
-				nodconst(&n1, types[tptr], v*w);
-				gins(optoas(OADD, types[tptr]), &n1, &n2);
-			}
-			gmove(&n2, res);
-			regfree(&n2);
-			break;
-		}
-
-		// i is in register n1, extend to 32 bits.
-		t = types[TUINT32];
-		if(issigned[n1.type->etype])
-			t = types[TINT32];
-
-		regalloc(&n2, t, &n1);			// i
-		gmove(&n1, &n2);
-		regfree(&n1);
-
-		if(!debug['B'] && !n->bounded) {
-			// check bounds
-			t = types[TUINT32];
-			if(isconst(nl, CTSTR)) {
-				nodconst(&nlen, t, nl->val.u.sval->len);
-			} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				nlen = n3;
-				nlen.type = t;
-				nlen.xoffset += Array_nel;
-			} else {
-				nodconst(&nlen, t, nl->type->bound);
-			}
-			gins(optoas(OCMP, t), &n2, &nlen);
-			p1 = gbranch(optoas(OLT, t), T, +1);
-			if(p2)
-				patch(p2, pc);
-			ginscall(panicindex, -1);
-			patch(p1, pc);
-		}
-
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n3, types[tptr], res);
-			p1 = gins(ALEAL, N, &n3);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			p1->from.scale = 1;
-			p1->from.index = n2.val.u.reg;
-			goto indexdone;
-		}
-
-		// Load base pointer in n3.
-		regalloc(&tmp, types[tptr], &n3);
-		if(isslice(nl->type) || nl->type->etype == TSTRING) {
-			n3.type = types[tptr];
-			n3.xoffset += Array_array;
-			gmove(&n3, &tmp);
-		}
-		regfree(&n3);
-		n3 = tmp;
-
-		if(w == 0) {
-			// nothing to do
-		} else if(w == 1 || w == 2 || w == 4 || w == 8) {
-			// LEAL (n3)(n2*w), n3
-			p1 = gins(ALEAL, &n2, &n3);
-			p1->from.scale = w;
-			p1->from.type = TYPE_MEM;
-			p1->from.index = p1->from.reg;
-			p1->from.reg = p1->to.reg;
-		} else {
-			nodconst(&tmp, types[TUINT32], w);
-			gins(optoas(OMUL, types[TUINT32]), &tmp, &n2);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-		}
-
-	indexdone:
-		gmove(&n3, res);
-		regfree(&n2);
-		regfree(&n3);
-		break;
-
-	case ONAME:
-		// should only get here with names in this func.
-		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME funcdepth %d != %d",
-				n->funcdepth, funcdepth);
-		}
-
-		// should only get here for heap vars or paramref
-		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME class %#x", n->class);
-		}
-		cgen(n->heapaddr, res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[tptr], n->xoffset);
-			gins(optoas(OADD, types[tptr]), &n1, res);
-		}
-		break;
-
-	case OIND:
-		cgen(nl, res);
-		cgen_checknil(res);
-		break;
-
-	case ODOT:
-		agen(nl, res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[tptr], n->xoffset);
-			gins(optoas(OADD, types[tptr]), &n1, res);
-		}
-		break;
-
-	case ODOTPTR:
-		t = nl->type;
-		if(!isptr[t->etype])
-			fatal("agen: not ptr %N", n);
-		cgen(nl, res);
-		cgen_checknil(res);
-		if(n->xoffset != 0) {
-			nodconst(&n1, types[tptr], n->xoffset);
-			gins(optoas(OADD, types[tptr]), &n1, res);
-		}
-		break;
-	}
-}
-
-/*
- * generate:
- *	newreg = &n;
- *	res = newreg
- *
- * on exit, a has been changed to be *newreg.
- * caller must regfree(a).
- * The generated code checks that the result is not *nil.
- */
-void
-igen(Node *n, Node *a, Node *res)
-{
-	Type *fp;
-	Iter flist;
-	Node n1;
-
-	if(debug['g']) {
-		dump("\nigen-n", n);
-	}
-	switch(n->op) {
-	case ONAME:
-		if((n->class&PHEAP) || n->class == PPARAMREF)
-			break;
-		*a = *n;
-		return;
-
-	case OINDREG:
-		// Increase the refcount of the register so that igen's caller
-		// has to call regfree.
-		if(n->val.u.reg != REG_SP)
-			reg[n->val.u.reg]++;
-		*a = *n;
-		return;
-
-	case ODOT:
-		igen(n->left, a, res);
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		return;
-
-	case ODOTPTR:
-		switch(n->left->op) {
-		case ODOT:
-		case ODOTPTR:
-		case OCALLFUNC:
-		case OCALLMETH:
-		case OCALLINTER:
-			// igen-able nodes.
-			igen(n->left, &n1, res);
-			regalloc(a, types[tptr], &n1);
-			gmove(&n1, a);
-			regfree(&n1);
-			break;
-		default:
-			regalloc(a, types[tptr], res);
-			cgen(n->left, a);
-		}
-		cgen_checknil(a);
-		a->op = OINDREG;
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		return;
-
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		switch(n->op) {
-		case OCALLFUNC:
-			cgen_call(n, 0);
-			break;
-		case OCALLMETH:
-			cgen_callmeth(n, 0);
-			break;
-		case OCALLINTER:
-			cgen_callinter(n, N, 0);
-			break;
-		}
-		fp = structfirst(&flist, getoutarg(n->left->type));
-		memset(a, 0, sizeof *a);
-		a->op = OINDREG;
-		a->val.u.reg = REG_SP;
-		a->addable = 1;
-		a->xoffset = fp->width;
-		a->type = n->type;
-		return;
-
-	case OINDEX:
-		// Index of fixed-size array by constant can
-		// put the offset in the addressing.
-		// Could do the same for slice except that we need
-		// to use the real index for the bounds checking.
-		if(isfixedarray(n->left->type) ||
-		   (isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
-		if(isconst(n->right, CTINT)) {
-			// Compute &a.
-			if(!isptr[n->left->type->etype])
-				igen(n->left, a, res);
-			else {
-				igen(n->left, &n1, res);
-				cgen_checknil(&n1);
-				regalloc(a, types[tptr], res);
-				gmove(&n1, a);
-				regfree(&n1);
-				a->op = OINDREG;
-			}
-
-			// Compute &a[i] as &a + i*width.
-			a->type = n->type;
-			a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
-			return;
-		}
-		break;
-	}
-
-	// release register for now, to avoid
-	// confusing tempname.
-	if(res != N && res->op == OREGISTER)
-		reg[res->val.u.reg]--;
-	tempname(&n1, types[tptr]);
-	agen(n, &n1);
-	if(res != N && res->op == OREGISTER)
-		reg[res->val.u.reg]++;
-	regalloc(a, types[tptr], res);
-	gmove(&n1, a);
-	a->op = OINDREG;
-	a->type = n->type;
-}
-
-/*
- * branch gen
- *	if(n == true) goto to;
- */
-void
-bgen(Node *n, int true, int likely, Prog *to)
-{
-	int et, a;
-	Node *nl, *nr, *r;
-	Node n1, n2, tmp;
-	Prog *p1, *p2;
-
-	if(debug['g']) {
-		dump("\nbgen", n);
-	}
-
-	if(n == N)
-		n = nodbool(1);
-
-	if(n->ninit != nil)
-		genlist(n->ninit);
-
-	if(n->type == T) {
-		convlit(&n, types[TBOOL]);
-		if(n->type == T)
-			return;
-	}
-
-	et = n->type->etype;
-	if(et != TBOOL) {
-		yyerror("cgen: bad type %T for %O", n->type, n->op);
-		patch(gins(AEND, N, N), to);
-		return;
-	}
-
-	while(n->op == OCONVNOP) {
-		n = n->left;
-		if(n->ninit != nil)
-			genlist(n->ninit);
-	}
-
-	nl = n->left;
-	nr = N;
-
-	if(nl != N && isfloat[nl->type->etype]) {
-		bgen_float(n, true, likely, to);
-		return;
-	}
-
-	switch(n->op) {
-	default:
-		goto def;
-
-	case OLITERAL:
-		// need to ask if it is bool?
-		if(!true == !n->val.u.bval)
-			patch(gbranch(AJMP, T, 0), to);
-		return;
-
-	case ONAME:
-		if(!n->addable)
-			goto def;
-		nodconst(&n1, n->type, 0);
-		gins(optoas(OCMP, n->type), n, &n1);
-		a = AJNE;
-		if(!true)
-			a = AJEQ;
-		patch(gbranch(a, n->type, likely), to);
-		return;
-
-	case OANDAND:
-	case OOROR:
-		if((n->op == OANDAND) == true) {
-			p1 = gbranch(AJMP, T, 0);
-			p2 = gbranch(AJMP, T, 0);
-			patch(p1, pc);
-			bgen(n->left, !true, -likely, p2);
-			bgen(n->right, !true, -likely, p2);
-			p1 = gbranch(AJMP, T, 0);
-			patch(p1, to);
-			patch(p2, pc);
-		} else {
-			bgen(n->left, true, likely, to);
-			bgen(n->right, true, likely, to);
-		}
-		return;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		nr = n->right;
-		if(nr == N || nr->type == T)
-			return;
-
-	case ONOT:	// unary
-		nl = n->left;
-		if(nl == N || nl->type == T)
-			return;
-	}
-
-	switch(n->op) {
-	case ONOT:
-		bgen(nl, !true, likely, to);
-		break;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		a = n->op;
-		if(!true) {
-			a = brcom(a);
-			true = !true;
-		}
-
-		// make simplest on right
-		if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
-			a = brrev(a);
-			r = nl;
-			nl = nr;
-			nr = r;
-		}
-
-		if(isslice(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal slice comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.xoffset += Array_array;
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-
-		if(isinter(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal interface comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-
-		if(iscomplex[nl->type->etype]) {
-			complexbool(a, nl, nr, true, likely, to);
-			break;
-		}
-
-		if(is64(nr->type)) {
-			if(!nl->addable || isconst(nl, CTINT)) {
-				tempname(&n1, nl->type);
-				cgen(nl, &n1);
-				nl = &n1;
-			}
-			if(!nr->addable) {
-				tempname(&n2, nr->type);
-				cgen(nr, &n2);
-				nr = &n2;
-			}
-			cmp64(nl, nr, a, likely, to);
-			break;
-		}
-
-		if(nr->ullman >= UINF) {
-			if(!nl->addable) {
-				tempname(&n1, nl->type);
-				cgen(nl, &n1);
-				nl = &n1;
-			}
-			if(!nr->addable) {
-				tempname(&tmp, nr->type);
-				cgen(nr, &tmp);
-				nr = &tmp;
-			}
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-			nr = &n2;
-			goto cmp;
-		}
-
-		if(!nl->addable) {
-			tempname(&n1, nl->type);
-			cgen(nl, &n1);
-			nl = &n1;
-		}
-
-		if(smallintconst(nr)) {
-			gins(optoas(OCMP, nr->type), nl, nr);
-			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-			break;
-		}
-
-		if(!nr->addable) {
-			tempname(&tmp, nr->type);
-			cgen(nr, &tmp);
-			nr = &tmp;
-		}
-		regalloc(&n2, nr->type, N);
-		gmove(nr, &n2);
-		nr = &n2;
-
-cmp:
-		gins(optoas(OCMP, nr->type), nl, nr);
-		patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-
-		if(nl->op == OREGISTER)
-			regfree(nl);
-		regfree(nr);
-		break;
-	}
-	return;
-
-def:
-	regalloc(&n1, n->type, N);
-	cgen(n, &n1);
-	nodconst(&n2, n->type, 0);
-	gins(optoas(OCMP, n->type), &n1, &n2);
-	a = AJNE;
-	if(!true)
-		a = AJEQ;
-	patch(gbranch(a, n->type, likely), to);
-	regfree(&n1);
-	return;
-}
-
-/*
- * n is on stack, either local variable
- * or return value from function call.
- * return n's offset from SP.
- */
-int32
-stkof(Node *n)
-{
-	Type *t;
-	Iter flist;
-	int32 off;
-
-	switch(n->op) {
-	case OINDREG:
-		return n->xoffset;
-
-	case ODOT:
-		t = n->left->type;
-		if(isptr[t->etype])
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		return off + n->xoffset;
-
-	case OINDEX:
-		t = n->left->type;
-		if(!isfixedarray(t))
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		if(isconst(n->right, CTINT))
-			return off + t->type->width * mpgetfix(n->right->val.u.xval);
-		return 1000;
-		
-	case OCALLMETH:
-	case OCALLINTER:
-	case OCALLFUNC:
-		t = n->left->type;
-		if(isptr[t->etype])
-			t = t->type;
-
-		t = structfirst(&flist, getoutarg(t));
-		if(t != T)
-			return t->width;
-		break;
-	}
-
-	// botch - probably failing to recognize address
-	// arithmetic on the above. eg INDEX and DOT
-	return -1000;
-}
-
-/*
- * struct gen
- *	memmove(&res, &n, w);
- */
-void
-sgen(Node *n, Node *res, int64 w)
-{
-	Node dst, src, tdst, tsrc, cx;
-	int32 c, q, odst, osrc;
-	NodeList *l;
-	Prog *p;
-
-	if(debug['g']) {
-		print("\nsgen w=%lld\n", w);
-		dump("r", n);
-		dump("res", res);
-	}
-	if(n->ullman >= UINF && res->ullman >= UINF)
-		fatal("sgen UINF");
-
-	if(w < 0 || (int32)w != w)
-		fatal("sgen copy %lld", w);
-
-	if(w == 0) {
-		// evaluate side effects only.
-		tempname(&tdst, types[tptr]);
-		agen(res, &tdst);
-		agen(n, &tdst);
-		return;
-	}
-
-	// If copying .args, that's all the results, so record definition sites
-	// for them for the liveness analysis.
-	if(res->op == ONAME && strcmp(res->sym->name, ".args") == 0)
-		for(l = curfn->dcl; l != nil; l = l->next)
-			if(l->n->class == PPARAMOUT)
-				gvardef(l->n);
-
-	// Avoid taking the address for simple enough types.
-	if(componentgen(n, res))
-		return;
-
-	// offset on the stack
-	osrc = stkof(n);
-	odst = stkof(res);
-	
-	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
-		// osrc and odst both on stack, and at least one is in
-		// an unknown position.  Could generate code to test
-		// for forward/backward copy, but instead just copy
-		// to a temporary location first.
-		tempname(&tsrc, n->type);
-		sgen(n, &tsrc, w);
-		sgen(&tsrc, res, w);
-		return;
-	}
-
-	nodreg(&dst, types[tptr], REG_DI);
-	nodreg(&src, types[tptr], REG_SI);
-
-	tempname(&tsrc, types[tptr]);
-	tempname(&tdst, types[tptr]);
-	if(!n->addable)
-		agen(n, &tsrc);
-	if(!res->addable)
-		agen(res, &tdst);
-	if(n->addable)
-		agen(n, &src);
-	else
-		gmove(&tsrc, &src);
-
-	if(res->op == ONAME)
-		gvardef(res);
-
-	if(res->addable)
-		agen(res, &dst);
-	else
-		gmove(&tdst, &dst);
-
-	c = w % 4;	// bytes
-	q = w / 4;	// doublewords
-
-	// if we are copying forward on the stack and
-	// the src and dst overlap, then reverse direction
-	if(osrc < odst && odst < osrc+w) {
-		// reverse direction
-		gins(ASTD, N, N);		// set direction flag
-		if(c > 0) {
-			gconreg(AADDL, w-1, REG_SI);
-			gconreg(AADDL, w-1, REG_DI);
-
-			gconreg(AMOVL, c, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSB, N, N);	// MOVB *(SI)-,*(DI)-
-		}
-
-		if(q > 0) {
-			if(c > 0) {
-				gconreg(AADDL, -3, REG_SI);
-				gconreg(AADDL, -3, REG_DI);
-			} else {
-				gconreg(AADDL, w-4, REG_SI);
-				gconreg(AADDL, w-4, REG_DI);
-			}
-			gconreg(AMOVL, q, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSL, N, N);	// MOVL *(SI)-,*(DI)-
-		}
-		// we leave with the flag clear
-		gins(ACLD, N, N);
-	} else {
-		gins(ACLD, N, N);	// paranoia.  TODO(rsc): remove?
-		// normal direction
-		if(q > 128 || (q >= 4 && nacl)) {
-			gconreg(AMOVL, q, REG_CX);
-			gins(AREP, N, N);	// repeat
-			gins(AMOVSL, N, N);	// MOVL *(SI)+,*(DI)+
-		} else if(q >= 4) {
-			p = gins(ADUFFCOPY, N, N);
-			p->to.type = TYPE_ADDR;
-			p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
-			// 10 and 128 = magic constants: see ../../runtime/asm_386.s
-			p->to.offset = 10*(128-q);
-		} else if(!nacl && c == 0) {
-			nodreg(&cx, types[TINT32], REG_CX);
-			// We don't need the MOVSL side-effect of updating SI and DI,
-			// and issuing a sequence of MOVLs directly is faster.
-			src.op = OINDREG;
-			dst.op = OINDREG;
-			while(q > 0) {
-				gmove(&src, &cx); // MOVL x+(SI),CX
-				gmove(&cx, &dst); // MOVL CX,x+(DI)
-				src.xoffset += 4;
-				dst.xoffset += 4;
-				q--;
-			}
-		} else
-		while(q > 0) {
-			gins(AMOVSL, N, N);	// MOVL *(SI)+,*(DI)+
-			q--;
-		}
-		while(c > 0) {
-			gins(AMOVSB, N, N);	// MOVB *(SI)+,*(DI)+
-			c--;
-		}
-	}
-}
-
-static int
-cadable(Node *n)
-{
-	if(!n->addable) {
-		// dont know how it happens,
-		// but it does
-		return 0;
-	}
-
-	switch(n->op) {
-	case ONAME:
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-int
-componentgen(Node *nr, Node *nl)
-{
-	Node nodl, nodr, tmp;
-	Type *t;
-	int freel, freer;
-	vlong fldcount;
-	vlong loffset, roffset;
-
-	freel = 0;
-	freer = 0;
-
-	switch(nl->type->etype) {
-	default:
-		goto no;
-
-	case TARRAY:
-		t = nl->type;
-
-		// Slices are ok.
-		if(isslice(t))
-			break;
-		// Small arrays are ok.
-		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
-			break;
-
-		goto no;
-
-	case TSTRUCT:
-		// Small structs with non-fat types are ok.
-		// Zero-sized structs are treated separately elsewhere.
-		fldcount = 0;
-		for(t=nl->type->type; t; t=t->down) {
-			if(isfat(t->type))
-				goto no;
-			if(t->etype != TFIELD)
-				fatal("componentgen: not a TFIELD: %lT", t);
-			fldcount++;
-		}
-		if(fldcount == 0 || fldcount > 4)
-			goto no;
-
-		break;
-
-	case TSTRING:
-	case TINTER:
-		break;
-	}
-
-	nodl = *nl;
-	if(!cadable(nl)) {
-		if(nr != N && !cadable(nr))
-			goto no;
-		igen(nl, &nodl, N);
-		freel = 1;
-	}
-
-	if(nr != N) {
-		nodr = *nr;
-		if(!cadable(nr)) {
-			igen(nr, &nodr, N);
-			freer = 1;
-		}
-	} else {
-		// When zeroing, prepare a register containing zero.
-		nodconst(&tmp, nl->type, 0);
-		regalloc(&nodr, types[TUINT], N);
-		gmove(&tmp, &nodr);
-		freer = 1;
-	}
-	
-	// nl and nr are 'cadable' which basically means they are names (variables) now.
-	// If they are the same variable, don't generate any code, because the
-	// VARDEF we generate will mark the old value as dead incorrectly.
-	// (And also the assignments are useless.)
-	if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
-		goto yes;
-
-	switch(nl->type->etype) {
-	case TARRAY:
-		// componentgen for arrays.
-		if(nl->op == ONAME)
-			gvardef(nl);
-		t = nl->type;
-		if(!isslice(t)) {
-			nodl.type = t->type;
-			nodr.type = nodl.type;
-			for(fldcount=0; fldcount < t->bound; fldcount++) {
-				if(nr == N)
-					clearslim(&nodl);
-				else
-					gmove(&nodr, &nodl);
-				nodl.xoffset += t->type->width;
-				nodr.xoffset += t->type->width;
-			}
-			goto yes;
-		}
-
-		// componentgen for slices.
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(nl->type->type);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_cap-Array_nel;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_cap-Array_nel;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRING:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TINTER:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRUCT:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		loffset = nodl.xoffset;
-		roffset = nodr.xoffset;
-		// funarg structs may not begin at offset zero.
-		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
-			loffset -= nl->type->type->width;
-		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
-			roffset -= nr->type->type->width;
-
-		for(t=nl->type->type; t; t=t->down) {
-			nodl.xoffset = loffset + t->width;
-			nodl.type = t->type;
-
-			if(nr == N)
-				clearslim(&nodl);
-			else {
-				nodr.xoffset = roffset + t->width;
-				nodr.type = nodl.type;
-				gmove(&nodr, &nodl);
-			}
-		}
-		goto yes;
-	}
-
-no:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 0;
-
-yes:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 1;
-}
diff --git a/src/cmd/new8g/cgen.go b/src/cmd/8g/cgen.go
similarity index 100%
rename from src/cmd/new8g/cgen.go
rename to src/cmd/8g/cgen.go
diff --git a/src/cmd/8g/cgen64.c b/src/cmd/8g/cgen64.c
deleted file mode 100644
index d9e812f..0000000
--- a/src/cmd/8g/cgen64.c
+++ /dev/null
@@ -1,549 +0,0 @@
-// 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"
-
-/*
- * attempt to generate 64-bit
- *	res = n
- * return 1 on success, 0 if op not handled.
- */
-void
-cgen64(Node *n, Node *res)
-{
-	Node t1, t2, ax, dx, cx, ex, fx, *l, *r;
-	Node lo1, lo2, hi1, hi2;
-	Prog *p1, *p2;
-	uint64 v;
-	uint32 lv, hv;
-
-	if(res->op != OINDREG && res->op != ONAME) {
-		dump("n", n);
-		dump("res", res);
-		fatal("cgen64 %O of %O", n->op, res->op);
-	}
-	switch(n->op) {
-	default:
-		fatal("cgen64 %O", n->op);
-
-	case OMINUS:
-		cgen(n->left, res);
-		split64(res, &lo1, &hi1);
-		gins(ANEGL, N, &lo1);
-		gins(AADCL, ncon(0), &hi1);
-		gins(ANEGL, N, &hi1);
-		splitclean();
-		return;
-
-	case OCOM:
-		cgen(n->left, res);
-		split64(res, &lo1, &hi1);
-		gins(ANOTL, N, &lo1);
-		gins(ANOTL, N, &hi1);
-		splitclean();
-		return;
-
-	case OADD:
-	case OSUB:
-	case OMUL:
-	case OLROT:
-	case OLSH:
-	case ORSH:
-	case OAND:
-	case OOR:
-	case OXOR:
-		// binary operators.
-		// common setup below.
-		break;
-	}
-
-	l = n->left;
-	r = n->right;
-	if(!l->addable) {
-		tempname(&t1, l->type);
-		cgen(l, &t1);
-		l = &t1;
-	}
-	if(r != N && !r->addable) {
-		tempname(&t2, r->type);
-		cgen(r, &t2);
-		r = &t2;
-	}
-
-	nodreg(&ax, types[TINT32], REG_AX);
-	nodreg(&cx, types[TINT32], REG_CX);
-	nodreg(&dx, types[TINT32], REG_DX);
-
-	// Setup for binary operation.
-	split64(l, &lo1, &hi1);
-	if(is64(r->type))
-		split64(r, &lo2, &hi2);
-
-	// Do op.  Leave result in DX:AX.
-	switch(n->op) {
-	case OADD:
-		// TODO: Constants
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-		gins(AADDL, &lo2, &ax);
-		gins(AADCL, &hi2, &dx);
-		break;
-
-	case OSUB:
-		// TODO: Constants.
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-		gins(ASUBL, &lo2, &ax);
-		gins(ASBBL, &hi2, &dx);
-		break;
-
-	case OMUL:
-		// let's call the next two EX and FX.
-		regalloc(&ex, types[TPTR32], N);
-		regalloc(&fx, types[TPTR32], N);
-
-		// load args into DX:AX and EX:CX.
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-		gins(AMOVL, &lo2, &cx);
-		gins(AMOVL, &hi2, &ex);
-
-		// if DX and EX are zero, use 32 x 32 -> 64 unsigned multiply.
-		gins(AMOVL, &dx, &fx);
-		gins(AORL, &ex, &fx);
-		p1 = gbranch(AJNE, T, 0);
-		gins(AMULL, &cx, N);	// implicit &ax
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-
-		// full 64x64 -> 64, from 32x32 -> 64.
-		gins(AIMULL, &cx, &dx);
-		gins(AMOVL, &ax, &fx);
-		gins(AIMULL, &ex, &fx);
-		gins(AADDL, &dx, &fx);
-		gins(AMOVL, &cx, &dx);
-		gins(AMULL, &dx, N);	// implicit &ax
-		gins(AADDL, &fx, &dx);
-		patch(p2, pc);
-
-		regfree(&ex);
-		regfree(&fx);
-		break;
-	
-	case OLROT:
-		// We only rotate by a constant c in [0,64).
-		// if c >= 32:
-		//	lo, hi = hi, lo
-		//	c -= 32
-		// if c == 0:
-		//	no-op
-		// else:
-		//	t = hi
-		//	shld hi:lo, c
-		//	shld lo:t, c
-		v = mpgetfix(r->val.u.xval);
-		if(v >= 32) {
-			// reverse during load to do the first 32 bits of rotate
-			v -= 32;
-			gins(AMOVL, &lo1, &dx);
-			gins(AMOVL, &hi1, &ax);
-		} else {
-			gins(AMOVL, &lo1, &ax);
-			gins(AMOVL, &hi1, &dx);
-		}
-		if(v == 0) {
-			// done
-		} else {
-			gins(AMOVL, &dx, &cx);
-			p1 = gins(ASHLL, ncon(v), &dx);
-			p1->from.index = REG_AX;	// double-width shift
-			p1->from.scale = 0;
-			p1 = gins(ASHLL, ncon(v), &ax);
-			p1->from.index = REG_CX;	// double-width shift
-			p1->from.scale = 0;
-		}
-		break;
-
-	case OLSH:
-		if(r->op == OLITERAL) {
-			v = mpgetfix(r->val.u.xval);
-			if(v >= 64) {
-				if(is64(r->type))
-					splitclean();
-				splitclean();
-				split64(res, &lo2, &hi2);
-				gins(AMOVL, ncon(0), &lo2);
-				gins(AMOVL, ncon(0), &hi2);
-				splitclean();
-				goto out;
-			}
-			if(v >= 32) {
-				if(is64(r->type))
-					splitclean();
-				split64(res, &lo2, &hi2);
-				gmove(&lo1, &hi2);
-				if(v > 32) {
-					gins(ASHLL, ncon(v - 32), &hi2);
-				}
-				gins(AMOVL, ncon(0), &lo2);
-				splitclean();
-				splitclean();
-				goto out;
-			}
-
-			// general shift
-			gins(AMOVL, &lo1, &ax);
-			gins(AMOVL, &hi1, &dx);
-			p1 = gins(ASHLL, ncon(v), &dx);
-			p1->from.index = REG_AX;	// double-width shift
-			p1->from.scale = 0;
-			gins(ASHLL, ncon(v), &ax);
-			break;
-		}
-
-		// load value into DX:AX.
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-
-		// load shift value into register.
-		// if high bits are set, zero value.
-		p1 = P;
-		if(is64(r->type)) {
-			gins(ACMPL, &hi2, ncon(0));
-			p1 = gbranch(AJNE, T, +1);
-			gins(AMOVL, &lo2, &cx);
-		} else {
-			cx.type = types[TUINT32];
-			gmove(r, &cx);
-		}
-
-		// if shift count is >=64, zero value
-		gins(ACMPL, &cx, ncon(64));
-		p2 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		if(p1 != P)
-			patch(p1, pc);
-		gins(AXORL, &dx, &dx);
-		gins(AXORL, &ax, &ax);
-		patch(p2, pc);
-
-		// if shift count is >= 32, zero low.
-		gins(ACMPL, &cx, ncon(32));
-		p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		gins(AMOVL, &ax, &dx);
-		gins(ASHLL, &cx, &dx);	// SHLL only uses bottom 5 bits of count
-		gins(AXORL, &ax, &ax);
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-
-		// general shift
-		p1 = gins(ASHLL, &cx, &dx);
-		p1->from.index = REG_AX;	// double-width shift
-		p1->from.scale = 0;
-		gins(ASHLL, &cx, &ax);
-		patch(p2, pc);
-		break;
-
-	case ORSH:
-		if(r->op == OLITERAL) {
-			v = mpgetfix(r->val.u.xval);
-			if(v >= 64) {
-				if(is64(r->type))
-					splitclean();
-				splitclean();
-				split64(res, &lo2, &hi2);
-				if(hi1.type->etype == TINT32) {
-					gmove(&hi1, &lo2);
-					gins(ASARL, ncon(31), &lo2);
-					gmove(&hi1, &hi2);
-					gins(ASARL, ncon(31), &hi2);
-				} else {
-					gins(AMOVL, ncon(0), &lo2);
-					gins(AMOVL, ncon(0), &hi2);
-				}
-				splitclean();
-				goto out;
-			}
-			if(v >= 32) {
-				if(is64(r->type))
-					splitclean();
-				split64(res, &lo2, &hi2);
-				gmove(&hi1, &lo2);
-				if(v > 32)
-					gins(optoas(ORSH, hi1.type), ncon(v-32), &lo2);
-				if(hi1.type->etype == TINT32) {
-					gmove(&hi1, &hi2);
-					gins(ASARL, ncon(31), &hi2);
-				} else
-					gins(AMOVL, ncon(0), &hi2);
-				splitclean();
-				splitclean();
-				goto out;
-			}
-
-			// general shift
-			gins(AMOVL, &lo1, &ax);
-			gins(AMOVL, &hi1, &dx);
-			p1 = gins(ASHRL, ncon(v), &ax);
-			p1->from.index = REG_DX;	// double-width shift
-			p1->from.scale = 0;
-			gins(optoas(ORSH, hi1.type), ncon(v), &dx);
-			break;
-		}
-
-		// load value into DX:AX.
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-
-		// load shift value into register.
-		// if high bits are set, zero value.
-		p1 = P;
-		if(is64(r->type)) {
-			gins(ACMPL, &hi2, ncon(0));
-			p1 = gbranch(AJNE, T, +1);
-			gins(AMOVL, &lo2, &cx);
-		} else {
-			cx.type = types[TUINT32];
-			gmove(r, &cx);
-		}
-
-		// if shift count is >=64, zero or sign-extend value
-		gins(ACMPL, &cx, ncon(64));
-		p2 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		if(p1 != P)
-			patch(p1, pc);
-		if(hi1.type->etype == TINT32) {
-			gins(ASARL, ncon(31), &dx);
-			gins(AMOVL, &dx, &ax);
-		} else {
-			gins(AXORL, &dx, &dx);
-			gins(AXORL, &ax, &ax);
-		}
-		patch(p2, pc);
-
-		// if shift count is >= 32, sign-extend hi.
-		gins(ACMPL, &cx, ncon(32));
-		p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		gins(AMOVL, &dx, &ax);
-		if(hi1.type->etype == TINT32) {
-			gins(ASARL, &cx, &ax);	// SARL only uses bottom 5 bits of count
-			gins(ASARL, ncon(31), &dx);
-		} else {
-			gins(ASHRL, &cx, &ax);
-			gins(AXORL, &dx, &dx);
-		}
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-
-		// general shift
-		p1 = gins(ASHRL, &cx, &ax);
-		p1->from.index = REG_DX;	// double-width shift
-		p1->from.scale = 0;
-		gins(optoas(ORSH, hi1.type), &cx, &dx);
-		patch(p2, pc);
-		break;
-
-	case OXOR:
-	case OAND:
-	case OOR:
-		// make constant the right side (it usually is anyway).
-		if(lo1.op == OLITERAL) {
-			nswap(&lo1, &lo2);
-			nswap(&hi1, &hi2);
-		}
-		if(lo2.op == OLITERAL) {
-			// special cases for constants.
-			lv = mpgetfix(lo2.val.u.xval);
-			hv = mpgetfix(hi2.val.u.xval);
-			splitclean();	// right side
-			split64(res, &lo2, &hi2);
-			switch(n->op) {
-			case OXOR:
-				gmove(&lo1, &lo2);
-				gmove(&hi1, &hi2);
-				switch(lv) {
-				case 0:
-					break;
-				case 0xffffffffu:
-					gins(ANOTL, N, &lo2);
-					break;
-				default:
-					gins(AXORL, ncon(lv), &lo2);
-					break;
-				}
-				switch(hv) {
-				case 0:
-					break;
-				case 0xffffffffu:
-					gins(ANOTL, N, &hi2);
-					break;
-				default:
-					gins(AXORL, ncon(hv), &hi2);
-					break;
-				}
-				break;
-
-			case OAND:
-				switch(lv) {
-				case 0:
-					gins(AMOVL, ncon(0), &lo2);
-					break;
-				default:
-					gmove(&lo1, &lo2);
-					if(lv != 0xffffffffu)
-						gins(AANDL, ncon(lv), &lo2);
-					break;
-				}
-				switch(hv) {
-				case 0:
-					gins(AMOVL, ncon(0), &hi2);
-					break;
-				default:
-					gmove(&hi1, &hi2);
-					if(hv != 0xffffffffu)
-						gins(AANDL, ncon(hv), &hi2);
-					break;
-				}
-				break;
-
-			case OOR:
-				switch(lv) {
-				case 0:
-					gmove(&lo1, &lo2);
-					break;
-				case 0xffffffffu:
-					gins(AMOVL, ncon(0xffffffffu), &lo2);
-					break;
-				default:
-					gmove(&lo1, &lo2);
-					gins(AORL, ncon(lv), &lo2);
-					break;
-				}
-				switch(hv) {
-				case 0:
-					gmove(&hi1, &hi2);
-					break;
-				case 0xffffffffu:
-					gins(AMOVL, ncon(0xffffffffu), &hi2);
-					break;
-				default:
-					gmove(&hi1, &hi2);
-					gins(AORL, ncon(hv), &hi2);
-					break;
-				}
-				break;
-			}
-			splitclean();
-			splitclean();
-			goto out;
-		}
-		gins(AMOVL, &lo1, &ax);
-		gins(AMOVL, &hi1, &dx);
-		gins(optoas(n->op, lo1.type), &lo2, &ax);
-		gins(optoas(n->op, lo1.type), &hi2, &dx);
-		break;
-	}
-	if(is64(r->type))
-		splitclean();
-	splitclean();
-
-	split64(res, &lo1, &hi1);
-	gins(AMOVL, &ax, &lo1);
-	gins(AMOVL, &dx, &hi1);
-	splitclean();
-
-out:;
-}
-
-/*
- * generate comparison of nl, nr, both 64-bit.
- * nl is memory; nr is constant or memory.
- */
-void
-cmp64(Node *nl, Node *nr, int op, int likely, Prog *to)
-{
-	Node lo1, hi1, lo2, hi2, rr;
-	Prog *br;
-	Type *t;
-
-	split64(nl, &lo1, &hi1);
-	split64(nr, &lo2, &hi2);
-
-	// compare most significant word;
-	// if they differ, we're done.
-	t = hi1.type;
-	if(nl->op == OLITERAL || nr->op == OLITERAL)
-		gins(ACMPL, &hi1, &hi2);
-	else {
-		regalloc(&rr, types[TINT32], N);
-		gins(AMOVL, &hi1, &rr);
-		gins(ACMPL, &rr, &hi2);
-		regfree(&rr);
-	}
-	br = P;
-	switch(op) {
-	default:
-		fatal("cmp64 %O %T", op, t);
-	case OEQ:
-		// cmp hi
-		// jne L
-		// cmp lo
-		// jeq to
-		// L:
-		br = gbranch(AJNE, T, -likely);
-		break;
-	case ONE:
-		// cmp hi
-		// jne to
-		// cmp lo
-		// jne to
-		patch(gbranch(AJNE, T, likely), to);
-		break;
-	case OGE:
-	case OGT:
-		// cmp hi
-		// jgt to
-		// jlt L
-		// cmp lo
-		// jge to (or jgt to)
-		// L:
-		patch(gbranch(optoas(OGT, t), T, likely), to);
-		br = gbranch(optoas(OLT, t), T, -likely);
-		break;
-	case OLE:
-	case OLT:
-		// cmp hi
-		// jlt to
-		// jgt L
-		// cmp lo
-		// jle to (or jlt to)
-		// L:
-		patch(gbranch(optoas(OLT, t), T, likely), to);
-		br = gbranch(optoas(OGT, t), T, -likely);
-		break;
-	}
-
-	// compare least significant word
-	t = lo1.type;
-	if(nl->op == OLITERAL || nr->op == OLITERAL)
-		gins(ACMPL, &lo1, &lo2);
-	else {
-		regalloc(&rr, types[TINT32], N);
-		gins(AMOVL, &lo1, &rr);
-		gins(ACMPL, &rr, &lo2);
-		regfree(&rr);
-	}
-
-	// jump again
-	patch(gbranch(optoas(op, t), T, likely), to);
-
-	// point first branch down here if appropriate
-	if(br != P)
-		patch(br, pc);
-
-	splitclean();
-	splitclean();
-}
-
diff --git a/src/cmd/new8g/cgen64.go b/src/cmd/8g/cgen64.go
similarity index 100%
rename from src/cmd/new8g/cgen64.go
rename to src/cmd/8g/cgen64.go
diff --git a/src/cmd/8g/doc.go b/src/cmd/8g/doc.go
deleted file mode 100644
index 9e46dca..0000000
--- a/src/cmd/8g/doc.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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
-
-/*
-
-8g is the version of the gc compiler for the x86.
-The $GOARCH for these tools is 386.
-
-It reads .go files and outputs .8 files. The flags are documented in ../gc/doc.go.
-
-*/
-package main
diff --git a/src/cmd/8g/galign.c b/src/cmd/8g/galign.c
deleted file mode 100644
index 33951ad..0000000
--- a/src/cmd/8g/galign.c
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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"
-
-int	thechar	= '8';
-char*	thestring	= "386";
-LinkArch*	thelinkarch = &link386;
-
-void
-linkarchinit(void)
-{
-}
-
-vlong MAXWIDTH = (1LL<<32) - 1;
-
-/*
- * go declares several platform-specific type aliases:
- * int, uint, float, and uintptr
- */
-Typedef	typedefs[] =
-{
-	{"int",		TINT,		TINT32},
-	{"uint",		TUINT,		TUINT32},
-	{"uintptr",	TUINTPTR,	TUINT32},
-	{0}
-};
-
-void
-betypeinit(void)
-{
-	widthptr = 4;
-	widthint = 4;
-	widthreg = 4;
-
-	listinit8();
-}
-
-void
-main(int argc, char **argv)
-{
-	thearch.thechar = thechar;
-	thearch.thestring = thestring;
-	thearch.thelinkarch = thelinkarch;
-	thearch.typedefs = typedefs;
-	thearch.REGSP = REGSP;
-	thearch.REGCTXT = REGCTXT;
-	thearch.MAXWIDTH = MAXWIDTH;
-	thearch.anyregalloc = anyregalloc;
-	thearch.betypeinit = betypeinit;
-	thearch.bgen = bgen;
-	thearch.cgen = cgen;
-	thearch.cgen_call = cgen_call;
-	thearch.cgen_callinter = cgen_callinter;
-	thearch.cgen_ret = cgen_ret;
-	thearch.clearfat = clearfat;
-	thearch.defframe = defframe;
-	thearch.excise = excise;
-	thearch.expandchecks = expandchecks;
-	thearch.gclean = gclean;
-	thearch.ginit = ginit;
-	thearch.gins = gins;
-	thearch.ginscall = ginscall;
-	thearch.igen = igen;
-	thearch.linkarchinit = linkarchinit;
-	thearch.peep = peep;
-	thearch.proginfo = proginfo;
-	thearch.regalloc = regalloc;
-	thearch.regfree = regfree;
-	thearch.regtyp = regtyp;
-	thearch.sameaddr = sameaddr;
-	thearch.smallindir = smallindir;
-	thearch.stackaddr = stackaddr;
-	thearch.excludedregs = excludedregs;
-	thearch.RtoB = RtoB;
-	thearch.FtoB = FtoB;
-	thearch.BtoR = BtoR;
-	thearch.BtoF = BtoF;
-	thearch.optoas = optoas;
-	thearch.doregbits = doregbits;
-	thearch.regnames = regnames;
-	
-	gcmain(argc, argv);
-}
diff --git a/src/cmd/new8g/galign.go b/src/cmd/8g/galign.go
similarity index 100%
rename from src/cmd/new8g/galign.go
rename to src/cmd/8g/galign.go
diff --git a/src/cmd/new8g/gg.go b/src/cmd/8g/gg.go
similarity index 100%
rename from src/cmd/new8g/gg.go
rename to src/cmd/8g/gg.go
diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h
deleted file mode 100644
index 872d946..0000000
--- a/src/cmd/8g/gg.h
+++ /dev/null
@@ -1,189 +0,0 @@
-// 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.
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#include "../gc/go.h"
-#include "../8l/8.out.h"
-
-// foptoas flags
-enum
-{
-	Frev = 1<<0,
-	Fpop = 1<<1,
-	Fpop2 = 1<<2,
-};
-
-EXTERN	uchar	reg[MAXREG];
-EXTERN	Node*	panicdiv;
-extern	uint32	unmappedzero;
-
-
-/*
- * ggen.c
- */
-void	compile(Node*);
-void	gen(Node*);
-Node*	lookdot(Node*, Node*, int);
-void	cgen_as(Node*, Node*);
-void	cgen_callmeth(Node*, int);
-void	cgen_callinter(Node*, Node*, int);
-void	cgen_proc(Node*, int);
-void	cgen_callret(Node*, Node*);
-void	cgen_div(int, Node*, Node*, Node*);
-void	cgen_bmul(int, Node*, Node*, Node*);
-void	cgen_hmul(Node*, Node*, Node*);
-void	cgen_shift(int, int, Node*, Node*, Node*);
-void	cgen_float(Node*, Node*);
-void	bgen_float(Node *n, int true, int likely, Prog *to);
-void	cgen_dcl(Node*);
-int	needconvert(Type*, Type*);
-void	genconv(Type*, Type*);
-void	allocparams(void);
-void	checklabels(void);
-void	ginscall(Node*, int);
-
-/*
- * cgen.c
- */
-void	agen(Node*, Node*);
-void	igen(Node*, Node*, Node*);
-vlong	fieldoffset(Type*, Node*);
-void	sgen(Node*, Node*, int64);
-void	gmove(Node*, Node*);
-Prog*	gins(int, Node*, Node*);
-int	samaddr(Node*, Node*);
-void	naddr(Node*, Addr*, int);
-void	cgen_aret(Node*, Node*);
-Node*	ncon(uint32);
-void	mgen(Node*, Node*, Node*);
-void	mfree(Node*);
-int	componentgen(Node*, Node*);
-
-/*
- * cgen64.c
- */
-void	cmp64(Node*, Node*, int, int, Prog*);
-void	cgen64(Node*, Node*);
-
-/*
- * gsubr.c
- */
-void	clearp(Prog*);
-Prog*	gbranch(int, Type*, int);
-Prog*	prog(int);
-void	gconv(int, int);
-int	conv2pt(Type*);
-vlong	convvtox(vlong, int);
-void	fnparam(Type*, int, int);
-Prog*	gop(int, Node*, Node*, Node*);
-int	optoas(int, Type*);
-int	foptoas(int, Type*, int);
-void	ginit(void);
-void	gclean(void);
-void	regalloc(Node*, Type*, Node*);
-void	regfree(Node*);
-Node*	nodarg(Type*, int);
-void	nodreg(Node*, Type*, int);
-void	nodindreg(Node*, Type*, int);
-void	nodconst(Node*, Type*, int64);
-void	gconreg(int, vlong, int);
-void	buildtxt(void);
-Plist*	newplist(void);
-int	isfat(Type*);
-void	sudoclean(void);
-int	sudoaddable(int, Node*, Addr*);
-int	dotaddable(Node*, Node*);
-void	afunclit(Addr*, Node*);
-void	split64(Node*, Node*, Node*);
-void	splitclean(void);
-void	nswap(Node*, Node*);
-void	gtrack(Sym*);
-/*
- * cplx.c
- */
-int	complexop(Node*, Node*);
-void	complexmove(Node*, Node*);
-void	complexgen(Node*, Node*);
-
-/*
- * gobj.c
- */
-void	datastring(char*, int, Addr*);
-void	datagostring(Strlit*, Addr*);
-
-/*
- * list.c
- */
-void	listinit(void);
-
-void	zaddr(Biobuf*, Addr*, int, int);
-
-void afunclit(Addr*, Node*);
-int anyregalloc(void);
-void betypeinit(void);
-void bgen(Node*, int, int, Prog*);
-void cgen(Node*, Node*);
-void cgen_call(Node*, int);
-void cgen_callinter(Node*, Node*, int);
-void cgen_ret(Node*);
-void clearfat(Node*);
-void clearp(Prog*);
-void defframe(Prog*);
-int dgostringptr(Sym*, int, char*);
-int dgostrlitptr(Sym*, int, Strlit*);
-int dsname(Sym*, int, char*, int);
-int dsymptr(Sym*, int, Sym*, int);
-void dumpdata(void);
-void dumpit(char*, Flow*, int);
-void excise(Flow*);
-void expandchecks(Prog*);
-void fixautoused(Prog*);
-void gclean(void);
-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 ginit(void);
-Prog*	gins(int, Node*, Node*);
-void	ginscall(Node*, int);
-Prog*	gjmp(Prog*);
-void gtrack(Sym*);
-void	gused(Node*);
-void	igen(Node*, Node*, Node*);
-int isfat(Type*);
-void linkarchinit(void);
-void markautoused(Prog*);
-void naddr(Node*, Addr*, int);
-Plist* newplist(void);
-Node* nodarg(Type*, int);
-void patch(Prog*, Prog*);
-void proginfo(ProgInfo*, Prog*);
-void regalloc(Node*, Type*, Node*);
-void regfree(Node*);
-void regopt(Prog*);
-int regtyp(Addr*);
-int sameaddr(Addr*, Addr*);
-int smallindir(Addr*, Addr*);
-int stackaddr(Addr*);
-Prog* unpatch(Prog*);
-
-/*
- * reg.c
- */
-uint64 excludedregs(void);
-uint64 RtoB(int);
-uint64 FtoB(int);
-int BtoR(uint64);
-int BtoF(uint64);
-uint64 doregbits(int);
-char** regnames(int*);
-
-/*
- * peep.c
- */
-void peep(Prog*);
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
deleted file mode 100644
index 8188348..0000000
--- a/src/cmd/8g/ggen.c
+++ /dev/null
@@ -1,1165 +0,0 @@
-// 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.
-
-#undef	EXTERN
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
-static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
-
-void
-defframe(Prog *ptxt)
-{
-	uint32 frame, ax;
-	Prog *p;
-	vlong lo, hi;
-	NodeList *l;
-	Node *n;
-
-	// fill in argument size, stack size
-	ptxt->to.type = TYPE_TEXTSIZE;
-	ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
-	frame = rnd(stksize+maxarg, widthreg);
-	ptxt->to.offset = frame;
-	
-	// insert code to zero ambiguously live variables
-	// so that the garbage collector only sees initialized values
-	// when it looks for pointers.
-	p = ptxt;
-	hi = 0;
-	lo = hi;
-	ax = 0;
-	for(l=curfn->dcl; l != nil; l = l->next) {
-		n = l->n;
-		if(!n->needzero)
-			continue;
-		if(n->class != PAUTO)
-			fatal("needzero class %d", n->class);
-		if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
-			fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
-		if(lo != hi && n->xoffset + n->type->width == lo - 2*widthptr) {
-			// merge with range we already have
-			lo = n->xoffset;
-			continue;
-		}
-		// zero old range
-		p = zerorange(p, frame, lo, hi, &ax);
-
-		// set new range
-		hi = n->xoffset + n->type->width;
-		lo = n->xoffset;
-	}
-	// zero final range
-	zerorange(p, frame, lo, hi, &ax);
-}
-
-static Prog*
-zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
-{
-	vlong cnt, i;
-
-	cnt = hi - lo;
-	if(cnt == 0)
-		return p;
-	if(*ax == 0) {
-		p = appendpp(p, AMOVL, TYPE_CONST, 0, 0, TYPE_REG, REG_AX, 0);
-		*ax = 1;
-	}
-	if(cnt <= 4*widthreg) {
-		for(i = 0; i < cnt; i += widthreg) {
-			p = appendpp(p, AMOVL, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo+i);
-		}
-	} else if(!nacl && cnt <= 128*widthreg) {
-		p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
-		p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_ADDR, 0, 1*(128-cnt/widthreg));
-		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-	} else {
-		p = appendpp(p, AMOVL, TYPE_CONST, 0, cnt/widthreg, TYPE_REG, REG_CX, 0);
-		p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
-		p = appendpp(p, AREP, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
-		p = appendpp(p, ASTOSL, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
-	}
-	return p;
-}
-
-static Prog*	
-appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)	
-{
-	Prog *q;
-	q = mal(sizeof(*q));	
-	clearp(q);	
-	q->as = as;	
-	q->lineno = p->lineno;	
-	q->from.type = ftype;	
-	q->from.reg = freg;
-	q->from.offset = foffset;	
-	q->to.type = ttype;	
-	q->to.reg = treg;
-	q->to.offset = toffset;	
-	q->link = p->link;	
-	p->link = q;	
-	return q;	
-}
-
-void
-clearfat(Node *nl)
-{
-	uint32 w, c, q;
-	Node n1, z;
-	Prog *p;
-
-	/* clear a fat object */
-	if(debug['g'])
-		dump("\nclearfat", nl);
-
-	w = nl->type->width;
-	// Avoid taking the address for simple enough types.
-	if(componentgen(N, nl))
-		return;
-
-	c = w % 4;	// bytes
-	q = w / 4;	// quads
-
-	if(q < 4) {
-		// Write sequence of MOV 0, off(base) instead of using STOSL.
-		// The hope is that although the code will be slightly longer,
-		// the MOVs will have no dependencies and pipeline better
-		// than the unrolled STOSL loop.
-		// NOTE: Must use agen, not igen, so that optimizer sees address
-		// being taken. We are not writing on field boundaries.
-		regalloc(&n1, types[tptr], N);
-		agen(nl, &n1);
-		n1.op = OINDREG;
-		nodconst(&z, types[TUINT64], 0);
-		while(q-- > 0) {
-			n1.type = z.type;
-			gins(AMOVL, &z, &n1);
-			n1.xoffset += 4;
-		}
-		nodconst(&z, types[TUINT8], 0);
-		while(c-- > 0) {
-			n1.type = z.type;
-			gins(AMOVB, &z, &n1);
-			n1.xoffset++;
-		}
-		regfree(&n1);
-		return;
-	}
-
-	nodreg(&n1, types[tptr], REG_DI);
-	agen(nl, &n1);
-	gconreg(AMOVL, 0, REG_AX);
-
-	if(q > 128 || (q >= 4 && nacl)) {
-		gconreg(AMOVL, q, REG_CX);
-		gins(AREP, N, N);	// repeat
-		gins(ASTOSL, N, N);	// STOL AL,*(DI)+
-	} else if(q >= 4) {
-		p = gins(ADUFFZERO, N, N);
-		p->to.type = TYPE_ADDR;
-		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-		// 1 and 128 = magic constants: see ../../runtime/asm_386.s
-		p->to.offset = 1*(128-q);
-	} else
-	while(q > 0) {
-		gins(ASTOSL, N, N);	// STOL AL,*(DI)+
-		q--;
-	}
-
-	while(c > 0) {
-		gins(ASTOSB, N, N);	// STOB AL,*(DI)+
-		c--;
-	}
-}
-
-/*
- * generate:
- *	call f
- *	proc=-1	normal call but no return
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
-  *	proc=3	normal call to C pointer (not Go func value)
- */
-void
-ginscall(Node *f, int proc)
-{
-	Prog *p;
-	Node reg, r1, con, stk;
-	int32 extra;
-
-	if(f->type != T) {
-		extra = 0;
-		if(proc == 1 || proc == 2)
-			extra = 2 * widthptr;
-		setmaxarg(f->type, extra);
-	}
-
-	switch(proc) {
-	default:
-		fatal("ginscall: bad proc %d", proc);
-		break;
-
-	case 0:	// normal call
-	case -1:	// normal call but no return
-		if(f->op == ONAME && f->class == PFUNC) {
-			if(f == deferreturn) {
-				// Deferred calls will appear to be returning to
-				// the CALL deferreturn(SB) that we are about to emit.
-				// However, the stack trace code will show the line
-				// of the instruction byte before the return PC. 
-				// To avoid that being an unrelated instruction,
-				// insert an x86 NOP that we will have the right line number.
-				// x86 NOP 0x90 is really XCHG AX, AX; use that description
-				// because the NOP pseudo-instruction will be removed by
-				// the linker.
-				nodreg(&reg, types[TINT], REG_AX);
-				gins(AXCHGL, &reg, &reg);
-			}
-			p = gins(ACALL, N, f);
-			afunclit(&p->to, f);
-			if(proc == -1 || noreturn(p))
-				gins(AUNDEF, N, N);
-			break;
-		}
-		nodreg(&reg, types[tptr], REG_DX);
-		nodreg(&r1, types[tptr], REG_BX);
-		gmove(f, &reg);
-		reg.op = OINDREG;
-		gmove(&reg, &r1);
-		reg.op = OREGISTER;
-		gins(ACALL, &reg, &r1);
-		break;
-	
-	case 3:	// normal call of c function pointer
-		gins(ACALL, N, f);
-		break;
-
-	case 1:	// call in new proc (go)
-	case 2:	// deferred call (defer)
-		memset(&stk, 0, sizeof(stk));
-		stk.op = OINDREG;
-		stk.val.u.reg = REG_SP;
-		stk.xoffset = 0;
-
-		// size of arguments at 0(SP)
-		nodconst(&con, types[TINT32], argsize(f->type));
-		gins(AMOVL, &con, &stk);
-
-		// FuncVal* at 4(SP)
-		stk.xoffset = widthptr;
-		gins(AMOVL, f, &stk);
-
-		if(proc == 1)
-			ginscall(newproc, 0);
-		else
-			ginscall(deferproc, 0);
-		if(proc == 2) {
-			nodreg(&reg, types[TINT32], REG_AX);
-			gins(ATESTL, &reg, &reg);
-			p = gbranch(AJEQ, T, +1);
-			cgen_ret(N);
-			patch(p, pc);
-		}
-		break;
-	}
-}
-
-/*
- * n is call to interface method.
- * generate res = n.
- */
-void
-cgen_callinter(Node *n, Node *res, int proc)
-{
-	Node *i, *f;
-	Node tmpi, nodi, nodo, nodr, nodsp;
-
-	i = n->left;
-	if(i->op != ODOTINTER)
-		fatal("cgen_callinter: not ODOTINTER %O", i->op);
-
-	f = i->right;		// field
-	if(f->op != ONAME)
-		fatal("cgen_callinter: not ONAME %O", f->op);
-
-	i = i->left;		// interface
-
-	if(!i->addable) {
-		tempname(&tmpi, i->type);
-		cgen(i, &tmpi);
-		i = &tmpi;
-	}
-
-	genlist(n->list);		// assign the args
-
-	// i is now addable, prepare an indirected
-	// register to hold its address.
-	igen(i, &nodi, res);		// REG = &inter
-
-	nodindreg(&nodsp, types[tptr], REG_SP);
-	nodsp.xoffset = 0;
-	if(proc != 0)
-		nodsp.xoffset += 2 * widthptr; // leave room for size & fn
-	nodi.type = types[tptr];
-	nodi.xoffset += widthptr;
-	cgen(&nodi, &nodsp);	// {0 or 8}(SP) = 4(REG) -- i.data
-
-	regalloc(&nodo, types[tptr], res);
-	nodi.type = types[tptr];
-	nodi.xoffset -= widthptr;
-	cgen(&nodi, &nodo);	// REG = 0(REG) -- i.tab
-	regfree(&nodi);
-
-	regalloc(&nodr, types[tptr], &nodo);
-	if(n->left->xoffset == BADWIDTH)
-		fatal("cgen_callinter: badwidth");
-	cgen_checknil(&nodo);
-	nodo.op = OINDREG;
-	nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
-	
-	if(proc == 0) {
-		// plain call: use direct c function pointer - more efficient
-		cgen(&nodo, &nodr);	// REG = 20+offset(REG) -- i.tab->fun[f]
-		proc = 3;
-	} else {
-		// go/defer. generate go func value.
-		gins(ALEAL, &nodo, &nodr);	// REG = &(20+offset(REG)) -- i.tab->fun[f]
-	}
-
-	nodr.type = n->left->type;
-	ginscall(&nodr, proc);
-
-	regfree(&nodr);
-	regfree(&nodo);
-}
-
-/*
- * generate function call;
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
- */
-void
-cgen_call(Node *n, int proc)
-{
-	Type *t;
-	Node nod, afun;
-
-	if(n == N)
-		return;
-
-	if(n->left->ullman >= UINF) {
-		// if name involves a fn call
-		// precompute the address of the fn
-		tempname(&afun, types[tptr]);
-		cgen(n->left, &afun);
-	}
-
-	genlist(n->list);		// assign the args
-	t = n->left->type;
-
-	// call tempname pointer
-	if(n->left->ullman >= UINF) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, &afun);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call pointer
-	if(n->left->op != ONAME || n->left->class != PFUNC) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, n->left);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call direct
-	n->left->method = 1;
-	ginscall(n->left, proc);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = return value from call.
- */
-void
-cgen_callret(Node *n, Node *res)
-{
-	Node nod;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(t->etype == TPTR32 || t->etype == TPTR64)
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_callret: nil");
-
-	memset(&nod, 0, sizeof(nod));
-	nod.op = OINDREG;
-	nod.val.u.reg = REG_SP;
-	nod.addable = 1;
-
-	nod.xoffset = fp->width;
-	nod.type = fp->type;
-	cgen_as(res, &nod);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = &return value from call.
- */
-void
-cgen_aret(Node *n, Node *res)
-{
-	Node nod1, nod2;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(isptr[t->etype])
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_aret: nil");
-
-	memset(&nod1, 0, sizeof(nod1));
-	nod1.op = OINDREG;
-	nod1.val.u.reg = REG_SP;
-	nod1.addable = 1;
-
-	nod1.xoffset = fp->width;
-	nod1.type = fp->type;
-
-	if(res->op != OREGISTER) {
-		regalloc(&nod2, types[tptr], res);
-		gins(ALEAL, &nod1, &nod2);
-		gins(AMOVL, &nod2, res);
-		regfree(&nod2);
-	} else
-		gins(ALEAL, &nod1, res);
-}
-
-/*
- * generate return.
- * n->left is assignments to return values.
- */
-void
-cgen_ret(Node *n)
-{
-	Prog *p;
-
-	if(n != N)
-		genlist(n->list);		// copy out args
-	if(hasdefer)
-		ginscall(deferreturn, 0);
-	genlist(curfn->exit);
-	p = gins(ARET, N, N);
-	if(n != N && n->op == ORETJMP) {
-		p->to.type = TYPE_MEM;
-		p->to.name = NAME_EXTERN;
-		p->to.sym = linksym(n->left->sym);
-	}
-}
-
-/*
- * generate division.
- * caller must set:
- *	ax = allocated AX register
- *	dx = allocated DX register
- * generates one of:
- *	res = nl / nr
- *	res = nl % nr
- * according to op.
- */
-void
-dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
-{
-	int check;
-	Node n1, t1, t2, t3, t4, n4, nz;
-	Type *t, *t0;
-	Prog *p1, *p2;
-
-	// Have to be careful about handling
-	// most negative int divided by -1 correctly.
-	// The hardware will trap.
-	// Also the byte divide instruction needs AH,
-	// which we otherwise don't have to deal with.
-	// Easiest way to avoid for int8, int16: use int32.
-	// For int32 and int64, use explicit test.
-	// Could use int64 hw for int32.
-	t = nl->type;
-	t0 = t;
-	check = 0;
-	if(issigned[t->etype]) {
-		check = 1;
-		if(isconst(nl, CTINT) && mpgetfix(nl->val.u.xval) != -1LL<<(t->width*8-1))
-			check = 0;
-		else if(isconst(nr, CTINT) && mpgetfix(nr->val.u.xval) != -1)
-			check = 0;
-	}
-	if(t->width < 4) {
-		if(issigned[t->etype])
-			t = types[TINT32];
-		else
-			t = types[TUINT32];
-		check = 0;
-	}
-
-	tempname(&t1, t);
-	tempname(&t2, t);
-	if(t0 != t) {
-		tempname(&t3, t0);
-		tempname(&t4, t0);
-		cgen(nl, &t3);
-		cgen(nr, &t4);
-		// Convert.
-		gmove(&t3, &t1);
-		gmove(&t4, &t2);
-	} else {
-		cgen(nl, &t1);
-		cgen(nr, &t2);
-	}
-
-	if(!samereg(ax, res) && !samereg(dx, res))
-		regalloc(&n1, t, res);
-	else
-		regalloc(&n1, t, N);
-	gmove(&t2, &n1);
-	gmove(&t1, ax);
-	p2 = P;
-	if(nacl) {
-		// Native Client does not relay the divide-by-zero trap
-		// to the executing program, so we must insert a check
-		// for ourselves.
-		nodconst(&n4, t, 0);
-		gins(optoas(OCMP, t), &n1, &n4);
-		p1 = gbranch(optoas(ONE, t), T, +1);
-		if(panicdiv == N)
-			panicdiv = sysfunc("panicdivide");
-		ginscall(panicdiv, -1);
-		patch(p1, pc);
-	}
-	if(check) {
-		nodconst(&n4, t, -1);
-		gins(optoas(OCMP, t), &n1, &n4);
-		p1 = gbranch(optoas(ONE, t), T, +1);
-		if(op == ODIV) {
-			// a / (-1) is -a.
-			gins(optoas(OMINUS, t), N, ax);
-			gmove(ax, res);
-		} else {
-			// a % (-1) is 0.
-			nodconst(&n4, t, 0);
-			gmove(&n4, res);
-		}
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-	}
-	if(!issigned[t->etype]) {
-		nodconst(&nz, t, 0);
-		gmove(&nz, dx);
-	} else
-		gins(optoas(OEXTEND, t), N, N);
-	gins(optoas(op, t), &n1, N);
-	regfree(&n1);
-
-	if(op == ODIV)
-		gmove(ax, res);
-	else
-		gmove(dx, res);
-	if(check)
-		patch(p2, pc);
-}
-
-static void
-savex(int dr, Node *x, Node *oldx, Node *res, Type *t)
-{
-	int r;
-
-	r = reg[dr];
-	nodreg(x, types[TINT32], dr);
-
-	// save current ax and dx if they are live
-	// and not the destination
-	memset(oldx, 0, sizeof *oldx);
-	if(r > 0 && !samereg(x, res)) {
-		tempname(oldx, types[TINT32]);
-		gmove(x, oldx);
-	}
-
-	regalloc(x, t, x);
-}
-
-static void
-restx(Node *x, Node *oldx)
-{
-	regfree(x);
-
-	if(oldx->op != 0) {
-		x->type = types[TINT32];
-		gmove(oldx, x);
-	}
-}
-
-/*
- * generate division according to op, one of:
- *	res = nl / nr
- *	res = nl % nr
- */
-void
-cgen_div(int op, Node *nl, Node *nr, Node *res)
-{
-	Node ax, dx, oldax, olddx;
-	Type *t;
-
-	if(is64(nl->type))
-		fatal("cgen_div %T", nl->type);
-
-	if(issigned[nl->type->etype])
-		t = types[TINT32];
-	else
-		t = types[TUINT32];
-	savex(REG_AX, &ax, &oldax, res, t);
-	savex(REG_DX, &dx, &olddx, res, t);
-	dodiv(op, nl, nr, res, &ax, &dx);
-	restx(&dx, &olddx);
-	restx(&ax, &oldax);
-}
-
-/*
- * generate shift according to op, one of:
- *	res = nl << nr
- *	res = nl >> nr
- */
-void
-cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, nt, cx, oldcx, hi, lo;
-	int a, w;
-	Prog *p1, *p2;
-	uvlong sc;
-
-	if(nl->type->width > 4)
-		fatal("cgen_shift %T", nl->type);
-
-	w = nl->type->width * 8;
-
-	a = optoas(op, nl->type);
-
-	if(nr->op == OLITERAL) {
-		tempname(&n2, nl->type);
-		cgen(nl, &n2);
-		regalloc(&n1, nl->type, res);
-		gmove(&n2, &n1);
-		sc = mpgetfix(nr->val.u.xval);
-		if(sc >= nl->type->width*8) {
-			// large shift gets 2 shifts by width-1
-			gins(a, ncon(w-1), &n1);
-			gins(a, ncon(w-1), &n1);
-		} else
-			gins(a, nr, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		return;
-	}
-
-	memset(&oldcx, 0, sizeof oldcx);
-	nodreg(&cx, types[TUINT32], REG_CX);
-	if(reg[REG_CX] > 1 && !samereg(&cx, res)) {
-		tempname(&oldcx, types[TUINT32]);
-		gmove(&cx, &oldcx);
-	}
-
-	if(nr->type->width > 4) {
-		tempname(&nt, nr->type);
-		n1 = nt;
-	} else {
-		nodreg(&n1, types[TUINT32], REG_CX);
-		regalloc(&n1, nr->type, &n1);		// to hold the shift type in CX
-	}
-
-	if(samereg(&cx, res))
-		regalloc(&n2, nl->type, N);
-	else
-		regalloc(&n2, nl->type, res);
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &n2);
-		cgen(nr, &n1);
-	} else {
-		cgen(nr, &n1);
-		cgen(nl, &n2);
-	}
-
-	// test and fix up large shifts
-	if(bounded) {
-		if(nr->type->width > 4) {
-			// delayed reg alloc
-			nodreg(&n1, types[TUINT32], REG_CX);
-			regalloc(&n1, types[TUINT32], &n1);		// to hold the shift type in CX
-			split64(&nt, &lo, &hi);
-			gmove(&lo, &n1);
-			splitclean();
-		}
-	} else {
-		if(nr->type->width > 4) {
-			// delayed reg alloc
-			nodreg(&n1, types[TUINT32], REG_CX);
-			regalloc(&n1, types[TUINT32], &n1);		// to hold the shift type in CX
-			split64(&nt, &lo, &hi);
-			gmove(&lo, &n1);
-			gins(optoas(OCMP, types[TUINT32]), &hi, ncon(0));
-			p2 = gbranch(optoas(ONE, types[TUINT32]), T, +1);
-			gins(optoas(OCMP, types[TUINT32]), &n1, ncon(w));
-			p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-			splitclean();
-			patch(p2, pc);
-		} else {
-			gins(optoas(OCMP, nr->type), &n1, ncon(w));
-			p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
-		}
-		if(op == ORSH && issigned[nl->type->etype]) {
-			gins(a, ncon(w-1), &n2);
-		} else {
-			gmove(ncon(0), &n2);
-		}
-		patch(p1, pc);
-	}
-	gins(a, &n1, &n2);
-
-	if(oldcx.op != 0)
-		gmove(&oldcx, &cx);
-
-	gmove(&n2, res);
-
-	regfree(&n1);
-	regfree(&n2);
-}
-
-/*
- * generate byte multiply:
- *	res = nl * nr
- * there is no 2-operand byte multiply instruction so
- * we do a full-width multiplication and truncate afterwards.
- */
-void
-cgen_bmul(int op, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, nt, *tmp;
-	Type *t;
-	int a;
-
-	// copy from byte to full registers
-	t = types[TUINT32];
-	if(issigned[nl->type->etype])
-		t = types[TINT32];
-
-	// largest ullman on left.
-	if(nl->ullman < nr->ullman) {
-		tmp = nl;
-		nl = nr;
-		nr = tmp;
-	}
-
-	tempname(&nt, nl->type);
-	cgen(nl, &nt);
-	regalloc(&n1, t, res);
-	cgen(nr, &n1);
-	regalloc(&n2, t, N);
-	gmove(&nt, &n2);
-	a = optoas(op, t);
-	gins(a, &n2, &n1);
-	regfree(&n2);
-	gmove(&n1, res);
-	regfree(&n1);
-}
-
-/*
- * generate high multiply:
- *   res = (nl*nr) >> width
- */
-void
-cgen_hmul(Node *nl, Node *nr, Node *res)
-{
-	Type *t;
-	int a;
-	Node n1, n2, ax, dx;
-
-	t = nl->type;
-	a = optoas(OHMUL, t);
-	// gen nl in n1.
-	tempname(&n1, t);
-	cgen(nl, &n1);
-	// gen nr in n2.
-	regalloc(&n2, t, res);
-	cgen(nr, &n2);
-
-	// multiply.
-	nodreg(&ax, t, REG_AX);
-	gmove(&n2, &ax);
-	gins(a, &n1, N);
-	regfree(&n2);
-
-	if(t->width == 1) {
-		// byte multiply behaves differently.
-		nodreg(&ax, t, REG_AH);
-		nodreg(&dx, t, REG_DX);
-		gmove(&ax, &dx);
-	}
-	nodreg(&dx, t, REG_DX);
-	gmove(&dx, res);
-}
-
-static void cgen_float387(Node *n, Node *res);
-static void cgen_floatsse(Node *n, Node *res);
-
-/*
- * generate floating-point operation.
- */
-void
-cgen_float(Node *n, Node *res)
-{
-	Node *nl;
-	Node n1, n2;
-	Prog *p1, *p2, *p3;
-
-	nl = n->left;
-	switch(n->op) {
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OLE:
-	case OGE:
-		p1 = gbranch(AJMP, T, 0);
-		p2 = pc;
-		gmove(nodbool(1), res);
-		p3 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		bgen(n, 1, 0, p2);
-		gmove(nodbool(0), res);
-		patch(p3, pc);
-		return;
-
-	case OPLUS:
-		cgen(nl, res);
-		return;
-
-	case OCONV:
-		if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
-			cgen(nl, res);
-			return;
-		}
-
-		tempname(&n2, n->type);
-		mgen(nl, &n1, res);
-		gmove(&n1, &n2);
-		gmove(&n2, res);
-		mfree(&n1);
-		return;
-	}
-
-	if(use_sse)
-		cgen_floatsse(n, res);
-	else
-		cgen_float387(n, res);
-}
-
-// floating-point.  387 (not SSE2)
-static void
-cgen_float387(Node *n, Node *res)
-{
-	Node f0, f1;
-	Node *nl, *nr;
-
-	nl = n->left;
-	nr = n->right;
-	nodreg(&f0, nl->type, REG_F0);
-	nodreg(&f1, n->type, REG_F0+1);
-	if(nr != N)
-		goto flt2;
-
-	// unary
-	cgen(nl, &f0);
-	if(n->op != OCONV && n->op != OPLUS)
-		gins(foptoas(n->op, n->type, 0), N, N);
-	gmove(&f0, res);
-	return;
-
-flt2:	// binary
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &f0);
-		if(nr->addable)
-			gins(foptoas(n->op, n->type, 0), nr, &f0);
-		else {
-			cgen(nr, &f0);
-			gins(foptoas(n->op, n->type, Fpop), &f0, &f1);
-		}
-	} else {
-		cgen(nr, &f0);
-		if(nl->addable)
-			gins(foptoas(n->op, n->type, Frev), nl, &f0);
-		else {
-			cgen(nl, &f0);
-			gins(foptoas(n->op, n->type, Frev|Fpop), &f0, &f1);
-		}
-	}
-	gmove(&f0, res);
-	return;
-
-}
-
-static void
-cgen_floatsse(Node *n, Node *res)
-{
-	Node *nl, *nr, *r;
-	Node n1, n2, nt;
-	int a;
-
-	nl = n->left;
-	nr = n->right;
-	switch(n->op) {
-	default:
-		dump("cgen_floatsse", n);
-		fatal("cgen_floatsse %O", n->op);
-		return;
-
-	case OMINUS:
-	case OCOM:
-		nr = nodintconst(-1);
-		convlit(&nr, n->type);
-		a = foptoas(OMUL, nl->type, 0);
-		goto sbop;
-
-	// symmetric binary
-	case OADD:
-	case OMUL:
-		a = foptoas(n->op, nl->type, 0);
-		goto sbop;
-
-	// asymmetric binary
-	case OSUB:
-	case OMOD:
-	case ODIV:
-		a = foptoas(n->op, nl->type, 0);
-		goto abop;
-	}
-
-sbop:	// symmetric binary
-	if(nl->ullman < nr->ullman || nl->op == OLITERAL) {
-		r = nl;
-		nl = nr;
-		nr = r;
-	}
-
-abop:	// asymmetric binary
-	if(nl->ullman >= nr->ullman) {
-		tempname(&nt, nl->type);
-		cgen(nl, &nt);
-		mgen(nr, &n2, N);
-		regalloc(&n1, nl->type, res);
-		gmove(&nt, &n1);
-		gins(a, &n2, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		mfree(&n2);
-	} else {
-		regalloc(&n2, nr->type, res);
-		cgen(nr, &n2);
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		gins(a, &n2, &n1);
-		regfree(&n2);
-		gmove(&n1, res);
-		regfree(&n1);
-	}
-	return;
-}
-
-void
-bgen_float(Node *n, int true, int likely, Prog *to)
-{
-	int et, a;
-	Node *nl, *nr, *r;
-	Node n1, n2, n3, tmp, t1, t2, ax;
-	Prog *p1, *p2;
-
-	nl = n->left;
-	nr = n->right;
-	a = n->op;
-	if(!true) {
-		// brcom is not valid on floats when NaN is involved.
-		p1 = gbranch(AJMP, T, 0);
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-		// No need to avoid re-genning ninit.
-		bgen_float(n, 1, -likely, p2);
-		patch(gbranch(AJMP, T, 0), to);
-		patch(p2, pc);
-		return;
-	}
-
-	if(use_sse)
-		goto sse;
-	else
-		goto x87;
-
-x87:
-	a = brrev(a);	// because the args are stacked
-	if(a == OGE || a == OGT) {
-		// only < and <= work right with NaN; reverse if needed
-		r = nr;
-		nr = nl;
-		nl = r;
-		a = brrev(a);
-	}
-
-	nodreg(&tmp, nr->type, REG_F0);
-	nodreg(&n2, nr->type, REG_F0 + 1);
-	nodreg(&ax, types[TUINT16], REG_AX);
-	et = simsimtype(nr->type);
-	if(et == TFLOAT64) {
-		if(nl->ullman > nr->ullman) {
-			cgen(nl, &tmp);
-			cgen(nr, &tmp);
-			gins(AFXCHD, &tmp, &n2);
-		} else {
-			cgen(nr, &tmp);
-			cgen(nl, &tmp);
-		}
-		gins(AFUCOMIP, &tmp, &n2);
-		gins(AFMOVDP, &tmp, &tmp);	// annoying pop but still better than STSW+SAHF
-	} else {
-		// TODO(rsc): The moves back and forth to memory
-		// here are for truncating the value to 32 bits.
-		// This handles 32-bit comparison but presumably
-		// all the other ops have the same problem.
-		// We need to figure out what the right general
-		// solution is, besides telling people to use float64.
-		tempname(&t1, types[TFLOAT32]);
-		tempname(&t2, types[TFLOAT32]);
-		cgen(nr, &t1);
-		cgen(nl, &t2);
-		gmove(&t2, &tmp);
-		gins(AFCOMFP, &t1, &tmp);
-		gins(AFSTSW, N, &ax);
-		gins(ASAHF, N, N);
-	}
-
-	goto ret;
-
-sse:
-	if(!nl->addable) {
-		tempname(&n1, nl->type);
-		cgen(nl, &n1);
-		nl = &n1;
-	}
-	if(!nr->addable) {
-		tempname(&tmp, nr->type);
-		cgen(nr, &tmp);
-		nr = &tmp;
-	}
-	regalloc(&n2, nr->type, N);
-	gmove(nr, &n2);
-	nr = &n2;
-
-	if(nl->op != OREGISTER) {
-		regalloc(&n3, nl->type, N);
-		gmove(nl, &n3);
-		nl = &n3;
-	}
-
-	if(a == OGE || a == OGT) {
-		// only < and <= work right with NaN; reverse if needed
-		r = nr;
-		nr = nl;
-		nl = r;
-		a = brrev(a);
-	}
-
-	gins(foptoas(OCMP, nr->type, 0), nl, nr);
-	if(nl->op == OREGISTER)
-		regfree(nl);
-	regfree(nr);
-
-ret:
-	if(a == OEQ) {
-		// neither NE nor P
-		p1 = gbranch(AJNE, T, -likely);
-		p2 = gbranch(AJPS, T, -likely);
-		patch(gbranch(AJMP, T, 0), to);
-		patch(p1, pc);
-		patch(p2, pc);
-	} else if(a == ONE) {
-		// either NE or P
-		patch(gbranch(AJNE, T, likely), to);
-		patch(gbranch(AJPS, T, likely), to);
-	} else
-		patch(gbranch(optoas(a, nr->type), T, likely), to);
-
-}
-
-// Called after regopt and peep have run.
-// Expand CHECKNIL pseudo-op into actual nil pointer check.
-void
-expandchecks(Prog *firstp)
-{
-	Prog *p, *p1, *p2;
-
-	for(p = firstp; p != P; p = p->link) {
-		if(p->as != ACHECKNIL)
-			continue;
-		if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
-			warnl(p->lineno, "generated nil check");
-		// check is
-		//	CMP arg, $0
-		//	JNE 2(PC) (likely)
-		//	MOV AX, 0
-		p1 = mal(sizeof *p1);
-		p2 = mal(sizeof *p2);
-		clearp(p1);
-		clearp(p2);
-		p1->link = p2;
-		p2->link = p->link;
-		p->link = p1;
-		p1->lineno = p->lineno;
-		p2->lineno = p->lineno;
-		p1->pc = 9999;
-		p2->pc = 9999;
-		p->as = ACMPL;
-		p->to.type = TYPE_CONST;
-		p->to.offset = 0;
-		p1->as = AJNE;
-		p1->from.type = TYPE_CONST;
-		p1->from.offset = 1; // likely
-		p1->to.type = TYPE_BRANCH;
-		p1->to.u.branch = p2->link;
-		// crash by write to memory address 0.
-		// if possible, since we know arg is 0, use 0(arg),
-		// which will be shorter to encode than plain 0.
-		p2->as = AMOVL;
-		p2->from.type = TYPE_REG;
-		p2->from.reg = REG_AX;
-		if(regtyp(&p->from)) {
-			p2->to.type = TYPE_MEM;
-			p2->to.reg = p->from.reg;
-		} else
-			p2->to.type = TYPE_MEM;
-		p2->to.offset = 0;
-	}
-}
diff --git a/src/cmd/new8g/ggen.go b/src/cmd/8g/ggen.go
similarity index 100%
rename from src/cmd/new8g/ggen.go
rename to src/cmd/8g/ggen.go
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c
deleted file mode 100644
index b82f762..0000000
--- a/src/cmd/8g/gsubr.c
+++ /dev/null
@@ -1,1874 +0,0 @@
-// Derived from Inferno utils/8c/txt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8c/txt.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 "gg.h"
-#include "../../runtime/funcdata.h"
-
-// TODO(rsc): Can make this bigger if we move
-// the text segment up higher in 8l for all GOOS.
-// At the same time, can raise StackBig in ../../runtime/stack.h.
-uint32 unmappedzero = 4096;
-
-#define	CASE(a,b)	(((a)<<16)|((b)<<0))
-/*c2go int CASE(int, int);*/
-
-/*
- * return Axxx for Oxxx on type t.
- */
-int
-optoas(int op, Type *t)
-{
-	int a;
-
-	if(t == T)
-		fatal("optoas: t is nil");
-
-	a = AXXX;
-	switch(CASE(op, simtype[t->etype])) {
-	default:
-		fatal("optoas: no entry %O-%T", op, t);
-		break;
-
-	case CASE(OADDR, TPTR32):
-		a = ALEAL;
-		break;
-
-	case CASE(OEQ, TBOOL):
-	case CASE(OEQ, TINT8):
-	case CASE(OEQ, TUINT8):
-	case CASE(OEQ, TINT16):
-	case CASE(OEQ, TUINT16):
-	case CASE(OEQ, TINT32):
-	case CASE(OEQ, TUINT32):
-	case CASE(OEQ, TINT64):
-	case CASE(OEQ, TUINT64):
-	case CASE(OEQ, TPTR32):
-	case CASE(OEQ, TPTR64):
-	case CASE(OEQ, TFLOAT32):
-	case CASE(OEQ, TFLOAT64):
-		a = AJEQ;
-		break;
-
-	case CASE(ONE, TBOOL):
-	case CASE(ONE, TINT8):
-	case CASE(ONE, TUINT8):
-	case CASE(ONE, TINT16):
-	case CASE(ONE, TUINT16):
-	case CASE(ONE, TINT32):
-	case CASE(ONE, TUINT32):
-	case CASE(ONE, TINT64):
-	case CASE(ONE, TUINT64):
-	case CASE(ONE, TPTR32):
-	case CASE(ONE, TPTR64):
-	case CASE(ONE, TFLOAT32):
-	case CASE(ONE, TFLOAT64):
-		a = AJNE;
-		break;
-
-	case CASE(OLT, TINT8):
-	case CASE(OLT, TINT16):
-	case CASE(OLT, TINT32):
-	case CASE(OLT, TINT64):
-		a = AJLT;
-		break;
-
-	case CASE(OLT, TUINT8):
-	case CASE(OLT, TUINT16):
-	case CASE(OLT, TUINT32):
-	case CASE(OLT, TUINT64):
-		a = AJCS;
-		break;
-
-	case CASE(OLE, TINT8):
-	case CASE(OLE, TINT16):
-	case CASE(OLE, TINT32):
-	case CASE(OLE, TINT64):
-		a = AJLE;
-		break;
-
-	case CASE(OLE, TUINT8):
-	case CASE(OLE, TUINT16):
-	case CASE(OLE, TUINT32):
-	case CASE(OLE, TUINT64):
-		a = AJLS;
-		break;
-
-	case CASE(OGT, TINT8):
-	case CASE(OGT, TINT16):
-	case CASE(OGT, TINT32):
-	case CASE(OGT, TINT64):
-		a = AJGT;
-		break;
-
-	case CASE(OGT, TUINT8):
-	case CASE(OGT, TUINT16):
-	case CASE(OGT, TUINT32):
-	case CASE(OGT, TUINT64):
-	case CASE(OLT, TFLOAT32):
-	case CASE(OLT, TFLOAT64):
-		a = AJHI;
-		break;
-
-	case CASE(OGE, TINT8):
-	case CASE(OGE, TINT16):
-	case CASE(OGE, TINT32):
-	case CASE(OGE, TINT64):
-		a = AJGE;
-		break;
-
-	case CASE(OGE, TUINT8):
-	case CASE(OGE, TUINT16):
-	case CASE(OGE, TUINT32):
-	case CASE(OGE, TUINT64):
-	case CASE(OLE, TFLOAT32):
-	case CASE(OLE, TFLOAT64):
-		a = AJCC;
-		break;
-
-	case CASE(OCMP, TBOOL):
-	case CASE(OCMP, TINT8):
-	case CASE(OCMP, TUINT8):
-		a = ACMPB;
-		break;
-
-	case CASE(OCMP, TINT16):
-	case CASE(OCMP, TUINT16):
-		a = ACMPW;
-		break;
-
-	case CASE(OCMP, TINT32):
-	case CASE(OCMP, TUINT32):
-	case CASE(OCMP, TPTR32):
-		a = ACMPL;
-		break;
-
-	case CASE(OAS, TBOOL):
-	case CASE(OAS, TINT8):
-	case CASE(OAS, TUINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(OAS, TINT16):
-	case CASE(OAS, TUINT16):
-		a = AMOVW;
-		break;
-
-	case CASE(OAS, TINT32):
-	case CASE(OAS, TUINT32):
-	case CASE(OAS, TPTR32):
-		a = AMOVL;
-		break;
-	
-	case CASE(OAS, TFLOAT32):
-		a = AMOVSS;
-		break;
-	
-	case CASE(OAS, TFLOAT64):
-		a = AMOVSD;
-		break;
-
-	case CASE(OADD, TINT8):
-	case CASE(OADD, TUINT8):
-		a = AADDB;
-		break;
-
-	case CASE(OADD, TINT16):
-	case CASE(OADD, TUINT16):
-		a = AADDW;
-		break;
-
-	case CASE(OADD, TINT32):
-	case CASE(OADD, TUINT32):
-	case CASE(OADD, TPTR32):
-		a = AADDL;
-		break;
-
-	case CASE(OSUB, TINT8):
-	case CASE(OSUB, TUINT8):
-		a = ASUBB;
-		break;
-
-	case CASE(OSUB, TINT16):
-	case CASE(OSUB, TUINT16):
-		a = ASUBW;
-		break;
-
-	case CASE(OSUB, TINT32):
-	case CASE(OSUB, TUINT32):
-	case CASE(OSUB, TPTR32):
-		a = ASUBL;
-		break;
-
-	case CASE(OINC, TINT8):
-	case CASE(OINC, TUINT8):
-		a = AINCB;
-		break;
-
-	case CASE(OINC, TINT16):
-	case CASE(OINC, TUINT16):
-		a = AINCW;
-		break;
-
-	case CASE(OINC, TINT32):
-	case CASE(OINC, TUINT32):
-	case CASE(OINC, TPTR32):
-		a = AINCL;
-		break;
-
-	case CASE(ODEC, TINT8):
-	case CASE(ODEC, TUINT8):
-		a = ADECB;
-		break;
-
-	case CASE(ODEC, TINT16):
-	case CASE(ODEC, TUINT16):
-		a = ADECW;
-		break;
-
-	case CASE(ODEC, TINT32):
-	case CASE(ODEC, TUINT32):
-	case CASE(ODEC, TPTR32):
-		a = ADECL;
-		break;
-
-	case CASE(OCOM, TINT8):
-	case CASE(OCOM, TUINT8):
-		a = ANOTB;
-		break;
-
-	case CASE(OCOM, TINT16):
-	case CASE(OCOM, TUINT16):
-		a = ANOTW;
-		break;
-
-	case CASE(OCOM, TINT32):
-	case CASE(OCOM, TUINT32):
-	case CASE(OCOM, TPTR32):
-		a = ANOTL;
-		break;
-
-	case CASE(OMINUS, TINT8):
-	case CASE(OMINUS, TUINT8):
-		a = ANEGB;
-		break;
-
-	case CASE(OMINUS, TINT16):
-	case CASE(OMINUS, TUINT16):
-		a = ANEGW;
-		break;
-
-	case CASE(OMINUS, TINT32):
-	case CASE(OMINUS, TUINT32):
-	case CASE(OMINUS, TPTR32):
-		a = ANEGL;
-		break;
-
-	case CASE(OAND, TINT8):
-	case CASE(OAND, TUINT8):
-		a = AANDB;
-		break;
-
-	case CASE(OAND, TINT16):
-	case CASE(OAND, TUINT16):
-		a = AANDW;
-		break;
-
-	case CASE(OAND, TINT32):
-	case CASE(OAND, TUINT32):
-	case CASE(OAND, TPTR32):
-		a = AANDL;
-		break;
-
-	case CASE(OOR, TINT8):
-	case CASE(OOR, TUINT8):
-		a = AORB;
-		break;
-
-	case CASE(OOR, TINT16):
-	case CASE(OOR, TUINT16):
-		a = AORW;
-		break;
-
-	case CASE(OOR, TINT32):
-	case CASE(OOR, TUINT32):
-	case CASE(OOR, TPTR32):
-		a = AORL;
-		break;
-
-	case CASE(OXOR, TINT8):
-	case CASE(OXOR, TUINT8):
-		a = AXORB;
-		break;
-
-	case CASE(OXOR, TINT16):
-	case CASE(OXOR, TUINT16):
-		a = AXORW;
-		break;
-
-	case CASE(OXOR, TINT32):
-	case CASE(OXOR, TUINT32):
-	case CASE(OXOR, TPTR32):
-		a = AXORL;
-		break;
-
-	case CASE(OLROT, TINT8):
-	case CASE(OLROT, TUINT8):
-		a = AROLB;
-		break;
-
-	case CASE(OLROT, TINT16):
-	case CASE(OLROT, TUINT16):
-		a = AROLW;
-		break;
-
-	case CASE(OLROT, TINT32):
-	case CASE(OLROT, TUINT32):
-	case CASE(OLROT, TPTR32):
-		a = AROLL;
-		break;
-
-	case CASE(OLSH, TINT8):
-	case CASE(OLSH, TUINT8):
-		a = ASHLB;
-		break;
-
-	case CASE(OLSH, TINT16):
-	case CASE(OLSH, TUINT16):
-		a = ASHLW;
-		break;
-
-	case CASE(OLSH, TINT32):
-	case CASE(OLSH, TUINT32):
-	case CASE(OLSH, TPTR32):
-		a = ASHLL;
-		break;
-
-	case CASE(ORSH, TUINT8):
-		a = ASHRB;
-		break;
-
-	case CASE(ORSH, TUINT16):
-		a = ASHRW;
-		break;
-
-	case CASE(ORSH, TUINT32):
-	case CASE(ORSH, TPTR32):
-		a = ASHRL;
-		break;
-
-	case CASE(ORSH, TINT8):
-		a = ASARB;
-		break;
-
-	case CASE(ORSH, TINT16):
-		a = ASARW;
-		break;
-
-	case CASE(ORSH, TINT32):
-		a = ASARL;
-		break;
-
-	case CASE(OHMUL, TINT8):
-	case CASE(OMUL, TINT8):
-	case CASE(OMUL, TUINT8):
-		a = AIMULB;
-		break;
-
-	case CASE(OHMUL, TINT16):
-	case CASE(OMUL, TINT16):
-	case CASE(OMUL, TUINT16):
-		a = AIMULW;
-		break;
-
-	case CASE(OHMUL, TINT32):
-	case CASE(OMUL, TINT32):
-	case CASE(OMUL, TUINT32):
-	case CASE(OMUL, TPTR32):
-		a = AIMULL;
-		break;
-
-	case CASE(OHMUL, TUINT8):
-		a = AMULB;
-		break;
-
-	case CASE(OHMUL, TUINT16):
-		a = AMULW;
-		break;
-
-	case CASE(OHMUL, TUINT32):
-	case CASE(OHMUL, TPTR32):
-		a = AMULL;
-		break;
-
-	case CASE(ODIV, TINT8):
-	case CASE(OMOD, TINT8):
-		a = AIDIVB;
-		break;
-
-	case CASE(ODIV, TUINT8):
-	case CASE(OMOD, TUINT8):
-		a = ADIVB;
-		break;
-
-	case CASE(ODIV, TINT16):
-	case CASE(OMOD, TINT16):
-		a = AIDIVW;
-		break;
-
-	case CASE(ODIV, TUINT16):
-	case CASE(OMOD, TUINT16):
-		a = ADIVW;
-		break;
-
-	case CASE(ODIV, TINT32):
-	case CASE(OMOD, TINT32):
-		a = AIDIVL;
-		break;
-
-	case CASE(ODIV, TUINT32):
-	case CASE(ODIV, TPTR32):
-	case CASE(OMOD, TUINT32):
-	case CASE(OMOD, TPTR32):
-		a = ADIVL;
-		break;
-
-	case CASE(OEXTEND, TINT16):
-		a = ACWD;
-		break;
-
-	case CASE(OEXTEND, TINT32):
-		a = ACDQ;
-		break;
-	}
-	return a;
-}
-
-#define FCASE(a, b, c)  (((a)<<16)|((b)<<8)|(c))
-/*c2go int FCASE(int, int, int); */
-int
-foptoas(int op, Type *t, int flg)
-{
-	int et, a;
-
-	a = AXXX;
-	et = simtype[t->etype];
-
-	if(use_sse)
-		goto sse;
-
-	// If we need Fpop, it means we're working on
-	// two different floating-point registers, not memory.
-	// There the instruction only has a float64 form.
-	if(flg & Fpop)
-		et = TFLOAT64;
-
-	// clear Frev if unneeded
-	switch(op) {
-	case OADD:
-	case OMUL:
-		flg &= ~Frev;
-		break;
-	}
-
-	switch(FCASE(op, et, flg)) {
-	case FCASE(OADD, TFLOAT32, 0):
-		return AFADDF;
-	case FCASE(OADD, TFLOAT64, 0):
-		return AFADDD;
-	case FCASE(OADD, TFLOAT64, Fpop):
-		return AFADDDP;
-
-	case FCASE(OSUB, TFLOAT32, 0):
-		return AFSUBF;
-	case FCASE(OSUB, TFLOAT32, Frev):
-		return AFSUBRF;
-
-	case FCASE(OSUB, TFLOAT64, 0):
-		return AFSUBD;
-	case FCASE(OSUB, TFLOAT64, Frev):
-		return AFSUBRD;
-	case FCASE(OSUB, TFLOAT64, Fpop):
-		return AFSUBDP;
-	case FCASE(OSUB, TFLOAT64, Fpop|Frev):
-		return AFSUBRDP;
-
-	case FCASE(OMUL, TFLOAT32, 0):
-		return AFMULF;
-	case FCASE(OMUL, TFLOAT64, 0):
-		return AFMULD;
-	case FCASE(OMUL, TFLOAT64, Fpop):
-		return AFMULDP;
-
-	case FCASE(ODIV, TFLOAT32, 0):
-		return AFDIVF;
-	case FCASE(ODIV, TFLOAT32, Frev):
-		return AFDIVRF;
-
-	case FCASE(ODIV, TFLOAT64, 0):
-		return AFDIVD;
-	case FCASE(ODIV, TFLOAT64, Frev):
-		return AFDIVRD;
-	case FCASE(ODIV, TFLOAT64, Fpop):
-		return AFDIVDP;
-	case FCASE(ODIV, TFLOAT64, Fpop|Frev):
-		return AFDIVRDP;
-
-	case FCASE(OCMP, TFLOAT32, 0):
-		return AFCOMF;
-	case FCASE(OCMP, TFLOAT32, Fpop):
-		return AFCOMFP;
-	case FCASE(OCMP, TFLOAT64, 0):
-		return AFCOMD;
-	case FCASE(OCMP, TFLOAT64, Fpop):
-		return AFCOMDP;
-	case FCASE(OCMP, TFLOAT64, Fpop2):
-		return AFCOMDPP;
-	
-	case FCASE(OMINUS, TFLOAT32, 0):
-		return AFCHS;
-	case FCASE(OMINUS, TFLOAT64, 0):
-		return AFCHS;
-	}
-
-	fatal("foptoas %O %T %#x", op, t, flg);
-	return 0;
-
-sse:
-	switch(CASE(op, et)) {
-	default:
-		fatal("foptoas-sse: no entry %O-%T", op, t);
-		break;
-
-	case CASE(OCMP, TFLOAT32):
-		a = AUCOMISS;
-		break;
-
-	case CASE(OCMP, TFLOAT64):
-		a = AUCOMISD;
-		break;
-
-	case CASE(OAS, TFLOAT32):
-		a = AMOVSS;
-		break;
-
-	case CASE(OAS, TFLOAT64):
-		a = AMOVSD;
-		break;
-
-	case CASE(OADD, TFLOAT32):
-		a = AADDSS;
-		break;
-
-	case CASE(OADD, TFLOAT64):
-		a = AADDSD;
-		break;
-
-	case CASE(OSUB, TFLOAT32):
-		a = ASUBSS;
-		break;
-
-	case CASE(OSUB, TFLOAT64):
-		a = ASUBSD;
-		break;
-
-	case CASE(OMUL, TFLOAT32):
-		a = AMULSS;
-		break;
-
-	case CASE(OMUL, TFLOAT64):
-		a = AMULSD;
-		break;
-
-	case CASE(ODIV, TFLOAT32):
-		a = ADIVSS;
-		break;
-
-	case CASE(ODIV, TFLOAT64):
-		a = ADIVSD;
-		break;
-	}
-	return a;
-}
-
-
-static	int	resvd[] =
-{
-//	REG_DI,	// for movstring
-//	REG_SI,	// for movstring
-
-	REG_AX,	// for divide
-	REG_CX,	// for shift
-	REG_DX,	// for divide
-	REG_SP,	// for stack
-
-	REG_BL,	// because REG_BX can be allocated
-	REG_BH,
-};
-
-void
-ginit(void)
-{
-	int i;
-
-	for(i=0; i<nelem(reg); i++)
-		reg[i] = 1;
-	for(i=REG_AX; i<=REG_DI; i++)
-		reg[i] = 0;
-	for(i=REG_X0; i<=REG_X7; i++)
-		reg[i] = 0;
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]++;
-}
-
-uintptr regpc[MAXREG];
-
-void
-gclean(void)
-{
-	int i;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i]]--;
-
-	for(i=REG_AX; i<=REG_DI; i++)
-		if(reg[i])
-			yyerror("reg %R left allocated at %ux", i, regpc[i]);
-	for(i=REG_X0; i<=REG_X7; i++)
-		if(reg[i])
-			yyerror("reg %R left allocated\n", i);
-}
-
-int
-anyregalloc(void)
-{
-	int i, j;
-
-	for(i=REG_AX; i<=REG_DI; i++) {
-		if(reg[i] == 0)
-			goto ok;
-		for(j=0; j<nelem(resvd); j++)
-			if(resvd[j] == i)
-				goto ok;
-		return 1;
-	ok:;
-	}
-	for(i=REG_X0; i<=REG_X7; i++)
-		if(reg[i])
-			return 1;
-	return 0;
-}
-
-/*
- * allocate register of type t, leave in n.
- * if o != N, o is desired fixed register.
- * caller must regfree(n).
- */
-void
-regalloc(Node *n, Type *t, Node *o)
-{
-	int i, et;
-
-	if(t == T)
-		fatal("regalloc: t nil");
-	et = simtype[t->etype];
-
-	switch(et) {
-	case TINT64:
-	case TUINT64:
-		fatal("regalloc64");
-
-	case TINT8:
-	case TUINT8:
-	case TINT16:
-	case TUINT16:
-	case TINT32:
-	case TUINT32:
-	case TPTR32:
-	case TPTR64:
-	case TBOOL:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REG_AX && i <= REG_DI)
-				goto out;
-		}
-		for(i=REG_AX; i<=REG_DI; i++)
-			if(reg[i] == 0)
-				goto out;
-
-		print("registers allocated at\n");
-		for(i=REG_AX; i<=REG_DI; i++)
-			print("\t%R\t%#lux\n", i, regpc[i]);
-		fatal("out of fixed registers");
-		goto err;
-
-	case TFLOAT32:
-	case TFLOAT64:
-		if(!use_sse) {
-			i = REG_F0;
-			goto out;
-		}
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REG_X0 && i <= REG_X7)
-				goto out;
-		}
-		for(i=REG_X0; i<=REG_X7; i++)
-			if(reg[i] == 0)
-				goto out;
-		print("registers allocated at\n");
-		for(i=REG_X0; i<=REG_X7; i++)
-			print("\t%R\t%#lux\n", i, regpc[i]);
-		fatal("out of floating registers");
-	}
-	yyerror("regalloc: unknown type %T", t);
-
-err:
-	nodreg(n, t, 0);
-	return;
-
-out:
-	if(i == REG_SP)
-		print("alloc SP\n");
-	if(reg[i] == 0) {
-		regpc[i] = (uintptr)getcallerpc(&n);
-		if(i == REG_AX || i == REG_CX || i == REG_DX || i == REG_SP) {
-			dump("regalloc-o", o);
-			fatal("regalloc %R", i);
-		}
-	}
-	reg[i]++;
-	nodreg(n, t, i);
-}
-
-void
-regfree(Node *n)
-{
-	int i;
-	
-	if(n->op == ONAME)
-		return;
-	if(n->op != OREGISTER && n->op != OINDREG)
-		fatal("regfree: not a register");
-	i = n->val.u.reg;
-	if(i == REG_SP)
-		return;
-	if(i < 0 || i >= nelem(reg))
-		fatal("regfree: reg out of range");
-	if(reg[i] <= 0)
-		fatal("regfree: reg not allocated");
-	reg[i]--;
-	if(reg[i] == 0 && (i == REG_AX || i == REG_CX || i == REG_DX || i == REG_SP))
-		fatal("regfree %R", i);
-}
-
-/*
- * generate
- *	as $c, reg
- */
-void
-gconreg(int as, vlong c, int reg)
-{
-	Node n1, n2;
-
-	nodconst(&n1, types[TINT64], c);
-	nodreg(&n2, types[TINT64], reg);
-	gins(as, &n1, &n2);
-}
-
-/*
- * swap node contents
- */
-void
-nswap(Node *a, Node *b)
-{
-	Node t;
-
-	t = *a;
-	*a = *b;
-	*b = t;
-}
-
-/*
- * return constant i node.
- * overwritten by next call, but useful in calls to gins.
- */
-Node*
-ncon(uint32 i)
-{
-	static Node n;
-
-	if(n.type == T)
-		nodconst(&n, types[TUINT32], 0);
-	mpmovecfix(n.val.u.xval, i);
-	return &n;
-}
-
-Node sclean[10];
-int nsclean;
-
-/*
- * n is a 64-bit value.  fill in lo and hi to refer to its 32-bit halves.
- */
-void
-split64(Node *n, Node *lo, Node *hi)
-{
-	Node n1;
-	int64 i;
-
-	if(!is64(n->type))
-		fatal("split64 %T", n->type);
-
-	if(nsclean >= nelem(sclean))
-		fatal("split64 clean");
-	sclean[nsclean].op = OEMPTY;
-	nsclean++;
-	switch(n->op) {
-	default:
-		switch(n->op) {
-		default:
-			if(!dotaddable(n, &n1)) {
-				igen(n, &n1, N);
-				sclean[nsclean-1] = n1;
-			}
-			n = &n1;
-			break;
-		case ONAME:
-			if(n->class == PPARAMREF) {
-				cgen(n->heapaddr, &n1);
-				sclean[nsclean-1] = n1;
-				n = &n1;
-			}
-			break;
-		case OINDREG:
-			// nothing
-			break;
-		}
-		*lo = *n;
-		*hi = *n;
-		lo->type = types[TUINT32];
-		if(n->type->etype == TINT64)
-			hi->type = types[TINT32];
-		else
-			hi->type = types[TUINT32];
-		hi->xoffset += 4;
-		break;
-
-	case OLITERAL:
-		convconst(&n1, n->type, &n->val);
-		i = mpgetfix(n1.val.u.xval);
-		nodconst(lo, types[TUINT32], (uint32)i);
-		i >>= 32;
-		if(n->type->etype == TINT64)
-			nodconst(hi, types[TINT32], (int32)i);
-		else
-			nodconst(hi, types[TUINT32], (uint32)i);
-		break;
-	}
-}
-
-void
-splitclean(void)
-{
-	if(nsclean <= 0)
-		fatal("splitclean");
-	nsclean--;
-	if(sclean[nsclean].op != OEMPTY)
-		regfree(&sclean[nsclean]);
-}
-
-/*
- * set up nodes representing fp constants
- */
-Node zerof;
-Node two64f;
-Node two63f;
-
-void
-bignodes(void)
-{
-	static int did;
-
-	if(did)
-		return;
-	did = 1;
-
-	two64f = *ncon(0);
-	two64f.type = types[TFLOAT64];
-	two64f.val.ctype = CTFLT;
-	two64f.val.u.fval = mal(sizeof *two64f.val.u.fval);
-	mpmovecflt(two64f.val.u.fval, 18446744073709551616.);
-
-	two63f = two64f;
-	two63f.val.u.fval = mal(sizeof *two63f.val.u.fval);
-	mpmovecflt(two63f.val.u.fval, 9223372036854775808.);
-
-	zerof = two64f;
-	zerof.val.u.fval = mal(sizeof *zerof.val.u.fval);
-	mpmovecflt(zerof.val.u.fval, 0);
-}
-
-void
-memname(Node *n, Type *t)
-{
-	tempname(n, t);
-	strcpy(namebuf, n->sym->name);
-	namebuf[0] = '.';	// keep optimizer from registerizing
-	n->sym = lookup(namebuf);
-	n->orig->sym = n->sym;
-}
-
-static void floatmove(Node *f, Node *t);
-static void floatmove_387(Node *f, Node *t);
-static void floatmove_sse(Node *f, Node *t);
-
-void
-gmove(Node *f, Node *t)
-{
-	int a, ft, tt;
-	Type *cvt;
-	Node r1, r2, flo, fhi, tlo, thi, con;
-
-	if(debug['M'])
-		print("gmove %N -> %N\n", f, t);
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-	
-	if(iscomplex[ft] || iscomplex[tt]) {
-		complexmove(f, t);
-		return;
-	}
-	if(isfloat[ft] || isfloat[tt]) {
-		floatmove(f, t);
-		return;
-	}
-
-	// cannot have two integer memory operands;
-	// except 64-bit, which always copies via registers anyway.
-	if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
-		goto hard;
-
-	// convert constant to desired type
-	if(f->op == OLITERAL) {
-		convconst(&con, t->type, &f->val);
-		f = &con;
-		ft = simsimtype(con.type);
-	}
-
-	// value -> value copy, only one memory operand.
-	// figure out the instruction to use.
-	// break out of switch for one-instruction gins.
-	// goto rdst for "destination must be register".
-	// goto hard for "convert to cvt type first".
-	// otherwise handle and return.
-
-	switch(CASE(ft, tt)) {
-	default:
-		goto fatal;
-
-	/*
-	 * integer copy and truncate
-	 */
-	case CASE(TINT8, TINT8):	// same size
-	case CASE(TINT8, TUINT8):
-	case CASE(TUINT8, TINT8):
-	case CASE(TUINT8, TUINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(TINT16, TINT8):	// truncate
-	case CASE(TUINT16, TINT8):
-	case CASE(TINT32, TINT8):
-	case CASE(TUINT32, TINT8):
-	case CASE(TINT16, TUINT8):
-	case CASE(TUINT16, TUINT8):
-	case CASE(TINT32, TUINT8):
-	case CASE(TUINT32, TUINT8):
-		a = AMOVB;
-		goto rsrc;
-
-	case CASE(TINT64, TINT8):	// truncate low word
-	case CASE(TUINT64, TINT8):
-	case CASE(TINT64, TUINT8):
-	case CASE(TUINT64, TUINT8):
-		split64(f, &flo, &fhi);
-		nodreg(&r1, t->type, REG_AX);
-		gmove(&flo, &r1);
-		gins(AMOVB, &r1, t);
-		splitclean();
-		return;
-
-	case CASE(TINT16, TINT16):	// same size
-	case CASE(TINT16, TUINT16):
-	case CASE(TUINT16, TINT16):
-	case CASE(TUINT16, TUINT16):
-		a = AMOVW;
-		break;
-
-	case CASE(TINT32, TINT16):	// truncate
-	case CASE(TUINT32, TINT16):
-	case CASE(TINT32, TUINT16):
-	case CASE(TUINT32, TUINT16):
-		a = AMOVW;
-		goto rsrc;
-
-	case CASE(TINT64, TINT16):	// truncate low word
-	case CASE(TUINT64, TINT16):
-	case CASE(TINT64, TUINT16):
-	case CASE(TUINT64, TUINT16):
-		split64(f, &flo, &fhi);
-		nodreg(&r1, t->type, REG_AX);
-		gmove(&flo, &r1);
-		gins(AMOVW, &r1, t);
-		splitclean();
-		return;
-
-	case CASE(TINT32, TINT32):	// same size
-	case CASE(TINT32, TUINT32):
-	case CASE(TUINT32, TINT32):
-	case CASE(TUINT32, TUINT32):
-		a = AMOVL;
-		break;
-
-	case CASE(TINT64, TINT32):	// truncate
-	case CASE(TUINT64, TINT32):
-	case CASE(TINT64, TUINT32):
-	case CASE(TUINT64, TUINT32):
-		split64(f, &flo, &fhi);
-		nodreg(&r1, t->type, REG_AX);
-		gmove(&flo, &r1);
-		gins(AMOVL, &r1, t);
-		splitclean();
-		return;
-
-	case CASE(TINT64, TINT64):	// same size
-	case CASE(TINT64, TUINT64):
-	case CASE(TUINT64, TINT64):
-	case CASE(TUINT64, TUINT64):
-		split64(f, &flo, &fhi);
-		split64(t, &tlo, &thi);
-		if(f->op == OLITERAL) {
-			gins(AMOVL, &flo, &tlo);
-			gins(AMOVL, &fhi, &thi);
-		} else {
-			nodreg(&r1, types[TUINT32], REG_AX);
-			nodreg(&r2, types[TUINT32], REG_DX);
-			gins(AMOVL, &flo, &r1);
-			gins(AMOVL, &fhi, &r2);
-			gins(AMOVL, &r1, &tlo);
-			gins(AMOVL, &r2, &thi);
-		}
-		splitclean();
-		splitclean();
-		return;
-
-	/*
-	 * integer up-conversions
-	 */
-	case CASE(TINT8, TINT16):	// sign extend int8
-	case CASE(TINT8, TUINT16):
-		a = AMOVBWSX;
-		goto rdst;
-	case CASE(TINT8, TINT32):
-	case CASE(TINT8, TUINT32):
-		a = AMOVBLSX;
-		goto rdst;
-	case CASE(TINT8, TINT64):	// convert via int32
-	case CASE(TINT8, TUINT64):
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT8, TINT16):	// zero extend uint8
-	case CASE(TUINT8, TUINT16):
-		a = AMOVBWZX;
-		goto rdst;
-	case CASE(TUINT8, TINT32):
-	case CASE(TUINT8, TUINT32):
-		a = AMOVBLZX;
-		goto rdst;
-	case CASE(TUINT8, TINT64):	// convert via uint32
-	case CASE(TUINT8, TUINT64):
-		cvt = types[TUINT32];
-		goto hard;
-
-	case CASE(TINT16, TINT32):	// sign extend int16
-	case CASE(TINT16, TUINT32):
-		a = AMOVWLSX;
-		goto rdst;
-	case CASE(TINT16, TINT64):	// convert via int32
-	case CASE(TINT16, TUINT64):
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT16, TINT32):	// zero extend uint16
-	case CASE(TUINT16, TUINT32):
-		a = AMOVWLZX;
-		goto rdst;
-	case CASE(TUINT16, TINT64):	// convert via uint32
-	case CASE(TUINT16, TUINT64):
-		cvt = types[TUINT32];
-		goto hard;
-
-	case CASE(TINT32, TINT64):	// sign extend int32
-	case CASE(TINT32, TUINT64):
-		split64(t, &tlo, &thi);
-		nodreg(&flo, tlo.type, REG_AX);
-		nodreg(&fhi, thi.type, REG_DX);
-		gmove(f, &flo);
-		gins(ACDQ, N, N);
-		gins(AMOVL, &flo, &tlo);
-		gins(AMOVL, &fhi, &thi);
-		splitclean();
-		return;
-
-	case CASE(TUINT32, TINT64):	// zero extend uint32
-	case CASE(TUINT32, TUINT64):
-		split64(t, &tlo, &thi);
-		gmove(f, &tlo);
-		gins(AMOVL, ncon(0), &thi);
-		splitclean();
-		return;
-	}
-
-	gins(a, f, t);
-	return;
-
-rsrc:
-	// requires register source
-	regalloc(&r1, f->type, t);
-	gmove(f, &r1);
-	gins(a, &r1, t);
-	regfree(&r1);
-	return;
-
-rdst:
-	// requires register destination
-	regalloc(&r1, t->type, t);
-	gins(a, f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-fatal:
-	// should not happen
-	fatal("gmove %N -> %N", f, t);
-}
-
-static void
-floatmove(Node *f, Node *t)
-{
-	Node r1, r2, t1, t2, tlo, thi, con, f0, f1, ax, dx, cx;
-	Type *cvt;
-	int ft, tt;
-	Prog *p1, *p2, *p3;
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-
-	// cannot have two floating point memory operands.
-	if(isfloat[ft] && isfloat[tt] && ismem(f) && ismem(t))
-		goto hard;
-
-	// convert constant to desired type
-	if(f->op == OLITERAL) {
-		convconst(&con, t->type, &f->val);
-		f = &con;
-		ft = simsimtype(con.type);
-
-		// some constants can't move directly to memory.
-		if(ismem(t)) {
-			// float constants come from memory.
-			if(isfloat[tt])
-				goto hard;
-		}
-	}
-
-	// value -> value copy, only one memory operand.
-	// figure out the instruction to use.
-	// break out of switch for one-instruction gins.
-	// goto rdst for "destination must be register".
-	// goto hard for "convert to cvt type first".
-	// otherwise handle and return.
-
-	switch(CASE(ft, tt)) {
-	default:
-		if(use_sse)
-			floatmove_sse(f, t);
-		else
-			floatmove_387(f, t);
-		return;
-
-	// float to very long integer.
-	case CASE(TFLOAT32, TINT64):
-	case CASE(TFLOAT64, TINT64):
-		if(f->op == OREGISTER) {
-			cvt = f->type;
-			goto hardmem;
-		}
-		nodreg(&r1, types[ft], REG_F0);
-		if(ft == TFLOAT32)
-			gins(AFMOVF, f, &r1);
-		else
-			gins(AFMOVD, f, &r1);
-
-		// set round to zero mode during conversion
-		memname(&t1, types[TUINT16]);
-		memname(&t2, types[TUINT16]);
-		gins(AFSTCW, N, &t1);
-		gins(AMOVW, ncon(0xf7f), &t2);
-		gins(AFLDCW, &t2, N);
-		if(tt == TINT16)
-			gins(AFMOVWP, &r1, t);
-		else if(tt == TINT32)
-			gins(AFMOVLP, &r1, t);
-		else
-			gins(AFMOVVP, &r1, t);
-		gins(AFLDCW, &t1, N);
-		return;
-
-	case CASE(TFLOAT32, TUINT64):
-	case CASE(TFLOAT64, TUINT64):
-		if(!ismem(f)) {
-			cvt = f->type;
-			goto hardmem;
-		}
-		bignodes();
-		nodreg(&f0, types[ft], REG_F0);
-		nodreg(&f1, types[ft], REG_F0 + 1);
-		nodreg(&ax, types[TUINT16], REG_AX);
-
-		if(ft == TFLOAT32)
-			gins(AFMOVF, f, &f0);
-		else
-			gins(AFMOVD, f, &f0);
-
-		// if 0 > v { answer = 0 }
-		gins(AFMOVD, &zerof, &f0);
-		gins(AFUCOMIP, &f0, &f1);
-		p1 = gbranch(optoas(OGT, types[tt]), T, 0);
-		// if 1<<64 <= v { answer = 0 too }
-		gins(AFMOVD, &two64f, &f0);
-		gins(AFUCOMIP, &f0, &f1);
-		p2 = gbranch(optoas(OGT, types[tt]), T, 0);
-		patch(p1, pc);
-		gins(AFMOVVP, &f0, t);	// don't care about t, but will pop the stack
-		split64(t, &tlo, &thi);
-		gins(AMOVL, ncon(0), &tlo);
-		gins(AMOVL, ncon(0), &thi);
-		splitclean();
-		p1 = gbranch(AJMP, T, 0);
-		patch(p2, pc);
-
-		// in range; algorithm is:
-		//	if small enough, use native float64 -> int64 conversion.
-		//	otherwise, subtract 2^63, convert, and add it back.
-
-		// set round to zero mode during conversion
-		memname(&t1, types[TUINT16]);
-		memname(&t2, types[TUINT16]);
-		gins(AFSTCW, N, &t1);
-		gins(AMOVW, ncon(0xf7f), &t2);
-		gins(AFLDCW, &t2, N);
-
-		// actual work
-		gins(AFMOVD, &two63f, &f0);
-		gins(AFUCOMIP, &f0, &f1);
-		p2 = gbranch(optoas(OLE, types[tt]), T, 0);
-		gins(AFMOVVP, &f0, t);
-		p3 = gbranch(AJMP, T, 0);
-		patch(p2, pc);
-		gins(AFMOVD, &two63f, &f0);
-		gins(AFSUBDP, &f0, &f1);
-		gins(AFMOVVP, &f0, t);
-		split64(t, &tlo, &thi);
-		gins(AXORL, ncon(0x80000000), &thi);	// + 2^63
-		patch(p3, pc);
-		splitclean();
-		// restore rounding mode
-		gins(AFLDCW, &t1, N);
-
-		patch(p1, pc);
-		return;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT64, TFLOAT32):
-	case CASE(TINT64, TFLOAT64):
-		if(t->op == OREGISTER)
-			goto hardmem;
-		nodreg(&f0, t->type, REG_F0);
-		gins(AFMOVV, f, &f0);
-		if(tt == TFLOAT32)
-			gins(AFMOVFP, &f0, t);
-		else
-			gins(AFMOVDP, &f0, t);
-		return;
-
-	case CASE(TUINT64, TFLOAT32):
-	case CASE(TUINT64, TFLOAT64):
-		// algorithm is:
-		//	if small enough, use native int64 -> float64 conversion.
-		//	otherwise, halve (rounding to odd?), convert, and double.
-		nodreg(&ax, types[TUINT32], REG_AX);
-		nodreg(&dx, types[TUINT32], REG_DX);
-		nodreg(&cx, types[TUINT32], REG_CX);
-		tempname(&t1, f->type);
-		split64(&t1, &tlo, &thi);
-		gmove(f, &t1);
-		gins(ACMPL, &thi, ncon(0));
-		p1 = gbranch(AJLT, T, 0);
-		// native
-		nodreg(&r1, types[tt], REG_F0);
-		gins(AFMOVV, &t1, &r1);
-		if(tt == TFLOAT32)
-			gins(AFMOVFP, &r1, t);
-		else
-			gins(AFMOVDP, &r1, t);
-		p2 = gbranch(AJMP, T, 0);
-		// simulated
-		patch(p1, pc);
-		gmove(&tlo, &ax);
-		gmove(&thi, &dx);
-		p1 = gins(ASHRL, ncon(1), &ax);
-		p1->from.index = REG_DX;	// double-width shift DX -> AX
-		p1->from.scale = 0;
-		gins(AMOVL, ncon(0), &cx);
-		gins(ASETCC, N, &cx);
-		gins(AORL, &cx, &ax);
-		gins(ASHRL, ncon(1), &dx);
-		gmove(&dx, &thi);
-		gmove(&ax, &tlo);
-		nodreg(&r1, types[tt], REG_F0);
-		nodreg(&r2, types[tt], REG_F0 + 1);
-		gins(AFMOVV, &t1, &r1);
-		gins(AFMOVD, &r1, &r1);
-		gins(AFADDDP, &r1, &r2);
-		if(tt == TFLOAT32)
-			gins(AFMOVFP, &r1, t);
-		else
-			gins(AFMOVDP, &r1, t);
-		patch(p2, pc);
-		splitclean();
-		return;
-	}
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hardmem:
-	// requires memory intermediate
-	tempname(&r1, cvt);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	return;
-}
-
-static void
-floatmove_387(Node *f, Node *t)
-{
-	Node r1, t1, t2;
-	Type *cvt;
-	Prog *p1, *p2, *p3;
-	int a, ft, tt;
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-
-	switch(CASE(ft, tt)) {
-	default:
-		goto fatal;
-
-	/*
-	* float to integer
-	*/
-	case CASE(TFLOAT32, TINT16):
-	case CASE(TFLOAT32, TINT32):
-	case CASE(TFLOAT32, TINT64):
-	case CASE(TFLOAT64, TINT16):
-	case CASE(TFLOAT64, TINT32):
-	case CASE(TFLOAT64, TINT64):
-		if(t->op == OREGISTER)
-			goto hardmem;
-		nodreg(&r1, types[ft], REG_F0);
-		if(f->op != OREGISTER) {
-			if(ft == TFLOAT32)
-				gins(AFMOVF, f, &r1);
-			else
-				gins(AFMOVD, f, &r1);
-		}
-
-		// set round to zero mode during conversion
-		memname(&t1, types[TUINT16]);
-		memname(&t2, types[TUINT16]);
-		gins(AFSTCW, N, &t1);
-		gins(AMOVW, ncon(0xf7f), &t2);
-		gins(AFLDCW, &t2, N);
-		if(tt == TINT16)
-			gins(AFMOVWP, &r1, t);
-		else if(tt == TINT32)
-			gins(AFMOVLP, &r1, t);
-		else
-			gins(AFMOVVP, &r1, t);
-		gins(AFLDCW, &t1, N);
-		return;
-
-	case CASE(TFLOAT32, TINT8):
-	case CASE(TFLOAT32, TUINT16):
-	case CASE(TFLOAT32, TUINT8):
-	case CASE(TFLOAT64, TINT8):
-	case CASE(TFLOAT64, TUINT16):
-	case CASE(TFLOAT64, TUINT8):
-		// convert via int32.
-		tempname(&t1, types[TINT32]);
-		gmove(f, &t1);
-		switch(tt) {
-		default:
-			fatal("gmove %N", t);
-		case TINT8:
-			gins(ACMPL, &t1, ncon(-0x80));
-			p1 = gbranch(optoas(OLT, types[TINT32]), T, -1);
-			gins(ACMPL, &t1, ncon(0x7f));
-			p2 = gbranch(optoas(OGT, types[TINT32]), T, -1);
-			p3 = gbranch(AJMP, T, 0);
-			patch(p1, pc);
-			patch(p2, pc);
-			gmove(ncon(-0x80), &t1);
-			patch(p3, pc);
-			gmove(&t1, t);
-			break;
-		case TUINT8:
-			gins(ATESTL, ncon(0xffffff00), &t1);
-			p1 = gbranch(AJEQ, T, +1);
-			gins(AMOVL, ncon(0), &t1);
-			patch(p1, pc);
-			gmove(&t1, t);
-			break;
-		case TUINT16:
-			gins(ATESTL, ncon(0xffff0000), &t1);
-			p1 = gbranch(AJEQ, T, +1);
-			gins(AMOVL, ncon(0), &t1);
-			patch(p1, pc);
-			gmove(&t1, t);
-			break;
-		}
-		return;
-
-	case CASE(TFLOAT32, TUINT32):
-	case CASE(TFLOAT64, TUINT32):
-		// convert via int64.
-		cvt = types[TINT64];
-		goto hardmem;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT16, TFLOAT32):
-	case CASE(TINT16, TFLOAT64):
-	case CASE(TINT32, TFLOAT32):
-	case CASE(TINT32, TFLOAT64):
-	case CASE(TINT64, TFLOAT32):
-	case CASE(TINT64, TFLOAT64):
-		if(t->op != OREGISTER)
-			goto hard;
-		if(f->op == OREGISTER) {
-			cvt = f->type;
-			goto hardmem;
-		}
-		switch(ft) {
-		case TINT16:
-			a = AFMOVW;
-			break;
-		case TINT32:
-			a = AFMOVL;
-			break;
-		default:
-			a = AFMOVV;
-			break;
-		}
-		break;
-
-	case CASE(TINT8, TFLOAT32):
-	case CASE(TINT8, TFLOAT64):
-	case CASE(TUINT16, TFLOAT32):
-	case CASE(TUINT16, TFLOAT64):
-	case CASE(TUINT8, TFLOAT32):
-	case CASE(TUINT8, TFLOAT64):
-		// convert via int32 memory
-		cvt = types[TINT32];
-		goto hardmem;
-
-	case CASE(TUINT32, TFLOAT32):
-	case CASE(TUINT32, TFLOAT64):
-		// convert via int64 memory
-		cvt = types[TINT64];
-		goto hardmem;
-
-	/*
-	 * float to float
-	 */
-	case CASE(TFLOAT32, TFLOAT32):
-	case CASE(TFLOAT64, TFLOAT64):
-		// The way the code generator uses floating-point
-		// registers, a move from F0 to F0 is intended as a no-op.
-		// On the x86, it's not: it pushes a second copy of F0
-		// on the floating point stack.  So toss it away here.
-		// Also, F0 is the *only* register we ever evaluate
-		// into, so we should only see register/register as F0/F0.
-		if(ismem(f) && ismem(t))
-			goto hard;
-		if(f->op == OREGISTER && t->op == OREGISTER) {
-			if(f->val.u.reg != REG_F0 || t->val.u.reg != REG_F0)
-				goto fatal;
-			return;
-		}
-		a = AFMOVF;
-		if(ft == TFLOAT64)
-			a = AFMOVD;
-		if(ismem(t)) {
-			if(f->op != OREGISTER || f->val.u.reg != REG_F0)
-				fatal("gmove %N", f);
-			a = AFMOVFP;
-			if(ft == TFLOAT64)
-				a = AFMOVDP;
-		}
-		break;
-
-	case CASE(TFLOAT32, TFLOAT64):
-		if(ismem(f) && ismem(t))
-			goto hard;
-		if(f->op == OREGISTER && t->op == OREGISTER) {
-			if(f->val.u.reg != REG_F0 || t->val.u.reg != REG_F0)
-				goto fatal;
-			return;
-		}
-		if(f->op == OREGISTER)
-			gins(AFMOVDP, f, t);
-		else
-			gins(AFMOVF, f, t);
-		return;
-
-	case CASE(TFLOAT64, TFLOAT32):
-		if(ismem(f) && ismem(t))
-			goto hard;
-		if(f->op == OREGISTER && t->op == OREGISTER) {
-			tempname(&r1, types[TFLOAT32]);
-			gins(AFMOVFP, f, &r1);
-			gins(AFMOVF, &r1, t);
-			return;
-		}
-		if(f->op == OREGISTER)
-			gins(AFMOVFP, f, t);
-		else
-			gins(AFMOVD, f, t);
-		return;
-	}
-
-	gins(a, f, t);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hardmem:
-	// requires memory intermediate
-	tempname(&r1, cvt);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	return;
-
-fatal:
-	// should not happen
-	fatal("gmove %lN -> %lN", f, t);
-	return;
-}
-
-static void
-floatmove_sse(Node *f, Node *t)
-{
-	Node r1;
-	Type *cvt;
-	int a, ft, tt;
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-
-	switch(CASE(ft, tt)) {
-	default:
-		// should not happen
-		fatal("gmove %N -> %N", f, t);
-		return;
-	/*
-	* float to integer
-	*/
-	case CASE(TFLOAT32, TINT16):
-	case CASE(TFLOAT32, TINT8):
-	case CASE(TFLOAT32, TUINT16):
-	case CASE(TFLOAT32, TUINT8):
-	case CASE(TFLOAT64, TINT16):
-	case CASE(TFLOAT64, TINT8):
-	case CASE(TFLOAT64, TUINT16):
-	case CASE(TFLOAT64, TUINT8):
-		// convert via int32.
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TFLOAT32, TUINT32):
-	case CASE(TFLOAT64, TUINT32):
-		// convert via int64.
-		cvt = types[TINT64];
-		goto hardmem;
-
-	case CASE(TFLOAT32, TINT32):
-		a = ACVTTSS2SL;
-		goto rdst;
-
-	case CASE(TFLOAT64, TINT32):
-		a = ACVTTSD2SL;
-		goto rdst;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT8, TFLOAT32):
-	case CASE(TINT8, TFLOAT64):
-	case CASE(TINT16, TFLOAT32):
-	case CASE(TINT16, TFLOAT64):
-	case CASE(TUINT16, TFLOAT32):
-	case CASE(TUINT16, TFLOAT64):
-	case CASE(TUINT8, TFLOAT32):
-	case CASE(TUINT8, TFLOAT64):
-		// convert via int32 memory
-		cvt = types[TINT32];
-		goto hard;
-
-	case CASE(TUINT32, TFLOAT32):
-	case CASE(TUINT32, TFLOAT64):
-		// convert via int64 memory
-		cvt = types[TINT64];
-		goto hardmem;
-
-	case CASE(TINT32, TFLOAT32):
-		a = ACVTSL2SS;
-		goto rdst;
-
-	case CASE(TINT32, TFLOAT64):
-		a = ACVTSL2SD;
-		goto rdst;
-
-	/*
-	 * float to float
-	 */
-	case CASE(TFLOAT32, TFLOAT32):
-		a = AMOVSS;
-		break;
-
-	case CASE(TFLOAT64, TFLOAT64):
-		a = AMOVSD;
-		break;
-
-	case CASE(TFLOAT32, TFLOAT64):
-		a = ACVTSS2SD;
-		goto rdst;
-
-	case CASE(TFLOAT64, TFLOAT32):
-		a = ACVTSD2SS;
-		goto rdst;
-	}
-
-	gins(a, f, t);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hardmem:
-	// requires memory intermediate
-	tempname(&r1, cvt);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	return;
-
-rdst:
-	// requires register destination
-	regalloc(&r1, t->type, t);
-	gins(a, f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-}
-
-int
-samaddr(Node *f, Node *t)
-{
-
-	if(f->op != t->op)
-		return 0;
-
-	switch(f->op) {
-	case OREGISTER:
-		if(f->val.u.reg != t->val.u.reg)
-			break;
-		return 1;
-	}
-	return 0;
-}
-/*
- * generate one instruction:
- *	as f, t
- */
-Prog*
-gins(int as, Node *f, Node *t)
-{
-	Prog *p;
-	Addr af, at;
-	int w;
-
-	if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER)
-		fatal("gins MOVF reg, reg");
-	if(as == ACVTSD2SS && f && f->op == OLITERAL)
-		fatal("gins CVTSD2SS const");
-	if(as == AMOVSD && t && t->op == OREGISTER && t->val.u.reg == REG_F0)
-		fatal("gins MOVSD into F0");
-
-	switch(as) {
-	case AMOVB:
-	case AMOVW:
-	case AMOVL:
-		if(f != N && t != N && samaddr(f, t))
-			return nil;
-		break;
-	
-	case ALEAL:
-		if(f != N && isconst(f, CTNIL))
-			fatal("gins LEAL nil %T", f->type);
-		break;
-	}
-
-	memset(&af, 0, sizeof af);
-	memset(&at, 0, sizeof at);
-	if(f != N)
-		naddr(f, &af, 1);
-	if(t != N)
-		naddr(t, &at, 1);
-	p = prog(as);
-	if(f != N)
-		p->from = af;
-	if(t != N)
-		p->to = at;
-	if(debug['g'])
-		print("%P\n", p);
-
-	w = 0;
-	switch(as) {
-	case AMOVB:
-		w = 1;
-		break;
-	case AMOVW:
-		w = 2;
-		break;
-	case AMOVL:
-		w = 4;
-		break;
-	}
-
-	if(1 && w != 0 && f != N && (af.width > w || at.width > w)) {
-		dump("bad width from:", f);
-		dump("bad width to:", t);
-		fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
-	}
-	if(p->to.type == TYPE_ADDR && w > 0)
-		fatal("bad use of addr: %P", p);
-
-	return p;
-}
-
-int
-dotaddable(Node *n, Node *n1)
-{
-	int o;
-	int64 oary[10];
-	Node *nn;
-
-	if(n->op != ODOT)
-		return 0;
-
-	o = dotoffset(n, oary, &nn);
-	if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
-		*n1 = *nn;
-		n1->type = n->type;
-		n1->xoffset += oary[0];
-		return 1;
-	}
-	return 0;
-}
-
-void
-sudoclean(void)
-{
-}
-
-int
-sudoaddable(int as, Node *n, Addr *a)
-{
-	USED(as);
-	USED(n);
-
-	memset(a, 0, sizeof *a);
-	return 0;
-}
diff --git a/src/cmd/new8g/gsubr.go b/src/cmd/8g/gsubr.go
similarity index 100%
rename from src/cmd/new8g/gsubr.go
rename to src/cmd/8g/gsubr.go
diff --git a/src/cmd/8g/peep.c b/src/cmd/8g/peep.c
deleted file mode 100644
index 712c8fe..0000000
--- a/src/cmd/8g/peep.c
+++ /dev/null
@@ -1,773 +0,0 @@
-// Derived from Inferno utils/6c/peep.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.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 "gg.h"
-#include "../gc/popt.h"
-
-enum {
-	REGEXT = 0,
-	exregoffset = REG_DI,
-};
-
-static void	conprop(Flow *r);
-static void	elimshortmov(Graph*);
-static int	subprop(Flow*);
-static int	copyprop(Graph*, Flow*);
-static int	copy1(Adr*, Adr*, Flow*, int);
-static int	copyas(Adr*, Adr*);
-static int	copyau(Adr*, Adr*);
-static int	copysub(Adr*, Adr*, Adr*, int);
-static int	copyu(Prog*, Adr*, Adr*);
-
-static uint32	gactive;
-
-// do we need the carry bit
-static int
-needc(Prog *p)
-{
-	ProgInfo info;
-
-	while(p != P) {
-		proginfo(&info, p);
-		if(info.flags & UseCarry)
-			return 1;
-		if(info.flags & (SetCarry|KillCarry))
-			return 0;
-		p = p->link;
-	}
-	return 0;
-}
-
-static Flow*
-rnops(Flow *r)
-{
-	Prog *p;
-	Flow *r1;
-
-	if(r != nil)
-	for(;;) {
-		p = r->prog;
-		if(p->as != ANOP || p->from.type != TYPE_NONE || p->to.type != TYPE_NONE)
-			break;
-		r1 = uniqs(r);
-		if(r1 == nil)
-			break;
-		r = r1;
-	}
-	return r;
-}
-
-void
-peep(Prog *firstp)
-{
-	Flow *r, *r1;
-	Graph *g;
-	Prog *p, *p1;
-	int t;
-
-	g = flowstart(firstp, 0);
-	if(g == nil)
-		return;
-	gactive = 0;
-
-	// byte, word arithmetic elimination.
-	elimshortmov(g);
-
-	// constant propagation
-	// find MOV $con,R followed by
-	// another MOV $con,R without
-	// setting R in the interim
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case ALEAL:
-			if(regtyp(&p->to))
-			if(p->from.sym != nil)
-			if(p->from.index == REG_NONE)
-				conprop(r);
-			break;
-
-		case AMOVB:
-		case AMOVW:
-		case AMOVL:
-		case AMOVSS:
-		case AMOVSD:
-			if(regtyp(&p->to))
-			if(p->from.type == TYPE_CONST || p->from.type == TYPE_FCONST)
-				conprop(r);
-			break;
-		}
-	}
-
-loop1:
-	if(debug['P'] && debug['v'])
-		dumpit("loop1", g->start, 0);
-
-	t = 0;
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case AMOVL:
-		case AMOVSS:
-		case AMOVSD:
-			if(regtyp(&p->to))
-			if(regtyp(&p->from)) {
-				if(copyprop(g, r)) {
-					excise(r);
-					t++;
-				} else
-				if(subprop(r) && copyprop(g, r)) {
-					excise(r);
-					t++;
-				}
-			}
-			break;
-
-		case AMOVBLZX:
-		case AMOVWLZX:
-		case AMOVBLSX:
-		case AMOVWLSX:
-			if(regtyp(&p->to)) {
-				r1 = rnops(uniqs(r));
-				if(r1 != nil) {
-					p1 = r1->prog;
-					if(p->as == p1->as && p->to.type == p1->from.type && p->to.reg == p1->from.reg){
-						p1->as = AMOVL;
-						t++;
-					}
-				}
-			}
-			break;
-
-		case AADDL:
-		case AADDW:
-			if(p->from.type != TYPE_CONST || needc(p->link))
-				break;
-			if(p->from.offset == -1){
-				if(p->as == AADDL)
-					p->as = ADECL;
-				else
-					p->as = ADECW;
-				p->from = zprog.from;
-				break;
-			}
-			if(p->from.offset == 1){
-				if(p->as == AADDL)
-					p->as = AINCL;
-				else
-					p->as = AINCW;
-				p->from = zprog.from;
-				break;
-			}
-			break;
-
-		case ASUBL:
-		case ASUBW:
-			if(p->from.type != TYPE_CONST || needc(p->link))
-				break;
-			if(p->from.offset == -1) {
-				if(p->as == ASUBL)
-					p->as = AINCL;
-				else
-					p->as = AINCW;
-				p->from = zprog.from;
-				break;
-			}
-			if(p->from.offset == 1){
-				if(p->as == ASUBL)
-					p->as = ADECL;
-				else
-					p->as = ADECW;
-				p->from = zprog.from;
-				break;
-			}
-			break;
-		}
-	}
-	if(t)
-		goto loop1;
-
-	// MOVSD removal.
-	// We never use packed registers, so a MOVSD between registers
-	// can be replaced by MOVAPD, which moves the pair of float64s
-	// instead of just the lower one.  We only use the lower one, but
-	// the processor can do better if we do moves using both.
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		if(p->as == AMOVSD)
-		if(regtyp(&p->from))
-		if(regtyp(&p->to))
-			p->as = AMOVAPD;
-	}
-	
-	flowend(g);
-}
-
-void
-excise(Flow *r)
-{
-	Prog *p;
-
-	p = r->prog;
-	if(debug['P'] && debug['v'])
-		print("%P ===delete===\n", p);
-
-	nopout(p);
-
-	ostats.ndelmov++;
-}
-
-int
-regtyp(Adr *a)
-{
-	return a->type == TYPE_REG && (REG_AX <= a->reg && a->reg <= REG_DI || REG_X0 <= a->reg && a->reg <= REG_X7);
-}
-
-// movb elimination.
-// movb is simulated by the linker
-// when a register other than ax, bx, cx, dx
-// is used, so rewrite to other instructions
-// when possible.  a movb into a register
-// can smash the entire 64-bit register without
-// causing any trouble.
-static void
-elimshortmov(Graph *g)
-{
-	Prog *p;
-	Flow *r;
-
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		if(regtyp(&p->to)) {
-			switch(p->as) {
-			case AINCB:
-			case AINCW:
-				p->as = AINCL;
-				break;
-			case ADECB:
-			case ADECW:
-				p->as = ADECL;
-				break;
-			case ANEGB:
-			case ANEGW:
-				p->as = ANEGL;
-				break;
-			case ANOTB:
-			case ANOTW:
-				p->as = ANOTL;
-				break;
-			}
-			if(regtyp(&p->from) || p->from.type == TYPE_CONST) {
-				// move or artihmetic into partial register.
-				// from another register or constant can be movl.
-				// we don't switch to 32-bit arithmetic if it can
-				// change how the carry bit is set (and the carry bit is needed).
-				switch(p->as) {
-				case AMOVB:
-				case AMOVW:
-					p->as = AMOVL;
-					break;
-				case AADDB:
-				case AADDW:
-					if(!needc(p->link))
-						p->as = AADDL;
-					break;
-				case ASUBB:
-				case ASUBW:
-					if(!needc(p->link))
-						p->as = ASUBL;
-					break;
-				case AMULB:
-				case AMULW:
-					p->as = AMULL;
-					break;
-				case AIMULB:
-				case AIMULW:
-					p->as = AIMULL;
-					break;
-				case AANDB:
-				case AANDW:
-					p->as = AANDL;
-					break;
-				case AORB:
-				case AORW:
-					p->as = AORL;
-					break;
-				case AXORB:
-				case AXORW:
-					p->as = AXORL;
-					break;
-				case ASHLB:
-				case ASHLW:
-					p->as = ASHLL;
-					break;
-				}
-			} else {
-				// explicit zero extension
-				switch(p->as) {
-				case AMOVB:
-					p->as = AMOVBLZX;
-					break;
-				case AMOVW:
-					p->as = AMOVWLZX;
-					break;
-				}
-			}
-		}
-	}
-}
-
-/*
- * the idea is to substitute
- * one register for another
- * from one MOV to another
- *	MOV	a, R0
- *	ADD	b, R0	/ no use of R1
- *	MOV	R0, R1
- * would be converted to
- *	MOV	a, R1
- *	ADD	b, R1
- *	MOV	R1, R0
- * hopefully, then the former or latter MOV
- * will be eliminated by copy propagation.
- */
-static int
-subprop(Flow *r0)
-{
-	Prog *p;
-	Adr *v1, *v2;
-	Flow *r;
-	int t;
-	ProgInfo info;
-
-	p = r0->prog;
-	v1 = &p->from;
-	if(!regtyp(v1))
-		return 0;
-	v2 = &p->to;
-	if(!regtyp(v2))
-		return 0;
-	for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
-		if(debug['P'] && debug['v'])
-			print("\t? %P\n", r->prog);
-		if(uniqs(r) == nil)
-			break;
-		p = r->prog;
-		if(p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-		proginfo(&info, p);
-		if(info.flags & Call)
-			return 0;
-
-		if(info.reguse | info.regset)
-			return 0;
-
-		if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type && p->to.reg == v1->reg)
-			goto gotit;
-
-		if(copyau(&p->from, v2) || copyau(&p->to, v2))
-			break;
-		if(copysub(&p->from, v1, v2, 0) || copysub(&p->to, v1, v2, 0))
-			break;
-	}
-	return 0;
-
-gotit:
-	copysub(&p->to, v1, v2, 1);
-	if(debug['P']) {
-		print("gotit: %D->%D\n%P", v1, v2, r->prog);
-		if(p->from.type == v2->type && p->from.reg == v2->reg)
-			print(" excise");
-		print("\n");
-	}
-	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
-		p = r->prog;
-		copysub(&p->from, v1, v2, 1);
-		copysub(&p->to, v1, v2, 1);
-		if(debug['P'])
-			print("%P\n", r->prog);
-	}
-	t = v1->reg;
-	v1->reg = v2->reg;
-	v2->reg = t;
-	if(debug['P'])
-		print("%P last\n", r->prog);
-	return 1;
-}
-
-/*
- * The idea is to remove redundant copies.
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	use v2	return fail
- *	-----------------
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	set v2	return success
- */
-static int
-copyprop(Graph *g, Flow *r0)
-{
-	Prog *p;
-	Adr *v1, *v2;
-
-	USED(g);
-	p = r0->prog;
-	v1 = &p->from;
-	v2 = &p->to;
-	if(copyas(v1, v2))
-		return 1;
-	gactive++;
-	return copy1(v1, v2, r0->s1, 0);
-}
-
-static int
-copy1(Adr *v1, Adr *v2, Flow *r, int f)
-{
-	int t;
-	Prog *p;
-
-	if(r->active == gactive) {
-		if(debug['P'])
-			print("act set; return 1\n");
-		return 1;
-	}
-	r->active = gactive;
-	if(debug['P'])
-		print("copy %D->%D f=%d\n", v1, v2, f);
-	for(; r != nil; r = r->s1) {
-		p = r->prog;
-		if(debug['P'])
-			print("%P", p);
-		if(!f && uniqp(r) == nil) {
-			f = 1;
-			if(debug['P'])
-				print("; merge; f=%d", f);
-		}
-		t = copyu(p, v2, nil);
-		switch(t) {
-		case 2:	/* rar, can't split */
-			if(debug['P'])
-				print("; %D rar; return 0\n", v2);
-			return 0;
-
-		case 3:	/* set */
-			if(debug['P'])
-				print("; %D set; return 1\n", v2);
-			return 1;
-
-		case 1:	/* used, substitute */
-		case 4:	/* use and set */
-			if(f) {
-				if(!debug['P'])
-					return 0;
-				if(t == 4)
-					print("; %D used+set and f=%d; return 0\n", v2, f);
-				else
-					print("; %D used and f=%d; return 0\n", v2, f);
-				return 0;
-			}
-			if(copyu(p, v2, v1)) {
-				if(debug['P'])
-					print("; sub fail; return 0\n");
-				return 0;
-			}
-			if(debug['P'])
-				print("; sub %D/%D", v2, v1);
-			if(t == 4) {
-				if(debug['P'])
-					print("; %D used+set; return 1\n", v2);
-				return 1;
-			}
-			break;
-		}
-		if(!f) {
-			t = copyu(p, v1, nil);
-			if(!f && (t == 2 || t == 3 || t == 4)) {
-				f = 1;
-				if(debug['P'])
-					print("; %D set and !f; f=%d", v1, f);
-			}
-		}
-		if(debug['P'])
-			print("\n");
-		if(r->s2)
-			if(!copy1(v1, v2, r->s2, f))
-				return 0;
-	}
-	return 1;
-}
-
-/*
- * return
- * 1 if v only used (and substitute),
- * 2 if read-alter-rewrite
- * 3 if set
- * 4 if set and used
- * 0 otherwise (not touched)
- */
-static int
-copyu(Prog *p, Adr *v, Adr *s)
-{
-	ProgInfo info;
-
-	switch(p->as) {
-	case AJMP:
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ARET:
-		if(s != nil)
-			return 1;
-		return 3;
-
-	case ACALL:
-		if(REGEXT && v->type == TYPE_REG && v->reg <= REGEXT && v->reg > exregoffset)
-			return 2;
-		if(REGARG >= 0 && v->type == TYPE_REG && v->reg == REGARG)
-			return 2;
-		if(v->type == p->from.type && v->reg == p->from.reg)
-			return 2;
-
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 4;
-		return 3;
-
-	case ATEXT:
-		if(REGARG >= 0 && v->type == TYPE_REG && v->reg == REGARG)
-			return 3;
-		return 0;
-	}
-
-	if(p->as == AVARDEF || p->as == AVARKILL)
-		return 0;
-	proginfo(&info, p);
-
-	if((info.reguse|info.regset) & RtoB(v->reg))
-		return 2;
-		
-	if(info.flags & LeftAddr)
-		if(copyas(&p->from, v))
-			return 2;
-
-	if((info.flags & (RightRead|RightWrite)) == (RightRead|RightWrite))
-		if(copyas(&p->to, v))
-			return 2;
-	
-	if(info.flags & RightWrite) {
-		if(copyas(&p->to, v)) {
-			if(s != nil)
-				return copysub(&p->from, v, s, 1);
-			if(copyau(&p->from, v))
-				return 4;
-			return 3;
-		}
-	}
-	
-	if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			return copysub(&p->to, v, s, 1);
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * direct reference,
- * could be set/use depending on
- * semantics
- */
-static int
-copyas(Adr *a, Adr *v)
-{
-	if(REG_AL <= a->reg && a->reg <= REG_BL)
-		fatal("use of byte register");
-	if(REG_AL <= v->reg && v->reg <= REG_BL)
-		fatal("use of byte register");
-
-	if(a->type != v->type || a->name != v->name || a->reg != v->reg)
-		return 0;
-	if(regtyp(v))
-		return 1;
-	if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
-		if(v->offset == a->offset)
-			return 1;
-	return 0;
-}
-
-int
-sameaddr(Addr *a, Addr *v)
-{
-	if(a->type != v->type || a->name != v->name || a->reg != v->reg)
-		return 0;
-	if(regtyp(v))
-		return 1;
-	if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
-		if(v->offset == a->offset)
-			return 1;
-	return 0;
-}
-
-/*
- * either direct or indirect
- */
-static int
-copyau(Adr *a, Adr *v)
-{
-
-	if(copyas(a, v))
-		return 1;
-	if(regtyp(v)) {
-		if(a->type == TYPE_MEM && a->reg == v->reg)
-			return 1;
-		if(a->index == v->reg)
-			return 1;
-	}
-	return 0;
-}
-
-/*
- * substitute s for v in a
- * return failure to substitute
- */
-static int
-copysub(Adr *a, Adr *v, Adr *s, int f)
-{
-	int reg;
-
-	if(copyas(a, v)) {
-		reg = s->reg;
-		if(reg >= REG_AX && reg <= REG_DI || reg >= REG_X0 && reg <= REG_X7) {
-			if(f)
-				a->reg = reg;
-		}
-		return 0;
-	}
-	if(regtyp(v)) {
-		reg = v->reg;
-		if(a->type == TYPE_MEM && a->reg == reg) {
-			if((s->reg == REG_BP) && a->index != TYPE_NONE)
-				return 1;	/* can't use BP-base with index */
-			if(f)
-				a->reg = s->reg;
-//			return 0;
-		}
-		if(a->index == reg) {
-			if(f)
-				a->index = s->reg;
-			return 0;
-		}
-		return 0;
-	}
-	return 0;
-}
-
-static void
-conprop(Flow *r0)
-{
-	Flow *r;
-	Prog *p, *p0;
-	int t;
-	Adr *v0;
-
-	p0 = r0->prog;
-	v0 = &p0->to;
-	r = r0;
-
-loop:
-	r = uniqs(r);
-	if(r == nil || r == r0)
-		return;
-	if(uniqp(r) == nil)
-		return;
-
-	p = r->prog;
-	t = copyu(p, v0, nil);
-	switch(t) {
-	case 0:	// miss
-	case 1:	// use
-		goto loop;
-
-	case 2:	// rar
-	case 4:	// use and set
-		break;
-
-	case 3:	// set
-		if(p->as == p0->as)
-		if(p->from.type == p0->from.type)
-		if(p->from.reg == p0->from.reg)
-		if(p->from.node == p0->from.node)
-		if(p->from.offset == p0->from.offset)
-		if(p->from.scale == p0->from.scale)
-		if(p->from.type == TYPE_FCONST && p->from.u.dval == p0->from.u.dval)
-		if(p->from.index == p0->from.index) {
-			excise(r);
-			goto loop;
-		}
-		break;
-	}
-}
-
-int
-smallindir(Addr *a, Addr *reg)
-{
-	return regtyp(reg) &&
-		a->type == TYPE_MEM && a->reg == reg->reg &&
-		a->index == REG_NONE &&
-		0 <= a->offset && a->offset < 4096;
-}
-
-int
-stackaddr(Addr *a)
-{
-	return a->type == TYPE_REG && a->reg == REG_SP;
-}
diff --git a/src/cmd/new8g/peep.go b/src/cmd/8g/peep.go
similarity index 100%
rename from src/cmd/new8g/peep.go
rename to src/cmd/8g/peep.go
diff --git a/src/cmd/8g/prog.c b/src/cmd/8g/prog.c
deleted file mode 100644
index e77a026..0000000
--- a/src/cmd/8g/prog.c
+++ /dev/null
@@ -1,349 +0,0 @@
-// 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 "gg.h"
-#include "../gc/popt.h"
-
-// Matches real RtoB but can be used in global initializer.
-#define RtoB(r) (1<<((r)-REG_AX))
-
-enum {
-	AX = RtoB(REG_AX),
-	BX = RtoB(REG_BX),
-	CX = RtoB(REG_CX),
-	DX = RtoB(REG_DX),
-	DI = RtoB(REG_DI),
-	SI = RtoB(REG_SI),
-	
-	LeftRdwr = LeftRead | LeftWrite,
-	RightRdwr = RightRead | RightWrite,
-};
-
-#undef RtoB
-
-// This table gives the basic information about instruction
-// generated by the compiler and processed in the optimizer.
-// See opt.h for bit definitions.
-//
-// Instructions not generated need not be listed.
-// As an exception to that rule, we typically write down all the
-// size variants of an operation even if we just use a subset.
-//
-// The table is formatted for 8-space tabs.
-static ProgInfo progtable[ALAST] = {
-	[ATYPE]=	{Pseudo | Skip},
-	[ATEXT]=	{Pseudo},
-	[AFUNCDATA]=	{Pseudo},
-	[APCDATA]=	{Pseudo},
-	[AUNDEF]=	{Break},
-	[AUSEFIELD]=	{OK},
-	[ACHECKNIL]=	{LeftRead},
-	[AVARDEF]=	{Pseudo | RightWrite},
-	[AVARKILL]=	{Pseudo | RightWrite},
-
-	// NOP is an internal no-op that also stands
-	// for USED and SET annotations, not the Intel opcode.
-	[ANOP]=		{LeftRead | RightWrite},
-
-	[AADCL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[AADCW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
-
-	[AADDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AADDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AADDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-	
-	[AADDSD]=	{SizeD | LeftRead | RightRdwr},
-	[AADDSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[AANDB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AANDL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AANDW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[ACALL]=	{RightAddr | Call | KillCarry},
-
-	[ACDQ]=		{OK, AX, AX | DX},
-	[ACWD]=		{OK, AX, AX | DX},
-
-	[ACLD]=		{OK},
-	[ASTD]=		{OK},
-
-	[ACMPB]=	{SizeB | LeftRead | RightRead | SetCarry},
-	[ACMPL]=	{SizeL | LeftRead | RightRead | SetCarry},
-	[ACMPW]=	{SizeW | LeftRead | RightRead | SetCarry},
-
-	[ACOMISD]=	{SizeD | LeftRead | RightRead | SetCarry},
-	[ACOMISS]=	{SizeF | LeftRead | RightRead | SetCarry},
-
-	[ACVTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTSD2SS]=	{SizeF | LeftRead | RightWrite | Conv},
-	[ACVTSL2SD]=	{SizeD | LeftRead | RightWrite | Conv},
-	[ACVTSL2SS]=	{SizeF | LeftRead | RightWrite | Conv},
-	[ACVTSS2SD]=	{SizeD | LeftRead | RightWrite | Conv},
-	[ACVTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTTSD2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-	[ACVTTSS2SL]=	{SizeL | LeftRead | RightWrite | Conv},
-
-	[ADECB]=	{SizeB | RightRdwr},
-	[ADECL]=	{SizeL | RightRdwr},
-	[ADECW]=	{SizeW | RightRdwr},
-
-	[ADIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[ADIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
-	[ADIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
-
-	[ADIVSD]=	{SizeD | LeftRead | RightRdwr},
-	[ADIVSS]=	{SizeF | LeftRead | RightRdwr},
-	
-	[AFLDCW]=	{SizeW | LeftAddr},
-	[AFSTCW]=	{SizeW | RightAddr},
-
-	[AFSTSW]=	{SizeW | RightAddr | RightWrite},
-
-	[AFADDD]=	{SizeD | LeftAddr | RightRdwr},
-	[AFADDDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFADDF]=	{SizeF | LeftAddr | RightRdwr},
-
-	[AFCOMD]=	{SizeD | LeftAddr | RightRead},
-	[AFCOMDP]=	{SizeD | LeftAddr | RightRead},
-	[AFCOMDPP]=	{SizeD | LeftAddr | RightRead},
-	[AFCOMF]=	{SizeF | LeftAddr | RightRead},
-	[AFCOMFP]=	{SizeF | LeftAddr | RightRead},
-	[AFUCOMIP]=	{SizeF | LeftAddr | RightRead},
-
-	[AFCHS]=	{SizeD | RightRdwr}, // also SizeF
-
-	[AFDIVDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFDIVF]=	{SizeF | LeftAddr | RightRdwr},
-	[AFDIVD]=	{SizeD | LeftAddr | RightRdwr},
-
-	[AFDIVRDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFDIVRF]=	{SizeF | LeftAddr | RightRdwr},
-	[AFDIVRD]=	{SizeD | LeftAddr | RightRdwr},
-
-	[AFXCHD]=	{SizeD | LeftRdwr | RightRdwr},
-
-	[AFSUBD]=	{SizeD | LeftAddr | RightRdwr},
-	[AFSUBDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFSUBF]=	{SizeF | LeftAddr | RightRdwr},
-	[AFSUBRD]=	{SizeD | LeftAddr | RightRdwr},
-	[AFSUBRDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFSUBRF]=	{SizeF | LeftAddr | RightRdwr},
-
-	[AFMOVD]=	{SizeD | LeftAddr | RightWrite},
-	[AFMOVF]=	{SizeF | LeftAddr | RightWrite},
-	[AFMOVL]=	{SizeL | LeftAddr | RightWrite},
-	[AFMOVW]=	{SizeW | LeftAddr | RightWrite},
-	[AFMOVV]=	{SizeQ | LeftAddr | RightWrite},
-
-	// These instructions are marked as RightAddr
-	// so that the register optimizer does not try to replace the
-	// memory references with integer register references.
-	// But they do not use the previous value at the address, so
-	// we also mark them RightWrite.
-	[AFMOVDP]=	{SizeD | LeftRead | RightWrite | RightAddr},
-	[AFMOVFP]=	{SizeF | LeftRead | RightWrite | RightAddr},
-	[AFMOVLP]=	{SizeL | LeftRead | RightWrite | RightAddr},
-	[AFMOVWP]=	{SizeW | LeftRead | RightWrite | RightAddr},
-	[AFMOVVP]=	{SizeQ | LeftRead | RightWrite | RightAddr},
-
-	[AFMULD]=	{SizeD | LeftAddr | RightRdwr},
-	[AFMULDP]=	{SizeD | LeftAddr | RightRdwr},
-	[AFMULF]=	{SizeF | LeftAddr | RightRdwr},
-
-	[AIDIVB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AIDIVL]=	{SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
-	[AIDIVW]=	{SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
-
-	[AIMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AIMULL]=	{SizeL | LeftRead | ImulAXDX | SetCarry},
-	[AIMULW]=	{SizeW | LeftRead | ImulAXDX | SetCarry},
-
-	[AINCB]=	{SizeB | RightRdwr},
-	[AINCL]=	{SizeL | RightRdwr},
-	[AINCW]=	{SizeW | RightRdwr},
-
-	[AJCC]=		{Cjmp | UseCarry},
-	[AJCS]=		{Cjmp | UseCarry},
-	[AJEQ]=		{Cjmp | UseCarry},
-	[AJGE]=		{Cjmp | UseCarry},
-	[AJGT]=		{Cjmp | UseCarry},
-	[AJHI]=		{Cjmp | UseCarry},
-	[AJLE]=		{Cjmp | UseCarry},
-	[AJLS]=		{Cjmp | UseCarry},
-	[AJLT]=		{Cjmp | UseCarry},
-	[AJMI]=		{Cjmp | UseCarry},
-	[AJNE]=		{Cjmp | UseCarry},
-	[AJOC]=		{Cjmp | UseCarry},
-	[AJOS]=		{Cjmp | UseCarry},
-	[AJPC]=		{Cjmp | UseCarry},
-	[AJPL]=		{Cjmp | UseCarry},
-	[AJPS]=		{Cjmp | UseCarry},
-
-	[AJMP]=		{Jump | Break | KillCarry},
-
-	[ALEAL]=	{LeftAddr | RightWrite},
-
-	[AMOVBLSX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVBLZX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVBWSX]=	{SizeW | LeftRead | RightWrite | Conv},
-	[AMOVBWZX]=	{SizeW | LeftRead | RightWrite | Conv},
-	[AMOVWLSX]=	{SizeL | LeftRead | RightWrite | Conv},
-	[AMOVWLZX]=	{SizeL | LeftRead | RightWrite | Conv},
-
-	[AMOVB]=	{SizeB | LeftRead | RightWrite | Move},
-	[AMOVL]=	{SizeL | LeftRead | RightWrite | Move},
-	[AMOVW]=	{SizeW | LeftRead | RightWrite | Move},
-
-	[AMOVSB]=	{OK, DI|SI, DI|SI},
-	[AMOVSL]=	{OK, DI|SI, DI|SI},
-	[AMOVSW]=	{OK, DI|SI, DI|SI},
-	[ADUFFCOPY]=	{OK, DI|SI, DI|SI|CX},
-
-	[AMOVSD]=	{SizeD | LeftRead | RightWrite | Move},
-	[AMOVSS]=	{SizeF | LeftRead | RightWrite | Move},
-
-	// We use MOVAPD as a faster synonym for MOVSD.
-	[AMOVAPD]=	{SizeD | LeftRead | RightWrite | Move},
-
-	[AMULB]=	{SizeB | LeftRead | SetCarry, AX, AX},
-	[AMULL]=	{SizeL | LeftRead | SetCarry, AX, AX|DX},
-	[AMULW]=	{SizeW | LeftRead | SetCarry, AX, AX|DX},
-	
-	[AMULSD]=	{SizeD | LeftRead | RightRdwr},
-	[AMULSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[ANEGB]=	{SizeB | RightRdwr | SetCarry},
-	[ANEGL]=	{SizeL | RightRdwr | SetCarry},
-	[ANEGW]=	{SizeW | RightRdwr | SetCarry},
-
-	[ANOTB]=	{SizeB | RightRdwr},
-	[ANOTL]=	{SizeL | RightRdwr},
-	[ANOTW]=	{SizeW | RightRdwr},
-
-	[AORB]=		{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AORL]=		{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AORW]=		{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[APOPL]=	{SizeL | RightWrite},
-	[APUSHL]=	{SizeL | LeftRead},
-
-	[ARCLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-
-	[ARCRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-	[ARCRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
-
-	[AREP]=		{OK, CX, CX},
-	[AREPN]=	{OK, CX, CX},
-
-	[ARET]=		{Break | KillCarry},
-
-	[AROLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[AROLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[AROLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ARORB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ARORL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ARORW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASAHF]=	{OK, AX, AX},
-
-	[ASALB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASALL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASALW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASARB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASARL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASARW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASBBB]=	{SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[ASBBL]=	{SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
-	[ASBBW]=	{SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
-
-	[ASETCC]=	{SizeB | RightRdwr | UseCarry},
-	[ASETCS]=	{SizeB | RightRdwr | UseCarry},
-	[ASETEQ]=	{SizeB | RightRdwr | UseCarry},
-	[ASETGE]=	{SizeB | RightRdwr | UseCarry},
-	[ASETGT]=	{SizeB | RightRdwr | UseCarry},
-	[ASETHI]=	{SizeB | RightRdwr | UseCarry},
-	[ASETLE]=	{SizeB | RightRdwr | UseCarry},
-	[ASETLS]=	{SizeB | RightRdwr | UseCarry},
-	[ASETLT]=	{SizeB | RightRdwr | UseCarry},
-	[ASETMI]=	{SizeB | RightRdwr | UseCarry},
-	[ASETNE]=	{SizeB | RightRdwr | UseCarry},
-	[ASETOC]=	{SizeB | RightRdwr | UseCarry},
-	[ASETOS]=	{SizeB | RightRdwr | UseCarry},
-	[ASETPC]=	{SizeB | RightRdwr | UseCarry},
-	[ASETPL]=	{SizeB | RightRdwr | UseCarry},
-	[ASETPS]=	{SizeB | RightRdwr | UseCarry},
-
-	[ASHLB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHLL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHLW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASHRB]=	{SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHRL]=	{SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
-	[ASHRW]=	{SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
-
-	[ASTOSB]=	{OK, AX|DI, DI},
-	[ASTOSL]=	{OK, AX|DI, DI},
-	[ASTOSW]=	{OK, AX|DI, DI},
-	[ADUFFZERO]=	{OK, AX|DI, DI},
-
-	[ASUBB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[ASUBL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[ASUBW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-
-	[ASUBSD]=	{SizeD | LeftRead | RightRdwr},
-	[ASUBSS]=	{SizeF | LeftRead | RightRdwr},
-
-	[ATESTB]=	{SizeB | LeftRead | RightRead | SetCarry},
-	[ATESTL]=	{SizeL | LeftRead | RightRead | SetCarry},
-	[ATESTW]=	{SizeW | LeftRead | RightRead | SetCarry},
-
-	[AUCOMISD]=	{SizeD | LeftRead | RightRead},
-	[AUCOMISS]=	{SizeF | LeftRead | RightRead},
-
-	[AXCHGB]=	{SizeB | LeftRdwr | RightRdwr},
-	[AXCHGL]=	{SizeL | LeftRdwr | RightRdwr},
-	[AXCHGW]=	{SizeW | LeftRdwr | RightRdwr},
-
-	[AXORB]=	{SizeB | LeftRead | RightRdwr | SetCarry},
-	[AXORL]=	{SizeL | LeftRead | RightRdwr | SetCarry},
-	[AXORW]=	{SizeW | LeftRead | RightRdwr | SetCarry},
-};
-
-void
-proginfo(ProgInfo *info, Prog *p)
-{
-	*info = progtable[p->as];
-	if(info->flags == 0)
-		fatal("unknown instruction %P", p);
-
-	if((info->flags & ShiftCX) && p->from.type != TYPE_CONST)
-		info->reguse |= CX;
-
-	if(info->flags & ImulAXDX) {
-		if(p->to.type == TYPE_NONE) {
-			info->reguse |= AX;
-			info->regset |= AX | DX;
-		} else {
-			info->flags |= RightRdwr;
-		}
-	}
-
-	// Addressing makes some registers used.
-	if(p->from.type == TYPE_MEM && p->from.name == NAME_NONE)
-		info->regindex |= RtoB(p->from.reg);
-	if(p->from.index != REG_NONE)
-		info->regindex |= RtoB(p->from.index);
-	if(p->to.type == TYPE_MEM && p->to.name == NAME_NONE)
-		info->regindex |= RtoB(p->to.reg);
-	if(p->to.index != REG_NONE)
-		info->regindex |= RtoB(p->to.index);
-}
diff --git a/src/cmd/new8g/prog.go b/src/cmd/8g/prog.go
similarity index 100%
rename from src/cmd/new8g/prog.go
rename to src/cmd/8g/prog.go
diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c
deleted file mode 100644
index 0470bdf..0000000
--- a/src/cmd/8g/reg.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-enum {
-	NREGVAR = 16,	/* 8 integer + 8 floating */
-};
-
-static char* regname[] = {
-	".ax", ".cx", ".dx", ".bx", ".sp", ".bp", ".si", ".di",
-	".x0", ".x1", ".x2", ".x3", ".x4", ".x5", ".x6", ".x7",
-};
-
-char**
-regnames(int *n)
-{
-	*n = NREGVAR;
-	return regname;
-}
-
-uint64
-excludedregs(void)
-{
-	return RtoB(REG_SP);
-}
-
-uint64
-doregbits(int r)
-{
-	uint64 b;
-
-	b = 0;
-	if(r >= REG_AX && r <= REG_DI)
-		b |= RtoB(r);
-	else
-	if(r >= REG_AL && r <= REG_BL)
-		b |= RtoB(r-REG_AL+REG_AX);
-	else
-	if(r >= REG_AH && r <= REG_BH)
-		b |= RtoB(r-REG_AH+REG_AX);
-	else
-	if(r >= REG_X0 && r <= REG_X0+7)
-		b |= FtoB(r);
-	return b;
-}
-
-uint64
-RtoB(int r)
-{
-
-	if(r < REG_AX || r > REG_DI)
-		return 0;
-	return 1ULL << (r-REG_AX);
-}
-
-int
-BtoR(uint64 b)
-{
-
-	b &= 0xffL;
-	if(b == 0)
-		return 0;
-	return bitno(b) + REG_AX;
-}
-
-uint64
-FtoB(int f)
-{
-	if(f < REG_X0 || f > REG_X7)
-		return 0;
-	return 1ULL << (f - REG_X0 + 8);
-}
-
-int
-BtoF(uint64 b)
-{
-	b &= 0xFF00L;
-	if(b == 0)
-		return 0;
-	return bitno(b) - 8 + REG_X0;
-}
diff --git a/src/cmd/new8g/reg.go b/src/cmd/8g/reg.go
similarity index 100%
rename from src/cmd/new8g/reg.go
rename to src/cmd/8g/reg.go
diff --git a/src/cmd/new8g/util.go b/src/cmd/8g/util.go
similarity index 100%
rename from src/cmd/new8g/util.go
rename to src/cmd/8g/util.go
diff --git a/src/cmd/9a/Makefile b/src/cmd/9a/Makefile
deleted file mode 100644
index 27290dd..0000000
--- a/src/cmd/9a/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
-
-y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/9a/a.h b/src/cmd/9a/a.h
deleted file mode 100644
index d4f2fee..0000000
--- a/src/cmd/9a/a.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// cmd/9a/a.h from Vita Nuova.
-//
-//	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-2008 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-2008 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 <bio.h>
-#include <link.h>
-#include "../9l/9.out.h"
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#undef	getc
-#undef	ungetc
-#undef	BUFSIZ
-
-#define	getc	ccgetc
-#define	ungetc	ccungetc
-
-typedef	struct	Sym	Sym;
-typedef	struct	Io	Io;
-
-#define	MAXALIGN	7
-#define	FPCHIP		1
-#define	NSYMB		8192
-#define	BUFSIZ		8192
-#define	HISTSZ		20
-#define	NINCLUDE	10
-#define	NHUNK		10000
-#ifndef EOF
-#define	EOF		(-1)
-#endif
-#define	IGN		(-2)
-#define	GETC()		((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
-#define	NHASH		503
-#define	STRINGSZ	200
-#define	NMACRO		10
-
-struct	Sym
-{
-	Sym*	link;
-	char*	macro;
-	vlong	value;
-	ushort	type;
-	char	*name;
-	char*	labelname;
-	char	sym;
-};
-#define	S	((Sym*)0)
-
-EXTERN struct
-{
-	char*	p;
-	int	c;
-} fi;
-
-struct	Io
-{
-	Io*	link;
-	char	b[BUFSIZ];
-	char*	p;
-	short	c;
-	short	f;
-};
-#define	I	((Io*)0)
-
-enum
-{
-	CLAST,
-	CMACARG,
-	CMACRO,
-	CPREPROC,
-};
-
-EXTERN	int	debug[256];
-EXTERN	Sym*	hash[NHASH];
-EXTERN	char**	Dlist;
-EXTERN	int	nDlist;
-EXTERN	int	newflag;
-EXTERN	char*	hunk;
-EXTERN	char**	include;
-EXTERN	Io*	iofree;
-EXTERN	Io*	ionext;
-EXTERN	Io*	iostack;
-EXTERN	int32	lineno;
-EXTERN	int	nerrors;
-EXTERN	int32	nhunk;
-EXTERN	int	nosched;
-EXTERN	int	ninclude;
-EXTERN	int32	nsymb;
-EXTERN	Addr	nullgen;
-EXTERN	char*	outfile;
-EXTERN	int	pass;
-EXTERN	int32	pc;
-EXTERN	int	peekc;
-EXTERN	int32	stmtline;
-EXTERN	int	sym;
-EXTERN	char*	symb;
-EXTERN	int	thechar;
-EXTERN	char*	thestring;
-EXTERN	int32	thunk;
-EXTERN	Biobuf	obuf;
-EXTERN	Link*	ctxt;
-EXTERN	Biobuf	bstdout;
-EXTERN	Prog*	lastpc;
-
-void*	alloc(int32);
-void*	allocn(void*, int32, int32);
-void	ensuresymb(int32);
-void	errorexit(void);
-void	pushio(void);
-void	newio(void);
-void	newfile(char*, int);
-Sym*	slookup(char*);
-Sym*	lookup(void);
-Sym*	labellookup(Sym*);
-void	settext(LSym*);
-void	syminit(Sym*);
-int32	yylex(void);
-int	getc(void);
-int	getnsc(void);
-void	unget(int);
-int	escchar(int);
-void	cinit(void);
-void	pinit(char*);
-void	cclean(void);
-void	outcode(int, Addr*, int, Addr*);
-void	outgcode(int, Addr*, int, Addr*, Addr*);
-int	filbuf(void);
-Sym*	getsym(void);
-void	domacro(void);
-void	macund(void);
-void	macdef(void);
-void	macexpand(Sym*, char*);
-void	macinc(void);
-void	macprag(void);
-void	maclin(void);
-void	macif(int);
-void	macend(void);
-void	dodefine(char*);
-void	prfile(int32);
-void	linehist(char*, int);
-void	gethunk(void);
-void	yyerror(char*, ...);
-int	yyparse(void);
-void	setinclude(char*);
-int	assemble(char*);
diff --git a/src/cmd/9a/a.y b/src/cmd/9a/a.y
index ccc3bcc..db733c5 100644
--- a/src/cmd/9a/a.y
+++ b/src/cmd/9a/a.y
@@ -28,20 +28,24 @@
 // THE SOFTWARE.
 
 %{
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
+package main
+
+import (
+	"cmd/internal/asm"
+	"cmd/internal/obj"
+	. "cmd/internal/obj/ppc64"
+)
 %}
+
 %union
 {
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
+	sym *asm.Sym
+	lval int64
+	dval float64
+	sval string
+	addr obj.Addr
 }
+
 %left	'|'
 %left	'^'
 %left	'&'
@@ -50,7 +54,7 @@
 %left	'*' '/' '%'
 %token	<lval>	LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
 %token	<lval>	LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
-%token	<lval>	LNOP LEND LRETT LWORD LTEXT LGLOBL LDATA LRETRN
+%token	<lval>	LNOP LEND LRETT LWORD LTEXT LDATA LGLOBL LRETRN
 %token	<lval>	LCONST LSP LSB LFP LPC LCREG LFLUSH
 %token	<lval>	LREG LFREG LR LCR LF LFPSCR
 %token	<lval>	LLR LCTR LSPR LSPREG LSEG LMSR
@@ -66,34 +70,36 @@
 prog:
 |	prog
 	{
-		stmtline = lineno;
+		stmtline = asm.Lineno
 	}
 	line
 
 line:
 	LNAME ':'
 	{
-		$1 = labellookup($1);
-		if($1->type == LLAB && $1->value != pc)
-			yyerror("redeclaration of %s", $1->labelname);
-		$1->type = LLAB;
-		$1->value = pc;
+		$1 = asm.LabelLookup($1);
+		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
+			yyerror("redeclaration of %s", $1.Labelname)
+		}
+		$1.Type = LLAB;
+		$1.Value = int64(asm.PC);
 	}
 	line
 |	LNAME '=' expr ';'
 	{
-		$1->type = LVAR;
-		$1->value = $3;
+		$1.Type = LVAR;
+		$1.Value = $3;
 	}
 |	LVAR '=' expr ';'
 	{
-		if($1->value != $3)
-			yyerror("redeclaration of %s", $1->name);
-		$1->value = $3;
+		if $1.Value != $3 {
+			yyerror("redeclaration of %s", $1.Name)
+		}
+		$1.Value = $3;
 	}
 |	LSCHED ';'
 	{
-		nosched = $1;
+		nosched = int($1);
 	}
 |	';'
 |	inst ';'
@@ -105,122 +111,122 @@
  */
 	LMOVW rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW addr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW regaddr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVB rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVB addr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVB regaddr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * load floats
  */
 |	LFMOV addr ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFMOV regaddr ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFMOV fimm ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFMOV freg ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFMOV freg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFMOV freg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * store ints and bytes
  */
 |	LMOVW rreg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW rreg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVB rreg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVB rreg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * store floats
  */
 |	LMOVW freg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW freg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * floating point status
  */
 |	LMOVW fpscr ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW freg ','  fpscr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW freg ',' imm ',' fpscr
 	{
-		outgcode($1, &$2, 0, &$4, &$6);
+		outgcode(int($1), &$2, 0, &$4, &$6);
 	}
 |	LMOVW fpscr ',' creg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMTFSB imm ',' con
 	{
-		outcode($1, &$2, $4, &nullgen);
+		outcode(int($1), &$2, int($4), &nullgen);
 	}
 /*
  * field moves (mtcrf)
  */
 |	LMOVW rreg ',' imm ',' lcr
 	{
-		outgcode($1, &$2, 0, &$4, &$6);
+		outgcode(int($1), &$2, 0, &$4, &$6);
 	}
 |	LMOVW rreg ',' creg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW rreg ',' lcr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * integer operations
@@ -230,84 +236,84 @@
  */
 |	LADDW rreg ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 |	LADDW imm ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 |	LADDW rreg ',' imm ',' rreg
 	{
-		outgcode($1, &$2, 0, &$4, &$6);
+		outgcode(int($1), &$2, 0, &$4, &$6);
 	}
 |	LADDW rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LADDW imm ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LLOGW rreg ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 |	LLOGW rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LSHW rreg ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 |	LSHW rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LSHW imm ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 |	LSHW imm ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LABS rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LABS rreg
 	{
-		outcode($1, &$2, 0, &$2);
+		outcode(int($1), &$2, 0, &$2);
 	}
 /*
  * multiply-accumulate
  */
 |	LMA rreg ',' sreg ',' rreg
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 /*
  * move immediate: macro for cau+or, addi, addis, and other combinations
  */
 |	LMOVW imm ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW ximm ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * condition register operations
  */
 |	LCROP cbit ',' cbit
 	{
-		outcode($1, &$2, $4.reg, &$4);
+		outcode(int($1), &$2, int($4.Reg), &$4);
 	}
 |	LCROP cbit ',' con ',' cbit
 	{
-		outcode($1, &$2, $4, &$6);
+		outcode(int($1), &$2, int($4), &$6);
 	}
 /*
  * condition register moves
@@ -315,35 +321,35 @@
  */
 |	LMOVW creg ',' creg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW psr ',' creg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW lcr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW psr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW xlreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW rreg ',' xlreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW creg ',' psr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVW rreg ',' psr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * branch, branch conditional
@@ -352,170 +358,170 @@
  */
 |	LBRA rel
 	{
-		outcode($1, &nullgen, 0, &$2);
+		outcode(int($1), &nullgen, 0, &$2);
 	}
 |	LBRA addr
 	{
-		outcode($1, &nullgen, 0, &$2);
+		outcode(int($1), &nullgen, 0, &$2);
 	}
 |	LBRA '(' xlreg ')'
 	{
-		outcode($1, &nullgen, 0, &$3);
+		outcode(int($1), &nullgen, 0, &$3);
 	}
 |	LBRA ',' rel
 	{
-		outcode($1, &nullgen, 0, &$3);
+		outcode(int($1), &nullgen, 0, &$3);
 	}
 |	LBRA ',' addr
 	{
-		outcode($1, &nullgen, 0, &$3);
+		outcode(int($1), &nullgen, 0, &$3);
 	}
 |	LBRA ',' '(' xlreg ')'
 	{
-		outcode($1, &nullgen, 0, &$4);
+		outcode(int($1), &nullgen, 0, &$4);
 	}
 |	LBRA creg ',' rel
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LBRA creg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LBRA creg ',' '(' xlreg ')'
 	{
-		outcode($1, &$2, 0, &$5);
+		outcode(int($1), &$2, 0, &$5);
 	}
 |	LBRA con ',' rel
 	{
-		outcode($1, &nullgen, $2, &$4);
+		outcode(int($1), &nullgen, int($2), &$4);
 	}
 |	LBRA con ',' addr
 	{
-		outcode($1, &nullgen, $2, &$4);
+		outcode(int($1), &nullgen, int($2), &$4);
 	}
 |	LBRA con ',' '(' xlreg ')'
 	{
-		outcode($1, &nullgen, $2, &$5);
+		outcode(int($1), &nullgen, int($2), &$5);
 	}
 |	LBRA con ',' con ',' rel
 	{
-		Addr g;
+		var g obj.Addr
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = $2;
-		outcode($1, &g, REG_R0+$4, &$6);
+		g.Type = obj.TYPE_CONST;
+		g.Offset = $2;
+		outcode(int($1), &g, int(REG_R0+$4), &$6);
 	}
 |	LBRA con ',' con ',' addr
 	{
-		Addr g;
+		var g obj.Addr
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = $2;
-		outcode($1, &g, REG_R0+$4, &$6);
+		g.Type = obj.TYPE_CONST;
+		g.Offset = $2;
+		outcode(int($1), &g, int(REG_R0+$4), &$6);
 	}
 |	LBRA con ',' con ',' '(' xlreg ')'
 	{
-		Addr g;
+		var g obj.Addr
 		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = $2;
-		outcode($1, &g, REG_R0+$4, &$7);
+		g.Type = obj.TYPE_CONST;
+		g.Offset = $2;
+		outcode(int($1), &g, int(REG_R0+$4), &$7);
 	}
 /*
  * conditional trap
  */
 |	LTRAP rreg ',' sreg
 	{
-		outcode($1, &$2, $4, &nullgen);
+		outcode(int($1), &$2, int($4), &nullgen);
 	}
 |	LTRAP imm ',' sreg
 	{
-		outcode($1, &$2, $4, &nullgen);
+		outcode(int($1), &$2, int($4), &nullgen);
 	}
 |	LTRAP rreg comma
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 |	LTRAP comma
 	{
-		outcode($1, &nullgen, 0, &nullgen);
+		outcode(int($1), &nullgen, 0, &nullgen);
 	}
 /*
  * floating point operate
  */
 |	LFCONV freg ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFADD freg ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFADD freg ',' freg ',' freg
 	{
-		outcode($1, &$2, $4.reg, &$6);
+		outcode(int($1), &$2, int($4.Reg), &$6);
 	}
 |	LFMA freg ',' freg ',' freg ',' freg
 	{
-		outgcode($1, &$2, $4.reg, &$6, &$8);
+		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
 	}
 |	LFCMP freg ',' freg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LFCMP freg ',' freg ',' creg
 	{
-		outcode($1, &$2, $6.reg, &$4);
+		outcode(int($1), &$2, int($6.Reg), &$4);
 	}
 /*
  * CMP
  */
 |	LCMP rreg ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LCMP rreg ',' imm
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LCMP rreg ',' rreg ',' creg
 	{
-		outcode($1, &$2, $6.reg, &$4);
+		outcode(int($1), &$2, int($6.Reg), &$4);
 	}
 |	LCMP rreg ',' imm ',' creg
 	{
-		outcode($1, &$2, $6.reg, &$4);
+		outcode(int($1), &$2, int($6.Reg), &$4);
 	}
 /*
  * rotate and mask
  */
 |	LRLWM  imm ',' rreg ',' imm ',' rreg
 	{
-		outgcode($1, &$2, $4.reg, &$6, &$8);
+		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
 	}
 |	LRLWM  imm ',' rreg ',' mask ',' rreg
 	{
-		outgcode($1, &$2, $4.reg, &$6, &$8);
+		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
 	}
 |	LRLWM  rreg ',' rreg ',' imm ',' rreg
 	{
-		outgcode($1, &$2, $4.reg, &$6, &$8);
+		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
 	}
 |	LRLWM  rreg ',' rreg ',' mask ',' rreg
 	{
-		outgcode($1, &$2, $4.reg, &$6, &$8);
+		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
 	}
 /*
  * load/store multiple
  */
 |	LMOVMW addr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LMOVMW rreg ',' addr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * various indexed load/store
@@ -523,112 +529,115 @@
  */
 |	LXLD regaddr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LXLD regaddr ',' imm ',' rreg
 	{
-		outgcode($1, &$2, 0, &$4, &$6);
+		outgcode(int($1), &$2, 0, &$4, &$6);
 	}
 |	LXST rreg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LXST rreg ',' imm ',' regaddr
 	{
-		outgcode($1, &$2, 0, &$4, &$6);
+		outgcode(int($1), &$2, 0, &$4, &$6);
 	}
 |	LXMV regaddr ',' rreg
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LXMV rreg ',' regaddr
 	{
-		outcode($1, &$2, 0, &$4);
+		outcode(int($1), &$2, 0, &$4);
 	}
 |	LXOP regaddr
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 /*
  * NOP
  */
 |	LNOP comma
 	{
-		outcode($1, &nullgen, 0, &nullgen);
+		outcode(int($1), &nullgen, 0, &nullgen);
 	}
 |	LNOP rreg comma
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 |	LNOP freg comma
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 |	LNOP ',' rreg
 	{
-		outcode($1, &nullgen, 0, &$3);
+		outcode(int($1), &nullgen, 0, &$3);
 	}
 |	LNOP ',' freg
 	{
-		outcode($1, &nullgen, 0, &$3);
+		outcode(int($1), &nullgen, 0, &$3);
 	}
 |	LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 /*
  * word
  */
 |	LWORD imm comma
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 |	LWORD ximm comma
 	{
-		outcode($1, &$2, 0, &nullgen);
+		outcode(int($1), &$2, 0, &nullgen);
 	}
 /*
  * PCDATA
  */
 |	LPCDAT imm ',' imm
 	{
-		if($2.type != TYPE_CONST || $4.type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
-		outcode($1, &$2, 0, &$4);
+		if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
+			yyerror("arguments to PCDATA must be integer constants")
+		}
+		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * FUNCDATA
  */
 |	LFUNCDAT imm ',' addr
 	{
-		if($2.type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if($4.type != NAME_EXTERN && $4.type != NAME_STATIC && $4.type != TYPE_MEM)
-			yyerror("value for FUNCDATA must be symbol reference");
- 		outcode($1, &$2, 0, &$4);
+		if $2.Type != obj.TYPE_CONST {
+			yyerror("index for FUNCDATA must be integer constant")
+		}
+		if $4.Type != obj.TYPE_MEM || ($4.Name != obj.NAME_EXTERN && $4.Name != obj.NAME_STATIC) {
+			yyerror("value for FUNCDATA must be symbol reference")
+		}
+ 		outcode(int($1), &$2, 0, &$4);
 	}
 /*
  * END
  */
 |	LEND comma
 	{
-		outcode($1, &nullgen, 0, &nullgen);
+		outcode(int($1), &nullgen, 0, &nullgen);
 	}
 /*
  * TEXT
  */
 |	LTEXT name ',' '$' textsize
 	{
-		settext($2.sym);
-		outcode($1, &$2, 0, &$5);
+		asm.Settext($2.Sym);
+		outcode(int($1), &$2, 0, &$5);
 	}
 |	LTEXT name ',' con ',' '$' textsize
 	{
-		settext($2.sym);
-		outcode($1, &$2, 0, &$7);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym);
+		outcode(int($1), &$2, int($4), &$7);
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 /*
@@ -636,16 +645,16 @@
  */
 |	LGLOBL name ',' imm
 	{
-		settext($2.sym);
-		outcode($1, &$2, 0, &$4);
+		asm.Settext($2.Sym)
+		outcode(int($1), &$2, 0, &$4)
 	}
 |	LGLOBL name ',' con ',' imm
 	{
-		settext($2.sym);
-		outcode($1, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		asm.Settext($2.Sym)
+		outcode(int($1), &$2, 0, &$6)
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 
@@ -654,26 +663,26 @@
  */
 |	LDATA name '/' con ',' imm
 	{
-		outcode($1, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		outcode(int($1), &$2, 0, &$6);
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 |	LDATA name '/' con ',' ximm
 	{
-		outcode($1, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		outcode(int($1), &$2, 0, &$6);
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 |	LDATA name '/' con ',' fimm
 	{
-		outcode($1, &$2, 0, &$6);
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = $4;
+		outcode(int($1), &$2, 0, &$6);
+		if asm.Pass > 1 {
+			lastpc.From3.Type = obj.TYPE_CONST
+			lastpc.From3.Offset = $4
 		}
 	}
 /*
@@ -681,32 +690,33 @@
  */
 |	LRETRN	comma
 	{
-		outcode($1, &nullgen, 0, &nullgen);
+		outcode(int($1), &nullgen, 0, &nullgen);
 	}
 
 rel:
 	con '(' LPC ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1 + pc;
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1 + int64(asm.PC);
 	}
 |	LNAME offset
 	{
-		$1 = labellookup($1);
+		$1 = asm.LabelLookup($1);
 		$$ = nullgen;
-		if(pass == 2 && $1->type != LLAB)
-			yyerror("undefined label: %s", $1->labelname);
-		$$.type = TYPE_BRANCH;
-		$$.offset = $1->value + $2;
+		if asm.Pass == 2 && $1.Type != LLAB {
+			yyerror("undefined label: %s", $1.Labelname)
+		}
+		$$.Type = obj.TYPE_BRANCH;
+		$$.Offset = $1.Value + $2;
 	}
 
 rreg:
 	sreg
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 xlreg:
@@ -717,48 +727,49 @@
 	LLR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 lcr:
 	LCR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;	/* whole register */
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);	/* whole register */
 	}
 
 ctr:
 	LCTR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 msr:
 	LMSR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1)
 	}
 
 psr:
 	LSPREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 |	LSPR '(' con ')'
 	{
-		if($3 < 0 || $3 >= 1024)
-			yyerror("SPR/DCR out of range");
+		if $3 < 0 || $3 >= 1024 {
+			yyerror("SPR/DCR out of range")
+		}
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1 + $3;
+		$$.Type = obj.TYPE_REG
+		$$.Reg = int16($1 + $3);
 	}
 |	msr
 
@@ -766,137 +777,140 @@
 	LFPSCR
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 freg:
 	LFREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 |	LF '(' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = REG_F0 + $3;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16(REG_F0 + $3);
 	}
 
 creg:
 	LCREG
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 |	LCR '(' con ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = REG_C0 + $3;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16(REG_C0 + $3);
 	}
 
 
 cbit:	con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_REG;
-		$$.reg = $1;
+		$$.Type = obj.TYPE_REG;
+		$$.Reg = int16($1);
 	}
 
 mask:
 	con ',' con
 	{
-		int mb, me;
-		uint32 v;
+		var mb, me int
+		var v uint32
 
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		mb = $1;
-		me = $3;
+		$$.Type = obj.TYPE_CONST;
+		mb = int($1);
+		me = int($3);
 		if(mb < 0 || mb > 31 || me < 0 || me > 31){
 			yyerror("illegal mask start/end value(s)");
-			mb = me = 0;
+			mb = 0
+			me = 0;
 		}
-		if(mb <= me)
-			v = ((uint32)~0L>>mb) & (~0L<<(31-me));
-		else
-			v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
-		$$.offset = v;
+		if mb <= me {
+			v = (^uint32(0)>>uint(mb)) & (^uint32(0)<<uint(31-me))
+		} else {
+			v = (^uint32(0)>>uint(me+1)) & (^uint32(0)<<uint(31-(mb-1)))
+		}
+		$$.Offset = int64(v);
 	}
 
 textsize:
 	LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = int64($1)
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	'-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = ArgsSizeUnknown;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -int64($2)
+		$$.U.Argsize = obj.ArgsSizeUnknown;
 	}
 |	LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = $1;
-		$$.u.argsize = $3;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = int64($1)
+		$$.U.Argsize = int32($3);
 	}
 |	'-' LCONST '-' LCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_TEXTSIZE;
-		$$.offset = -$2;
-		$$.u.argsize = $4;
+		$$.Type = obj.TYPE_TEXTSIZE;
+		$$.Offset = -int64($2)
+		$$.U.Argsize = int32($4);
 	}
 
 ximm:
 	'$' addr
 	{
 		$$ = $2;
-		$$.type = TYPE_ADDR;
+		$$.Type = obj.TYPE_ADDR;
 	}
 |	'$' LSCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_SCONST;
-		memcpy($$.u.sval, $2, sizeof($$.u.sval));
+		$$.Type = obj.TYPE_SCONST;
+		$$.U.Sval = $2
 	}
 
 fimm:
 	'$' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = $2;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = $2;
 	}
 |	'$' '-' LFCONST
 	{
 		$$ = nullgen;
-		$$.type = TYPE_FCONST;
-		$$.u.dval = -$3;
+		$$.Type = obj.TYPE_FCONST;
+		$$.U.Dval = -$3;
 	}
 
 imm:	'$' con
 	{
 		$$ = nullgen;
-		$$.type = TYPE_CONST;
-		$$.offset = $2;
+		$$.Type = obj.TYPE_CONST;
+		$$.Offset = $2;
 	}
 
 sreg:
 	LREG
 |	LR '(' con ')'
 	{
-		if($$ < 0 || $$ >= NREG)
-			print("register value out of range\n");
+		if $$ < 0 || $$ >= NREG {
+			print("register value out of range\n")
+		}
 		$$ = REG_R0 + $3;
 	}
 
@@ -904,17 +918,17 @@
 	'(' sreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
-		$$.offset = 0;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($2);
+		$$.Offset = 0;
 	}
 |	'(' sreg '+' sreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $2;
-		$$.scale = $4;
-		$$.offset = 0;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($2);
+		$$.Scale = int8($4);
+		$$.Offset = 0;
 	}
 
 addr:
@@ -922,35 +936,35 @@
 |	con '(' sreg ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.reg = $3;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM;
+		$$.Reg = int16($3);
+		$$.Offset = $1;
 	}
 
 name:
 	con '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $3;
-		$$.sym = nil;
-		$$.offset = $1;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = int8($3);
+		$$.Sym = nil;
+		$$.Offset = $1;
 	}
 |	LNAME offset '(' pointer ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = $4;
-		$$.sym = linklookup(ctxt, $1->name, 0);
-		$$.offset = $2;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = int8($4);
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
+		$$.Offset = $2;
 	}
 |	LNAME '<' '>' offset '(' LSB ')'
 	{
 		$$ = nullgen;
-		$$.type = TYPE_MEM;
-		$$.name = NAME_STATIC;
-		$$.sym = linklookup(ctxt, $1->name, 1);
-		$$.offset = $4;
+		$$.Type = obj.TYPE_MEM;
+		$$.Name = obj.NAME_STATIC;
+		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
+		$$.Offset = $4;
 	}
 
 comma:
@@ -978,7 +992,7 @@
 	LCONST
 |	LVAR
 	{
-		$$ = $1->value;
+		$$ = $1.Value;
 	}
 |	'-' con
 	{
@@ -990,7 +1004,7 @@
 	}
 |	'~' con
 	{
-		$$ = ~$2;
+		$$ = ^$2;
 	}
 |	'(' expr ')'
 	{
@@ -1021,11 +1035,11 @@
 	}
 |	expr '<' '<' expr
 	{
-		$$ = $1 << $4;
+		$$ = $1 << uint($4);
 	}
 |	expr '>' '>' expr
 	{
-		$$ = $1 >> $4;
+		$$ = $1 >> uint($4);
 	}
 |	expr '&' expr
 	{
diff --git a/src/cmd/9a/doc.go b/src/cmd/9a/doc.go
deleted file mode 100644
index f6eed6d..0000000
--- a/src/cmd/9a/doc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
-
-/*
-
-9a is a version of the Plan 9 assembler.  The original is documented at
-
-	http://plan9.bell-labs.com/magic/man2html/1/8a
-
-Go-specific considerations are documented at
-
-	http://golang.org/doc/asm
-
-Its target architecture is 64-bit PowerPC and Power Architecture processors,
-referred to by these tools as ppc64 (big endian) or ppc64le (little endian).
-
-*/
-package main
diff --git a/src/cmd/9a/lex.c b/src/cmd/9a/lex.c
deleted file mode 100644
index ad55237..0000000
--- a/src/cmd/9a/lex.c
+++ /dev/null
@@ -1,726 +0,0 @@
-// cmd/9a/lex.c from Vita Nuova.
-//
-//	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-2008 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-2008 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.
-
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "a.h"
-#include "y.tab.h"
-
-enum
-{
-	Plan9	= 1<<0,
-	Unix	= 1<<1,
-	Windows	= 1<<2,
-};
-
-int
-systemtype(int sys)
-{
-#ifdef _WIN32
-	return sys&Windows;
-#else
-	return sys&Plan9;
-#endif
-}
-
-int
-pathchar(void)
-{
-	return '/';
-}
-
-int
-Lconv(Fmt *fp)
-{
-	return linklinefmt(ctxt, fp);
-}
-
-void
-dodef(char *p)
-{
-	if(nDlist%8 == 0)
-		Dlist = allocn(Dlist, nDlist*sizeof(char *),
-			8*sizeof(char *));
-	Dlist[nDlist++] = p;
-}
-
-LinkArch*       thelinkarch = &linkppc64;
-
-void
-usage(void)
-{
-	print("usage: %ca [options] file.c...\n", thechar);
-	flagprint(1);
-	errorexit();
-}
-
-void
-main(int argc, char *argv[])
-{
-	char *p;
-
-	thechar = '9';
-	thestring = "ppc64";
-
-	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
-	// but not other values.	
-	p = getgoarch();
-	if(strncmp(p, thestring, strlen(thestring)) != 0)
-		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
-	if(strcmp(p, "ppc64le") == 0)
-		thelinkarch = &linkppc64le;
-
-	ctxt = linknew(thelinkarch);
-	ctxt->diag = yyerror;
-	ctxt->bso = &bstdout;
-	ctxt->enforce_data_order = 1;
-	Binit(&bstdout, 1, OWRITE);
-	listinit9();
-	fmtinstall('L', Lconv);
-
-	ensuresymb(NSYMB);
-	memset(debug, 0, sizeof(debug));
-	cinit();
-	outfile = 0;
-	setinclude(".");
-
-	flagfn1("D", "name[=value]: add #define", dodef);
-	flagfn1("I", "dir: add dir to include path", setinclude);
-	flagcount("S", "print assembly and machine code", &debug['S']);
-	flagcount("m", "debug preprocessor macros", &debug['m']);
-	flagstr("o", "file: set output file", &outfile);
-	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
-
-	flagparse(&argc, &argv, usage);
-	ctxt->debugasm = debug['S'];
-
-	if(argc < 1)
-		usage();
-	if(argc > 1){
-		print("can't assemble multiple files\n");
-		errorexit();
-	}
-
-	if(assemble(argv[0]))
-		errorexit();
-	Bflush(&bstdout);
-	if(nerrors > 0)
-		errorexit();
-	exits(0);
-}
-
-int
-assemble(char *file)
-{
-	char *ofile, *p;
-	int i, of;
-
-	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
-	strcpy(ofile, file);
-	p = utfrrune(ofile, pathchar());
-	if(p) {
-		include[0] = ofile;
-		*p++ = 0;
-	} else
-		p = ofile;
-	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
-			p = utfrrune(outfile, '.');
-			if(p)
-				if(p[1] == 's' && p[2] == 0)
-					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
-		} else
-			outfile = "/dev/null";
-	}
-
-	of = create(outfile, OWRITE, 0664);
-	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
-		errorexit();
-	}
-	Binit(&obuf, of, OWRITE);
-	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
-	Bprint(&obuf, "!\n");
-
-	for(pass = 1; pass <= 2; pass++) {
-		nosched = 0;
-		pinit(file);
-		for(i=0; i<nDlist; i++)
-			dodefine(Dlist[i]);
-		yyparse();
-		cclean();
-		if(nerrors)
-			return nerrors;
-	}
-
-	writeobj(ctxt, &obuf);
-	Bflush(&obuf);
-	return 0;
-}
-
-struct
-{
-	char	*name;
-	ushort	type;
-	ushort	value;
-} itab[] =
-{
-	"SP",		LSP,	NAME_AUTO,
-	"SB",		LSB,	NAME_EXTERN,
-	"FP",		LFP,	NAME_PARAM,
-	"PC",		LPC,	TYPE_BRANCH,
-
-	"LR",		LLR,	REG_LR,
-	"CTR",		LCTR,	REG_CTR,
-
-	"XER",		LSPREG,	REG_XER,
-	"MSR",		LMSR,	REG_MSR,
-	"FPSCR",	LFPSCR,	REG_FPSCR,
-	"SPR",		LSPR,	REG_SPR0,
-	"DCR",		LSPR,	REG_DCR0,
-
-	"CR",		LCR,	REG_CR,
-	"CR0",		LCREG,	REG_C0,
-	"CR1",		LCREG,	REG_C1,
-	"CR2",		LCREG,	REG_C2,
-	"CR3",		LCREG,	REG_C3,
-	"CR4",		LCREG,	REG_C4,
-	"CR5",		LCREG,	REG_C5,
-	"CR6",		LCREG,	REG_C6,
-	"CR7",		LCREG,	REG_C7,
-
-	"R",		LR,	0,
-	"R0",		LREG,	REG_R0,
-	"R1",		LREG,	REG_R1,
-	"R2",		LREG,	REG_R2,
-	"R3",		LREG,	REG_R3,
-	"R4",		LREG,	REG_R4,
-	"R5",		LREG,	REG_R5,
-	"R6",		LREG,	REG_R6,
-	"R7",		LREG,	REG_R7,
-	"R8",		LREG,	REG_R8,
-	"R9",		LREG,	REG_R9,
-	"R10",		LREG,	REG_R10,
-	"R11",		LREG,	REG_R11,
-	"R12",		LREG,	REG_R12,
-	"R13",		LREG,	REG_R13,
-	"R14",		LREG,	REG_R14,
-	"R15",		LREG,	REG_R15,
-	"R16",		LREG,	REG_R16,
-	"R17",		LREG,	REG_R17,
-	"R18",		LREG,	REG_R18,
-	"R19",		LREG,	REG_R19,
-	"R20",		LREG,	REG_R20,
-	"R21",		LREG,	REG_R21,
-	"R22",		LREG,	REG_R22,
-	"R23",		LREG,	REG_R23,
-	"R24",		LREG,	REG_R24,
-	"R25",		LREG,	REG_R25,
-	"R26",		LREG,	REG_R26,
-	"R27",		LREG,	REG_R27,
-	"R28",		LREG,	REG_R28,
-	"R29",		LREG,	REG_R29,
-	"g",		LREG,	REG_R30, // avoid unintentionally clobbering g using R30
-	"R31",		LREG,	REG_R31,
-
-	"F",		LF,	0,
-	"F0",		LFREG,	REG_F0,
-	"F1",		LFREG,	REG_F1,
-	"F2",		LFREG,	REG_F2,
-	"F3",		LFREG,	REG_F3,
-	"F4",		LFREG,	REG_F4,
-	"F5",		LFREG,	REG_F5,
-	"F6",		LFREG,	REG_F6,
-	"F7",		LFREG,	REG_F7,
-	"F8",		LFREG,	REG_F8,
-	"F9",		LFREG,	REG_F9,
-	"F10",		LFREG,	REG_F10,
-	"F11",		LFREG,	REG_F11,
-	"F12",		LFREG,	REG_F12,
-	"F13",		LFREG,	REG_F13,
-	"F14",		LFREG,	REG_F14,
-	"F15",		LFREG,	REG_F15,
-	"F16",		LFREG,	REG_F16,
-	"F17",		LFREG,	REG_F17,
-	"F18",		LFREG,	REG_F18,
-	"F19",		LFREG,	REG_F19,
-	"F20",		LFREG,	REG_F20,
-	"F21",		LFREG,	REG_F21,
-	"F22",		LFREG,	REG_F22,
-	"F23",		LFREG,	REG_F23,
-	"F24",		LFREG,	REG_F24,
-	"F25",		LFREG,	REG_F25,
-	"F26",		LFREG,	REG_F26,
-	"F27",		LFREG,	REG_F27,
-	"F28",		LFREG,	REG_F28,
-	"F29",		LFREG,	REG_F29,
-	"F30",		LFREG,	REG_F30,
-	"F31",		LFREG,	REG_F31,
-
-	"CREQV",	LCROP, ACREQV,
-	"CRXOR",	LCROP, ACRXOR,
-	"CRAND",	LCROP, ACRAND,
-	"CROR",		LCROP, ACROR,
-	"CRANDN",	LCROP, ACRANDN,
-	"CRORN",	LCROP, ACRORN,
-	"CRNAND",	LCROP, ACRNAND,
-	"CRNOR",	LCROP, ACRNOR,
-
-	"ADD",		LADDW, AADD,
-	"ADDV",		LADDW, AADDV,
-	"ADDCC",	LADDW, AADDCC,
-	"ADDVCC",	LADDW, AADDVCC,
-	"ADDC",		LADDW, AADDC,
-	"ADDCV",	LADDW, AADDCV,
-	"ADDCCC",	LADDW, AADDCCC,
-	"ADDCVCC",	LADDW, AADDCVCC,
-	"ADDE",		LLOGW, AADDE,
-	"ADDEV",	LLOGW, AADDEV,
-	"ADDECC",	LLOGW, AADDECC,
-	"ADDEVCC",	LLOGW, AADDEVCC,
-
-	"ADDME",	LABS, AADDME,
-	"ADDMEV",	LABS, AADDMEV,
-	"ADDMECC",	LABS, AADDMECC,
-	"ADDMEVCC",	LABS, AADDMEVCC,
-	"ADDZE",	LABS, AADDZE,
-	"ADDZEV",	LABS, AADDZEV,
-	"ADDZECC",	LABS, AADDZECC,
-	"ADDZEVCC",	LABS, AADDZEVCC,
-
-	"SUB",		LADDW, ASUB,
-	"SUBV",		LADDW, ASUBV,
-	"SUBCC",	LADDW, ASUBCC,
-	"SUBVCC",	LADDW, ASUBVCC,
-	"SUBE",		LLOGW, ASUBE,
-	"SUBECC",	LLOGW, ASUBECC,
-	"SUBEV",	LLOGW, ASUBEV,
-	"SUBEVCC",	LLOGW, ASUBEVCC,
-	"SUBC",		LADDW, ASUBC,
-	"SUBCCC",	LADDW, ASUBCCC,
-	"SUBCV",	LADDW, ASUBCV,
-	"SUBCVCC",	LADDW, ASUBCVCC,
-
-	"SUBME",	LABS, ASUBME,
-	"SUBMEV",	LABS, ASUBMEV,
-	"SUBMECC",	LABS, ASUBMECC,
-	"SUBMEVCC",	LABS, ASUBMEVCC,
-	"SUBZE",	LABS, ASUBZE,
-	"SUBZEV",	LABS, ASUBZEV,
-	"SUBZECC",	LABS, ASUBZECC,
-	"SUBZEVCC",	LABS, ASUBZEVCC,
-
-	"AND",		LADDW, AAND,
-	"ANDCC",	LADDW, AANDCC,	/* includes andil & andiu */
-	"ANDN",		LLOGW, AANDN,
-	"ANDNCC",	LLOGW, AANDNCC,
-	"EQV",		LLOGW, AEQV,
-	"EQVCC",	LLOGW, AEQVCC,
-	"NAND",		LLOGW, ANAND,
-	"NANDCC",	LLOGW, ANANDCC,
-	"NOR",		LLOGW, ANOR,
-	"NORCC",	LLOGW, ANORCC,
-	"OR",		LADDW, AOR,	/* includes oril & oriu */
-	"ORCC",		LADDW, AORCC,
-	"ORN",		LLOGW, AORN,
-	"ORNCC",	LLOGW, AORNCC,
-	"XOR",		LADDW, AXOR,	/* includes xoril & xoriu */
-	"XORCC",	LLOGW, AXORCC,
-
-	"EXTSB",	LABS,	AEXTSB,
-	"EXTSBCC",	LABS,	AEXTSBCC,
-	"EXTSH",	LABS, AEXTSH,
-	"EXTSHCC",	LABS, AEXTSHCC,
-
-	"CNTLZW",	LABS, ACNTLZW,
-	"CNTLZWCC",	LABS, ACNTLZWCC,
-
-	"RLWMI",	LRLWM, ARLWMI,
-	"RLWMICC",	LRLWM, ARLWMICC,
-	"RLWNM",	LRLWM, ARLWNM,
-	"RLWNMCC", LRLWM, ARLWNMCC,
-
-	"SLW",		LSHW, ASLW,
-	"SLWCC",	LSHW, ASLWCC,
-	"SRW",		LSHW, ASRW,
-	"SRWCC",	LSHW, ASRWCC,
-	"SRAW",		LSHW, ASRAW,
-	"SRAWCC",	LSHW, ASRAWCC,
-
-	"BR",		LBRA, ABR,
-	"BC",		LBRA, ABC,
-	"BCL",		LBRA, ABC,
-	"BL",		LBRA, ABL,
-	"BEQ",		LBRA, ABEQ,
-	"BNE",		LBRA, ABNE,
-	"BGT",		LBRA, ABGT,
-	"BGE",		LBRA, ABGE,
-	"BLT",		LBRA, ABLT,
-	"BLE",		LBRA, ABLE,
-	"BVC",		LBRA, ABVC,
-	"BVS",		LBRA, ABVS,
-
-	"CMP",		LCMP, ACMP,
-	"CMPU",		LCMP, ACMPU,
-	"CMPW",		LCMP, ACMPW,
-	"CMPWU",	LCMP, ACMPWU,
-
-	"DIVW",		LLOGW, ADIVW,
-	"DIVWV",	LLOGW, ADIVWV,
-	"DIVWCC",	LLOGW, ADIVWCC,
-	"DIVWVCC",	LLOGW, ADIVWVCC,
-	"DIVWU",	LLOGW, ADIVWU,
-	"DIVWUV",	LLOGW, ADIVWUV,
-	"DIVWUCC",	LLOGW, ADIVWUCC,
-	"DIVWUVCC",	LLOGW, ADIVWUVCC,
-
-	"FABS",		LFCONV,	AFABS,
-	"FABSCC",	LFCONV,	AFABSCC,
-	"FNEG",		LFCONV,	AFNEG,
-	"FNEGCC",	LFCONV,	AFNEGCC,
-	"FNABS",	LFCONV,	AFNABS,
-	"FNABSCC",	LFCONV,	AFNABSCC,
-
-	"FADD",		LFADD,	AFADD,
-	"FADDCC",	LFADD,	AFADDCC,
-	"FSUB",		LFADD,  AFSUB,
-	"FSUBCC",	LFADD,	AFSUBCC,
-	"FMUL",		LFADD,	AFMUL,
-	"FMULCC",	LFADD,	AFMULCC,
-	"FDIV",		LFADD,	AFDIV,
-	"FDIVCC",	LFADD,	AFDIVCC,
-	"FRSP",		LFCONV,	AFRSP,
-	"FRSPCC",	LFCONV,	AFRSPCC,
-	"FCTIW",	LFCONV,	AFCTIW,
-	"FCTIWCC",	LFCONV,	AFCTIWCC,
-	"FCTIWZ",	LFCONV,	AFCTIWZ,
-	"FCTIWZCC",	LFCONV,	AFCTIWZCC,
-
-	"FMADD",	LFMA, AFMADD,
-	"FMADDCC",	LFMA, AFMADDCC,
-	"FMSUB",	LFMA, AFMSUB,
-	"FMSUBCC",	LFMA, AFMSUBCC,
-	"FNMADD",	LFMA, AFNMADD,
-	"FNMADDCC",	LFMA, AFNMADDCC,
-	"FNMSUB",	LFMA, AFNMSUB,
-	"FNMSUBCC",	LFMA, AFNMSUBCC,
-	"FMADDS",	LFMA, AFMADDS,
-	"FMADDSCC",	LFMA, AFMADDSCC,
-	"FMSUBS",	LFMA, AFMSUBS,
-	"FMSUBSCC",	LFMA, AFMSUBSCC,
-	"FNMADDS",	LFMA, AFNMADDS,
-	"FNMADDSCC",	LFMA, AFNMADDSCC,
-	"FNMSUBS",	LFMA, AFNMSUBS,
-	"FNMSUBSCC",	LFMA, AFNMSUBSCC,
-
-	"FCMPU",	LFCMP, AFCMPU,
-	"FCMPO",	LFCMP, AFCMPO,
-	"MTFSB0",	LMTFSB, AMTFSB0,
-	"MTFSB1",	LMTFSB,	AMTFSB1,
-
-	"FMOVD",	LFMOV, AFMOVD,
-	"FMOVS",	LFMOV, AFMOVS,
-	"FMOVDCC",	LFCONV,	AFMOVDCC,	/* fmr. */
-
-	"GLOBL",	LGLOBL, AGLOBL,
-
-	"MOVB",		LMOVB, AMOVB,
-	"MOVBZ",	LMOVB, AMOVBZ,
-	"MOVBU",	LMOVB, AMOVBU,
-	"MOVBZU", LMOVB, AMOVBZU,
-	"MOVH",		LMOVB, AMOVH,
-	"MOVHZ",	LMOVB, AMOVHZ,
-	"MOVHU",	LMOVB, AMOVHU,
-	"MOVHZU", LMOVB, AMOVHZU,
-	"MOVHBR", 	LXMV, AMOVHBR,
-	"MOVWBR",	LXMV, AMOVWBR,
-	"MOVW",		LMOVW, AMOVW,
-	"MOVWU",	LMOVW, AMOVWU,
-	"MOVMW",	LMOVMW, AMOVMW,
-	"MOVFL",	LMOVW,	AMOVFL,
-
-	"MULLW",	LADDW, AMULLW,		/* includes multiply immediate 10-139 */
-	"MULLWV",	LLOGW, AMULLWV,
-	"MULLWCC",	LLOGW, AMULLWCC,
-	"MULLWVCC",	LLOGW, AMULLWVCC,
-
-	"MULHW",	LLOGW, AMULHW,
-	"MULHWCC",	LLOGW, AMULHWCC,
-	"MULHWU",	LLOGW, AMULHWU,
-	"MULHWUCC",	LLOGW, AMULHWUCC,
-
-	"NEG",		LABS, ANEG,
-	"NEGV",		LABS, ANEGV,
-	"NEGCC",	LABS, ANEGCC,
-	"NEGVCC",	LABS, ANEGVCC,
-
-	"NOP",		LNOP, ANOP,	/* ori 0,0,0 */
-	"SYSCALL",	LNOP, ASYSCALL,
-	"UNDEF",	LNOP, AUNDEF,
-
-	"RET",		LRETRN, ARETURN,
-	"RETURN",	LRETRN, ARETURN,
-	"RFI",		LRETRN,	ARFI,
-	"RFCI",		LRETRN,	ARFCI,
-
-	"DATA",		LDATA, ADATA,
-	"END",		LEND, AEND,
-	"TEXT",		LTEXT, ATEXT,
-
-	/* 64-bit instructions */
-	"CNTLZD",	LABS,	ACNTLZD,
-	"CNTLZDCC",	LABS,	ACNTLZDCC,
-	"DIVD",	LLOGW,	ADIVD,
-	"DIVDCC",	LLOGW,	ADIVDCC,
-	"DIVDVCC",	LLOGW,	ADIVDVCC,
-	"DIVDV",	LLOGW,	ADIVDV,
-	"DIVDU",	LLOGW,	ADIVDU,
-	"DIVDUCC",	LLOGW,	ADIVDUCC,
-	"DIVDUVCC",	LLOGW,	ADIVDUVCC,
-	"DIVDUV",	LLOGW,	ADIVDUV,
-	"EXTSW",	LABS, AEXTSW,
-	"EXTSWCC",	LABS, AEXTSWCC,
-	"FCTID",	LFCONV,	AFCTID,
-	"FCTIDCC",	LFCONV,	AFCTIDCC,
-	"FCTIDZ",	LFCONV,	AFCTIDZ,
-	"FCTIDZCC",	LFCONV,	AFCTIDZCC,
-	"FCFID",	LFCONV,	AFCFID,
-	"FCFIDCC",	LFCONV,	AFCFIDCC,
-	"LDAR", LXLD, ALDAR,
-	"MOVD",	LMOVW,	AMOVD,
-	"MOVDU",	LMOVW,	AMOVDU,
-	"MOVWZ",	LMOVW,	AMOVWZ,
-	"MOVWZU",	LMOVW,	AMOVWZU,
-	"MULHD",	LLOGW,	AMULHD,
-	"MULHDCC",	LLOGW,	AMULHDCC,
-	"MULHDU",	LLOGW,	AMULHDU,
-	"MULHDUCC",	LLOGW,	AMULHDUCC,
-	"MULLD",	LADDW,	AMULLD,	/* includes multiply immediate? */
-	"MULLDCC",	LLOGW,	AMULLDCC,
-	"MULLDVCC",	LLOGW,	AMULLDVCC,
-	"MULLDV",	LLOGW,	AMULLDV,
-	"RFID",	LRETRN,	ARFID,
-	"HRFID", LRETRN, AHRFID,
-	"RLDMI",	LRLWM,	ARLDMI,
-	"RLDMICC",	LRLWM,	ARLDMICC,
-	"RLDC",	LRLWM,	ARLDC,
-	"RLDCCC",	LRLWM,	ARLDCCC,
-	"RLDCR",	LRLWM,	ARLDCR,
-	"RLDCRCC",	LRLWM,	ARLDCRCC,
-	"RLDCL",	LRLWM,	ARLDCL,
-	"RLDCLCC",	LRLWM,	ARLDCLCC,
-	"SLBIA",	LNOP,	ASLBIA,
-	"SLBIE",	LNOP,	ASLBIE,
-	"SLBMFEE",	LABS,	ASLBMFEE,
-	"SLBMFEV",	LABS,	ASLBMFEV,
-	"SLBMTE",	LABS,	ASLBMTE,
-	"SLD",	LSHW,	ASLD,
-	"SLDCC",	LSHW,	ASLDCC,
-	"SRD",	LSHW,	ASRD,
-	"SRAD",	LSHW,	ASRAD,
-	"SRADCC",	LSHW,	ASRADCC,
-	"SRDCC",	LSHW,	ASRDCC,
-	"STDCCC",	LXST,	ASTDCCC,
-	"TD",	LADDW,	ATD,
-
-	/* pseudo instructions */
-	"REM",	LLOGW,	AREM,
-	"REMCC",	LLOGW,	AREMCC,
-	"REMV",	LLOGW,	AREMV,
-	"REMVCC",	LLOGW,	AREMVCC,
-	"REMU",	LLOGW,	AREMU,
-	"REMUCC",	LLOGW,	AREMUCC,
-	"REMUV",	LLOGW,	AREMUV,
-	"REMUVCC",	LLOGW,	AREMUVCC,
-	"REMD",	LLOGW,	AREMD,
-	"REMDCC",	LLOGW,	AREMDCC,
-	"REMDV",	LLOGW,	AREMDV,
-	"REMDVCC",	LLOGW,	AREMDVCC,
-	"REMDU",	LLOGW,	AREMDU,
-	"REMDUCC",	LLOGW,	AREMDUCC,
-	"REMDUV",	LLOGW,	AREMDUV,
-	"REMDUVCC",	LLOGW,	AREMDUVCC,
-
-/* special instructions */
-	"DCBF",		LXOP,	ADCBF,
-	"DCBI",		LXOP,	ADCBI,
-	"DCBST",	LXOP,	ADCBST,
-	"DCBT",		LXOP,	ADCBT,
-	"DCBTST",	LXOP,	ADCBTST,
-	"DCBZ",		LXOP,	ADCBZ,
-	"ICBI",		LXOP,	AICBI,
-
-	"ECIWX",	LXLD,	AECIWX,
-	"ECOWX",	LXST,	AECOWX,
-	"LWAR", LXLD, ALWAR,
-	"LWAR", LXLD, ALWAR,
-	"STWCCC", LXST, ASTWCCC,
-	"EIEIO",	LRETRN,	AEIEIO,
-	"TLBIE",	LNOP,	ATLBIE,
-	"TLBIEL",	LNOP,	ATLBIEL,
-	"LSW",	LXLD, ALSW,
-	"STSW",	LXST, ASTSW,
-	
-	"ISYNC",	LRETRN, AISYNC,
-	"SYNC",		LRETRN, ASYNC,
-	"TLBSYNC",	LRETRN,	ATLBSYNC,
-	"PTESYNC",	LRETRN,	APTESYNC,
-/*	"TW",		LADDW,	ATW,*/
-
-	"WORD",		LWORD, AWORD,
-	"DWORD",	LWORD, ADWORD,
-	"SCHED",	LSCHED, 0,
-	"NOSCHED",	LSCHED,	0x80,
-
-	"PCDATA",	LPCDAT,	APCDATA,
-	"FUNCDATA",	LFUNCDAT,	AFUNCDATA,
-
-	0
-};
-
-void
-cinit(void)
-{
-	Sym *s;
-	int i;
-
-	nullgen.type = TYPE_NONE;
-	nullgen.name = NAME_NONE;
-	nullgen.reg = 0;
-	nullgen.scale = 0; // replaced Gen.xreg with Prog.scale
-
-	nerrors = 0;
-	iostack = I;
-	iofree = I;
-	peekc = IGN;
-	nhunk = 0;
-	for(i=0; i<NHASH; i++)
-		hash[i] = S;
-	for(i=0; itab[i].name; i++) {
-		s = slookup(itab[i].name);
-		s->type = itab[i].type;
-		s->value = itab[i].value;
-	}
-}
-
-void
-syminit(Sym *s)
-{
-
-	s->type = LNAME;
-	s->value = 0;
-}
-
-void
-cclean(void)
-{
-
-	outcode(AEND, &nullgen, 0, &nullgen);
-}
-
-void
-outcode(int a, Addr *g1, int reg, Addr *g2)
-{
-	Prog *p;
-	Plist *pl;
-
-	if(pass == 1)
-		goto out;
-
-	if(g1->scale != 0) {
-		if(reg != 0 || g2->scale != 0)
-			yyerror("bad addressing modes");
-		reg = g1->scale;
-	} else
-	if(g2->scale != 0) {
-		if(reg != 0)
-			yyerror("bad addressing modes");
-		reg = g2->scale;
-	}
-
-	p = emallocz(sizeof(Prog));
-	p->as = a;
-	p->lineno = stmtline;
-	if(nosched)
-		p->mark |= NOSCHED;
-	p->from = *g1;
-	p->reg = reg;
-	p->to = *g2;
-	p->pc = pc;
-
-	if(lastpc == nil) {
-		pl = linknewplist(ctxt);
-		pl->firstpc = p;
-	} else
-		lastpc->link = p;
-	lastpc = p;
-out:
-	if(a != AGLOBL && a != ADATA)
-		pc++;
-}
-
-void
-outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
-{
-	Prog *p;
-	Plist *pl;
-
-	if(pass == 1)
-		goto out;
-
-	p = emallocz(sizeof(Prog));
-	p->as = a;
-	p->lineno = stmtline;
-	if(nosched)
-		p->mark |= NOSCHED;
-	p->from = *g1;
-	p->reg = reg;
-	p->from3 = *g2;
-	p->to = *g3;
-	p->pc = pc;
-
-	if(lastpc == nil) {
-		pl = linknewplist(ctxt);
-		pl->firstpc = p;
-	} else
-		lastpc->link = p;
-	lastpc = p;
-out:
-	if(a != AGLOBL && a != ADATA)
-		pc++;
-}
-
-#include "../cc/lexbody"
-#include "../cc/macbody"
diff --git a/src/cmd/new9a/lex.go b/src/cmd/9a/lex.go
similarity index 100%
rename from src/cmd/new9a/lex.go
rename to src/cmd/9a/lex.go
diff --git a/src/cmd/new9a/y.go b/src/cmd/9a/y.go
similarity index 100%
rename from src/cmd/new9a/y.go
rename to src/cmd/9a/y.go
diff --git a/src/cmd/9a/y.tab.c b/src/cmd/9a/y.tab.c
deleted file mode 100644
index 829f4d5..0000000
--- a/src/cmd/9a/y.tab.c
+++ /dev/null
@@ -1,3466 +0,0 @@
-/* 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 {
-     LMOVW = 258,
-     LMOVB = 259,
-     LABS = 260,
-     LLOGW = 261,
-     LSHW = 262,
-     LADDW = 263,
-     LCMP = 264,
-     LCROP = 265,
-     LBRA = 266,
-     LFMOV = 267,
-     LFCONV = 268,
-     LFCMP = 269,
-     LFADD = 270,
-     LFMA = 271,
-     LTRAP = 272,
-     LXORW = 273,
-     LNOP = 274,
-     LEND = 275,
-     LRETT = 276,
-     LWORD = 277,
-     LTEXT = 278,
-     LGLOBL = 279,
-     LDATA = 280,
-     LRETRN = 281,
-     LCONST = 282,
-     LSP = 283,
-     LSB = 284,
-     LFP = 285,
-     LPC = 286,
-     LCREG = 287,
-     LFLUSH = 288,
-     LREG = 289,
-     LFREG = 290,
-     LR = 291,
-     LCR = 292,
-     LF = 293,
-     LFPSCR = 294,
-     LLR = 295,
-     LCTR = 296,
-     LSPR = 297,
-     LSPREG = 298,
-     LSEG = 299,
-     LMSR = 300,
-     LPCDAT = 301,
-     LFUNCDAT = 302,
-     LSCHED = 303,
-     LXLD = 304,
-     LXST = 305,
-     LXOP = 306,
-     LXMV = 307,
-     LRLWM = 308,
-     LMOVMW = 309,
-     LMOVEM = 310,
-     LMOVFL = 311,
-     LMTFSB = 312,
-     LMA = 313,
-     LFCONST = 314,
-     LSCONST = 315,
-     LNAME = 316,
-     LLAB = 317,
-     LVAR = 318
-   };
-#endif
-/* Tokens.  */
-#define LMOVW 258
-#define LMOVB 259
-#define LABS 260
-#define LLOGW 261
-#define LSHW 262
-#define LADDW 263
-#define LCMP 264
-#define LCROP 265
-#define LBRA 266
-#define LFMOV 267
-#define LFCONV 268
-#define LFCMP 269
-#define LFADD 270
-#define LFMA 271
-#define LTRAP 272
-#define LXORW 273
-#define LNOP 274
-#define LEND 275
-#define LRETT 276
-#define LWORD 277
-#define LTEXT 278
-#define LGLOBL 279
-#define LDATA 280
-#define LRETRN 281
-#define LCONST 282
-#define LSP 283
-#define LSB 284
-#define LFP 285
-#define LPC 286
-#define LCREG 287
-#define LFLUSH 288
-#define LREG 289
-#define LFREG 290
-#define LR 291
-#define LCR 292
-#define LF 293
-#define LFPSCR 294
-#define LLR 295
-#define LCTR 296
-#define LSPR 297
-#define LSPREG 298
-#define LSEG 299
-#define LMSR 300
-#define LPCDAT 301
-#define LFUNCDAT 302
-#define LSCHED 303
-#define LXLD 304
-#define LXST 305
-#define LXOP 306
-#define LXMV 307
-#define LRLWM 308
-#define LMOVMW 309
-#define LMOVEM 310
-#define LMOVFL 311
-#define LMTFSB 312
-#define LMA 313
-#define LFCONST 314
-#define LSCONST 315
-#define LNAME 316
-#define LLAB 317
-#define LVAR 318
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 30 "a.y"
-
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
-
-
-/* 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 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-}
-/* Line 193 of yacc.c.  */
-#line 238 "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 251 "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  2
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   880
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  82
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  32
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  187
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  463
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   318
-
-#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,     2,     2,     2,    80,    12,     5,     2,
-      78,    79,    10,     8,    77,     9,     2,    11,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    74,    76,
-       6,    75,     7,     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,     4,     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,     3,     2,    81,     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,    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,    49,    50,    51,    52,    53,    54,
-      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
-      65,    66,    67,    68,    69,    70,    71,    72,    73
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint16 yyprhs[] =
-{
-       0,     0,     3,     4,     5,     9,    10,    15,    20,    25,
-      28,    30,    33,    36,    41,    46,    51,    56,    61,    66,
-      71,    76,    81,    86,    91,    96,   101,   106,   111,   116,
-     121,   126,   131,   136,   143,   148,   153,   160,   165,   170,
-     177,   184,   191,   196,   201,   208,   213,   220,   225,   232,
-     237,   242,   245,   252,   257,   262,   267,   274,   279,   284,
-     289,   294,   299,   304,   309,   314,   317,   320,   325,   329,
-     333,   339,   344,   349,   356,   361,   366,   373,   380,   387,
-     396,   401,   406,   410,   413,   418,   423,   430,   439,   444,
-     451,   456,   461,   468,   475,   484,   493,   502,   511,   516,
-     521,   526,   533,   538,   545,   550,   555,   558,   561,   565,
-     569,   573,   577,   580,   584,   588,   593,   598,   601,   607,
-     615,   620,   627,   634,   641,   648,   651,   656,   659,   661,
-     663,   665,   667,   669,   671,   673,   675,   680,   682,   684,
-     686,   691,   693,   698,   700,   704,   706,   709,   713,   718,
-     721,   724,   727,   731,   734,   736,   741,   745,   751,   753,
-     758,   763,   769,   777,   778,   780,   781,   784,   787,   789,
-     791,   793,   795,   797,   800,   803,   806,   810,   812,   816,
-     820,   824,   828,   832,   837,   842,   846,   850
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      83,     0,    -1,    -1,    -1,    83,    84,    85,    -1,    -1,
-      71,    74,    86,    85,    -1,    71,    75,   113,    76,    -1,
-      73,    75,   113,    76,    -1,    58,    76,    -1,    76,    -1,
-      87,    76,    -1,     1,    76,    -1,    13,    89,    77,    89,
-      -1,    13,   107,    77,    89,    -1,    13,   106,    77,    89,
-      -1,    14,    89,    77,    89,    -1,    14,   107,    77,    89,
-      -1,    14,   106,    77,    89,    -1,    22,   107,    77,    97,
-      -1,    22,   106,    77,    97,    -1,    22,   103,    77,    97,
-      -1,    22,    97,    77,    97,    -1,    22,    97,    77,   107,
-      -1,    22,    97,    77,   106,    -1,    13,    89,    77,   107,
-      -1,    13,    89,    77,   106,    -1,    14,    89,    77,   107,
-      -1,    14,    89,    77,   106,    -1,    13,    97,    77,   107,
-      -1,    13,    97,    77,   106,    -1,    13,    96,    77,    97,
-      -1,    13,    97,    77,    96,    -1,    13,    97,    77,   104,
-      77,    96,    -1,    13,    96,    77,    98,    -1,    67,   104,
-      77,   112,    -1,    13,    89,    77,   104,    77,    92,    -1,
-      13,    89,    77,    98,    -1,    13,    89,    77,    92,    -1,
-      18,    89,    77,   105,    77,    89,    -1,    18,   104,    77,
-     105,    77,    89,    -1,    18,    89,    77,   104,    77,    89,
-      -1,    18,    89,    77,    89,    -1,    18,   104,    77,    89,
-      -1,    16,    89,    77,   105,    77,    89,    -1,    16,    89,
-      77,    89,    -1,    17,    89,    77,   105,    77,    89,    -1,
-      17,    89,    77,    89,    -1,    17,   104,    77,   105,    77,
-      89,    -1,    17,   104,    77,    89,    -1,    15,    89,    77,
-      89,    -1,    15,    89,    -1,    68,    89,    77,   105,    77,
-      89,    -1,    13,   104,    77,    89,    -1,    13,   102,    77,
-      89,    -1,    20,    99,    77,    99,    -1,    20,    99,    77,
-     112,    77,    99,    -1,    13,    98,    77,    98,    -1,    13,
-      95,    77,    98,    -1,    13,    92,    77,    89,    -1,    13,
-      95,    77,    89,    -1,    13,    90,    77,    89,    -1,    13,
-      89,    77,    90,    -1,    13,    98,    77,    95,    -1,    13,
-      89,    77,    95,    -1,    21,    88,    -1,    21,   107,    -1,
-      21,    78,    90,    79,    -1,    21,    77,    88,    -1,    21,
-      77,   107,    -1,    21,    77,    78,    90,    79,    -1,    21,
-      98,    77,    88,    -1,    21,    98,    77,   107,    -1,    21,
-      98,    77,    78,    90,    79,    -1,    21,   112,    77,    88,
-      -1,    21,   112,    77,   107,    -1,    21,   112,    77,    78,
-      90,    79,    -1,    21,   112,    77,   112,    77,    88,    -1,
-      21,   112,    77,   112,    77,   107,    -1,    21,   112,    77,
-     112,    77,    78,    90,    79,    -1,    27,    89,    77,   105,
-      -1,    27,   104,    77,   105,    -1,    27,    89,   109,    -1,
-      27,   109,    -1,    23,    97,    77,    97,    -1,    25,    97,
-      77,    97,    -1,    25,    97,    77,    97,    77,    97,    -1,
-      26,    97,    77,    97,    77,    97,    77,    97,    -1,    24,
-      97,    77,    97,    -1,    24,    97,    77,    97,    77,    98,
-      -1,    19,    89,    77,    89,    -1,    19,    89,    77,   104,
-      -1,    19,    89,    77,    89,    77,    98,    -1,    19,    89,
-      77,   104,    77,    98,    -1,    63,   104,    77,    89,    77,
-     104,    77,    89,    -1,    63,   104,    77,    89,    77,   100,
-      77,    89,    -1,    63,    89,    77,    89,    77,   104,    77,
-      89,    -1,    63,    89,    77,    89,    77,   100,    77,    89,
-      -1,    64,   107,    77,    89,    -1,    64,    89,    77,   107,
-      -1,    59,   106,    77,    89,    -1,    59,   106,    77,   104,
-      77,    89,    -1,    60,    89,    77,   106,    -1,    60,    89,
-      77,   104,    77,   106,    -1,    62,   106,    77,    89,    -1,
-      62,    89,    77,   106,    -1,    61,   106,    -1,    29,   109,
-      -1,    29,    89,   109,    -1,    29,    97,   109,    -1,    29,
-      77,    89,    -1,    29,    77,    97,    -1,    29,   104,    -1,
-      32,   104,   109,    -1,    32,   102,   109,    -1,    56,   104,
-      77,   104,    -1,    57,   104,    77,   107,    -1,    30,   109,
-      -1,    33,   108,    77,    80,   101,    -1,    33,   108,    77,
-     112,    77,    80,   101,    -1,    34,   108,    77,   104,    -1,
-      34,   108,    77,   112,    77,   104,    -1,    35,   108,    11,
-     112,    77,   104,    -1,    35,   108,    11,   112,    77,   102,
-      -1,    35,   108,    11,   112,    77,   103,    -1,    36,   109,
-      -1,   112,    78,    41,    79,    -1,    71,   110,    -1,   105,
-      -1,    91,    -1,    93,    -1,    50,    -1,    47,    -1,    51,
-      -1,    55,    -1,    53,    -1,    52,    78,   112,    79,    -1,
-      94,    -1,    49,    -1,    45,    -1,    48,    78,   112,    79,
-      -1,    42,    -1,    47,    78,   112,    79,    -1,   112,    -1,
-     112,    77,   112,    -1,    37,    -1,     9,    37,    -1,    37,
-       9,    37,    -1,     9,    37,     9,    37,    -1,    80,   107,
-      -1,    80,    70,    -1,    80,    69,    -1,    80,     9,    69,
-      -1,    80,   112,    -1,    44,    -1,    46,    78,   112,    79,
-      -1,    78,   105,    79,    -1,    78,   105,     8,   105,    79,
-      -1,   108,    -1,   112,    78,   105,    79,    -1,   112,    78,
-     111,    79,    -1,    71,   110,    78,   111,    79,    -1,    71,
-       6,     7,   110,    78,    39,    79,    -1,    -1,    77,    -1,
-      -1,     8,   112,    -1,     9,   112,    -1,    39,    -1,    38,
-      -1,    40,    -1,    37,    -1,    73,    -1,     9,   112,    -1,
-       8,   112,    -1,    81,   112,    -1,    78,   113,    79,    -1,
-     112,    -1,   113,     8,   113,    -1,   113,     9,   113,    -1,
-     113,    10,   113,    -1,   113,    11,   113,    -1,   113,    12,
-     113,    -1,   113,     6,     6,   113,    -1,   113,     7,     7,
-     113,    -1,   113,     5,   113,    -1,   113,     4,   113,    -1,
-     113,     3,   113,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,    66,    66,    68,    67,    75,    74,    83,    88,    94,
-      98,    99,   100,   106,   110,   114,   118,   122,   126,   133,
-     137,   141,   145,   149,   153,   160,   164,   168,   172,   179,
-     183,   190,   194,   198,   202,   206,   213,   217,   221,   231,
-     235,   239,   243,   247,   251,   255,   259,   263,   267,   271,
-     275,   279,   286,   293,   297,   304,   308,   316,   320,   324,
-     328,   332,   336,   340,   344,   353,   357,   361,   365,   369,
-     373,   377,   381,   385,   389,   393,   397,   401,   409,   417,
-     428,   432,   436,   440,   447,   451,   455,   459,   463,   467,
-     474,   478,   482,   486,   493,   497,   501,   505,   512,   516,
-     524,   528,   532,   536,   540,   544,   548,   555,   559,   563,
-     567,   571,   575,   582,   586,   593,   602,   613,   620,   625,
-     637,   642,   655,   663,   671,   682,   688,   694,   705,   713,
-     714,   717,   725,   733,   741,   749,   755,   763,   766,   774,
-     780,   788,   794,   802,   810,   831,   838,   845,   852,   861,
-     866,   874,   880,   887,   895,   896,   904,   911,   921,   922,
-     931,   939,   947,   956,   957,   960,   963,   967,   973,   974,
-     975,   978,   979,   983,   987,   991,   995,  1001,  1002,  1006,
-    1010,  1014,  1018,  1022,  1026,  1030,  1034,  1038
-};
-#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.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "'|'", "'^'", "'&'", "'<'", "'>'", "'+'",
-  "'-'", "'*'", "'/'", "'%'", "LMOVW", "LMOVB", "LABS", "LLOGW", "LSHW",
-  "LADDW", "LCMP", "LCROP", "LBRA", "LFMOV", "LFCONV", "LFCMP", "LFADD",
-  "LFMA", "LTRAP", "LXORW", "LNOP", "LEND", "LRETT", "LWORD", "LTEXT",
-  "LGLOBL", "LDATA", "LRETRN", "LCONST", "LSP", "LSB", "LFP", "LPC",
-  "LCREG", "LFLUSH", "LREG", "LFREG", "LR", "LCR", "LF", "LFPSCR", "LLR",
-  "LCTR", "LSPR", "LSPREG", "LSEG", "LMSR", "LPCDAT", "LFUNCDAT", "LSCHED",
-  "LXLD", "LXST", "LXOP", "LXMV", "LRLWM", "LMOVMW", "LMOVEM", "LMOVFL",
-  "LMTFSB", "LMA", "LFCONST", "LSCONST", "LNAME", "LLAB", "LVAR", "':'",
-  "'='", "';'", "','", "'('", "')'", "'$'", "'~'", "$accept", "prog", "@1",
-  "line", "@2", "inst", "rel", "rreg", "xlreg", "lr", "lcr", "ctr", "msr",
-  "psr", "fpscr", "freg", "creg", "cbit", "mask", "textsize", "ximm",
-  "fimm", "imm", "sreg", "regaddr", "addr", "name", "comma", "offset",
-  "pointer", "con", "expr", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   124,    94,    38,    60,    62,    43,    45,
-      42,    47,    37,   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,   304,
-     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
-     315,   316,   317,   318,    58,    61,    59,    44,    40,    41,
-      36,   126
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    82,    83,    84,    83,    86,    85,    85,    85,    85,
-      85,    85,    85,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    87,    87,    87,    88,    88,    89,    90,
-      90,    91,    92,    93,    94,    95,    95,    95,    96,    97,
-      97,    98,    98,    99,   100,   101,   101,   101,   101,   102,
-     102,   103,   103,   104,   105,   105,   106,   106,   107,   107,
-     108,   108,   108,   109,   109,   110,   110,   110,   111,   111,
-     111,   112,   112,   112,   112,   112,   112,   113,   113,   113,
-     113,   113,   113,   113,   113,   113,   113,   113
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     0,     0,     3,     0,     4,     4,     4,     2,
-       1,     2,     2,     4,     4,     4,     4,     4,     4,     4,
-       4,     4,     4,     4,     4,     4,     4,     4,     4,     4,
-       4,     4,     4,     6,     4,     4,     6,     4,     4,     6,
-       6,     6,     4,     4,     6,     4,     6,     4,     6,     4,
-       4,     2,     6,     4,     4,     4,     6,     4,     4,     4,
-       4,     4,     4,     4,     4,     2,     2,     4,     3,     3,
-       5,     4,     4,     6,     4,     4,     6,     6,     6,     8,
-       4,     4,     3,     2,     4,     4,     6,     8,     4,     6,
-       4,     4,     6,     6,     8,     8,     8,     8,     4,     4,
-       4,     6,     4,     6,     4,     4,     2,     2,     3,     3,
-       3,     3,     2,     3,     3,     4,     4,     2,     5,     7,
-       4,     6,     6,     6,     6,     2,     4,     2,     1,     1,
-       1,     1,     1,     1,     1,     1,     4,     1,     1,     1,
-       4,     1,     4,     1,     3,     1,     2,     3,     4,     2,
-       2,     2,     3,     2,     1,     4,     3,     5,     1,     4,
-       4,     5,     7,     0,     1,     0,     2,     2,     1,     1,
-       1,     1,     1,     2,     2,     2,     3,     1,     3,     3,
-       3,     3,     3,     4,     4,     3,     3,     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_uint8 yydefact[] =
-{
-       2,     3,     1,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   163,
-     163,   163,     0,     0,     0,     0,   163,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      10,     4,     0,    12,     0,     0,   171,   141,   154,   139,
-       0,   132,     0,   138,   131,   133,     0,   135,   134,   165,
-     172,     0,     0,     0,     0,     0,   129,     0,   130,   137,
-       0,     0,     0,     0,     0,     0,   128,     0,     0,   158,
-       0,     0,     0,     0,    51,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   143,     0,   165,     0,     0,    65,
-       0,    66,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   164,   163,     0,    83,   164,   163,   163,   112,
-     107,   117,   163,   163,     0,     0,     0,     0,   125,     0,
-       0,     9,     0,     0,     0,   106,     0,     0,     0,     0,
-       0,     0,     0,     0,     5,     0,     0,    11,   174,   173,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   177,
-       0,   150,   149,   153,   175,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   153,     0,     0,     0,     0,     0,     0,   127,
-       0,    68,    69,     0,     0,     0,     0,     0,     0,   151,
-       0,     0,     0,     0,     0,     0,     0,     0,   164,    82,
-       0,   110,   111,   108,   109,   114,   113,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     165,   166,   167,     0,     0,   156,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   176,    13,    62,    38,
-      64,    37,     0,    26,    25,    61,    59,    60,    58,    31,
-      34,    32,     0,    30,    29,    63,    57,    54,    53,    15,
-      14,   169,   168,   170,     0,     0,    16,    28,    27,    18,
-      17,    50,    45,   128,    47,   128,    49,   128,    42,     0,
-     128,    43,   128,    90,    91,    55,   143,     0,    67,     0,
-      71,    72,     0,    74,    75,     0,     0,   152,    22,    24,
-      23,    21,    20,    19,    84,    88,    85,     0,    80,    81,
-       0,     0,   120,     0,     0,   115,   116,   100,     0,     0,
-     102,   105,   104,     0,     0,    99,    98,    35,     0,     6,
-       7,     8,   155,   142,   140,   136,     0,     0,     0,   187,
-     186,   185,     0,     0,   178,   179,   180,   181,   182,     0,
-       0,   159,   160,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    70,     0,     0,     0,   126,     0,     0,     0,
-       0,   145,   118,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   161,   157,   183,   184,   132,    36,    33,    44,
-      46,    48,    41,    39,    40,    92,    93,    56,    73,    76,
-       0,    77,    78,    89,    86,     0,   146,     0,     0,   121,
-       0,   123,   124,   122,   101,   103,     0,     0,     0,     0,
-       0,    52,     0,     0,     0,     0,   147,   119,     0,     0,
-       0,     0,     0,     0,   162,    79,    87,   148,    97,    96,
-     144,    95,    94
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     1,     3,    41,   233,    42,    99,    64,    65,    66,
-      67,    68,    69,    70,    71,    72,    73,    93,   436,   392,
-      74,   105,    75,    76,    77,   162,    79,   115,   157,   285,
-     159,   160
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -180
-static const yytype_int16 yypact[] =
-{
-    -180,    12,  -180,   484,   -53,   517,   619,    28,    28,   -24,
-     -24,    28,   799,   577,   596,   -29,   -29,   -29,   -29,    19,
-     -11,   -51,   -38,   701,   701,   701,   -51,   -19,   -19,    -8,
-      -7,    28,    -7,   -14,   -24,   643,   -19,    28,   -36,     6,
-    -180,  -180,    26,  -180,   799,   799,  -180,  -180,  -180,  -180,
-       7,    27,    51,  -180,  -180,  -180,    61,  -180,  -180,   188,
-    -180,   662,   674,   799,    79,    93,  -180,    99,  -180,  -180,
-     112,   116,   126,   136,   138,   157,  -180,   168,   176,  -180,
-      80,   179,   182,   184,   186,   194,   799,   196,   198,   200,
-     201,   202,   799,   203,  -180,    27,   188,   714,   676,  -180,
-     206,  -180,    49,     8,   215,   216,   217,   219,   220,   221,
-     223,   224,  -180,   225,   226,  -180,   181,   -51,   -51,  -180,
-    -180,  -180,   -51,   -51,   227,   158,   231,   296,  -180,   232,
-     233,  -180,    28,   234,   236,  -180,   237,   238,   242,   245,
-     246,   248,   249,   250,  -180,   799,   799,  -180,  -180,  -180,
-     799,   799,   799,   799,   321,   799,   799,   251,     3,  -180,
-     377,  -180,  -180,    80,  -180,   565,    28,    28,   172,   162,
-     623,    31,    28,    28,    28,    28,   230,   619,    28,    28,
-      28,    28,  -180,    28,    28,   -24,    28,   -24,   799,   251,
-     676,  -180,  -180,   254,   257,   723,   753,   111,   268,  -180,
-      67,   -29,   -29,   -29,   -29,   -29,   -29,   -29,    28,  -180,
-      28,  -180,  -180,  -180,  -180,  -180,  -180,   733,    96,   760,
-     799,   -19,   701,   -24,    40,    -7,    28,    28,    28,   701,
-      28,   799,    28,   484,   463,   524,   265,   266,   267,   270,
-     135,  -180,  -180,    96,    28,  -180,   799,   799,   799,   341,
-     347,   799,   799,   799,   799,   799,  -180,  -180,  -180,  -180,
-    -180,  -180,   278,  -180,  -180,  -180,  -180,  -180,  -180,  -180,
-    -180,  -180,   279,  -180,  -180,  -180,  -180,  -180,  -180,  -180,
-    -180,  -180,  -180,  -180,   281,   282,  -180,  -180,  -180,  -180,
-    -180,  -180,  -180,   280,  -180,   285,  -180,   286,  -180,   288,
-     289,  -180,   297,   299,   301,  -180,   319,   294,  -180,   676,
-    -180,  -180,   676,  -180,  -180,   171,   318,  -180,  -180,  -180,
-    -180,  -180,  -180,  -180,  -180,   324,   325,   327,  -180,  -180,
-       9,   328,  -180,   329,   330,  -180,  -180,  -180,   331,   335,
-    -180,  -180,  -180,   336,   337,  -180,  -180,  -180,   338,  -180,
-    -180,  -180,  -180,  -180,  -180,  -180,   320,   339,   340,   571,
-     430,    82,   799,   799,   153,   153,  -180,  -180,  -180,   374,
-     373,  -180,  -180,    28,    28,    28,    28,    28,    28,    20,
-      20,   799,  -180,   344,   345,   772,  -180,    20,   -29,   -29,
-     390,   419,  -180,   349,   -19,   350,    28,    -7,   760,   760,
-      28,   392,  -180,  -180,   277,   277,  -180,  -180,  -180,  -180,
-    -180,  -180,  -180,  -180,  -180,  -180,  -180,  -180,  -180,  -180,
-     676,  -180,  -180,  -180,  -180,   355,   436,   411,     9,  -180,
-     322,  -180,  -180,  -180,  -180,  -180,   375,   376,   378,   380,
-     381,  -180,   372,   382,   -29,   417,  -180,  -180,   790,    28,
-      28,   799,    28,    28,  -180,  -180,  -180,  -180,  -180,  -180,
-    -180,  -180,  -180
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-    -180,  -180,  -180,   229,  -180,  -180,   -73,    -6,   -62,  -180,
-    -158,  -180,  -180,  -150,  -162,    37,    30,  -179,    60,    32,
-     -16,    68,    97,   167,    81,    95,   159,    24,   -86,   239,
-      35,    87
-};
-
-/* 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 -1
-static const yytype_uint16 yytable[] =
-{
-      81,    84,    85,    87,    89,    91,   122,   259,   271,   305,
-     189,   244,     2,   113,   117,   260,    49,   198,   390,    52,
-      48,   275,    50,    43,   191,   134,   112,   136,   138,   140,
-      48,   143,    50,    48,    49,    50,   194,    52,   144,   145,
-      80,    80,    62,   100,   120,   121,   391,    94,   102,    80,
-     128,   104,   108,   109,   110,   111,    86,   118,   125,   125,
-     125,    86,    47,    48,   132,    50,   116,    95,   131,    86,
-      80,   132,    48,    47,    50,    44,    45,   199,    95,   148,
-     149,   146,   245,    56,    57,   150,    58,    82,   249,   250,
-     251,   252,   253,   254,   255,   106,   112,   163,   164,    86,
-      78,    83,   147,   258,    46,   151,    88,    90,   101,   107,
-     211,   133,    49,   135,   137,    52,   114,   119,   132,   123,
-      86,   182,   310,   313,   129,   130,   196,   197,   307,   152,
-     141,   139,   193,   142,   281,   282,   283,   209,    59,   153,
-      60,   213,   214,   155,   156,    61,   215,   216,    63,   281,
-     282,   283,   316,   212,   356,    48,   165,    50,   176,   257,
-     265,   266,   267,   253,   254,   255,   277,   278,   279,   280,
-     166,   286,   289,   290,   291,   292,   167,   294,   296,   298,
-     301,   303,   124,   126,   127,   236,   237,   238,   239,   168,
-     241,   242,   192,   169,   154,   261,   155,   156,   268,   270,
-      80,   276,   417,   170,    47,    80,   269,    49,   408,    95,
-      52,   407,    80,   171,    47,   172,    48,   337,    50,    95,
-     342,   343,   344,   306,   346,    48,    49,    50,   158,    52,
-     193,   315,   234,   235,   173,    80,   218,   318,   321,   322,
-     323,   324,   325,   326,   327,   174,   263,   383,   385,   197,
-     384,   273,   331,   175,   333,   334,   177,    80,   287,   178,
-     264,   179,   262,   180,    80,   274,   347,   272,   281,   282,
-     283,   181,   288,   183,    48,   184,    50,   185,   186,   187,
-     188,   319,   299,   195,   304,   251,   252,   253,   254,   255,
-     311,   314,   200,   201,   202,   320,   203,   204,   205,   158,
-     206,   207,   208,   210,   217,   340,   341,   220,   219,   221,
-     222,   223,   421,   224,   225,   226,   332,   336,   335,   227,
-     338,   339,   228,   229,   345,   230,   231,   232,   240,   243,
-      44,   448,   197,   359,   360,   361,   308,   317,   364,   365,
-     366,   367,   368,   284,   352,   353,   354,   362,   293,   355,
-     295,   297,   300,   302,   363,   369,   370,   373,   443,    46,
-     371,   372,   374,   375,   284,   376,   377,   409,   410,   411,
-     412,   413,   414,   382,   378,   328,   379,   329,   380,   431,
-     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,
-     434,   199,   161,    59,   441,    60,   381,   386,   401,   348,
-      92,   387,   388,    63,   389,   393,   394,   395,   396,   415,
-     416,   358,   397,   398,   399,   400,    94,   423,   402,   403,
-     193,   406,    53,   418,   419,   424,   425,   426,   427,   428,
-     430,   442,   444,   438,   438,   248,   249,   250,   251,   252,
-     253,   254,   255,   458,   459,   445,   461,   462,   446,   404,
-     405,   454,   449,   450,   457,   451,   256,   452,   453,   439,
-     447,   455,   349,   432,     0,   163,   246,   247,   248,   249,
-     250,   251,   252,   253,   254,   255,     0,     0,   435,     0,
-     422,   456,   357,   149,     0,     4,   460,     0,     0,     0,
-       0,   429,   433,     0,     0,   437,   440,     5,     6,     7,
-       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,     0,    20,    21,     0,    22,    23,    24,    25,
-      26,     0,     0,     0,     0,    44,    45,   246,   247,   248,
-     249,   250,   251,   252,   253,   254,   255,     0,     0,   350,
-      27,    28,    29,    30,    31,    32,    33,    34,    35,     0,
-       0,    36,    37,     0,    46,    38,     0,    39,     0,    47,
-      40,    48,    49,    50,    51,    52,    53,    54,    55,    56,
-      57,     0,    58,    44,    45,   247,   248,   249,   250,   251,
-     252,   253,   254,   255,     0,    44,    45,     0,    59,     0,
-      60,     0,     0,     0,     0,    61,     0,    62,    63,     0,
-     351,     0,    46,     0,    44,    45,     0,    47,     0,    48,
-       0,    50,    51,     0,    46,    54,    55,    56,    57,    47,
-      58,     0,     0,     0,    95,     0,     0,    44,    45,     0,
-       0,    44,    45,    46,     0,     0,    59,     0,    60,     0,
-       0,    49,     0,    61,    52,    86,    63,     0,    96,     0,
-      60,    44,    45,     0,    97,    98,    46,     0,    63,     0,
-      46,     0,     0,    48,     0,    50,     0,    59,     0,    60,
-      44,    45,    53,     0,    61,     0,   103,    63,     0,     0,
-      46,     0,    44,    45,    44,    45,     0,    48,     0,    50,
-      59,     0,    60,     0,    59,     0,    60,    61,     0,    46,
-      63,    61,     0,    86,    63,     0,    48,     0,    50,    44,
-      45,    46,     0,    46,    59,     0,    60,     0,     0,     0,
-       0,    92,    44,    45,    63,     0,    54,    55,     0,     0,
-       0,    44,    45,     0,     0,    60,     0,     0,    46,     0,
-      92,    44,    45,    63,   161,    59,     0,    60,     0,    60,
-       0,    46,    92,     0,    92,    63,     0,    63,     0,     0,
-      46,    44,    45,     0,     0,     0,     0,     0,    44,    45,
-      46,     0,    59,     0,    60,     0,     0,     0,     0,    92,
-      44,    45,    63,     0,     0,    96,     0,    60,     0,     0,
-      46,     0,   190,     0,    96,    63,    60,    46,    44,    45,
-       0,   309,     0,     0,    63,     0,    60,    44,    45,    46,
-       0,    92,     0,   330,    63,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    96,     0,    60,    46,     0,     0,
-       0,   312,     0,    60,    63,     0,    46,     0,    92,     0,
-      86,    63,     0,    96,     0,    60,     0,     0,     0,     0,
-     420,     0,     0,    63,     0,     0,     0,     0,     0,   317,
-       0,     0,     0,    60,     0,     0,     0,     0,    92,     0,
-       0,    63,    60,     0,     0,     0,     0,    92,     0,     0,
-      63
-};
-
-static const yytype_int16 yycheck[] =
-{
-       6,     7,     8,     9,    10,    11,    22,   165,   170,   188,
-      96,     8,     0,    19,    20,   165,    45,     9,     9,    48,
-      44,   171,    46,    76,    97,    31,    77,    33,    34,    35,
-      44,    37,    46,    44,    45,    46,    98,    48,    74,    75,
-       5,     6,    80,    13,    20,    21,    37,    12,    13,    14,
-      26,    14,    15,    16,    17,    18,    80,    20,    23,    24,
-      25,    80,    42,    44,    78,    46,    77,    47,    76,    80,
-      35,    78,    44,    42,    46,     8,     9,    69,    47,    44,
-      45,    75,    79,    52,    53,    78,    55,     6,     6,     7,
-       8,     9,    10,    11,    12,    14,    77,    62,    63,    80,
-       5,     6,    76,   165,    37,    78,     9,    10,    13,    14,
-     116,    30,    45,    32,    33,    48,    19,    20,    78,    22,
-      80,    86,   195,   196,    27,    28,    77,    78,   190,    78,
-      35,    34,    97,    36,    38,    39,    40,   113,    71,    78,
-      73,   117,   118,     8,     9,    78,   122,   123,    81,    38,
-      39,    40,    41,   116,   240,    44,    77,    46,    78,   165,
-     166,   167,   168,    10,    11,    12,   172,   173,   174,   175,
-      77,   177,   178,   179,   180,   181,    77,   183,   184,   185,
-     186,   187,    23,    24,    25,   150,   151,   152,   153,    77,
-     155,   156,    97,    77,     6,   165,     8,     9,   168,   169,
-     165,   171,   381,    77,    42,   170,   169,    45,   370,    47,
-      48,   369,   177,    77,    42,    77,    44,   223,    46,    47,
-     226,   227,   228,   188,   230,    44,    45,    46,    61,    48,
-     195,   196,   145,   146,    77,   200,    78,   200,   201,   202,
-     203,   204,   205,   206,   207,    77,   165,   309,    77,    78,
-     312,   170,   217,    77,   219,   220,    77,   222,   177,    77,
-     165,    77,   165,    77,   229,   170,   231,   170,    38,    39,
-      40,    77,   177,    77,    44,    77,    46,    77,    77,    77,
-      77,   200,   185,    77,   187,     8,     9,    10,    11,    12,
-     195,   196,    77,    77,    77,   200,    77,    77,    77,   132,
-      77,    77,    77,    77,    77,   224,   225,    11,    77,    77,
-      77,    77,   385,    77,    77,    77,   219,   222,   221,    77,
-     223,   224,    77,    77,   229,    77,    77,    77,     7,    78,
-       8,     9,    78,   246,   247,   248,    79,    69,   251,   252,
-     253,   254,   255,   176,    79,    79,    79,     6,   181,    79,
-     183,   184,   185,   186,     7,    77,    77,    77,   420,    37,
-      79,    79,    77,    77,   197,    77,    77,   373,   374,   375,
-     376,   377,   378,    79,    77,   208,    77,   210,    77,   395,
-       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-     396,    69,    70,    71,   400,    73,    77,    79,    78,   232,
-      78,    77,    77,    81,    77,    77,    77,    77,    77,   379,
-     380,   244,    77,    77,    77,    77,   381,   387,    79,    79,
-     385,    47,    49,    79,    79,   388,   389,    37,     9,    80,
-      80,    39,    77,   398,   399,     5,     6,     7,     8,     9,
-      10,    11,    12,   449,   450,     9,   452,   453,    37,   362,
-     363,    79,    77,    77,    37,    77,    79,    77,    77,   399,
-     428,    79,   233,   395,    -1,   430,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    -1,    -1,   397,    -1,
-     385,   444,   243,   448,    -1,     1,   451,    -1,    -1,    -1,
-      -1,   394,   395,    -1,    -1,   398,   399,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    -1,    29,    30,    -1,    32,    33,    34,    35,
-      36,    -1,    -1,    -1,    -1,     8,     9,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    -1,    -1,    76,
-      56,    57,    58,    59,    60,    61,    62,    63,    64,    -1,
-      -1,    67,    68,    -1,    37,    71,    -1,    73,    -1,    42,
-      76,    44,    45,    46,    47,    48,    49,    50,    51,    52,
-      53,    -1,    55,     8,     9,     4,     5,     6,     7,     8,
-       9,    10,    11,    12,    -1,     8,     9,    -1,    71,    -1,
-      73,    -1,    -1,    -1,    -1,    78,    -1,    80,    81,    -1,
-      76,    -1,    37,    -1,     8,     9,    -1,    42,    -1,    44,
-      -1,    46,    47,    -1,    37,    50,    51,    52,    53,    42,
-      55,    -1,    -1,    -1,    47,    -1,    -1,     8,     9,    -1,
-      -1,     8,     9,    37,    -1,    -1,    71,    -1,    73,    -1,
-      -1,    45,    -1,    78,    48,    80,    81,    -1,    71,    -1,
-      73,     8,     9,    -1,    77,    78,    37,    -1,    81,    -1,
-      37,    -1,    -1,    44,    -1,    46,    -1,    71,    -1,    73,
-       8,     9,    49,    -1,    78,    -1,    80,    81,    -1,    -1,
-      37,    -1,     8,     9,     8,     9,    -1,    44,    -1,    46,
-      71,    -1,    73,    -1,    71,    -1,    73,    78,    -1,    37,
-      81,    78,    -1,    80,    81,    -1,    44,    -1,    46,     8,
-       9,    37,    -1,    37,    71,    -1,    73,    -1,    -1,    -1,
-      -1,    78,     8,     9,    81,    -1,    50,    51,    -1,    -1,
-      -1,     8,     9,    -1,    -1,    73,    -1,    -1,    37,    -1,
-      78,     8,     9,    81,    70,    71,    -1,    73,    -1,    73,
-      -1,    37,    78,    -1,    78,    81,    -1,    81,    -1,    -1,
-      37,     8,     9,    -1,    -1,    -1,    -1,    -1,     8,     9,
-      37,    -1,    71,    -1,    73,    -1,    -1,    -1,    -1,    78,
-       8,     9,    81,    -1,    -1,    71,    -1,    73,    -1,    -1,
-      37,    -1,    78,    -1,    71,    81,    73,    37,     8,     9,
-      -1,    78,    -1,    -1,    81,    -1,    73,     8,     9,    37,
-      -1,    78,    -1,    80,    81,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    71,    -1,    73,    37,    -1,    -1,
-      -1,    78,    -1,    73,    81,    -1,    37,    -1,    78,    -1,
-      80,    81,    -1,    71,    -1,    73,    -1,    -1,    -1,    -1,
-      78,    -1,    -1,    81,    -1,    -1,    -1,    -1,    -1,    69,
-      -1,    -1,    -1,    73,    -1,    -1,    -1,    -1,    78,    -1,
-      -1,    81,    73,    -1,    -1,    -1,    -1,    78,    -1,    -1,
-      81
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,    83,     0,    84,     1,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      29,    30,    32,    33,    34,    35,    36,    56,    57,    58,
-      59,    60,    61,    62,    63,    64,    67,    68,    71,    73,
-      76,    85,    87,    76,     8,     9,    37,    42,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    55,    71,
-      73,    78,    80,    81,    89,    90,    91,    92,    93,    94,
-      95,    96,    97,    98,   102,   104,   105,   106,   107,   108,
-     112,    89,   106,   107,    89,    89,    80,    89,   104,    89,
-     104,    89,    78,    99,   112,    47,    71,    77,    78,    88,
-      98,   107,   112,    80,    97,   103,   106,   107,    97,    97,
-      97,    97,    77,    89,   104,   109,    77,    89,    97,   104,
-     109,   109,   102,   104,   108,   112,   108,   108,   109,   104,
-     104,    76,    78,   106,    89,   106,    89,   106,    89,   104,
-      89,   107,   104,    89,    74,    75,    75,    76,   112,   112,
-      78,    78,    78,    78,     6,     8,     9,   110,   105,   112,
-     113,    70,   107,   112,   112,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    78,    77,    77,    77,
-      77,    77,   112,    77,    77,    77,    77,    77,    77,   110,
-      78,    88,   107,   112,    90,    77,    77,    78,     9,    69,
-      77,    77,    77,    77,    77,    77,    77,    77,    77,   109,
-      77,    89,    97,   109,   109,   109,   109,    77,    78,    77,
-      11,    77,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    86,   113,   113,   112,   112,   112,   112,
-       7,   112,   112,    78,     8,    79,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    79,    89,    90,    92,
-      95,    98,   104,   106,   107,    89,    89,    89,    98,    97,
-      98,    96,   104,   106,   107,    95,    98,    89,    89,    89,
-      89,    38,    39,    40,   105,   111,    89,   106,   107,    89,
-      89,    89,    89,   105,    89,   105,    89,   105,    89,   104,
-     105,    89,   105,    89,   104,    99,   112,    90,    79,    78,
-      88,   107,    78,    88,   107,   112,    41,    69,    97,   106,
-     107,    97,    97,    97,    97,    97,    97,    97,   105,   105,
-      80,   112,   104,   112,   112,   104,   107,    89,   104,   104,
-     106,   106,    89,    89,    89,   107,    89,   112,   105,    85,
-      76,    76,    79,    79,    79,    79,   110,   111,   105,   113,
-     113,   113,     6,     7,   113,   113,   113,   113,   113,    77,
-      77,    79,    79,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    79,    90,    90,    77,    79,    77,    77,    77,
-       9,    37,   101,    77,    77,    77,    77,    77,    77,    77,
-      77,    78,    79,    79,   113,   113,    47,    92,    96,    89,
-      89,    89,    89,    89,    89,    98,    98,    99,    79,    79,
-      78,    88,   107,    98,    97,    97,    37,     9,    80,   104,
-      80,   102,   103,   104,    89,   106,   100,   104,   112,   100,
-     104,    89,    39,    90,    77,     9,    37,   101,     9,    77,
-      77,    77,    77,    77,    79,    79,    97,    37,    89,    89,
-     112,    89,    89
-};
-
-#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;
-
-/* 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 yystate;
-  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 3:
-#line 68 "a.y"
-    {
-		stmtline = lineno;
-	}
-    break;
-
-  case 5:
-#line 75 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
-			yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyvsp[(1) - (2)].sym)->type = LLAB;
-		(yyvsp[(1) - (2)].sym)->value = pc;
-	}
-    break;
-
-  case 7:
-#line 84 "a.y"
-    {
-		(yyvsp[(1) - (4)].sym)->type = LVAR;
-		(yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 8:
-#line 89 "a.y"
-    {
-		if((yyvsp[(1) - (4)].sym)->value != (yyvsp[(3) - (4)].lval))
-			yyerror("redeclaration of %s", (yyvsp[(1) - (4)].sym)->name);
-		(yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 9:
-#line 95 "a.y"
-    {
-		nosched = (yyvsp[(1) - (2)].lval);
-	}
-    break;
-
-  case 13:
-#line 107 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 14:
-#line 111 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 15:
-#line 115 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 16:
-#line 119 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 17:
-#line 123 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 18:
-#line 127 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 19:
-#line 134 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 20:
-#line 138 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 21:
-#line 142 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 22:
-#line 146 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 23:
-#line 150 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 24:
-#line 154 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 25:
-#line 161 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 26:
-#line 165 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 27:
-#line 169 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 28:
-#line 173 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 29:
-#line 180 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 30:
-#line 184 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 31:
-#line 191 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 32:
-#line 195 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 33:
-#line 199 "a.y"
-    {
-		outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 34:
-#line 203 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 35:
-#line 207 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
-	}
-    break;
-
-  case 36:
-#line 214 "a.y"
-    {
-		outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 37:
-#line 218 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 38:
-#line 222 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 39:
-#line 232 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 40:
-#line 236 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 41:
-#line 240 "a.y"
-    {
-		outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 42:
-#line 244 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 43:
-#line 248 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 44:
-#line 252 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 45:
-#line 256 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 46:
-#line 260 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 47:
-#line 264 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 48:
-#line 268 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 49:
-#line 272 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 50:
-#line 276 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 51:
-#line 280 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), 0, &(yyvsp[(2) - (2)].addr));
-	}
-    break;
-
-  case 52:
-#line 287 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 53:
-#line 294 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 54:
-#line 298 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 55:
-#line 305 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].addr).reg, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 56:
-#line 309 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 57:
-#line 317 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 58:
-#line 321 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 59:
-#line 325 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 60:
-#line 329 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 61:
-#line 333 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 62:
-#line 337 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 63:
-#line 341 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 64:
-#line 345 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 65:
-#line 354 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &(yyvsp[(2) - (2)].addr));
-	}
-    break;
-
-  case 66:
-#line 358 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &(yyvsp[(2) - (2)].addr));
-	}
-    break;
-
-  case 67:
-#line 362 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &nullgen, 0, &(yyvsp[(3) - (4)].addr));
-	}
-    break;
-
-  case 68:
-#line 366 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 69:
-#line 370 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 70:
-#line 374 "a.y"
-    {
-		outcode((yyvsp[(1) - (5)].lval), &nullgen, 0, &(yyvsp[(4) - (5)].addr));
-	}
-    break;
-
-  case 71:
-#line 378 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 72:
-#line 382 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 73:
-#line 386 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(5) - (6)].addr));
-	}
-    break;
-
-  case 74:
-#line 390 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &nullgen, (yyvsp[(2) - (4)].lval), &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 75:
-#line 394 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &nullgen, (yyvsp[(2) - (4)].lval), &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 76:
-#line 398 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &nullgen, (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].addr));
-	}
-    break;
-
-  case 77:
-#line 402 "a.y"
-    {
-		Addr g;
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = (yyvsp[(2) - (6)].lval);
-		outcode((yyvsp[(1) - (6)].lval), &g, REG_R0+(yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 78:
-#line 410 "a.y"
-    {
-		Addr g;
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = (yyvsp[(2) - (6)].lval);
-		outcode((yyvsp[(1) - (6)].lval), &g, REG_R0+(yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 79:
-#line 418 "a.y"
-    {
-		Addr g;
-		g = nullgen;
-		g.type = TYPE_CONST;
-		g.offset = (yyvsp[(2) - (8)].lval);
-		outcode((yyvsp[(1) - (8)].lval), &g, REG_R0+(yyvsp[(4) - (8)].lval), &(yyvsp[(7) - (8)].addr));
-	}
-    break;
-
-  case 80:
-#line 429 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
-	}
-    break;
-
-  case 81:
-#line 433 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
-	}
-    break;
-
-  case 82:
-#line 437 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 83:
-#line 441 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 84:
-#line 448 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 85:
-#line 452 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 86:
-#line 456 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].addr).reg, &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 87:
-#line 460 "a.y"
-    {
-		outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
-	}
-    break;
-
-  case 88:
-#line 464 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 89:
-#line 468 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
-	}
-    break;
-
-  case 90:
-#line 475 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 91:
-#line 479 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 92:
-#line 483 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
-	}
-    break;
-
-  case 93:
-#line 487 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
-	}
-    break;
-
-  case 94:
-#line 494 "a.y"
-    {
-		outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
-	}
-    break;
-
-  case 95:
-#line 498 "a.y"
-    {
-		outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
-	}
-    break;
-
-  case 96:
-#line 502 "a.y"
-    {
-		outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
-	}
-    break;
-
-  case 97:
-#line 506 "a.y"
-    {
-		outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
-	}
-    break;
-
-  case 98:
-#line 513 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 99:
-#line 517 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 100:
-#line 525 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 101:
-#line 529 "a.y"
-    {
-		outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 102:
-#line 533 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 103:
-#line 537 "a.y"
-    {
-		outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
-	}
-    break;
-
-  case 104:
-#line 541 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 105:
-#line 545 "a.y"
-    {
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 106:
-#line 549 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 107:
-#line 556 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 108:
-#line 560 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 109:
-#line 564 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 110:
-#line 568 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 111:
-#line 572 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &nullgen, 0, &(yyvsp[(3) - (3)].addr));
-	}
-    break;
-
-  case 112:
-#line 576 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 113:
-#line 583 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 114:
-#line 587 "a.y"
-    {
-		outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), 0, &nullgen);
-	}
-    break;
-
-  case 115:
-#line 594 "a.y"
-    {
-		if((yyvsp[(2) - (4)].addr).type != TYPE_CONST || (yyvsp[(4) - (4)].addr).type != TYPE_CONST)
-			yyerror("arguments to PCDATA must be integer constants");
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 116:
-#line 603 "a.y"
-    {
-		if((yyvsp[(2) - (4)].addr).type != TYPE_CONST)
-			yyerror("index for FUNCDATA must be integer constant");
-		if((yyvsp[(4) - (4)].addr).type != NAME_EXTERN && (yyvsp[(4) - (4)].addr).type != NAME_STATIC && (yyvsp[(4) - (4)].addr).type != TYPE_MEM)
-			yyerror("value for FUNCDATA must be symbol reference");
- 		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 117:
-#line 614 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 118:
-#line 621 "a.y"
-    {
-		settext((yyvsp[(2) - (5)].addr).sym);
-		outcode((yyvsp[(1) - (5)].lval), &(yyvsp[(2) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
-	}
-    break;
-
-  case 119:
-#line 626 "a.y"
-    {
-		settext((yyvsp[(2) - (7)].addr).sym);
-		outcode((yyvsp[(1) - (7)].lval), &(yyvsp[(2) - (7)].addr), 0, &(yyvsp[(7) - (7)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (7)].lval);
-		}
-	}
-    break;
-
-  case 120:
-#line 638 "a.y"
-    {
-		settext((yyvsp[(2) - (4)].addr).sym);
-		outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
-	}
-    break;
-
-  case 121:
-#line 643 "a.y"
-    {
-		settext((yyvsp[(2) - (6)].addr).sym);
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 122:
-#line 656 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 123:
-#line 664 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 124:
-#line 672 "a.y"
-    {
-		outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), 0, &(yyvsp[(6) - (6)].addr));
-		if(pass > 1) {
-			lastpc->from3.type = TYPE_CONST;
-			lastpc->from3.offset = (yyvsp[(4) - (6)].lval);
-		}
-	}
-    break;
-
-  case 125:
-#line 683 "a.y"
-    {
-		outcode((yyvsp[(1) - (2)].lval), &nullgen, 0, &nullgen);
-	}
-    break;
-
-  case 126:
-#line 689 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
-	}
-    break;
-
-  case 127:
-#line 695 "a.y"
-    {
-		(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
-		(yyval.addr) = nullgen;
-		if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
-			yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
-		(yyval.addr).type = TYPE_BRANCH;
-		(yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 128:
-#line 706 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 131:
-#line 718 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 132:
-#line 726 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);	/* whole register */
-	}
-    break;
-
-  case 133:
-#line 734 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 134:
-#line 742 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 135:
-#line 750 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 136:
-#line 756 "a.y"
-    {
-		if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= 1024)
-			yyerror("SPR/DCR out of range");
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (4)].lval) + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 138:
-#line 767 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 139:
-#line 775 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 140:
-#line 781 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = REG_F0 + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 141:
-#line 789 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 142:
-#line 795 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = REG_C0 + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 143:
-#line 803 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_REG;
-		(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
-	}
-    break;
-
-  case 144:
-#line 811 "a.y"
-    {
-		int mb, me;
-		uint32 v;
-
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		mb = (yyvsp[(1) - (3)].lval);
-		me = (yyvsp[(3) - (3)].lval);
-		if(mb < 0 || mb > 31 || me < 0 || me > 31){
-			yyerror("illegal mask start/end value(s)");
-			mb = me = 0;
-		}
-		if(mb <= me)
-			v = ((uint32)~0L>>mb) & (~0L<<(31-me));
-		else
-			v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
-		(yyval.addr).offset = v;
-	}
-    break;
-
-  case 145:
-#line 832 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 146:
-#line 839 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (2)].lval);
-		(yyval.addr).u.argsize = ArgsSizeUnknown;
-	}
-    break;
-
-  case 147:
-#line 846 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = (yyvsp[(1) - (3)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 148:
-#line 853 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_TEXTSIZE;
-		(yyval.addr).offset = -(yyvsp[(2) - (4)].lval);
-		(yyval.addr).u.argsize = (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 149:
-#line 862 "a.y"
-    {
-		(yyval.addr) = (yyvsp[(2) - (2)].addr);
-		(yyval.addr).type = TYPE_ADDR;
-	}
-    break;
-
-  case 150:
-#line 867 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_SCONST;
-		memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
-	}
-    break;
-
-  case 151:
-#line 875 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
-	}
-    break;
-
-  case 152:
-#line 881 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_FCONST;
-		(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
-	}
-    break;
-
-  case 153:
-#line 888 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_CONST;
-		(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 155:
-#line 897 "a.y"
-    {
-		if((yyval.lval) < 0 || (yyval.lval) >= NREG)
-			print("register value out of range\n");
-		(yyval.lval) = REG_R0 + (yyvsp[(3) - (4)].lval);
-	}
-    break;
-
-  case 156:
-#line 905 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (3)].lval);
-		(yyval.addr).offset = 0;
-	}
-    break;
-
-  case 157:
-#line 912 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(2) - (5)].lval);
-		(yyval.addr).scale = (yyvsp[(4) - (5)].lval);
-		(yyval.addr).offset = 0;
-	}
-    break;
-
-  case 159:
-#line 923 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 160:
-#line 932 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(3) - (4)].lval);
-		(yyval.addr).sym = nil;
-		(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
-	}
-    break;
-
-  case 161:
-#line 940 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = (yyvsp[(4) - (5)].lval);
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
-		(yyval.addr).offset = (yyvsp[(2) - (5)].lval);
-	}
-    break;
-
-  case 162:
-#line 948 "a.y"
-    {
-		(yyval.addr) = nullgen;
-		(yyval.addr).type = TYPE_MEM;
-		(yyval.addr).name = NAME_STATIC;
-		(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
-		(yyval.addr).offset = (yyvsp[(4) - (7)].lval);
-	}
-    break;
-
-  case 165:
-#line 960 "a.y"
-    {
-		(yyval.lval) = 0;
-	}
-    break;
-
-  case 166:
-#line 964 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 167:
-#line 968 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 172:
-#line 980 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
-	}
-    break;
-
-  case 173:
-#line 984 "a.y"
-    {
-		(yyval.lval) = -(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 174:
-#line 988 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 175:
-#line 992 "a.y"
-    {
-		(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
-	}
-    break;
-
-  case 176:
-#line 996 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(2) - (3)].lval);
-	}
-    break;
-
-  case 178:
-#line 1003 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 179:
-#line 1007 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 180:
-#line 1011 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 181:
-#line 1015 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 182:
-#line 1019 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 183:
-#line 1023 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 184:
-#line 1027 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
-	}
-    break;
-
-  case 185:
-#line 1031 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 186:
-#line 1035 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-  case 187:
-#line 1039 "a.y"
-    {
-		(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
-	}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 3253 "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);
-}
-
-
-
diff --git a/src/cmd/9a/y.tab.h b/src/cmd/9a/y.tab.h
deleted file mode 100644
index e7b0033..0000000
--- a/src/cmd/9a/y.tab.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/* 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 {
-     LMOVW = 258,
-     LMOVB = 259,
-     LABS = 260,
-     LLOGW = 261,
-     LSHW = 262,
-     LADDW = 263,
-     LCMP = 264,
-     LCROP = 265,
-     LBRA = 266,
-     LFMOV = 267,
-     LFCONV = 268,
-     LFCMP = 269,
-     LFADD = 270,
-     LFMA = 271,
-     LTRAP = 272,
-     LXORW = 273,
-     LNOP = 274,
-     LEND = 275,
-     LRETT = 276,
-     LWORD = 277,
-     LTEXT = 278,
-     LGLOBL = 279,
-     LDATA = 280,
-     LRETRN = 281,
-     LCONST = 282,
-     LSP = 283,
-     LSB = 284,
-     LFP = 285,
-     LPC = 286,
-     LCREG = 287,
-     LFLUSH = 288,
-     LREG = 289,
-     LFREG = 290,
-     LR = 291,
-     LCR = 292,
-     LF = 293,
-     LFPSCR = 294,
-     LLR = 295,
-     LCTR = 296,
-     LSPR = 297,
-     LSPREG = 298,
-     LSEG = 299,
-     LMSR = 300,
-     LPCDAT = 301,
-     LFUNCDAT = 302,
-     LSCHED = 303,
-     LXLD = 304,
-     LXST = 305,
-     LXOP = 306,
-     LXMV = 307,
-     LRLWM = 308,
-     LMOVMW = 309,
-     LMOVEM = 310,
-     LMOVFL = 311,
-     LMTFSB = 312,
-     LMA = 313,
-     LFCONST = 314,
-     LSCONST = 315,
-     LNAME = 316,
-     LLAB = 317,
-     LVAR = 318
-   };
-#endif
-/* Tokens.  */
-#define LMOVW 258
-#define LMOVB 259
-#define LABS 260
-#define LLOGW 261
-#define LSHW 262
-#define LADDW 263
-#define LCMP 264
-#define LCROP 265
-#define LBRA 266
-#define LFMOV 267
-#define LFCONV 268
-#define LFCMP 269
-#define LFADD 270
-#define LFMA 271
-#define LTRAP 272
-#define LXORW 273
-#define LNOP 274
-#define LEND 275
-#define LRETT 276
-#define LWORD 277
-#define LTEXT 278
-#define LGLOBL 279
-#define LDATA 280
-#define LRETRN 281
-#define LCONST 282
-#define LSP 283
-#define LSB 284
-#define LFP 285
-#define LPC 286
-#define LCREG 287
-#define LFLUSH 288
-#define LREG 289
-#define LFREG 290
-#define LR 291
-#define LCR 292
-#define LF 293
-#define LFPSCR 294
-#define LLR 295
-#define LCTR 296
-#define LSPR 297
-#define LSPREG 298
-#define LSEG 299
-#define LMSR 300
-#define LPCDAT 301
-#define LFUNCDAT 302
-#define LSCHED 303
-#define LXLD 304
-#define LXST 305
-#define LXOP 306
-#define LXMV 307
-#define LRLWM 308
-#define LMOVMW 309
-#define LMOVEM 310
-#define LMOVFL 311
-#define LMTFSB 312
-#define LMA 313
-#define LFCONST 314
-#define LSCONST 315
-#define LNAME 316
-#define LLAB 317
-#define LVAR 318
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 38 "a.y"
-{
-	Sym	*sym;
-	vlong	lval;
-	double	dval;
-	char	sval[8];
-	Addr	addr;
-}
-/* Line 1529 of yacc.c.  */
-#line 183 "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/9g/cgen.c b/src/cmd/9g/cgen.c
deleted file mode 100644
index 009ea1e..0000000
--- a/src/cmd/9g/cgen.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-// 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"
-
-/*
- * generate:
- *	res = n;
- * simplifies and calls gmove.
- */
-void
-cgen(Node *n, Node *res)
-{
-	Node *nl, *nr, *r;
-	Node n1, n2;
-	int a, f;
-	Prog *p1, *p2, *p3;
-	Addr addr;
-
-//print("cgen %N(%d) -> %N(%d)\n", n, n->addable, res, res->addable);
-	if(debug['g']) {
-		dump("\ncgen-n", n);
-		dump("cgen-res", res);
-	}
-	if(n == N || n->type == T)
-		goto ret;
-
-	if(res == N || res->type == T)
-		fatal("cgen: res nil");
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	switch(n->op) {
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_slice(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_slice(n, res);
-		goto ret;
-	case OEFACE:
-		if (res->op != ONAME || !res->addable) {
-			tempname(&n1, n->type);
-			cgen_eface(n, &n1);
-			cgen(&n1, res);
-		} else
-			cgen_eface(n, res);
-		goto ret;
-	}
-
-	if(n->ullman >= UINF) {
-		if(n->op == OINDREG)
-			fatal("cgen: this is going to misscompile");
-		if(res->ullman >= UINF) {
-			tempname(&n1, n->type);
-			cgen(n, &n1);
-			cgen(&n1, res);
-			goto ret;
-		}
-	}
-
-	if(isfat(n->type)) {
-		if(n->type->width < 0)
-			fatal("forgot to compute width for %T", n->type);
-		sgen(n, res, n->type->width);
-		goto ret;
-	}
-
-	if(!res->addable) {
-		if(n->ullman > res->ullman) {
-			regalloc(&n1, n->type, res);
-			cgen(n, &n1);
-			if(n1.ullman > res->ullman) {
-				dump("n1", &n1);
-				dump("res", res);
-				fatal("loop in cgen");
-			}
-			cgen(&n1, res);
-			regfree(&n1);
-			goto ret;
-		}
-
-		if(res->ullman >= UINF)
-			goto gen;
-
-		if(complexop(n, res)) {
-			complexgen(n, res);
-			goto ret;
-		}
-
-		f = 1;	// gen thru register
-		switch(n->op) {
-		case OLITERAL:
-			if(smallintconst(n))
-				f = 0;
-			break;
-		case OREGISTER:
-			f = 0;
-			break;
-		}
-
-		if(!iscomplex[n->type->etype]) {
-			a = optoas(OAS, res->type);
-			if(sudoaddable(a, res, &addr)) {
-				if(f) {
-					regalloc(&n2, res->type, N);
-					cgen(n, &n2);
-					p1 = gins(a, &n2, N);
-					regfree(&n2);
-				} else
-					p1 = gins(a, n, N);
-				p1->to = addr;
-				if(debug['g'])
-					print("%P [ignore previous line]\n", p1);
-				sudoclean();
-				goto ret;
-			}
-		}
-
-	gen:
-		igen(res, &n1, N);
-		cgen(n, &n1);
-		regfree(&n1);
-		goto ret;
-	}
-
-	// update addressability for string, slice
-	// can't do in walk because n->left->addable
-	// changes if n->left is an escaping local variable.
-	switch(n->op) {
-	case OSPTR:
-	case OLEN:
-		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
-			n->addable = n->left->addable;
-		break;
-	case OCAP:
-		if(isslice(n->left->type))
-			n->addable = n->left->addable;
-		break;
-	case OITAB:
-		n->addable = n->left->addable;
-		break;
-	}
-
-	if(complexop(n, res)) {
-		complexgen(n, res);
-		goto ret;
-	}
-
-	// if both are addressable, move
-	if(n->addable) {
-		if(n->op == OREGISTER || res->op == OREGISTER) {
-			gmove(n, res);
-		} else {
-			regalloc(&n1, n->type, N);
-			gmove(n, &n1);
-			cgen(&n1, res);
-			regfree(&n1);
-		}
-		goto ret;
-	}
-
-	nl = n->left;
-	nr = n->right;
-
-	if(nl != N && nl->ullman >= UINF)
-	if(nr != N && nr->ullman >= UINF) {
-		tempname(&n1, nl->type);
-		cgen(nl, &n1);
-		n2 = *n;
-		n2.left = &n1;
-		cgen(&n2, res);
-		goto ret;
-	}
-
-	if(!iscomplex[n->type->etype]) {
-		a = optoas(OAS, n->type);
-		if(sudoaddable(a, n, &addr)) {
-			if(res->op == OREGISTER) {
-				p1 = gins(a, N, res);
-				p1->from = addr;
-			} else {
-				regalloc(&n2, n->type, N);
-				p1 = gins(a, N, &n2);
-				p1->from = addr;
-				gins(a, &n2, res);
-				regfree(&n2);
-			}
-			sudoclean();
-			goto ret;
-		}
-	}
-
-	// TODO(minux): we shouldn't reverse FP comparisons, but then we need to synthesize
-	// OGE, OLE, and ONE ourselves.
-	// if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) goto flt;
-
-	switch(n->op) {
-	default:
-		dump("cgen", n);
-		fatal("cgen: unknown op %+hN", n);
-		break;
-
-	// these call bgen to get a bool value
-	case OOROR:
-	case OANDAND:
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OLE:
-	case OGE:
-	case OGT:
-	case ONOT:
-		p1 = gbranch(ABR, T, 0);
-		p2 = pc;
-		gmove(nodbool(1), res);
-		p3 = gbranch(ABR, T, 0);
-		patch(p1, pc);
-		bgen(n, 1, 0, p2);
-		gmove(nodbool(0), res);
-		patch(p3, pc);
-		goto ret;
-
-	case OPLUS:
-		cgen(nl, res);
-		goto ret;
-
-	// unary
-	case OCOM:
-		a = optoas(OXOR, nl->type);
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-		nodconst(&n2, nl->type, -1);
-		gins(a, &n2, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		goto ret;
-
-	case OMINUS:
-		if(isfloat[nl->type->etype]) {
-			nr = nodintconst(-1);
-			convlit(&nr, n->type);
-			a = optoas(OMUL, nl->type);
-			goto sbop;
-		}
-		a = optoas(n->op, nl->type);
-		goto uop;
-
-	// symmetric binary
-	case OAND:
-	case OOR:
-	case OXOR:
-	case OADD:
-	case OMUL:
-		a = optoas(n->op, nl->type);
-		goto sbop;
-
-	// asymmetric binary
-	case OSUB:
-		a = optoas(n->op, nl->type);
-		goto abop;
-
-	case OHMUL:
-		cgen_hmul(nl, nr, res);
-		break;
-
-	case OCONV:
-		if(n->type->width > nl->type->width) {
-			// If loading from memory, do conversion during load,
-			// so as to avoid use of 8-bit register in, say, int(*byteptr).
-			switch(nl->op) {
-			case ODOT:
-			case ODOTPTR:
-			case OINDEX:
-			case OIND:
-			case ONAME:
-				igen(nl, &n1, res);
-				regalloc(&n2, n->type, res);
-				gmove(&n1, &n2);
-				gmove(&n2, res);
-				regfree(&n2);
-				regfree(&n1);
-				goto ret;
-			}
-		}
-
-		regalloc(&n1, nl->type, res);
-		regalloc(&n2, n->type, &n1);
-		cgen(nl, &n1);
-
-		// if we do the conversion n1 -> n2 here
-		// reusing the register, then gmove won't
-		// have to allocate its own register.
-		gmove(&n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		regfree(&n1);
-		break;
-
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OIND:
-	case ONAME:	// PHEAP or PPARAMREF var
-		igen(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-	
-	case OITAB:
-		// interface table is first word of interface value
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OSPTR:
-		// pointer is the first word of string or slice.
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n1, types[tptr], res);
-			p1 = gins(AMOVD, N, &n1);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		igen(nl, &n1, res);
-		n1.type = n->type;
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case OLEN:
-		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
-			// map and chan have len in the first int-sized word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.type = types[simtype[TINT]];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
-			// both slice and string have len one pointer into the struct.
-			// a zero pointer means zero length
-			igen(nl, &n1, res);
-			n1.type = types[simtype[TUINT]];
-			n1.xoffset += Array_nel;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OLEN: unknown type %lT", nl->type);
-		break;
-
-	case OCAP:
-		if(istype(nl->type, TCHAN)) {
-			// chan has cap in the second int-sized word.
-			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
-			cgen(nl, &n1);
-
-			nodconst(&n2, types[tptr], 0);
-			gins(optoas(OCMP, types[tptr]), &n1, &n2);
-			p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
-
-			n2 = n1;
-			n2.op = OINDREG;
-			n2.xoffset = widthint;
-			n2.type = types[simtype[TINT]];
-			gmove(&n2, &n1);
-
-			patch(p1, pc);
-
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		if(isslice(nl->type)) {
-			igen(nl, &n1, res);
-			n1.type = types[simtype[TUINT]];
-			n1.xoffset += Array_cap;
-			gmove(&n1, res);
-			regfree(&n1);
-			break;
-		}
-		fatal("cgen: OCAP: unknown type %lT", nl->type);
-		break;
-
-	case OADDR:
-		if(n->bounded) // let race detector avoid nil checks
-			disable_checknil++;
-		agen(nl, res);
-		if(n->bounded)
-			disable_checknil--;
-		break;
-
-	case OCALLMETH:
-		cgen_callmeth(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_callret(n, res);
-		break;
-
-	case OMOD:
-	case ODIV:
-		if(isfloat[n->type->etype]) {
-			a = optoas(n->op, nl->type);
-			goto abop;
-		}
-
-		if(nl->ullman >= nr->ullman) {
-			regalloc(&n1, nl->type, res);
-			cgen(nl, &n1);
-			cgen_div(n->op, &n1, nr, res);
-			regfree(&n1);
-		} else {
-			if(!smallintconst(nr)) {
-				regalloc(&n2, nr->type, res);
-				cgen(nr, &n2);
-			} else {
-				n2 = *nr;
-			}
-			cgen_div(n->op, nl, &n2, res);
-			if(n2.op != OLITERAL)
-				regfree(&n2);
-		}
-		break;
-
-	case OLSH:
-	case ORSH:
-	case OLROT:
-		cgen_shift(n->op, n->bounded, nl, nr, res);
-		break;
-	}
-	goto ret;
-
-sbop:	// symmetric binary
-	/*
-	 * put simplest on right - we'll generate into left
-	 * and then adjust it using the computation of right.
-	 * constants and variables have the same ullman
-	 * count, so look for constants specially.
-	 *
-	 * an integer constant we can use as an immediate
-	 * is simpler than a variable - we can use the immediate
-	 * in the adjustment instruction directly - so it goes
-	 * on the right.
-	 *
-	 * other constants, like big integers or floating point
-	 * constants, require a mov into a register, so those
-	 * might as well go on the left, so we can reuse that
-	 * register for the computation.
-	 */
-	if(nl->ullman < nr->ullman ||
-	   (nl->ullman == nr->ullman &&
-	    (smallintconst(nl) || (nr->op == OLITERAL && !smallintconst(nr))))) {
-		r = nl;
-		nl = nr;
-		nr = r;
-	}
-
-abop:	// asymmetric binary
-	if(nl->ullman >= nr->ullman) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-	/*
-	 * This generates smaller code - it avoids a MOV - but it's
-	 * easily 10% slower due to not being able to
-	 * optimize/manipulate the move.
-	 * To see, run: go test -bench . crypto/md5
-	 * with and without.
-	 *
-		if(sudoaddable(a, nr, &addr)) {
-			p1 = gins(a, N, &n1);
-			p1->from = addr;
-			gmove(&n1, res);
-			sudoclean();
-			regfree(&n1);
-			goto ret;
-		}
-	 *
-	 */
-		// TODO(minux): enable using constants directly in certain instructions.
-		//if(smallintconst(nr))
-		//	n2 = *nr;
-		//else {
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-		//}
-	} else {
-		//if(smallintconst(nr))
-		//	n2 = *nr;
-		//else {
-			regalloc(&n2, nr->type, res);
-			cgen(nr, &n2);
-		//}
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-	}
-	gins(a, &n2, &n1);
-	// Normalize result for types smaller than word.
-	if(n->type->width < widthreg) {
-		switch(n->op) {
-		case OADD:
-		case OSUB:
-		case OMUL:
-		case OLSH:
-			gins(optoas(OAS, n->type), &n1, &n1);
-			break;
-		}
-	}
-	gmove(&n1, res);
-	regfree(&n1);
-	if(n2.op != OLITERAL)
-		regfree(&n2);
-	goto ret;
-
-uop:	// unary
-	regalloc(&n1, nl->type, res);
-	cgen(nl, &n1);
-	gins(a, N, &n1);
-	gmove(&n1, res);
-	regfree(&n1);
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * allocate a register (reusing res if possible) and generate
- *  a = n
- * The caller must call regfree(a).
- */
-void
-cgenr(Node *n, Node *a, Node *res)
-{
-	Node n1;
-
-	if(debug['g'])
-		dump("cgenr-n", n);
-
-	if(isfat(n->type))
-		fatal("cgenr on fat node");
-
-	if(n->addable) {
-		regalloc(a, n->type, res);
-		gmove(n, a);
-		return;
-	}
-
-	switch(n->op) {
-	case ONAME:
-	case ODOT:
-	case ODOTPTR:
-	case OINDEX:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		gmove(&n1, a);
-		regfree(&n1);
-		break;
-	default:
-		regalloc(a, n->type, res);
-		cgen(n, a);
-		break;
-	}
-}
-
-/*
- * allocate a register (reusing res if possible) and generate
- * a = &n
- * The caller must call regfree(a).
- * The generated code checks that the result is not nil.
- */
-void
-agenr(Node *n, Node *a, Node *res)
-{
-	Node *nl, *nr;
-	Node n1, n2, n3, n4, tmp;
-	Prog *p1, *p2;
-	uint32 w;
-	uint64 v;
-
-	if(debug['g'])
-		dump("agenr-n", n);
-
-	nl = n->left;
-	nr = n->right;
-
-	switch(n->op) {
-	case ODOT:
-	case ODOTPTR:
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		igen(n, &n1, res);
-		regalloc(a, types[tptr], &n1);
-		agen(&n1, a);
-		regfree(&n1);
-		break;
-
-	case OIND:
-		cgenr(n->left, a, res);
-		cgen_checknil(a);
-		break;
-
-	case OINDEX:
-		p2 = nil;  // to be patched to panicindex.
-		w = n->type->width;
-		//bounded = debug['B'] || n->bounded;
-		if(nr->addable) {
-			if(!isconst(nr, CTINT))
-				tempname(&tmp, types[TINT64]);
-			if(!isconst(nl, CTSTR))
-				agenr(nl, &n3, res);
-			if(!isconst(nr, CTINT)) {
-				cgen(nr, &tmp);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-		} else if(nl->addable) {
-			if(!isconst(nr, CTINT)) {
-				tempname(&tmp, types[TINT64]);
-				cgen(nr, &tmp);
-				regalloc(&n1, tmp.type, N);
-				gmove(&tmp, &n1);
-			}
-			if(!isconst(nl, CTSTR)) {
-				agenr(nl, &n3, res);
-			}
-		} else {
-			tempname(&tmp, types[TINT64]);
-			cgen(nr, &tmp);
-			nr = &tmp;
-			if(!isconst(nl, CTSTR))
-				agenr(nl, &n3, res);
-			regalloc(&n1, tmp.type, N);
-			gins(optoas(OAS, tmp.type), &tmp, &n1);
-		}
-
-		// &a is in &n3 (allocated in res)
-		// i is in &n1 (if not constant)
-		// w is width
-
-		// constant index
-		if(isconst(nr, CTINT)) {
-			if(isconst(nl, CTSTR))
-				fatal("constant string constant index");
-			v = mpgetfix(nr->val.u.xval);
-			if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				if(!debug['B'] && !n->bounded) {
-					n1 = n3;
-					n1.op = OINDREG;
-					n1.type = types[tptr];
-					n1.xoffset = Array_nel;
-					regalloc(&n4, n1.type, N);
-					gmove(&n1, &n4);
-					ginscon2(optoas(OCMP, types[TUINT64]), &n4, v);
-					regfree(&n4);
-					p1 = gbranch(optoas(OGT, types[TUINT64]), T, +1);
-					ginscall(panicindex, 0);
-					patch(p1, pc);
-				}
-
-				n1 = n3;
-				n1.op = OINDREG;
-				n1.type = types[tptr];
-				n1.xoffset = Array_array;
-				gmove(&n1, &n3);
-			}
-
-			if (v*w != 0) {
-				ginscon(optoas(OADD, types[tptr]), v*w, &n3);
-			}
-			*a = n3;
-			break;
-		}
-
-		regalloc(&n2, types[TINT64], &n1);			// i
-		gmove(&n1, &n2);
-		regfree(&n1);
-
-		if(!debug['B'] && !n->bounded) {
-			// check bounds
-			if(isconst(nl, CTSTR)) {
-				nodconst(&n4, types[TUINT64], nl->val.u.sval->len);
-			} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
-				n1 = n3;
-				n1.op = OINDREG;
-				n1.type = types[tptr];
-				n1.xoffset = Array_nel;
-				regalloc(&n4, types[TUINT64], N);
-				gmove(&n1, &n4);
-			} else {
-				if(nl->type->bound < (1<<15)-1)
-					nodconst(&n4, types[TUINT64], nl->type->bound);
-				else {
-					regalloc(&n4, types[TUINT64], N);
-					p1 = gins(AMOVD, N, &n4);
-					p1->from.type = TYPE_CONST;
-					p1->from.offset = nl->type->bound;
-				}
-			}
-			gins(optoas(OCMP, types[TUINT64]), &n2, &n4);
-			if(n4.op == OREGISTER)
-				regfree(&n4);
-			p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
-			if(p2)
-				patch(p2, pc);
-			ginscall(panicindex, 0);
-			patch(p1, pc);
-		}
-		
-		if(isconst(nl, CTSTR)) {
-			regalloc(&n3, types[tptr], res);
-			p1 = gins(AMOVD, N, &n3);
-			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			p1->from.type = TYPE_ADDR;
-		} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
-			n1 = n3;
-			n1.op = OINDREG;
-			n1.type = types[tptr];
-			n1.xoffset = Array_array;
-			gmove(&n1, &n3);
-		}
-
-		if(w == 0) {
-			// nothing to do
-		} else if(w == 1) {
-			/* w already scaled */
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-		} /* else if(w == 2 || w == 4 || w == 8) {
-			// TODO(minux): scale using shift
-		} */ else {
-			regalloc(&n4, types[TUINT64], N);
-			nodconst(&n1, types[TUINT64], w);
-			gmove(&n1, &n4);
-			gins(optoas(OMUL, types[TUINT64]), &n4, &n2);
-			gins(optoas(OADD, types[tptr]), &n2, &n3);
-			regfree(&n4);
-		}
-
-		*a = n3;
-		regfree(&n2);
-		break;
-
-	default:
-		regalloc(a, types[tptr], res);
-		agen(n, a);
-		break;
-	}
-}
-
-static void
-ginsadd(int as, vlong off, Node *dst)
-{
-	Node n1;
-
-	regalloc(&n1, types[tptr], dst);
-	gmove(dst, &n1);
-	ginscon(as, off, &n1);
-	gmove(&n1, dst);
-	regfree(&n1);
-}
-
-/*
- * generate:
- *	res = &n;
- * The generated code checks that the result is not nil.
- */
-void
-agen(Node *n, Node *res)
-{
-	Node *nl;
-	Node n1, n2, n3;
-
-	if(debug['g']) {
-		dump("\nagen-res", res);
-		dump("agen-r", n);
-	}
-	if(n == N || n->type == T)
-		return;
-
-	while(n->op == OCONVNOP)
-		n = n->left;
-
-	if(isconst(n, CTNIL) && n->type->width > widthptr) {
-		// Use of a nil interface or nil slice.
-		// Create a temporary we can take the address of and read.
-		// The generated code is just going to panic, so it need not
-		// be terribly efficient. See issue 3670.
-		tempname(&n1, n->type);
-		gvardef(&n1);
-		clearfat(&n1);
-		regalloc(&n2, types[tptr], res);
-		memset(&n3, 0, sizeof n3);
-		n3.op = OADDR;
-		n3.left = &n1;
-		gins(AMOVD, &n3, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		goto ret;
-	}
-		
-	if(n->addable) {
-		memset(&n1, 0, sizeof n1);
-		n1.op = OADDR;
-		n1.left = n;
-		regalloc(&n2, types[tptr], res);
-		gins(AMOVD, &n1, &n2);
-		gmove(&n2, res);
-		regfree(&n2);
-		goto ret;
-	}
-
-	nl = n->left;
-
-	switch(n->op) {
-	default:
-		fatal("agen: unknown op %+hN", n);
-		break;
-
-	case OCALLMETH:
-		// TODO(minux): 5g has this: Release res so that it is available for cgen_call.
-		// Pick it up again after the call for OCALLMETH and OCALLFUNC.
-		cgen_callmeth(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLINTER:
-		cgen_callinter(n, res, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OCALLFUNC:
-		cgen_call(n, 0);
-		cgen_aret(n, res);
-		break;
-
-	case OSLICE:
-	case OSLICEARR:
-	case OSLICESTR:
-	case OSLICE3:
-	case OSLICE3ARR:
-		tempname(&n1, n->type);
-		cgen_slice(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OEFACE:
-		tempname(&n1, n->type);
-		cgen_eface(n, &n1);
-		agen(&n1, res);
-		break;
-
-	case OINDEX:
-		agenr(n, &n1, res);
-		gmove(&n1, res);
-		regfree(&n1);
-		break;
-
-	case ONAME:
-		// should only get here with names in this func.
-		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME funcdepth %d != %d",
-				n->funcdepth, funcdepth);
-		}
-
-		// should only get here for heap vars or paramref
-		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
-			dump("bad agen", n);
-			fatal("agen: bad ONAME class %#x", n->class);
-		}
-		cgen(n->heapaddr, res);
-		if(n->xoffset != 0) {
-			ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
-		}
-		break;
-
-	case OIND:
-		cgen(nl, res);
-		cgen_checknil(res);
-		break;
-
-	case ODOT:
-		agen(nl, res);
-		if(n->xoffset != 0) {
-			ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
-		}
-		break;
-
-	case ODOTPTR:
-		cgen(nl, res);
-		cgen_checknil(res);
-		if(n->xoffset != 0) {
-			ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
-		}
-		break;
-	}
-
-ret:
-	;
-}
-
-/*
- * generate:
- *	newreg = &n;
- *	res = newreg
- *
- * on exit, a has been changed to be *newreg.
- * caller must regfree(a).
- * The generated code checks that the result is not *nil.
- */
-void
-igen(Node *n, Node *a, Node *res)
-{
-	Type *fp;
-	Iter flist;
-	Node n1;
-
-	if(debug['g']) {
-		dump("\nigen-n", n);
-	}
-	switch(n->op) {
-	case ONAME:
-		if((n->class&PHEAP) || n->class == PPARAMREF)
-			break;
-		*a = *n;
-		return;
-
-	case OINDREG:
-		// Increase the refcount of the register so that igen's caller
-		// has to call regfree.
-		if(n->val.u.reg != REGSP)
-			reg[n->val.u.reg]++;
-		*a = *n;
-		return;
-
-	case ODOT:
-		igen(n->left, a, res);
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		fixlargeoffset(a);
-		return;
-
-	case ODOTPTR:
-		cgenr(n->left, a, res);
-		cgen_checknil(a);
-		a->op = OINDREG;
-		a->xoffset += n->xoffset;
-		a->type = n->type;
-		fixlargeoffset(a);
-		return;
-
-	case OCALLFUNC:
-	case OCALLMETH:
-	case OCALLINTER:
-		switch(n->op) {
-		case OCALLFUNC:
-			cgen_call(n, 0);
-			break;
-		case OCALLMETH:
-			cgen_callmeth(n, 0);
-			break;
-		case OCALLINTER:
-			cgen_callinter(n, N, 0);
-			break;
-		}
-		fp = structfirst(&flist, getoutarg(n->left->type));
-		memset(a, 0, sizeof *a);
-		a->op = OINDREG;
-		a->val.u.reg = REGSP;
-		a->addable = 1;
-		a->xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
-		a->type = n->type;
-		return;
-
-	case OINDEX:
-		// Index of fixed-size array by constant can
-		// put the offset in the addressing.
-		// Could do the same for slice except that we need
-		// to use the real index for the bounds checking.
-		if(isfixedarray(n->left->type) ||
-		   (isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
-		if(isconst(n->right, CTINT)) {
-			// Compute &a.
-			if(!isptr[n->left->type->etype])
-				igen(n->left, a, res);
-			else {
-				igen(n->left, &n1, res);
-				cgen_checknil(&n1);
-				regalloc(a, types[tptr], res);
-				gmove(&n1, a);
-				regfree(&n1);
-				a->op = OINDREG;
-			}
-
-			// Compute &a[i] as &a + i*width.
-			a->type = n->type;
-			a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
-			fixlargeoffset(a);
-			return;
-		}
-		break;
-	}
-
-	agenr(n, a, res);
-	a->op = OINDREG;
-	a->type = n->type;
-}
-
-/*
- * generate:
- *	if(n == true) goto to;
- */
-void
-bgen(Node *n, int true, int likely, Prog *to)
-{
-	int et, a;
-	Node *nl, *nr, *l, *r;
-	Node n1, n2, tmp;
-	NodeList *ll;
-	Prog *p1, *p2;
-
-	if(debug['g']) {
-		dump("\nbgen", n);
-	}
-
-	if(n == N)
-		n = nodbool(1);
-
-	if(n->ninit != nil)
-		genlist(n->ninit);
-
-	if(n->type == T) {
-		convlit(&n, types[TBOOL]);
-		if(n->type == T)
-			goto ret;
-	}
-
-	et = n->type->etype;
-	if(et != TBOOL) {
-		yyerror("cgen: bad type %T for %O", n->type, n->op);
-		patch(gins(AEND, N, N), to);
-		goto ret;
-	}
-	nr = N;
-
-	while(n->op == OCONVNOP) {
-		n = n->left;
-		if(n->ninit != nil)
-			genlist(n->ninit);
-	}
-
-	switch(n->op) {
-	default:
-		regalloc(&n1, n->type, N);
-		cgen(n, &n1);
-		nodconst(&n2, n->type, 0);
-		gins(optoas(OCMP, n->type), &n1, &n2);
-		a = ABNE;
-		if(!true)
-			a = ABEQ;
-		patch(gbranch(a, n->type, likely), to);
-		regfree(&n1);
-		goto ret;
-
-	case OLITERAL:
-		// need to ask if it is bool?
-		if(!true == !n->val.u.bval)
-			patch(gbranch(ABR, T, likely), to);
-		goto ret;
-
-	case OANDAND:
-	case OOROR:
-		if((n->op == OANDAND) == true) {
-			p1 = gbranch(AJMP, T, 0);
-			p2 = gbranch(AJMP, T, 0);
-			patch(p1, pc);
-			bgen(n->left, !true, -likely, p2);
-			bgen(n->right, !true, -likely, p2);
-			p1 = gbranch(AJMP, T, 0);
-			patch(p1, to);
-			patch(p2, pc);
-		} else {
-			bgen(n->left, true, likely, to);
-			bgen(n->right, true, likely, to);
-		}
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		nr = n->right;
-		if(nr == N || nr->type == T)
-			goto ret;
-
-	case ONOT:	// unary
-		nl = n->left;
-		if(nl == N || nl->type == T)
-			goto ret;
-		break;
-	}
-
-	switch(n->op) {
-
-	case ONOT:
-		bgen(nl, !true, likely, to);
-		goto ret;
-
-	case OEQ:
-	case ONE:
-	case OLT:
-	case OGT:
-	case OLE:
-	case OGE:
-		a = n->op;
-		if(!true) {
-			if(isfloat[nr->type->etype]) {
-				// brcom is not valid on floats when NaN is involved.
-				p1 = gbranch(ABR, T, 0);
-				p2 = gbranch(ABR, T, 0);
-				patch(p1, pc);
-				ll = n->ninit;   // avoid re-genning ninit
-				n->ninit = nil;
-				bgen(n, 1, -likely, p2);
-				n->ninit = ll;
-				patch(gbranch(ABR, T, 0), to);
-				patch(p2, pc);
-				goto ret;
-			}
-			a = brcom(a);
-			true = !true;
-		}
-
-		// make simplest on right
-		if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
-			a = brrev(a);
-			r = nl;
-			nl = nr;
-			nr = r;
-		}
-
-		if(isslice(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal slice comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.xoffset += Array_array;
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			regalloc(&n2, types[tptr], &n1);
-			gmove(&n1, &n2);
-			gins(optoas(OCMP, types[tptr]), &n2, &tmp);
-			regfree(&n2);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-
-		if(isinter(nl->type)) {
-			// front end should only leave cmp to literal nil
-			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
-				yyerror("illegal interface comparison");
-				break;
-			}
-			a = optoas(a, types[tptr]);
-			igen(nl, &n1, N);
-			n1.type = types[tptr];
-			nodconst(&tmp, types[tptr], 0);
-			regalloc(&n2, types[tptr], &n1);
-			gmove(&n1, &n2);
-			gins(optoas(OCMP, types[tptr]), &n2, &tmp);
-			regfree(&n2);
-			patch(gbranch(a, types[tptr], likely), to);
-			regfree(&n1);
-			break;
-		}
-		if(iscomplex[nl->type->etype]) {
-			complexbool(a, nl, nr, true, likely, to);
-			break;
-		}
-
-		if(nr->ullman >= UINF) {
-			regalloc(&n1, nl->type, N);
-			cgen(nl, &n1);
-
-			tempname(&tmp, nl->type);
-			gmove(&n1, &tmp);
-			regfree(&n1);
-
-			regalloc(&n2, nr->type, N);
-			cgen(nr, &n2);
-
-			regalloc(&n1, nl->type, N);
-			cgen(&tmp, &n1);
-
-			goto cmp;
-		}
-
-		regalloc(&n1, nl->type, N);
-		cgen(nl, &n1);
-
-		// TODO(minux): cmpi does accept 16-bit signed immediate as p->to.
-		// and cmpli accepts 16-bit unsigned immediate.
-		//if(smallintconst(nr)) {
-		//	gins(optoas(OCMP, nr->type), &n1, nr);
-		//	patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-		//	regfree(&n1);
-		//	break;
-		//}
-
-		regalloc(&n2, nr->type, N);
-		cgen(nr, &n2);
-	cmp:
-		l = &n1;
-		r = &n2;
-		gins(optoas(OCMP, nr->type), l, r);
-		if(isfloat[nr->type->etype] && (a == OLE || a == OGE)) {
-			// To get NaN right, must rewrite x <= y into separate x < y or x = y.
-			switch(a) {
-			case OLE:
-				a = OLT;
-				break;
-			case OGE:
-				a = OGT;
-				break;
-			}
-			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-			patch(gbranch(optoas(OEQ, nr->type), nr->type, likely), to);			
-		} else {
-			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
-		}
-		regfree(&n1);
-		regfree(&n2);
-		break;
-	}
-	goto ret;
-
-ret:
-	;
-}
-
-/*
- * n is on stack, either local variable
- * or return value from function call.
- * return n's offset from SP.
- */
-int64
-stkof(Node *n)
-{
-	Type *t;
-	Iter flist;
-	int64 off;
-
-	switch(n->op) {
-	case OINDREG:
-		return n->xoffset;
-
-	case ODOT:
-		t = n->left->type;
-		if(isptr[t->etype])
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		return off + n->xoffset;
-
-	case OINDEX:
-		t = n->left->type;
-		if(!isfixedarray(t))
-			break;
-		off = stkof(n->left);
-		if(off == -1000 || off == 1000)
-			return off;
-		if(isconst(n->right, CTINT))
-			return off + t->type->width * mpgetfix(n->right->val.u.xval);
-		return 1000;
-		
-	case OCALLMETH:
-	case OCALLINTER:
-	case OCALLFUNC:
-		t = n->left->type;
-		if(isptr[t->etype])
-			t = t->type;
-
-		t = structfirst(&flist, getoutarg(t));
-		if(t != T)
-			return t->width + widthptr;	// +widthptr: correct for saved LR
-		break;
-	}
-
-	// botch - probably failing to recognize address
-	// arithmetic on the above. eg INDEX and DOT
-	return -1000;
-}
-
-/*
- * block copy:
- *	memmove(&ns, &n, w);
- */
-void
-sgen(Node *n, Node *ns, int64 w)
-{
-	Node dst, src, tmp, nend;
-	int32 c, odst, osrc;
-	int dir, align, op;
-	Prog *p, *ploop;
-	NodeList *l;
-	Node *res = ns;
-
-	if(debug['g']) {
-		print("\nsgen w=%lld\n", w);
-		dump("r", n);
-		dump("res", ns);
-	}
-
-	if(n->ullman >= UINF && ns->ullman >= UINF)
-		fatal("sgen UINF");
-
-	if(w < 0)
-		fatal("sgen copy %lld", w);
-	
-	// If copying .args, that's all the results, so record definition sites
-	// for them for the liveness analysis.
-	if(ns->op == ONAME && strcmp(ns->sym->name, ".args") == 0)
-		for(l = curfn->dcl; l != nil; l = l->next)
-			if(l->n->class == PPARAMOUT)
-				gvardef(l->n);
-
-	// Avoid taking the address for simple enough types.
-	//if(componentgen(n, ns))
-	//	return;
-	
-	if(w == 0) {
-		// evaluate side effects only.
-		regalloc(&dst, types[tptr], N);
-		agen(res, &dst);
-		agen(n, &dst);
-		regfree(&dst);
-		return;
-	}
-
-	// determine alignment.
-	// want to avoid unaligned access, so have to use
-	// smaller operations for less aligned types.
-	// for example moving [4]byte must use 4 MOVB not 1 MOVW.
-	align = n->type->align;
-	switch(align) {
-	default:
-		fatal("sgen: invalid alignment %d for %T", align, n->type);
-	case 1:
-		op = AMOVBU;
-		break;
-	case 2:
-		op = AMOVHU;
-		break;
-	case 4:
-		op = AMOVWZU; // there is no lwau, only lwaux
-		break;
-	case 8:
-		op = AMOVDU;
-		break;
-	}
-	if(w%align)
-		fatal("sgen: unaligned size %lld (align=%d) for %T", w, align, n->type);
-	c = w / align;
-
-	// offset on the stack
-	osrc = stkof(n);
-	odst = stkof(res);
-	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
-		// osrc and odst both on stack, and at least one is in
-		// an unknown position.  Could generate code to test
-		// for forward/backward copy, but instead just copy
-		// to a temporary location first.
-		tempname(&tmp, n->type);
-		sgen(n, &tmp, w);
-		sgen(&tmp, res, w);
-		return;
-	}
-	if(osrc%align != 0 || odst%align != 0)
-		fatal("sgen: unaligned offset src %d or dst %d (align %d)", osrc, odst, align);
-
-	// if we are copying forward on the stack and
-	// the src and dst overlap, then reverse direction
-	dir = align;
-	if(osrc < odst && odst < osrc+w)
-		dir = -dir;
-
-	if(n->ullman >= res->ullman) {
-		agenr(n, &dst, res);	// temporarily use dst
-		regalloc(&src, types[tptr], N);
-		gins(AMOVD, &dst, &src);
-		if(res->op == ONAME)
-			gvardef(res);
-		agen(res, &dst);
-	} else {
-		if(res->op == ONAME)
-			gvardef(res);
-		agenr(res, &dst, res);
-		agenr(n, &src, N);
-	}
-
-	regalloc(&tmp, types[tptr], N);
-
-	// set up end marker
-	memset(&nend, 0, sizeof nend);
-
-	// move src and dest to the end of block if necessary
-	if(dir < 0) {
-		if(c >= 4) {
-			regalloc(&nend, types[tptr], N);
-			p = gins(AMOVD, &src, &nend);
-		}
-
-		p = gins(AADD, N, &src);
-		p->from.type = TYPE_CONST;
-		p->from.offset = w;
-
-		p = gins(AADD, N, &dst);
-		p->from.type = TYPE_CONST;
-		p->from.offset = w;
-	} else {
-		p = gins(AADD, N, &src);
-		p->from.type = TYPE_CONST;
-		p->from.offset = -dir;
-
-		p = gins(AADD, N, &dst);
-		p->from.type = TYPE_CONST;
-		p->from.offset = -dir;
-
-		if(c >= 4) {
-			regalloc(&nend, types[tptr], N);
-			p = gins(AMOVD, &src, &nend);
-			p->from.type = TYPE_ADDR;
-			p->from.offset = w;
-		}
-	}
-
-
-	// move
-	// TODO: enable duffcopy for larger copies.
-	if(c >= 4) {
-		p = gins(op, &src, &tmp);
-		p->from.type = TYPE_MEM;
-		p->from.offset = dir;
-		ploop = p;
-
-		p = gins(op, &tmp, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = dir;
-
-		p = gins(ACMP, &src, &nend);
-
-		patch(gbranch(ABNE, T, 0), ploop);
- 		regfree(&nend);
-	} else {
-		// TODO(austin): Instead of generating ADD $-8,R8; ADD
-		// $-8,R7; n*(MOVDU 8(R8),R9; MOVDU R9,8(R7);) just
-		// generate the offsets directly and eliminate the
-		// ADDs.  That will produce shorter, more
-		// pipeline-able code.
-		while(c-- > 0) {
-			p = gins(op, &src, &tmp);
-			p->from.type = TYPE_MEM;
-			p->from.offset = dir;
-	
-			p = gins(op, &tmp, &dst);
-			p->to.type = TYPE_MEM;
-			p->to.offset = dir;
-		}
-	}
-
-	regfree(&dst);
-	regfree(&src);
-	regfree(&tmp);
-}
-
-static int
-cadable(Node *n)
-{
-	if(!n->addable) {
-		// dont know how it happens,
-		// but it does
-		return 0;
-	}
-
-	switch(n->op) {
-	case ONAME:
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * copy a composite value by moving its individual components.
- * Slices, strings and interfaces are supported.
- * Small structs or arrays with elements of basic type are
- * also supported.
- * nr is N when assigning a zero value.
- * return 1 if can do, 0 if can't.
- */
-int
-componentgen(Node *nr, Node *nl)
-{
-	Node nodl, nodr, tmp;
-	Type *t;
-	int freel, freer;
-	vlong fldcount;
-	vlong loffset, roffset;
-
-	freel = 0;
-	freer = 0;
-
-	switch(nl->type->etype) {
-	default:
-		goto no;
-
-	case TARRAY:
-		t = nl->type;
-
-		// Slices are ok.
-		if(isslice(t))
-			break;
-		// Small arrays are ok.
-		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
-			break;
-
-		goto no;
-
-	case TSTRUCT:
-		// Small structs with non-fat types are ok.
-		// Zero-sized structs are treated separately elsewhere.
-		fldcount = 0;
-		for(t=nl->type->type; t; t=t->down) {
-			if(isfat(t->type))
-				goto no;
-			if(t->etype != TFIELD)
-				fatal("componentgen: not a TFIELD: %lT", t);
-			fldcount++;
-		}
-		if(fldcount == 0 || fldcount > 4)
-			goto no;
-
-		break;
-
-	case TSTRING:
-	case TINTER:
-		break;
-	}
-
-	nodl = *nl;
-	if(!cadable(nl)) {
-		if(nr != N && !cadable(nr))
-			goto no;
-		igen(nl, &nodl, N);
-		freel = 1;
-	}
-
-	if(nr != N) {
-		nodr = *nr;
-		if(!cadable(nr)) {
-			igen(nr, &nodr, N);
-			freer = 1;
-		}
-	} else {
-		// When zeroing, prepare a register containing zero.
-		nodconst(&tmp, nl->type, 0);
-		regalloc(&nodr, types[TUINT], N);
-		gmove(&tmp, &nodr);
-		freer = 1;
-	}
-	
-	// nl and nr are 'cadable' which basically means they are names (variables) now.
-	// If they are the same variable, don't generate any code, because the
-	// VARDEF we generate will mark the old value as dead incorrectly.
-	// (And also the assignments are useless.)
-	if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
-		goto yes;
-
-	switch(nl->type->etype) {
-	case TARRAY:
-		// componentgen for arrays.
-		if(nl->op == ONAME)
-			gvardef(nl);
-		t = nl->type;
-		if(!isslice(t)) {
-			nodl.type = t->type;
-			nodr.type = nodl.type;
-			for(fldcount=0; fldcount < t->bound; fldcount++) {
-				if(nr == N)
-					clearslim(&nodl);
-				else
-					gmove(&nodr, &nodl);
-				nodl.xoffset += t->type->width;
-				nodr.xoffset += t->type->width;
-			}
-			goto yes;
-		}
-
-		// componentgen for slices.
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(nl->type->type);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_cap-Array_nel;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_cap-Array_nel;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRING:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[simtype[TUINT]];
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TINTER:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		nodl.xoffset += Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = ptrto(types[TUINT8]);
-
-		if(nr != N) {
-			nodr.xoffset += Array_nel-Array_array;
-			nodr.type = nodl.type;
-		}
-		gmove(&nodr, &nodl);
-
-		goto yes;
-
-	case TSTRUCT:
-		if(nl->op == ONAME)
-			gvardef(nl);
-		loffset = nodl.xoffset;
-		roffset = nodr.xoffset;
-		// funarg structs may not begin at offset zero.
-		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
-			loffset -= nl->type->type->width;
-		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
-			roffset -= nr->type->type->width;
-
-		for(t=nl->type->type; t; t=t->down) {
-			nodl.xoffset = loffset + t->width;
-			nodl.type = t->type;
-
-			if(nr == N)
-				clearslim(&nodl);
-			else {
-				nodr.xoffset = roffset + t->width;
-				nodr.type = nodl.type;
-				gmove(&nodr, &nodl);
-			}
-		}
-		goto yes;
-	}
-
-no:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 0;
-
-yes:
-	if(freer)
-		regfree(&nodr);
-	if(freel)
-		regfree(&nodl);
-	return 1;
-}
diff --git a/src/cmd/new9g/cgen.go b/src/cmd/9g/cgen.go
similarity index 100%
rename from src/cmd/new9g/cgen.go
rename to src/cmd/9g/cgen.go
diff --git a/src/cmd/9g/doc.go b/src/cmd/9g/doc.go
deleted file mode 100644
index 56bb143..0000000
--- a/src/cmd/9g/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 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
-
-/*
-
-9g is the version of the gc compiler for 64-bit PowerPC or Power Architecture processors.
-The $GOARCH for these tools is ppc64 (big endian) or
-ppc64le (little endian).
-
-It reads .go files and outputs .9 files. The flags are documented in ../gc/doc.go.
-
-*/
-package main
diff --git a/src/cmd/9g/galign.c b/src/cmd/9g/galign.c
deleted file mode 100644
index 74856e2..0000000
--- a/src/cmd/9g/galign.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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"
-
-int	thechar	= '9';
-char*	thestring = "ppc64";
-LinkArch*	thelinkarch;
-
-void
-linkarchinit(void)
-{
-	thestring = getgoarch();
-	thearch.thestring = thestring;
-	if(strcmp(thestring, "ppc64le") == 0)
-		thelinkarch = &linkppc64le;
-	else
-		thelinkarch = &linkppc64;
-	thearch.thelinkarch = thelinkarch;
-}
-
-vlong MAXWIDTH = 1LL<<50;
-
-/*
- * go declares several platform-specific type aliases:
- * int, uint, float, and uintptr
- */
-Typedef	typedefs[] =
-{
-	{"int",		TINT,		TINT64},
-	{"uint",		TUINT,		TUINT64},
-	{"uintptr",	TUINTPTR,	TUINT64},
-	{0}
-};
-
-void
-betypeinit(void)
-{
-	widthptr = 8;
-	widthint = 8;
-	widthreg = 8;
-
-	listinit9();
-}
-
-void
-main(int argc, char **argv)
-{
-	thearch.thechar = thechar;
-	thearch.thestring = thestring;
-	thearch.thelinkarch = thelinkarch;
-	thearch.typedefs = typedefs;
-	thearch.REGSP = REGSP;
-	thearch.REGCTXT = REGCTXT;
-	thearch.MAXWIDTH = MAXWIDTH;
-	thearch.anyregalloc = anyregalloc;
-	thearch.betypeinit = betypeinit;
-	thearch.bgen = bgen;
-	thearch.cgen = cgen;
-	thearch.cgen_call = cgen_call;
-	thearch.cgen_callinter = cgen_callinter;
-	thearch.cgen_ret = cgen_ret;
-	thearch.clearfat = clearfat;
-	thearch.defframe = defframe;
-	thearch.excise = excise;
-	thearch.expandchecks = expandchecks;
-	thearch.gclean = gclean;
-	thearch.ginit = ginit;
-	thearch.gins = gins;
-	thearch.ginscall = ginscall;
-	thearch.igen = igen;
-	thearch.linkarchinit = linkarchinit;
-	thearch.peep = peep;
-	thearch.proginfo = proginfo;
-	thearch.regalloc = regalloc;
-	thearch.regfree = regfree;
-	thearch.regtyp = regtyp;
-	thearch.sameaddr = sameaddr;
-	thearch.smallindir = smallindir;
-	thearch.stackaddr = stackaddr;
-	thearch.excludedregs = excludedregs;
-	thearch.RtoB = RtoB;
-	thearch.FtoB = RtoB;
-	thearch.BtoR = BtoR;
-	thearch.BtoF = BtoF;
-	thearch.optoas = optoas;
-	thearch.doregbits = doregbits;
-	thearch.regnames = regnames;
-	
-	gcmain(argc, argv);
-}
diff --git a/src/cmd/new9g/galign.go b/src/cmd/9g/galign.go
similarity index 100%
rename from src/cmd/new9g/galign.go
rename to src/cmd/9g/galign.go
diff --git a/src/cmd/new9g/gg.go b/src/cmd/9g/gg.go
similarity index 100%
rename from src/cmd/new9g/gg.go
rename to src/cmd/9g/gg.go
diff --git a/src/cmd/9g/gg.h b/src/cmd/9g/gg.h
deleted file mode 100644
index 9386759..0000000
--- a/src/cmd/9g/gg.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef	EXTERN
-#define	EXTERN	extern
-#endif
-
-#include "../gc/go.h"
-#include "../9l/9.out.h"
-
-EXTERN	uchar	reg[NREG+NFREG];
-EXTERN	Node*	panicdiv;
-extern	vlong	unmappedzero;
-
-/*
- * ggen.c
- */
-void	compile(Node*);
-void	gen(Node*);
-Node*	lookdot(Node*, Node*, int);
-void	cgen_as(Node*, Node*);
-void	cgen_callmeth(Node*, int);
-void	cgen_callinter(Node*, Node*, int);
-void	cgen_proc(Node*, int);
-void	cgen_callret(Node*, Node*);
-void	cgen_div(int, Node*, Node*, Node*);
-void	cgen_hmul(Node*, Node*, Node*);
-void	cgen_shift(int, int, Node*, Node*, Node*);
-void	cgen_dcl(Node*);
-int	needconvert(Type*, Type*);
-void	genconv(Type*, Type*);
-void	allocparams(void);
-void	checklabels(void);
-void	ginscall(Node*, int);
-int	gen_as_init(Node*);
-
-/*
- * cgen.c
- */
-void	agen(Node*, Node*);
-void	agenr(Node*, Node*, Node*);
-void	cgenr(Node*, Node*, Node*);
-void	igen(Node*, Node*, Node*);
-vlong	fieldoffset(Type*, Node*);
-void	sgen(Node*, Node*, int64);
-void	gmove(Node*, Node*);
-Prog*	gins(int, Node*, Node*);
-void	naddr(Node*, Addr*, int);
-void	cgen_aret(Node*, Node*);
-int	componentgen(Node*, Node*);
-
-/*
- * gsubr.c
- */
-void	clearp(Prog*);
-Prog*	gbranch(int, Type*, int);
-Prog*	prog(int);
-void	gconv(int, int);
-int	conv2pt(Type*);
-vlong	convvtox(vlong, int);
-void	fnparam(Type*, int, int);
-Prog*	gop(int, Node*, Node*, Node*);
-int	optoas(int, Type*);
-void	ginit(void);
-void	gclean(void);
-void	regalloc(Node*, Type*, Node*);
-void	regfree(Node*);
-Node*	nodarg(Type*, int);
-void	nodreg(Node*, Type*, int);
-void	nodindreg(Node*, Type*, int);
-void	ginscon(int, vlong, Node*);
-void	ginscon2(int, Node*, vlong);
-void	buildtxt(void);
-Plist*	newplist(void);
-int	isfat(Type*);
-void	sudoclean(void);
-int	sudoaddable(int, Node*, Addr*);
-void	afunclit(Addr*, Node*);
-void	nodfconst(Node*, Type*, Mpflt*);
-void	gtrack(Sym*);
-void	fixlargeoffset(Node *n);
-
-/*
- * cplx.c
- */
-int	complexop(Node*, Node*);
-void	complexmove(Node*, Node*);
-void	complexgen(Node*, Node*);
-
-/*
- * gobj.c
- */
-void	datastring(char*, int, Addr*);
-void	datagostring(Strlit*, Addr*);
-
-/*
- * list.c
- */
-void	listinit(void);
-
-void	zaddr(Biobuf*, Addr*, int, int);
-
-void afunclit(Addr*, Node*);
-int anyregalloc(void);
-void betypeinit(void);
-void bgen(Node*, int, int, Prog*);
-void cgen(Node*, Node*);
-void cgen_call(Node*, int);
-void cgen_callinter(Node*, Node*, int);
-void cgen_ret(Node*);
-void clearfat(Node*);
-void clearp(Prog*);
-void defframe(Prog*);
-int dgostringptr(Sym*, int, char*);
-int dgostrlitptr(Sym*, int, Strlit*);
-int dsname(Sym*, int, char*, int);
-int dsymptr(Sym*, int, Sym*, int);
-void dumpdata(void);
-void dumpit(char*, Flow*, int);
-void excise(Flow*);
-void expandchecks(Prog*);
-void fixautoused(Prog*);
-void gclean(void);
-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 ginit(void);
-Prog*	gins(int, Node*, Node*);
-void	ginscall(Node*, int);
-Prog*	gjmp(Prog*);
-void gtrack(Sym*);
-void	gused(Node*);
-void	igen(Node*, Node*, Node*);
-int isfat(Type*);
-void linkarchinit(void);
-void markautoused(Prog*);
-void naddr(Node*, Addr*, int);
-Plist* newplist(void);
-Node* nodarg(Type*, int);
-void patch(Prog*, Prog*);
-void proginfo(ProgInfo*, Prog*);
-void regalloc(Node*, Type*, Node*);
-void regfree(Node*);
-void regopt(Prog*);
-int regtyp(Addr*);
-int sameaddr(Addr*, Addr*);
-int smallindir(Addr*, Addr*);
-int stackaddr(Addr*);
-Prog* unpatch(Prog*);
-
-
-/*
- * reg.c
- */
-uint64 excludedregs(void);
-uint64 RtoB(int);
-uint64 FtoB(int);
-int BtoR(uint64);
-int BtoF(uint64);
-uint64 doregbits(int);
-char** regnames(int*);
-
-/*
- * peep.c
- */
-void peep(Prog*);
diff --git a/src/cmd/9g/ggen.c b/src/cmd/9g/ggen.c
deleted file mode 100644
index 7b34282..0000000
--- a/src/cmd/9g/ggen.c
+++ /dev/null
@@ -1,965 +0,0 @@
-// 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.
-
-#undef	EXTERN
-#define	EXTERN
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-static Prog *appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset);
-static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi);
-
-void
-defframe(Prog *ptxt)
-{
-	uint32 frame;
-	Prog *p;
-	vlong hi, lo;
-	NodeList *l;
-	Node *n;
-
-	// fill in argument size, stack size
-	ptxt->to.type = TYPE_TEXTSIZE;
-	ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
-	frame = rnd(stksize+maxarg, widthreg);
-	ptxt->to.offset = frame;
-	
-	// insert code to zero ambiguously live variables
-	// so that the garbage collector only sees initialized values
-	// when it looks for pointers.
-	p = ptxt;
-	lo = hi = 0;
-	// iterate through declarations - they are sorted in decreasing xoffset order.
-	for(l=curfn->dcl; l != nil; l = l->next) {
-		n = l->n;
-		if(!n->needzero)
-			continue;
-		if(n->class != PAUTO)
-			fatal("needzero class %d", n->class);
-		if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
-			fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
-
-		if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthreg) {
-			// merge with range we already have
-			lo = n->xoffset;
-			continue;
-		}
-		// zero old range
-		p = zerorange(p, frame, lo, hi);
-
-		// set new range
-		hi = n->xoffset + n->type->width;
-		lo = n->xoffset;
-	}
-	// zero final range
-	zerorange(p, frame, lo, hi);
-}
-
-static Prog*
-zerorange(Prog *p, vlong frame, vlong lo, vlong hi)
-{
-	vlong cnt, i;
-	Prog *p1;
-	Node *f;
-
-	cnt = hi - lo;
-	if(cnt == 0)
-		return p;
-	if(cnt < 4*widthptr) {
-		for(i = 0; i < cnt; i += widthptr)
-			p = appendpp(p, AMOVD, TYPE_REG, REGZERO, 0, TYPE_MEM, REGSP, 8+frame+lo+i);
-	} else if(cnt <= 128*widthptr) {
-		p = appendpp(p, AADD, TYPE_CONST, 0, 8+frame+lo-8, TYPE_REG, REGRT1, 0);
-		p->reg = REGSP;
-		p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_MEM, 0, 0);
-		f = sysfunc("duffzero");
-		naddr(f, &p->to, 1);
-		afunclit(&p->to, f);
-		p->to.offset = 4*(128-cnt/widthptr);
-	} else {
-		p = appendpp(p, AMOVD, TYPE_CONST, 0, 8+frame+lo-8, TYPE_REG, REGTMP, 0);
-		p = appendpp(p, AADD, TYPE_REG, REGTMP, 0, TYPE_REG, REGRT1, 0);
-		p->reg = REGSP;
-		p = appendpp(p, AMOVD, TYPE_CONST, 0, cnt, TYPE_REG, REGTMP, 0);
-		p = appendpp(p, AADD, TYPE_REG, REGTMP, 0, TYPE_REG, REGRT2, 0);
-		p->reg = REGRT1;
-		p1 = p = appendpp(p, AMOVDU, TYPE_REG, REGZERO, 0, TYPE_MEM, REGRT1, widthptr);
-		p = appendpp(p, ACMP, TYPE_REG, REGRT1, 0, TYPE_REG, REGRT2, 0);
-		p = appendpp(p, ABNE, TYPE_NONE, 0, 0, TYPE_BRANCH, 0, 0);
-		patch(p, p1);
-	}
-	return p;
-}
-
-static Prog*
-appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)
-{
-	Prog *q;
-	q = mal(sizeof(*q));
-	clearp(q);
-	q->as = as;
-	q->lineno = p->lineno;
-	q->from.type = ftype;
-	q->from.reg = freg;
-	q->from.offset = foffset;
-	q->to.type = ttype;
-	q->to.reg = treg;
-	q->to.offset = toffset;
-	q->link = p->link;
-	p->link = q;
-	return q;
-}
-
-/*
- * generate: BL reg, f
- * where both reg and f are registers.
- * On power, f must be moved to CTR first.
- */
-static void
-ginsBL(Node *reg, Node *f)
-{
-	Prog *p;
-	p = gins(AMOVD, f, N);
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_CTR;
-	p = gins(ABL, reg, N);
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_CTR;
-}
-
-/*
- * generate:
- *	call f
- *	proc=-1	normal call but no return
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
-  *	proc=3	normal call to C pointer (not Go func value)
- */
-void
-ginscall(Node *f, int proc)
-{
-	Prog *p;
-	Node reg, con, reg2;
-	Node r1;
-	int32 extra;
-
-	if(f->type != T) {
-		extra = 0;
-		if(proc == 1 || proc == 2)
-			extra = 2 * widthptr;
-		setmaxarg(f->type, extra);
-	}
-
-	switch(proc) {
-	default:
-		fatal("ginscall: bad proc %d", proc);
-		break;
-
-	case 0:	// normal call
-	case -1:	// normal call but no return
-		if(f->op == ONAME && f->class == PFUNC) {
-			if(f == deferreturn) {
-				// Deferred calls will appear to be returning to
-				// the CALL deferreturn(SB) that we are about to emit.
-				// However, the stack trace code will show the line
-				// of the instruction byte before the return PC. 
-				// To avoid that being an unrelated instruction,
-				// insert a ppc64 NOP that we will have the right line number.
-				// The ppc64 NOP is really or r0, r0, r0; use that description
-				// because the NOP pseudo-instruction would be removed by
-				// the linker.
-				nodreg(&reg, types[TINT], REG_R0);
-				gins(AOR, &reg, &reg);
-			}
-			p = gins(ABL, N, f);
-			afunclit(&p->to, f);
-			if(proc == -1 || noreturn(p))
-				gins(AUNDEF, N, N);
-			break;
-		}
-		nodreg(&reg, types[tptr], REGCTXT);
-		nodreg(&r1, types[tptr], REG_R3);
-		gmove(f, &reg);
-		reg.op = OINDREG;
-		gmove(&reg, &r1);
-		reg.op = OREGISTER;
-		ginsBL(&reg, &r1);
-		break;
-	
-	case 3:	// normal call of c function pointer
-		ginsBL(N, f);
-		break;
-
-	case 1:	// call in new proc (go)
-	case 2:	// deferred call (defer)
-		nodconst(&con, types[TINT64], argsize(f->type));
-		nodreg(&reg, types[TINT64], REG_R3);
-		nodreg(&reg2, types[TINT64], REG_R4);
-		gmove(f, &reg);
-
-		gmove(&con, &reg2);
-		p = gins(AMOVW, &reg2, N);
-		p->to.type = TYPE_MEM;
-		p->to.reg = REGSP;
-		p->to.offset = 8;
-
-		p = gins(AMOVD, &reg, N);
-		p->to.type = TYPE_MEM;
-		p->to.reg = REGSP;
-		p->to.offset = 16;
-
-		if(proc == 1)
-			ginscall(newproc, 0);
-		else {
-			if(!hasdefer)
-				fatal("hasdefer=0 but has defer");
-			ginscall(deferproc, 0);
-		}
-
-		if(proc == 2) {
-			nodreg(&reg, types[TINT64], REG_R3);
-			p = gins(ACMP, &reg, N);
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_R0;
-			p = gbranch(ABEQ, T, +1);
-			cgen_ret(N);
-			patch(p, pc);
-		}
-		break;
-	}
-}
-
-/*
- * n is call to interface method.
- * generate res = n.
- */
-void
-cgen_callinter(Node *n, Node *res, int proc)
-{
-	Node *i, *f;
-	Node tmpi, nodi, nodo, nodr, nodsp;
-	Prog *p;
-
-	i = n->left;
-	if(i->op != ODOTINTER)
-		fatal("cgen_callinter: not ODOTINTER %O", i->op);
-
-	f = i->right;		// field
-	if(f->op != ONAME)
-		fatal("cgen_callinter: not ONAME %O", f->op);
-
-	i = i->left;		// interface
-
-	if(!i->addable) {
-		tempname(&tmpi, i->type);
-		cgen(i, &tmpi);
-		i = &tmpi;
-	}
-
-	genlist(n->list);		// assign the args
-
-	// i is now addable, prepare an indirected
-	// register to hold its address.
-	igen(i, &nodi, res);		// REG = &inter
-
-	nodindreg(&nodsp, types[tptr], REGSP);
-	nodsp.xoffset = widthptr;
-	if(proc != 0)
-		nodsp.xoffset += 2 * widthptr; // leave room for size & fn
-	nodi.type = types[tptr];
-	nodi.xoffset += widthptr;
-	cgen(&nodi, &nodsp);	// {8 or 24}(SP) = 8(REG) -- i.data
-
-	regalloc(&nodo, types[tptr], res);
-	nodi.type = types[tptr];
-	nodi.xoffset -= widthptr;
-	cgen(&nodi, &nodo);	// REG = 0(REG) -- i.tab
-	regfree(&nodi);
-
-	regalloc(&nodr, types[tptr], &nodo);
-	if(n->left->xoffset == BADWIDTH)
-		fatal("cgen_callinter: badwidth");
-	cgen_checknil(&nodo); // in case offset is huge
-	nodo.op = OINDREG;
-	nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
-	if(proc == 0) {
-		// plain call: use direct c function pointer - more efficient
-		cgen(&nodo, &nodr);	// REG = 32+offset(REG) -- i.tab->fun[f]
-		proc = 3;
-	} else {
-		// go/defer. generate go func value.
-		p = gins(AMOVD, &nodo, &nodr);	// REG = &(32+offset(REG)) -- i.tab->fun[f]
-		p->from.type = TYPE_ADDR;
-	}
-
-	nodr.type = n->left->type;
-	ginscall(&nodr, proc);
-
-	regfree(&nodr);
-	regfree(&nodo);
-}
-
-/*
- * generate function call;
- *	proc=0	normal call
- *	proc=1	goroutine run in new proc
- *	proc=2	defer call save away stack
- */
-void
-cgen_call(Node *n, int proc)
-{
-	Type *t;
-	Node nod, afun;
-
-	if(n == N)
-		return;
-
-	if(n->left->ullman >= UINF) {
-		// if name involves a fn call
-		// precompute the address of the fn
-		tempname(&afun, types[tptr]);
-		cgen(n->left, &afun);
-	}
-
-	genlist(n->list);		// assign the args
-	t = n->left->type;
-
-	// call tempname pointer
-	if(n->left->ullman >= UINF) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, &afun);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call pointer
-	if(n->left->op != ONAME || n->left->class != PFUNC) {
-		regalloc(&nod, types[tptr], N);
-		cgen_as(&nod, n->left);
-		nod.type = t;
-		ginscall(&nod, proc);
-		regfree(&nod);
-		return;
-	}
-
-	// call direct
-	n->left->method = 1;
-	ginscall(n->left, proc);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = return value from call.
- */
-void
-cgen_callret(Node *n, Node *res)
-{
-	Node nod;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(t->etype == TPTR32 || t->etype == TPTR64)
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_callret: nil");
-
-	memset(&nod, 0, sizeof(nod));
-	nod.op = OINDREG;
-	nod.val.u.reg = REGSP;
-	nod.addable = 1;
-
-	nod.xoffset = fp->width + widthptr; // +widthptr: saved LR at 0(R1)
-	nod.type = fp->type;
-	cgen_as(res, &nod);
-}
-
-/*
- * call to n has already been generated.
- * generate:
- *	res = &return value from call.
- */
-void
-cgen_aret(Node *n, Node *res)
-{
-	Node nod1, nod2;
-	Type *fp, *t;
-	Iter flist;
-
-	t = n->left->type;
-	if(isptr[t->etype])
-		t = t->type;
-
-	fp = structfirst(&flist, getoutarg(t));
-	if(fp == T)
-		fatal("cgen_aret: nil");
-
-	memset(&nod1, 0, sizeof(nod1));
-	nod1.op = OINDREG;
-	nod1.val.u.reg = REGSP;
-	nod1.addable = 1;
-
-	nod1.xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
-	nod1.type = fp->type;
-
-	if(res->op != OREGISTER) {
-		regalloc(&nod2, types[tptr], res);
-		agen(&nod1, &nod2);
-		gins(AMOVD, &nod2, res);
-		regfree(&nod2);
-	} else
-		agen(&nod1, res);
-}
-
-/*
- * generate return.
- * n->left is assignments to return values.
- */
-void
-cgen_ret(Node *n)
-{
-	Prog *p;
-
-	if(n != N)
-		genlist(n->list);		// copy out args
-	if(hasdefer)
-		ginscall(deferreturn, 0);
-	genlist(curfn->exit);
-	p = gins(ARET, N, N);
-	if(n != N && n->op == ORETJMP) {
-		p->to.name = NAME_EXTERN;
-		p->to.type = TYPE_ADDR;
-		p->to.sym = linksym(n->left->sym);
-	}
-}
-
-/*
- * generate division.
- * generates one of:
- *	res = nl / nr
- *	res = nl % nr
- * according to op.
- */
-void
-dodiv(int op, Node *nl, Node *nr, Node *res)
-{
-	int a, check;
-	Type *t, *t0;
-	Node tl, tr, tl2, tr2, nm1, nz, tm;
-	Prog *p1, *p2;
-
-	// Have to be careful about handling
-	// most negative int divided by -1 correctly.
-	// The hardware will generate undefined result.
-	// Also need to explicitly trap on division on zero,
-	// the hardware will silently generate undefined result.
-	// DIVW will leave unpredicable result in higher 32-bit,
-	// so always use DIVD/DIVDU.
-	t = nl->type;
-	t0 = t;
-	check = 0;
-	if(issigned[t->etype]) {
-		check = 1;
-		if(isconst(nl, CTINT) && mpgetfix(nl->val.u.xval) != -(1ULL<<(t->width*8-1)))
-			check = 0;
-		else if(isconst(nr, CTINT) && mpgetfix(nr->val.u.xval) != -1)
-			check = 0;
-	}
-	if(t->width < 8) {
-		if(issigned[t->etype])
-			t = types[TINT64];
-		else
-			t = types[TUINT64];
-		check = 0;
-	}
-
-	a = optoas(ODIV, t);
-
-	regalloc(&tl, t0, N);
-	regalloc(&tr, t0, N);
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &tl);
-		cgen(nr, &tr);
-	} else {
-		cgen(nr, &tr);
-		cgen(nl, &tl);
-	}
-	if(t != t0) {
-		// Convert
-		tl2 = tl;
-		tr2 = tr;
-		tl.type = t;
-		tr.type = t;
-		gmove(&tl2, &tl);
-		gmove(&tr2, &tr);
-	}
-
-	// Handle divide-by-zero panic.
-	p1 = gins(optoas(OCMP, t), &tr, N);
-	p1->to.type = TYPE_REG;
-	p1->to.reg = REGZERO;
-	p1 = gbranch(optoas(ONE, t), T, +1);
-	if(panicdiv == N)
-		panicdiv = sysfunc("panicdivide");
-	ginscall(panicdiv, -1);
-	patch(p1, pc);
-
-	if(check) {
-		nodconst(&nm1, t, -1);
-		gins(optoas(OCMP, t), &tr, &nm1);
-		p1 = gbranch(optoas(ONE, t), T, +1);
-		if(op == ODIV) {
-			// a / (-1) is -a.
-			gins(optoas(OMINUS, t), N, &tl);
-			gmove(&tl, res);
-		} else {
-			// a % (-1) is 0.
-			nodconst(&nz, t, 0);
-			gmove(&nz, res);
-		}
-		p2 = gbranch(AJMP, T, 0);
-		patch(p1, pc);
-	}
-	p1 = gins(a, &tr, &tl);
-	if(op == ODIV) {
-		regfree(&tr);
-		gmove(&tl, res);
-	} else {
-		// A%B = A-(A/B*B)
-		regalloc(&tm, t, N);
-		// patch div to use the 3 register form
-		// TODO(minux): add gins3?
-		p1->reg = p1->to.reg;
-		p1->to.reg = tm.val.u.reg;
-		gins(optoas(OMUL, t), &tr, &tm);
-		regfree(&tr);
-		gins(optoas(OSUB, t), &tm, &tl);
-		regfree(&tm);
-		gmove(&tl, res);
-	}
-	regfree(&tl);
-	if(check)
-		patch(p2, pc);
-}
-
-/*
- * generate division according to op, one of:
- *	res = nl / nr
- *	res = nl % nr
- */
-void
-cgen_div(int op, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n3;
-	int w, a;
-	Magic m;
-
-	// TODO(minux): enable division by magic multiply (also need to fix longmod below)
-	//if(nr->op != OLITERAL)
-		goto longdiv;
-	w = nl->type->width*8;
-
-	// Front end handled 32-bit division. We only need to handle 64-bit.
-	// try to do division by multiply by (2^w)/d
-	// see hacker's delight chapter 10
-	switch(simtype[nl->type->etype]) {
-	default:
-		goto longdiv;
-
-	case TUINT64:
-		m.w = w;
-		m.ud = mpgetfix(nr->val.u.xval);
-		umagic(&m);
-		if(m.bad)
-			break;
-		if(op == OMOD)
-			goto longmod;
-
-		cgenr(nl, &n1, N);
-		nodconst(&n2, nl->type, m.um);
-		regalloc(&n3, nl->type, res);
-		cgen_hmul(&n1, &n2, &n3);
-
-		if(m.ua) {
-			// need to add numerator accounting for overflow
-			gins(optoas(OADD, nl->type), &n1, &n3);
-			nodconst(&n2, nl->type, 1);
-			gins(optoas(ORROTC, nl->type), &n2, &n3);
-			nodconst(&n2, nl->type, m.s-1);
-			gins(optoas(ORSH, nl->type), &n2, &n3);
-		} else {
-			nodconst(&n2, nl->type, m.s);
-			gins(optoas(ORSH, nl->type), &n2, &n3);	// shift dx
-		}
-
-		gmove(&n3, res);
-		regfree(&n1);
-		regfree(&n3);
-		return;
-
-	case TINT64:
-		m.w = w;
-		m.sd = mpgetfix(nr->val.u.xval);
-		smagic(&m);
-		if(m.bad)
-			break;
-		if(op == OMOD)
-			goto longmod;
-
-		cgenr(nl, &n1, res);
-		nodconst(&n2, nl->type, m.sm);
-		regalloc(&n3, nl->type, N);
-		cgen_hmul(&n1, &n2, &n3);
-
-		if(m.sm < 0) {
-			// need to add numerator
-			gins(optoas(OADD, nl->type), &n1, &n3);
-		}
-
-		nodconst(&n2, nl->type, m.s);
-		gins(optoas(ORSH, nl->type), &n2, &n3);	// shift n3
-
-		nodconst(&n2, nl->type, w-1);
-		gins(optoas(ORSH, nl->type), &n2, &n1);	// -1 iff num is neg
-		gins(optoas(OSUB, nl->type), &n1, &n3);	// added
-
-		if(m.sd < 0) {
-			// this could probably be removed
-			// by factoring it into the multiplier
-			gins(optoas(OMINUS, nl->type), N, &n3);
-		}
-
-		gmove(&n3, res);
-		regfree(&n1);
-		regfree(&n3);
-		return;
-	}
-	goto longdiv;
-
-longdiv:
-	// division and mod using (slow) hardware instruction
-	dodiv(op, nl, nr, res);
-	return;
-
-longmod:
-	// mod using formula A%B = A-(A/B*B) but
-	// we know that there is a fast algorithm for A/B
-	regalloc(&n1, nl->type, res);
-	cgen(nl, &n1);
-	regalloc(&n2, nl->type, N);
-	cgen_div(ODIV, &n1, nr, &n2);
-	a = optoas(OMUL, nl->type);
-	if(w == 8) {
-		// use 2-operand 16-bit multiply
-		// because there is no 2-operand 8-bit multiply
-		//a = AIMULW;
-	}
-	if(!smallintconst(nr)) {
-		regalloc(&n3, nl->type, N);
-		cgen(nr, &n3);
-		gins(a, &n3, &n2);
-		regfree(&n3);
-	} else
-		gins(a, nr, &n2);
-	gins(optoas(OSUB, nl->type), &n2, &n1);
-	gmove(&n1, res);
-	regfree(&n1);
-	regfree(&n2);
-}
-
-/*
- * generate high multiply:
- *   res = (nl*nr) >> width
- */
-void
-cgen_hmul(Node *nl, Node *nr, Node *res)
-{
-	int w;
-	Node n1, n2, *tmp;
-	Type *t;
-	Prog *p;
-
-	// largest ullman on left.
-	if(nl->ullman < nr->ullman) {
-		tmp = nl;
-		nl = nr;
-		nr = tmp;
-	}
-	t = nl->type;
-	w = t->width * 8;
-	cgenr(nl, &n1, res);
-	cgenr(nr, &n2, N);
-	switch(simtype[t->etype]) {
-	case TINT8:
-	case TINT16:
-	case TINT32:
-		gins(optoas(OMUL, t), &n2, &n1);
-		p = gins(ASRAD, N, &n1);
-		p->from.type = TYPE_CONST;
-		p->from.offset = w;
-		break;
-	case TUINT8:
-	case TUINT16:
-	case TUINT32:
-		gins(optoas(OMUL, t), &n2, &n1);
-		p = gins(ASRD, N, &n1);
-		p->from.type = TYPE_CONST;
-		p->from.offset = w;
-		break;
-	case TINT64:
-	case TUINT64:
-		if(issigned[t->etype])
-			p = gins(AMULHD, &n2, &n1);
-		else
-			p = gins(AMULHDU, &n2, &n1);
-		break;
-	default:
-		fatal("cgen_hmul %T", t);
-		break;
-	}
-	cgen(&n1, res);
-	regfree(&n1);
-	regfree(&n2);
-}
-
-/*
- * generate shift according to op, one of:
- *	res = nl << nr
- *	res = nl >> nr
- */
-void
-cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
-{
-	Node n1, n2, n3, n4, n5;
-	int a;
-	Prog *p1;
-	uvlong sc;
-	Type *tcount;
-
-	a = optoas(op, nl->type);
-
-	if(nr->op == OLITERAL) {
-		regalloc(&n1, nl->type, res);
-		cgen(nl, &n1);
-		sc = mpgetfix(nr->val.u.xval);
-		if(sc >= nl->type->width*8) {
-			// large shift gets 2 shifts by width-1
-			nodconst(&n3, types[TUINT32], nl->type->width*8-1);
-			gins(a, &n3, &n1);
-			gins(a, &n3, &n1);
-		} else
-			gins(a, nr, &n1);
-		gmove(&n1, res);
-		regfree(&n1);
-		goto ret;
-	}
-
-	if(nl->ullman >= UINF) {
-		tempname(&n4, nl->type);
-		cgen(nl, &n4);
-		nl = &n4;
-	}
-	if(nr->ullman >= UINF) {
-		tempname(&n5, nr->type);
-		cgen(nr, &n5);
-		nr = &n5;
-	}
-
-	// Allow either uint32 or uint64 as shift type,
-	// to avoid unnecessary conversion from uint32 to uint64
-	// just to do the comparison.
-	tcount = types[simtype[nr->type->etype]];
-	if(tcount->etype < TUINT32)
-		tcount = types[TUINT32];
-
-	regalloc(&n1, nr->type, N);		// to hold the shift type in CX
-	regalloc(&n3, tcount, &n1);	// to clear high bits of CX
-
-	regalloc(&n2, nl->type, res);
-	if(nl->ullman >= nr->ullman) {
-		cgen(nl, &n2);
-		cgen(nr, &n1);
-		gmove(&n1, &n3);
-	} else {
-		cgen(nr, &n1);
-		gmove(&n1, &n3);
-		cgen(nl, &n2);
-	}
-	regfree(&n3);
-
-	// test and fix up large shifts
-	if(!bounded) {
-		nodconst(&n3, tcount, nl->type->width*8);
-		gins(optoas(OCMP, tcount), &n1, &n3);
-		p1 = gbranch(optoas(OLT, tcount), T, +1);
-		if(op == ORSH && issigned[nl->type->etype]) {
-			nodconst(&n3, types[TUINT32], nl->type->width*8-1);
-			gins(a, &n3, &n2);
-		} else {
-			nodconst(&n3, nl->type, 0);
-			gmove(&n3, &n2);
-		}
-		patch(p1, pc);
-	}
-
-	gins(a, &n1, &n2);
-
-	gmove(&n2, res);
-
-	regfree(&n1);
-	regfree(&n2);
-
-ret:
-	;
-}
-
-void
-clearfat(Node *nl)
-{
-	uint64 w, c, q, t, boff;
-	Node dst, end, r0, *f;
-	Prog *p, *pl;
-
-	/* clear a fat object */
-	if(debug['g']) {
-		print("clearfat %N (%T, size: %lld)\n", nl, nl->type, nl->type->width);
-	}
-
-	w = nl->type->width;
-	// Avoid taking the address for simple enough types.
-	//if(componentgen(N, nl))
-	//	return;
-
-	c = w % 8;	// bytes
-	q = w / 8;	// dwords
-
-	if(reg[REGRT1] > 0)
-		fatal("R%d in use during clearfat", REGRT1);
-
-	nodreg(&r0, types[TUINT64], REG_R0); // r0 is always zero
-	nodreg(&dst, types[tptr], REGRT1);
-	reg[REGRT1]++;
-	agen(nl, &dst);
-
-	if(q > 128) {
-		p = gins(ASUB, N, &dst);
-		p->from.type = TYPE_CONST;
-		p->from.offset = 8;
-
-		regalloc(&end, types[tptr], N);
-		p = gins(AMOVD, &dst, &end);
-		p->from.type = TYPE_ADDR;
-		p->from.offset = q*8;
-
-		p = gins(AMOVDU, &r0, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = 8;
-		pl = p;
-
-		p = gins(ACMP, &dst, &end);
-		patch(gbranch(ABNE, T, 0), pl);
-
-		regfree(&end);
-		// The loop leaves R3 on the last zeroed dword
-		boff = 8;
-	} else if(q >= 4) {
-		p = gins(ASUB, N, &dst);
-		p->from.type = TYPE_CONST;
-		p->from.offset = 8;
-		f = sysfunc("duffzero");
-		p = gins(ADUFFZERO, N, f);
-		afunclit(&p->to, f);
-		// 4 and 128 = magic constants: see ../../runtime/asm_ppc64x.s
-		p->to.offset = 4*(128-q);
-		// duffzero leaves R3 on the last zeroed dword
-		boff = 8;
-	} else {
-		for(t = 0; t < q; t++) {
-			p = gins(AMOVD, &r0, &dst);
-			p->to.type = TYPE_MEM;
-			p->to.offset = 8*t;
-		}
-		boff = 8*q;
-	}
-
-	for(t = 0; t < c; t++) {
-		p = gins(AMOVB, &r0, &dst);
-		p->to.type = TYPE_MEM;
-		p->to.offset = t+boff;
-	}
-	reg[REGRT1]--;
-}
-
-// Called after regopt and peep have run.
-// Expand CHECKNIL pseudo-op into actual nil pointer check.
-void
-expandchecks(Prog *firstp)
-{
-	Prog *p, *p1, *p2;
-
-	for(p = firstp; p != P; p = p->link) {
-		if(debug_checknil && ctxt->debugvlog)
-			print("expandchecks: %P\n", p);
-		if(p->as != ACHECKNIL)
-			continue;
-		if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
-			warnl(p->lineno, "generated nil check");
-		if(p->from.type != TYPE_REG)
-			fatal("invalid nil check %P\n", p);
-		/*
-		// check is
-		//	TD $4, R0, arg (R0 is always zero)
-		// eqv. to:
-		// 	tdeq r0, arg
-		// NOTE: this needs special runtime support to make SIGTRAP recoverable.
-		reg = p->from.reg;
-		p->as = ATD;
-		p->from = p->to = p->from3 = zprog.from;
-		p->from.type = TYPE_CONST;
-		p->from.offset = 4;
-		p->from.reg = 0;
-		p->reg = REG_R0;
-		p->to.type = TYPE_REG;
-		p->to.reg = reg;
-		*/
-		// check is
-		//	CMP arg, R0
-		//	BNE 2(PC) [likely]
-		//	MOVD R0, 0(R0)
-		p1 = mal(sizeof *p1);
-		p2 = mal(sizeof *p2);
-		clearp(p1);
-		clearp(p2);
-		p1->link = p2;
-		p2->link = p->link;
-		p->link = p1;
-		p1->lineno = p->lineno;
-		p2->lineno = p->lineno;
-		p1->pc = 9999;
-		p2->pc = 9999;
-		p->as = ACMP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REGZERO;
-		p1->as = ABNE;
-		//p1->from.type = TYPE_CONST;
-		//p1->from.offset = 1; // likely
-		p1->to.type = TYPE_BRANCH;
-		p1->to.u.branch = p2->link;
-		// crash by write to memory address 0.
-		p2->as = AMOVD;
-		p2->from.type = TYPE_REG;
-		p2->from.reg = REG_R0;
-		p2->to.type = TYPE_MEM;
-		p2->to.reg = REG_R0;
-		p2->to.offset = 0;
-	}
-}
diff --git a/src/cmd/new9g/ggen.go b/src/cmd/9g/ggen.go
similarity index 100%
rename from src/cmd/new9g/ggen.go
rename to src/cmd/9g/ggen.go
diff --git a/src/cmd/9g/gsubr.c b/src/cmd/9g/gsubr.c
deleted file mode 100644
index 1fb1511..0000000
--- a/src/cmd/9g/gsubr.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-// Derived from Inferno utils/6c/txt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.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 "gg.h"
-#include "../../runtime/funcdata.h"
-
-// TODO(rsc): Can make this bigger if we move
-// the text segment up higher in 6l for all GOOS.
-// At the same time, can raise StackBig in ../../runtime/stack.h.
-vlong unmappedzero = 4096;
-
-static	int	resvd[] =
-{
-	REGZERO,
-	REGSP,	// reserved for SP
-	// We need to preserve the C ABI TLS pointer because sigtramp
-	// may happen during C code and needs to access the g.  C
-	// clobbers REGG, so if Go were to clobber REGTLS, sigtramp
-	// won't know which convention to use.  By preserving REGTLS,
-	// we can just retrieve g from TLS when we aren't sure.
-	REGTLS,
-	// TODO(austin): Consolidate REGTLS and REGG?
-	REGG,
-	REGTMP,	// REGTMP
-	FREGCVI,
-	FREGZERO,
-	FREGHALF,
-	FREGONE,
-	FREGTWO,
-};
-
-void
-ginit(void)
-{
-	int i;
-
-	for(i=0; i<nelem(reg); i++)
-		reg[i] = 1;
-	for(i=0; i<NREG+NFREG; i++)
-		reg[i] = 0;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i] - REG_R0]++;
-}
-
-static	uintptr	regpc[nelem(reg)];
-
-void
-gclean(void)
-{
-	int i;
-
-	for(i=0; i<nelem(resvd); i++)
-		reg[resvd[i] - REG_R0]--;
-
-	for(i=0; i<nelem(reg); i++)
-		if(reg[i])
-			yyerror("reg %R left allocated, %p\n", i+REG_R0, regpc[i]);
-}
-
-int
-anyregalloc(void)
-{
-	int i, j;
-
-	for(i=0; i<nelem(reg); i++) {
-		if(reg[i] == 0)
-			goto ok;
-		for(j=0; j<nelem(resvd); j++)
-			if(resvd[j] == i)
-				goto ok;
-		return 1;
-	ok:;
-	}
-	return 0;
-}
-
-/*
- * allocate register of type t, leave in n.
- * if o != N, o is desired fixed register.
- * caller must regfree(n).
- */
-void
-regalloc(Node *n, Type *t, Node *o)
-{
-	int i, et;
-	int fixfree, fltfree;
-
-	if(t == T)
-		fatal("regalloc: t nil");
-	et = simtype[t->etype];
-
-	if(debug['r']) {
-		fixfree = 0;
-		fltfree = 0;
-		for(i = REG_R0; i < REG_F31; i++)
-			if(reg[i - REG_R0] == 0) {
-				if(i < REG_F0)
-					fixfree++;
-				else
-					fltfree++;
-			}
-		print("regalloc fix %d flt %d free\n", fixfree, fltfree);
-	}
-
-	switch(et) {
-	case TINT8:
-	case TUINT8:
-	case TINT16:
-	case TUINT16:
-	case TINT32:
-	case TUINT32:
-	case TINT64:
-	case TUINT64:
-	case TPTR32:
-	case TPTR64:
-	case TBOOL:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= REGMIN && i <= REGMAX)
-				goto out;
-		}
-		for(i=REGMIN; i<=REGMAX; i++)
-			if(reg[i - REG_R0] == 0) {
-				regpc[i - REG_R0] = (uintptr)getcallerpc(&n);
-				goto out;
-			}
-		flusherrors();
-		for(i=REG_R0; i<REG_R0+NREG; i++)
-			print("R%d %p\n", i, regpc[i - REG_R0]);
-		fatal("out of fixed registers");
-
-	case TFLOAT32:
-	case TFLOAT64:
-		if(o != N && o->op == OREGISTER) {
-			i = o->val.u.reg;
-			if(i >= FREGMIN && i <= FREGMAX)
-				goto out;
-		}
-		for(i=FREGMIN; i<=FREGMAX; i++)
-			if(reg[i - REG_R0] == 0) {
-				regpc[i - REG_R0] = (uintptr)getcallerpc(&n);
-				goto out;
-			}
-		flusherrors();
-		for(i=REG_F0; i<REG_F0+NREG; i++)
-			print("F%d %p\n", i, regpc[i - REG_R0]);
-		fatal("out of floating registers");
-
-	case TCOMPLEX64:
-	case TCOMPLEX128:
-		tempname(n, t);
-		return;
-	}
-	fatal("regalloc: unknown type %T", t);
-	return;
-
-out:
-	reg[i - REG_R0]++;
-	nodreg(n, t, i);
-}
-
-void
-regfree(Node *n)
-{
-	int i;
-
-	if(n->op == ONAME)
-		return;
-	if(n->op != OREGISTER && n->op != OINDREG)
-		fatal("regfree: not a register");
-	i = n->val.u.reg - REG_R0;
-	if(i == REGSP - REG_R0)
-		return;
-	if(i < 0 || i >= nelem(reg))
-		fatal("regfree: reg out of range");
-	if(reg[i] <= 0)
-		fatal("regfree: reg not allocated");
-	reg[i]--;
-	if(reg[i] == 0)
-		regpc[i] = 0;
-}
-
-/*
- * generate
- *	as $c, n
- */
-void
-ginscon(int as, vlong c, Node *n2)
-{
-	Node n1, ntmp;
-
-	nodconst(&n1, types[TINT64], c);
-
-	if(as != AMOVD && (c < -BIG || c > BIG)) {
-		// cannot have more than 16-bit of immediate in ADD, etc.
-		// instead, MOV into register first.
-		regalloc(&ntmp, types[TINT64], N);
-		gins(AMOVD, &n1, &ntmp);
-		gins(as, &ntmp, n2);
-		regfree(&ntmp);
-		return;
-	}
-	gins(as, &n1, n2);
-}
-
-/*
- * generate
- *	as n, $c (CMP/CMPU)
- */
-void
-ginscon2(int as, Node *n2, vlong c)
-{
-	Node n1, ntmp;
-
-	nodconst(&n1, types[TINT64], c);
-
-	switch(as) {
-	default:
-		fatal("ginscon2");
-	case ACMP:
-		if(-BIG <= c && c <= BIG) {
-			gins(as, n2, &n1);
-			return;
-		}
-		break;
-	case ACMPU:
-		if(0 <= c && c <= 2*BIG) {
-			gins(as, n2, &n1);
-			return;
-		}
-		break;
-	}
-	// MOV n1 into register first
-	regalloc(&ntmp, types[TINT64], N);
-	gins(AMOVD, &n1, &ntmp);
-	gins(as, n2, &ntmp);
-	regfree(&ntmp);
-}
-
-#define	CASE(a,b)	(((a)<<16)|((b)<<0))
-/*c2go int CASE(int, int); */
-
-/*
- * set up nodes representing 2^63
- */
-Node bigi;
-Node bigf;
-
-void
-bignodes(void)
-{
-	static int did;
-
-	if(did)
-		return;
-	did = 1;
-
-	nodconst(&bigi, types[TUINT64], 1);
-	mpshiftfix(bigi.val.u.xval, 63);
-
-	bigf = bigi;
-	bigf.type = types[TFLOAT64];
-	bigf.val.ctype = CTFLT;
-	bigf.val.u.fval = mal(sizeof *bigf.val.u.fval);
-	mpmovefixflt(bigf.val.u.fval, bigi.val.u.xval);
-}
-
-/*
- * generate move:
- *	t = f
- * hard part is conversions.
- */
-void
-gmove(Node *f, Node *t)
-{
-	int a, ft, tt;
-	Type *cvt;
-	Node r1, r2, r3, con;
-	Prog *p1, *p2;
-
-	if(debug['M'])
-		print("gmove %lN -> %lN\n", f, t);
-
-	ft = simsimtype(f->type);
-	tt = simsimtype(t->type);
-	cvt = t->type;
-
-	if(iscomplex[ft] || iscomplex[tt]) {
-		complexmove(f, t);
-		return;
-	}
-
-	// cannot have two memory operands
-	if(ismem(f) && ismem(t))
-		goto hard;
-
-	// convert constant to desired type
-	if(f->op == OLITERAL) {
-		switch(tt) {
-		default:
-			convconst(&con, t->type, &f->val);
-			break;
-
-		case TINT32:
-		case TINT16:
-		case TINT8:
-			convconst(&con, types[TINT64], &f->val);
-			regalloc(&r1, con.type, t);
-			gins(AMOVD, &con, &r1);
-			gmove(&r1, t);
-			regfree(&r1);
-			return;
-
-		case TUINT32:
-		case TUINT16:
-		case TUINT8:
-			convconst(&con, types[TUINT64], &f->val);
-			regalloc(&r1, con.type, t);
-			gins(AMOVD, &con, &r1);
-			gmove(&r1, t);
-			regfree(&r1);
-			return;
-		}
-
-		f = &con;
-		ft = tt;	// so big switch will choose a simple mov
-
-		// constants can't move directly to memory.
-		if(ismem(t)) {
-			goto hard;
-			// float constants come from memory.
-			//if(isfloat[tt])
-			//	goto hard;
-
-			// 64-bit immediates are also from memory.
-			//if(isint[tt])
-			//	goto hard;
-			//// 64-bit immediates are really 32-bit sign-extended
-			//// unless moving into a register.
-			//if(isint[tt]) {
-			//	if(mpcmpfixfix(con.val.u.xval, minintval[TINT32]) < 0)
-			//		goto hard;
-			//	if(mpcmpfixfix(con.val.u.xval, maxintval[TINT32]) > 0)
-			//		goto hard;
-			//}
-		}
-	}
-
-	// value -> value copy, only one memory operand.
-	// figure out the instruction to use.
-	// break out of switch for one-instruction gins.
-	// goto rdst for "destination must be register".
-	// goto hard for "convert to cvt type first".
-	// otherwise handle and return.
-
-	switch(CASE(ft, tt)) {
-	default:
-		fatal("gmove %lT -> %lT", f->type, t->type);
-
-	/*
-	 * integer copy and truncate
-	 */
-	case CASE(TINT8, TINT8):	// same size
-	case CASE(TUINT8, TINT8):
-	case CASE(TINT16, TINT8):	// truncate
-	case CASE(TUINT16, TINT8):
-	case CASE(TINT32, TINT8):
-	case CASE(TUINT32, TINT8):
-	case CASE(TINT64, TINT8):
-	case CASE(TUINT64, TINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(TINT8, TUINT8):	// same size
-	case CASE(TUINT8, TUINT8):
-	case CASE(TINT16, TUINT8):	// truncate
-	case CASE(TUINT16, TUINT8):
-	case CASE(TINT32, TUINT8):
-	case CASE(TUINT32, TUINT8):
-	case CASE(TINT64, TUINT8):
-	case CASE(TUINT64, TUINT8):
-		a = AMOVBZ;
-		break;
-
-	case CASE(TINT16, TINT16):	// same size
-	case CASE(TUINT16, TINT16):
-	case CASE(TINT32, TINT16):	// truncate
-	case CASE(TUINT32, TINT16):
-	case CASE(TINT64, TINT16):
-	case CASE(TUINT64, TINT16):
-		a = AMOVH;
-		break;
-
-	case CASE(TINT16, TUINT16):	// same size
-	case CASE(TUINT16, TUINT16):
-	case CASE(TINT32, TUINT16):	// truncate
-	case CASE(TUINT32, TUINT16):
-	case CASE(TINT64, TUINT16):
-	case CASE(TUINT64, TUINT16):
-		a = AMOVHZ;
-		break;
-
-	case CASE(TINT32, TINT32):	// same size
-	case CASE(TUINT32, TINT32):
-	case CASE(TINT64, TINT32):	// truncate
-	case CASE(TUINT64, TINT32):
-		a = AMOVW;
-		break;
-
-	case CASE(TINT32, TUINT32):	// same size
-	case CASE(TUINT32, TUINT32):
-	case CASE(TINT64, TUINT32):
-	case CASE(TUINT64, TUINT32):
-		a = AMOVWZ;
-		break;
-
-	case CASE(TINT64, TINT64):	// same size
-	case CASE(TINT64, TUINT64):
-	case CASE(TUINT64, TINT64):
-	case CASE(TUINT64, TUINT64):
-		a = AMOVD;
-		break;
-
-	/*
-	 * integer up-conversions
-	 */
-	case CASE(TINT8, TINT16):	// sign extend int8
-	case CASE(TINT8, TUINT16):
-	case CASE(TINT8, TINT32):
-	case CASE(TINT8, TUINT32):
-	case CASE(TINT8, TINT64):
-	case CASE(TINT8, TUINT64):
-		a = AMOVB;
-		goto rdst;
-
-	case CASE(TUINT8, TINT16):	// zero extend uint8
-	case CASE(TUINT8, TUINT16):
-	case CASE(TUINT8, TINT32):
-	case CASE(TUINT8, TUINT32):
-	case CASE(TUINT8, TINT64):
-	case CASE(TUINT8, TUINT64):
-		a = AMOVBZ;
-		goto rdst;
-
-	case CASE(TINT16, TINT32):	// sign extend int16
-	case CASE(TINT16, TUINT32):
-	case CASE(TINT16, TINT64):
-	case CASE(TINT16, TUINT64):
-		a = AMOVH;
-		goto rdst;
-
-	case CASE(TUINT16, TINT32):	// zero extend uint16
-	case CASE(TUINT16, TUINT32):
-	case CASE(TUINT16, TINT64):
-	case CASE(TUINT16, TUINT64):
-		a = AMOVHZ;
-		goto rdst;
-
-	case CASE(TINT32, TINT64):	// sign extend int32
-	case CASE(TINT32, TUINT64):
-		a = AMOVW;
-		goto rdst;
-
-	case CASE(TUINT32, TINT64):	// zero extend uint32
-	case CASE(TUINT32, TUINT64):
-		a = AMOVWZ;
-		goto rdst;
-
-	/*
-	* float to integer
-	*/
-	case CASE(TFLOAT32, TINT32):
-	case CASE(TFLOAT64, TINT32):
-	case CASE(TFLOAT32, TINT64):
-	case CASE(TFLOAT64, TINT64):
-	case CASE(TFLOAT32, TINT16):
-	case CASE(TFLOAT32, TINT8):
-	case CASE(TFLOAT32, TUINT16):
-	case CASE(TFLOAT32, TUINT8):
-	case CASE(TFLOAT64, TINT16):
-	case CASE(TFLOAT64, TINT8):
-	case CASE(TFLOAT64, TUINT16):
-	case CASE(TFLOAT64, TUINT8):
-	case CASE(TFLOAT32, TUINT32):
-	case CASE(TFLOAT64, TUINT32):
-	case CASE(TFLOAT32, TUINT64):
-	case CASE(TFLOAT64, TUINT64):
-		//warn("gmove: convert float to int not implemented: %N -> %N\n", f, t);
-		//return;
-		// algorithm is:
-		//	if small enough, use native float64 -> int64 conversion.
-		//	otherwise, subtract 2^63, convert, and add it back.
-		bignodes();
-		regalloc(&r1, types[ft], f);
-		gmove(f, &r1);
-		if(tt == TUINT64) {
-			regalloc(&r2, types[TFLOAT64], N);
-			gmove(&bigf, &r2);
-			gins(AFCMPU, &r1, &r2);
-			p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1);
-			gins(AFSUB, &r2, &r1);
-			patch(p1, pc);
-			regfree(&r2);
-		}
-		regalloc(&r2, types[TFLOAT64], N);
-		regalloc(&r3, types[TINT64], t);
-		gins(AFCTIDZ, &r1, &r2);
-		p1 = gins(AFMOVD, &r2, N);
-		p1->to.type = TYPE_MEM;
-		p1->to.reg = REGSP;
-		p1->to.offset = -8;
-		p1 = gins(AMOVD, N, &r3);
-		p1->from.type = TYPE_MEM;
-		p1->from.reg = REGSP;
-		p1->from.offset = -8;
-		regfree(&r2);
-		regfree(&r1);
-		if(tt == TUINT64) {
-			p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1); // use CR0 here again
-			nodreg(&r1, types[TINT64], REGTMP);
-			gins(AMOVD, &bigi, &r1);
-			gins(AADD, &r1, &r3);
-			patch(p1, pc);
-		}
-		gmove(&r3, t);
-		regfree(&r3);
-		return;
-
-	/*
-	 * integer to float
-	 */
-	case CASE(TINT32, TFLOAT32):
-	case CASE(TINT32, TFLOAT64):
-	case CASE(TINT64, TFLOAT32):
-	case CASE(TINT64, TFLOAT64):
-	case CASE(TINT16, TFLOAT32):
-	case CASE(TINT16, TFLOAT64):
-	case CASE(TINT8, TFLOAT32):
-	case CASE(TINT8, TFLOAT64):
-	case CASE(TUINT16, TFLOAT32):
-	case CASE(TUINT16, TFLOAT64):
-	case CASE(TUINT8, TFLOAT32):
-	case CASE(TUINT8, TFLOAT64):
-	case CASE(TUINT32, TFLOAT32):
-	case CASE(TUINT32, TFLOAT64):
-	case CASE(TUINT64, TFLOAT32):
-	case CASE(TUINT64, TFLOAT64):
-		//warn("gmove: convert int to float not implemented: %N -> %N\n", f, t);
-		//return;
-		// algorithm is:
-		//	if small enough, use native int64 -> uint64 conversion.
-		//	otherwise, halve (rounding to odd?), convert, and double.
-		bignodes();
-		regalloc(&r1, types[TINT64], N);
-		gmove(f, &r1);
-		if(ft == TUINT64) {
-			nodreg(&r2, types[TUINT64], REGTMP);
-			gmove(&bigi, &r2);
-			gins(ACMPU, &r1, &r2);
-			p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
-			p2 = gins(ASRD, N, &r1);
-			p2->from.type = TYPE_CONST;
-			p2->from.offset = 1;
-			patch(p1, pc);
-		}
-		regalloc(&r2, types[TFLOAT64], t);
-		p1 = gins(AMOVD, &r1, N);
-		p1->to.type = TYPE_MEM;
-		p1->to.reg = REGSP;
-		p1->to.offset = -8;
-		p1 = gins(AFMOVD, N, &r2);
-		p1->from.type = TYPE_MEM;
-		p1->from.reg = REGSP;
-		p1->from.offset = -8;
-		gins(AFCFID, &r2, &r2);
-		regfree(&r1);
-		if(ft == TUINT64) {
-			p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1); // use CR0 here again
-			nodreg(&r1, types[TFLOAT64], FREGTWO);
-			gins(AFMUL, &r1, &r2);
-			patch(p1, pc);
-		}
-		gmove(&r2, t);
-		regfree(&r2);
-		return;
-
-	/*
-	 * float to float
-	 */
-	case CASE(TFLOAT32, TFLOAT32):
-		a = AFMOVS;
-		break;
-
-	case CASE(TFLOAT64, TFLOAT64):
-		a = AFMOVD;
-		break;
-
-	case CASE(TFLOAT32, TFLOAT64):
-		a = AFMOVS;
-		goto rdst;
-
-	case CASE(TFLOAT64, TFLOAT32):
-		a = AFRSP;
-		goto rdst;
-	}
-
-	gins(a, f, t);
-	return;
-
-rdst:
-	// requires register destination
-	regalloc(&r1, t->type, t);
-	gins(a, f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-
-hard:
-	// requires register intermediate
-	regalloc(&r1, cvt, t);
-	gmove(f, &r1);
-	gmove(&r1, t);
-	regfree(&r1);
-	return;
-}
-
-/*
- * generate one instruction:
- *	as f, t
- */
-Prog*
-gins(int as, Node *f, Node *t)
-{
-	int32 w;
-	Prog *p;
-	Addr af, at;
-
-	// TODO(austin): Add self-move test like in 6g (but be careful
-	// of truncation moves)
-
-	memset(&af, 0, sizeof af);
-	memset(&at, 0, sizeof at);
-	if(f != N)
-		naddr(f, &af, 1);
-	if(t != N)
-		naddr(t, &at, 1);
-	p = prog(as);
-	if(f != N)
-		p->from = af;
-	if(t != N)
-		p->to = at;
-	if(debug['g'])
-		print("%P\n", p);
-
-	w = 0;
-	switch(as) {
-	case AMOVB:
-	case AMOVBU:
-	case AMOVBZ:
-	case AMOVBZU:
-		w = 1;
-		break;
-	case AMOVH:
-	case AMOVHU:
-	case AMOVHZ:
-	case AMOVHZU:
-		w = 2;
-		break;
-	case AMOVW:
-	case AMOVWU:
-	case AMOVWZ:
-	case AMOVWZU:
-		w = 4;
-		break;
-	case AMOVD:
-	case AMOVDU:
-		if(af.type == TYPE_CONST || af.type == TYPE_ADDR)
-			break;
-		w = 8;
-		break;
-	}
-	if(w != 0 && ((f != N && af.width < w) || (t != N && at.type != TYPE_REG && at.width > w))) {
-		dump("f", f);
-		dump("t", t);
-		fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
-	}
-
-	return p;
-}
-
-void
-fixlargeoffset(Node *n)
-{
-	Node a;
-
-	if(n == N)
-		return;
-	if(n->op != OINDREG)
-		return;
-	if(n->val.u.reg == REGSP) // stack offset cannot be large
-		return;
-	if(n->xoffset != (int32)n->xoffset) {
-		// TODO(minux): offset too large, move into R31 and add to R31 instead.
-		// this is used only in test/fixedbugs/issue6036.go.
-		fatal("offset too large: %N", n);
-		a = *n;
-		a.op = OREGISTER;
-		a.type = types[tptr];
-		a.xoffset = 0;
-		cgen_checknil(&a);
-		ginscon(optoas(OADD, types[tptr]), n->xoffset, &a);
-		n->xoffset = 0;
-	}
-}
-
-/*
- * return Axxx for Oxxx on type t.
- */
-int
-optoas(int op, Type *t)
-{
-	int a;
-
-	if(t == T)
-		fatal("optoas: t is nil");
-
-	a = AXXX;
-	switch(CASE(op, simtype[t->etype])) {
-	default:
-		fatal("optoas: no entry for op=%O type=%T", op, t);
-		break;
-
-	case CASE(OEQ, TBOOL):
-	case CASE(OEQ, TINT8):
-	case CASE(OEQ, TUINT8):
-	case CASE(OEQ, TINT16):
-	case CASE(OEQ, TUINT16):
-	case CASE(OEQ, TINT32):
-	case CASE(OEQ, TUINT32):
-	case CASE(OEQ, TINT64):
-	case CASE(OEQ, TUINT64):
-	case CASE(OEQ, TPTR32):
-	case CASE(OEQ, TPTR64):
-	case CASE(OEQ, TFLOAT32):
-	case CASE(OEQ, TFLOAT64):
-		a = ABEQ;
-		break;
-
-	case CASE(ONE, TBOOL):
-	case CASE(ONE, TINT8):
-	case CASE(ONE, TUINT8):
-	case CASE(ONE, TINT16):
-	case CASE(ONE, TUINT16):
-	case CASE(ONE, TINT32):
-	case CASE(ONE, TUINT32):
-	case CASE(ONE, TINT64):
-	case CASE(ONE, TUINT64):
-	case CASE(ONE, TPTR32):
-	case CASE(ONE, TPTR64):
-	case CASE(ONE, TFLOAT32):
-	case CASE(ONE, TFLOAT64):
-		a = ABNE;
-		break;
-
-	case CASE(OLT, TINT8):	// ACMP
-	case CASE(OLT, TINT16):
-	case CASE(OLT, TINT32):
-	case CASE(OLT, TINT64):
-	case CASE(OLT, TUINT8):	// ACMPU
-	case CASE(OLT, TUINT16):
-	case CASE(OLT, TUINT32):
-	case CASE(OLT, TUINT64):
-	case CASE(OLT, TFLOAT32): // AFCMPU
-	case CASE(OLT, TFLOAT64):
-		a = ABLT;
-		break;
-
-	case CASE(OLE, TINT8):	// ACMP
-	case CASE(OLE, TINT16):
-	case CASE(OLE, TINT32):
-	case CASE(OLE, TINT64):
-	case CASE(OLE, TUINT8):	// ACMPU
-	case CASE(OLE, TUINT16):
-	case CASE(OLE, TUINT32):
-	case CASE(OLE, TUINT64):
-	case CASE(OLE, TFLOAT32): // AFCMPU
-	case CASE(OLE, TFLOAT64):
-		a = ABLE;
-		break;
-
-	case CASE(OGT, TINT8):
-	case CASE(OGT, TINT16):
-	case CASE(OGT, TINT32):
-	case CASE(OGT, TINT64):
-	case CASE(OGT, TUINT8):
-	case CASE(OGT, TUINT16):
-	case CASE(OGT, TUINT32):
-	case CASE(OGT, TUINT64):
-	case CASE(OGT, TFLOAT32):
-	case CASE(OGT, TFLOAT64):
-		a = ABGT;
-		break;
-
-	case CASE(OGE, TINT8):
-	case CASE(OGE, TINT16):
-	case CASE(OGE, TINT32):
-	case CASE(OGE, TINT64):
-	case CASE(OGE, TUINT8):
-	case CASE(OGE, TUINT16):
-	case CASE(OGE, TUINT32):
-	case CASE(OGE, TUINT64):
-	case CASE(OGE, TFLOAT32):
-	case CASE(OGE, TFLOAT64):
-		a = ABGE;
-		break;
-
-	case CASE(OCMP, TBOOL):
-	case CASE(OCMP, TINT8):
-	case CASE(OCMP, TINT16):
-	case CASE(OCMP, TINT32):
-	case CASE(OCMP, TPTR32):
-	case CASE(OCMP, TINT64):
-		a = ACMP;
-		break;
-
-	case CASE(OCMP, TUINT8):
-	case CASE(OCMP, TUINT16):
-	case CASE(OCMP, TUINT32):
-	case CASE(OCMP, TUINT64):
-	case CASE(OCMP, TPTR64):
-		a = ACMPU;
-		break;
-
-	case CASE(OCMP, TFLOAT32):
-	case CASE(OCMP, TFLOAT64):
-		a = AFCMPU;
-		break;
-
-	case CASE(OAS, TBOOL):
-	case CASE(OAS, TINT8):
-		a = AMOVB;
-		break;
-
-	case CASE(OAS, TUINT8):
-		a = AMOVBZ;
-		break;
-
-	case CASE(OAS, TINT16):
-		a = AMOVH;
-		break;
-
-	case CASE(OAS, TUINT16):
-		a = AMOVHZ;
-		break;
-
-	case CASE(OAS, TINT32):
-		a = AMOVW;
-		break;
-
-	case CASE(OAS, TUINT32):
-	case CASE(OAS, TPTR32):
-		a = AMOVWZ;
-		break;
-
-	case CASE(OAS, TINT64):
-	case CASE(OAS, TUINT64):
-	case CASE(OAS, TPTR64):
-		a = AMOVD;
-		break;
-
-	case CASE(OAS, TFLOAT32):
-		a = AFMOVS;
-		break;
-
-	case CASE(OAS, TFLOAT64):
-		a = AFMOVD;
-		break;
-
-	case CASE(OADD, TINT8):
-	case CASE(OADD, TUINT8):
-	case CASE(OADD, TINT16):
-	case CASE(OADD, TUINT16):
-	case CASE(OADD, TINT32):
-	case CASE(OADD, TUINT32):
-	case CASE(OADD, TPTR32):
-	case CASE(OADD, TINT64):
-	case CASE(OADD, TUINT64):
-	case CASE(OADD, TPTR64):
-		a = AADD;
-		break;
-
-	case CASE(OADD, TFLOAT32):
-		a = AFADDS;
-		break;
-
-	case CASE(OADD, TFLOAT64):
-		a = AFADD;
-		break;
-
-	case CASE(OSUB, TINT8):
-	case CASE(OSUB, TUINT8):
-	case CASE(OSUB, TINT16):
-	case CASE(OSUB, TUINT16):
-	case CASE(OSUB, TINT32):
-	case CASE(OSUB, TUINT32):
-	case CASE(OSUB, TPTR32):
-	case CASE(OSUB, TINT64):
-	case CASE(OSUB, TUINT64):
-	case CASE(OSUB, TPTR64):
-		a = ASUB;
-		break;
-
-	case CASE(OSUB, TFLOAT32):
-		a = AFSUBS;
-		break;
-
-	case CASE(OSUB, TFLOAT64):
-		a = AFSUB;
-		break;
-
-	case CASE(OMINUS, TINT8):
-	case CASE(OMINUS, TUINT8):
-	case CASE(OMINUS, TINT16):
-	case CASE(OMINUS, TUINT16):
-	case CASE(OMINUS, TINT32):
-	case CASE(OMINUS, TUINT32):
-	case CASE(OMINUS, TPTR32):
-	case CASE(OMINUS, TINT64):
-	case CASE(OMINUS, TUINT64):
-	case CASE(OMINUS, TPTR64):
-		a = ANEG;
-		break;
-
-	case CASE(OAND, TINT8):
-	case CASE(OAND, TUINT8):
-	case CASE(OAND, TINT16):
-	case CASE(OAND, TUINT16):
-	case CASE(OAND, TINT32):
-	case CASE(OAND, TUINT32):
-	case CASE(OAND, TPTR32):
-	case CASE(OAND, TINT64):
-	case CASE(OAND, TUINT64):
-	case CASE(OAND, TPTR64):
-		a = AAND;
-		break;
-
-	case CASE(OOR, TINT8):
-	case CASE(OOR, TUINT8):
-	case CASE(OOR, TINT16):
-	case CASE(OOR, TUINT16):
-	case CASE(OOR, TINT32):
-	case CASE(OOR, TUINT32):
-	case CASE(OOR, TPTR32):
-	case CASE(OOR, TINT64):
-	case CASE(OOR, TUINT64):
-	case CASE(OOR, TPTR64):
-		a = AOR;
-		break;
-
-	case CASE(OXOR, TINT8):
-	case CASE(OXOR, TUINT8):
-	case CASE(OXOR, TINT16):
-	case CASE(OXOR, TUINT16):
-	case CASE(OXOR, TINT32):
-	case CASE(OXOR, TUINT32):
-	case CASE(OXOR, TPTR32):
-	case CASE(OXOR, TINT64):
-	case CASE(OXOR, TUINT64):
-	case CASE(OXOR, TPTR64):
-		a = AXOR;
-		break;
-
-	// TODO(minux): handle rotates
-	//case CASE(OLROT, TINT8):
-	//case CASE(OLROT, TUINT8):
-	//case CASE(OLROT, TINT16):
-	//case CASE(OLROT, TUINT16):
-	//case CASE(OLROT, TINT32):
-	//case CASE(OLROT, TUINT32):
-	//case CASE(OLROT, TPTR32):
-	//case CASE(OLROT, TINT64):
-	//case CASE(OLROT, TUINT64):
-	//case CASE(OLROT, TPTR64):
-	//	a = 0//???; RLDC?
-	//	break;
-
-	case CASE(OLSH, TINT8):
-	case CASE(OLSH, TUINT8):
-	case CASE(OLSH, TINT16):
-	case CASE(OLSH, TUINT16):
-	case CASE(OLSH, TINT32):
-	case CASE(OLSH, TUINT32):
-	case CASE(OLSH, TPTR32):
-	case CASE(OLSH, TINT64):
-	case CASE(OLSH, TUINT64):
-	case CASE(OLSH, TPTR64):
-		a = ASLD;
-		break;
-
-	case CASE(ORSH, TUINT8):
-	case CASE(ORSH, TUINT16):
-	case CASE(ORSH, TUINT32):
-	case CASE(ORSH, TPTR32):
-	case CASE(ORSH, TUINT64):
-	case CASE(ORSH, TPTR64):
-		a = ASRD;
-		break;
-
-	case CASE(ORSH, TINT8):
-	case CASE(ORSH, TINT16):
-	case CASE(ORSH, TINT32):
-	case CASE(ORSH, TINT64):
-		a = ASRAD;
-		break;
-
-	// TODO(minux): handle rotates
-	//case CASE(ORROTC, TINT8):
-	//case CASE(ORROTC, TUINT8):
-	//case CASE(ORROTC, TINT16):
-	//case CASE(ORROTC, TUINT16):
-	//case CASE(ORROTC, TINT32):
-	//case CASE(ORROTC, TUINT32):
-	//case CASE(ORROTC, TINT64):
-	//case CASE(ORROTC, TUINT64):
-	//	a = 0//??? RLDC??
-	//	break;
-
-	case CASE(OHMUL, TINT64):
-		a = AMULHD;
-		break;
-	case CASE(OHMUL, TUINT64):
-	case CASE(OHMUL, TPTR64):
-		a = AMULHDU;
-		break;
-
-	case CASE(OMUL, TINT8):
-	case CASE(OMUL, TINT16):
-	case CASE(OMUL, TINT32):
-	case CASE(OMUL, TINT64):
-		a = AMULLD;
-		break;
-
-	case CASE(OMUL, TUINT8):
-	case CASE(OMUL, TUINT16):
-	case CASE(OMUL, TUINT32):
-	case CASE(OMUL, TPTR32):
-		// don't use word multiply, the high 32-bit are undefined.
-		// fallthrough
-	case CASE(OMUL, TUINT64):
-	case CASE(OMUL, TPTR64):
-		a = AMULLD; // for 64-bit multiplies, signedness doesn't matter.
-		break;
-
-	case CASE(OMUL, TFLOAT32):
-		a = AFMULS;
-		break;
-
-	case CASE(OMUL, TFLOAT64):
-		a = AFMUL;
-		break;
-
-	case CASE(ODIV, TINT8):
-	case CASE(ODIV, TINT16):
-	case CASE(ODIV, TINT32):
-	case CASE(ODIV, TINT64):
-		a = ADIVD;
-		break;
-
-	case CASE(ODIV, TUINT8):
-	case CASE(ODIV, TUINT16):
-	case CASE(ODIV, TUINT32):
-	case CASE(ODIV, TPTR32):
-	case CASE(ODIV, TUINT64):
-	case CASE(ODIV, TPTR64):
-		a = ADIVDU;
-		break;
-
-	case CASE(ODIV, TFLOAT32):
-		a = AFDIVS;
-		break;
-
-	case CASE(ODIV, TFLOAT64):
-		a = AFDIV;
-		break;
-
-	}
-	return a;
-}
-
-enum
-{
-	ODynam		= 1<<0,
-	OAddable	= 1<<1,
-};
-
-int
-xgen(Node *n, Node *a, int o)
-{
-	// TODO(minux)
-	USED(n); USED(a); USED(o);
-	return -1;
-}
-
-void
-sudoclean(void)
-{
-	return;
-}
-
-/*
- * generate code to compute address of n,
- * a reference to a (perhaps nested) field inside
- * an array or struct.
- * return 0 on failure, 1 on success.
- * on success, leaves usable address in a.
- *
- * caller is responsible for calling sudoclean
- * after successful sudoaddable,
- * to release the register used for a.
- */
-int
-sudoaddable(int as, Node *n, Addr *a)
-{
-	// TODO(minux)
-	USED(as); USED(n);
-	memset(a, 0, sizeof *a);
-	return 0;
-}
diff --git a/src/cmd/new9g/gsubr.go b/src/cmd/9g/gsubr.go
similarity index 100%
rename from src/cmd/new9g/gsubr.go
rename to src/cmd/9g/gsubr.go
diff --git a/src/cmd/new9g/opt.go b/src/cmd/9g/opt.go
similarity index 100%
rename from src/cmd/new9g/opt.go
rename to src/cmd/9g/opt.go
diff --git a/src/cmd/9g/opt.h b/src/cmd/9g/opt.h
deleted file mode 100644
index 79a34fb..0000000
--- a/src/cmd/9g/opt.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 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.
-
-// Many Power ISA arithmetic and logical instructions come in four
-// standard variants.  These bits let us map between variants.
-enum {
-	V_CC = 1<<0,		// xCC (affect CR field 0 flags)
-	V_V  = 1<<1,		// xV (affect SO and OV flags)
-};
-
-int as2variant(int);
-int variant2as(int, int);
diff --git a/src/cmd/9g/peep.c b/src/cmd/9g/peep.c
deleted file mode 100644
index cf96d5d..0000000
--- a/src/cmd/9g/peep.c
+++ /dev/null
@@ -1,959 +0,0 @@
-// Derived from Inferno utils/6c/peep.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.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 "gg.h"
-#include "../gc/popt.h"
-#include "opt.h"
-
-static int	regzer(Addr *a);
-static int	subprop(Flow*);
-static int	copyprop(Flow*);
-static int	copy1(Addr*, Addr*, Flow*, int);
-static int	copyas(Addr*, Addr*);
-static int	copyau(Addr*, Addr*);
-static int	copysub(Addr*, Addr*, Addr*, int);
-static int	copysub1(Prog*, Addr*, Addr*, int);
-static int	copyau1(Prog *p, Addr *v);
-static int	copyu(Prog *p, Addr *v, Addr *s);
-
-static uint32	gactive;
-
-void
-peep(Prog *firstp)
-{
-	Graph *g;
-	Flow *r, *r1;
-	Prog *p, *p1;
-	int t;
-
-	g = flowstart(firstp, 0);
-	if(g == nil)
-		return;
-	gactive = 0;
-
-loop1:
-	if(debug['P'] && debug['v'])
-		dumpit("loop1", g->start, 0);
-
-	t = 0;
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		// TODO(austin) Handle smaller moves.  arm and amd64
-		// distinguish between moves that moves that *must*
-		// sign/zero extend and moves that don't care so they
-		// can eliminate moves that don't care without
-		// breaking moves that do care.  This might let us
-		// simplify or remove the next peep loop, too.
-		if(p->as == AMOVD || p->as == AFMOVD)
-		if(regtyp(&p->to)) {
-			// Try to eliminate reg->reg moves
-			if(regtyp(&p->from))
-			if(p->from.type == p->to.type) {
-				if(copyprop(r)) {
-					excise(r);
-					t++;
-				} else
-				if(subprop(r) && copyprop(r)) {
-					excise(r);
-					t++;
-				}
-			}
-			// Convert uses to $0 to uses of R0 and
-			// propagate R0
-			if(regzer(&p->from))
-			if(p->to.type == TYPE_REG) {
-				p->from.type = TYPE_REG;
-				p->from.reg = REGZERO;
-				if(copyprop(r)) {
-					excise(r);
-					t++;
-				} else
-				if(subprop(r) && copyprop(r)) {
-					excise(r);
-					t++;
-				}
-			}
-		}
-	}
-	if(t)
-		goto loop1;
-
-	/*
-	 * look for MOVB x,R; MOVB R,R (for small MOVs not handled above)
-	 */
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		default:
-			continue;
-		case AMOVH:
-		case AMOVHZ:
-		case AMOVB:
-		case AMOVBZ:
-		case AMOVW:
-		case AMOVWZ:
-			if(p->to.type != TYPE_REG)
-				continue;
-			break;
-		}
-		r1 = r->link;
-		if(r1 == nil)
-			continue;
-		p1 = r1->prog;
-		if(p1->as != p->as)
-			continue;
-		if(p1->from.type != TYPE_REG || p1->from.reg != p->to.reg)
-			continue;
-		if(p1->to.type != TYPE_REG || p1->to.reg != p->to.reg)
-			continue;
-		excise(r1);
-	}
-
-	if(debug['D'] > 1)
-		goto ret;	/* allow following code improvement to be suppressed */
-
-	/*
-	 * look for OP x,y,R; CMP R, $0 -> OPCC x,y,R
-	 * when OP can set condition codes correctly
-	 */
-	for(r=g->start; r!=nil; r=r->link) {
-		p = r->prog;
-		switch(p->as) {
-		case ACMP:
-		case ACMPW:		/* always safe? */
-			if(!regzer(&p->to))
-				continue;
-			r1 = r->s1;
-			if(r1 == nil)
-				continue;
-			switch(r1->prog->as) {
-			default:
-				continue;
-			case ABCL:
-			case ABC:
-				/* the conditions can be complex and these are currently little used */
-				continue;
-			case ABEQ:
-			case ABGE:
-			case ABGT:
-			case ABLE:
-			case ABLT:
-			case ABNE:
-			case ABVC:
-			case ABVS:
-				break;
-			}
-			r1 = r;
-			do
-				r1 = uniqp(r1);
-			while (r1 != nil && r1->prog->as == ANOP);
-			if(r1 == nil)
-				continue;
-			p1 = r1->prog;
-			if(p1->to.type != TYPE_REG || p1->to.reg != p->from.reg)
-				continue;
-			switch(p1->as) {
-			case ASUB:
-			case AADD:
-			case AXOR:
-			case AOR:
-				/* irregular instructions */
-				if(p1->from.type == TYPE_CONST || p1->from.type == TYPE_ADDR)
-					continue;
-				break;
-			}
-			switch(p1->as) {
-			default:
-				continue;
-			case AMOVW:
-			case AMOVD:
-				if(p1->from.type != TYPE_REG)
-					continue;
-				continue;
-			case AANDCC:
-			case AANDNCC:
-			case AORCC:
-			case AORNCC:
-			case AXORCC:
-			case ASUBCC:
-			case ASUBECC:
-			case ASUBMECC:
-			case ASUBZECC:
-			case AADDCC:
-			case AADDCCC:
-			case AADDECC:
-			case AADDMECC:
-			case AADDZECC:
-			case ARLWMICC:
-			case ARLWNMCC:
-			/* don't deal with floating point instructions for now */
-/*
-			case AFABS:
-			case AFADD:
-			case AFADDS:
-			case AFCTIW:
-			case AFCTIWZ:
-			case AFDIV:
-			case AFDIVS:
-			case AFMADD:
-			case AFMADDS:
-			case AFMOVD:
-			case AFMSUB:
-			case AFMSUBS:
-			case AFMUL:
-			case AFMULS:
-			case AFNABS:
-			case AFNEG:
-			case AFNMADD:
-			case AFNMADDS:
-			case AFNMSUB:
-			case AFNMSUBS:
-			case AFRSP:
-			case AFSUB:
-			case AFSUBS:
-			case ACNTLZW:
-			case AMTFSB0:
-			case AMTFSB1:
-*/
-			case AADD:
-			case AADDV:
-			case AADDC:
-			case AADDCV:
-			case AADDME:
-			case AADDMEV:
-			case AADDE:
-			case AADDEV:
-			case AADDZE:
-			case AADDZEV:
-			case AAND:
-			case AANDN:
-			case ADIVW:
-			case ADIVWV:
-			case ADIVWU:
-			case ADIVWUV:
-			case ADIVD:
-			case ADIVDV:
-			case ADIVDU:
-			case ADIVDUV:
-			case AEQV:
-			case AEXTSB:
-			case AEXTSH:
-			case AEXTSW:
-			case AMULHW:
-			case AMULHWU:
-			case AMULLW:
-			case AMULLWV:
-			case AMULHD:
-			case AMULHDU:
-			case AMULLD:
-			case AMULLDV:
-			case ANAND:
-			case ANEG:
-			case ANEGV:
-			case ANOR:
-			case AOR:
-			case AORN:
-			case AREM:
-			case AREMV:
-			case AREMU:
-			case AREMUV:
-			case AREMD:
-			case AREMDV:
-			case AREMDU:
-			case AREMDUV:
-			case ARLWMI:
-			case ARLWNM:
-			case ASLW:
-			case ASRAW:
-			case ASRW:
-			case ASLD:
-			case ASRAD:
-			case ASRD:
-			case ASUB:
-			case ASUBV:
-			case ASUBC:
-			case ASUBCV:
-			case ASUBME:
-			case ASUBMEV:
-			case ASUBE:
-			case ASUBEV:
-			case ASUBZE:
-			case ASUBZEV:
-			case AXOR:
-				t = variant2as(p1->as, as2variant(p1->as) | V_CC);
-				break;
-			}
-			if(debug['D'])
-				print("cmp %P; %P -> ", p1, p);
-			p1->as = t;
-			if(debug['D'])
-				print("%P\n", p1);
-			excise(r);
-			continue;
-		}
-	}
-
-ret:
-	flowend(g);
-}
-
-void
-excise(Flow *r)
-{
-	Prog *p;
-
-	p = r->prog;
-	if(debug['P'] && debug['v'])
-		print("%P ===delete===\n", p);
-	nopout(p);
-	ostats.ndelmov++;
-}
-
-/*
- * regzer returns 1 if a's value is 0 (a is R0 or $0)
- */
-static int
-regzer(Addr *a)
-{
-	if(a->type == TYPE_CONST || a->type == TYPE_ADDR)
-		if(a->sym == nil && a->reg == 0)
-			if(a->offset == 0)
-				return 1;
-	if(a->type == TYPE_REG)
-		if(a->reg == REGZERO)
-			return 1;
-	return 0;
-}
-
-int
-regtyp(Adr *a)
-{
-	// TODO(rsc): Floating point register exclusions?
-	return a->type == TYPE_REG && REG_R0 <= a->reg && a->reg <= REG_F31 && a->reg != REGZERO;
-}
-
-/*
- * the idea is to substitute
- * one register for another
- * from one MOV to another
- *	MOV	a, R1
- *	ADD	b, R1	/ no use of R2
- *	MOV	R1, R2
- * would be converted to
- *	MOV	a, R2
- *	ADD	b, R2
- *	MOV	R2, R1
- * hopefully, then the former or latter MOV
- * will be eliminated by copy propagation.
- *
- * r0 (the argument, not the register) is the MOV at the end of the
- * above sequences.  This returns 1 if it modified any instructions.
- */
-static int
-subprop(Flow *r0)
-{
-	Prog *p;
-	Addr *v1, *v2;
-	Flow *r;
-	int t;
-	ProgInfo info;
-
-	p = r0->prog;
-	v1 = &p->from;
-	if(!regtyp(v1))
-		return 0;
-	v2 = &p->to;
-	if(!regtyp(v2))
-		return 0;
-	for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
-		if(uniqs(r) == nil)
-			break;
-		p = r->prog;
-		if(p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-		proginfo(&info, p);
-		if(info.flags & Call)
-			return 0;
-
-		if((info.flags & (RightRead|RightWrite)) == RightWrite) {
-			if(p->to.type == v1->type)
-			if(p->to.reg == v1->reg)
-				goto gotit;
-		}
-
-		if(copyau(&p->from, v2) ||
-		   copyau1(p, v2) ||
-		   copyau(&p->to, v2))
-			break;
-		if(copysub(&p->from, v1, v2, 0) ||
-		   copysub1(p, v1, v2, 0) ||
-		   copysub(&p->to, v1, v2, 0))
-			break;
-	}
-	return 0;
-
-gotit:
-	copysub(&p->to, v1, v2, 1);
-	if(debug['P']) {
-		print("gotit: %D->%D\n%P", v1, v2, r->prog);
-		if(p->from.type == v2->type)
-			print(" excise");
-		print("\n");
-	}
-	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
-		p = r->prog;
-		copysub(&p->from, v1, v2, 1);
-		copysub1(p, v1, v2, 1);
-		copysub(&p->to, v1, v2, 1);
-		if(debug['P'])
-			print("%P\n", r->prog);
-	}
-	t = v1->reg;
-	v1->reg = v2->reg;
-	v2->reg = t;
-	if(debug['P'])
-		print("%P last\n", r->prog);
-	return 1;
-}
-
-/*
- * The idea is to remove redundant copies.
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	use v2	return fail (v1->v2 move must remain)
- *	-----------------
- *	v1->v2	F=0
- *	(use v2	s/v2/v1/)*
- *	set v1	F=1
- *	set v2	return success (caller can remove v1->v2 move)
- */
-static int
-copyprop(Flow *r0)
-{
-	Prog *p;
-	Addr *v1, *v2;
-
-	p = r0->prog;
-	v1 = &p->from;
-	v2 = &p->to;
-	if(copyas(v1, v2)) {
-		if(debug['P'])
-			print("eliminating self-move\n", r0->prog);
-		return 1;
-	}
-	gactive++;
-	if(debug['P'])
-		print("trying to eliminate %D->%D move from:\n%P\n", v1, v2, r0->prog);
-	return copy1(v1, v2, r0->s1, 0);
-}
-
-// copy1 replaces uses of v2 with v1 starting at r and returns 1 if
-// all uses were rewritten.
-static int
-copy1(Addr *v1, Addr *v2, Flow *r, int f)
-{
-	int t;
-	Prog *p;
-
-	if(r->active == gactive) {
-		if(debug['P'])
-			print("act set; return 1\n");
-		return 1;
-	}
-	r->active = gactive;
-	if(debug['P'])
-		print("copy1 replace %D with %D f=%d\n", v2, v1, f);
-	for(; r != nil; r = r->s1) {
-		p = r->prog;
-		if(debug['P'])
-			print("%P", p);
-		if(!f && uniqp(r) == nil) {
-			// Multiple predecessors; conservatively
-			// assume v1 was set on other path
-			f = 1;
-			if(debug['P'])
-				print("; merge; f=%d", f);
-		}
-		t = copyu(p, v2, nil);
-		switch(t) {
-		case 2:	/* rar, can't split */
-			if(debug['P'])
-				print("; %D rar; return 0\n", v2);
-			return 0;
-
-		case 3:	/* set */
-			if(debug['P'])
-				print("; %D set; return 1\n", v2);
-			return 1;
-
-		case 1:	/* used, substitute */
-		case 4:	/* use and set */
-			if(f) {
-				if(!debug['P'])
-					return 0;
-				if(t == 4)
-					print("; %D used+set and f=%d; return 0\n", v2, f);
-				else
-					print("; %D used and f=%d; return 0\n", v2, f);
-				return 0;
-			}
-			if(copyu(p, v2, v1)) {
-				if(debug['P'])
-					print("; sub fail; return 0\n");
-				return 0;
-			}
-			if(debug['P'])
-				print("; sub %D->%D\n => %P", v2, v1, p);
-			if(t == 4) {
-				if(debug['P'])
-					print("; %D used+set; return 1\n", v2);
-				return 1;
-			}
-			break;
-		}
-		if(!f) {
-			t = copyu(p, v1, nil);
-			if(!f && (t == 2 || t == 3 || t == 4)) {
-				f = 1;
-				if(debug['P'])
-					print("; %D set and !f; f=%d", v1, f);
-			}
-		}
-		if(debug['P'])
-			print("\n");
-		if(r->s2)
-			if(!copy1(v1, v2, r->s2, f))
-				return 0;
-	}
-	return 1;
-}
-
-// If s==nil, copyu returns the set/use of v in p; otherwise, it
-// modifies p to replace reads of v with reads of s and returns 0 for
-// success or non-zero for failure.
-//
-// If s==nil, copy returns one of the following values:
-// 	1 if v only used
-//	2 if v is set and used in one address (read-alter-rewrite;
-// 	  can't substitute)
-//	3 if v is only set
-//	4 if v is set in one address and used in another (so addresses
-// 	  can be rewritten independently)
-//	0 otherwise (not touched)
-static int
-copyu(Prog *p, Addr *v, Addr *s)
-{
-	if(p->from3.type != TYPE_NONE)
-		// 9g never generates a from3
-		print("copyu: from3 (%D) not implemented\n", &p->from3);
-
-	switch(p->as) {
-
-	default:
-		print("copyu: can't find %A\n", p->as);
-		return 2;
-
-	case ANOP:	/* read p->from, write p->to */
-	case AMOVH:
-	case AMOVHZ:
-	case AMOVB:
-	case AMOVBZ:
-	case AMOVW:
-	case AMOVWZ:
-	case AMOVD:
-
-	case ANEG:
-	case ANEGCC:
-	case AADDME:
-	case AADDMECC:
-	case AADDZE:
-	case AADDZECC:
-	case ASUBME:
-	case ASUBMECC:
-	case ASUBZE:
-	case ASUBZECC:
-
-	case AFCTIW:
-	case AFCTIWZ:
-	case AFCTID:
-	case AFCTIDZ:
-	case AFCFID:
-	case AFCFIDCC:
-	case AFMOVS:
-	case AFMOVD:
-	case AFRSP:
-	case AFNEG:
-	case AFNEGCC:
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			// Update only indirect uses of v in p->to
-			if(!copyas(&p->to, v))
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-			return 0;
-		}
-		if(copyas(&p->to, v)) {
-			// Fix up implicit from
-			if(p->from.type == TYPE_NONE)
-				p->from = p->to;
-			if(copyau(&p->from, v))
-				return 4;
-			return 3;
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau(&p->to, v))
-			// p->to only indirectly uses v
-			return 1;
-		return 0;
-
-	case AMOVBU:	/* rar p->from, write p->to or read p->from, rar p->to */
-	case AMOVBZU:
-	case AMOVHU:
-	case AMOVHZU:
-	case AMOVWZU:
-	case AMOVDU:
-		if(p->from.type == TYPE_MEM) {
-			if(copyas(&p->from, v))
-				// No s!=nil check; need to fail
-				// anyway in that case
-				return 2;
-			if(s != nil) {
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-				return 0;
-			}
-			if(copyas(&p->to, v))
-				return 3;
-		} else if (p->to.type == TYPE_MEM) {
-			if(copyas(&p->to, v))
-				return 2;
-			if(s != nil) {
-				if(copysub(&p->from, v, s, 1))
-					return 1;
-				return 0;
-			}
-			if(copyau(&p->from, v))
-				return 1;
-		} else {
-			print("copyu: bad %P\n", p);
-		}
-		return 0;
-
-	case ARLWMI:	/* read p->from, read p->reg, rar p->to */
-	case ARLWMICC:
-		if(copyas(&p->to, v))
-			return 2;
-		/* fall through */
-
-	case AADD:	/* read p->from, read p->reg, write p->to */
-	case AADDC:
-	case AADDE:
-	case ASUB:
-	case ASLW:
-	case ASRW:
-	case ASRAW:
-	case ASLD:
-	case ASRD:
-	case ASRAD:
-	case AOR:
-	case AORCC:
-	case AORN:
-	case AORNCC:
-	case AAND:
-	case AANDCC:
-	case AANDN:
-	case AANDNCC:
-	case ANAND:
-	case ANANDCC:
-	case ANOR:
-	case ANORCC:
-	case AXOR:
-	case AMULHW:
-	case AMULHWU:
-	case AMULLW:
-	case AMULLD:
-	case ADIVW:
-	case ADIVD:
-	case ADIVWU:
-	case ADIVDU:
-	case AREM:
-	case AREMU:
-	case AREMD:
-	case AREMDU:
-	case ARLWNM:
-	case ARLWNMCC:
-
-	case AFADDS:
-	case AFADD:
-	case AFSUBS:
-	case AFSUB:
-	case AFMULS:
-	case AFMUL:
-	case AFDIVS:
-	case AFDIV:
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			if(copysub1(p, v, s, 1))
-				return 1;
-			// Update only indirect uses of v in p->to
-			if(!copyas(&p->to, v))
-				if(copysub(&p->to, v, s, 1))
-					return 1;
-			return 0;
-		}
-		if(copyas(&p->to, v)) {
-			if(p->reg == 0)
-				// Fix up implicit reg (e.g., ADD
-				// R3,R4 -> ADD R3,R4,R4) so we can
-				// update reg and to separately.
-				p->reg = p->to.reg;
-			if(copyau(&p->from, v))
-				return 4;
-			if(copyau1(p, v))
-				return 4;
-			return 3;
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau1(p, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ABEQ:
-	case ABGT:
-	case ABGE:
-	case ABLT:
-	case ABLE:
-	case ABNE:
-	case ABVC:
-	case ABVS:
-		return 0;
-
-	case ACHECKNIL:	/* read p->from */
-	case ACMP:	/* read p->from, read p->to */
-	case ACMPU:
-	case ACMPW:
-	case ACMPWU:
-	case AFCMPO:
-	case AFCMPU:
-		if(s != nil) {
-			if(copysub(&p->from, v, s, 1))
-				return 1;
-			return copysub(&p->to, v, s, 1);
-		}
-		if(copyau(&p->from, v))
-			return 1;
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ABR:	/* read p->to */
-		// 9g never generates a branch to a GPR (this isn't
-		// even a normal instruction; liblink turns it in to a
-		// mov and a branch).
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 1;
-		return 0;
-
-	case ARETURN:	/* funny */
-		if(s != nil)
-			return 0;
-		// All registers die at this point, so claim
-		// everything is set (and not used).
-		return 3;
-
-	case ABL:	/* funny */
-		if(v->type == TYPE_REG) {
-			// TODO(rsc): REG_R0 and REG_F0 used to be
-			// (when register numbers started at 0) exregoffset and exfregoffset,
-			// which are unset entirely. 
-			// It's strange that this handles R0 and F0 differently from the other
-			// registers. Possible failure to optimize?
-			if(REG_R0 < v->reg && v->reg <= REGEXT)
-				return 2;
-			if(v->reg == REGARG)
-				return 2;
-			if(REG_F0 < v->reg && v->reg <= FREGEXT)
-				return 2;
-		}
-		if(p->from.type == TYPE_REG && v->type == TYPE_REG && p->from.reg == v->reg)
-			return 2;
-
-		if(s != nil) {
-			if(copysub(&p->to, v, s, 1))
-				return 1;
-			return 0;
-		}
-		if(copyau(&p->to, v))
-			return 4;
-		return 3;
-
-	case ADUFFZERO:
-		// R0 is zero, used by DUFFZERO, cannot be substituted.
-		// R3 is ptr to memory, used and set, cannot be substituted.
-		if(v->type == TYPE_REG) {
-			if(v->reg == 0)
-				return 1;
-			if(v->reg == 3)
-				return 2;
-		}
-		return 0;
-
-	case ADUFFCOPY:
-		// R3, R4 are ptr to src, dst, used and set, cannot be substituted.
-		// R5 is scratch, set by DUFFCOPY, cannot be substituted.
-		if(v->type == TYPE_REG) {
-			if(v->reg == 3 || v->reg == 4)
-				return 2;
-			if(v->reg == 5)
-				return 3;
-		}
-		return 0;
-
-	case ATEXT:	/* funny */
-		if(v->type == TYPE_REG)
-			if(v->reg == REGARG)
-				return 3;
-		return 0;
-
-	case APCDATA:
-	case AFUNCDATA:
-	case AVARDEF:
-	case AVARKILL:
-		return 0;
-	}
-}
-
-// copyas returns 1 if a and v address the same register.
-//
-// If a is the from operand, this means this operation reads the
-// register in v.  If a is the to operand, this means this operation
-// writes the register in v.
-static int
-copyas(Addr *a, Addr *v)
-{
-	if(regtyp(v))
-		if(a->type == v->type)
-		if(a->reg == v->reg)
-			return 1;
-	return 0;
-}
-
-// copyau returns 1 if a either directly or indirectly addresses the
-// same register as v.
-//
-// If a is the from operand, this means this operation reads the
-// register in v.  If a is the to operand, this means the operation
-// either reads or writes the register in v (if !copyas(a, v), then
-// the operation reads the register in v).
-static int
-copyau(Addr *a, Addr *v)
-{
-	if(copyas(a, v))
-		return 1;
-	if(v->type == TYPE_REG)
-		if(a->type == TYPE_MEM || (a->type == TYPE_ADDR && a->reg != 0))
-			if(v->reg == a->reg)
-				return 1;
-	return 0;
-}
-
-// copyau1 returns 1 if p->reg references the same register as v and v
-// is a direct reference.
-static int
-copyau1(Prog *p, Addr *v)
-{
-	if(regtyp(v) && v->reg != 0)
-		if(p->reg == v->reg)
-			return 1;
-	return 0;
-}
-
-// copysub replaces v with s in a if f!=0 or indicates it if could if f==0.
-// Returns 1 on failure to substitute (it always succeeds on ppc64).
-static int
-copysub(Addr *a, Addr *v, Addr *s, int f)
-{
-	if(f)
-	if(copyau(a, v))
-		a->reg = s->reg;
-	return 0;
-}
-
-// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0.
-// Returns 1 on failure to substitute (it always succeeds on ppc64).
-static int
-copysub1(Prog *p1, Addr *v, Addr *s, int f)
-{
-	if(f)
-	if(copyau1(p1, v))
-		p1->reg = s->reg;
-	return 0;
-}
-
-int
-sameaddr(Addr *a, Addr *v)
-{
-	if(a->type != v->type)
-		return 0;
-	if(regtyp(v) && a->reg == v->reg)
-		return 1;
-	if(v->type == NAME_AUTO || v->type == NAME_PARAM)
-		if(v->offset == a->offset)
-			return 1;
-	return 0;
-}
-
-int
-smallindir(Addr *a, Addr *reg)
-{
-	return reg->type == TYPE_REG && a->type == TYPE_MEM &&
-		a->reg == reg->reg &&
-		0 <= a->offset && a->offset < 4096;
-}
-
-int
-stackaddr(Addr *a)
-{
-	return a->type == TYPE_REG && a->reg == REGSP;
-}
diff --git a/src/cmd/new9g/peep.go b/src/cmd/9g/peep.go
similarity index 100%
rename from src/cmd/new9g/peep.go
rename to src/cmd/9g/peep.go
diff --git a/src/cmd/9g/prog.c b/src/cmd/9g/prog.c
deleted file mode 100644
index 561249c..0000000
--- a/src/cmd/9g/prog.c
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2014 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"
-#include "../gc/popt.h"
-#include "opt.h"
-
-enum {
-	LeftRdwr = LeftRead | LeftWrite,
-	RightRdwr = RightRead | RightWrite,
-};
-
-// This table gives the basic information about instruction
-// generated by the compiler and processed in the optimizer.
-// See opt.h for bit definitions.
-//
-// Instructions not generated need not be listed.
-// As an exception to that rule, we typically write down all the
-// size variants of an operation even if we just use a subset.
-//
-// The table is formatted for 8-space tabs.
-static ProgInfo progtable[ALAST] = {
-	[ATYPE]=	{Pseudo | Skip},
-	[ATEXT]=	{Pseudo},
-	[AFUNCDATA]=	{Pseudo},
-	[APCDATA]=	{Pseudo},
-	[AUNDEF]=	{Break},
-	[AUSEFIELD]=	{OK},
-	[ACHECKNIL]=	{LeftRead},
-	[AVARDEF]=	{Pseudo | RightWrite},
-	[AVARKILL]=	{Pseudo | RightWrite},
-
-	// NOP is an internal no-op that also stands
-	// for USED and SET annotations, not the Power opcode.
-	[ANOP]=		{LeftRead | RightWrite},
-
-	// Integer
-	[AADD]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[ASUB]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[ANEG]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[AAND]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[AOR]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[AXOR]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[AMULLD]=	{SizeQ | LeftRead | RegRead | RightWrite},
-	[AMULLW]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMULHD]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[AMULHDU]=	{SizeL | LeftRead | RegRead | RightWrite},
-	[ADIVD]=	{SizeQ | LeftRead | RegRead | RightWrite},
-	[ADIVDU]=	{SizeQ | LeftRead | RegRead | RightWrite},
-	[ASLD]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[ASRD]=		{SizeQ | LeftRead | RegRead | RightWrite},
-	[ASRAD]=	{SizeQ | LeftRead | RegRead | RightWrite},
-	[ACMP]=		{SizeQ | LeftRead | RightRead},
-	[ACMPU]=	{SizeQ | LeftRead | RightRead},
-	[ATD]=		{SizeQ | RightRead},
-
-	// Floating point.
-	[AFADD]=	{SizeD | LeftRead | RegRead | RightWrite},
-	[AFADDS]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFSUB]=	{SizeD | LeftRead | RegRead | RightWrite},
-	[AFSUBS]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFMUL]=	{SizeD | LeftRead | RegRead | RightWrite},
-	[AFMULS]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFDIV]=	{SizeD | LeftRead | RegRead | RightWrite},
-	[AFDIVS]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFCTIDZ]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFCFID]=	{SizeF | LeftRead | RegRead | RightWrite},
-	[AFCMPU]=	{SizeD | LeftRead | RightRead},
-	[AFRSP]=	{SizeD | LeftRead | RightWrite | Conv},
-
-	// Moves
-	[AMOVB]=	{SizeB | LeftRead | RightWrite | Move | Conv},
-	[AMOVBU]=	{SizeB | LeftRead | RightWrite | Move | Conv | PostInc},
-	[AMOVBZ]=	{SizeB | LeftRead | RightWrite | Move | Conv},
-	[AMOVH]=	{SizeW | LeftRead | RightWrite | Move | Conv},
-	[AMOVHU]=	{SizeW | LeftRead | RightWrite | Move | Conv | PostInc},
-	[AMOVHZ]=	{SizeW | LeftRead | RightWrite | Move | Conv},
-	[AMOVW]=	{SizeL | LeftRead | RightWrite | Move | Conv},
-	// there is no AMOVWU.
-	[AMOVWZU]=	{SizeL | LeftRead | RightWrite | Move | Conv | PostInc},
-	[AMOVWZ]=	{SizeL | LeftRead | RightWrite | Move | Conv},
-	[AMOVD]=	{SizeQ | LeftRead | RightWrite | Move},
-	[AMOVDU]=	{SizeQ | LeftRead | RightWrite | Move | PostInc},
-	[AFMOVS]=	{SizeF | LeftRead | RightWrite | Move | Conv},
-	[AFMOVD]=	{SizeD | LeftRead | RightWrite | Move},
-
-	// Jumps
-	[ABR]=		{Jump | Break},
-	[ABL]=		{Call},
-	[ABEQ]=		{Cjmp},
-	[ABNE]=		{Cjmp},
-	[ABGE]=		{Cjmp},
-	[ABLT]=		{Cjmp},
-	[ABGT]=		{Cjmp},
-	[ABLE]=		{Cjmp},
-	[ARETURN]=	{Break},
-
-	[ADUFFZERO]=	{Call},
-	[ADUFFCOPY]=	{Call},
-};
-
-static void
-initproginfo(void)
-{
-	static int initialized;
-	int addvariant[] = {V_CC, V_V, V_CC|V_V};
-	int as, as2, i, variant;
-
-	if(initialized)
-		return;
-	initialized = 1;
-
-	// Perform one-time expansion of instructions in progtable to
-	// their CC, V, and VCC variants
-	for(as=0; as<nelem(progtable); as++) {
-		if(progtable[as].flags == 0)
-			continue;
-		variant = as2variant(as);
-		for(i=0; i<nelem(addvariant); i++) {
-			as2 = variant2as(as, variant | addvariant[i]);
-			if(as2 != 0 && progtable[as2].flags == 0)
-				progtable[as2] = progtable[as];
-		}
-	}
-}
-
-void
-proginfo(ProgInfo *info, Prog *p)
-{
-	initproginfo();
-
-	*info = progtable[p->as];
-	if(info->flags == 0) {
-		*info = progtable[AADD];
-		fatal("proginfo: unknown instruction %P", p);
-	}
-
-	if((info->flags & RegRead) && p->reg == 0) {
-		info->flags &= ~RegRead;
-		info->flags |= /*CanRegRead |*/ RightRead;
-	}
-
-	if((p->from.type == TYPE_MEM || p->from.type == TYPE_ADDR) && p->from.reg != 0) {
-		info->regindex |= RtoB(p->from.reg);
-		if(info->flags & PostInc) {
-			info->regset |= RtoB(p->from.reg);
-		}
-	}
-	if((p->to.type == TYPE_MEM || p->to.type == TYPE_ADDR) && p->to.reg != 0) {
-		info->regindex |= RtoB(p->to.reg);
-		if(info->flags & PostInc) {
-			info->regset |= RtoB(p->to.reg);
-		}
-	}
-
-	if(p->from.type == TYPE_ADDR && p->from.sym != nil && (info->flags & LeftRead)) {
-		info->flags &= ~LeftRead;
-		info->flags |= LeftAddr;
-	}
-
-	if(p->as == ADUFFZERO) {
-		info->reguse |= (1<<0) | RtoB(REG_R3);
-		info->regset |= RtoB(REG_R3);
-	}
-	if(p->as == ADUFFCOPY) {
-		// TODO(austin) Revisit when duffcopy is implemented
-		info->reguse |= RtoB(REG_R3) | RtoB(REG_R4) | RtoB(REG_R5);
-		info->regset |= RtoB(REG_R3) | RtoB(REG_R4);
-	}
-}
-
-// Instruction variants table.  Initially this contains entries only
-// for the "base" form of each instruction.  On the first call to
-// as2variant or variant2as, we'll add the variants to the table.
-static int varianttable[ALAST][4] = {
-	[AADD]=		{AADD,		AADDCC,		AADDV,		AADDVCC},
-	[AADDC]=	{AADDC,		AADDCCC,	AADDCV,		AADDCVCC},
-	[AADDE]=	{AADDE,		AADDECC,	AADDEV,		AADDEVCC},
-	[AADDME]=	{AADDME,	AADDMECC,	AADDMEV,	AADDMEVCC},
-	[AADDZE]=	{AADDZE,	AADDZECC,	AADDZEV,	AADDZEVCC},
-	[AAND]=		{AAND,		AANDCC,		0,		0},
-	[AANDN]=	{AANDN,		AANDNCC,	0,		0},
-	[ACNTLZD]=	{ACNTLZD,	ACNTLZDCC,	0,		0},
-	[ACNTLZW]=	{ACNTLZW,	ACNTLZWCC,	0,		0},
-	[ADIVD]=	{ADIVD,		ADIVDCC,	ADIVDV,		ADIVDVCC},
-	[ADIVDU]=	{ADIVDU,	ADIVDUCC,	ADIVDUV,	ADIVDUVCC},
-	[ADIVW]=	{ADIVW,		ADIVWCC,	ADIVWV,		ADIVWVCC},
-	[ADIVWU]=	{ADIVWU,	ADIVWUCC,	ADIVWUV,	ADIVWUVCC},
-	[AEQV]=		{AEQV,		AEQVCC,		0,		0},
-	[AEXTSB]=	{AEXTSB,	AEXTSBCC,	0,		0},
-	[AEXTSH]=	{AEXTSH,	AEXTSHCC,	0,		0},
-	[AEXTSW]=	{AEXTSW,	AEXTSWCC,	0,		0},
-	[AFABS]=	{AFABS,		AFABSCC,	0,		0},
-	[AFADD]=	{AFADD,		AFADDCC,	0,		0},
-	[AFADDS]=	{AFADDS,	AFADDSCC,	0,		0},
-	[AFCFID]=	{AFCFID,	AFCFIDCC,	0,		0},
-	[AFCTID]=	{AFCTID,	AFCTIDCC,	0,		0},
-	[AFCTIDZ]=	{AFCTIDZ,	AFCTIDZCC,	0,		0},
-	[AFCTIW]=	{AFCTIW,	AFCTIWCC,	0,		0},
-	[AFCTIWZ]=	{AFCTIWZ,	AFCTIWZCC,	0,		0},
-	[AFDIV]=	{AFDIV,		AFDIVCC,	0,		0},
-	[AFDIVS]=	{AFDIVS,	AFDIVSCC,	0,		0},
-	[AFMADD]=	{AFMADD,	AFMADDCC,	0,		0},
-	[AFMADDS]=	{AFMADDS,	AFMADDSCC,	0,		0},
-	[AFMOVD]=	{AFMOVD,	AFMOVDCC,	0,		0},
-	[AFMSUB]=	{AFMSUB,	AFMSUBCC,	0,		0},
-	[AFMSUBS]=	{AFMSUBS,	AFMSUBSCC,	0,		0},
-	[AFMUL]=	{AFMUL,		AFMULCC,	0,		0},
-	[AFMULS]=	{AFMULS,	AFMULSCC,	0,		0},
-	[AFNABS]=	{AFNABS,	AFNABSCC,	0,		0},
-	[AFNEG]=	{AFNEG,		AFNEGCC,	0,		0},
-	[AFNMADD]=	{AFNMADD,	AFNMADDCC,	0,		0},
-	[AFNMADDS]=	{AFNMADDS,	AFNMADDSCC,	0,		0},
-	[AFNMSUB]=	{AFNMSUB,	AFNMSUBCC,	0,		0},
-	[AFNMSUBS]=	{AFNMSUBS,	AFNMSUBSCC,	0,		0},
-	[AFRES]=	{AFRES,		AFRESCC,	0,		0},
-	[AFRSP]=	{AFRSP,		AFRSPCC,	0,		0},
-	[AFRSQRTE]=	{AFRSQRTE,	AFRSQRTECC,	0,		0},
-	[AFSEL]=	{AFSEL,		AFSELCC,	0,		0},
-	[AFSQRT]=	{AFSQRT,	AFSQRTCC,	0,		0},
-	[AFSQRTS]=	{AFSQRTS,	AFSQRTSCC,	0,		0},
-	[AFSUB]=	{AFSUB,		AFSUBCC,	0,		0},
-	[AFSUBS]=	{AFSUBS,	AFSUBSCC,	0,		0},
-	[AMTFSB0]=	{AMTFSB0,	AMTFSB0CC,	0,		0},
-	[AMTFSB1]=	{AMTFSB1,	AMTFSB1CC,	0,		0},
-	[AMULHD]=	{AMULHD,	AMULHDCC,	0,		0},
-	[AMULHDU]=	{AMULHDU,	AMULHDUCC,	0,		0},
-	[AMULHW]=	{AMULHW,	AMULHWCC,	0,		0},
-	[AMULHWU]=	{AMULHWU,	AMULHWUCC,	0,		0},
-	[AMULLD]=	{AMULLD,	AMULLDCC,	AMULLDV,	AMULLDVCC},
-	[AMULLW]=	{AMULLW,	AMULLWCC,	AMULLWV,	AMULLWVCC},
-	[ANAND]=	{ANAND,		ANANDCC,	0,		0},
-	[ANEG]=		{ANEG,		ANEGCC,		ANEGV,		ANEGVCC},
-	[ANOR]=		{ANOR,		ANORCC,		0,		0},
-	[AOR]=		{AOR,		AORCC,		0,		0},
-	[AORN]=		{AORN,		AORNCC,		0,		0},
-	[AREM]=		{AREM,		AREMCC,		AREMV,		AREMVCC},
-	[AREMD]=	{AREMD,		AREMDCC,	AREMDV,		AREMDVCC},
-	[AREMDU]=	{AREMDU,	AREMDUCC,	AREMDUV,	AREMDUVCC},
-	[AREMU]=	{AREMU,		AREMUCC,	AREMUV,		AREMUVCC},
-	[ARLDC]=	{ARLDC,		ARLDCCC,	0,		0},
-	[ARLDCL]=	{ARLDCL,	ARLDCLCC,	0,		0},
-	[ARLDCR]=	{ARLDCR,	ARLDCRCC,	0,		0},
-	[ARLDMI]=	{ARLDMI,	ARLDMICC,	0,		0},
-	[ARLWMI]=	{ARLWMI,	ARLWMICC,	0,		0},
-	[ARLWNM]=	{ARLWNM,	ARLWNMCC,	0,		0},
-	[ASLD]=		{ASLD,		ASLDCC,		0,		0},
-	[ASLW]=		{ASLW,		ASLWCC,		0,		0},
-	[ASRAD]=	{ASRAD,		ASRADCC,	0,		0},
-	[ASRAW]=	{ASRAW,		ASRAWCC,	0,		0},
-	[ASRD]=		{ASRD,		ASRDCC,		0,		0},
-	[ASRW]=		{ASRW,		ASRWCC,		0,		0},
-	[ASUB]=		{ASUB,		ASUBCC,		ASUBV,		ASUBVCC},
-	[ASUBC]=	{ASUBC,		ASUBCCC,	ASUBCV,		ASUBCVCC},
-	[ASUBE]=	{ASUBE,		ASUBECC,	ASUBEV,		ASUBEVCC},
-	[ASUBME]=	{ASUBME,	ASUBMECC,	ASUBMEV,	ASUBMEVCC},
-	[ASUBZE]=	{ASUBZE,	ASUBZECC,	ASUBZEV,	ASUBZEVCC},
-	[AXOR]=		{AXOR,		AXORCC,		0,		0},
-};
-
-static void
-initvariants(void)
-{
-	static int initialized;
-	int i, j;
-
-	if(initialized)
-		return;
-	initialized = 1;
-
-	for(i=0; i<nelem(varianttable); i++) {
-		if(varianttable[i][0] == 0) {
-			// Instruction has no variants
-			varianttable[i][0] = i;
-			continue;
-		}
-		// Copy base form to other variants
-		if(varianttable[i][0] == i) {
-			for(j=0; j<nelem(varianttable[i]); j++)
-				memmove(&varianttable[varianttable[i][j]], &varianttable[i], sizeof(varianttable[i]));
-		}
-	}
-}
-
-// as2variant returns the variant (V_*) flags of instruction as.
-int
-as2variant(int as)
-{
-	int i;
-	initvariants();
-	for(i=0; i<nelem(varianttable[as]); i++)
-		if(varianttable[as][i] == as)
-			return i;
-	fatal("as2variant: instruction %A is not a variant of itself", as);
-	return 0;
-}
-
-// variant2as returns the instruction as with the given variant (V_*) flags.
-// If no such variant exists, this returns 0.
-int
-variant2as(int as, int flags)
-{
-	initvariants();
-	return varianttable[as][flags];
-}
diff --git a/src/cmd/new9g/prog.go b/src/cmd/9g/prog.go
similarity index 100%
rename from src/cmd/new9g/prog.go
rename to src/cmd/9g/prog.go
diff --git a/src/cmd/9g/reg.c b/src/cmd/9g/reg.c
deleted file mode 100644
index 84e1747..0000000
--- a/src/cmd/9g/reg.c
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-#include "../gc/popt.h"
-
-enum {
-	NREGVAR = 64,	/* 32 general + 32 floating */
-};
-
-
-static char* regname[] = {
-	".R0",
-	".R1",
-	".R2",
-	".R3",
-	".R4",
-	".R5",
-	".R6",
-	".R7",
-	".R8",
-	".R9",
-	".R10",
-	".R11",
-	".R12",
-	".R13",
-	".R14",
-	".R15",
-	".R16",
-	".R17",
-	".R18",
-	".R19",
-	".R20",
-	".R21",
-	".R22",
-	".R23",
-	".R24",
-	".R25",
-	".R26",
-	".R27",
-	".R28",
-	".R29",
-	".R30",
-	".R31",
-	".F0",
-	".F1",
-	".F2",
-	".F3",
-	".F4",
-	".F5",
-	".F6",
-	".F7",
-	".F8",
-	".F9",
-	".F10",
-	".F11",
-	".F12",
-	".F13",
-	".F14",
-	".F15",
-	".F16",
-	".F17",
-	".F18",
-	".F19",
-	".F20",
-	".F21",
-	".F22",
-	".F23",
-	".F24",
-	".F25",
-	".F26",
-	".F27",
-	".F28",
-	".F29",
-	".F30",
-	".F31",
-};
-
-char**
-regnames(int *n)
-{
-	*n = NREGVAR;
-	return regname;
-}
-
-uint64
-excludedregs(void)
-{
-	uint64 regbits;
-
-	// Exclude registers with fixed functions
-	regbits = (1<<0)|RtoB(REGSP)|RtoB(REGG)|RtoB(REGTLS);
-	// Also exclude floating point registers with fixed constants
-	regbits |= RtoB(REG_F27)|RtoB(REG_F28)|RtoB(REG_F29)|RtoB(REG_F30)|RtoB(REG_F31);
-	return regbits;
-}
-
-uint64
-doregbits(int r)
-{
-	USED(r);
-	return 0;
-}
-
-/*
- * track register variables including external registers:
- *	bit	reg
- *	0	R0
- *	1	R1
- *	...	...
- *	31	R31
- *	32+0	F0
- *	32+1	F1
- *	...	...
- *	32+31	F31
- */
-uint64
-RtoB(int r)
-{
-	if(r > REG_R0 && r <= REG_R31)
-		return 1ULL << (r - REG_R0);
-	if(r >= REG_F0 && r <= REG_F31)
-		return 1ULL << (32 + r - REG_F0);
-	return 0;
-}
-
-int
-BtoR(uint64 b)
-{
-	b &= 0xffffffffull;
-	if(b == 0)
-		return 0;
-	return bitno(b) + REG_R0;
-}
-
-int
-BtoF(uint64 b)
-{
-	b >>= 32;
-	if(b == 0)
-		return 0;
-	return bitno(b) + REG_F0;
-}
diff --git a/src/cmd/new9g/reg.go b/src/cmd/9g/reg.go
similarity index 100%
rename from src/cmd/new9g/reg.go
rename to src/cmd/9g/reg.go
diff --git a/src/cmd/new9g/util.go b/src/cmd/9g/util.go
similarity index 100%
rename from src/cmd/new9g/util.go
rename to src/cmd/9g/util.go
diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile
deleted file mode 100644
index 58e25fa..0000000
--- a/src/cmd/gc/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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
deleted file mode 100644
index 59ff0ab..0000000
--- a/src/cmd/gc/align.c
+++ /dev/null
@@ -1,689 +0,0 @@
-// 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 %lld", r);
-	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 >= thearch.MAXWIDTH) {
-			yyerror("interface too large");
-			o = widthptr;
-		}
-	}
-}
-
-static vlong
-widstruct(Type *errtype, Type *t, vlong o, int flag)
-{
-	Type *f;
-	int64 w;
-	int32 maxalign;
-	vlong starto, lastzero;
-	
-	starto = o;
-	maxalign = flag;
-	if(maxalign < 1)
-		maxalign = 1;
-	lastzero = 0;
-	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;
-		}
-		if(w == 0)
-			lastzero = o;
-		o += w;
-		if(o >= thearch.MAXWIDTH) {
-			yyerror("type %lT too large", errtype);
-			o = 8;  // small but nonzero
-		}
-	}
-	// For nonzero-sized structs which end in a zero-sized thing, we add
-	// an extra byte of padding to the type.  This padding ensures that
-	// taking the address of the zero-sized thing can't manufacture a
-	// pointer to the next object in the heap.  See issue 9401.
-	if(flag == 1 && o > starto && o == lastzero)
-		o++;
-
-	// final width is rounded
-	if(flag)
-		o = rnd(o, maxalign);
-	t->align = maxalign;
-
-	// type width only includes back to first field's offset
-	t->width = o - starto;
-	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 = (thearch.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 thearch.typedefs */
-	for(i=0; thearch.typedefs[i].name; i++) {
-		s = lookup(thearch.typedefs[i].name);
-		s1 = pkglookup(thearch.typedefs[i].name, builtinpkg);
-
-		etype = thearch.typedefs[i].etype;
-		if(etype < 0 || etype >= nelem(types))
-			fatal("typeinit: %s bad etype", s->name);
-		sameas = thearch.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
deleted file mode 100644
index d5d9646..0000000
--- a/src/cmd/gc/array.c
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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,
-};
-
-Array*
-arraynew(int 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);
-}
-
-int
-arraylength(Array *array)
-{
-	return array->length;
-}
-
-void*
-arrayget(Array *array, int 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, int 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, int 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
deleted file mode 100755
index fa74c67..0000000
--- a/src/cmd/gc/bisonerrors
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/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
deleted file mode 100644
index 21e25dd..0000000
--- a/src/cmd/gc/bits.c
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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;
-	uint64 b;
-
-	for(i=0; i<BITS; i++){
-		b = a.b[i];
-		if(b)
-			return 64*i + bitno(b);
-	}
-	fatal("bad in bnum");
-	return 0;
-}
-
-Bits
-blsh(uint n)
-{
-	Bits c;
-
-	c = zbits;
-	c.b[n/64] = 1LL << (n%64);
-	return c;
-}
-
-int
-btest(Bits *a, uint n)
-{
-	return (a->b[n/64] & (1LL << (n%64))) != 0;
-}
-
-void
-biset(Bits *a, uint n)
-{
-	a->b[n/64] |= 1LL << (n%64);
-}
-
-void
-biclr(Bits *a, uint n)
-{
-	a->b[n/64] &= ~(1LL << (n%64));
-}
-
-int
-bitno(uint64 b)
-{
-	int i;
-
-	for(i=0; i<64; i++)
-		if(b & (1LL<<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);
-		}
-		biclr(&bits, i);
-	}
-	return 0;
-}
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
deleted file mode 100644
index 1178f62..0000000
--- a/src/cmd/gc/builtin.c
+++ /dev/null
@@ -1,165 +0,0 @@
-// AUTO-GENERATED by mkbuiltin; DO NOT EDIT
-#include <u.h>
-#include <libc.h>
-#include "go.h"
-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 @\"\".printlock ()\n"
-	"func @\"\".printunlock ()\n"
-	"func @\"\".concatstring2 (? *[32]byte, ? string, ? string) (? string)\n"
-	"func @\"\".concatstring3 (? *[32]byte, ? string, ? string, ? string) (? string)\n"
-	"func @\"\".concatstring4 (? *[32]byte, ? string, ? string, ? string, ? string) (? string)\n"
-	"func @\"\".concatstring5 (? *[32]byte, ? string, ? string, ? string, ? string, ? string) (? string)\n"
-	"func @\"\".concatstrings (? *[32]byte, ? []string) (? string)\n"
-	"func @\"\".cmpstring (? string, ? string) (? int)\n"
-	"func @\"\".eqstring (? string, ? string) (? bool)\n"
-	"func @\"\".intstring (? *[4]byte, ? int64) (? string)\n"
-	"func @\"\".slicebytetostring (? *[32]byte, ? []byte) (? string)\n"
-	"func @\"\".slicebytetostringtmp (? []byte) (? string)\n"
-	"func @\"\".slicerunetostring (? *[32]byte, ? []rune) (? string)\n"
-	"func @\"\".stringtoslicebyte (? *[32]byte, ? string) (? []byte)\n"
-	"func @\"\".stringtoslicebytetmp (? string) (? []byte)\n"
-	"func @\"\".stringtoslicerune (? *[32]rune, ? 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·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertE2E2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n"
-	"func @\"\".assertE2I (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertE2I2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n"
-	"func @\"\".assertE2T (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertE2T2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n"
-	"func @\"\".assertI2E (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertI2E2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n"
-	"func @\"\".assertI2I (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertI2I2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n"
-	"func @\"\".assertI2T (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n"
-	"func @\"\".assertI2T2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? 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, @\"\".mapbuf·4 *any, @\"\".bucketbuf·5 *any) (@\"\".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 @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
-	"func @\"\".typedmemmove (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n"
-	"func @\"\".typedslicecopy (@\"\".typ·2 *byte, @\"\".dst·3 any, @\"\".src·4 any) (? int)\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 @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr)\n"
-	"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
-	"func @\"\".memequal8 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n"
-	"func @\"\".memequal16 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n"
-	"func @\"\".memequal32 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n"
-	"func @\"\".memequal64 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n"
-	"func @\"\".memequal128 (@\"\".x·2 *any, @\"\".y·3 *any) (? 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
deleted file mode 100644
index 2428006..0000000
--- a/src/cmd/gc/bv.c
+++ /dev/null
@@ -1,213 +0,0 @@
-// 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 = 4,
-	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
deleted file mode 100644
index 35b6d4b..0000000
--- a/src/cmd/gc/closure.c
+++ /dev/null
@@ -1,659 +0,0 @@
-// 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;
-	n->outerfunc = curfn;
-
-	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->outerexpr = oldname(v->sym);
-	}
-
-	return func;
-}
-
-static Node* makeclosure(Node *func);
-
-void
-typecheckclosure(Node *func, int top)
-{
-	Node *oldfn, *n;
-	NodeList *l;
-	int olddd;
-
-	for(l=func->cvars; l; l=l->next) {
-		n = l->n->closure;
-		if(!n->captured) {
-			n->captured = 1;
-			if(n->decldepth == 0)
-				fatal("typecheckclosure: var %hN does not have decldepth assigned", n);
-			// Ignore assignments to the variable in straightline code
-			// preceding the first capturing by a closure.
-			if(n->decldepth == decldepth)
-				n->assigned = 0;
-		}
-	}
-
-	for(l=func->dcl; l; l=l->next)
-		if(l->n->op == ONAME && (l->n->class == PPARAM || l->n->class == PPARAMOUT))
-			l->n->decldepth = 1;
-
-	oldfn = curfn;
-	typecheck(&func->ntype, Etype);
-	func->type = func->ntype->type;
-	func->top = top;
-
-	// 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;
-		olddd = decldepth;
-		decldepth = 1;
-		typechecklist(func->nbody, Etop);
-		decldepth = olddd;
-		curfn = oldfn;
-	}
-
-	// Create top-level function 
-	xtop = list(xtop, makeclosure(func));
-}
-
-// closurename returns name for OCLOSURE n.
-// It is not as simple as it ought to be, because we typecheck nested closures
-// starting from the innermost one. So when we check the inner closure,
-// we don't yet have name for the outer closure. This function uses recursion
-// to generate names all the way up if necessary.
-static Sym*
-closurename(Node *n)
-{
-	static int closgen;
-	char *outer, *prefix;
-	int gen;
-
-	if(n->sym != S)
-		return n->sym;
-	gen = 0;
-	outer = nil;
-	prefix = nil;
-	if(n->outerfunc == N) {
-		// Global closure.
-		outer = "glob";
-		prefix = "func";
-		gen = ++closgen;
-	} else if(n->outerfunc->op == ODCLFUNC) {
-		// The outermost closure inside of a named function.
-		outer = n->outerfunc->nname->sym->name;
-		prefix = "func";
-		// Yes, functions can be named _.
-		// Can't use function closgen in such case,
-		// because it would lead to name clashes.
-		if(!isblank(n->outerfunc->nname))
-			gen = ++n->outerfunc->closgen;
-		else
-			gen = ++closgen;
-	} else if(n->outerfunc->op == OCLOSURE) {
-		// Nested closure, recurse.
-		outer = closurename(n->outerfunc)->name;
-		prefix = "";
-		gen = ++n->outerfunc->closgen;
-	} else
-		fatal("closurename called for %hN", n);
-	snprint(namebuf, sizeof namebuf, "%s.%s%d", outer, prefix, gen);
-	n->sym = lookup(namebuf);
-	return n->sym;
-}
-
-static Node*
-makeclosure(Node *func)
-{
-	Node *xtype, *xfunc;
-
-	/*
-	 * 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);
-	xfunc->nname = newname(closurename(func));
-	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;
-
-	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;
-}
-
-// capturevars is called in a separate phase after all typechecking is done.
-// It decides whether each variable captured by a closure should be captured
-// by value or by reference.
-// We use value capturing for values <= 128 bytes that are never reassigned
-// after capturing (effectively constant).
-void
-capturevars(Node *xfunc)
-{
-	Node *func, *v, *outer;
-	NodeList *l;
-	int lno;
-
-	lno = lineno;
-	lineno = xfunc->lineno;
-
-	func = xfunc->closure;
-	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 = OXXX;
-			continue;
-		}
-
-		// type check the & of closed variables outside the closure,
-		// so that the outer frame also grabs them and knows they escape.
-		dowidth(v->type);
-		outer = v->outerexpr;
-		v->outerexpr = N;
-		// out parameters will be assigned to implicitly upon return.
-		if(outer->class != PPARAMOUT && !v->closure->addrtaken && !v->closure->assigned && v->type->width <= 128)
-			v->byval = 1;
-		else {
-			v->closure->addrtaken = 1;
-			outer = nod(OADDR, outer, N);
-		}
-		if(debug['m'] > 1) {
-			Sym *name;
-			char *how;
-			name = nil;
-			if(v->curfn && v->curfn->nname)
-				name = v->curfn->nname->sym;
-			how = "ref";
-			if(v->byval)
-				how = "value";
-			warnl(v->lineno, "%S capturing by %s: %S (addr=%d assign=%d width=%d)",
-				name, how,
-				v->sym, v->closure->addrtaken, v->closure->assigned, (int32)v->type->width);
-		}
-		typecheck(&outer, Erv);
-		func->enter = list(func->enter, outer);
-	}
-
-	lineno = lno;
-}
-
-// transformclosure is called in a separate phase after escape analysis.
-// It transform closure bodies to properly reference captured variables.
-void
-transformclosure(Node *xfunc)
-{
-	Node *func, *cv, *addr, *v, *f;
-	NodeList *l, *body;
-	Type **param, *fld;
-	vlong offset;
-	int lno, nvar;
-
-	lno = lineno;
-	lineno = xfunc->lineno;
-	func = xfunc->closure;
-
-	if(func->top&Ecall) {
-		// If the closure is directly called, we transform it to a plain function call
-		// with variables passed as args. This avoids allocation of a closure object.
-		// Here we do only a part of the transformation. Walk of OCALLFUNC(OCLOSURE)
-		// will complete the transformation later.
-		// For illustration, the following closure:
-		//	func(a int) {
-		//		println(byval)
-		//		byref++
-		//	}(42)
-		// becomes:
-		//	func(a int, byval int, &byref *int) {
-		//		println(byval)
-		//		(*&byref)++
-		//	}(42, byval, &byref)
-
-		// f is ONAME of the actual function.
-		f = xfunc->nname;
-		// Get pointer to input arguments and rewind to the end.
-		// We are going to append captured variables to input args.
-		param = &getinargx(f->type)->type;
-		for(; *param; param = &(*param)->down) {
-		}
-		for(l=func->cvars; l; l=l->next) {
-			v = l->n;
-			if(v->op == OXXX)
-				continue;
-			fld = typ(TFIELD);
-			fld->funarg = 1;
-			if(v->byval) {
-				// If v is captured by value, we merely downgrade it to PPARAM.
-				v->class = PPARAM;
-				v->ullman = 1;
-				fld->nname = v;
-			} else {
-				// If v of type T is captured by reference,
-				// we introduce function param &v *T
-				// and v remains PPARAMREF with &v heapaddr
-				// (accesses will implicitly deref &v).
-				snprint(namebuf, sizeof namebuf, "&%s", v->sym->name);
-				addr = newname(lookup(namebuf));
-				addr->type = ptrto(v->type);
-				addr->class = PPARAM;
-				v->heapaddr = addr;
-				fld->nname = addr;
-			}
-			fld->type = fld->nname->type;
-			fld->sym = fld->nname->sym;
-			// Declare the new param and append it to input arguments.
-			xfunc->dcl = list(xfunc->dcl, fld->nname);
-			*param = fld;
-			param = &fld->down;
-		}
-		// Recalculate param offsets.
-		if(f->type->width > 0)
-			fatal("transformclosure: width is already calculated");
-		dowidth(f->type);
-		xfunc->type = f->type; // update type of ODCLFUNC
-	} else {
-		// The closure is not called, so it is going to stay as closure.
-		nvar = 0;
-		body = nil;
-		offset = widthptr;
-		for(l=func->cvars; l; l=l->next) {
-			v = l->n;
-			if(v->op == OXXX)
-				continue;
-			nvar++;
-			// cv refers to the field inside of closure OSTRUCTLIT.
-			cv = nod(OCLOSUREVAR, N, N);
-			cv->type = v->type;
-			if(!v->byval)
-				cv->type = ptrto(v->type);
-			offset = rnd(offset, cv->type->align);
-			cv->xoffset = offset;
-			offset += cv->type->width;
-
-			if(v->byval && v->type->width <= 2*widthptr && thearch.thechar == '6') {
-				//  If it is a small variable captured by value, downgrade it to PAUTO.
-				// This optimization is currently enabled only for amd64, see:
-				// https://github.com/golang/go/issues/9865
-				v->class = PAUTO;
-				v->ullman = 1;
-				xfunc->dcl = list(xfunc->dcl, v);
-				body = list(body, nod(OAS, v, cv));
-			} else {
-				// Declare variable holding addresses taken from closure
-				// and initialize in entry prologue.
-				snprint(namebuf, sizeof namebuf, "&%s", v->sym->name);
-				addr = newname(lookup(namebuf));
-				addr->ntype = nod(OIND, typenod(v->type), N);
-				addr->class = PAUTO;
-				addr->used = 1;
-				addr->curfn = xfunc;
-				xfunc->dcl = list(xfunc->dcl, addr);
-				v->heapaddr = addr;
-				if(v->byval)
-					cv = nod(OADDR, cv, N);
-				body = list(body, nod(OAS, addr, cv));
-			}
-		}
-		typechecklist(body, Etop);
-		walkstmtlist(body);
-		xfunc->enter = body;
-		xfunc->needctxt = nvar > 0;
-	}
-
-	lineno = lno;
-}
-
-Node*
-walkclosure(Node *func, NodeList **init)
-{
-	Node *clos, *typ, *typ1, *v;
-	NodeList *l;
-
-	// 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; i *int; s *string}{func.1, &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.
-
-	typ = nod(OTSTRUCT, N, N);
-	typ->list = list1(nod(ODCLFIELD, newname(lookup(".F")), typenod(types[TUINTPTR])));
-	for(l=func->cvars; l; l=l->next) {
-		v = l->n;
-		if(v->op == OXXX)
-			continue;
-		typ1 = typenod(v->type);
-		if(!v->byval)
-			typ1 = nod(OIND, typ1, N);
-		typ->list = list(typ->list, nod(ODCLFIELD, newname(v->sym), typ1));
-	}
-
-	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;
-
-	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(newstrlit("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
deleted file mode 100644
index 50accb9..0000000
--- a/src/cmd/gc/const.c
+++ /dev/null
@@ -1,1678 +0,0 @@
-// 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:
-		goto illegal;
-	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;
-
-illegal:
-	if(!n->diag) {
-		yyerror("illegal constant expression: %T %O %T",
-			nl->type, n->op, nr->type);
-		n->diag = 1;
-	}
-	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;
-	}
-	lineno = lno;
-	return;
-
-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);
-	lineno = lno;
-	return;
-}
-
-/*
- * 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
deleted file mode 100644
index 26c21df..0000000
--- a/src/cmd/gc/cplx.c
+++ /dev/null
@@ -1,494 +0,0 @@
-// 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"
-
-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))
-
-/*c2go
-static int
-CASE(int a, int b)
-{
-	return a<<16 | b;
-}
-*/
-
-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);
-
-		thearch.cgen(&n1, &n3);
-		thearch.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);
-			thearch.cgen(n->left, &tmp);
-			thearch.cgen(n->right, &n2);
-			thearch.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) {
-			thearch.cgen(&n1, res);
-			return;
-		}
-		thearch.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) {
-		thearch.igen(res, &n1, N);
-		thearch.cgen(n, &n1);
-		thearch.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:
-		thearch.igen(n, &n1, res);
-		complexmove(&n1, res);
-		thearch.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);
-			thearch.cgen(nl, &tnl);
-			nl = &tnl;
-		}
-		if(!nr->addable) {
-			tempname(&tnr, nr->type);
-			thearch.cgen(nr, &tnr);
-			nr = &tnr;
-		}
-	}
-	if(!nl->addable) {
-		tempname(&tnl, nl->type);
-		thearch.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);
-			thearch.cgen(nl, &tnl);
-			nl = &tnl;
-		}
-		if(!nr->addable) {
-			tempname(&tnr, nr->type);
-			thearch.cgen(nr, &tnr);
-			nr = &tnr;
-		}
-	}
-	if(!nl->addable) {
-		tempname(&tnl, nl->type);
-		thearch.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(nb));
-	nb.op = OEQ;
-	nb.left = &n1;
-	nb.right = &n3;
-	nb.type = types[TBOOL];
-
-	memset(&nc, 0, sizeof(nc));
-	nc.op = OEQ;
-	nc.left = &n2;
-	nc.right = &n4;
-	nc.type = types[TBOOL];
-
-	if(op == ONE)
-		true = !true;
-
-	thearch.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;
-	thearch.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;
-	thearch.cgen(&ra, &n5);
-
-	memset(&ra, 0, sizeof(ra));
-	ra.op = op;
-	ra.left = &n2;
-	ra.right = &n4;
-	ra.type = n2.type;
-	thearch.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(rm1));
-	rm1.op = OMUL;
-	rm1.left = &n1;
-	rm1.right = &n3;
-	rm1.type = n1.type;
-
-	memset(&rm2, 0, sizeof(rm2));
-	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;
-	thearch.cgen(&ra, &tmp);
-
-	// imag part
-	memset(&rm1, 0, sizeof(rm1));
-	rm1.op = OMUL;
-	rm1.left = &n1;
-	rm1.right = &n4;
-	rm1.type = n1.type;
-
-	memset(&rm2, 0, sizeof(rm2));
-	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;
-	thearch.cgen(&ra, &n6);
-
-	// tmp ->real part
-	thearch.cgen(&tmp, &n5);
-}
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
deleted file mode 100644
index 9a6c002..0000000
--- a/src/cmd/gc/dcl.c
+++ /dev/null
@@ -1,1479 +0,0 @@
-// 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;
-			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(newstrlit("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: %lT", 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)
-{
-	stksize = BADWIDTH;
-	maxarg = 0;
-
-	if(n->type == T) {
-		if(nerrors == 0)
-			fatal("funccompile missing type");
-		return;
-	}
-
-	// assign parameter offsets
-	checkwidth(n->type);
-	
-	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
deleted file mode 100644
index 03df93a..0000000
--- a/src/cmd/gc/doc.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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
deleted file mode 100644
index 5b09c0b..0000000
--- a/src/cmd/gc/esc.c
+++ /dev/null
@@ -1,1342 +0,0 @@
-// 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 = newstrlit(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, *v;
-
-	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:
-		// Filter out the following special case.
-		//
-		//	func (b *Buffer) Foo() {
-		//		n, m := ...
-		//		b.buf = b.buf[n:m]
-		//	}
-		//
-		// This assignment is a no-op for escape analysis,
-		// it does not store any new pointers into b that were not already there.
-		// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
-		if((n->left->op == OIND || n->left->op == ODOTPTR) && n->left->left->op == ONAME && // dst is ONAME dereference
-			(n->right->op == OSLICE || n->right->op == OSLICE3 || n->right->op == OSLICESTR) && // src is slice operation
-			(n->right->left->op == OIND || n->right->left->op == ODOTPTR) && n->right->left->left->op == ONAME && // slice is applied to ONAME dereference
-			n->left->left == n->right->left->left) { // dst and src reference the same base ONAME
-			// Here we also assume that the statement will not contain calls,
-			// that is, that order will move any calls to init.
-			// Otherwise base ONAME value could change between the moments
-			// when we evaluate it for dst and for src.
-			//
-			// Note, this optimization does not apply to OSLICEARR,
-			// because it does introduce a new pointer into b that was not already there
-			// (pointer to b itself). After such assignment, if b contents escape,
-			// b escapes as well. If we ignore such OSLICEARR, we will conclude
-			// that b does not escape when b contents do.
-			if(debug['m']) {
-				warnl(n->lineno, "%S ignoring self-assignment to %hN",
-					(n->curfn && n->curfn->nname) ? n->curfn->nname->sym : S, n->left);
-			}
-			break;
-		}
-		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;
-		// Link OSTRUCTLIT to OPTRLIT; if OPTRLIT escapes, OSTRUCTLIT elements do too.
-		escassign(e, n, 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) {
-			v = ll->n;
-			if(v->op == OXXX)  // unnamed out argument; see dcl.c:/^funcargs
-				continue;
-			a = v->closure;
-			if(!v->byval) {
-				a = nod(OADDR, a, N);
-				a->lineno = v->lineno;
-				a->escloopdepth = e->loopdepth;
-				typecheck(&a, Erv);
-			}
-			escassign(e, n, a);
-		}
-		// fallthrough
-	case OMAKECHAN:
-	case OMAKEMAP:
-	case OMAKESLICE:
-	case ONEW:
-	case OARRAYRUNESTR:
-	case OARRAYBYTESTR:
-	case OSTRARRAYRUNE:
-	case OSTRARRAYBYTE:
-	case ORUNESTR:
-		n->escloopdepth = e->loopdepth;
-		n->esc = EscNone;  // until proven otherwise
-		e->noesc = list(e->noesc, n);
-		break;
-
-	case OADDSTR:
-		n->escloopdepth = e->loopdepth;
-		n->esc = EscNone;  // until proven otherwise
-		e->noesc = list(e->noesc, n);
-		// Arguments of OADDSTR do not escape.
-		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 OPTRLIT:
-	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 OARRAYRUNESTR:
-	case OARRAYBYTESTR:
-	case OSTRARRAYRUNE:
-	case OSTRARRAYBYTE:
-	case OADDSTR:
-	case ONEW:
-	case OCLOSURE:
-	case OCALLPART:
-	case ORUNESTR:
-		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:
-	case OSLICESTR:
-		// 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 OARRAYRUNESTR:
-	case OARRAYBYTESTR:
-	case OSTRARRAYRUNE:
-	case OSTRARRAYBYTE:
-	case OADDSTR:
-	case OMAPLIT:
-	case ONEW:
-	case OCLOSURE:
-	case OCALLPART:
-	case ORUNESTR:
-		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:
-	case OSLICESTR:
-		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
deleted file mode 100644
index 91f4957..0000000
--- a/src/cmd/gc/export.c
+++ /dev/null
@@ -1,563 +0,0 @@
-// 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 NodeList *asmlist;
-
-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);
-	if(asmhdr && n->sym->pkg == localpkg && !(n->sym->flags & SymAsm)) {
-		n->sym->flags |= SymAsm;
-		asmlist = list(asmlist, 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
-methodbyname(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], methodbyname);
-
-	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);
-}
-
-void
-dumpasmhdr(void)
-{
-	Biobuf *b;
-	NodeList *l;
-	Node *n;
-	Type *t;
-
-	b = Bopen(asmhdr, OWRITE);
-	if(b == nil)
-		fatal("open %s: %r", asmhdr);
-	Bprint(b, "// generated by %cg -asmhdr from package %s\n\n", thearch.thechar, localpkg->name);
-	for(l=asmlist; l; l=l->next) {
-		n = l->n;
-		if(isblanksym(n->sym))
-			continue;
-		switch(n->op) {
-		case OLITERAL:
-			Bprint(b, "#define const_%s %#V\n", n->sym->name, &n->val);
-			break;
-		case OTYPE:
-			t = n->type;
-			if(t->etype != TSTRUCT || t->map != T || t->funarg)
-				break;
-			Bprint(b, "#define %s__size %d\n", t->sym->name, (int)t->width);
-			for(t=t->type; t != T; t=t->down)
-				if(!isblanksym(t->sym))
-					Bprint(b, "#define %s_%s %d\n", n->sym->name, t->sym->name, (int)t->width);
-			break;
-		}
-	}
-	
-	Bterm(b);
-}
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
deleted file mode 100644
index bd0a29f..0000000
--- a/src/cmd/gc/fmt.c
+++ /dev/null
@@ -1,1697 +0,0 @@
-// 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
-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(n->addrtaken != 0)
-		fmtprint(fp, " addrtaken");
-
-	if(n->assigned != 0)
-		fmtprint(fp, " assigned");
-
-	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)
-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
deleted file mode 100644
index 72bcc49..0000000
--- a/src/cmd/gc/gen.c
+++ /dev/null
@@ -1,987 +0,0 @@
-// 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 = thearch.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:
-		thearch.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:
-		thearch.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 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:
-		thearch.cgen_callinter(n, N, 0);
-		break;
-
-	case OCALLFUNC:
-		thearch.cgen_call(n, 0);
-		break;
-
-	case OPROC:
-		cgen_proc(n, 1);
-		break;
-
-	case ODEFER:
-		cgen_proc(n, 2);
-		break;
-
-	case ORETURN:
-	case ORETJMP:
-		thearch.cgen_ret(n);
-		break;
-	
-	case OCHECKNIL:
-		cgen_checknil(n->left);
-		break;
-	
-	case OVARKILL:
-		gvarkill(n->left);
-		break;
-	}
-
-ret:
-	if(thearch.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;
-	thearch.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:
-		thearch.cgen_callinter(n->left, N, proc);
-		break;
-
-	case OCALLFUNC:
-		thearch.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);
-	thearch.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);
-			thearch.clearfat(nl);
-			return;
-		}
-		clearslim(nl);
-		return;
-	}
-
-	tl = nl->type;
-	if(tl == T)
-		return;
-
-	thearch.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]);
-	thearch.cgen(n->right, tmp);
-
-	gvardef(res);
-
-	dst = *res;
-	dst.type = types[tptr];
-	dst.xoffset += widthptr;
-	thearch.cgen(tmp, &dst);
-
-	dst.xoffset -= widthptr;
-	thearch.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);
-		thearch.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);
-		thearch.cgen(&src, base);
-		cgen_checknil(base);
-	} else {
-		src.type = types[tptr];
-		thearch.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.
-	thearch.cgen(len, tmplen);
-	if(n->op != OSLICESTR)
-		thearch.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);
-		thearch.bgen(cmp, 1, -1, p2);
-
-		add = nod(OADD, base, offs);
-		typecheck(&add, Erv);
-		thearch.cgen(add, base);
-
-		patch(p2, pc);
-	}
-
-	// dst.array = src.array  [ + lo *width ]
-	dst = *res;
-	dst.xoffset += Array_array;
-	dst.type = types[tptr];
-	thearch.cgen(base, &dst);
-
-	// dst.len = hi [ - lo ]
-	dst = *res;
-	dst.xoffset += Array_nel;
-	dst.type = types[simtype[TUINT]];
-	thearch.cgen(tmplen, &dst);
-
-	if(n->op != OSLICESTR) {
-		// dst.cap = cap [ - lo ]
-		dst = *res;
-		dst.xoffset += Array_cap;
-		dst.type = types[simtype[TUINT]];
-		thearch.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
deleted file mode 100644
index f90d619..0000000
--- a/src/cmd/gc/go.errors
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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
deleted file mode 100644
index 92584f6..0000000
--- a/src/cmd/gc/go.h
+++ /dev/null
@@ -1,1757 +0,0 @@
-// 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,
-};
-
-/*
- * 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;
-};
-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	Array
-{
-	int32	length;  // number of elements
-	int32	size;  // element size
-	int32	capacity;  // size of data in elements
-	char	*data;  // element storage
-};
-
-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	nowritebarrier;	// emit compiler error instead of write barrier
-	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	assigned;	// is the variable ever assigned to
-	uchar	captured;	// is the variable captured by a closure
-	uchar	byval;		// is the variable captured by value or by reference
-	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
-	int	closgen;
-	Node*	outerfunc;
-
-	// 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
-	int	decldepth;	// declaration loop depth, increased for every loop or label
-
-	// ONAME func param with PHEAP
-	Node*	heapaddr;	// temp holding heap address of param
-	Node*	outerexpr;	// expression copied into closure for variable
-	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
-	int	top;	// top context (Ecall, Eproc, etc)
-
-	// 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,
-	SymAsm		= 1<<5,
-	SymAlgGen	= 1<<6,
-};
-
-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
-	char*	linkname;	// link name
-
-	// 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)
-	OSTRARRAYBYTETMP,	// []byte(s) ephemeral
-	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
-
-	// thearch-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
-};
-
-enum {
-	BITS = 3,
-	NVAR = 	(BITS*64)
-};
-
-typedef	struct	Bits	Bits;
-struct	Bits
-{
-	uint64	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;
-	int	id;
-	char	name;
-	char	etype;
-	char	addr;
-};
-
-EXTERN	Var	var[NVAR];
-
-typedef	struct	Typedef	Typedef;
-struct	Typedef
-{
-	char*	name;
-	int	etype;
-	int	sameas;
-};
-
-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	Fmt	pragcgobuf;
-
-EXTERN	char*	infile;
-EXTERN	char*	outfile;
-EXTERN	Biobuf*	bout;
-EXTERN	int	nerrors;
-EXTERN	int	nsavederrors;
-EXTERN	int	nsyntaxerrors;
-EXTERN	int	decldepth;
-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*	rawpkg;	// fake package for raw symbol names
-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	char*	asmhdr;
-
-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*	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  	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	nowritebarrier;
-EXTERN	int	debuglive;
-EXTERN	Link*	ctxt;
-
-EXTERN	int	nointerface;
-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(uint64 b);
-Bits	blsh(uint n);
-Bits	bnot(Bits a);
-int	bnum(Bits a);
-Bits	bor(Bits a, Bits b);
-int	btest(Bits *a, uint n);
-void	biset(Bits *a, uint n);
-void	biclr(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);
-void	capturevars(Node *func);
-void	transformclosure(Node *func);
-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);
-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);
-void	dumpasmhdr(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);
-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*	hmap(Type *t);
-Type*	hiter(Type* t);
-Type*	mapbucket(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, int32 extra);
-Type*	shallow(Type *t);
-int	simsimtype(Type *t);
-void	smagic(Magic *m);
-Type*	sortinter(Type *t);
-uint32	stringhash(char *p);
-Strlit*	newstrlit(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, ...);
-void	adderrorname(Node*);
-
-/*
- *	swt.c
- */
-void	typecheckswitch(Node *n);
-void	walkswitch(Node *sw);
-
-/*
- *	typecheck.c
- */
-int	islvalue(Node *n);
-int	samesafeexpr(Node *l, Node *r);
-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	checkassign(Node *stmt, 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	walkexprlistcheap(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*);
-
-/*
- *	thearch-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;
-
-void	checknil(Node*, NodeList**);
-void	cgen_checknil(Node*);
-void	compile(Node*);
-int	duintxx(Sym *s, int off, uint64 v, int wid);
-void	gvardef(Node*);
-void	gvarkill(Node*);
-void	movelarge(NodeList*);
-void	liveness(Node*, Prog*, Sym*, Sym*);
-void	twobitwalktype1(Type*, vlong*, Bvec*);
-
-#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);
-
-/*
- *	flow.c
- */
-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	id;		// sequence number in flow graph
-	int32	rpo;		// reverse post ordering
-	uint16	loop;		// x5 for every loop
-	uchar	refset;		// diagnostic generated
-	
-	void*	data;	// for use by client
-};
-
-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*);
-Flow*	uniqp(Flow*);
-Flow*	uniqs(Flow*);
-
-/*
- *	interface to back end
- */
-
-typedef struct ProgInfo ProgInfo;
-struct ProgInfo
-{
-	uint32 flags; // the bits below
-	uint64 reguse; // registers implicitly used by this instruction
-	uint64 regset; // registers implicitly set by this instruction
-	uint64 regindex; // registers used by addressing mode
-};
-
-enum
-{
-	// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
-	Pseudo = 1<<1,
-	
-	// There's nothing to say about the instruction,
-	// but it's still okay to see.
-	OK = 1<<2,
-
-	// Size of right-side write, or right-side read if no write.
-	SizeB = 1<<3,
-	SizeW = 1<<4,
-	SizeL = 1<<5,
-	SizeQ = 1<<6,
-	SizeF = 1<<7, // float aka float32
-	SizeD = 1<<8, // double aka float64
-
-	// Left side (Prog.from): address taken, read, write.
-	LeftAddr = 1<<9,
-	LeftRead = 1<<10,
-	LeftWrite = 1<<11,
-	
-	// Register in middle (Prog.reg); only ever read. (arm, ppc64)
-	RegRead = 1<<12,
-	CanRegRead = 1<<13,
-	
-	// Right side (Prog.to): address taken, read, write.
-	RightAddr = 1<<14,
-	RightRead = 1<<15,
-	RightWrite = 1<<16,
-
-	// Instruction kinds
-	Move = 1<<17, // straight move
-	Conv = 1<<18, // size conversion
-	Cjmp = 1<<19, // conditional jump
-	Break = 1<<20, // breaks control flow (no fallthrough)
-	Call = 1<<21, // function call
-	Jump = 1<<22, // jump
-	Skip = 1<<23, // data instruction
-
-	// Set, use, or kill of carry bit.
-	// Kill means we never look at the carry bit after this kind of instruction.
-	SetCarry = 1<<24,
-	UseCarry = 1<<25,
-	KillCarry = 1<<26,
-
-	// Special cases for register use. (amd64, 386)
-	ShiftCX = 1<<27, // possible shift by CX
-	ImulAXDX = 1<<28, // possible multiply into DX:AX
-
-	// Instruction updates whichever of from/to is type D_OREG. (ppc64)
-	PostInc = 1<<29,
-};
-
-typedef struct Arch Arch;
-
-struct Arch
-{
-	int thechar;
-	char *thestring;
-	LinkArch *thelinkarch;
-	Typedef *typedefs;
-
-	int	REGSP;
-	int	REGCTXT;
-	vlong MAXWIDTH;
-
-	int (*anyregalloc)(void);
-	void (*betypeinit)(void);
-	void (*bgen)(Node*, int, int, Prog*);
-	void (*cgen)(Node*, Node*);
-	void (*cgen_call)(Node*, int);
-	void (*cgen_callinter)(Node*, Node*, int);
-	void (*cgen_ret)(Node*);
-	void (*clearfat)(Node*);
-	void (*defframe)(Prog*);
-	void (*excise)(Flow*);
-	void (*expandchecks)(Prog*);
-	void (*gclean)(void);
-	void (*ginit)(void);
-	Prog*	(*gins)(int, Node*, Node*);
-	void	(*ginscall)(Node*, int);
-	void	(*igen)(Node*, Node*, Node*);
-	void (*linkarchinit)(void);
-	void (*peep)(Prog*);
-	void (*proginfo)(ProgInfo*, Prog*);
-	void (*regalloc)(Node*, Type*, Node*);
-	void (*regfree)(Node*);
-	int (*regtyp)(Addr*);
-	int (*sameaddr)(Addr*, Addr*);
-	int (*smallindir)(Addr*, Addr*);
-	int (*stackaddr)(Addr*);
-	uint64 (*excludedregs)(void);
-	uint64 (*RtoB)(int);
-	uint64 (*FtoB)(int);
-	int (*BtoR)(uint64);
-	int (*BtoF)(uint64);
-	int (*optoas)(int, Type*);
-	uint64 (*doregbits)(int);
-	char **(*regnames)(int*);
-};
-
-void afunclit(Addr*, Node*);
-void clearp(Prog*);
-int dgostringptr(Sym*, int, char*);
-int dgostrlitptr(Sym*, int, Strlit*);
-int dsname(Sym*, int, char*, int);
-int dsymptr(Sym*, int, Sym*, int);
-void dumpdata(void);
-void fixautoused(Prog*);
-void	gdata(Node*, Node*, int);
-void	gdatacomplex(Node*, Mpcplx*);
-void	gdatastring(Node*, Strlit*);
-void	ggloblnod(Node*);
-void	ggloblsym(Sym*, int32, int8);
-Prog*	gjmp(Prog*);
-void gtrack(Sym*);
-void	gused(Node*);
-int isfat(Type*);
-void markautoused(Prog*);
-void naddr(Node*, Addr*, int);
-Plist* newplist(void);
-Node* nodarg(Type*, int);
-void patch(Prog*, Prog*);
-Prog* unpatch(Prog*);
-void datagostring(Strlit *sval, Addr *a);
-int ismem(Node*);
-int samereg(Node*, Node*);
-void	regopt(Prog*);
-int	Tconv(Fmt*);
-int	Oconv(Fmt*);
-Prog*	gbranch(int as, Type *t, int likely);
-void	nodindreg(Node *n, Type *t, int r);
-void	nodreg(Node *n, Type *t, int r);
-Prog*	prog(int as);
-void	datastring(char*, int, Addr*);
-
-EXTERN int32	pcloc;
-
-EXTERN Arch thearch;
-
-EXTERN Node *newproc;
-EXTERN Node *deferproc;
-EXTERN Node *deferreturn;
-EXTERN Node *panicindex;
-EXTERN Node *panicslice;
-EXTERN Node *throwreturn;
-
-int	gcmain(int, char**);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
deleted file mode 100644
index dc8b530..0000000
--- a/src/cmd/gc/go.y
+++ /dev/null
@@ -1,2225 +0,0 @@
-// 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;
-		$$->nowritebarrier = nowritebarrier;
-		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;
-		nowritebarrier = 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/gsubr.c b/src/cmd/gc/gsubr.c
deleted file mode 100644
index 5175ae3..0000000
--- a/src/cmd/gc/gsubr.c
+++ /dev/null
@@ -1,654 +0,0 @@
-// Derived from Inferno utils/6c/txt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.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"
-#include "../../runtime/funcdata.h"
-#include "../ld/textflag.h"
-
-void
-ggloblnod(Node *nam)
-{
-	Prog *p;
-
-	p = thearch.gins(AGLOBL, nam, N);
-	p->lineno = nam->lineno;
-	p->from.sym->gotype = linksym(ngotype(nam));
-	p->to.sym = nil;
-	p->to.type = TYPE_CONST;
-	p->to.offset = nam->type->width;
-	if(nam->readonly)
-		p->from3.offset = RODATA;
-	if(nam->type != T && !haspointers(nam->type))
-		p->from3.offset |= NOPTR;
-}
-
-void
-gtrack(Sym *s)
-{
-	Prog *p;
-	
-	p = thearch.gins(AUSEFIELD, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.sym = linksym(s);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int8 flags)
-{
-	Prog *p;
-
-	p = thearch.gins(AGLOBL, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.sym = linksym(s);
-	p->to.type = TYPE_CONST;
-	p->to.offset = width;
-	p->from3.offset = flags;
-}
-
-void
-clearp(Prog *p)
-{
-	nopout(p);
-	p->as = AEND;
-	p->pc = pcloc;
-	pcloc++;
-}
-
-static int ddumped;
-static Prog *dfirst;
-static Prog *dpc;
-
-/*
- * generate and return proc with p->as = as,
- * linked into program. pc is next instruction.
- */
-Prog*
-prog(int as)
-{
-	Prog *p;
-
-	if(as == ADATA || as == AGLOBL) {
-		if(ddumped)
-			fatal("already dumped data");
-		if(dpc == nil) {
-			dpc = mal(sizeof(*dpc));
-			dfirst = dpc;
-		}
-		p = dpc;
-		dpc = mal(sizeof(*dpc));
-		p->link = dpc;
-	} else {
-		p = pc;
-		pc = mal(sizeof(*pc));
-		clearp(pc);
-		p->link = pc;
-	}
-
-	if(lineno == 0) {
-		if(debug['K'])
-			warn("prog: line 0");
-	}
-
-	p->as = as;
-	p->lineno = lineno;
-	return p;
-}
-
-void
-dumpdata(void)
-{
-	ddumped = 1;
-	if(dfirst == nil)
-		return;
-	newplist();
-	*pc = *dfirst;
-	pc = dpc;
-	clearp(pc);
-}
-
-/*
- * generate a branch.
- * t is ignored.
- * likely values are for branch prediction:
- *	-1 unlikely
- *	0 no opinion
- *	+1 likely
- */
-Prog*
-gbranch(int as, Type *t, int likely)
-{
-	Prog *p;
-	
-	USED(t);
-
-	p = prog(as);
-	p->to.type = TYPE_BRANCH;
-	p->to.u.branch = P;
-	if(as != AJMP && likely != 0 && thearch.thechar != '9') {
-		p->from.type = TYPE_CONST;
-		p->from.offset = likely > 0;
-	}
-	return p;
-}
-
-/*
- * patch previous branch to jump to to.
- */
-void
-patch(Prog *p, Prog *to)
-{
-	if(p->to.type != TYPE_BRANCH)
-		fatal("patch: not a branch");
-	p->to.u.branch = to;
-	p->to.offset = to->pc;
-}
-
-Prog*
-unpatch(Prog *p)
-{
-	Prog *q;
-
-	if(p->to.type != TYPE_BRANCH)
-		fatal("unpatch: not a branch");
-	q = p->to.u.branch;
-	p->to.u.branch = P;
-	p->to.offset = 0;
-	return q;
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-newplist(void)
-{
-	Plist *pl;
-
-	pl = linknewplist(ctxt);
-
-	pc = mal(sizeof(*pc));
-	clearp(pc);
-	pl->firstpc = pc;
-
-	return pl;
-}
-
-void
-gused(Node *n)
-{
-	thearch.gins(ANOP, n, N);	// used
-}
-
-Prog*
-gjmp(Prog *to)
-{
-	Prog *p;
-
-	p = gbranch(AJMP, T, 0);
-	if(to != P)
-		patch(p, to);
-	return p;
-}
-
-int
-isfat(Type *t)
-{
-	if(t != T)
-	switch(t->etype) {
-	case TSTRUCT:
-	case TARRAY:
-	case TSTRING:
-	case TINTER:	// maybe remove later
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * naddr of func generates code for address of func.
- * if using opcode that can take address implicitly,
- * call afunclit to fix up the argument.
- */
-void
-afunclit(Addr *a, Node *n)
-{
-	if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
-		a->type = TYPE_MEM;
-		a->sym = linksym(n->sym);
-	}
-}
-
-/*
- * initialize n to be register r of type t.
- */
-void
-nodreg(Node *n, Type *t, int r)
-{
-	if(t == T)
-		fatal("nodreg: t nil");
-
-	memset(n, 0, sizeof(*n));
-	n->op = OREGISTER;
-	n->addable = 1;
-	ullmancalc(n);
-	n->val.u.reg = r;
-	n->type = t;
-}
-
-/*
- * initialize n to be indirect of register r; n is type t.
- */
-void
-nodindreg(Node *n, Type *t, int r)
-{
-	nodreg(n, t, r);
-	n->op = OINDREG;
-}
-
-/*
- * Is this node a memory operand?
- */
-int
-ismem(Node *n)
-{
-	switch(n->op) {
-	case OITAB:
-	case OSPTR:
-	case OLEN:
-	case OCAP:
-	case OINDREG:
-	case ONAME:
-	case OPARAM:
-	case OCLOSUREVAR:
-		return 1;
-	case OADDR:
-		return thearch.thechar == '6' || thearch.thechar == '9'; // because 6g uses PC-relative addressing; TODO(rsc): not sure why 9g too
-	}
-	return 0;
-}
-
-// Sweep the prog list to mark any used nodes.
-void
-markautoused(Prog* p)
-{
-	for (; p; p = p->link) {
-		if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-
-		if (p->from.node)
-			((Node*)(p->from.node))->used = 1;
-
-		if (p->to.node)
-			((Node*)(p->to.node))->used = 1;
-	}
-}
-
-// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
-void
-fixautoused(Prog *p)
-{
-	Prog **lp;
-
-	for (lp=&p; (p=*lp) != P; ) {
-		if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
-			*lp = p->link;
-			continue;
-		}
-		if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
-			// Cannot remove VARDEF instruction, because - unlike TYPE handled above -
-			// VARDEFs are interspersed with other code, and a jump might be using the
-			// VARDEF as a target. Replace with a no-op instead. A later pass will remove
-			// the no-ops.
-			nopout(p);
-			continue;
-		}
-		if (p->from.name == NAME_AUTO && p->from.node)
-			p->from.offset += ((Node*)(p->from.node))->stkdelta;
-
-		if (p->to.name == NAME_AUTO && p->to.node)
-			p->to.offset += ((Node*)(p->to.node))->stkdelta;
-
-		lp = &p->link;
-	}
-}
-
-int
-samereg(Node *a, Node *b)
-{
-	if(a == N || b == N)
-		return 0;
-	if(a->op != OREGISTER)
-		return 0;
-	if(b->op != OREGISTER)
-		return 0;
-	if(a->val.u.reg != b->val.u.reg)
-		return 0;
-	return 1;
-}
-
-Node*
-nodarg(Type *t, int fp)
-{
-	Node *n;
-	NodeList *l;
-	Type *first;
-	Iter savet;
-
-	// entire argument struct, not just one arg
-	if(t->etype == TSTRUCT && t->funarg) {
-		n = nod(ONAME, N, N);
-		n->sym = lookup(".args");
-		n->type = t;
-		first = structfirst(&savet, &t);
-		if(first == nil)
-			fatal("nodarg: bad struct");
-		if(first->width == BADWIDTH)
-			fatal("nodarg: offset not computed for %T", t);
-		n->xoffset = first->width;
-		n->addable = 1;
-		goto fp;
-	}
-
-	if(t->etype != TFIELD)
-		fatal("nodarg: not field %T", t);
-	
-	if(fp == 1) {
-		for(l=curfn->dcl; l; l=l->next) {
-			n = l->n;
-			if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
-				return n;
-		}
-	}
-
-	n = nod(ONAME, N, N);
-	n->type = t->type;
-	n->sym = t->sym;
-	
-	if(t->width == BADWIDTH)
-		fatal("nodarg: offset not computed for %T", t);
-	n->xoffset = t->width;
-	n->addable = 1;
-	n->orig = t->nname;
-
-fp:
-	// Rewrite argument named _ to __,
-	// or else the assignment to _ will be
-	// discarded during code generation.
-	if(isblank(n))
-		n->sym = lookup("__");
-
-	switch(fp) {
-	case 0:		// output arg
-		n->op = OINDREG;
-		n->val.u.reg = thearch.REGSP;
-		if(thearch.thechar == '5')
-			n->xoffset += 4;
-		if(thearch.thechar == '9')
-			n->xoffset += 8;
-		break;
-
-	case 1:		// input arg
-		n->class = PPARAM;
-		break;
-
-	case 2:		// offset output arg
-fatal("shouldn't be used");
-		n->op = OINDREG;
-		n->val.u.reg = thearch.REGSP;
-		n->xoffset += types[tptr]->width;
-		break;
-	}
-	n->typecheck = 1;
-	return n;
-}
-
-/*
- * generate code to compute n;
- * make a refer to result.
- */
-void
-naddr(Node *n, Addr *a, int canemitcode)
-{
-	Sym *s;
-
-	*a = zprog.from;
-	if(n == N)
-		return;
-
-	if(n->type != T && n->type->etype != TIDEAL) {
-		// TODO(rsc): This is undone by the selective clearing of width below,
-		// to match architectures that were not as aggressive in setting width
-		// during naddr. Those widths must be cleared to avoid triggering
-		// failures in gins when it detects real but heretofore latent (and one
-		// hopes innocuous) type mismatches.
-		// The type mismatches should be fixed and the clearing below removed.
-		dowidth(n->type);
-		a->width = n->type->width;
-	}
-
-	switch(n->op) {
-	default:
-		fatal("naddr: bad %O %D", n->op, a);
-		break;
-
-	case OREGISTER:
-		a->type = TYPE_REG;
-		a->reg = n->val.u.reg;
-		a->sym = nil;
-		if(thearch.thechar == '8') // TODO(rsc): Never clear a->width.
-			a->width = 0;
-		break;
-
-	case OINDREG:
-		a->type = TYPE_MEM;
-		a->reg = n->val.u.reg;
-		a->sym = linksym(n->sym);
-		a->offset = n->xoffset;
-		if(a->offset != (int32)a->offset)
-			yyerror("offset %lld too large for OINDREG", a->offset);
-		if(thearch.thechar == '8') // TODO(rsc): Never clear a->width.
-			a->width = 0;
-		break;
-
-	case OPARAM:
-		// n->left is PHEAP ONAME for stack parameter.
-		// compute address of actual parameter on stack.
-		a->etype = simtype[n->left->type->etype];
-		a->width = n->left->type->width;
-		a->offset = n->xoffset;
-		a->sym = linksym(n->left->sym);
-		a->type = TYPE_MEM;
-		a->name = NAME_PARAM;
-		a->node = n->left->orig;
-		break;
-	
-	case OCLOSUREVAR:
-		if(!curfn->needctxt)
-			fatal("closurevar without needctxt");
-		a->type = TYPE_MEM;
-		a->reg = thearch.REGCTXT;
-		a->sym = nil;
-		a->offset = n->xoffset;
-		break;
-	
-	case OCFUNC:
-		naddr(n->left, a, canemitcode);
-		a->sym = linksym(n->left->sym);
-		break;
-
-	case ONAME:
-		a->etype = 0;
-		if(n->type != T)
-			a->etype = simtype[n->type->etype];
-		a->offset = n->xoffset;
-		s = n->sym;
-		a->node = n->orig;
-		//if(a->node >= (Node*)&n)
-		//	fatal("stack node");
-		if(s == S)
-			s = lookup(".noname");
-		if(n->method) {
-			if(n->type != T)
-			if(n->type->sym != S)
-			if(n->type->sym->pkg != nil)
-				s = pkglookup(s->name, n->type->sym->pkg);
-		}
-
-		a->type = TYPE_MEM;
-		switch(n->class) {
-		default:
-			fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
-		case PEXTERN:
-			a->name = NAME_EXTERN;
-			break;
-		case PAUTO:
-			a->name = NAME_AUTO;
-			break;
-		case PPARAM:
-		case PPARAMOUT:
-			a->name = NAME_PARAM;
-			break;
-		case PFUNC:
-			a->name = NAME_EXTERN;
-			a->type = TYPE_ADDR;
-			a->width = widthptr;
-			s = funcsym(s);			
-			break;
-		}
-		a->sym = linksym(s);
-		break;
-
-	case OLITERAL:
-		if(thearch.thechar == '8')
-			a->width = 0;
-		switch(n->val.ctype) {
-		default:
-			fatal("naddr: const %lT", n->type);
-			break;
-		case CTFLT:
-			a->type = TYPE_FCONST;
-			a->u.dval = mpgetflt(n->val.u.fval);
-			break;
-		case CTINT:
-		case CTRUNE:
-			a->sym = nil;
-			a->type = TYPE_CONST;
-			a->offset = mpgetfix(n->val.u.xval);
-			break;
-		case CTSTR:
-			datagostring(n->val.u.sval, a);
-			break;
-		case CTBOOL:
-			a->sym = nil;
-			a->type = TYPE_CONST;
-			a->offset = n->val.u.bval;
-			break;
-		case CTNIL:
-			a->sym = nil;
-			a->type = TYPE_CONST;
-			a->offset = 0;
-			break;
-		}
-		break;
-
-	case OADDR:
-		naddr(n->left, a, canemitcode);
-		a->etype = tptr;
-		if(thearch.thechar != '5' && thearch.thechar != '9') // TODO(rsc): Do this even for arm, ppc64.
-			a->width = widthptr;
-		if(a->type != TYPE_MEM)
-			fatal("naddr: OADDR %D (from %O)", a, n->left->op);
-		a->type = TYPE_ADDR;
-		break;
-	
-	case OITAB:
-		// itable of interface value
-		naddr(n->left, a, canemitcode);
-		if(a->type == TYPE_CONST && a->offset == 0)
-			break;  // itab(nil)
-		a->etype = tptr;
-		a->width = widthptr;
-		break;
-
-	case OSPTR:
-		// pointer in a string or slice
-		naddr(n->left, a, canemitcode);
-		if(a->type == TYPE_CONST && a->offset == 0)
-			break;	// ptr(nil)
-		a->etype = simtype[tptr];
-		a->offset += Array_array;
-		a->width = widthptr;
-		break;
-
-	case OLEN:
-		// len of string or slice
-		naddr(n->left, a, canemitcode);
-		if(a->type == TYPE_CONST && a->offset == 0)
-			break;	// len(nil)
-		a->etype = simtype[TUINT];
-		if(thearch.thechar == '9')
-			a->etype = simtype[TINT];
-		a->offset += Array_nel;
-		if(thearch.thechar != '5') // TODO(rsc): Do this even on arm.
-			a->width = widthint;
-		break;
-
-	case OCAP:
-		// cap of string or slice
-		naddr(n->left, a, canemitcode);
-		if(a->type == TYPE_CONST && a->offset == 0)
-			break;	// cap(nil)
-		a->etype = simtype[TUINT];
-		if(thearch.thechar == '9')
-			a->etype = simtype[TINT];
-		a->offset += Array_cap;
-		if(thearch.thechar != '5') // TODO(rsc): Do this even on arm.
-			a->width = widthint;
-		break;
-
-//	case OADD:
-//		if(n->right->op == OLITERAL) {
-//			v = n->right->vconst;
-//			naddr(n->left, a, canemitcode);
-//		} else
-//		if(n->left->op == OLITERAL) {
-//			v = n->left->vconst;
-//			naddr(n->right, a, canemitcode);
-//		} else
-//			goto bad;
-//		a->offset += v;
-//		break;
-
-	}
-}
diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c
deleted file mode 100644
index f1484ea..0000000
--- a/src/cmd/gc/init.c
+++ /dev/null
@@ -1,194 +0,0 @@
-// 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
-	s = lookup("init.1");
-	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);
-}
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
deleted file mode 100644
index 45e15bb..0000000
--- a/src/cmd/gc/inl.c
+++ /dev/null
@@ -1,986 +0,0 @@
-// 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
deleted file mode 100644
index a4b832a..0000000
--- a/src/cmd/gc/lex.c
+++ /dev/null
@@ -1,2590 +0,0 @@
-// 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>
-
-#ifndef PLAN9
-#include	<signal.h>
-#endif
-
-#undef	getc
-#undef	ungetc
-#define	getc	ccgetc
-#define	ungetc	ccungetc
-
-extern int yychar;
-int yyprev;
-int yylast;
-
-static int	imported_unsafe;
-
-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
-
-// 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},
-};
-
-// 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", thearch.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, *sep;
-
-	p = expstring();
-	if(strcmp(p, "X:none") == 0)
-		p = "";
-	sep = "";
-	if(*p)
-		sep = " ";
-	print("%cg version %s%s%s\n", thearch.thechar, getgoversion(), sep, p);
-	exits(0);
-}
-
-int
-gcmain(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=thearch.thestring or GOARCH=thearch.thestringsuffix,
-	// but not other values.	
-	p = getgoarch();
-	if(strncmp(p, thearch.thestring, strlen(thearch.thestring)) != 0)
-		sysfatal("cannot use %cg with GOARCH=%s", thearch.thechar, p);
-	goarch = p;
-
-	thearch.linkarchinit();
-	ctxt = linknew(thearch.thelinkarch);
-	ctxt->diag = yyerror;
-	ctxt->bso = &bstdout;
-	Binit(&bstdout, 1, OWRITE);
-
-	localpkg = mkpkg(newstrlit(""));
-	localpkg->prefix = "\"\"";
-	
-	// pseudo-package, for scoping
-	builtinpkg = mkpkg(newstrlit("go.builtin"));
-	builtinpkg->prefix = "go.builtin"; // not go%2ebuiltin
-
-	// pseudo-package, accessed by import "unsafe"
-	unsafepkg = mkpkg(newstrlit("unsafe"));
-	unsafepkg->name = "unsafe";
-
-	// real package, referred to by generated runtime calls
-	runtimepkg = mkpkg(newstrlit("runtime"));
-	runtimepkg->name = "runtime";
-
-	// pseudo-packages used in symbol tables
-	gostringpkg = mkpkg(newstrlit("go.string"));
-	gostringpkg->name = "go.string";
-	gostringpkg->prefix = "go.string";	// not go%2estring
-
-	itabpkg = mkpkg(newstrlit("go.itab"));
-	itabpkg->name = "go.itab";
-	itabpkg->prefix = "go.itab";	// not go%2eitab
-
-	weaktypepkg = mkpkg(newstrlit("go.weak.type"));
-	weaktypepkg->name = "go.weak.type";
-	weaktypepkg->prefix = "go.weak.type";  // not go%2eweak%2etype
-	
-	typelinkpkg = mkpkg(newstrlit("go.typelink"));
-	typelinkpkg->name = "go.typelink";
-	typelinkpkg->prefix = "go.typelink"; // not go%2etypelink
-
-	trackpkg = mkpkg(newstrlit("go.track"));
-	trackpkg->name = "go.track";
-	trackpkg->prefix = "go.track";  // not go%2etrack
-
-	typepkg = mkpkg(newstrlit("type"));
-	typepkg->name = "type";
-
-	goroot = getgoroot();
-	goos = getgoos();
-
-	nacl = strcmp(goos, "nacl") == 0;
-	if(nacl)
-		flag_largemodel = 1;
-
-	fmtstrinit(&pragcgobuf);
-	quotefmtinstall();
-
-	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']);
-	flagstr("asmhdr", "file: write assembly header to named file", &asmhdr);
-	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(thearch.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(newstrlit("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; j<nelem(debugtab); j++) {
-				if(strcmp(debugtab[j].name, f[i]) == 0) {
-					if(debugtab[j].val != nil)
-						*debugtab[j].val = 1;
-					break;
-				}
-			}
-			if(j >= nelem(debugtab))
-				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(thearch.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();
-	thearch.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;
-		
-		imported_unsafe = 0;
-
-		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;
-			decldepth = 1;
-			saveerrors();
-			typechecklist(l->n->nbody, Etop);
-			checkreturn(l->n);
-			if(nerrors != 0)
-				l->n->nbody = nil;  // type errors; do not compile
-		}
-	}
-
-	// Phase 4: Decide how to capture closed variables.
-	// This needs to run before escape analysis,
-	// because variables captured by value do not escape.
-	for(l=xtop; l; l=l->next) {
-		if(l->n->op == ODCLFUNC && l->n->closure) {
-			curfn = l->n;
-			capturevars(l->n);
-		}
-	}
-
-	curfn = nil;
-	
-	if(nsavederrors+nerrors)
-		errorexit();
-
-	// Phase 5: 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 6: 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 7: Transform closure bodies to properly reference captured variables.
-	// This needs to happen before walk, because closures must be transformed
-	// before walk reaches a call of a closure.
-	for(l=xtop; l; l=l->next) {
-		if(l->n->op == ODCLFUNC && l->n->closure) {
-			curfn = l->n;
-			transformclosure(l->n);
-		}
-	}
-	curfn = N;
-
-	// Phase 8: Compile top level functions.
-	for(l=xtop; l; l=l->next)
-		if(l->n->op == ODCLFUNC)
-			funccompile(l->n);
-
-	if(nsavederrors+nerrors == 0)
-		fninit(xtop);
-
-	// Phase 9: 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(asmhdr)
-		dumpasmhdr();
-
-	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, thearch.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, thearch.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, thearch.thechar);
-		if(access(namebuf, 0) >= 0)
-			return 1;
-	}
-	return 0;
-}
-
-static void
-fakeimport(void)
-{
-	importpkg = mkpkg(newstrlit("fake"));
-	cannedimports("fake.6", "$$\n");
-}
-
-void
-importfile(Val *f, int line)
-{
-	Biobuf *imp;
-	char *file, *p, *q, *tag;
-	int32 c;
-	int n;
-	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);
-		imported_unsafe = 1;
-		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 = newstrlit(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);
-
-	n = strlen(namebuf);
-	if(n > 2 && namebuf[n-2] == '.' && namebuf[n-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 + n - 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);
-		}
-		goto strlit;
-
-	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;
-
-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;
-}
-
-static void pragcgo(char*);
-
-static int
-more(char **pp)
-{
-	char *p;
-	
-	p = *pp;
-	while(yy_isspace(*p))
-		p++;
-	*pp = p;
-	return *p != '\0';
-}
-
-/*
- * 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;
-	
-	if(strncmp(lexbuf, "go:cgo_", 7) == 0)
-		pragcgo(lexbuf);
-	
-	ep = strchr(lexbuf, ' ');
-	if(ep != nil)
-		*ep = 0;
-	
-	if(strcmp(lexbuf, "go:linkname") == 0) {
-		if(!imported_unsafe)
-			yyerror("//go:linkname only allowed in Go files that import \"unsafe\"");
-		if(ep == nil) {
-			yyerror("usage: //go:linkname localname linkname");
-			goto out;
-		}
-		cp = ep+1;
-		while(yy_isspace(*cp))
-			cp++;
-		ep = strchr(cp, ' ');
-		if(ep == nil) {
-			yyerror("usage: //go:linkname localname linkname");
-			goto out;
-		}
-		*ep++ = 0;
-		while(yy_isspace(*ep))
-			ep++;
-		if(*ep == 0) {
-			yyerror("usage: //go:linkname localname linkname");
-			goto out;
-		}
-		lookup(cp)->linkname = strdup(ep);
-		goto out;
-	}	
-
-	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;
-	}
-	if(strcmp(lexbuf, "go:nowritebarrier") == 0) {
-		if(!compiling_runtime)
-			yyerror("//go:nowritebarrier only allowed in runtime");
-		nowritebarrier = 1;
-		goto out;
-	}
-	
-out:
-	return c;
-}
-
-static char*
-getimpsym(char **pp)
-{
-	char *p, *start;
-	
-	more(pp); // skip spaces
-
-	p = *pp;
-	if(*p == '\0' || *p == '"')
-		return nil;
-	
-	start = p;
-	while(*p != '\0' && !yy_isspace(*p) && *p != '"')
-		p++;
-	if(*p != '\0')
-		*p++ = '\0';
-	
-	*pp = p;
-	return start;
-}
-
-static char*
-getquoted(char **pp)
-{
-	char *p, *start;
-	
-	more(pp); // skip spaces
-	
-	p = *pp;
-	if(*p != '"')
-		return nil;
-	p++;
-	
-	start = p;
-	while(*p != '"') {
-		if(*p == '\0')
-			return nil;
-		p++;
-	}
-	*p++ = '\0';
-	*pp = p;
-	return start;
-}
-
-// Copied nearly verbatim from the C compiler's #pragma parser.
-// TODO: Rewrite more cleanly once the compiler is written in Go.
-static void
-pragcgo(char *text)
-{
-	char *local, *remote, *p, *q, *verb;
-	
-	for(q=text; *q != '\0' && *q != ' '; q++)
-		;
-	if(*q == ' ')
-		*q++ = '\0';
-	
-	verb = text+3; // skip "go:"
-
-	if(strcmp(verb, "cgo_dynamic_linker") == 0 || strcmp(verb, "dynlinker") == 0) {
-		p = getquoted(&q);
-		if(p == nil)
-			goto err1;
-		fmtprint(&pragcgobuf, "cgo_dynamic_linker %q\n", p);
-		goto out;
-	
-	err1:
-		yyerror("usage: //go:cgo_dynamic_linker \"path\"");
-		goto out;
-	}	
-
-	if(strcmp(verb, "dynexport") == 0)
-		verb = "cgo_export_dynamic";
-	if(strcmp(verb, "cgo_export_static") == 0 || strcmp(verb, "cgo_export_dynamic") == 0) {
-		local = getimpsym(&q);
-		if(local == nil)
-			goto err2;
-		if(!more(&q)) {
-			fmtprint(&pragcgobuf, "%s %q\n", verb, local);
-			goto out;
-		}
-		remote = getimpsym(&q);
-		if(remote == nil)
-			goto err2;
-		fmtprint(&pragcgobuf, "%s %q %q\n", verb, local, remote);
-		goto out;
-	
-	err2:
-		yyerror("usage: //go:%s local [remote]", verb);
-		goto out;
-	}
-	
-	if(strcmp(verb, "cgo_import_dynamic") == 0 || strcmp(verb, "dynimport") == 0) {
-		local = getimpsym(&q);
-		if(local == nil)
-			goto err3;
-		if(!more(&q)) {
-			fmtprint(&pragcgobuf, "cgo_import_dynamic %q\n", local);
-			goto out;
-		}
-		remote = getimpsym(&q);
-		if(remote == nil)
-			goto err3;
-		if(!more(&q)) {
-			fmtprint(&pragcgobuf, "cgo_import_dynamic %q %q\n", local, remote);
-			goto out;
-		}
-		p = getquoted(&q);
-		if(p == nil)	
-			goto err3;
-		fmtprint(&pragcgobuf, "cgo_import_dynamic %q %q %q\n", local, remote, p);
-		goto out;
-	
-	err3:
-		yyerror("usage: //go:cgo_import_dynamic local [remote [\"library\"]]");
-		goto out;
-	}
-	
-	if(strcmp(verb, "cgo_import_static") == 0) {
-		local = getimpsym(&q);
-		if(local == nil || more(&q))
-			goto err4;
-		fmtprint(&pragcgobuf, "cgo_import_static %q\n", local);
-		goto out;
-		
-	err4:
-		yyerror("usage: //go:cgo_import_static local");
-		goto out;
-	}
-	
-	if(strcmp(verb, "cgo_ldflag") == 0) {
-		p = getquoted(&q);
-		if(p == nil)
-			goto err5;
-		fmtprint(&pragcgobuf, "cgo_ldflag %q\n", p);
-		goto out;
-
-	err5:
-		yyerror("usage: //go:cgo_ldflag \"arg\"");
-		goto out;
-	}
-
-out:;
-}
-
-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; thearch.typedefs[i].name; i++) {
-		s = lookup(thearch.typedefs[i].name);
-		if(s->def == N) {
-			s->def = typenod(types[thearch.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, thearch.thechar);
-	}
-}
diff --git a/src/cmd/gc/md5.c b/src/cmd/gc/md5.c
deleted file mode 100644
index 46cb6b7..0000000
--- a/src/cmd/gc/md5.c
+++ /dev/null
@@ -1,302 +0,0 @@
-// 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
deleted file mode 100644
index 5a60106..0000000
--- a/src/cmd/gc/md5.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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
deleted file mode 100755
index 696aa82..0000000
--- a/src/cmd/gc/mkbuiltin
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/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
-echo "#include <u.h>" >>_builtin.c
-echo "#include <libc.h>" >>_builtin.c
-echo '#include "go.h"' >>_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
deleted file mode 100644
index 69027fd..0000000
--- a/src/cmd/gc/mkbuiltin1.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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
deleted file mode 100755
index d3f27e8..0000000
--- a/src/cmd/gc/mkopnames
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/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
deleted file mode 100644
index 6a0eb2d..0000000
--- a/src/cmd/gc/mparith1.c
+++ /dev/null
@@ -1,655 +0,0 @@
-// 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 c;
-	long d;
-	int bit, hexdigitp, end;
-
-	while(*s == '0') {
-		s++;
-		n--;
-	}
-
-	// overflow
-	if(4*n > Mpscale*Mpprec) {
-		a->ovf = 1;
-		return;
-	}
-
-	end = n-1;
-	for(hexdigitp=end; hexdigitp>=0; hexdigitp--) {
-		c = s[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) {
-			yyerror("malformed hex constant: %s", as);
-			goto bad;
-		}
-
-		mphextofix(&a->val, start, s-start);
-		if(a->val.ovf) {
-			yyerror("constant too large: %s", as);
-			goto bad;
-		}
-		a->exp = 0;
-		mpnorm(a);
-	}
-	for(;;) {
-		c = *s++;
-		switch(c) {
-		default:
-			yyerror("malformed constant: %s (at %c)", as, c);
-			goto bad;
-
-		case '-':
-			f = 1;
-
-		case ' ':
-		case '\t':
-		case '+':
-			continue;
-
-		case '.':
-			if(base == 16) {
-				yyerror("decimal point in hex constant: %s", as);
-				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) {
-			yyerror("decimal point and binary point in constant: %s", as);
-			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:
-	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;
-		}
-		yyerror("malformed decimal constant: %s", as);
-		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;
-		}
-		yyerror("malformed octal constant: %s", as);
-		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;
-		}
-		yyerror("malformed hex constant: %s", as);
-		goto bad;
-	}
-	mphextofix(a, s0, s-s0);
-	if(a->ovf) {
-		yyerror("constant too large: %s", as);
-		goto bad;
-	}
-
-out:
-	if(f)
-		mpnegfix(a);
-	return;
-
-bad:
-	mpmovecfix(a, 0);
-}
-
-int
-Bconv(Fmt *fp)
-{
-	char buf[500];
-	int 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 = sizeof(buf);
-	buf[--p] = 0;
-	if(fp->flags & FmtSharp) {
-		// Hexadecimal
-		mpmovecfix(&sixteen, 16);
-		for(;;) {
-			mpdivmodfixfix(&q, &r, &q, &sixteen);
-			digit = mpgetfix(&r);
-			if(digit < 10)
-				buf[--p] = digit + '0';
-			else
-				buf[--p] = digit - 10 + 'A';
-			if(mptestfix(&q) <= 0)
-				break;
-		}
-		buf[--p] = 'x';
-		buf[--p] = '0';
-	} else {
-		// Decimal
-		mpmovecfix(&ten, 10);
-		for(;;) {
-			mpdivmodfixfix(&q, &r, &q, &ten);
-			buf[--p] = mpgetfix(&r) + '0';
-			if(mptestfix(&q) <= 0)
-				break;
-		}
-	}
-	if(f)
-		buf[--p] = '-';
-	return fmtstrcpy(fp, &buf[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
deleted file mode 100644
index 37aafbb..0000000
--- a/src/cmd/gc/mparith2.c
+++ /dev/null
@@ -1,689 +0,0 @@
-// 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;
-
-	n = -1;
-	for(i=0; i<Mpprec; i++) {
-		if(a->a[i] != 0)
-			n = i;
-	}
-	return n+1;
-}
-
-//
-// left shift mpint by one
-// ignores sign
-//
-static void
-mplsh(Mpint *a, int quiet)
-{
-	long x;
-	int i, c;
-
-	c = 0;
-	for(i=0; i<Mpprec; i++) {
-		x = (a->a[i] << 1) + c;
-		c = 0;
-		if(x >= Mpbase) {
-			x -= Mpbase;
-			c = 1;
-		}
-		a->a[i] = 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)
-{
-	int i;
-
-	i = Mpprec-1;
-	if(a->a[i]) {
-		a->ovf = 1;
-		if(!quiet)
-			yyerror("constant shift overflow");
-	}
-	for(; i > 0; i--)
-		a->a[i] = a->a[i-1];
-	a->a[i] = 0;
-}
-
-//
-// right shift mpint by one
-// ignores sign and overflow
-//
-static void
-mprsh(Mpint *a)
-{
-	long x, lo;
-	int i, c;
-
-	c = 0;
-	lo = a->a[0] & 1;
-	for(i=Mpprec-1; i>=0; i--) {
-		x = a->a[i];
-		a->a[i] = (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 lo;
-	int i;
-
-	lo = a->a[0];
-	for(i=0; i<Mpprec-1; i++) {
-		a->a[i] = a->a[i+1];
-	}
-	a->a[i] = 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;
-	int i;
-
-	if(a->ovf || b->ovf) {
-		if(nsavederrors+nerrors == 0)
-			yyerror("ovf in cmp");
-		return 0;
-	}
-
-	for(i=Mpprec-1; i>=0; i--) {
-		x = a->a[i] - b->a[i];
-		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;
-	int i, c;
-
-	c = 0;
-	for(i=0; i<Mpprec; i++) {
-		x = -a->a[i] -c;
-		c = 0;
-		if(x < 0) {
-			x += Mpbase;
-			c = 1;
-		}
-		a->a[i] = 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;
-
-	if(a->ovf || b->ovf) {
-		if(nsavederrors+nerrors == 0)
-			yyerror("ovf in mpaddxx");
-		a->ovf = 1;
-		return;
-	}
-
-	c = 0;
-	if(a->neg != b->neg)
-		goto sub;
-
-	// perform a+b
-	for(i=0; i<Mpprec; i++) {
-		x = a->a[i] + b->a[i] + c;
-		c = 0;
-		if(x >= Mpbase) {
-			x -= Mpbase;
-			c = 1;
-		}
-		a->a[i] = 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 = a->a[i] - b->a[i] - c;
-			c = 0;
-			if(x < 0) {
-				x += Mpbase;
-				c = 1;
-			}
-			a->a[i] = x;
-		}
-		break;
-
-	case -1:
-		a->neg ^= 1;
-		for(i=0; i<Mpprec; i++) {
-			x = b->a[i] - a->a[i] - c;
-			c = 0;
-			if(x < 0) {
-				x += Mpbase;
-				c = 1;
-			}
-			a->a[i] = x;
-		}
-		break;
-	}
-}
-
-void
-mpmulfixfix(Mpint *a, Mpint *b)
-{
-
-	int i, j, na, nb;
-	long x;
-	Mpint s, q;
-	Mpint *c;
-
-	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);
-		c = b;
-		na = nb;
-	} else {
-		mpmovefixfix(&s, b);
-		c = a;
-	}
-	s.neg = 0;
-
-	mpmovecfix(&q, 0);
-	for(i=0; i<na; i++) {
-		x = c->a[i];
-		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 x;
-	Mpint s, q;
-
-	if(a->ovf || b->ovf) {
-		if(nsavederrors+nerrors == 0)
-			yyerror("ovf in mpmulflt");
-		a->ovf = 1;
-		return;
-	}
-
-	mpmovefixfix(&s, b);
-	s.neg = 0;
-	mpmovecfix(&q, 0);
-
-	i = Mpprec-1;
-	x = a->a[i];
-	if(x != 0)
-		yyerror("mpmulfract not normal");
-
-	for(i--; i >= 0; i--) {
-		x = a->a[i];
-		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;
-
-	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);
-
-	for(i=0; i<Mpprec; i++) {
-		x = a->a[i] | b->a[i];
-		a->a[i] = x;
-	}
-
-	if(b->neg)
-		mpneg(b);
-	if(x & Mpsign) {
-		a->neg = 1;
-		mpneg(a);
-	}
-}
-
-void
-mpandfixfix(Mpint *a, Mpint *b)
-{
-	int i;
-	long x;
-
-	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);
-
-	for(i=0; i<Mpprec; i++) {
-		x = a->a[i] & b->a[i];
-		a->a[i] = x;
-	}
-
-	if(b->neg)
-		mpneg(b);
-	if(x & Mpsign) {
-		a->neg = 1;
-		mpneg(a);
-	}
-}
-
-void
-mpandnotfixfix(Mpint *a, Mpint *b)
-{
-	int i;
-	long x;
-
-	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);
-
-	for(i=0; i<Mpprec; i++) {
-		x = a->a[i] & ~b->a[i];
-		a->a[i] = x;
-	}
-
-	if(b->neg)
-		mpneg(b);
-	if(x & Mpsign) {
-		a->neg = 1;
-		mpneg(a);
-	}
-}
-
-void
-mpxorfixfix(Mpint *a, Mpint *b)
-{
-	int i;
-	long x;
-
-	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);
-
-	for(i=0; i<Mpprec; i++) {
-		x = a->a[i] ^ b->a[i];
-		a->a[i] = 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;
-	vlong x;
-
-	a->neg = 0;
-	a->ovf = 0;
-
-	x = c;
-	if(x < 0) {
-		a->neg = 1;
-		x = -(uvlong)x;
-	}
-
-	for(i=0; i<Mpprec; i++) {
-		a->a[i] = 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)
-{
-	int i;
-
-	for(i=Mpprec-1; i>=0; i--)
-		if(a->a[i] != 0)
-			return 0;
-	return 1;
-}
-
-void
-mpdivfract(Mpint *a, Mpint *b)
-{
-	Mpint n, d;
-	int i, j, neg;
-	long x;
-
-	mpmovefixfix(&n, a);	// numerator
-	mpmovefixfix(&d, b);	// denominator
-
-	neg = n.neg ^ d.neg;
-	n.neg = 0;
-	d.neg = 0;
-	for(i=Mpprec-1; i >= 0; 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);
-		}
-		a->a[i] = 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
deleted file mode 100644
index 6afd75c..0000000
--- a/src/cmd/gc/mparith3.c
+++ /dev/null
@@ -1,346 +0,0 @@
-// 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
deleted file mode 100644
index 3983f99..0000000
--- a/src/cmd/gc/obj.c
+++ /dev/null
@@ -1,498 +0,0 @@
-// 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());
-	}
-	
-	if(pragcgobuf.to > pragcgobuf.start) {
-		if(writearchive) {
-			// write empty export section; must be before cgo section
-			Bprint(bout, "\n$$\n\n$$\n\n");
-		}
-		Bprint(bout, "\n$$  // cgo\n");
-		Bprint(bout, "%s\n$$\n\n", fmtstrflush(&pragcgobuf));
-	}
-
-
-	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", thearch.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 if(s->linkname != nil)
-		s->lsym = linklookup(ctxt, s->linkname, 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);
-}
-
-int
-dsname(Sym *s, int off, char *t, int n)
-{
-	Prog *p;
-
-	p = thearch.gins(ADATA, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.offset = off;
-	p->from.sym = linksym(s);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = n;
-	
-	p->to.type = TYPE_SCONST;
-	memmove(p->to.u.sval, t, n);
-	return off + n;
-}
-
-/*
- * make a refer to the data s, s+len
- * emitting DATA if needed.
- */
-void
-datastring(char *s, int len, Addr *a)
-{
-	Sym *sym;
-	
-	sym = stringsym(s, len);
-	a->type = TYPE_MEM;
-	a->name = NAME_EXTERN;
-	a->sym = linksym(sym);
-	a->node = sym->def;
-	a->offset = widthptr+widthint;  // skip header
-	a->etype = simtype[TINT];
-}
-
-/*
- * make a refer to the string sval,
- * emitting DATA if needed.
- */
-void
-datagostring(Strlit *sval, Addr *a)
-{
-	Sym *sym;
-
-	sym = stringsym(sval->s, sval->len);
-	a->type = TYPE_MEM;
-	a->name = NAME_EXTERN;
-	a->sym = linksym(sym);
-	a->node = sym->def;
-	a->offset = 0;  // header
-	a->etype = TSTRING;
-}
-
-void
-gdata(Node *nam, Node *nr, int wid)
-{
-	Prog *p;
-
-	if(nr->op == OLITERAL) {
-		switch(nr->val.ctype) {
-		case CTCPLX:
-			gdatacomplex(nam, nr->val.u.cval);
-			return;
-		case CTSTR:
-			gdatastring(nam, nr->val.u.sval);
-			return;
-		}
-	}
-	p = thearch.gins(ADATA, nam, nr);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = wid;
-}
-
-void
-gdatacomplex(Node *nam, Mpcplx *cval)
-{
-	Prog *p;
-	int w;
-
-	w = cplxsubtype(nam->type->etype);
-	w = types[w]->width;
-
-	p = thearch.gins(ADATA, nam, N);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = w;
-	p->to.type = TYPE_FCONST;
-	p->to.u.dval = mpgetflt(&cval->real);
-
-	p = thearch.gins(ADATA, nam, N);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = w;
-	p->from.offset += w;
-	p->to.type = TYPE_FCONST;
-	p->to.u.dval = mpgetflt(&cval->imag);
-}
-
-void
-gdatastring(Node *nam, Strlit *sval)
-{
-	Prog *p;
-	Node nod1;
-
-	p = thearch.gins(ADATA, nam, N);
-	datastring(sval->s, sval->len, &p->to);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = types[tptr]->width;
-	p->to.type = TYPE_ADDR;
-//print("%P\n", p);
-
-	nodconst(&nod1, types[TINT], sval->len);
-	p = thearch.gins(ADATA, nam, &nod1);
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = widthint;
-	p->from.offset += widthptr;
-}
-
-int
-dstringptr(Sym *s, int off, char *str)
-{
-	Prog *p;
-
-	off = rnd(off, widthptr);
-	p = thearch.gins(ADATA, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.sym = linksym(s);
-	p->from.offset = off;
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = widthptr;
-
-	datastring(str, strlen(str)+1, &p->to);
-	p->to.type = TYPE_ADDR;
-	p->to.etype = simtype[TINT];
-	off += widthptr;
-
-	return off;
-}
-
-int
-dgostrlitptr(Sym *s, int off, Strlit *lit)
-{
-	Prog *p;
-
-	if(lit == nil)
-		return duintptr(s, off, 0);
-
-	off = rnd(off, widthptr);
-	p = thearch.gins(ADATA, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.sym = linksym(s);
-	p->from.offset = off;
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = widthptr;
-	datagostring(lit, &p->to);
-	p->to.type = TYPE_ADDR;
-	p->to.etype = simtype[TINT];
-	off += widthptr;
-
-	return off;
-}
-
-int
-dgostringptr(Sym *s, int off, char *str)
-{
-	int n;
-	Strlit *lit;
-
-	if(str == nil)
-		return duintptr(s, off, 0);
-
-	n = strlen(str);
-	lit = mal(sizeof *lit + n);
-	strcpy(lit->s, str);
-	lit->len = n;
-	return dgostrlitptr(s, off, lit);
-}
-
-int
-dsymptr(Sym *s, int off, Sym *x, int xoff)
-{
-	Prog *p;
-
-	off = rnd(off, widthptr);
-
-	p = thearch.gins(ADATA, N, N);
-	p->from.type = TYPE_MEM;
-	p->from.name = NAME_EXTERN;
-	p->from.sym = linksym(s);
-	p->from.offset = off;
-	p->from3.type = TYPE_CONST;
-	p->from3.offset = widthptr;
-	p->to.type = TYPE_ADDR;
-	p->to.name = NAME_EXTERN;
-	p->to.sym = linksym(x);
-	p->to.offset = xoff;
-	off += widthptr;
-
-	return off;
-}
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
deleted file mode 100644
index 8e670bd..0000000
--- a/src/cmd/gc/order.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-// 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)
-{
-	char s[50];
-
-	if(debug['W'] > 1) {
-		snprint(s, sizeof(s), "\nbefore order %S", fn->nname->sym);
-		dumplist(s, fn->nbody);
-	}
-
-	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) {
-	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;
-	}
-
-	fatal("ordersafeexpr %O", n->op);
-	return nil; // not reached
-}		
-
-// 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, *typ;
-
-	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 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 OAS2DOTTYPE:
-		// Special: use temporary variables to hold result,
-		// so that assertI2Tetc can take address of temporary.
-		// No temporary for blank assignment.
-		t = marktemp(order);
-		orderexprlist(n->list, order);
-		orderexpr(&n->rlist->n->left, order);  // i in i.(T)
-		if(isblank(n->list->n))
-			order->out = list(order->out, n);
-		else {
-			typ = n->rlist->n->type;
-			tmp1 = ordertemp(typ, order, haspointers(typ));
-			order->out = list(order->out, n);
-			r = nod(OAS, n->list->n, tmp1);
-			typecheck(&r, Etop);
-			ordermapassign(r, order);
-			n->list = list(list1(tmp1), n->list->next->n);
-		}
-		cleantemp(t, order);
-		break;
-
-	case OAS2RECV:
-		// Special: 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:
-			// Mark []byte(str) range expression to reuse string backing storage.
-			// It is safe because the storage cannot be mutated.
-			if(n->right->op == OSTRARRAYBYTE)
-				n->right->op = OSTRARRAYBYTETMP;
-			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, haslit, hasbyte;
-
-	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);
-		}
-
-		// Mark string(byteSlice) arguments to reuse byteSlice backing
-		// buffer during conversion. String concatenation does not
-		// memorize the strings for later use, so it is safe.
-		// However, we can do it only if there is at least one non-empty string literal.
-		// Otherwise if all other arguments are empty strings,
-		// concatstrings will return the reference to the temp string
-		// to the caller.
-		hasbyte = 0;
-		haslit = 0;
-		for(l=n->list; l != nil; l=l->next) {
-			hasbyte |= l->n->op == OARRAYBYTESTR;
-			haslit |= l->n->op == OLITERAL && l->n->val.u.sval->len != 0;
-		}
-		if(haslit && hasbyte) {
-			for(l=n->list; l != nil; l=l->next) {
-				if(l->n->op == OARRAYBYTESTR)
-					l->n->op = OARRAYBYTESTRTMP;
-			}
-		}
-		break;
-
-	case OCMPSTR:
-		orderexpr(&n->left, order);
-		orderexpr(&n->right, order);
-		// Mark string(byteSlice) arguments to reuse byteSlice backing
-		// buffer during conversion. String comparison does not
-		// memorize the strings for later use, so it is safe.
-		if(n->left->op == OARRAYBYTESTR)
-			n->left->op = OARRAYBYTESTRTMP;
-		if(n->right->op == OARRAYBYTESTR)
-			n->right->op = OARRAYBYTESTRTMP;
-		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:
-	case ODOTTYPE:
-		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
deleted file mode 100644
index 16a8691..0000000
--- a/src/cmd/gc/pgen.c
+++ /dev/null
@@ -1,547 +0,0 @@
-// 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	"go.h"
-//#include	"opt.h"
-#include	"../../runtime/funcdata.h"
-#include	"../ld/textflag.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);
-	thearch.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:
-		thearch.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 == TYPE_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;
-	Node *nam;
-	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.", 5) == 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);
-	nam = curfn->nname;
-	if(isblank(nam))
-		nam = N;
-	ptxt = thearch.gins(ATEXT, nam, &nod1);
-	if(fn->dupok)
-		ptxt->from3.offset |= DUPOK;
-	if(fn->wrapper)
-		ptxt->from3.offset |= WRAPPER;
-	if(fn->needctxt)
-		ptxt->from3.offset |= NEEDCTXT;
-	if(fn->nosplit)
-		ptxt->from3.offset |= 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->from3.offset |= WRAPPER;
-	}	
-	
-	afunclit(&ptxt->from, curfn->nname);
-
-	thearch.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 = thearch.gins(ATYPE, l->n, &nod1);
-			p->from.gotype = linksym(ngotype(l->n));
-			break;
-		}
-	}
-
-	genlist(curfn->enter);
-	genlist(curfn->nbody);
-	thearch.gclean();
-	checklabels();
-	if(nerrors != 0)
-		goto ret;
-	if(curfn->endlineno)
-		lineno = curfn->endlineno;
-
-	if(curfn->type->outtuple != 0)
-		thearch.ginscall(throwreturn, 0);
-
-	thearch.ginit();
-	// TODO: Determine when the final cgen_ret can be omitted. Perhaps always?
-	thearch.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;
-	}
-	thearch.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);
-	}
-	thearch.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);
-
-	thearch.defframe(ptxt);
-
-	if(debug['f'])
-		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) {
-		if(a->class == PAUTO)
-			return +1;
-		return -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 >= thearch.MAXWIDTH || w < 0)
-			fatal("bad width");
-		stksize += w;
-		stksize = rnd(stksize, n->type->align);
-		if(haspointers(n->type))
-			stkptrsize = stksize;
-		if(thearch.thechar == '5' || thearch.thechar == '9')
-			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(((thearch.thechar == '5' || thearch.thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
-		thearch.regalloc(&reg, types[tptr], n);
-		thearch.cgen(n, &reg);
-		thearch.gins(ACHECKNIL, &reg, N);
-		thearch.regfree(&reg);
-		return;
-	}
-	thearch.gins(ACHECKNIL, n, N);
-}
diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c
deleted file mode 100644
index c0d1e57..0000000
--- a/src/cmd/gc/plive.c
+++ /dev/null
@@ -1,2005 +0,0 @@
-// 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 "go.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 == TYPE_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 == TYPE_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.
-			if(bb->last->as != AJMP && bb->last->as != ARET && bb->last->as != AUNDEF)
-				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 n;
-
-	n = arraylength(cfg);
-	if(n > 0) {
-		bb0 = *(BasicBlock**)arrayget(cfg, 0);
-		for(p = bb0->first; p != P; p = p->link) {
-			p->opt = nil;
-		}
-		for(i = 0; i < n; 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);
-
-	thearch.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 == thearch.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 == TYPE_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 && ((Node*)(from->node))->curfn == curfn) {
-			switch(((Node*)(from->node))->class & ~PHEAP) {
-			case PAUTO:
-			case PPARAM:
-			case PPARAMOUT:
-				pos = (int)(uintptr)((Node*)(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(((Node*)(from->node))->addrtaken) {
-					bvset(avarinit, pos);
-				} else {
-					if(info.flags & (LeftRead | LeftAddr))
-						bvset(uevar, pos);
-					if(info.flags & LeftWrite)
-						if(from->node != nil && !isfat(((Node*)(from->node))->type))
-							bvset(varkill, pos);
-				}
-			}
-		}
-	}
-Next:
-	if(info.flags & (RightRead | RightWrite | RightAddr)) {
-		to = &prog->to;
-		if (to->node != nil && to->sym != nil && ((Node*)(to->node))->curfn == curfn) {
-			switch(((Node*)(to->node))->class & ~PHEAP) {
-			case PAUTO:
-			case PPARAM:
-			case PPARAMOUT:
-				pos = (int)(uintptr)((Node*)(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(((Node*)(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(((Node*)(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 = "";
-	if(haspointers(node->type))
-		p = "^";
-	a = "";
-	if(node->addrtaken)
-		a = "@";
-	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;
-
-	if(n == nil) {
-		print("%L: checkauto %N: nil node in %P\n", p->lineno, curfn, p);
-		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.name == NAME_AUTO)
-		checkauto(fn, p, p->from.node);
-	if(p->from.name == NAME_PARAM)
-		checkparam(fn, p, p->from.node);
-	if(p->to.name == NAME_AUTO)
-		checkauto(fn, p, p->to.node);
-	if(p->to.name == NAME_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);
-		if(p->as != ADATA && p->as != AGLOBL && p->as != ATYPE)
-			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 (BitsScalar)
-		}
-		*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 (BitsPointer)
-		*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 (BitsPointer)
-		*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 + 1); // 2 = live ptr in first slot (BitsPointer)
-		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 3); // 2 = live ptr in second slot (BitsPointer)
-		*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 (BitsPointer)
-			*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.
-				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:", ((Node*)(p->to.node))->sym->name);
-					else if(p->as == ACALL)
-						fmtprint(&fmt, "indirect call:");
-					else
-						fmtprint(&fmt, "entry to %s:", ((Node*)(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)
-{
-	int i, n;
-	uint32 w;
-	
-	n = (bv->n+31)/32;
-	for(i=0; i<n; i++) {
-		w = bv->b[i];
-		h = (h*Hp) ^ (w&0xff);
-		h = (h*Hp) ^ ((w>>8)&0xff);
-		h = (h*Hp) ^ ((w>>16)&0xff);
-		h = (h*Hp) ^ ((w>>24)&0xff);
-	}
-	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, n;
-	uint32 word;
-
-	n = 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 < n; 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
deleted file mode 100644
index b02d58e..0000000
--- a/src/cmd/gc/popt.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-// 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	"go.h"
-#include	"popt.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 = ((Node*)(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 == TYPE_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 == TYPE_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 == TYPE_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 == TYPE_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, 0);
-//	... 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)
-//
-// The size argument to flowstart specifies an amount of zeroed memory
-// to allocate in every f->data field, for use by the client.
-// If size == 0, f->data will be nil.
-
-Graph*
-flowstart(Prog *firstp, int size)
-{
-	int id, nf;
-	Flow *f, *f1, *start, *last;
-	Graph *graph;
-	Prog *p;
-	ProgInfo info;
-	char *data;
-
-	// 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
-		thearch.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 + sizeof(Flow)*nf + size*nf, 1);
-	if(graph == nil)
-		fatal("out of memory");
-	start = (Flow*)(graph+1);
-	last = nil;
-	f = start;
-	data = (char*)(f+nf);
-	if(size == 0)
-		data = nil;
-	id = 0;
-	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->data = data;
-		f->id = id;
-		f++;
-		id++;
-		data += size;
-	}
-
-	// Fill in pred/succ information.
-	for(f = start; f != nil; f = f->link) {
-		p = f->prog;
-		thearch.proginfo(&info, p);
-		if(!(info.flags & Break)) {
-			f1 = f->link;
-			f->s1 = f1;
-			f1->p1 = f;
-		}
-		if(p->to.type == TYPE_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;
-
-struct TempVar
-{
-	Node *node;
-	Flow *def; // definition of temp var
-	Flow *use; // use list, chained through Flow.data
-	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
-};
-
-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;
-	// Order what's left by id or symbol name,
-	// just so that sort is forced into a specific ordering,
-	// so that the result of the sort does not depend on
-	// the sort implementation.
-	if(a->def != b->def)
-		return a->def->id - b->def->id;
-	if(a->node != b->node)
-		return strcmp(a->node->sym->name, b->node->sym->name);
-	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*, Flow*, uint32);
-static void varkillwalk(TempVar*, Flow*, uint32);
-
-void
-mergetemp(Prog *firstp)
-{
-	int i, j, nvar, ninuse, nfree, nkill;
-	TempVar *var, *v, *v1, **bystart, **inuse;
-	Flow *f;
-	NodeList *l, **lp;
-	Node *n;
-	Prog *p, *p1;
-	Type *t;
-	ProgInfo info, info1;
-	int32 gen;
-	Graph *g;
-
-	enum { debugmerge = 1 };
-
-	g = flowstart(firstp, 0);
-	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(f = g->start; f != nil; f = f->link) {
-		p = f->prog;
-		thearch.proginfo(&info, p);
-
-		if(p->from.node != N && ((Node*)(p->from.node))->opt && p->to.node != N && ((Node*)(p->to.node))->opt)
-			fatal("double node %P", p);
-		v = nil;
-		if((n = p->from.node) != N)
-			v = n->opt;
-		if(v == nil && (n = p->to.node) != N)
-			v = n->opt;
-		if(v != nil) {
-		   	if(v->def == nil)
-		   		v->def = f;
-		   	f->data = v->use;
-			v->use = f;
-			if(n == p->from.node && (info.flags & LeftAddr))
-				v->addr = 1;
-		}
-	}
-	
-	if(debugmerge > 1 && debug['v'])
-		dumpit("before", g->start, 0);
-	
-	nkill = 0;
-
-	// Special case.
-	for(i = 0; i < nvar; i++) {
-		v = &var[i];
-		if(v->addr)
-			continue;
-		// Used in only one instruction, which had better be a write.
-		if((f = v->use) != nil && (Flow*)f->data == nil) {
-			p = f->prog;
-			thearch.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(debugmerge > 0 && debug['v'])
-					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((f = v->use) != nil && f->link == (Flow*)f->data && (Flow*)((Flow*)f->data)->data == nil && uniqp(f->link) == f) {
-			p = f->prog;
-			thearch.proginfo(&info, p);
-			p1 = f->link->prog;
-			thearch.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;
-				thearch.excise(f);
-				v->removed = 1;
-				if(debugmerge > 0 && debug['v'])
-					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->active words after each variable.
-	gen = 0;
-	for(i = 0; i < nvar; i++) {
-		v = &var[i];
-		gen++;
-		for(f = v->use; f != nil; f = (Flow*)f->data)
-			mergewalk(v, f, gen);
-		if(v->addr) {
-			gen++;
-			for(f = v->use; f != nil; f = (Flow*)f->data)
-				varkillwalk(v, f, 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(debugmerge > 0 && debug['v'])
-			print("consider %#N: removed=%d\n", v->node, v->removed);
-			
-		if(v->removed)
-			continue;
-
-		// Expire no longer in use.
-		while(ninuse > 0 && inuse[ninuse-1]->end < v->start) {
-			v1 = inuse[--ninuse];
-			inuse[--nfree] = v1;
-		}
-
-		if(debugmerge > 0 && debug['v'])
-			print("consider %#N: removed=%d nfree=%d nvar=%d\n", v->node, v->removed, nfree, nvar);
-		// Find old temp to reuse if possible.
-		t = v->node->type;
-		for(j=nfree; j<nvar; j++) {
-			v1 = inuse[j];
-			if(debugmerge > 0 && debug['v'])
-				print("consider %#N: maybe %#N: type=%T,%T addrtaken=%d,%d\n", v->node, v1->node, t, v1->node->type, v->node->addrtaken, v1->node->addrtaken);
-			// 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(debugmerge > 0 && debug['v']) {
-		print("%S [%d - %d]\n", curfn->nname->sym, nvar, nkill);
-		for(i = 0; i < nvar; i++) {
-			v = &var[i];
-			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 && v->def != nil)
-				print(" %P", v->def->prog);
-			print("\n");
-		}
-	
-		if(debugmerge > 1 && debug['v'])
-			dumpit("after", g->start, 0);
-	}
-
-	// Update node references to use merged temporaries.
-	for(f = g->start; f != nil; f = f->link) {
-		p = 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(i = 0; i < nvar; i++)
-		var[i].node->opt = nil;
-
-	free(var);
-	free(bystart);
-	free(inuse);
-	flowend(g);
-}
-
-static void
-mergewalk(TempVar *v, Flow *f0, uint32 gen)
-{
-	Prog *p;
-	Flow *f1, *f, *f2;
-	
-	for(f1 = f0; f1 != nil; f1 = f1->p1) {
-		if(f1->active == gen)
-			break;
-		f1->active = gen;
-		p = f1->prog;
-		if(v->end < p->pc)
-			v->end = p->pc;
-		if(f1 == v->def) {
-			v->start = p->pc;
-			break;
-		}
-	}
-	
-	for(f = f0; f != f1; f = f->p1)
-		for(f2 = f->p2; f2 != nil; f2 = f2->p2link)
-			mergewalk(v, f2, gen);
-}
-
-static void
-varkillwalk(TempVar *v, Flow *f0, uint32 gen)
-{
-	Prog *p;
-	Flow *f1, *f;
-	
-	for(f1 = f0; f1 != nil; f1 = f1->s1) {
-		if(f1->active == gen)
-			break;
-		f1->active = gen;
-		p = f1->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(f = f0; f != f1; f = f->s1)
-		varkillwalk(v, 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;
-
-static void nilwalkback(Flow *rcheck);
-static void nilwalkfwd(Flow *rcheck);
-
-static int killed; // f->data is either nil or &killed
-
-void
-nilopt(Prog *firstp)
-{
-	Flow *f;
-	Prog *p;
-	Graph *g;
-	int ncheck, nkill;
-
-	g = flowstart(firstp, 0);
-	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(f = g->start; f != nil; f = f->link) {
-		p = f->prog;
-		if(p->as != ACHECKNIL || !thearch.regtyp(&p->from))
-			continue;
-		ncheck++;
-		if(thearch.stackaddr(&p->from)) {
-			if(debug_checknil && p->lineno > 1)
-				warnl(p->lineno, "removed nil check of SP address");
-			f->data = &killed;
-			continue;
-		}
-		nilwalkfwd(f);
-		if(f->data != nil) {
-			if(debug_checknil && p->lineno > 1)
-				warnl(p->lineno, "removed nil check before indirect");
-			continue;
-		}
-		nilwalkback(f);
-		if(f->data != nil) {
-			if(debug_checknil && p->lineno > 1)
-				warnl(p->lineno, "removed repeated nil check");
-			continue;
-		}
-	}
-	
-	for(f = g->start; f != nil; f = f->link) {
-		if(f->data != nil) {
-			nkill++;
-			thearch.excise(f);
-		}
-	}
-
-	flowend(g);
-	
-	if(debug_checknil > 1)
-		print("%S: removed %d of %d nil checks\n", curfn->nname->sym, nkill, ncheck);
-}
-
-static void
-nilwalkback(Flow *fcheck)
-{
-	Prog *p;
-	ProgInfo info;
-	Flow *f;
-	
-	for(f = fcheck; f != nil; f = uniqp(f)) {
-		p = f->prog;
-		thearch.proginfo(&info, p);
-		if((info.flags & RightWrite) && thearch.sameaddr(&p->to, &fcheck->prog->from)) {
-			// Found initialization of value we're checking for nil.
-			// without first finding the check, so this one is unchecked.
-			return;
-		}
-		if(f != fcheck && p->as == ACHECKNIL && thearch.sameaddr(&p->from, &fcheck->prog->from)) {
-			fcheck->data = &killed;
-			return;
-		}
-	}
-
-	// Here is a more complex version that scans backward across branches.
-	// It assumes fcheck->kill = 1 has been set on entry, and its job is to find a reason
-	// to keep the check (setting fcheck->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(f1 = f0; f1 != nil; f1 = f1->p1) {
-		if(f1->active == gen)
-			break;
-		f1->active = gen;
-		p = f1->prog;
-		
-		// If same check, stop this loop but still check
-		// alternate predecessors up to this point.
-		if(f1 != fcheck && p->as == ACHECKNIL && thearch.sameaddr(&p->from, &fcheck->prog->from))
-			break;
-
-		thearch.proginfo(&info, p);
-		if((info.flags & RightWrite) && thearch.sameaddr(&p->to, &fcheck->prog->from)) {
-			// Found initialization of value we're checking for nil.
-			// without first finding the check, so this one is unchecked.
-			fcheck->kill = 0;
-			return;
-		}
-		
-		if(f1->p1 == nil && f1->p2 == nil) {
-			print("lost pred for %P\n", fcheck->prog);
-			for(f1=f0; f1!=nil; f1=f1->p1) {
-				thearch.proginfo(&info, f1->prog);
-				print("\t%P %d %d %D %D\n", r1->prog, info.flags&RightWrite, thearch.sameaddr(&f1->prog->to, &fcheck->prog->from), &f1->prog->to, &fcheck->prog->from);
-			}
-			fatal("lost pred trail");
-		}
-	}
-
-	for(f = f0; f != f1; f = f->p1)
-		for(f2 = f->p2; f2 != nil; f2 = f2->p2link)
-			nilwalkback(fcheck, f2, gen);
-	*/
-}
-
-static void
-nilwalkfwd(Flow *fcheck)
-{
-	Flow *f, *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(f = uniqs(fcheck); f != nil; f = uniqs(f)) {
-		p = f->prog;
-		thearch.proginfo(&info, p);
-		
-		if((info.flags & LeftRead) && thearch.smallindir(&p->from, &fcheck->prog->from)) {
-			fcheck->data = &killed;
-			return;
-		}
-		if((info.flags & (RightRead|RightWrite)) && thearch.smallindir(&p->to, &fcheck->prog->from)) {
-			fcheck->data = &killed;
-			return;
-		}
-		
-		// Stop if another nil check happens.
-		if(p->as == ACHECKNIL)
-			return;
-		// Stop if value is lost.
-		if((info.flags & RightWrite) && thearch.sameaddr(&p->to, &fcheck->prog->from))
-			return;
-		// Stop if memory write.
-		if((info.flags & RightWrite) && !thearch.regtyp(&p->to))
-			return;
-		// Stop if we jump backward.
-		if(last != nil && f->id <= last->id)
-			return;
-		last = f;
-	}
-}
diff --git a/src/cmd/gc/popt.h b/src/cmd/gc/popt.h
deleted file mode 100644
index 4e89dbd..0000000
--- a/src/cmd/gc/popt.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Derived from Inferno utils/6c/gc.h
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/gc.h
-//
-//	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.
-
-#define	Z	N
-#define	Adr	Addr
-
-#define	BLOAD(r)	band(bnot(r->refbehind), r->refahead)
-#define	BSTORE(r)	band(bnot(r->calbehind), r->calahead)
-#define	LOAD(r)		(~r->refbehind.b[z] & r->refahead.b[z])
-#define	STORE(r)	(~r->calbehind.b[z] & r->calahead.b[z])
-
-enum
-{
-	CLOAD = 5,
-	CREF = 5,
-	CINF = 1000,
-	LOOP = 3,
-};
-
-typedef	struct	Reg	Reg;
-typedef	struct	Rgn	Rgn;
-
-/*c2go
-extern Node *Z;
-
-uint32 BLOAD(Reg*);
-uint32 BSTORE(Reg*);
-uint64 LOAD(Reg*);
-uint64 STORE(Reg*);
-*/
-
-// A Reg is a wrapper around a single Prog (one instruction) that holds
-// register optimization information while the optimizer runs.
-// r->prog is the instruction.
-struct	Reg
-{
-	Bits	set;  		// regopt variables written by this instruction.
-	Bits	use1; 		// regopt variables read by prog->from.
-	Bits	use2; 		// regopt variables read by prog->to.
-
-	// refahead/refbehind are the regopt variables whose current
-	// value may be used in the following/preceding instructions
-	// up to a CALL (or the value is clobbered).
-	Bits	refbehind;
-	Bits	refahead;
-	// calahead/calbehind are similar, but for variables in
-	// instructions that are reachable after hitting at least one
-	// CALL.
-	Bits	calbehind;
-	Bits	calahead;
-	Bits	regdiff;
-	Bits	act;
-
-	uint64	regu;		// register used bitmap
-};
-#define	R	((Reg*)0)
-/*c2go extern Reg *R; */
-
-#define	NRGN	600
-/*c2go enum { NRGN = 600 }; */
-
-// A Rgn represents a single regopt variable over a region of code
-// where a register could potentially be dedicated to that variable.
-// The code encompassed by a Rgn is defined by the flow graph,
-// starting at enter, flood-filling forward while varno is refahead
-// and backward while varno is refbehind, and following branches.  A
-// single variable may be represented by multiple disjoint Rgns and
-// each Rgn may choose a different register for that variable.
-// Registers are allocated to regions greedily in order of descending
-// cost.
-struct	Rgn
-{
-	Flow*	enter;
-	short	cost;
-	short	varno;
-	short	regno;
-};
-
-EXTERN	Reg	zreg;
-EXTERN	Rgn	region[NRGN];
-EXTERN	Rgn*	rgp;
-EXTERN	int	nregion;
-EXTERN	int	nvar;
-EXTERN	uint64	regbits;
-EXTERN	Bits	externs;
-EXTERN	Bits	params;
-EXTERN	Bits	consts;
-EXTERN	Bits	addrs;
-EXTERN	Bits	ivar;
-EXTERN	Bits	ovar;
-EXTERN	int	change;
-EXTERN	int32	maxnr;
-
-typedef struct OptStats OptStats;
-struct OptStats
-{
-	int32	ncvtreg;
-	int32	nspill;
-	int32	nreload;
-	int32	ndelmov;
-	int32	nvar;
-	int32	naddr;
-};
-
-EXTERN	OptStats ostats;
-
-/*
- * reg.c
- */
-void	regopt(Prog*);
-void	dumpone(Flow*, int);
-void	dumpit(char*, Flow*, int);
-
-/*
- * peep.c
-void	peep(Prog*);
-void	excise(Flow*);
-int	copyu(Prog*, Adr*, Adr*);
- */
-
-/*
- * prog.c
-
-void proginfo(ProgInfo*, Prog*);
- */
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
deleted file mode 100644
index 3aa7e36..0000000
--- a/src/cmd/gc/racewalk.c
+++ /dev/null
@@ -1,653 +0,0 @@
-// 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 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 OAS:
-	case OAS2FUNC:
-		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.
-		// typedslicecopy is instrumented in runtime.
-		if(n->left->sym != S && n->left->sym->pkg == runtimepkg && 
-		(strncmp(n->left->sym->name, "writebarrier", 12) == 0 || strcmp(n->left->sym->name, "typedmemmove") == 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, "typedmemmove") == 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:
-		// n->left is Type* which is not interesting.
-		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:
-	case OAS2:
-	case OAS2RECV:
-	case OAS2MAPR:
-	case OASOP:
-		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)
-{
-	char *name;
-	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 = outervalue(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) {
-		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)) {
-			name = "racereadrange";
-			if(wr)
-				name = "racewriterange";
-			f = mkcall(name, T, init, uintptraddr(n), nodintconst(t->width));
-		} else {
-			name = "raceread";
-			if(wr)
-				name = "racewrite";
-			f = mkcall(name, 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;
-}
-
-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
deleted file mode 100644
index ff9de6c..0000000
--- a/src/cmd/gc/range.c
+++ /dev/null
@@ -1,378 +0,0 @@
-// 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)
-{
-	int toomany;
-	char *why;
-	Type *t, *t1, *t2;
-	Node *v1, *v2;
-	NodeList *ll;
-
-	// Typechecking order is important here:
-	// 0. first typecheck range expression (slice/map/chan),
-	//	it is evaluated only once and so logically it is not part of the loop.
-	// 1. typcheck produced values,
-	//	this part can declare new vars and so it must be typechecked before body,
-	//	because body can contain a closure that captures the vars.
-	// 2. decldepth++ to denote loop body.
-	// 3. typecheck body.
-	// 4. decldepth--.
-
-	typecheck(&n->right, Erv);
-	if((t = n->right->type) == T)
-		goto out;
-
-	// delicate little dance.  see typecheckas2
-	for(ll=n->list; ll; ll=ll->next)
-		if(ll->n->defn != n)
-			typecheck(&ll->n, Erv | Easgn);
-
-	if(isptr[t->etype] && isfixedarray(t->type))
-		t = t->type;
-	n->type = t;
-
-	toomany = 0;
-	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)
-			toomany = 1;
-		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);
-		checkassign(n, v1);
-	}
-	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);
-		checkassign(n, v2);
-	}
-
-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);
-
-	decldepth++;
-	typechecklist(n->nbody, Etop);
-	decldepth--;
-}
-
-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:
-		// Lower n into runtime·memclr if possible, for
-		// fast zeroing of slices and arrays (issue 5373).
-		// Look for instances of
-		//
-		// for i := range a {
-		// 	a[i] = zero
-		// }
-		//
-		// in which the evaluation of a is side-effect-free.
-		if(!debug['N'])
-		if(!flag_race)
-		if(v1 != N)
-		if(v2 == N)
-		if(n->nbody != nil)
-		if(n->nbody->n != N)	// at least one statement in body
-		if(n->nbody->next == nil) {	// at most one statement in body
-			tmp = n->nbody->n;	// first statement of body
-			if(tmp->op == OAS)
-			if(tmp->left->op == OINDEX)
-			if(samesafeexpr(tmp->left->left, a))
-			if(samesafeexpr(tmp->left->right, v1))
-			if(t->type->width > 0)
-			if(iszero(tmp->right)) {
-				// Convert to
-				// if len(a) != 0 {
-				// 	hp = &a[0]
-				// 	hn = len(a)*sizeof(elem(a))
-				// 	memclr(hp, hn)
-				// 	i = len(a) - 1
-				// }
-				n->op = OIF;
-				n->nbody = nil;
-				n->ntest = nod(ONE, nod(OLEN, a, N), nodintconst(0));
-				n->nincr = nil;
-
-				// hp = &a[0]
-				hp = temp(ptrto(types[TUINT8]));
-				tmp = nod(OINDEX, a, nodintconst(0));
-				tmp->bounded = 1;
-				tmp = nod(OADDR, tmp, N);
-				tmp = nod(OCONVNOP, tmp, N);
-				tmp->type = ptrto(types[TUINT8]);
-				n->nbody = list(n->nbody, nod(OAS, hp, tmp));
-
-				// hn = len(a) * sizeof(elem(a))
-				hn = temp(types[TUINTPTR]);
-				tmp = nod(OLEN, a, N);
-				tmp = nod(OMUL, tmp, nodintconst(t->type->width));
-				tmp = conv(tmp, types[TUINTPTR]);
-				n->nbody = list(n->nbody, nod(OAS, hn, tmp));
-
-				// memclr(hp, hn)
-				fn = mkcall("memclr", T, nil, hp, hn);
-				n->nbody = list(n->nbody, fn);
-
-				// i = len(a) - 1
-				v1 = nod(OAS, v1, nod(OSUB, nod(OLEN, a, N), nodintconst(1)));
-				n->nbody = list(n->nbody, v1);
-
-				typecheck(&n->ntest, Erv);
-				typechecklist(n->nbody, Etop);
-				walkstmt(&n);
-				lineno = lno;
-				return;
-			}
-		}
-
-		// 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
deleted file mode 100644
index 9390ab9..0000000
--- a/src/cmd/gc/reflect.c
+++ /dev/null
@@ -1,1609 +0,0 @@
-// 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*
-makefield(char *name, Type *t)
-{
-	Type *f;
-
-	f = typ(TFIELD);
-	f->type = t;
-	f->sym = mal(sizeof(Sym));
-	f->sym->name = name;
-	return f;
-}
-
-Type*
-mapbucket(Type *t)
-{
-	Type *keytype, *valtype;
-	Type *bucket, *arr;
-	Type *field[4];
-	int32 n;
-
-	if(t->bucket != T)
-		return t->bucket;
-
-	bucket = typ(TSTRUCT);
-	keytype = t->down;
-	valtype = t->type;
-	dowidth(keytype);
-	dowidth(valtype);
-	if(keytype->width > MAXKEYSIZE)
-		keytype = ptrto(keytype);
-	if(valtype->width > MAXVALSIZE)
-		valtype = ptrto(valtype);
-
-	// The first field is: uint8 topbits[BUCKETSIZE].
-	arr = typ(TARRAY);
-	arr->type = types[TUINT8];
-	arr->bound = BUCKETSIZE;
-	field[0] = makefield("topbits", arr);
-	arr = typ(TARRAY);
-	arr->type = keytype;
-	arr->bound = BUCKETSIZE;
-	field[1] = makefield("keys", arr);
-	arr = typ(TARRAY);
-	arr->type = valtype;
-	arr->bound = BUCKETSIZE;
-	field[2] = makefield("values", arr);
-	field[3] = makefield("overflow", ptrto(bucket));
-
-	// link up fields
-	bucket->noalg = 1;
-	bucket->local = t->local;
-	bucket->type = field[0];
-	for(n = 0; n < nelem(field)-1; n++)
-		field[n]->down = field[n+1];
-	field[nelem(field)-1]->down = T;
-	dowidth(bucket);
-
-	// Pad to the native integer alignment.
-	// This is usually the same as widthptr; the exception (as usual) is amd64p32.
-	if(widthreg > widthptr)
-		bucket->width += widthreg - widthptr;
-
-	// See comment on hmap.overflow in ../../runtime/hashmap.go.
-	if(!haspointers(t->type) && !haspointers(t->down) &&
-		t->type->width <= MAXKEYSIZE && t->down->width <= MAXVALSIZE)
-		bucket->haspointers = 1;  // no pointers
-
-	t->bucket = bucket;
-	bucket->map = t;
-	return bucket;
-}
-
-// Builds a type representing a Hmap structure for the given map type.
-// Make sure this stays in sync with ../../runtime/hashmap.go!
-Type*
-hmap(Type *t)
-{
-	Type *h, *bucket;
-	Type *field[8];
-	int32 n;
-
-	if(t->hmap != T)
-		return t->hmap;
-
-	bucket = mapbucket(t);
-	field[0] = makefield("count", types[TINT]);
-	field[1] = makefield("flags", types[TUINT8]);
-	field[2] = makefield("B", types[TUINT8]);
-	field[3] = makefield("hash0", types[TUINT32]);
-	field[4] = makefield("buckets", ptrto(bucket));
-	field[5] = makefield("oldbuckets", ptrto(bucket));
-	field[6] = makefield("nevacuate", types[TUINTPTR]);
-	field[7] = makefield("overflow", types[TUNSAFEPTR]);
-
-	h = typ(TSTRUCT);
-	h->noalg = 1;
-	h->local = t->local;
-	h->type = field[0];
-	for(n = 0; n < nelem(field)-1; n++)
-		field[n]->down = field[n+1];
-	field[nelem(field)-1]->down = T;
-	dowidth(h);
-	t->hmap = h;
-	h->map = t;
-	return h;
-}
-
-Type*
-hiter(Type *t)
-{
-	int32 n;
-	Type *field[12];
-	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
-	//    overflow0 unsafe.Pointer
-	//    overflow1 unsafe.Pointer
-	//    startBucket uintptr
-	//    stuff uintptr
-	//    bucket uintptr
-	//    checkBucket uintptr
-	// }
-	// must match ../../runtime/hashmap.c:hash_iter.
-	field[0] = makefield("key", ptrto(t->down));
-	field[1] = makefield("val", ptrto(t->type));
-	field[2] = makefield("t", ptrto(types[TUINT8]));
-	field[3] = makefield("h", ptrto(hmap(t)));
-	field[4] = makefield("buckets", ptrto(mapbucket(t)));
-	field[5] = makefield("bptr", ptrto(mapbucket(t)));
-	field[6] = makefield("overflow0", types[TUNSAFEPTR]);
-	field[7] = makefield("overflow1", types[TUNSAFEPTR]);
-	field[8] = makefield("startBucket", types[TUINTPTR]);
-	field[9] = makefield("stuff", types[TUINTPTR]); // offset+wrapped+B+I
-	field[10] = makefield("bucket", types[TUINTPTR]);
-	field[11] = makefield("checkBucket", types[TUINTPTR]);
-	
-	// build iterator struct holding the above fields
-	i = typ(TSTRUCT);
-	i->noalg = 1;
-	i->type = field[0];
-	for(n = 0; n < nelem(field)-1; n++)
-		field[n]->down = field[n+1];
-	field[nelem(field)-1]->down = T;
-	dowidth(i);
-	if(i->width != 12 * widthptr)
-		yyerror("hash_iter size not correct %d %d", i->width, 12 * 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(newstrlit("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(newstrlit("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 || alg == AMEM)
-		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(algsym == S)
-		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.0x%016llux", x1);
-		} else {
-			x2 = 0;
-			for(i=0; i<8; i++)
-				x2 = x2<<8 | gcmask[i+8];
-			p = smprint("gcbits.0x%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;
-}
-
-/*
- * Returns 1 if t has a reflexive equality operator.
- * That is, if x==x for all x of type t.
- */
-static int
-isreflexive(Type *t)
-{
-	Type *t1;
-	switch(t->etype) {
-		case TBOOL:
-		case TINT:
-		case TUINT:
-		case TINT8:
-		case TUINT8:
-		case TINT16:
-		case TUINT16:
-		case TINT32:
-		case TUINT32:
-		case TINT64:
-		case TUINT64:
-		case TUINTPTR:
-		case TPTR32:
-		case TPTR64:
-		case TUNSAFEPTR:
-		case TSTRING:
-		case TCHAN:
-			return 1;
-		case TFLOAT32:
-		case TFLOAT64:
-		case TCOMPLEX64:
-		case TCOMPLEX128:
-		case TINTER:
-			return 0;
-		case TARRAY:
-			if(isslice(t))
-				fatal("slice can't be a map key: %T", t);
-			return isreflexive(t->type);
-		case TSTRUCT:
-			for(t1=t->type; t1!=T; t1=t1->down) {
-				if(!isreflexive(t1->type))
-					return 0;
-			}
-			return 1;
-		default:
-			fatal("bad type for map key: %T", t);
-			return 0;
-	}
-}
-
-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);
-                ot = duint8(s, ot, isreflexive(t->down));
-		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(newstrlit("main")));
-	}
-}
-
-static Sym*
-dalgsym(Type *t)
-{
-	int ot;
-	Sym *s, *hash, *hashfunc, *eq, *eqfunc;
-	char *p;
-
-	// 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).
-
-	if(algtype(t) == AMEM) {
-		// we use one algorithm table for all AMEM types of a given size
-		p = smprint(".alg%lld", t->width);
-		s = pkglookup(p, typepkg);
-		free(p);
-		if(s->flags & SymAlgGen)
-			return s;
-		s->flags |= SymAlgGen;
-
-		// make hash closure
-		p = smprint(".hashfunc%lld", t->width);
-		hashfunc = pkglookup(p, typepkg);
-		free(p);
-		ot = 0;
-		ot = dsymptr(hashfunc, ot, pkglookup("memhash_varlen", runtimepkg), 0);
-		ot = duintxx(hashfunc, ot, t->width, widthptr); // size encoded in closure
-		ggloblsym(hashfunc, ot, DUPOK|RODATA);
-
-		// make equality closure
-		p = smprint(".eqfunc%lld", t->width);
-		eqfunc = pkglookup(p, typepkg);
-		free(p);
-		ot = 0;
-		ot = dsymptr(eqfunc, ot, pkglookup("memequal_varlen", runtimepkg), 0);
-		ot = duintxx(eqfunc, ot, t->width, widthptr);
-		ggloblsym(eqfunc, ot, DUPOK|RODATA);
-	} else {
-		// generate an alg table specific to this type
-		s = typesymprefix(".alg", t);
-		hash = typesymprefix(".hash", t);
-		eq = typesymprefix(".eq", t);
-		hashfunc = typesymprefix(".hashfunc", t);
-		eqfunc = typesymprefix(".eqfunc", t);
-
-		genhash(hash, t);
-		geneq(eq, t);
-
-		// make Go funcs (closures) for calling hash and equal from Go
-		dsymptr(hashfunc, 0, hash, 0);
-		ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
-		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)
-{
-	Bvec *vec;
-	vlong xoffset, nptr, i, j;
-	int  half;
-	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 = gcmask;
-	nptr = (t->width+widthptr-1)/widthptr;
-	half = 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(bits == BitsDead)
-				bits = BitsScalar;
-			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:
-		// Assuming IfacePointerOnly=1.
-		proggendata(g, BitsPointer);
-		proggendata(g, BitsPointer);
-		*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/reg.c b/src/cmd/gc/reg.c
deleted file mode 100644
index 67409c2..0000000
--- a/src/cmd/gc/reg.c
+++ /dev/null
@@ -1,1233 +0,0 @@
-// 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.
-
-#include <u.h>
-#include <libc.h>
-#include "go.h"
-#include "popt.h"
-
-static	Flow*	firstf;
-static	int	first	= 1;
-
-static void	addmove(Flow*, int, int, int);
-static Bits	mkvar(Flow*, Adr*);
-static void	prop(Flow*, Bits, Bits);
-static void	synch(Flow*, Bits);
-static uint64	allreg(uint64, Rgn*);
-static void	paint1(Flow*, int);
-static uint64	paint2(Flow*, int, int);
-static void	paint3(Flow*, int, uint64, int);
-static void	addreg(Adr*, int);
-
-static int
-rcmp(const void *a1, const void *a2)
-{
-	Rgn *p1, *p2;
-
-	p1 = (Rgn*)a1;
-	p2 = (Rgn*)a2;
-	if(p1->cost != p2->cost)
-		return p2->cost - p1->cost;
-	if(p1->varno != p2->varno)
-		return p2->varno - p1->varno;
-	if(p1->enter != p2->enter)
-		return p2->enter->id - p1->enter->id;
-	return 0;
-}
-
-static void
-setaddrs(Bits bit)
-{
-	int i, n;
-	Var *v;
-	Node *node;
-
-	while(bany(&bit)) {
-		// convert each bit to a variable
-		i = bnum(bit);
-		node = var[i].node;
-		n = var[i].name;
-		biclr(&bit, i);
-
-		// disable all pieces of that variable
-		for(i=0; i<nvar; i++) {
-			v = var+i;
-			if(v->node == node && v->name == n)
-				v->addr = 2;
-		}
-	}
-}
-
-static Node* regnodes[64];
-
-static void walkvardef(Node *n, Flow *r, int active);
-
-void
-regopt(Prog *firstp)
-{
-	Flow *f, *f1;
-	Reg *r;
-	Prog *p;
-	Graph *g;
-	ProgInfo info;
-	int i, z, active;
-	uint64 vreg, usedreg;
-	uint64 mask;
-	int nreg;
-	char **regnames;
-	Bits bit;
-	Rgn *rgp;
-
-	if(first) {
-		fmtinstall('Q', Qconv);
-		first = 0;
-	}
-
-	mergetemp(firstp);
-
-	/*
-	 * control flow is more complicated in generated go code
-	 * than in generated c code.  define pseudo-variables for
-	 * registers, so we have complete register usage information.
-	 */
-	regnames = thearch.regnames(&nreg);
-	nvar = nreg;
-	memset(var, 0, nreg*sizeof var[0]);
-	for(i=0; i<nreg; i++) {
-		if(regnodes[i] == N)
-			regnodes[i] = newname(lookup(regnames[i]));
-		var[i].node = regnodes[i];
-	}
-
-	regbits = thearch.excludedregs();
-	externs = zbits;
-	params = zbits;
-	consts = zbits;
-	addrs = zbits;
-	ivar = zbits;
-	ovar = zbits;
-
-	/*
-	 * pass 1
-	 * build aux data structure
-	 * allocate pcs
-	 * find use and set of variables
-	 */
-	g = flowstart(firstp, sizeof(Reg));
-	if(g == nil) {
-		for(i=0; i<nvar; i++)
-			var[i].node->opt = nil;
-		return;
-	}
-
-	firstf = g->start;
-
-	for(f = firstf; f != nil; f = f->link) {
-		p = f->prog;
-		if(p->as == AVARDEF || p->as == AVARKILL)
-			continue;
-		thearch.proginfo(&info, p);
-
-		// Avoid making variables for direct-called functions.
-		if(p->as == ACALL && p->to.type == TYPE_MEM && p->to.name == NAME_EXTERN)
-			continue;
-
-		// from vs to doesn't matter for registers.
-		r = (Reg*)f->data;
-		r->use1.b[0] |= info.reguse | info.regindex;
-		r->set.b[0] |= info.regset;
-
-		bit = mkvar(f, &p->from);
-		if(bany(&bit)) {
-			if(info.flags & LeftAddr)
-				setaddrs(bit);
-			if(info.flags & LeftRead)
-				for(z=0; z<BITS; z++)
-					r->use1.b[z] |= bit.b[z];
-			if(info.flags & LeftWrite)
-				for(z=0; z<BITS; z++)
-					r->set.b[z] |= bit.b[z];
-		}
-
-		// Compute used register for reg
-		if(info.flags & RegRead)
-			r->use1.b[0] |= thearch.RtoB(p->reg);
-
-		// Currently we never generate three register forms.
-		// If we do, this will need to change.
-		if(p->from3.type != TYPE_NONE)
-			fatal("regopt not implemented for from3");
-
-		bit = mkvar(f, &p->to);
-		if(bany(&bit)) {	
-			if(info.flags & RightAddr)
-				setaddrs(bit);
-			if(info.flags & RightRead)
-				for(z=0; z<BITS; z++)
-					r->use2.b[z] |= bit.b[z];
-			if(info.flags & RightWrite)
-				for(z=0; z<BITS; z++)
-					r->set.b[z] |= bit.b[z];
-		}
-	}
-
-	for(i=0; i<nvar; i++) {
-		Var *v;
-		v = var+i;
-		if(v->addr) {
-			bit = blsh(i);
-			for(z=0; z<BITS; z++)
-				addrs.b[z] |= bit.b[z];
-		}
-
-		if(debug['R'] && debug['v'])
-			print("bit=%2d addr=%d et=%E w=%-2d s=%N + %lld\n",
-				i, v->addr, v->etype, v->width, v->node, v->offset);
-	}
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass1", firstf, 1);
-
-	/*
-	 * pass 2
-	 * find looping structure
-	 */
-	flowrpo(g);
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass2", firstf, 1);
-
-	/*
-	 * pass 2.5
-	 * iterate propagating fat vardef covering forward
-	 * r->act records vars with a VARDEF since the last CALL.
-	 * (r->act will be reused in pass 5 for something else,
-	 * but we'll be done with it by then.)
-	 */
-	active = 0;
-	for(f = firstf; f != nil; f = f->link) {
-		f->active = 0;
-		r = (Reg*)f->data;
-		r->act = zbits;
-	}
-	for(f = firstf; f != nil; f = f->link) {
-		p = f->prog;
-		if(p->as == AVARDEF && isfat(((Node*)(p->to.node))->type) && ((Node*)(p->to.node))->opt != nil) {
-			active++;
-			walkvardef(p->to.node, f, active);
-		}
-	}
-
-	/*
-	 * pass 3
-	 * iterate propagating usage
-	 * 	back until flow graph is complete
-	 */
-loop1:
-	change = 0;
-	for(f = firstf; f != nil; f = f->link)
-		f->active = 0;
-	for(f = firstf; f != nil; f = f->link)
-		if(f->prog->as == ARET)
-			prop(f, zbits, zbits);
-loop11:
-	/* pick up unreachable code */
-	i = 0;
-	for(f = firstf; f != nil; f = f1) {
-		f1 = f->link;
-		if(f1 && f1->active && !f->active) {
-			prop(f, zbits, zbits);
-			i = 1;
-		}
-	}
-	if(i)
-		goto loop11;
-	if(change)
-		goto loop1;
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass3", firstf, 1);
-
-	/*
-	 * pass 4
-	 * iterate propagating register/variable synchrony
-	 * 	forward until graph is complete
-	 */
-loop2:
-	change = 0;
-	for(f = firstf; f != nil; f = f->link)
-		f->active = 0;
-	synch(firstf, zbits);
-	if(change)
-		goto loop2;
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass4", firstf, 1);
-
-	/*
-	 * pass 4.5
-	 * move register pseudo-variables into regu.
-	 */
-	if(nreg == 64)
-		mask = ~0ULL; // can't rely on C to shift by 64
-	else
-		mask = (1ULL<<nreg) - 1;
-	for(f = firstf; f != nil; f = f->link) {
-		r = (Reg*)f->data;
-		r->regu = (r->refbehind.b[0] | r->set.b[0]) & mask;
-		r->set.b[0] &= ~mask;
-		r->use1.b[0] &= ~mask;
-		r->use2.b[0] &= ~mask;
-		r->refbehind.b[0] &= ~mask;
-		r->refahead.b[0] &= ~mask;
-		r->calbehind.b[0] &= ~mask;
-		r->calahead.b[0] &= ~mask;
-		r->regdiff.b[0] &= ~mask;
-		r->act.b[0] &= ~mask;
-	}
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass4.5", firstf, 1);
-
-	/*
-	 * pass 5
-	 * isolate regions
-	 * calculate costs (paint1)
-	 */
-	f = firstf;
-	if(f) {
-		r = (Reg*)f->data;
-		for(z=0; z<BITS; z++)
-			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
-			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
-		if(bany(&bit) && !f->refset) {
-			// should never happen - all variables are preset
-			if(debug['w'])
-				print("%L: used and not set: %Q\n", f->prog->lineno, bit);
-			f->refset = 1;
-		}
-	}
-	for(f = firstf; f != nil; f = f->link)
-		((Reg*)f->data)->act = zbits;
-	nregion = 0;
-	for(f = firstf; f != nil; f = f->link) {
-		r = (Reg*)f->data;
-		for(z=0; z<BITS; z++)
-			bit.b[z] = r->set.b[z] &
-			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
-		if(bany(&bit) && !f->refset) {
-			if(debug['w'])
-				print("%L: set and not used: %Q\n", f->prog->lineno, bit);
-			f->refset = 1;
-			thearch.excise(f);
-		}
-		for(z=0; z<BITS; z++)
-			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
-		while(bany(&bit)) {
-			i = bnum(bit);
-			change = 0;
-			paint1(f, i);
-			biclr(&bit, i);
-			if(change <= 0)
-				continue;
-			if(nregion >= NRGN) {
-				if(debug['R'] && debug['v'])
-					print("too many regions\n");
-				goto brk;
-			}
-			rgp = &region[nregion];
-			rgp->enter = f;
-			rgp->varno = i;
-			rgp->cost = change;
-			nregion++;
-		}
-	}
-brk:
-	qsort(region, nregion, sizeof(region[0]), rcmp);
-
-	if(debug['R'] && debug['v'])
-		dumpit("pass5", firstf, 1);
-
-	/*
-	 * pass 6
-	 * determine used registers (paint2)
-	 * replace code (paint3)
-	 */
-	if(debug['R'] && debug['v'])
-		print("\nregisterizing\n");
-	for(i=0; i<nregion; i++) {
-		rgp = &region[i];
-		if(debug['R'] && debug['v'])
-			print("region %d: cost %d varno %d enter %lld\n", i, rgp->cost, rgp->varno, rgp->enter->prog->pc);
-		bit = blsh(rgp->varno);
-		usedreg = paint2(rgp->enter, rgp->varno, 0);
-		vreg = allreg(usedreg, rgp);
-		if(rgp->regno != 0) {
-			if(debug['R'] && debug['v']) {
-				Var *v;
-
-				v = var + rgp->varno;
-				print("registerize %N+%lld (bit=%2d et=%E) in %R usedreg=%#llx vreg=%#llx\n",
-						v->node, v->offset, rgp->varno, v->etype, rgp->regno, usedreg, vreg);
-			}
-			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
-		}
-	}
-
-	/*
-	 * free aux structures. peep allocates new ones.
-	 */
-	for(i=0; i<nvar; i++)
-		var[i].node->opt = nil;
-	flowend(g);
-	firstf = nil;
-
-	if(debug['R'] && debug['v']) {
-		// Rebuild flow graph, since we inserted instructions
-		g = flowstart(firstp, 0);
-		firstf = g->start;
-		dumpit("pass6", firstf, 0);
-		flowend(g);
-		firstf = nil;
-	}
-
-	/*
-	 * pass 7
-	 * peep-hole on basic block
-	 */
-	if(!debug['R'] || debug['P'])
-		thearch.peep(firstp);
-
-	/*
-	 * eliminate nops
-	 */
-	for(p=firstp; p!=P; p=p->link) {
-		while(p->link != P && p->link->as == ANOP)
-			p->link = p->link->link;
-		if(p->to.type == TYPE_BRANCH)
-			while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
-				p->to.u.branch = p->to.u.branch->link;
-	}
-
-	if(debug['R']) {
-		if(ostats.ncvtreg ||
-		   ostats.nspill ||
-		   ostats.nreload ||
-		   ostats.ndelmov ||
-		   ostats.nvar ||
-		   ostats.naddr ||
-		   0)
-			print("\nstats\n");
-
-		if(ostats.ncvtreg)
-			print("	%4d cvtreg\n", ostats.ncvtreg);
-		if(ostats.nspill)
-			print("	%4d spill\n", ostats.nspill);
-		if(ostats.nreload)
-			print("	%4d reload\n", ostats.nreload);
-		if(ostats.ndelmov)
-			print("	%4d delmov\n", ostats.ndelmov);
-		if(ostats.nvar)
-			print("	%4d var\n", ostats.nvar);
-		if(ostats.naddr)
-			print("	%4d addr\n", ostats.naddr);
-
-		memset(&ostats, 0, sizeof(ostats));
-	}
-}
-
-static void
-walkvardef(Node *n, Flow *f, int active)
-{
-	Flow *f1, *f2;
-	int bn;
-	Var *v;
-	
-	for(f1=f; f1!=nil; f1=f1->s1) {
-		if(f1->active == active)
-			break;
-		f1->active = active;
-		if(f1->prog->as == AVARKILL && f1->prog->to.node == n)
-			break;
-		for(v=n->opt; v!=nil; v=v->nextinnode) {
-			bn = v->id;
-			biset(&((Reg*)f1->data)->act, bn);
-		}
-		if(f1->prog->as == ACALL)
-			break;
-	}
-
-	for(f2=f; f2!=f1; f2=f2->s1)
-		if(f2->s2 != nil)
-			walkvardef(n, f2->s2, active);
-}
-
-/*
- * add mov b,rn
- * just after r
- */
-static void
-addmove(Flow *r, int bn, int rn, int f)
-{
-	Prog *p, *p1;
-	Adr *a;
-	Var *v;
-
-	p1 = mal(sizeof(*p1));
-	clearp(p1);
-	p1->pc = 9999;
-
-	p = r->prog;
-	p1->link = p->link;
-	p->link = p1;
-	p1->lineno = p->lineno;
-
-	v = var + bn;
-
-	a = &p1->to;
-	a->offset = v->offset;
-	a->etype = v->etype;
-	a->type = TYPE_MEM;
-	a->name = v->name;
-	a->node = v->node;
-	a->sym = linksym(v->node->sym);
-	/* NOTE(rsc): 9g did
-	if(a->etype == TARRAY)
-		a->type = TYPE_ADDR;
-	else if(a->sym == nil)
-		a->type = TYPE_CONST;
-	*/
-
-	p1->as = thearch.optoas(OAS, types[(uchar)v->etype]);
-	// TODO(rsc): Remove special case here.
-	if((thearch.thechar == '9' || thearch.thechar == '5') && v->etype == TBOOL)
-		p1->as = thearch.optoas(OAS, types[TUINT8]);
-	p1->from.type = TYPE_REG;
-	p1->from.reg = rn;
-	p1->from.name = NAME_NONE;
-	if(!f) {
-		p1->from = *a;
-		*a = zprog.from;
-		a->type = TYPE_REG;
-		a->reg = rn;
-	}
-	if(debug['R'] && debug['v'])
-		print("%P ===add=== %P\n", p, p1);
-	ostats.nspill++;
-}
-
-static int
-overlap(int64 o1, int w1, int64 o2, int w2)
-{
-	int64 t1, t2;
-
-	t1 = o1+w1;
-	t2 = o2+w2;
-
-	if(!(t1 > o2 && t2 > o1))
-		return 0;
-
-	return 1;
-}
-
-static Bits
-mkvar(Flow *f, Adr *a)
-{
-	Var *v;
-	int i, n, et, z, flag;
-	int64 w;
-	uint64 regu;
-	int64 o;
-	Bits bit;
-	Node *node;
-	Reg *r;
-	
-
-	/*
-	 * mark registers used
-	 */
-	if(a->type == TYPE_NONE)
-		goto none;
-
-	r = (Reg*)f->data;
-	r->use1.b[0] |= thearch.doregbits(a->index); // TODO: Use RtoB
-
-	switch(a->type) {
-	default:
-		regu = thearch.doregbits(a->reg) | thearch.RtoB(a->reg); // TODO: Use RtoB
-		if(regu == 0)
-			goto none;
-		bit = zbits;
-		bit.b[0] = regu;
-		return bit;
-
-	case TYPE_ADDR:
-		// TODO(rsc): Remove special case here.
-		if(thearch.thechar == '9' || thearch.thechar == '5')
-			goto memcase;
-		a->type = TYPE_MEM;
-		bit = mkvar(f, a);
-		setaddrs(bit);
-		a->type = TYPE_ADDR;
-		ostats.naddr++;
-		goto none;
-
-	case TYPE_MEM:
-	memcase:
-		if(r != R) {
-			r->use1.b[0] |= thearch.RtoB(a->reg);
-			/* NOTE: 5g did
-				if(r->f.prog->scond & (C_PBIT|C_WBIT))
-					r->set.b[0] |= RtoB(a->reg);
-			*/
-		}
-		switch(a->name) {
-		default:
-			goto none;
-		case NAME_EXTERN:
-		case NAME_STATIC:
-		case NAME_PARAM:
-		case NAME_AUTO:
-			n = a->name;
-			break;
-		}
-	}
-
-	node = a->node;
-	if(node == N || node->op != ONAME || node->orig == N)
-		goto none;
-	node = node->orig;
-	if(node->orig != node)
-		fatal("%D: bad node", a);
-	if(node->sym == S || node->sym->name[0] == '.')
-		goto none;
-	et = a->etype;
-	o = a->offset;
-	w = a->width;
-	if(w < 0)
-		fatal("bad width %lld for %D", w, a);
-
-	flag = 0;
-	for(i=0; i<nvar; i++) {
-		v = var+i;
-		if(v->node == node && v->name == n) {
-			if(v->offset == o)
-			if(v->etype == et)
-			if(v->width == w) {
-				// TODO(rsc): Remove special case for arm here.
-				if(!flag || thearch.thechar != '5')
-					return blsh(i);
-			}
-
-			// if they overlap, disable both
-			if(overlap(v->offset, v->width, o, w)) {
-//				print("disable overlap %s %d %d %d %d, %E != %E\n", s->name, v->offset, v->width, o, w, v->etype, et);
-				v->addr = 1;
-				flag = 1;
-			}
-		}
-	}
-
-	switch(et) {
-	case 0:
-	case TFUNC:
-		goto none;
-	}
-
-	if(nvar >= NVAR) {
-		if(debug['w'] > 1 && node != N)
-			fatal("variable not optimized: %#N", node);
-		
-		// If we're not tracking a word in a variable, mark the rest as
-		// having its address taken, so that we keep the whole thing
-		// live at all calls. otherwise we might optimize away part of
-		// a variable but not all of it.
-		for(i=0; i<nvar; i++) {
-			v = var+i;
-			if(v->node == node)
-				v->addr = 1;
-		}
-		goto none;
-	}
-
-	i = nvar;
-	nvar++;
-	v = var+i;
-	v->id = i;
-	v->offset = o;
-	v->name = n;
-	v->etype = et;
-	v->width = w;
-	v->addr = flag;		// funny punning
-	v->node = node;
-	
-	// node->opt is the head of a linked list
-	// of Vars within the given Node, so that
-	// we can start at a Var and find all the other
-	// Vars in the same Go variable.
-	v->nextinnode = node->opt;
-	node->opt = v;
-
-	bit = blsh(i);
-	if(n == NAME_EXTERN || n == NAME_STATIC)
-		for(z=0; z<BITS; z++)
-			externs.b[z] |= bit.b[z];
-	if(n == NAME_PARAM)
-		for(z=0; z<BITS; z++)
-			params.b[z] |= bit.b[z];
-
-	if(node->class == PPARAM)
-		for(z=0; z<BITS; z++)
-			ivar.b[z] |= bit.b[z];
-	if(node->class == PPARAMOUT)
-		for(z=0; z<BITS; z++)
-			ovar.b[z] |= bit.b[z];
-
-	// Treat values with their address taken as live at calls,
-	// because the garbage collector's liveness analysis in ../gc/plive.c does.
-	// These must be consistent or else we will elide stores and the garbage
-	// collector will see uninitialized data.
-	// The typical case where our own analysis is out of sync is when the
-	// node appears to have its address taken but that code doesn't actually
-	// get generated and therefore doesn't show up as an address being
-	// taken when we analyze the instruction stream.
-	// One instance of this case is when a closure uses the same name as
-	// an outer variable for one of its own variables declared with :=.
-	// The parser flags the outer variable as possibly shared, and therefore
-	// sets addrtaken, even though it ends up not being actually shared.
-	// If we were better about _ elision, _ = &x would suffice too.
-	// The broader := in a closure problem is mentioned in a comment in
-	// closure.c:/^typecheckclosure and dcl.c:/^oldname.
-	if(node->addrtaken)
-		v->addr = 1;
-
-	// Disable registerization for globals, because:
-	// (1) we might panic at any time and we want the recovery code
-	// to see the latest values (issue 1304).
-	// (2) we don't know what pointers might point at them and we want
-	// loads via those pointers to see updated values and vice versa (issue 7995).
-	//
-	// Disable registerization for results if using defer, because the deferred func
-	// might recover and return, causing the current values to be used.
-	if(node->class == PEXTERN || (hasdefer && node->class == PPARAMOUT))
-		v->addr = 1;
-
-	if(debug['R'])
-		print("bit=%2d et=%E w=%lld+%lld %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
-	ostats.nvar++;
-
-	return bit;
-
-none:
-	return zbits;
-}
-
-static void
-prop(Flow *f, Bits ref, Bits cal)
-{
-	Flow *f1, *f2;
-	Reg *r, *r1;
-	int z, i;
-	Var *v, *v1;
-
-	for(f1 = f; f1 != nil; f1 = f1->p1) {
-		r1 = (Reg*)f1->data;
-		for(z=0; z<BITS; z++) {
-			ref.b[z] |= r1->refahead.b[z];
-			if(ref.b[z] != r1->refahead.b[z]) {
-				r1->refahead.b[z] = ref.b[z];
-				change++;
-			}
-			cal.b[z] |= r1->calahead.b[z];
-			if(cal.b[z] != r1->calahead.b[z]) {
-				r1->calahead.b[z] = cal.b[z];
-				change++;
-			}
-		}
-		switch(f1->prog->as) {
-		case ACALL:
-			if(noreturn(f1->prog))
-				break;
-
-			// Mark all input variables (ivar) as used, because that's what the
-			// liveness bitmaps say. The liveness bitmaps say that so that a
-			// panic will not show stale values in the parameter dump.
-			// Mark variables with a recent VARDEF (r1->act) as used,
-			// so that the optimizer flushes initializations to memory,
-			// so that if a garbage collection happens during this CALL,
-			// the collector will see initialized memory. Again this is to
-			// match what the liveness bitmaps say.
-			for(z=0; z<BITS; z++) {
-				cal.b[z] |= ref.b[z] | externs.b[z] | ivar.b[z] | r1->act.b[z];
-				ref.b[z] = 0;
-			}
-			
-			// cal.b is the current approximation of what's live across the call.
-			// Every bit in cal.b is a single stack word. For each such word,
-			// find all the other tracked stack words in the same Go variable
-			// (struct/slice/string/interface) and mark them live too.
-			// This is necessary because the liveness analysis for the garbage
-			// collector works at variable granularity, not at word granularity.
-			// It is fundamental for slice/string/interface: the garbage collector
-			// needs the whole value, not just some of the words, in order to
-			// interpret the other bits correctly. Specifically, slice needs a consistent
-			// ptr and cap, string needs a consistent ptr and len, and interface
-			// needs a consistent type word and data word.
-			for(z=0; z<BITS; z++) {
-				if(cal.b[z] == 0)
-					continue;
-				for(i=0; i<64; i++) {
-					if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0)
-						continue;
-					v = var+z*64+i;
-					if(v->node->opt == nil) // v represents fixed register, not Go variable
-						continue;
-
-					// v->node->opt is the head of a linked list of Vars
-					// corresponding to tracked words from the Go variable v->node.
-					// Walk the list and set all the bits.
-					// For a large struct this could end up being quadratic:
-					// after the first setting, the outer loop (for z, i) would see a 1 bit
-					// for all of the remaining words in the struct, and for each such
-					// word would go through and turn on all the bits again.
-					// To avoid the quadratic behavior, we only turn on the bits if
-					// v is the head of the list or if the head's bit is not yet turned on.
-					// This will set the bits at most twice, keeping the overall loop linear.
-					v1 = v->node->opt;
-					if(v == v1 || !btest(&cal, v1->id)) {
-						for(; v1 != nil; v1 = v1->nextinnode) {
-							biset(&cal, v1->id);
-						}
-					}
-				}
-			}
-			break;
-
-		case ATEXT:
-			for(z=0; z<BITS; z++) {
-				cal.b[z] = 0;
-				ref.b[z] = 0;
-			}
-			break;
-
-		case ARET:
-			for(z=0; z<BITS; z++) {
-				cal.b[z] = externs.b[z] | ovar.b[z];
-				ref.b[z] = 0;
-			}
-			break;
-		}
-		for(z=0; z<BITS; z++) {
-			ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
-				r1->use1.b[z] | r1->use2.b[z];
-			cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
-			r1->refbehind.b[z] = ref.b[z];
-			r1->calbehind.b[z] = cal.b[z];
-		}
-		if(f1->active)
-			break;
-		f1->active = 1;
-	}
-
-	for(; f != f1; f = f->p1) {
-		r = (Reg*)f->data;
-		for(f2 = f->p2; f2 != nil; f2 = f2->p2link)
-			prop(f2, r->refbehind, r->calbehind);
-	}
-}
-
-static void
-synch(Flow *f, Bits dif)
-{
-	Flow *f1;
-	Reg *r1;
-	int z;
-
-	for(f1 = f; f1 != nil; f1 = f1->s1) {
-		r1 = (Reg*)f1->data;
-		for(z=0; z<BITS; z++) {
-			dif.b[z] = (dif.b[z] &
-				~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
-					r1->set.b[z] | r1->regdiff.b[z];
-			if(dif.b[z] != r1->regdiff.b[z]) {
-				r1->regdiff.b[z] = dif.b[z];
-				change++;
-			}
-		}
-		if(f1->active)
-			break;
-		f1->active = 1;
-		for(z=0; z<BITS; z++)
-			dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
-		if(f1->s2 != nil)
-			synch(f1->s2, dif);
-	}
-}
-
-static uint64
-allreg(uint64 b, Rgn *r)
-{
-	Var *v;
-	int i;
-
-	v = var + r->varno;
-	r->regno = 0;
-	switch(v->etype) {
-
-	default:
-		fatal("unknown etype %d/%E", bitno(b), v->etype);
-		break;
-
-	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:
-		i = thearch.BtoR(~b);
-		if(i && r->cost > 0) {
-			r->regno = i;
-			return thearch.RtoB(i);
-		}
-		break;
-
-	case TFLOAT32:
-	case TFLOAT64:
-		i = thearch.BtoF(~b);
-		if(i && r->cost > 0) {
-			r->regno = i;
-			return thearch.FtoB(i);
-		}
-		break;
-	}
-	return 0;
-}
-
-static void
-paint1(Flow *f, int bn)
-{
-	Flow *f1;
-	Reg *r, *r1;
-	int z;
-	uint64 bb;
-
-	z = bn/64;
-	bb = 1LL<<(bn%64);
-	r = (Reg*)f->data;
-	if(r->act.b[z] & bb)
-		return;
-	for(;;) {
-		if(!(r->refbehind.b[z] & bb))
-			break;
-		f1 = f->p1;
-		if(f1 == nil)
-			break;
-		r1 = (Reg*)f1->data;
-		if(!(r1->refahead.b[z] & bb))
-			break;
-		if(r1->act.b[z] & bb)
-			break;
-		f = f1;
-		r = r1;
-	}
-
-	if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
-		change -= CLOAD * f->loop;
-	}
-	for(;;) {
-		r->act.b[z] |= bb;
-
-		if(f->prog->as != ANOP) { // don't give credit for NOPs
-			if(r->use1.b[z] & bb)
-				change += CREF * f->loop;
-			if((r->use2.b[z]|r->set.b[z]) & bb)
-				change += CREF * f->loop;
-		}
-
-		if(STORE(r) & r->regdiff.b[z] & bb) {
-			change -= CLOAD * f->loop;
-		}
-
-		if(r->refbehind.b[z] & bb)
-			for(f1 = f->p2; f1 != nil; f1 = f1->p2link)
-				if(((Reg*)f1->data)->refahead.b[z] & bb)
-					paint1(f1, bn);
-
-		if(!(r->refahead.b[z] & bb))
-			break;
-		f1 = f->s2;
-		if(f1 != nil)
-			if(((Reg*)f1->data)->refbehind.b[z] & bb)
-				paint1(f1, bn);
-		f = f->s1;
-		if(f == nil)
-			break;
-		r = (Reg*)f->data;
-		if(r->act.b[z] & bb)
-			break;
-		if(!(r->refbehind.b[z] & bb))
-			break;
-	}
-}
-
-static uint64
-paint2(Flow *f, int bn, int depth)
-{
-	Flow *f1;
-	Reg *r, *r1;
-	int z;
-	uint64 bb, vreg;
-
-	z = bn/64;
-	bb = 1LL << (bn%64);
-	vreg = regbits;
-	r = (Reg*)f->data;
-	if(!(r->act.b[z] & bb))
-		return vreg;
-	for(;;) {
-		if(!(r->refbehind.b[z] & bb))
-			break;
-		f1 = f->p1;
-		if(f1 == nil)
-			break;
-		r1 = (Reg*)f1->data;
-		if(!(r1->refahead.b[z] & bb))
-			break;
-		if(!(r1->act.b[z] & bb))
-			break;
-		f = f1;
-		r = r1;
-	}
-	for(;;) {
-		if(debug['R'] && debug['v'])
-			print("  paint2 %d %P\n", depth, f->prog);
-
-		r->act.b[z] &= ~bb;
-
-		vreg |= r->regu;
-
-		if(r->refbehind.b[z] & bb)
-			for(f1 = f->p2; f1 != nil; f1 = f1->p2link)
-				if(((Reg*)f1->data)->refahead.b[z] & bb)
-					vreg |= paint2(f1, bn, depth+1);
-
-		if(!(r->refahead.b[z] & bb))
-			break;
-		f1 = f->s2;
-		if(f1 != nil)
-			if(((Reg*)f1->data)->refbehind.b[z] & bb)
-				vreg |= paint2(f1, bn, depth+1);
-		f = f->s1;
-		if(f == nil)
-			break;
-		r = (Reg*)f->data;
-		if(!(r->act.b[z] & bb))
-			break;
-		if(!(r->refbehind.b[z] & bb))
-			break;
-	}
-
-	return vreg;
-}
-
-static void
-paint3(Flow *f, int bn, uint64 rb, int rn)
-{
-	Flow *f1;
-	Reg *r, *r1;
-	Prog *p;
-	int z;
-	uint64 bb;
-
-	z = bn/64;
-	bb = 1LL << (bn%64);
-	r = (Reg*)f->data;
-	if(r->act.b[z] & bb)
-		return;
-	for(;;) {
-		if(!(r->refbehind.b[z] & bb))
-			break;
-		f1 = f->p1;
-		if(f1 == nil)
-			break;
-		r1 = (Reg*)f1->data;
-		if(!(r1->refahead.b[z] & bb))
-			break;
-		if(r1->act.b[z] & bb)
-			break;
-		f = f1;
-		r = r1;
-	}
-
-	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
-		addmove(f, bn, rn, 0);
-	for(;;) {
-		r->act.b[z] |= bb;
-		p = f->prog;
-
-		if(r->use1.b[z] & bb) {
-			if(debug['R'] && debug['v'])
-				print("%P", p);
-			addreg(&p->from, rn);
-			if(debug['R'] && debug['v'])
-				print(" ===change== %P\n", p);
-		}
-		if((r->use2.b[z]|r->set.b[z]) & bb) {
-			if(debug['R'] && debug['v'])
-				print("%P", p);
-			addreg(&p->to, rn);
-			if(debug['R'] && debug['v'])
-				print(" ===change== %P\n", p);
-		}
-
-		if(STORE(r) & r->regdiff.b[z] & bb)
-			addmove(f, bn, rn, 1);
-		r->regu |= rb;
-
-		if(r->refbehind.b[z] & bb)
-			for(f1 = f->p2; f1 != nil; f1 = f1->p2link)
-				if(((Reg*)f1->data)->refahead.b[z] & bb)
-					paint3(f1, bn, rb, rn);
-
-		if(!(r->refahead.b[z] & bb))
-			break;
-		f1 = f->s2;
-		if(f1 != nil)
-			if(((Reg*)f1->data)->refbehind.b[z] & bb)
-				paint3(f1, bn, rb, rn);
-		f = f->s1;
-		if(f == nil)
-			break;
-		r = (Reg*)f->data;
-		if(r->act.b[z] & bb)
-			break;
-		if(!(r->refbehind.b[z] & bb))
-			break;
-	}
-}
-
-static void
-addreg(Adr *a, int rn)
-{
-	a->sym = nil;
-	a->node = nil;
-	a->offset = 0;
-	a->type = TYPE_REG;
-	a->reg = rn;
-	a->name = 0;
-
-	ostats.ncvtreg++;
-}
-
-void
-dumpone(Flow *f, int isreg)
-{
-	int z;
-	Bits bit;
-	Reg *r;
-
-	print("%d:%P", f->loop, f->prog);
-	if(isreg) {	
-		r = (Reg*)f->data;
-		for(z=0; z<BITS; z++)
-			bit.b[z] =
-				r->set.b[z] |
-				r->use1.b[z] |
-				r->use2.b[z] |
-				r->refbehind.b[z] |
-				r->refahead.b[z] |
-				r->calbehind.b[z] |
-				r->calahead.b[z] |
-				r->regdiff.b[z] |
-				r->act.b[z] |
-					0;
-		if(bany(&bit)) {
-			print("\t");
-			if(bany(&r->set))
-				print(" s:%Q", r->set);
-			if(bany(&r->use1))
-				print(" u1:%Q", r->use1);
-			if(bany(&r->use2))
-				print(" u2:%Q", r->use2);
-			if(bany(&r->refbehind))
-				print(" rb:%Q ", r->refbehind);
-			if(bany(&r->refahead))
-				print(" ra:%Q ", r->refahead);
-			if(bany(&r->calbehind))
-				print(" cb:%Q ", r->calbehind);
-			if(bany(&r->calahead))
-				print(" ca:%Q ", r->calahead);
-			if(bany(&r->regdiff))
-				print(" d:%Q ", r->regdiff);
-			if(bany(&r->act))
-				print(" a:%Q ", r->act);
-		}
-	}
-	print("\n");
-}
-
-void
-dumpit(char *str, Flow *r0, int isreg)
-{
-	Flow *r, *r1;
-
-	print("\n%s\n", str);
-	for(r = r0; r != nil; r = r->link) {
-		dumpone(r, isreg);
-		r1 = r->p2;
-		if(r1 != nil) {
-			print("	pred:");
-			for(; r1 != nil; r1 = r1->p2link)
-				print(" %.4ud", (int)r1->prog->pc);
-			if(r->p1 != nil)
-				print(" (and %.4ud)", (int)r->p1->prog->pc);
-			else
-				print(" (only)");
-			print("\n");
-		}
-		// Print successors if it's not just the next one
-		if(r->s1 != r->link || r->s2 != nil) {
-			print("	succ:");
-			if(r->s1 != nil)
-				print(" %.4ud", (int)r->s1->prog->pc);
-			if(r->s2 != nil)
-				print(" %.4ud", (int)r->s2->prog->pc);
-			print("\n");
-		}
-	}
-}
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
deleted file mode 100644
index 0a4c1b8..0000000
--- a/src/cmd/gc/runtime.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// 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 printlock()
-func printunlock()
-
-func concatstring2(*[32]byte, string, string) string
-func concatstring3(*[32]byte, string, string, string) string
-func concatstring4(*[32]byte, string, string, string, string) string
-func concatstring5(*[32]byte, string, string, string, string, string) string
-func concatstrings(*[32]byte, []string) string
-
-func cmpstring(string, string) int
-func eqstring(string, string) bool
-func intstring(*[4]byte, int64) string
-func slicebytetostring(*[32]byte, []byte) string
-func slicebytetostringtmp([]byte) string
-func slicerunetostring(*[32]byte, []rune) string
-func stringtoslicebyte(*[32]byte, string) []byte
-func stringtoslicebytetmp(string) []byte
-func stringtoslicerune(*[32]rune, 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) bool
-func assertE2I(typ *byte, iface any, ret *any)
-func assertE2I2(typ *byte, iface any, ret *any) bool
-func assertE2T(typ *byte, iface any, ret *any)
-func assertE2T2(typ *byte, iface any, ret *any) bool
-func assertI2E(typ *byte, iface any, ret *any)
-func assertI2E2(typ *byte, iface any, ret *any) bool
-func assertI2I(typ *byte, iface any, ret *any)
-func assertI2I2(typ *byte, iface any, ret *any) bool
-func assertI2T(typ *byte, iface any, ret *any)
-func assertI2T2(typ *byte, iface any, ret *any) 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, mapbuf *any, bucketbuf *any) (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).
-// The bitmap in the name tells which words being copied are pointers.
-func writebarrierfat01(dst *any, _ *byte, src any)
-func writebarrierfat10(dst *any, _ *byte, src any)
-func writebarrierfat11(dst *any, _ *byte, src any)
-func writebarrierfat001(dst *any, _ *byte, src any)
-func writebarrierfat010(dst *any, _ *byte, src any)
-func writebarrierfat011(dst *any, _ *byte, src any)
-func writebarrierfat100(dst *any, _ *byte, src any)
-func writebarrierfat101(dst *any, _ *byte, src any)
-func writebarrierfat110(dst *any, _ *byte, src any)
-func writebarrierfat111(dst *any, _ *byte, src any)
-func writebarrierfat0001(dst *any, _ *byte, src any)
-func writebarrierfat0010(dst *any, _ *byte, src any)
-func writebarrierfat0011(dst *any, _ *byte, src any)
-func writebarrierfat0100(dst *any, _ *byte, src any)
-func writebarrierfat0101(dst *any, _ *byte, src any)
-func writebarrierfat0110(dst *any, _ *byte, src any)
-func writebarrierfat0111(dst *any, _ *byte, src any)
-func writebarrierfat1000(dst *any, _ *byte, src any)
-func writebarrierfat1001(dst *any, _ *byte, src any)
-func writebarrierfat1010(dst *any, _ *byte, src any)
-func writebarrierfat1011(dst *any, _ *byte, src any)
-func writebarrierfat1100(dst *any, _ *byte, src any)
-func writebarrierfat1101(dst *any, _ *byte, src any)
-func writebarrierfat1110(dst *any, _ *byte, src any)
-func writebarrierfat1111(dst *any, _ *byte, src any)
-
-func typedmemmove(typ *byte, dst *any, src *any)
-func typedslicecopy(typ *byte, dst any, src any) int
-
-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 memclr(ptr *byte, length uintptr)
-
-func memequal(x, y *any, size uintptr) bool
-func memequal8(x, y *any) bool
-func memequal16(x, y *any) bool
-func memequal32(x, y *any) bool
-func memequal64(x, y *any) bool
-func memequal128(x, y *any) 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
deleted file mode 100644
index 537d0ca..0000000
--- a/src/cmd/gc/select.c
+++ /dev/null
@@ -1,375 +0,0 @@
-// 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:
-			case OSELRECV2:
-				ch = n->right->left;
-				if(n->op == OSELRECV || n->ntest == N) {
-					if(n->left == N)
-						n = n->right;
-					else
-						n->op = OAS;
-					break;
-				}
-			
-				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("next")), 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
deleted file mode 100644
index 1015950..0000000
--- a/src/cmd/gc/sinit.c
+++ /dev/null
@@ -1,1502 +0,0 @@
-// 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, nam;
-	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:
-		if(stataddr(&nam, r->left)) {
-			n1 = *r;
-			n1.left = &nam;
-			gdata(l, &n1, 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 && thearch.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
deleted file mode 100644
index f739a72..0000000
--- a/src/cmd/gc/subr.c
+++ /dev/null
@@ -1,3856 +0,0 @@
-// 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;
-}
-
-void
-adderrorname(Node *n)
-{
-	char *old;
-	
-	if(n->op != ODOT)
-		return;
-	old = smprint("%L: undefined: %N\n", n->lineno, n->left);
-	if(nerr > 0 && err[nerr-1].lineno == n->lineno && strcmp(err[nerr-1].msg, old) == 0)
-		err[nerr-1].msg = smprint("%L: undefined: %N in %N\n", n->lineno, n->left, n);
-	free(old);
-}
-
-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("https://golang.org/issue/new\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 k;
-	
-	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;
-	k = strcmp(a->sym->name, b->sym->name);
-	if(k != 0)
-		return k;
-	if(!exportname(a->sym->name)) {
-		k = strcmp(a->sym->pkg->path->s, b->sym->pkg->path->s);
-		if(k != 0)
-			return k;
-	}
-	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://golang.org/issue/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)
-{
-	NodeList *l;
-	Node *n;
-	vlong w;
-
-	if(context) {
-		print("--- external frame ---\n");
-		l = externdcl;
-	} else if(curfn) {
-		print("--- %S frame ---\n", curfn->nname->sym);
-		l = curfn->dcl;
-	} else
-		return;
-
-	for(; l; l=l->next) {
-		n = l->n;
-		w = -1;
-		if(n->type)
-			w = n->type->width;
-		switch(n->op) {
-		case ONAME:
-			print("%O %S G%d %T width=%lld\n", n->op, n->sym, n->vargen, n->type, w);
-			break;
-
-		case OTYPE:
-			print("%O %T width=%lld\n", n->op, n->type, w);
-			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 %O\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 %O\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, int32 extra)
-{
-	int64 w;
-
-	dowidth(t);
-	w = t->argwid;
-	if(w >= thearch.MAXWIDTH)
-		fatal("bad argwid %T", t);
-	w += extra;
-	if(w >= thearch.MAXWIDTH)
-		fatal("bad argwid %d + %T", extra, 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 = newstrlit(rcvr->type->sym->pkg->name);  // package name
-		l = list(l, nodlit(v));
-		v.u.sval = newstrlit(rcvr->type->sym->name);  // type name
-		l = list(l, nodlit(v));
-		v.u.sval = newstrlit(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);
-}
-
-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:
-		fatal("hashfor with AMEM type");
-	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->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, 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("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], 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, 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, nh);
-				call->list = list(call->list, nodintconst(size));
-				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.
-			if(algtype1(t1->type, nil) == AMEM) {
-				hashel = hashmem(t1->type);
-				// h = memhash(&p.t1, h, size)
-				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, nh);
-				call->list = list(call->list, nodintconst(t1->type->width));
-				fn->nbody = list(fn->nbody, nod(OAS, nh, call));
-			} else {
-				hashel = hashfor(t1->type);
-				// h = hashel(&p.t1, 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, 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);
-	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, int *needsize)
-{
-	char buf[30];
-	Node *fn;
-
-	switch(size) {
-	default:
-		fn = syslook("memequal", 1);
-		*needsize = 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);
-		*needsize = 0;
-		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;
-	int needsize;
-
-	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, &needsize), N);
-	call->list = list(call->list, nx);
-	call->list = list(call->list, ny);
-	if(needsize)
-		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) 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, 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);
-	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*
-newstrlit(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?
- * Yes, if the representation is a single pointer.
- */
-int
-isdirectiface(Type *t)
-{
-	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;
-}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
deleted file mode 100644
index 0dc0065..0000000
--- a/src/cmd/gc/swt.c
+++ /dev/null
@@ -1,944 +0,0 @@
-// 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((arg != Strue && arg != Sfalse) ||
-			   assignop(n->left->type, exprname->type, nil) == OCONVIFACE ||
-			   assignop(exprname->type, n->left->type, nil) == OCONVIFACE) {
-				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
-			} else if(arg == Strue) {
-				a = nod(OIF, N, N);
-				a->ntest = n->left;			// if val
-				a->nbody = list1(n->right);			// then goto l
-			} else { // arg == 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
-			}
-
-			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.
- * rebuild 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 = nodbool(arg == Strue);
-	else if(consttype(sw->ntest) >= 0)
-		// leave constants to enable dead code elimination (issue 9608)
-		exprname = sw->ntest;
-	else {
-		exprname = temp(sw->ntest->type);
-		cas = list1(nod(OAS, exprname, sw->ntest));
-		typechecklist(cas, Etop);
-	}
-
-	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);
-				}
-				typecheck(&nvar, Erv | Easgn);
-				ncase->nname = nvar;
-			}
-		}
-		typechecklist(ncase->nbody, Etop);
-	}
-
-	lineno = lno;
-}
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
deleted file mode 100644
index 649f1c5..0000000
--- a/src/cmd/gc/typecheck.c
+++ /dev/null
@@ -1,3649 +0,0 @@
-// 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	checkassignlist(Node*, 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->decldepth == 0)
-			n->decldepth = decldepth;
-		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);
-		r = typecheck(&n->right, Erv);
-		checkassign(n, n->left);
-		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;
-		goto arith;
-
-	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->closure)
-				l->closure->addrtaken = 1;
-		}
-		if(l->orig != l && l->op == ONAME)
-			fatal("found non-orig name node %N", l);
-		l->addrtaken = 1;
-		if(l->closure)
-			l->closure->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(n->right->op != ONAME) {
-			yyerror("rhs of . must be a name");	// impossible
-			goto error;
-		}
-		if((t = n->left->type) == T) {
-			adderrorname(n);
-			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);
-			if(n->list->n->op != OCALLFUNC && n->list->n->op != OCALLMETH) {
-				yyerror("invalid operation: complex expects two arguments");
-				goto error;
-			}
-			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:
-		goto doconv;
-
-	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:
-			yyerror("cannot make type %T", t);
-			goto error;
-
-		case TARRAY:
-			if(!isslice(t)) {
-				yyerror("cannot make type %T", t);
-				goto error;
-			}
-			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);
-		// Code that creates temps does not bother to set defn, so do it here.
-		if(n->left->op == ONAME && strncmp(n->left->sym->name, "autotmp_", 8) == 0)
-			n->left->defn = n;
-		goto ret;
-
-	case OAS2:
-		ok |= Etop;
-		typecheckas2(n);
-		goto ret;
-
-	case OBREAK:
-	case OCONTINUE:
-	case ODCL:
-	case OEMPTY:
-	case OGOTO:
-	case OXFALL:
-	case OVARKILL:
-		ok |= Etop;
-		goto ret;
-
-	case OLABEL:
-		ok |= Etop;
-		decldepth++;
-		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);
-		decldepth++;
-		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);
-		decldepth--;
-		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;
-	}
-	goto ret;
-
-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;
-	aop = 0;
-	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.
-		// The conversion allocates, so only do it if the concrete type is huge.
-		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;
-			}
-			dowidth(l->type);
-			if(isinter(r->type) == isinter(l->type) || l->type->width >= 1<<16) {
-				l = nod(aop, l, N);
-				l->type = r->type;
-				l->typecheck = 1;
-				n->left = l;
-			}
-			t = r->type;
-			goto converted;
-		}
-		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;
-			}
-			dowidth(r->type);
-			if(isinter(r->type) == isinter(l->type) || r->type->width >= 1<<16) {
-				r = nod(aop, r, N);
-				r->type = l->type;
-				r->typecheck = 1;
-				n->right = r;
-			}
-			t = l->type;
-		}
-	converted:
-		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;
-		}
-		if(isinter(r->type) == isinter(l->type) || aop == 0) {
-			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;
-		}
-	} else if(n->op == OANDAND || n->op == OOROR) {
-		if(l->type == r->type)
-			t = l->type;
-		else if(l->type == idealbool)
-			t = r->type;
-		else if(r->type == idealbool)
-			t = l->type;
-	// 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 if(isinter(r->type) == isinter(l->type)) {
-			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;
-
-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 && n->type != types[TBOOL]) {
-			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;
-
-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
-		return;
-	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)
-			break;
-		yyerror("%s discards result of %N", what, n->left);
-		return;
-	}
-
-	// 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)
-		return;
-
-	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);
-	}
-}
-
-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("%L: redundant type: %T\n", n->lineno, t);
-	}
-}
-
-static void
-typecheckcomplit(Node **np)
-{
-	int bad, i, nerr;
-	int64 length;
-	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));
-
-		length = 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 > length) {
-				length = i;
-				if(t->bound >= 0 && length > t->bound) {
-					setlineno(l);
-					yyerror("array index %lld out of bounds [0:%lld]", length-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 = length;
-		if(t->bound < 0)
-			n->right = nodintconst(length);
-		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:
-	case OPARAM:
-		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);
-}
-
-void
-checkassign(Node *stmt, Node *n)
-{
-	Node *r, *l;
-
-	// Variables declared in ORANGE are assigned on every iteration.
-	if(n->defn != stmt || stmt->op == ORANGE) {
-		r = outervalue(n);
-		for(l = n; l != r; l = l->left) {
-			l->assigned = 1;
-			if(l->closure)
-				l->closure->assigned = 1;
-		}
-		l->assigned = 1;
-		if(l->closure)
-			l->closure->assigned = 1;
-	}
-
-	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(Node *stmt, NodeList *l)
-{
-	for(; l; l=l->next)
-		checkassign(stmt, 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.
-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);
-
-	typecheck(&n->right, Erv);
-	checkassign(n, n->left);
-	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.
-			// TODO(rsc): Reenable once it is actually updated in place without touching the pointer.
-			if(0 && 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.
-			// TODO(rsc): Reenable once the emitted code does update the pointer.
-			if(0 && 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);
-	if(cl > 1 && cr == 1)
-		typecheck(&n->rlist->n, Erv | Efnstruct);
-	else
-		typechecklist(n->rlist, Erv);
-	checkassignlist(n, n->list);
-
-	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;
-
-	// 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:
-		case ORECV:
-		case ODOTTYPE:
-			switch(r->op) {
-			case OINDEXMAP:
-				n->op = OAS2MAPR;
-				break;
-			case ORECV:
-				n->op = OAS2RECV;
-				break;
-			case ODOTTYPE:
-				n->op = OAS2DOTTYPE;
-				r->op = ODOTTYPE2;
-				break;
-			}
-			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;
-	NodeList *l;
-
-	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);
-
-	for(l=n->dcl; l; l=l->next)
-		if(l->n->op == ONAME && (l->n->class == PPARAM || l->n->class == PPARAMOUT))
-			l->n->decldepth = 1;
-}
-
-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;
-			// Note: adderrorname looks for this string and
-			// adds context about the outer expression
-			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
deleted file mode 100644
index 95d212e..0000000
--- a/src/cmd/gc/unsafe.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// 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)
-		goto no;
-	if((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
deleted file mode 100644
index c3c6278..0000000
--- a/src/cmd/gc/unsafe.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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
deleted file mode 100644
index 50dae8c..0000000
--- a/src/cmd/gc/walk.c
+++ /dev/null
@@ -1,4189 +0,0 @@
-// 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"
-
-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**);
-
-// The constant is known to runtime.
-enum
-{
-	tmpstringbufsize = 32,
-};
-
-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;
-}
-
-// adds "adjust" to all the argument locations for the call n.
-// n must be a defer or go node that has already been walked.
-static void
-adjustargs(Node *n, int adjust)
-{
-	Node *callfunc, *arg, *lhs;
-	NodeList *args;
-
-	callfunc = n->left;
-	for(args = callfunc->list; args != 0; args = args->next) {
-		arg = args->n;
-		if(arg->op != OAS)
-			yyerror("call arg not assignment");
-		lhs = arg->left;
-		if(lhs->op == ONAME) {
-			// This is a temporary introduced by reorder1.
-			// The real store to the stack appears later in the arg list.
-			continue;
-		}
-		if(lhs->op != OINDREG) {
-			yyerror("call argument store does not use OINDREG");
-		}
-		// can't really check this in machine-indep code.
-		//if(lhs->val.u.reg != D_SP)
-		//      yyerror("call arg assign not indreg(SP)");
-		lhs->xoffset += adjust;
-	}
-}
-
-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;
-		}
-		// make room for size & fn arguments.
-		adjustargs(n, 2 * widthptr);
-		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;
-		}
-		// make room for size & fn arguments.
-		adjustargs(n, 2 * widthptr);
-		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
-walkexprlistcheap(NodeList *l, NodeList **init)
-{
-	for(; l; l=l->next) {
-		l->n = cheapexpr(l->n, init);
-		walkexpr(&l->n, init);
-	}
-}
-
-void
-walkexpr(Node **np, NodeList **init)
-{
-	Node *r, *l, *var, *a, *ok;
-	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, *from, *to;
-
-	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:
-	case OPARAM:
-		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:
-		if(n->left->op == OCLOSURE) {
-			// Transform direct call of a closure to call of a normal function.
-			// transformclosure already did all preparation work.
-
-			// Append captured variables to argument list.
-			n->list = concat(n->list, n->left->enter);
-			n->left->enter = nil;
-			// Replace OCLOSURE with ONAME/PFUNC.
-			n->left = n->left->closure->nname;
-			// Update type of OCALLFUNC node.
-			// Output arguments had not changed, but their offsets could.
-			if(n->left->type->outtuple == 1) {
-				t = getoutargx(n->left->type)->type;
-				if(t->etype == TFIELD)
-					t = t->type;
-				n->type = t;
-			} else
-				n->type = getoutargx(n->left->type);
-		}
-
-		t = n->left->type;
-		if(n->list && 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 ODOTTYPE:
-			// x = i.(T); n->left is x, n->right->left is i.
-			// orderstmt made sure x is addressable.
-			walkexpr(&n->right->left, init);
-			n1 = nod(OADDR, n->left, N);
-			r = n->right; // i.(T)
-
-			from = "I";
-			to = "T";
-			if(isnilinter(r->left->type))
-				from = "E";
-			if(isnilinter(r->type))
-				to = "E";
-			else if(isinter(r->type))
-				to = "I";
-			
-			snprint(buf, sizeof buf, "assert%s2%s", from, to);
-
-			fn = syslook(buf, 1);
-			argtype(fn, r->left->type);
-			argtype(fn, r->type);
-		
-			n = mkcall1(fn, T, init, typename(r->type), r->left, n1);
-			walkexpr(&n, init);
-			goto ret;
-
-		case ORECV:
-			// x = <-c; n->left is x, n->right->left is c.
-			// orderstmt made sure x is addressable.
-			walkexpr(&n->right->left, init);
-			n1 = nod(OADDR, n->left, 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.go: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;
-		fn = mapfn(p, t);
-		r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
-
-		// mapaccess2* returns a typed bool, but due to spec changes,
-		// the boolean result of i.(T) is now untyped so we make it the
-		// same type as the variable on the lhs.
-		if(!isblank(n->list->next->n))
-			r->type->type->down->type = n->list->next->n->type;
-		n->rlist = list1(r);
-		n->op = OAS2FUNC;
-
-		// don't generate a = *var if a is _
-		if(!isblank(a)) {
-			var = temp(ptrto(t->type));
-			var->typecheck = 1;
-			n->list->n = var;
-			walkexpr(&n, init);
-			*init = list(*init, n);
-			n = nod(OAS, a, nod(OIND, var, 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)
-		// orderstmt made sure a 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
-
-		from = "I";
-		to = "T";
-		if(isnilinter(r->left->type))
-			from = "E";
-		if(isnilinter(r->type))
-			to = "E";
-		else if(isinter(r->type))
-			to = "I";
-		snprint(buf, sizeof buf, "assert%s2%s2", from, to);
-		
-		fn = syslook(buf, 1);
-		argtype(fn, r->left->type);
-		argtype(fn, r->type);
-		
-		t = types[TBOOL];
-		ok = n->list->next->n;
-		if(!isblank(ok))
-			t = ok->type;
-		r = mkcall1(fn, t, init, typename(r->type), r->left, n1);
-		n = nod(OAS, ok, r);
-		typecheck(&n, Etop);
-		goto ret;
-
-	case ODOTTYPE:
-	case ODOTTYPE2:
-		fatal("walkexpr ODOTTYPE"); // should see inside OAS or OAS2 only
-
-	case OCONVIFACE:
-		walkexpr(&n->left, init);
-
-		// Optimize convT2E as a two-word copy when T is pointer-shaped.
-		if(isnilinter(n->type) && isdirectiface(n->left->type)) {
-			l = nod(OEFACE, typename(n->left->type), n->left);
-			l->type = n->type;
-			l->typecheck = n->typecheck;
-			n = l;
-			goto ret;
-		}
-
-		// Build name of function: convI2E etc.
-		// Not all names are possible
-		// (e.g., we'll never generate convE2E or convE2I).
-		from = "T";
-		to = "I";
-		if(isnilinter(n->left->type))
-			from = "E";
-		else if(isinter(n->left->type))
-			from = "I";
-		if(isnilinter(n->type))
-			to = "E";
-		snprint(buf, sizeof buf, "conv%s2%s", from, to);
-
-		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)) {
-				/* 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(thearch.thechar == '5') {
-			if(isfloat[n->left->type->etype]) {
-				if(n->type->etype == TINT64) {
-					n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
-					goto ret;
-				}
-				if(n->type->etype == TUINT64) {
-					n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
-					goto ret;
-				}
-			}
-			if(isfloat[n->type->etype]) {
-				if(n->left->type->etype == TINT64) {
-					n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
-					goto ret;
-				}
-				if(n->left->type->etype == TUINT64) {
-					n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
-					goto ret;
-				}
-			}
-		}
-		walkexpr(&n->left, init);
-		goto ret;
-
-	case OANDNOT:
-		walkexpr(&n->left, init);
-		n->op = OAND;
-		n->right = nod(OCOM, n->right, 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.go: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 !=
-			// eqstring assumes that the lengths are equal
-			if(n->etype == OEQ) {
-				// len(left) == len(right) && eqstring(left, right)
-				r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, 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);
-
-		a = nodnil(); // hmap buffer
-		r = nodnil(); // bucket buffer
-		if(n->esc == EscNone) {
-			// Allocate hmap buffer on stack.
-			var = temp(hmap(t));
-			a = nod(OAS, var, N); // zero temp
-			typecheck(&a, Etop);
-			*init = list(*init, a);
-			a = nod(OADDR, var, N);
-
-			// Allocate one bucket on stack.
-			// Maximum key/value size is 128 bytes, larger objects
-			// are stored with an indirection. So max bucket size is 2048+eps.
-			var = temp(mapbucket(t));
-			r = nod(OAS, var, N); // zero temp
-			typecheck(&r, Etop);
-			*init = list(*init, r);
-			r = nod(OADDR, var, N);
-		}
-
-		argtype(fn, hmap(t));	// hmap buffer
-		argtype(fn, mapbucket(t));	// bucket buffer
-		argtype(fn, t->down);	// key type
-		argtype(fn, t->type);	// value type
-		n = mkcall1(fn, n->type, init, typename(n->type), conv(n->left, types[TINT64]), a, r);
-		goto ret;
-
-	case OMAKESLICE:
-		l = n->left;
-		r = n->right;
-		if(r == nil)
-			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:
-		a = nodnil();
-		if(n->esc == EscNone) {
-			t = aindex(nodintconst(4), types[TUINT8]);
-			var = temp(t);
-			a = nod(OADDR, var, N);
-		}
-		// intstring(*[4]byte, rune)
-		n = mkcall("intstring", n->type, init, a, conv(n->left, types[TINT64]));
-		goto ret;
-
-	case OARRAYBYTESTR:
-		a = nodnil();
-		if(n->esc == EscNone) {
-			// Create temporary buffer for string on stack.
-			t = aindex(nodintconst(tmpstringbufsize), types[TUINT8]);
-			a = nod(OADDR, temp(t), N);
-		}
-		// slicebytetostring(*[32]byte, []byte) string;
-		n = mkcall("slicebytetostring", n->type, init, a, n->left);
-		goto ret;
-
-	case OARRAYBYTESTRTMP:
-		// slicebytetostringtmp([]byte) string;
-		n = mkcall("slicebytetostringtmp", n->type, init, n->left);
-		goto ret;
-
-	case OARRAYRUNESTR:
-		// slicerunetostring(*[32]byte, []rune) string;
-		a = nodnil();
-		if(n->esc == EscNone) {
-			// Create temporary buffer for string on stack.
-			t = aindex(nodintconst(tmpstringbufsize), types[TUINT8]);
-			a = nod(OADDR, temp(t), N);
-		}
-		n = mkcall("slicerunetostring", n->type, init, a, n->left);
-		goto ret;
-
-	case OSTRARRAYBYTE:
-		// stringtoslicebyte(*32[byte], string) []byte;
-		a = nodnil();
-		if(n->esc == EscNone) {
-			// Create temporary buffer for slice on stack.
-			t = aindex(nodintconst(tmpstringbufsize), types[TUINT8]);
-			a = nod(OADDR, temp(t), N);
-		}
-		n = mkcall("stringtoslicebyte", n->type, init, a, conv(n->left, types[TSTRING]));
-		goto ret;
-
-	case OSTRARRAYBYTETMP:
-		// stringtoslicebytetmp(string) []byte;
-		n = mkcall("stringtoslicebytetmp", n->type, init, conv(n->left, types[TSTRING]));
-		goto ret;
-
-	case OSTRARRAYRUNE:
-		// stringtoslicerune(*[32]rune, string) []rune
-		a = nodnil();
-		if(n->esc == EscNone) {
-			// Create temporary buffer for slice on stack.
-			t = aindex(nodintconst(tmpstringbufsize), types[TINT32]);
-			a = nod(OADDR, temp(t), N);
-		}
-		n = mkcall("stringtoslicerune", n->type, init, a, 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;
-
-	op = nn->op;
-	all = nn->list;
-	calls = nil;
-	notfirst = 0;
-
-	// Hoist all the argument evaluation up before the lock.
-	walkexprlistcheap(all, init);
-
-	calls = list(calls, mkcall("printlock", T, init));
-
-	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));
-
-	calls = list(calls, mkcall("printunlock", T, init));
-
-	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)
-{
-	Node *defn;
-
-	n = outervalue(n);
-
-	// If n is *autotmp and autotmp = &foo, replace n with foo.
-	// We introduce such temps when initializing struct literals.
-	if(n->op == OIND && n->left->op == ONAME && strncmp(n->left->sym->name, "autotmp_", 8) == 0) {
-		defn = n->left->defn;
-		if(defn != N && defn->op == OAS && defn->right->op == OADDR)
-			n = defn->right->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)
-{
-	n = outervalue(n);
-
-	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;
-	vlong x;
-	static Bvec *bv;
-	char name[32];
-
-	if(n->left && n->right && needwritebarrier(n->left, n->right)) {
-		if(curfn && curfn->nowritebarrier)
-			yyerror("write barrier prohibited");
-		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 <= 4*widthptr) {
-			x = 0;
-			if(bv == nil)
-				bv = bvalloc(BitsPerPointer*4);
-			bvresetall(bv);
-			twobitwalktype1(t, &x, bv);
-			// The bvgets are looking for BitsPointer in successive slots.
-			enum {
-				PtrBit = 1,
-			};
-			if(BitsPointer != (1<<PtrBit))
-				fatal("wrong PtrBit");
-			switch(t->width/widthptr) {
-			default:
-				fatal("found writebarrierfat for %d-byte object of type %T", (int)t->width, t);
-			case 2:
-				snprint(name, sizeof name, "writebarrierfat%d%d",
-					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit));
-				break;
-			case 3:
-				snprint(name, sizeof name, "writebarrierfat%d%d%d",
-					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit));
-				break;
-			case 4:
-				snprint(name, sizeof name, "writebarrierfat%d%d%d%d",
-					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit), bvget(bv, 3*BitsPerPointer+PtrBit));
-				break;
-			}
-			n = mkcall1(writebarrierfn(name, 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, "typedmemmove %T %N", t, r);
-			n = mkcall1(writebarrierfn("typedmemmove", 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 == OXDOT)
-			fatal("OXDOT in walk");
-		if(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP) {
-			n = n->left;
-			continue;
-		}
-		if(n->op == OINDEX && isfixedarray(n->left->type)) {
-			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, *as;
-	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;
-		// For precise stacks, the garbage collector assumes results
-		// are always live, so zero them always.
-		if(out) {
-			// 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) {
-			as = nod(OAS, v, v->stackparam);
-			v->stackparam->typecheck = 1;
-			typecheck(&as, Etop);
-			as = applywritebarrier(as, &nn);
-			nn = list(nn, as);
-		}
-	}
-	return nn;
-}
-
-/*
- * walk through argout parameters copying back to stack
- */
-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, *buf;
-	NodeList *args, *l;
-	int c;
-	vlong sz;
-	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);
-
-	buf = nodnil();
-	if(n->esc == EscNone) {
-		sz = 0;
-		for(l=n->list; l != nil; l=l->next) {
-			if(n->op == OLITERAL)
-				sz += n->val.u.sval->len;
-		}
-		// Don't allocate the buffer if the result won't fit.
-		if(sz < tmpstringbufsize) {
-			// Create temporary buffer for result string on stack.
-			t = aindex(nodintconst(tmpstringbufsize), types[TUINT8]);
-			buf = nod(OADDR, temp(t), N);
-		}
-	}
-
-	// build list of string arguments
-	args = list1(buf);
-	for(l=n->list; l != nil; l=l->next)
-		args = list(args, conv(l->n, types[TSTRING]));
-
-	if(c <= 5) {
-		// small numbers of strings use direct runtime helpers.
-		// note: orderexpr knows this cutoff too.
-		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->next; // skip buf arg
-		args = list1(buf);
-		args = list(args, slice);
-		slice->esc = EscNone;
-	}
-	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(haspointers(l1->type->type)) {
-		// 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;
-		fn = syslook("typedslicecopy", 1);
-		argtype(fn, l1->type);
-		argtype(fn, l2->type);
-		nt = mkcall1(fn, types[TINT], &l,
-				typename(l1->type->type),
-				nptr1, nptr2);
-		l = list(l, nt);
-	} else if(flag_race) {
-		// 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(haspointers(n->left->type->type)) {
-		fn = writebarrierfn("typedslicecopy", n->left->type, n->right->type);
-		return mkcall1(fn, n->type, init, typename(n->left->type->type), n->left, n->right);
-	}
-
-	if(runtimecall) {
-		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 *needsize)
-{
-	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);
-		*needsize = 1;
-		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->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL])));
-	typecheck(&ntype, Etype);
-	n->type = ntype->type;
-	*needsize = 0;
-	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;
-	Node *x, *ok;
-	int andor, i, needsize;
-	Type *t, *t1;
-	
-	n = *np;
-
-	// Given interface value l and concrete value r, rewrite
-	//   l == r
-	// to
-	//   x, ok := l.(type(r)); ok && x == r
-	// Handle != similarly.
-	// This avoids the allocation that would be required
-	// to convert r to l for comparison.
-	l = N;
-	r = N;
-	if(isinter(n->left->type) && !isinter(n->right->type)) {
-		l = n->left;
-		r = n->right;
-	} else if(!isinter(n->left->type) && isinter(n->right->type)) {
-		l = n->right;
-		r = n->left;
-	}
-	if(l != N) {
-		x = temp(r->type);
-		ok = temp(types[TBOOL]);
-
-		// l.(type(r))
-		a = nod(ODOTTYPE, l, N);
-		a->type = r->type;
-
-		// x, ok := l.(type(r))
-		expr = nod(OAS2, N, N);
-		expr->list = list1(x);
-		expr->list = list(expr->list, ok);
-		expr->rlist = list1(a);
-		typecheck(&expr, Etop);
-		walkexpr(&expr, init);
-
-		if(n->op == OEQ)
-			r = nod(OANDAND, ok, nod(OEQ, x, r));
-		else
-			r = nod(OOROR, nod(ONOT, ok, N), nod(ONE, x, r));
-		*init = list(*init, expr);
-		goto ret;
-	}
-	
-	// Must be comparison of array or struct.
-	// Otherwise back end handles it.
-	t = n->left->type;
-	switch(t->etype) {
-	default:
-		return;
-	case TARRAY:
-		if(isslice(t))
-			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, &needsize), N);
-	call->list = list(call->list, l);
-	call->list = list(call->list, r);
-	if(needsize)
-		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;
-
-	if(thearch.thechar == '9')
-		return;
-	
-	n = *np;
-
-	// Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
-	l = n->left;
-	r = n->right;
-	if((n->op != OOR && n->op != OXOR) ||
-	   (l->op != OLSH && l->op != ORSH) ||
-	   (r->op != OLSH && r->op != ORSH) ||
-	   n->type == 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;
-
-	// TODO(minux)
-	if(thearch.thechar == '9')
-		return;
-
-	n = *np;
-	if(n->right->op != OLITERAL)
-		return;
-	// nr is a constant.
-	nl = cheapexpr(n->left, init);
-	nr = n->right;
-
-	// special cases of mod/div
-	// by a constant
-	w = 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
deleted file mode 100644
index d45623a..0000000
--- a/src/cmd/gc/y.tab.c
+++ /dev/null
@@ -1,5134 +0,0 @@
-/* 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,  1327,  1356,  1394,  1419,
-    1437,  1446,  1449,  1457,  1461,  1465,  1472,  1478,  1483,  1495,
-    1498,  1510,  1511,  1517,  1518,  1524,  1528,  1534,  1535,  1541,
-    1545,  1551,  1574,  1579,  1585,  1591,  1598,  1607,  1616,  1631,
-    1637,  1642,  1646,  1653,  1666,  1667,  1673,  1679,  1682,  1686,
-    1692,  1695,  1704,  1707,  1708,  1712,  1713,  1719,  1720,  1721,
-    1722,  1723,  1725,  1724,  1739,  1745,  1749,  1753,  1757,  1761,
-    1766,  1785,  1791,  1799,  1803,  1809,  1813,  1819,  1823,  1829,
-    1833,  1842,  1846,  1850,  1854,  1860,  1863,  1871,  1872,  1874,
-    1875,  1878,  1881,  1884,  1887,  1890,  1893,  1896,  1899,  1902,
-    1905,  1908,  1911,  1914,  1917,  1923,  1927,  1931,  1935,  1939,
-    1943,  1963,  1970,  1981,  1982,  1983,  1986,  1987,  1990,  1994,
-    2004,  2008,  2012,  2016,  2020,  2024,  2028,  2034,  2040,  2048,
-    2056,  2062,  2069,  2085,  2107,  2111,  2117,  2120,  2123,  2127,
-    2137,  2141,  2160,  2168,  2169,  2181,  2182,  2185,  2189,  2195,
-    2199,  2205,  2209
-};
-#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;
-		(yyval.node)->nowritebarrier = nowritebarrier;
-		funcbody((yyval.node));
-	}
-    break;
-
-  case 206:
-#line 1328 "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 1357 "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 1395 "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 1420 "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 1438 "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 1446 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 212:
-#line 1450 "go.y"
-    {
-		(yyval.list) = (yyvsp[(2) - (3)].list);
-		if((yyval.list) == nil)
-			(yyval.list) = list1(nod(OEMPTY, N, N));
-	}
-    break;
-
-  case 213:
-#line 1458 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 214:
-#line 1462 "go.y"
-    {
-		(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
-	}
-    break;
-
-  case 215:
-#line 1466 "go.y"
-    {
-		(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
-		(yyval.list) = (yyvsp[(2) - (3)].list);
-	}
-    break;
-
-  case 216:
-#line 1473 "go.y"
-    {
-		closurehdr((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 217:
-#line 1479 "go.y"
-    {
-		(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
-		fixlbrace((yyvsp[(2) - (4)].i));
-	}
-    break;
-
-  case 218:
-#line 1484 "go.y"
-    {
-		(yyval.node) = closurebody(nil);
-	}
-    break;
-
-  case 219:
-#line 1495 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 220:
-#line 1499 "go.y"
-    {
-		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
-		if(nsyntaxerrors == 0)
-			testdclstack();
-		nointerface = 0;
-		noescape = 0;
-		nosplit = 0;
-		nowritebarrier = 0;
-	}
-    break;
-
-  case 222:
-#line 1512 "go.y"
-    {
-		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
-	}
-    break;
-
-  case 224:
-#line 1519 "go.y"
-    {
-		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
-	}
-    break;
-
-  case 225:
-#line 1525 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 226:
-#line 1529 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 228:
-#line 1536 "go.y"
-    {
-		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
-	}
-    break;
-
-  case 229:
-#line 1542 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 230:
-#line 1546 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 231:
-#line 1552 "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 1575 "go.y"
-    {
-		(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
-		(yyval.list) = list1((yyvsp[(1) - (2)].node));
-	}
-    break;
-
-  case 233:
-#line 1580 "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 1586 "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 1592 "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 1599 "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 1608 "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 1617 "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 1632 "go.y"
-    {
-		(yyval.node) = embedded((yyvsp[(1) - (1)].sym), localpkg);
-	}
-    break;
-
-  case 240:
-#line 1638 "go.y"
-    {
-		(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
-		ifacedcl((yyval.node));
-	}
-    break;
-
-  case 241:
-#line 1643 "go.y"
-    {
-		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
-	}
-    break;
-
-  case 242:
-#line 1647 "go.y"
-    {
-		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
-		yyerror("cannot parenthesize embedded type");
-	}
-    break;
-
-  case 243:
-#line 1654 "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 1668 "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 1674 "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 1683 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 249:
-#line 1687 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 250:
-#line 1692 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 251:
-#line 1696 "go.y"
-    {
-		(yyval.list) = (yyvsp[(1) - (2)].list);
-	}
-    break;
-
-  case 252:
-#line 1704 "go.y"
-    {
-		(yyval.node) = N;
-	}
-    break;
-
-  case 254:
-#line 1709 "go.y"
-    {
-		(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
-	}
-    break;
-
-  case 256:
-#line 1714 "go.y"
-    {
-		(yyval.node) = N;
-	}
-    break;
-
-  case 262:
-#line 1725 "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 1730 "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 1740 "go.y"
-    {
-		// will be converted to OFALL
-		(yyval.node) = nod(OXFALL, N, N);
-		(yyval.node)->xoffset = block;
-	}
-    break;
-
-  case 265:
-#line 1746 "go.y"
-    {
-		(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
-	}
-    break;
-
-  case 266:
-#line 1750 "go.y"
-    {
-		(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
-	}
-    break;
-
-  case 267:
-#line 1754 "go.y"
-    {
-		(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
-	}
-    break;
-
-  case 268:
-#line 1758 "go.y"
-    {
-		(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
-	}
-    break;
-
-  case 269:
-#line 1762 "go.y"
-    {
-		(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
-		(yyval.node)->sym = dclstack;  // context, for goto restrictions
-	}
-    break;
-
-  case 270:
-#line 1767 "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 1786 "go.y"
-    {
-		(yyval.list) = nil;
-		if((yyvsp[(1) - (1)].node) != N)
-			(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 272:
-#line 1792 "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 1800 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 274:
-#line 1804 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 275:
-#line 1810 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 276:
-#line 1814 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 277:
-#line 1820 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 278:
-#line 1824 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 279:
-#line 1830 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 280:
-#line 1834 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 281:
-#line 1843 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 282:
-#line 1847 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 283:
-#line 1851 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 284:
-#line 1855 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 285:
-#line 1860 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 286:
-#line 1864 "go.y"
-    {
-		(yyval.list) = (yyvsp[(1) - (2)].list);
-	}
-    break;
-
-  case 291:
-#line 1878 "go.y"
-    {
-		(yyval.node) = N;
-	}
-    break;
-
-  case 293:
-#line 1884 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 295:
-#line 1890 "go.y"
-    {
-		(yyval.node) = N;
-	}
-    break;
-
-  case 297:
-#line 1896 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 299:
-#line 1902 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 301:
-#line 1908 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 303:
-#line 1914 "go.y"
-    {
-		(yyval.val).ctype = CTxxx;
-	}
-    break;
-
-  case 305:
-#line 1924 "go.y"
-    {
-		importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
-	}
-    break;
-
-  case 306:
-#line 1928 "go.y"
-    {
-		importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
-	}
-    break;
-
-  case 307:
-#line 1932 "go.y"
-    {
-		importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
-	}
-    break;
-
-  case 308:
-#line 1936 "go.y"
-    {
-		importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
-	}
-    break;
-
-  case 309:
-#line 1940 "go.y"
-    {
-		importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
-	}
-    break;
-
-  case 310:
-#line 1944 "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 1964 "go.y"
-    {
-		(yyval.sym) = (yyvsp[(1) - (1)].sym);
-		structpkg = (yyval.sym)->pkg;
-	}
-    break;
-
-  case 312:
-#line 1971 "go.y"
-    {
-		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
-		importsym((yyvsp[(1) - (1)].sym), OTYPE);
-	}
-    break;
-
-  case 318:
-#line 1991 "go.y"
-    {
-		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
-	}
-    break;
-
-  case 319:
-#line 1995 "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 2005 "go.y"
-    {
-		(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
-	}
-    break;
-
-  case 321:
-#line 2009 "go.y"
-    {
-		(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
-	}
-    break;
-
-  case 322:
-#line 2013 "go.y"
-    {
-		(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
-	}
-    break;
-
-  case 323:
-#line 2017 "go.y"
-    {
-		(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
-	}
-    break;
-
-  case 324:
-#line 2021 "go.y"
-    {
-		(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
-	}
-    break;
-
-  case 325:
-#line 2025 "go.y"
-    {
-		(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
-	}
-    break;
-
-  case 326:
-#line 2029 "go.y"
-    {
-		(yyval.type) = typ(TCHAN);
-		(yyval.type)->type = (yyvsp[(2) - (2)].type);
-		(yyval.type)->chan = Cboth;
-	}
-    break;
-
-  case 327:
-#line 2035 "go.y"
-    {
-		(yyval.type) = typ(TCHAN);
-		(yyval.type)->type = (yyvsp[(3) - (4)].type);
-		(yyval.type)->chan = Cboth;
-	}
-    break;
-
-  case 328:
-#line 2041 "go.y"
-    {
-		(yyval.type) = typ(TCHAN);
-		(yyval.type)->type = (yyvsp[(3) - (3)].type);
-		(yyval.type)->chan = Csend;
-	}
-    break;
-
-  case 329:
-#line 2049 "go.y"
-    {
-		(yyval.type) = typ(TCHAN);
-		(yyval.type)->type = (yyvsp[(3) - (3)].type);
-		(yyval.type)->chan = Crecv;
-	}
-    break;
-
-  case 330:
-#line 2057 "go.y"
-    {
-		(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
-	}
-    break;
-
-  case 331:
-#line 2063 "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 2070 "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 2086 "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 2108 "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 2112 "go.y"
-    {
-		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
-	}
-    break;
-
-  case 336:
-#line 2117 "go.y"
-    {
-		(yyval.list) = nil;
-	}
-    break;
-
-  case 338:
-#line 2124 "go.y"
-    {
-		(yyval.list) = (yyvsp[(2) - (3)].list);
-	}
-    break;
-
-  case 339:
-#line 2128 "go.y"
-    {
-		(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
-	}
-    break;
-
-  case 340:
-#line 2138 "go.y"
-    {
-		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
-	}
-    break;
-
-  case 341:
-#line 2142 "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 2161 "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 2170 "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 2186 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 348:
-#line 2190 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 349:
-#line 2196 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 350:
-#line 2200 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-  case 351:
-#line 2206 "go.y"
-    {
-		(yyval.list) = list1((yyvsp[(1) - (1)].node));
-	}
-    break;
-
-  case 352:
-#line 2210 "go.y"
-    {
-		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
-	}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 4909 "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 2214 "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
deleted file mode 100644
index d01fbe1..0000000
--- a/src/cmd/gc/y.tab.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* 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
deleted file mode 100644
index d0dd639..0000000
--- a/src/cmd/gc/yerr.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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"}
-};
diff --git a/src/cmd/new5a/a.y b/src/cmd/new5a/a.y
deleted file mode 100644
index 39fab8f..0000000
--- a/src/cmd/new5a/a.y
+++ /dev/null
@@ -1,795 +0,0 @@
-// Inferno utils/5a/a.y
-// http://code.google.com/p/inferno-os/source/browse/utils/5a/a.y
-//
-//	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.
-
-%{
-package main
-
-import (
-	"cmd/internal/asm"
-	"cmd/internal/obj"
-	. "cmd/internal/obj/arm"
-)
-%}
-
-%union {
-	sym *asm.Sym
-	lval int32
-	dval float64
-	sval string
-	addr obj.Addr
-}
-
-%left	'|'
-%left	'^'
-%left	'&'
-%left	'<' '>'
-%left	'+' '-'
-%left	'*' '/' '%'
-%token	<lval>	LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
-%token	<lval>	LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
-%token	<lval>	LTYPEB LTYPEC LTYPED LTYPEE
-%token	<lval>	LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
-%token	<lval>	LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
-%token	<lval>	LCONST LSP LSB LFP LPC
-%token	<lval>	LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
-%token	<lval>	LCOND LS LAT LGLOBL
-%token	<dval>	LFCONST
-%token	<sval>	LSCONST
-%token	<sym>	LNAME LLAB LVAR
-%type	<lval>	con expr oexpr pointer offset sreg spreg creg
-%type	<lval>	rcon cond reglist
-%type	<addr>	gen rel reg regreg freg shift fcon frcon textsize
-%type	<addr>	imm ximm name oreg ireg nireg ioreg imsr
-%%
-prog:
-|	prog
-	{
-		stmtline = asm.Lineno;
-	}
-	line
-
-line:
-	LNAME ':'
-	{
-		$1 = asm.LabelLookup($1);
-		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
-			yyerror("redeclaration of %s", $1.Labelname)
-		}
-		$1.Type = LLAB;
-		$1.Value = int64(asm.PC)
-	}
-	line
-|	LNAME '=' expr ';'
-	{
-		$1.Type = LVAR;
-		$1.Value = int64($3);
-	}
-|	LVAR '=' expr ';'
-	{
-		if $1.Value != int64($3) {
-			yyerror("redeclaration of %s", $1.Name)
-		}
-		$1.Value = int64($3);
-	}
-|	';'
-|	inst ';'
-|	error ';'
-
-inst:
-/*
- * ADD
- */
-	LTYPE1 cond imsr ',' spreg ',' reg
-	{
-		outcode($1, $2, &$3, $5, &$7);
-	}
-|	LTYPE1 cond imsr ',' spreg ','
-	{
-		outcode($1, $2, &$3, $5, &nullgen);
-	}
-|	LTYPE1 cond imsr ',' reg
-	{
-		outcode($1, $2, &$3, 0, &$5);
-	}
-/*
- * MVN
- */
-|	LTYPE2 cond imsr ',' reg
-	{
-		outcode($1, $2, &$3, 0, &$5);
-	}
-/*
- * MOVW
- */
-|	LTYPE3 cond gen ',' gen
-	{
-		outcode($1, $2, &$3, 0, &$5);
-	}
-/*
- * B/BL
- */
-|	LTYPE4 cond comma rel
-	{
-		outcode($1, $2, &nullgen, 0, &$4);
-	}
-|	LTYPE4 cond comma nireg
-	{
-		outcode($1, $2, &nullgen, 0, &$4);
-	}
-/*
- * BX
- */
-|	LTYPEBX comma ireg
-	{
-		outcode($1, Always, &nullgen, 0, &$3);
-	}
-/*
- * BEQ
- */
-|	LTYPE5 comma rel
-	{
-		outcode($1, Always, &nullgen, 0, &$3);
-	}
-/*
- * SWI
- */
-|	LTYPE6 cond comma gen
-	{
-		outcode($1, $2, &nullgen, 0, &$4);
-	}
-/*
- * CMP
- */
-|	LTYPE7 cond imsr ',' spreg comma
-	{
-		outcode($1, $2, &$3, $5, &nullgen);
-	}
-/*
- * MOVM
- */
-|	LTYPE8 cond ioreg ',' '[' reglist ']'
-	{
-		var g obj.Addr
-
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = int64($6);
-		outcode($1, $2, &$3, 0, &g);
-	}
-|	LTYPE8 cond '[' reglist ']' ',' ioreg
-	{
-		var g obj.Addr
-
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = int64($4);
-		outcode($1, $2, &g, 0, &$7);
-	}
-/*
- * SWAP
- */
-|	LTYPE9 cond reg ',' ireg ',' reg
-	{
-		outcode($1, $2, &$5, int32($3.Reg), &$7);
-	}
-|	LTYPE9 cond reg ',' ireg comma
-	{
-		outcode($1, $2, &$5, int32($3.Reg), &$3);
-	}
-|	LTYPE9 cond comma ireg ',' reg
-	{
-		outcode($1, $2, &$4, int32($6.Reg), &$6);
-	}
-/*
- * RET
- */
-|	LTYPEA cond comma
-	{
-		outcode($1, $2, &nullgen, 0, &nullgen);
-	}
-/*
- * TEXT
- */
-|	LTYPEB name ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode($1, Always, &$2, 0, &$5);
-	}
-|	LTYPEB name ',' con ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode($1, Always, &$2, 0, &$7);
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST;
-			lastpc.From3.Offset = int64($4)
-		}
-	}
-/*
- * GLOBL
- */
-|	LGLOBL name ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode($1, Always, &$2, 0, &$4)
-	}
-|	LGLOBL name ',' con ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode($1, Always, &$2, 0, &$6)
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = int64($4)
-		}
-	}
-
-/*
- * DATA
- */
-|	LTYPEC name '/' con ',' ximm
-	{
-		outcode($1, Always, &$2, 0, &$6)
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = int64($4)
-		}
-	}
-/*
- * CASE
- */
-|	LTYPED cond reg comma
-	{
-		outcode($1, $2, &$3, 0, &nullgen);
-	}
-/*
- * word
- */
-|	LTYPEH comma ximm
-	{
-		outcode($1, Always, &nullgen, 0, &$3);
-	}
-/*
- * floating-point coprocessor
- */
-|	LTYPEI cond freg ',' freg
-	{
-		outcode($1, $2, &$3, 0, &$5);
-	}
-|	LTYPEK cond frcon ',' freg
-	{
-		outcode($1, $2, &$3, 0, &$5);
-	}
-|	LTYPEK cond frcon ',' LFREG ',' freg
-	{
-		outcode($1, $2, &$3, $5, &$7);
-	}
-|	LTYPEL cond freg ',' freg comma
-	{
-		outcode($1, $2, &$3, int32($5.Reg), &nullgen);
-	}
-/*
- * MCR MRC
- */
-|	LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
-	{
-		var g obj.Addr
-
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = int64(
-			(0xe << 24) |		/* opcode */
-			($1 << 20) |		/* MCR/MRC */
-			(($2^C_SCOND_XOR) << 28) |		/* scond */
-			(($3 & 15) << 8) |	/* coprocessor number */
-			(($5 & 7) << 21) |	/* coprocessor operation */
-			(($7 & 15) << 12) |	/* arm register */
-			(($9 & 15) << 16) |	/* Crn */
-			(($11 & 15) << 0) |	/* Crm */
-			(($12 & 7) << 5) |	/* coprocessor information */
-			(1<<4));			/* must be set */
-		outcode(AMRC, Always, &nullgen, 0, &g);
-	}
-/*
- * MULL r1,r2,(hi,lo)
- */
-|	LTYPEM cond reg ',' reg ',' regreg
-	{
-		outcode($1, $2, &$3, int32($5.Reg), &$7);
-	}
-/*
- * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff . r4
- * MULAW{T,B} r1,r2,r3,r4
- */
-|	LTYPEN cond reg ',' reg ',' reg ',' spreg
-	{
-		$7.Type = obj.TYPE_REGREG2;
-		$7.Offset = int64($9);
-		outcode($1, $2, &$3, int32($5.Reg), &$7);
-	}
-/*
- * PLD
- */
-|	LTYPEPLD oreg
-	{
-		outcode($1, Always, &$2, 0, &nullgen);
-	}
-/*
- * PCDATA
- */
-|	LTYPEPC gen ',' gen
-	{
-		if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
-			yyerror("arguments to PCDATA must be integer constants")
-		}
-		outcode($1, Always, &$2, 0, &$4);
-	}
-/*
- * FUNCDATA
- */
-|	LTYPEF gen ',' gen
-	{
-		if $2.Type != obj.TYPE_CONST {
-			yyerror("index for FUNCDATA must be integer constant")
-		}
-		if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
-			yyerror("value for FUNCDATA must be symbol reference")
-		}
- 		outcode($1, Always, &$2, 0, &$4);
-	}
-/*
- * END
- */
-|	LTYPEE comma
-	{
-		outcode($1, Always, &nullgen, 0, &nullgen);
-	}
-
-textsize:
-	LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = int64($1)
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	'-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -int64($2)
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = int64($1)
-		$$.U.Argsize = int32($3);
-	}
-|	'-' LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -int64($2)
-		$$.U.Argsize = int32($4);
-	}
-
-cond:
-	{
-		$$ = Always;
-	}
-|	cond LCOND
-	{
-		$$ = ($1 & ^ C_SCOND) | $2;
-	}
-|	cond LS
-	{
-		$$ = $1 | $2;
-	}
-
-comma:
-|	',' comma
-
-rel:
-	con '(' LPC ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = int64($1) + int64(asm.PC);
-	}
-|	LNAME offset
-	{
-		$1 = asm.LabelLookup($1);
-		$$ = nullgen;
-		if asm.Pass == 2 && $1.Type != LLAB {
-			yyerror("undefined label: %s", $1.Labelname)
-		}
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1.Value + int64($2);
-	}
-
-ximm:	'$' con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		$$.Offset = int64($2);
-	}
-|	'$' oreg
-	{
-		$$ = $2;
-		$$.Type = obj.TYPE_ADDR;
-	}
-|	'$' LSCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SCONST;
-		$$.U.Sval = $2
-	}
-|	fcon
-
-fcon:
-	'$' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $2;
-	}
-|	'$' '-' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$3;
-	}
-
-reglist:
-	spreg
-	{
-		$$ = 1 << uint($1&15);
-	}
-|	spreg '-' spreg
-	{
-		$$=0;
-		for i:=$1; i<=$3; i++ {
-			$$ |= 1<<uint(i&15)
-		}
-		for i:=$3; i<=$1; i++ {
-			$$ |= 1<<uint(i&15)
-		}
-	}
-|	spreg comma reglist
-	{
-		$$ = (1<<uint($1&15)) | $3;
-	}
-
-gen:
-	reg
-|	ximm
-|	shift
-|	shift '(' spreg ')'
-	{
-		$$ = $1;
-		$$.Reg = int16($3);
-	}
-|	LPSR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LFCR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Offset = int64($1);
-	}
-|	oreg
-|	freg
-
-nireg:
-	ireg
-|	name
-	{
-		$$ = $1;
-		if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
-		}
-	}
-
-ireg:
-	'(' spreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($2);
-		$$.Offset = 0;
-	}
-
-ioreg:
-	ireg
-|	con '(' sreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($3);
-		$$.Offset = int64($1);
-	}
-
-oreg:
-	name
-|	name '(' sreg ')'
-	{
-		$$ = $1;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($3);
-	}
-|	ioreg
-
-imsr:
-	reg
-|	imm
-|	shift
-
-imm:	'$' con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		$$.Offset = int64($2);
-	}
-
-reg:
-	spreg
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-regreg:
-	'(' spreg ',' spreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REGREG;
-		$$.Reg = int16($2);
-		$$.Offset = int64($4);
-	}
-
-shift:
-	spreg '<' '<' rcon
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SHIFT;
-		$$.Offset = int64($1&15) | int64($4) | (0 << 5);
-	}
-|	spreg '>' '>' rcon
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SHIFT;
-		$$.Offset = int64($1&15) | int64($4) | (1 << 5);
-	}
-|	spreg '-' '>' rcon
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SHIFT;
-		$$.Offset = int64($1&15) | int64($4) | (2 << 5);
-	}
-|	spreg LAT '>' rcon
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SHIFT;
-		$$.Offset = int64($1&15) | int64($4) | (3 << 5);
-	}
-
-rcon:
-	spreg
-	{
-		if $$ < REG_R0 || $$ > REG_R15 {
-			print("register value out of range\n")
-		}
-		$$ = (($1&15) << 8) | (1 << 4);
-	}
-|	con
-	{
-		if $$ < 0 || $$ >= 32 {
-			print("shift value out of range\n")
-		}
-		$$ = ($1&31) << 7;
-	}
-
-sreg:
-	LREG
-|	LPC
-	{
-		$$ = REGPC;
-	}
-|	LR '(' expr ')'
-	{
-		if $3 < 0 || $3 >= NREG {
-			print("register value out of range\n")
-		}
-		$$ = REG_R0 + $3;
-	}
-
-spreg:
-	sreg
-|	LSP
-	{
-		$$ = REGSP;
-	}
-
-creg:
-	LCREG
-|	LC '(' expr ')'
-	{
-		if $3 < 0 || $3 >= NREG {
-			print("register value out of range\n")
-		}
-		$$ = $3; // TODO(rsc): REG_C0+$3
-	}
-
-frcon:
-	freg
-|	fcon
-
-freg:
-	LFREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-|	LF '(' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16(REG_F0 + $3);
-	}
-
-name:
-	con '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = int8($3);
-		$$.Sym = nil;
-		$$.Offset = int64($1);
-	}
-|	LNAME offset '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = int8($4);
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
-		$$.Offset = int64($2);
-	}
-|	LNAME '<' '>' offset '(' LSB ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = obj.NAME_STATIC;
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
-		$$.Offset = int64($4);
-	}
-
-offset:
-	{
-		$$ = 0;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-
-pointer:
-	LSB
-|	LSP
-|	LFP
-
-con:
-	LCONST
-|	LVAR
-	{
-		$$ = int32($1.Value);
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'~' con
-	{
-		$$ = ^$2;
-	}
-|	'(' expr ')'
-	{
-		$$ = $2;
-	}
-
-oexpr:
-	{
-		$$ = 0;
-	}
-|	',' expr
-	{
-		$$ = $2;
-	}
-
-expr:
-	con
-|	expr '+' expr
-	{
-		$$ = $1 + $3;
-	}
-|	expr '-' expr
-	{
-		$$ = $1 - $3;
-	}
-|	expr '*' expr
-	{
-		$$ = $1 * $3;
-	}
-|	expr '/' expr
-	{
-		$$ = $1 / $3;
-	}
-|	expr '%' expr
-	{
-		$$ = $1 % $3;
-	}
-|	expr '<' '<' expr
-	{
-		$$ = $1 << uint($4);
-	}
-|	expr '>' '>' expr
-	{
-		$$ = $1 >> uint($4);
-	}
-|	expr '&' expr
-	{
-		$$ = $1 & $3;
-	}
-|	expr '^' expr
-	{
-		$$ = $1 ^ $3;
-	}
-|	expr '|' expr
-	{
-		$$ = $1 | $3;
-	}
diff --git a/src/cmd/new6a/a.y b/src/cmd/new6a/a.y
deleted file mode 100644
index bd59a1f..0000000
--- a/src/cmd/new6a/a.y
+++ /dev/null
@@ -1,723 +0,0 @@
-// Inferno utils/6a/a.y
-// http://code.google.com/p/inferno-os/source/browse/utils/6a/a.y
-//
-//	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.
-
-%{
-package main
-
-import (
-	"cmd/internal/asm"
-	"cmd/internal/obj"
-	"cmd/internal/obj/x86"
-)
-%}
-
-%union {
-	sym *asm.Sym
-	lval int64
-	dval float64
-	sval string
-	addr obj.Addr
-	addr2 Addr2
-}
-
-%left	'|'
-%left	'^'
-%left	'&'
-%left	'<' '>'
-%left	'+' '-'
-%left	'*' '/' '%'
-%token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
-%token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC
-%token	<lval>	LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF
-%token	<lval>	LCONST LFP LPC LSB
-%token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
-%token	<dval>	LFCONST
-%token	<sval>	LSCONST LSP
-%token	<sym>	LNAME LLAB LVAR
-%type	<lval>	con expr pointer offset
-%type	<addr>	mem imm textsize reg nam rel rem rim rom omem nmem
-%type	<addr2>	nonnon nonrel nonrem rimnon rimrem remrim
-%type	<addr2>	spec3 spec4 spec5 spec6 spec7 spec8 spec9
-%type	<addr2>	spec10 spec12 spec13
-%%
-prog:
-|	prog 
-	{
-		stmtline = asm.Lineno;
-	}
-	line
-
-line:
-	LNAME ':'
-	{
-		$1 = asm.LabelLookup($1);
-		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
-			yyerror("redeclaration of %s (%s)", $1.Labelname, $1.Name);
-		}
-		$1.Type = LLAB;
-		$1.Value = int64(asm.PC)
-	}
-	line
-|	';'
-|	inst ';'
-|	error ';'
-
-inst:
-	LNAME '=' expr
-	{
-		$1.Type = LVAR;
-		$1.Value = $3;
-	}
-|	LVAR '=' expr
-	{
-		if $1.Value != $3 {
-			yyerror("redeclaration of %s", $1.Name);
-		}
-		$1.Value = $3;
-	}
-|	LTYPE0 nonnon	{ outcode(int($1), &$2); }
-|	LTYPE1 nonrem	{ outcode(int($1), &$2); }
-|	LTYPE2 rimnon	{ outcode(int($1), &$2); }
-|	LTYPE3 rimrem	{ outcode(int($1), &$2); }
-|	LTYPE4 remrim	{ outcode(int($1), &$2); }
-|	LTYPER nonrel	{ outcode(int($1), &$2); }
-|	spec1
-|	spec2
-|	LTYPEC spec3	{ outcode(int($1), &$2); }
-|	LTYPEN spec4	{ outcode(int($1), &$2); }
-|	LTYPES spec5	{ outcode(int($1), &$2); }
-|	LTYPEM spec6	{ outcode(int($1), &$2); }
-|	LTYPEI spec7	{ outcode(int($1), &$2); }
-|	LTYPEXC spec8	{ outcode(int($1), &$2); }
-|	LTYPEX spec9	{ outcode(int($1), &$2); }
-|	LTYPERT spec10	{ outcode(int($1), &$2); }
-|	spec11
-|	LTYPEPC spec12	{ outcode(int($1), &$2); }
-|	LTYPEF spec13	{ outcode(int($1), &$2); }
-
-nonnon:
-	{
-		$$.from = nullgen;
-		$$.to = nullgen;
-	}
-|	','
-	{
-		$$.from = nullgen;
-		$$.to = nullgen;
-	}
-
-rimrem:
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-remrim:
-	rem ',' rim
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-rimnon:
-	rim ','
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-
-nonrem:
-	',' rem
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rem
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-
-nonrel:
-	',' rel
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rel
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-|	imm ',' rel
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec1:	/* DATA */
-	LTYPED nam '/' con ',' imm
-	{
-		var a Addr2
-		a.from = $2
-		a.to = $6
-		outcode(obj.ADATA, &a)
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-spec2:	/* TEXT */
-	LTYPET mem ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.ATEXT, &Addr2{$2, $5})
-	}
-|	LTYPET mem ',' con ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.ATEXT, &Addr2{$2, $7})
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-spec11:	/* GLOBL */
-	LTYPEG mem ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode(obj.AGLOBL, &Addr2{$2, $4})
-	}
-|	LTYPEG mem ',' con ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode(obj.AGLOBL, &Addr2{$2, $6})
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-spec3:	/* JMP/CALL */
-	',' rom
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rom
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-
-spec4:	/* NOP */
-	nonnon
-|	nonrem
-
-spec5:	/* SHL/SHR */
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-|	rim ',' rem ':' LLREG
-	{
-		$$.from = $1;
-		$$.to = $3;
-		if $$.from.Index != obj.TYPE_NONE {
-			yyerror("dp shift with lhs index");
-		}
-		$$.from.Index = int16($5);
-	}
-
-spec6:	/* MOVW/MOVL */
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-|	rim ',' rem ':' LSREG
-	{
-		$$.from = $1;
-		$$.to = $3;
-		if $$.to.Index != obj.TYPE_NONE {
-			yyerror("dp move with lhs index");
-		}
-		$$.to.Index = int16($5);
-	}
-
-spec7:
-	rim ','
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec8:	/* CMPPS/CMPPD */
-	reg ',' rem ',' con
-	{
-		$$.from = $1;
-		$$.to = $3;
-		$$.to.Offset = $5;
-	}
-
-spec9:	/* shufl */
-	imm ',' rem ',' reg
-	{
-		$$.from = $3;
-		$$.to = $5;
-		if $1.Type != obj.TYPE_CONST {
-			yyerror("illegal constant");
-		}
-		$$.to.Offset = $1.Offset;
-	}
-
-spec10:	/* RET/RETF */
-	{
-		$$.from = nullgen;
-		$$.to = nullgen;
-	}
-|	imm
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-
-spec12:	/* asm.PCDATA */
-	rim ',' rim
-	{
-		if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
-			yyerror("arguments to asm.PCDATA must be integer constants");
-		}
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec13:	/* FUNCDATA */
-	rim ',' rim
-	{
-		if $1.Type != obj.TYPE_CONST {
-			yyerror("index for FUNCDATA must be integer constant");
-		}
-		if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
-			yyerror("value for FUNCDATA must be symbol reference");
-		}
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-rem:
-	reg
-|	mem
-
-rom:
-	rel
-|	nmem
-|	'*' reg
-	{
-		$$ = $2;
-	}
-|	'*' omem
-	{
-		$$ = $2;
-	}
-|	reg
-|	omem
-
-rim:
-	rem
-|	imm
-
-rel:
-	con '(' LPC ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1 + int64(asm.PC);
-	}
-|	LNAME offset
-	{
-		$1 = asm.LabelLookup($1);
-		$$ = nullgen;
-		if asm.Pass == 2 && $1.Type != LLAB {
-			yyerror("undefined label: %s", $1.Labelname);
-		}
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1.Value + $2;
-	}
-
-reg:
-	LBREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LFREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LLREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LMREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LSP
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = x86.REG_SP;
-	}
-|	LSREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LXREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-
-imm:
-	'$' con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		$$.Offset = $2;
-	}
-|	'$' nam
-	{
-		$$ = $2;
-		$$.Type = obj.TYPE_ADDR;
-		/*
-		if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
-			yyerror("constant cannot be automatic: %s",
-				$2.sym.Name);
-		 */
-	}
-|	'$' LSCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SCONST;
-		$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
-	}
-|	'$' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $2;
-	}
-|	'$' '(' LFCONST ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $3;
-	}
-|	'$' '(' '-' LFCONST ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$4;
-	}
-|	'$' '-' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$3;
-	}
-
-mem:
-	omem
-|	nmem
-
-omem:
-	con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Offset = $1;
-	}
-|	con '(' LLREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-	}
-|	con '(' LSP ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = x86.REG_SP
-		$$.Offset = $1;
-	}
-|	con '(' LSREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-	}
-|	con '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Offset = $1;
-		$$.Index = int16($3);
-		$$.Scale = int8($5);
-		checkscale($$.Scale);
-	}
-|	con '(' LLREG ')' '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-		$$.Index = int16($6);
-		$$.Scale = int8($8);
-		checkscale($$.Scale);
-	}
-|	con '(' LLREG ')' '(' LSREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-		$$.Index = int16($6);
-		$$.Scale = int8($8);
-		checkscale($$.Scale);
-	}
-|	'(' LLREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($2)
-	}
-|	'(' LSP ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = x86.REG_SP
-	}
-|	'(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Index = int16($2);
-		$$.Scale = int8($4);
-		checkscale($$.Scale);
-	}
-|	'(' LLREG ')' '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($2)
-		$$.Index = int16($5);
-		$$.Scale = int8($7);
-		checkscale($$.Scale);
-	}
-
-nmem:
-	nam
-	{
-		$$ = $1;
-	}
-|	nam '(' LLREG '*' con ')'
-	{
-		$$ = $1;
-		$$.Index = int16($3);
-		$$.Scale = int8($5);
-		checkscale($$.Scale);
-	}
-
-nam:
-	LNAME offset '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Name = int8($4)
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
-		$$.Offset = $2;
-	}
-|	LNAME '<' '>' offset '(' LSB ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Name = obj.NAME_STATIC
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
-		$$.Offset = $4;
-	}
-
-offset:
-	{
-		$$ = 0;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-
-pointer:
-	LSB
-|	LSP
-	{
-		$$ = obj.NAME_AUTO;
-	}
-|	LFP
-
-con:
-	LCONST
-|	LVAR
-	{
-		$$ = $1.Value;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'~' con
-	{
-		$$ = ^$2;
-	}
-|	'(' expr ')'
-	{
-		$$ = $2;
-	}
-
-textsize:
-	LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = $1;
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	'-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -$2;
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = $1;
-		$$.U.Argsize = int32($3);
-	}
-|	'-' LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -$2;
-		$$.U.Argsize = int32($4);
-	}
-
-expr:
-	con
-|	expr '+' expr
-	{
-		$$ = $1 + $3;
-	}
-|	expr '-' expr
-	{
-		$$ = $1 - $3;
-	}
-|	expr '*' expr
-	{
-		$$ = $1 * $3;
-	}
-|	expr '/' expr
-	{
-		$$ = $1 / $3;
-	}
-|	expr '%' expr
-	{
-		$$ = $1 % $3;
-	}
-|	expr '<' '<' expr
-	{
-		$$ = $1 << uint($4);
-	}
-|	expr '>' '>' expr
-	{
-		$$ = $1 >> uint($4);
-	}
-|	expr '&' expr
-	{
-		$$ = $1 & $3;
-	}
-|	expr '^' expr
-	{
-		$$ = $1 ^ $3;
-	}
-|	expr '|' expr
-	{
-		$$ = $1 | $3;
-	}
diff --git a/src/cmd/new8a/a.y b/src/cmd/new8a/a.y
deleted file mode 100644
index 906ad33..0000000
--- a/src/cmd/new8a/a.y
+++ /dev/null
@@ -1,713 +0,0 @@
-// Inferno utils/8a/a.y
-// http://code.google.com/p/inferno-os/source/browse/utils/8a/a.y
-//
-//	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.
-
-%{
-package main
-
-import (
-	"cmd/internal/asm"
-	"cmd/internal/obj"
-	. "cmd/internal/obj/i386"
-)
-%}
-
-%union {
-	sym *asm.Sym
-	lval int64
-	con2 struct {
-		v1 int32
-		v2 int32
-	}
-	dval float64
-	sval string
-	addr obj.Addr
-	addr2 Addr2
-}
-
-%left	'|'
-%left	'^'
-%left	'&'
-%left	'<' '>'
-%left	'+' '-'
-%left	'*' '/' '%'
-%token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
-%token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
-%token	<lval>	LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB
-%token	<lval>	LBREG LLREG LSREG LFREG LXREG
-%token	<dval>	LFCONST
-%token	<sval>	LSCONST LSP
-%token	<sym>	LNAME LLAB LVAR
-%type	<lval>	con expr pointer offset
-%type	<addr>	mem imm reg nam rel rem rim rom omem nmem textsize
-%type	<addr2>	nonnon nonrel nonrem rimnon rimrem remrim
-%type	<addr2>	spec3 spec4 spec5 spec6 spec7 spec9 spec10 spec11 spec12
-%%
-prog:
-|	prog
-	{
-		stmtline = asm.Lineno;
-	}
-	line
-
-line:
-	LNAME ':'
-	{
-		$1 = asm.LabelLookup($1);
-		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
-			yyerror("redeclaration of %s", $1.Labelname)
-		}
-		$1.Type = LLAB;
-		$1.Value = int64(asm.PC)
-	}
-	line
-|	';'
-|	inst ';'
-|	error ';'
-
-inst:
-	LNAME '=' expr
-	{
-		$1.Type = LVAR;
-		$1.Value = $3;
-	}
-|	LVAR '=' expr
-	{
-		if $1.Value != int64($3) {
-			yyerror("redeclaration of %s", $1.Name);
-		}
-		$1.Value = $3;
-	}
-|	LTYPE0 nonnon	{ outcode(int($1), &$2); }
-|	LTYPE1 nonrem	{ outcode(int($1), &$2); }
-|	LTYPE2 rimnon	{ outcode(int($1), &$2); }
-|	LTYPE3 rimrem	{ outcode(int($1), &$2); }
-|	LTYPE4 remrim	{ outcode(int($1), &$2); }
-|	LTYPER nonrel	{ outcode(int($1), &$2); }
-|	spec1
-|	spec2
-|	LTYPEC spec3	{ outcode(int($1), &$2); }
-|	LTYPEN spec4	{ outcode(int($1), &$2); }
-|	LTYPES spec5	{ outcode(int($1), &$2); }
-|	LTYPEM spec6	{ outcode(int($1), &$2); }
-|	LTYPEI spec7	{ outcode(int($1), &$2); }
-|	spec8
-|	LTYPEXC spec9	{ outcode(int($1), &$2); }
-|	LTYPEX spec10	{ outcode(int($1), &$2); }
-|	LTYPEPC spec11	{ outcode(int($1), &$2); }
-|	LTYPEF spec12	{ outcode(int($1), &$2); }
-
-nonnon:
-	{
-		$$.from = nullgen;
-		$$.to = nullgen;
-	}
-|	','
-	{
-		$$.from = nullgen;
-		$$.to = nullgen;
-	}
-
-rimrem:
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-remrim:
-	rem ',' rim
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-rimnon:
-	rim ','
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-
-nonrem:
-	',' rem
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rem
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-
-nonrel:
-	',' rel
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rel
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-|	imm ',' rel
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec1:	/* DATA */
-	LTYPED nam '/' con ',' imm
-	{
-		outcode(obj.ADATA, &Addr2{$2, $6})
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-spec2:	/* TEXT */
-	LTYPET mem ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.ATEXT, &Addr2{$2, $5})
-	}
-|	LTYPET mem ',' con ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.ATEXT, &Addr2{$2, $7})
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-spec8:	/* GLOBL */
-	LTYPEG mem ',' imm
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.AGLOBL, &Addr2{$2, $4})
-	}
-|	LTYPEG mem ',' con ',' imm
-	{
-		asm.Settext($2.Sym);
-		outcode(obj.AGLOBL, &Addr2{$2, $6})
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-
-spec3:	/* JMP/CALL */
-	',' rom
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-	}
-|	rom
-	{
-		$$.from = nullgen;
-		$$.to = $1;
-	}
-|	'*' nam
-	{
-		$$.from = nullgen;
-		$$.to = $2;
-		$$.to.Type = obj.TYPE_INDIR
-	}
-
-spec4:	/* NOP */
-	nonnon
-|	nonrem
-
-spec5:	/* SHL/SHR */
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-|	rim ',' rem ':' LLREG
-	{
-		$$.from = $1;
-		$$.to = $3;
-		if $$.from.Index != obj.TYPE_NONE {
-			yyerror("dp shift with lhs index");
-		}
-		$$.from.Index = int16($5);
-	}
-
-spec6:	/* MOVW/MOVL */
-	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-|	rim ',' rem ':' LSREG
-	{
-		$$.from = $1;
-		$$.to = $3;
-		if $$.to.Index != obj.TYPE_NONE {
-			yyerror("dp move with lhs index");
-		}
-		$$.to.Index = int16($5);
-	}
-
-spec7:
-	rim ','
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim
-	{
-		$$.from = $1;
-		$$.to = nullgen;
-	}
-|	rim ',' rem
-	{
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec9:	/* CMPPS/CMPPD */
-	reg ',' rem ',' con
-	{
-		$$.from = $1;
-		$$.to = $3;
-		$$.to.Offset = $5;
-	}
-
-spec10:	/* PINSRD */
-	imm ',' rem ',' reg
-	{
-		$$.from = $3;
-		$$.to = $5;
-		if $1.Type != obj.TYPE_CONST {
-			yyerror("illegal constant")
-		}
-		$$.to.Offset = $1.Offset;
-	}
-
-spec11:	/* PCDATA */
-	rim ',' rim
-	{
-		if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
-			yyerror("arguments to PCDATA must be integer constants");
-		}
-		$$.from = $1;
-		$$.to = $3;
-	}
-
-spec12:	/* FUNCDATA */
-	rim ',' rim
-	{
-		if $1.Type != obj.TYPE_CONST {
-			yyerror("index for FUNCDATA must be integer constant");
-		}
-		if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
-			yyerror("value for FUNCDATA must be symbol reference");
-		}
- 		$$.from = $1;
- 		$$.to = $3;
- 	}
-
-rem:
-	reg
-|	mem
-
-rom:
-	rel
-|	nmem
-|	'*' reg
-	{
-		$$ = $2;
-	}
-|	'*' omem
-	{
-		$$ = $2;
-	}
-|	reg
-|	omem
-|	imm
-
-rim:
-	rem
-|	imm
-
-rel:
-	con '(' LPC ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1 + int64(asm.PC);
-	}
-|	LNAME offset
-	{
-		$1 = asm.LabelLookup($1);
-		$$ = nullgen;
-		if asm.Pass == 2 && $1.Type != LLAB {
-			yyerror("undefined label: %s", $1.Labelname);
-		}
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1.Value + $2;
-	}
-
-reg:
-	LBREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LFREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LLREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LXREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-|	LSP
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = REG_SP;
-	}
-|	LSREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1);
-	}
-
-imm:
-	'$' con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		$$.Offset = $2;
-	}
-|	'$' nam
-	{
-		$$ = $2;
-		$$.Type = obj.TYPE_ADDR
-		/*
-		if($2.Type == D_AUTO || $2.Type == D_PARAM)
-			yyerror("constant cannot be automatic: %s",
-				$2.Sym.name);
-		 */
-	}
-|	'$' LSCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SCONST;
-		$$.U.Sval = $2
-	}
-|	'$' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $2;
-	}
-|	'$' '(' LFCONST ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $3;
-	}
-|	'$' '(' '-' LFCONST ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$4;
-	}
-|	'$' '-' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$3;
-	}
-
-textsize:
-	LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = $1;
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	'-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -$2;
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = $1;
-		$$.U.Argsize = int32($3);
-	}
-|	'-' LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -$2;
-		$$.U.Argsize = int32($4);
-	}
-
-
-mem:
-	omem
-|	nmem
-
-omem:
-	con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Offset = $1;
-	}
-|	con '(' LLREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-	}
-|	con '(' LSP ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = REG_SP
-		$$.Offset = $1;
-	}
-|	con '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Offset = $1;
-		$$.Index = int16($3);
-		$$.Scale = int8($5);
-		checkscale($$.Scale);
-	}
-|	con '(' LLREG ')' '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-		$$.Index = int16($6);
-		$$.Scale = int8($8);
-		checkscale($$.Scale);
-	}
-|	con '(' LLREG ')' '(' LSREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-		$$.Index = int16($6);
-		$$.Scale = int8($8);
-		checkscale($$.Scale);
-	}
-|	'(' LLREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($2);
-	}
-|	'(' LSP ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = REG_SP
-	}
-|	con '(' LSREG ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($3)
-		$$.Offset = $1;
-	}
-|	'(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Index = int16($2);
-		$$.Scale = int8($4);
-		checkscale($$.Scale);
-	}
-|	'(' LLREG ')' '(' LLREG '*' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Reg = int16($2)
-		$$.Index = int16($5);
-		$$.Scale = int8($7);
-		checkscale($$.Scale);
-	}
-
-nmem:
-	nam
-	{
-		$$ = $1;
-	}
-|	nam '(' LLREG '*' con ')'
-	{
-		$$ = $1;
-		$$.Index = int16($3);
-		$$.Scale = int8($5);
-		checkscale($$.Scale);
-	}
-
-nam:
-	LNAME offset '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Name = int8($4);
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
-		$$.Offset = $2;
-	}
-|	LNAME '<' '>' offset '(' LSB ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM
-		$$.Name = obj.NAME_STATIC
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
-		$$.Offset = $4;
-	}
-
-offset:
-	{
-		$$ = 0;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-
-pointer:
-	LSB
-|	LSP
-	{
-		$$ = obj.NAME_AUTO;
-	}
-|	LFP
-
-con:
-	LCONST
-|	LVAR
-	{
-		$$ = $1.Value;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'~' con
-	{
-		$$ = ^$2;
-	}
-|	'(' expr ')'
-	{
-		$$ = $2;
-	}
-
-expr:
-	con
-|	expr '+' expr
-	{
-		$$ = $1 + $3;
-	}
-|	expr '-' expr
-	{
-		$$ = $1 - $3;
-	}
-|	expr '*' expr
-	{
-		$$ = $1 * $3;
-	}
-|	expr '/' expr
-	{
-		$$ = $1 / $3;
-	}
-|	expr '%' expr
-	{
-		$$ = $1 % $3;
-	}
-|	expr '<' '<' expr
-	{
-		$$ = $1 << uint($4);
-	}
-|	expr '>' '>' expr
-	{
-		$$ = $1 >> uint($4);
-	}
-|	expr '&' expr
-	{
-		$$ = $1 & $3;
-	}
-|	expr '^' expr
-	{
-		$$ = $1 ^ $3;
-	}
-|	expr '|' expr
-	{
-		$$ = $1 | $3;
-	}
diff --git a/src/cmd/new9a/a.y b/src/cmd/new9a/a.y
deleted file mode 100644
index db733c5..0000000
--- a/src/cmd/new9a/a.y
+++ /dev/null
@@ -1,1055 +0,0 @@
-// cmd/9a/a.y from Vita Nuova.
-//
-//	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-2008 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-2008 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.
-
-%{
-package main
-
-import (
-	"cmd/internal/asm"
-	"cmd/internal/obj"
-	. "cmd/internal/obj/ppc64"
-)
-%}
-
-%union
-{
-	sym *asm.Sym
-	lval int64
-	dval float64
-	sval string
-	addr obj.Addr
-}
-
-%left	'|'
-%left	'^'
-%left	'&'
-%left	'<' '>'
-%left	'+' '-'
-%left	'*' '/' '%'
-%token	<lval>	LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
-%token	<lval>	LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
-%token	<lval>	LNOP LEND LRETT LWORD LTEXT LDATA LGLOBL LRETRN
-%token	<lval>	LCONST LSP LSB LFP LPC LCREG LFLUSH
-%token	<lval>	LREG LFREG LR LCR LF LFPSCR
-%token	<lval>	LLR LCTR LSPR LSPREG LSEG LMSR
-%token	<lval>	LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV
-%token	<lval>	LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA
-%token	<dval>	LFCONST
-%token	<sval>	LSCONST
-%token	<sym>	LNAME LLAB LVAR
-%type	<lval>	con expr pointer offset sreg
-%type	<addr>	addr rreg regaddr name creg freg xlreg lr ctr textsize
-%type	<addr>	imm ximm fimm rel psr lcr cbit fpscr msr mask
-%%
-prog:
-|	prog
-	{
-		stmtline = asm.Lineno
-	}
-	line
-
-line:
-	LNAME ':'
-	{
-		$1 = asm.LabelLookup($1);
-		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
-			yyerror("redeclaration of %s", $1.Labelname)
-		}
-		$1.Type = LLAB;
-		$1.Value = int64(asm.PC);
-	}
-	line
-|	LNAME '=' expr ';'
-	{
-		$1.Type = LVAR;
-		$1.Value = $3;
-	}
-|	LVAR '=' expr ';'
-	{
-		if $1.Value != $3 {
-			yyerror("redeclaration of %s", $1.Name)
-		}
-		$1.Value = $3;
-	}
-|	LSCHED ';'
-	{
-		nosched = int($1);
-	}
-|	';'
-|	inst ';'
-|	error ';'
-
-inst:
-/*
- * load ints and bytes
- */
-	LMOVW rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW addr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW regaddr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVB rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVB addr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVB regaddr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * load floats
- */
-|	LFMOV addr ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFMOV regaddr ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFMOV fimm ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFMOV freg ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFMOV freg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFMOV freg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * store ints and bytes
- */
-|	LMOVW rreg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW rreg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVB rreg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVB rreg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * store floats
- */
-|	LMOVW freg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW freg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * floating point status
- */
-|	LMOVW fpscr ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW freg ','  fpscr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW freg ',' imm ',' fpscr
-	{
-		outgcode(int($1), &$2, 0, &$4, &$6);
-	}
-|	LMOVW fpscr ',' creg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMTFSB imm ',' con
-	{
-		outcode(int($1), &$2, int($4), &nullgen);
-	}
-/*
- * field moves (mtcrf)
- */
-|	LMOVW rreg ',' imm ',' lcr
-	{
-		outgcode(int($1), &$2, 0, &$4, &$6);
-	}
-|	LMOVW rreg ',' creg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW rreg ',' lcr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * integer operations
- * logical instructions
- * shift instructions
- * unary instructions
- */
-|	LADDW rreg ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-|	LADDW imm ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-|	LADDW rreg ',' imm ',' rreg
-	{
-		outgcode(int($1), &$2, 0, &$4, &$6);
-	}
-|	LADDW rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LADDW imm ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LLOGW rreg ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-|	LLOGW rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LSHW rreg ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-|	LSHW rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LSHW imm ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-|	LSHW imm ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LABS rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LABS rreg
-	{
-		outcode(int($1), &$2, 0, &$2);
-	}
-/*
- * multiply-accumulate
- */
-|	LMA rreg ',' sreg ',' rreg
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-/*
- * move immediate: macro for cau+or, addi, addis, and other combinations
- */
-|	LMOVW imm ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW ximm ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * condition register operations
- */
-|	LCROP cbit ',' cbit
-	{
-		outcode(int($1), &$2, int($4.Reg), &$4);
-	}
-|	LCROP cbit ',' con ',' cbit
-	{
-		outcode(int($1), &$2, int($4), &$6);
-	}
-/*
- * condition register moves
- * move from machine state register
- */
-|	LMOVW creg ',' creg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW psr ',' creg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW lcr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW psr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW xlreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW rreg ',' xlreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW creg ',' psr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVW rreg ',' psr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * branch, branch conditional
- * branch conditional register
- * branch conditional to count register
- */
-|	LBRA rel
-	{
-		outcode(int($1), &nullgen, 0, &$2);
-	}
-|	LBRA addr
-	{
-		outcode(int($1), &nullgen, 0, &$2);
-	}
-|	LBRA '(' xlreg ')'
-	{
-		outcode(int($1), &nullgen, 0, &$3);
-	}
-|	LBRA ',' rel
-	{
-		outcode(int($1), &nullgen, 0, &$3);
-	}
-|	LBRA ',' addr
-	{
-		outcode(int($1), &nullgen, 0, &$3);
-	}
-|	LBRA ',' '(' xlreg ')'
-	{
-		outcode(int($1), &nullgen, 0, &$4);
-	}
-|	LBRA creg ',' rel
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LBRA creg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LBRA creg ',' '(' xlreg ')'
-	{
-		outcode(int($1), &$2, 0, &$5);
-	}
-|	LBRA con ',' rel
-	{
-		outcode(int($1), &nullgen, int($2), &$4);
-	}
-|	LBRA con ',' addr
-	{
-		outcode(int($1), &nullgen, int($2), &$4);
-	}
-|	LBRA con ',' '(' xlreg ')'
-	{
-		outcode(int($1), &nullgen, int($2), &$5);
-	}
-|	LBRA con ',' con ',' rel
-	{
-		var g obj.Addr
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = $2;
-		outcode(int($1), &g, int(REG_R0+$4), &$6);
-	}
-|	LBRA con ',' con ',' addr
-	{
-		var g obj.Addr
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = $2;
-		outcode(int($1), &g, int(REG_R0+$4), &$6);
-	}
-|	LBRA con ',' con ',' '(' xlreg ')'
-	{
-		var g obj.Addr
-		g = nullgen;
-		g.Type = obj.TYPE_CONST;
-		g.Offset = $2;
-		outcode(int($1), &g, int(REG_R0+$4), &$7);
-	}
-/*
- * conditional trap
- */
-|	LTRAP rreg ',' sreg
-	{
-		outcode(int($1), &$2, int($4), &nullgen);
-	}
-|	LTRAP imm ',' sreg
-	{
-		outcode(int($1), &$2, int($4), &nullgen);
-	}
-|	LTRAP rreg comma
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-|	LTRAP comma
-	{
-		outcode(int($1), &nullgen, 0, &nullgen);
-	}
-/*
- * floating point operate
- */
-|	LFCONV freg ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFADD freg ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFADD freg ',' freg ',' freg
-	{
-		outcode(int($1), &$2, int($4.Reg), &$6);
-	}
-|	LFMA freg ',' freg ',' freg ',' freg
-	{
-		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
-	}
-|	LFCMP freg ',' freg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LFCMP freg ',' freg ',' creg
-	{
-		outcode(int($1), &$2, int($6.Reg), &$4);
-	}
-/*
- * CMP
- */
-|	LCMP rreg ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LCMP rreg ',' imm
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LCMP rreg ',' rreg ',' creg
-	{
-		outcode(int($1), &$2, int($6.Reg), &$4);
-	}
-|	LCMP rreg ',' imm ',' creg
-	{
-		outcode(int($1), &$2, int($6.Reg), &$4);
-	}
-/*
- * rotate and mask
- */
-|	LRLWM  imm ',' rreg ',' imm ',' rreg
-	{
-		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
-	}
-|	LRLWM  imm ',' rreg ',' mask ',' rreg
-	{
-		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
-	}
-|	LRLWM  rreg ',' rreg ',' imm ',' rreg
-	{
-		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
-	}
-|	LRLWM  rreg ',' rreg ',' mask ',' rreg
-	{
-		outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
-	}
-/*
- * load/store multiple
- */
-|	LMOVMW addr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LMOVMW rreg ',' addr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * various indexed load/store
- * indexed unary (eg, cache clear)
- */
-|	LXLD regaddr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LXLD regaddr ',' imm ',' rreg
-	{
-		outgcode(int($1), &$2, 0, &$4, &$6);
-	}
-|	LXST rreg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LXST rreg ',' imm ',' regaddr
-	{
-		outgcode(int($1), &$2, 0, &$4, &$6);
-	}
-|	LXMV regaddr ',' rreg
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LXMV rreg ',' regaddr
-	{
-		outcode(int($1), &$2, 0, &$4);
-	}
-|	LXOP regaddr
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-/*
- * NOP
- */
-|	LNOP comma
-	{
-		outcode(int($1), &nullgen, 0, &nullgen);
-	}
-|	LNOP rreg comma
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-|	LNOP freg comma
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-|	LNOP ',' rreg
-	{
-		outcode(int($1), &nullgen, 0, &$3);
-	}
-|	LNOP ',' freg
-	{
-		outcode(int($1), &nullgen, 0, &$3);
-	}
-|	LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-/*
- * word
- */
-|	LWORD imm comma
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-|	LWORD ximm comma
-	{
-		outcode(int($1), &$2, 0, &nullgen);
-	}
-/*
- * PCDATA
- */
-|	LPCDAT imm ',' imm
-	{
-		if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
-			yyerror("arguments to PCDATA must be integer constants")
-		}
-		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * FUNCDATA
- */
-|	LFUNCDAT imm ',' addr
-	{
-		if $2.Type != obj.TYPE_CONST {
-			yyerror("index for FUNCDATA must be integer constant")
-		}
-		if $4.Type != obj.TYPE_MEM || ($4.Name != obj.NAME_EXTERN && $4.Name != obj.NAME_STATIC) {
-			yyerror("value for FUNCDATA must be symbol reference")
-		}
- 		outcode(int($1), &$2, 0, &$4);
-	}
-/*
- * END
- */
-|	LEND comma
-	{
-		outcode(int($1), &nullgen, 0, &nullgen);
-	}
-/*
- * TEXT
- */
-|	LTEXT name ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(int($1), &$2, 0, &$5);
-	}
-|	LTEXT name ',' con ',' '$' textsize
-	{
-		asm.Settext($2.Sym);
-		outcode(int($1), &$2, int($4), &$7);
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-/*
- * GLOBL
- */
-|	LGLOBL name ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode(int($1), &$2, 0, &$4)
-	}
-|	LGLOBL name ',' con ',' imm
-	{
-		asm.Settext($2.Sym)
-		outcode(int($1), &$2, 0, &$6)
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-
-/*
- * DATA
- */
-|	LDATA name '/' con ',' imm
-	{
-		outcode(int($1), &$2, 0, &$6);
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-|	LDATA name '/' con ',' ximm
-	{
-		outcode(int($1), &$2, 0, &$6);
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-|	LDATA name '/' con ',' fimm
-	{
-		outcode(int($1), &$2, 0, &$6);
-		if asm.Pass > 1 {
-			lastpc.From3.Type = obj.TYPE_CONST
-			lastpc.From3.Offset = $4
-		}
-	}
-/*
- * RETURN
- */
-|	LRETRN	comma
-	{
-		outcode(int($1), &nullgen, 0, &nullgen);
-	}
-
-rel:
-	con '(' LPC ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1 + int64(asm.PC);
-	}
-|	LNAME offset
-	{
-		$1 = asm.LabelLookup($1);
-		$$ = nullgen;
-		if asm.Pass == 2 && $1.Type != LLAB {
-			yyerror("undefined label: %s", $1.Labelname)
-		}
-		$$.Type = obj.TYPE_BRANCH;
-		$$.Offset = $1.Value + $2;
-	}
-
-rreg:
-	sreg
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-xlreg:
-	lr
-|	ctr
-
-lr:
-	LLR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-lcr:
-	LCR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);	/* whole register */
-	}
-
-ctr:
-	LCTR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-msr:
-	LMSR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1)
-	}
-
-psr:
-	LSPREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-|	LSPR '(' con ')'
-	{
-		if $3 < 0 || $3 >= 1024 {
-			yyerror("SPR/DCR out of range")
-		}
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG
-		$$.Reg = int16($1 + $3);
-	}
-|	msr
-
-fpscr:
-	LFPSCR
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-freg:
-	LFREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-|	LF '(' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16(REG_F0 + $3);
-	}
-
-creg:
-	LCREG
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-|	LCR '(' con ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16(REG_C0 + $3);
-	}
-
-
-cbit:	con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_REG;
-		$$.Reg = int16($1);
-	}
-
-mask:
-	con ',' con
-	{
-		var mb, me int
-		var v uint32
-
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		mb = int($1);
-		me = int($3);
-		if(mb < 0 || mb > 31 || me < 0 || me > 31){
-			yyerror("illegal mask start/end value(s)");
-			mb = 0
-			me = 0;
-		}
-		if mb <= me {
-			v = (^uint32(0)>>uint(mb)) & (^uint32(0)<<uint(31-me))
-		} else {
-			v = (^uint32(0)>>uint(me+1)) & (^uint32(0)<<uint(31-(mb-1)))
-		}
-		$$.Offset = int64(v);
-	}
-
-textsize:
-	LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = int64($1)
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	'-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -int64($2)
-		$$.U.Argsize = obj.ArgsSizeUnknown;
-	}
-|	LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = int64($1)
-		$$.U.Argsize = int32($3);
-	}
-|	'-' LCONST '-' LCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_TEXTSIZE;
-		$$.Offset = -int64($2)
-		$$.U.Argsize = int32($4);
-	}
-
-ximm:
-	'$' addr
-	{
-		$$ = $2;
-		$$.Type = obj.TYPE_ADDR;
-	}
-|	'$' LSCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_SCONST;
-		$$.U.Sval = $2
-	}
-
-fimm:
-	'$' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = $2;
-	}
-|	'$' '-' LFCONST
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_FCONST;
-		$$.U.Dval = -$3;
-	}
-
-imm:	'$' con
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_CONST;
-		$$.Offset = $2;
-	}
-
-sreg:
-	LREG
-|	LR '(' con ')'
-	{
-		if $$ < 0 || $$ >= NREG {
-			print("register value out of range\n")
-		}
-		$$ = REG_R0 + $3;
-	}
-
-regaddr:
-	'(' sreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($2);
-		$$.Offset = 0;
-	}
-|	'(' sreg '+' sreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($2);
-		$$.Scale = int8($4);
-		$$.Offset = 0;
-	}
-
-addr:
-	name
-|	con '(' sreg ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Reg = int16($3);
-		$$.Offset = $1;
-	}
-
-name:
-	con '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = int8($3);
-		$$.Sym = nil;
-		$$.Offset = $1;
-	}
-|	LNAME offset '(' pointer ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = int8($4);
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
-		$$.Offset = $2;
-	}
-|	LNAME '<' '>' offset '(' LSB ')'
-	{
-		$$ = nullgen;
-		$$.Type = obj.TYPE_MEM;
-		$$.Name = obj.NAME_STATIC;
-		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
-		$$.Offset = $4;
-	}
-
-comma:
-|	','
-
-offset:
-	{
-		$$ = 0;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-
-pointer:
-	LSB
-|	LSP
-|	LFP
-
-con:
-	LCONST
-|	LVAR
-	{
-		$$ = $1.Value;
-	}
-|	'-' con
-	{
-		$$ = -$2;
-	}
-|	'+' con
-	{
-		$$ = $2;
-	}
-|	'~' con
-	{
-		$$ = ^$2;
-	}
-|	'(' expr ')'
-	{
-		$$ = $2;
-	}
-
-expr:
-	con
-|	expr '+' expr
-	{
-		$$ = $1 + $3;
-	}
-|	expr '-' expr
-	{
-		$$ = $1 - $3;
-	}
-|	expr '*' expr
-	{
-		$$ = $1 * $3;
-	}
-|	expr '/' expr
-	{
-		$$ = $1 / $3;
-	}
-|	expr '%' expr
-	{
-		$$ = $1 % $3;
-	}
-|	expr '<' '<' expr
-	{
-		$$ = $1 << uint($4);
-	}
-|	expr '>' '>' expr
-	{
-		$$ = $1 >> uint($4);
-	}
-|	expr '&' expr
-	{
-		$$ = $1 & $3;
-	}
-|	expr '^' expr
-	{
-		$$ = $1 ^ $3;
-	}
-|	expr '|' expr
-	{
-		$$ = $1 | $3;
-	}
diff --git a/src/cmd/objwriter/main.go b/src/cmd/objwriter/main.go
deleted file mode 100644
index df83298..0000000
--- a/src/cmd/objwriter/main.go
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2015 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Objwriter reads an object file description in an unspecified format
-// and writes a Go object file. It is invoked by parts of the toolchain
-// that have not yet been converted from C to Go and should not be
-// used otherwise.
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"flag"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"math"
-	"os"
-	"runtime/pprof"
-	"strconv"
-	"strings"
-
-	"cmd/internal/obj"
-	"cmd/internal/obj/arm"
-	"cmd/internal/obj/i386"
-	"cmd/internal/obj/ppc64"
-	"cmd/internal/obj/x86"
-)
-
-var arch *obj.LinkArch
-var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
-var memprofile = flag.String("memprofile", "", "write memory profile to this file")
-
-func main() {
-	log.SetPrefix("goobj: ")
-	log.SetFlags(0)
-	flag.Parse()
-
-	if flag.NArg() == 1 && flag.Arg(0) == "ping" {
-		// old invocation from liblink, just testing that objwriter exists
-		return
-	}
-
-	if flag.NArg() != 4 {
-		fmt.Fprintf(os.Stderr, "usage: goobj infile objfile offset goarch\n")
-		os.Exit(2)
-	}
-
-	if *cpuprofile != "" {
-		f, err := os.Create(*cpuprofile)
-		if err != nil {
-			log.Fatal(err)
-		}
-		pprof.StartCPUProfile(f)
-		defer pprof.StopCPUProfile()
-	}
-	if *memprofile != "" {
-		f, err := os.Create(*memprofile)
-		if err != nil {
-			log.Fatal(err)
-		}
-		defer pprof.WriteHeapProfile(f)
-	}
-
-	switch flag.Arg(3) {
-	case "amd64":
-		arch = &x86.Linkamd64
-	case "amd64p32":
-		arch = &x86.Linkamd64p32
-	case "386":
-		// TODO(rsc): Move Link386 to package x86.
-		arch = &i386.Link386
-	case "arm":
-		arch = &arm.Linkarm
-	case "ppc64":
-		arch = &ppc64.Linkppc64
-	case "ppc64le":
-		arch = &ppc64.Linkppc64le
-	}
-
-	input()
-}
-
-const (
-	// must match liblink/objfilego.c
-	TypeEnd = iota
-	TypeCtxt
-	TypePlist
-	TypeSym
-	TypeProg
-	TypeAddr
-	TypeHist
-)
-
-var (
-	ctxt   *obj.Link
-	plists = map[int64]*obj.Plist{}
-	syms   = map[int64]*obj.LSym{}
-	progs  = map[int64]*obj.Prog{}
-	hists  = map[int64]*obj.Hist{}
-	undef  = map[interface{}]bool{}
-)
-
-func input() {
-	args := flag.Args()
-	ctxt = obj.Linknew(arch)
-	ctxt.Debugasm = 1
-	ctxt.Bso = obj.Binitw(os.Stdout)
-	defer obj.Bflush(ctxt.Bso)
-	ctxt.Diag = log.Fatalf
-	f, err := os.Open(args[0])
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	b := bufio.NewReaderSize(f, 1<<20)
-	if v := rdint(b); v != TypeCtxt {
-		log.Fatalf("invalid input - missing ctxt - got %d", v)
-	}
-	name := rdstring(b)
-	if name != ctxt.Arch.Name {
-		log.Fatalf("bad arch %s - want %s", name, ctxt.Arch.Name)
-	}
-
-	ctxt.Goarm = int32(rdint(b))
-	ctxt.Debugasm = int32(rdint(b))
-	ctxt.Trimpath = rdstring(b)
-	ctxt.Plist = rdplist(b)
-	ctxt.Plast = rdplist(b)
-	ctxt.Hist = rdhist(b)
-	ctxt.Ehist = rdhist(b)
-	for {
-		i := rdint(b)
-		if i < 0 {
-			break
-		}
-		ctxt.Hash[i] = rdsym(b)
-	}
-	last := int64(TypeCtxt)
-
-Loop:
-	for {
-		t := rdint(b)
-		switch t {
-		default:
-			log.Fatalf("unexpected input after type %d: %v", last, t)
-		case TypeEnd:
-			break Loop
-		case TypePlist:
-			readplist(b, rdplist(b))
-		case TypeSym:
-			readsym(b, rdsym(b))
-		case TypeProg:
-			readprog(b, rdprog(b))
-		case TypeHist:
-			readhist(b, rdhist(b))
-		}
-		last = t
-	}
-
-	if len(undef) > 0 {
-		panic("missing definitions")
-	}
-
-	var buf bytes.Buffer
-	obuf := obj.Binitw(&buf)
-	obj.Writeobjdirect(ctxt, obuf)
-	obj.Bflush(obuf)
-
-	data, err := ioutil.ReadFile(args[1])
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	offset, err := strconv.Atoi(args[2])
-	if err != nil {
-		log.Fatalf("bad offset: %v", err)
-	}
-	if offset > len(data) {
-		log.Fatalf("offset too large: %v > %v", offset, len(data))
-	}
-
-	old := data[offset:]
-	if len(old) > 0 && !bytes.Equal(old, buf.Bytes()) {
-		out := strings.TrimSuffix(args[0], ".in") + ".out"
-		if err := ioutil.WriteFile(out, append(data[:offset:offset], buf.Bytes()...), 0666); err != nil {
-			log.Fatal(err)
-		}
-		log.Fatalf("goobj produced different output:\n\toriginal: %s\n\tgoobj: %s", args[1], out)
-	}
-
-	if len(old) == 0 {
-		data = append(data, buf.Bytes()...)
-		if err := ioutil.WriteFile(args[1], data, 0666); err != nil {
-			log.Fatal(err)
-		}
-	}
-}
-
-func rdstring(b *bufio.Reader) string {
-	v := rdint(b)
-	buf := make([]byte, v)
-	io.ReadFull(b, buf)
-	return string(buf)
-}
-
-func rdint(b *bufio.Reader) int64 {
-	var v uint64
-	shift := uint(0)
-	for {
-		b, err := b.ReadByte()
-		if err != nil {
-			log.Fatal(err)
-		}
-		v |= uint64(b&0x7F) << shift
-		shift += 7
-		if b&0x80 == 0 {
-			break
-		}
-	}
-	return int64(v>>1) ^ int64(v<<63)>>63
-}
-
-func rdplist(b *bufio.Reader) *obj.Plist {
-	id := rdint(b)
-	if id == 0 {
-		return nil
-	}
-	pl := plists[id]
-	if pl == nil {
-		pl = new(obj.Plist)
-		plists[id] = pl
-		undef[pl] = true
-	}
-	return pl
-}
-
-func rdsym(b *bufio.Reader) *obj.LSym {
-	id := rdint(b)
-	if id == 0 {
-		return nil
-	}
-	sym := syms[id]
-	if sym == nil {
-		sym = new(obj.LSym)
-		syms[id] = sym
-		undef[sym] = true
-	}
-	return sym
-}
-
-func rdprog(b *bufio.Reader) *obj.Prog {
-	id := rdint(b)
-	if id == 0 {
-		return nil
-	}
-	prog := progs[id]
-	if prog == nil {
-		prog = new(obj.Prog)
-		prog.Ctxt = ctxt
-		progs[id] = prog
-		undef[prog] = true
-	}
-	return prog
-}
-
-func rdhist(b *bufio.Reader) *obj.Hist {
-	id := rdint(b)
-	if id == 0 {
-		return nil
-	}
-	h := hists[id]
-	if h == nil {
-		h = new(obj.Hist)
-		hists[id] = h
-		undef[h] = true
-	}
-	return h
-}
-
-func readplist(b *bufio.Reader, pl *obj.Plist) {
-	if !undef[pl] {
-		panic("double-def")
-	}
-	delete(undef, pl)
-	pl.Recur = int(rdint(b))
-	pl.Name = rdsym(b)
-	pl.Firstpc = rdprog(b)
-	pl.Link = rdplist(b)
-}
-
-func readsym(b *bufio.Reader, s *obj.LSym) {
-	if !undef[s] {
-		panic("double-def")
-	}
-	delete(undef, s)
-	s.Name = rdstring(b)
-	s.Extname = rdstring(b)
-	s.Type = int16(rdint(b))
-	s.Version = int16(rdint(b))
-	s.Dupok = uint8(rdint(b))
-	s.External = uint8(rdint(b))
-	s.Nosplit = uint8(rdint(b))
-	s.Reachable = uint8(rdint(b))
-	s.Cgoexport = uint8(rdint(b))
-	s.Special = uint8(rdint(b))
-	s.Stkcheck = uint8(rdint(b))
-	s.Hide = uint8(rdint(b))
-	s.Leaf = uint8(rdint(b))
-	s.Fnptr = uint8(rdint(b))
-	s.Seenglobl = uint8(rdint(b))
-	s.Onlist = uint8(rdint(b))
-	s.Symid = int16(rdint(b))
-	s.Dynid = int32(rdint(b))
-	s.Sig = int32(rdint(b))
-	s.Plt = int32(rdint(b))
-	s.Got = int32(rdint(b))
-	s.Align = int32(rdint(b))
-	s.Elfsym = int32(rdint(b))
-	s.Args = int32(rdint(b))
-	s.Locals = int32(rdint(b))
-	s.Value = rdint(b)
-	s.Size = rdint(b)
-	s.Hash = rdsym(b)
-	s.Allsym = rdsym(b)
-	s.Next = rdsym(b)
-	s.Sub = rdsym(b)
-	s.Outer = rdsym(b)
-	s.Gotype = rdsym(b)
-	s.Reachparent = rdsym(b)
-	s.Queue = rdsym(b)
-	s.File = rdstring(b)
-	s.Dynimplib = rdstring(b)
-	s.Dynimpvers = rdstring(b)
-	s.Text = rdprog(b)
-	s.Etext = rdprog(b)
-	n := int(rdint(b))
-	if n > 0 {
-		s.P = make([]byte, n)
-		io.ReadFull(b, s.P)
-	}
-	s.R = make([]obj.Reloc, int(rdint(b)))
-	for i := range s.R {
-		r := &s.R[i]
-		r.Off = int32(rdint(b))
-		r.Siz = uint8(rdint(b))
-		r.Done = uint8(rdint(b))
-		r.Type = int32(rdint(b))
-		r.Add = rdint(b)
-		r.Xadd = rdint(b)
-		r.Sym = rdsym(b)
-		r.Xsym = rdsym(b)
-	}
-}
-
-func readprog(b *bufio.Reader, p *obj.Prog) {
-	if !undef[p] {
-		panic("double-def")
-	}
-	delete(undef, p)
-	p.Pc = rdint(b)
-	p.Lineno = int32(rdint(b))
-	p.Link = rdprog(b)
-	p.As = int16(rdint(b))
-	p.Reg = int16(rdint(b))
-	p.Scond = uint8(rdint(b))
-	p.Width = int8(rdint(b))
-	readaddr(b, &p.From)
-	readaddr(b, &p.From3)
-	readaddr(b, &p.To)
-}
-
-func readaddr(b *bufio.Reader, a *obj.Addr) {
-	if rdint(b) != TypeAddr {
-		log.Fatal("out of sync")
-	}
-	a.Offset = rdint(b)
-	a.U.Dval = rdfloat(b)
-	buf := make([]byte, 8)
-	io.ReadFull(b, buf)
-	a.U.Sval = string(buf)
-	a.U.Branch = rdprog(b)
-	a.Sym = rdsym(b)
-	a.Gotype = rdsym(b)
-	a.Type = int16(rdint(b))
-	a.Index = int16(rdint(b))
-	a.Scale = int8(rdint(b))
-	a.Reg = int16(rdint(b))
-	a.Name = int8(rdint(b))
-	a.Class = int8(rdint(b))
-	a.Etype = uint8(rdint(b))
-	a.U.Argsize = int32(rdint(b))
-	a.Width = rdint(b)
-}
-
-func readhist(b *bufio.Reader, h *obj.Hist) {
-	if !undef[h] {
-		panic("double-def")
-	}
-	delete(undef, h)
-	h.Link = rdhist(b)
-	h.Name = rdstring(b)
-	h.Line = int32(rdint(b))
-	h.Offset = int32(rdint(b))
-}
-
-func rdfloat(b *bufio.Reader) float64 {
-	return math.Float64frombits(uint64(rdint(b)))
-}