liblink: delete unused code

Liblink is still needed for the linker (for a bit longer) but mostly not.
Delete the unused parts.

Change-Id: Ie63a7c1520dee52b17425b384943cd16262d36e3
Reviewed-on: https://go-review.googlesource.com/6110
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/include/link.h b/include/link.h
index 7fa136b..c511a95 100644
--- a/include/link.h
+++ b/include/link.h
@@ -28,14 +28,10 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-typedef	struct	Addr	Addr;
-typedef	struct	Prog	Prog;
 typedef	struct	LSym	LSym;
 typedef	struct	Reloc	Reloc;
 typedef	struct	Auto	Auto;
-typedef	struct	Hist	Hist;
 typedef	struct	Link	Link;
-typedef	struct	Plist	Plist;
 typedef	struct	LinkArch	LinkArch;
 typedef	struct	Library	Library;
 
@@ -43,158 +39,6 @@
 typedef	struct	Pcdata	Pcdata;
 typedef	struct	Pciter	Pciter;
 
-// An Addr is an argument to an instruction.
-// The general forms and their encodings are:
-//
-//	sym±offset(symkind)(reg)(index*scale)
-//		Memory reference at address &sym(symkind) + offset + reg + index*scale.
-//		Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
-//		If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
-//		To force a parsing as index*scale, write (index*1).
-//		Encoding:
-//			type = TYPE_MEM
-//			name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
-//			sym = sym
-//			offset = ±offset
-//			reg = reg (REG_*)
-//			index = index (REG_*)
-//			scale = scale (1, 2, 4, 8)
-//
-//	$<mem>
-//		Effective address of memory reference <mem>, defined above.
-//		Encoding: same as memory reference, but type = TYPE_ADDR.
-//
-//	$<±integer value>
-//		This is a special case of $<mem>, in which only ±offset is present.
-//		It has a separate type for easy recognition.
-//		Encoding:
-//			type = TYPE_CONST
-//			offset = ±integer value
-//
-//	*<mem>
-//		Indirect reference through memory reference <mem>, defined above.
-//		Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
-//		pointer stored in the data word sym(SB), not a function named sym(SB).
-//		Encoding: same as above, but type = TYPE_INDIR.
-//
-//	$*$<mem>
-//		No longer used.
-//		On machines with actual SB registers, $*$<mem> forced the
-//		instruction encoding to use a full 32-bit constant, never a
-//		reference relative to SB.
-//
-//	$<floating point literal>
-//		Floating point constant value.
-//		Encoding:
-//			type = TYPE_FCONST
-//			u.dval = floating point value
-//
-//	$<string literal, up to 8 chars>
-//		String literal value (raw bytes used for DATA instruction).
-//		Encoding:
-//			type = TYPE_SCONST
-//			u.sval = string
-//
-//	<register name>
-//		Any register: integer, floating point, control, segment, and so on.
-//		If looking for specific register kind, must check type and reg value range.
-//		Encoding:
-//			type = TYPE_REG
-//			reg = reg (REG_*)
-//
-//	x(PC)
-//		Encoding:
-//			type = TYPE_BRANCH
-//			u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority)
-//
-//	$±x-±y
-//		Final argument to TEXT, specifying local frame size x and argument size y.
-//		In this form, x and y are integer literals only, not arbitrary expressions.
-//		This avoids parsing ambiguities due to the use of - as a separator.
-//		The ± are optional.
-//		If the final argument to TEXT omits the -±y, the encoding should still
-//		use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
-//		Encoding:
-//			type = TYPE_TEXTSIZE
-//			offset = x
-//			u.argsize = y
-//
-//	reg<<shift, reg>>shift, reg->shift, reg@>shift
-//		Shifted register value, for ARM.
-//		In this form, reg must be a register and shift can be a register or an integer constant.
-//		Encoding:
-//			type = TYPE_SHIFT
-//			offset = (reg&15) | shifttype<<5 | count
-//			shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
-//			count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
-//
-//	(reg, reg)
-//		A destination register pair. When used as the last argument of an instruction,
-//		this form makes clear that both registers are destinations.
-//		Encoding:
-//			type = TYPE_REGREG
-//			reg = first register
-//			offset = second register
-//
-//	reg, reg
-//		TYPE_REGREG2, to be removed.
-//
-struct	Addr
-{
-	int16	type; // could be int8
-	int16	reg;
-	int16	index;
-	int8	scale;
-	int8	name;
-	int64	offset;
-	LSym*	sym;
-	
-	union
-	{
-		char	sval[8];
-		float64	dval;
-		Prog*	branch;
-		int32	argsize;	// for 5l, 8l
-		uint64	bits; // raw union bits, for testing if anything has been written to any field
-	} u;
-
-	// gotype is the name of the Go type descriptor for sym.
-	// It cannot be set using assembly syntax.
-	// It is generated by the Go compiler for global declarations,
-	// to convey information about pointer locations to the back end
-	// and for use in generating debug information.
-	LSym*	gotype;
-
-	int8	class;	// for internal use by liblink
-	uint8	etype; // for internal use by 5g, 6g, 8g
-	void*	node; // for internal use by 5g, 6g, 8g
-	int64	width; // for internal use by 5g, 6g, 8g
-};
-
-enum {
-	NAME_NONE = 0,
-	NAME_EXTERN,
-	NAME_STATIC,
-	NAME_AUTO,
-	NAME_PARAM,
-};
-
-enum {
-	TYPE_NONE = 0,
-	TYPE_BRANCH = 5, // avoid accidental conflicts with NAME_* 
-	TYPE_TEXTSIZE,
-	TYPE_MEM,
-	TYPE_CONST,
-	TYPE_FCONST,
-	TYPE_SCONST,
-	TYPE_REG,
-	TYPE_ADDR,
-	TYPE_SHIFT,
-	TYPE_REGREG,
-	TYPE_REGREG2,
-	TYPE_INDIR,
-};
-
 struct	Reloc
 {
 	int32	off;
@@ -208,79 +52,6 @@
 	LSym*	xsym;
 };
 
-// TODO(rsc): Describe prog.
-// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
-struct	Prog
-{
-	vlong	pc;
-	int32	lineno;
-	Prog*	link;
-	short	as;
-	uchar	scond; // arm only; condition codes
-
-	// operands
-	Addr	from;
-	int16	reg; // arm, ppc64 only (e.g., ADD from, reg, to);
-		     // starts at 0 for both GPRs and FPRs;
-		     // also used for ADATA width on arm, ppc64
-	Addr	from3; // addl source argument (e.g., RLWM/FMADD from, reg, from3, to)
-	Addr	to;
-	
-	// for 5g, 6g, 8g internal use
-	void*	opt;
-
-	// for liblink internal use
-	Prog*	forwd;
-	Prog*	pcond;
-	Prog*	comefrom;	// amd64, 386
-	Prog*	pcrel;	// arm
-	int32	spadj;
-	uint16	mark;
-	uint16	optab;	// arm, ppc64
-	uchar	back;	// amd64, 386
-	uchar	ft;	// oclass cache
-	uchar	tt;	// oclass cache
-	uchar	isize;	// amd64, 386
-	uchar	printed;
-
-	char	width;	/* fake for DATA */
-	char	mode;	/* 16, 32, or 64 in 6l, 8l; internal use in 5g, 6g, 8g */
-};
-
-extern Prog zprog; // zeroed Prog
-
-// Prog.as opcodes.
-// These are the portable opcodes, common to all architectures.
-// Each architecture defines many more arch-specific opcodes,
-// with values starting at A_ARCHSPECIFIC.
-enum {
-	AXXX = 0,
-
-	ACALL,
-	ACHECKNIL,
-	ADATA,
-	ADUFFCOPY,
-	ADUFFZERO,
-	AEND,
-	AFUNCDATA,
-	AGLOBL,
-	AJMP,
-	ANOP,
-	APCDATA,
-	ARET,
-	ATEXT,
-	ATYPE,
-	AUNDEF,
-	AUSEFIELD,
-	AVARDEF,
-	AVARKILL,
-	
-	A_ARCHSPECIFIC, // first architecture-specific opcode value
-};
-
-void	nopout(Prog*);
-void	nocache(Prog*);
-
 // prevent incompatible type signatures between liblink and 8l on Plan 9
 #pragma incomplete struct Section
 
@@ -300,12 +71,8 @@
 	uchar	stkcheck;
 	uchar	hide;
 	uchar	leaf;	// arm only
-	uchar	fnptr;	// arm only
 	uchar	localentry;	// ppc64: instrs between global & local entry
-	uchar	seenglobl;
 	uchar	onlist;	// on the textp or datap lists
-	uchar	printed;
-	int16	symid;	// for writing .5/.6/.8 files
 	int32	dynid;
 	int32	sig;
 	int32	plt;
@@ -331,8 +98,6 @@
 	
 	// STEXT
 	Auto*	autom;
-	Prog*	text;
-	Prog*	etext;
 	Pcln*	pcln;
 
 	// SDATA, SBSS
@@ -454,23 +219,6 @@
 	LINKHASH = 100003,
 };
 
-struct	Hist
-{
-	Hist*	link;
-	char*	name;
-	int32	line;
-	int32	offset;
-	uchar	printed;
-};
-
-struct	Plist
-{
-	LSym*	name;
-	Prog*	firstpc;
-	int	recur;
-	Plist*	link;
-};
-
 struct	Library
 {
 	char *objref;	// object where we found the reference
@@ -539,65 +287,21 @@
 	int	headtype;
 
 	LinkArch*	arch;
-	int32	(*ignore)(char*);	// do not emit names satisfying this function
 	int32	debugasm;	// -S flag in compiler
-	int32	debugline;	// -L flag in compiler
-	int32	debughist;	// -O flag in linker
-	int32	debugread;	// -W flag in linker
 	int32	debugvlog;	// -v flag in linker
-	int32	debugstack;	// -K flag in linker
-	int32	debugzerostack;	// -Z flag in linker
-	int32	debugdivmod;	// -M flag in 5l
-	int32	debugfloat;	// -F flag in 5l
-	int32	debugpcln;	// -O flag in linker
-	int32	flag_shared;	// -shared flag in linker
-	int32	iself;
 	Biobuf*	bso;	// for -v flag
-	char*	pathname;
 	int32	windows;
-	char*	trimpath;
 	char*	goroot;
-	char*	goroot_final;
-	int32	enforce_data_order;	// for use by assembler
 
 	// hash table of all symbols
 	LSym*	hash[LINKHASH];
 	LSym*	allsym;
 	int32	nsymbol;
-
-	// file-line history
-	Hist*	hist;
-	Hist*	ehist;
-	
-	// all programs
-	Plist*	plist;
-	Plist*	plast;
 	
 	// code generation
-	LSym*	sym_div;
-	LSym*	sym_divu;
-	LSym*	sym_mod;
-	LSym*	sym_modu;
-	LSym*	symmorestack[2];
 	LSym*	tlsg;
-	LSym*	plan9privates;
-	Prog*	curp;
-	Prog*	printp;
-	Prog*	blitrl;
-	Prog*	elitrl;
-	int	rexflag;
-	int	rep; // for nacl
-	int	repn; // for nacl
-	int	lock; // for nacl
-	int	asmode;
-	uchar*	andptr;
-	uchar	and[100];
-	int64	instoffset;
-	int32	autosize;
-	int32	armsize;
 
 	// for reading input files (during linker)
-	vlong	pc;
 	char**	libdir;
 	int32	nlibdir;
 	int32	maxlibdir;
@@ -606,14 +310,10 @@
 	int	nlibrary;
 	int	tlsoffset;
 	void	(*diag)(char*, ...);
-	int	mode;
-	Auto*	curauto;
-	Auto*	curhist;
 	LSym*	cursym;
 	int	version;
 	LSym*	textp;
 	LSym*	etextp;
-	int32	histdepth;
 	int32	nhistfile;
 	LSym*	filesyms;
 };
@@ -630,11 +330,6 @@
 	int	thechar;	// '5', '6', and so on
 	int32	endian; // LittleEndian or BigEndian
 
-	void	(*preprocess)(Link*, LSym*);
-	void	(*assemble)(Link*, LSym*);
-	void	(*follow)(Link*, LSym*);
-	void	(*progedit)(Link*, Prog*);
-
 	int	minlc;
 	int	ptrsize;
 	int	regsize;
@@ -670,24 +365,11 @@
 extern	uchar	inuxi4[4];
 extern	uchar	inuxi8[8];
 
-// asm5.c
-void	span5(Link *ctxt, LSym *s);
-int	chipfloat5(Link *ctxt, float64 e);
-int	chipzero5(Link *ctxt, float64 e);
-
-// asm6.c
-void	span6(Link *ctxt, LSym *s);
-
-// asm8.c
-void	span8(Link *ctxt, LSym *s);
-
-// asm9.c
-void	span9(Link *ctxt, LSym *s);
-
-// data.c
 vlong	addaddr(Link *ctxt, LSym *s, LSym *t);
 vlong	addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
 vlong	addaddrplus4(Link *ctxt, LSym *s, LSym *t, vlong add);
+void	addlib(Link *ctxt, char *src, char *obj, char *pathname);
+void	addlibpath(Link *ctxt, char *srcref, char *objref, char *file, char *pkg);
 vlong	addpcrelplus(Link *ctxt, LSym *s, LSym *t, vlong add);
 Reloc*	addrel(LSym *s);
 vlong	addsize(Link *ctxt, LSym *s, LSym *t);
@@ -696,91 +378,28 @@
 vlong	adduint64(Link *ctxt, LSym *s, uint64 v);
 vlong	adduint8(Link *ctxt, LSym *s, uint8 v);
 vlong	adduintxx(Link *ctxt, LSym *s, uint64 v, int wid);
-void	mangle(char *file);
-void	savedata(Link *ctxt, LSym *s, Prog *p, char *pn);
-void	savedata1(Link *ctxt, LSym *s, Prog *p, char *pn, int enforce_order);
-vlong	setaddr(Link *ctxt, LSym *s, vlong off, LSym *t);
-vlong	setaddrplus(Link *ctxt, LSym *s, vlong off, LSym *t, vlong add);
-vlong	setuint16(Link *ctxt, LSym *s, vlong r, uint16 v);
-vlong	setuint32(Link *ctxt, LSym *s, vlong r, uint32 v);
-vlong	setuint64(Link *ctxt, LSym *s, vlong r, uint64 v);
-vlong	setuint8(Link *ctxt, LSym *s, vlong r, uint8 v);
-vlong	setuintxx(Link *ctxt, LSym *s, vlong off, uint64 v, vlong wid);
-void	symgrow(Link *ctxt, LSym *s, vlong siz);
-
-// go.c
-void	double2ieee(uint64 *ieee, double native);
+vlong	atolwhex(char *s);
 void*	emallocz(long n);
 void*	erealloc(void *p, long n);
 char*	estrdup(char *p);
 char*	expandpkg(char *t0, char *pkg);
-void	linksetexp(void);
-char*	expstring(void);
-
-extern	int	fieldtrack_enabled;
-extern	int	framepointer_enabled;
-
-// ld.c
-void	addhist(Link *ctxt, int32 line, int type);
-void	addlib(Link *ctxt, char *src, char *obj, char *path);
-void	addlibpath(Link *ctxt, char *srcref, char *objref, char *file, char *pkg);
-void	collapsefrog(Link *ctxt, LSym *s);
-void	copyhistfrog(Link *ctxt, char *buf, int nbuf);
 int	find1(int32 l, int c);
-void	linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l);
-void	histtoauto(Link *ctxt);
-void	mkfwd(LSym*);
-void	nuxiinit(LinkArch*);
-void	savehist(Link *ctxt, int32 line, int32 off);
-Prog*	copyp(Link*, Prog*);
-Prog*	appendp(Link*, Prog*);
-vlong	atolwhex(char*);
-
-// list[5689].c
-void	listinit5(void);
-void	listinit6(void);
-void	listinit8(void);
-void	listinit9(void);
-
-// obj.c
-int	linklinefmt(Link *ctxt, Fmt *fp);
-void	linklinehist(Link *ctxt, int lineno, char *f, int offset);
-Plist*	linknewplist(Link *ctxt);
-void	linkprfile(Link *ctxt, int32 l);
-
-// objfile.c
-void	ldobjfile(Link *ctxt, Biobuf *b, char *pkg, int64 len, char *path);
-void	writeobj(Link *ctxt, Biobuf *b);
-
-// pass.c
-Prog*	brchain(Link *ctxt, Prog *p);
-Prog*	brloop(Link *ctxt, Prog *p);
-void	linkpatch(Link *ctxt, LSym *sym);
-
-// pcln.c
-void	linkpcln(Link*, LSym*);
-
-// sym.c
+char*	headstr(int v);
+int	headtype(char *name);
+void	ldobjfile(Link *ctxt, Biobuf *f, char *pkg, int64 len, char *pn);
 LSym*	linklookup(Link *ctxt, char *name, int v);
-Link*	linknew(LinkArch*);
+Link*	linknew(LinkArch *arch);
 LSym*	linknewsym(Link *ctxt, char *symb, int v);
 LSym*	linkrlookup(Link *ctxt, char *name, int v);
-int	linksymfmt(Fmt *f);
-int	headtype(char*);
-char*	headstr(int);
-
-extern	char*	anames5[];
-extern	char*	anames6[];
-extern	char*	anames8[];
-extern	char*	anames9[];
-
-extern	char*	cnames5[];
-extern	char*	cnames9[];
-
-extern	char*	dnames5[];
-extern	char*	dnames6[];
-extern	char*	dnames8[];
-extern	char*	dnames9[];
+void	nuxiinit(LinkArch *arch);
+void	pciterinit(Link *ctxt, Pciter *it, Pcdata *d);
+void	pciternext(Pciter *it);
+vlong	setaddr(Link *ctxt, LSym *s, vlong off, LSym *t);
+vlong	setaddrplus(Link *ctxt, LSym *s, vlong off, LSym *t, vlong add);
+vlong	setuint32(Link *ctxt, LSym *s, vlong r, uint32 v);
+vlong	setuint8(Link *ctxt, LSym *s, vlong r, uint8 v);
+vlong	setuintxx(Link *ctxt, LSym *s, vlong off, uint64 v, vlong wid);
+void	symgrow(Link *ctxt, LSym *s, vlong lsiz);
 
 extern	LinkArch	link386;
 extern	LinkArch	linkamd64;
@@ -788,18 +407,3 @@
 extern	LinkArch	linkarm;
 extern	LinkArch	linkppc64;
 extern	LinkArch	linkppc64le;
-
-extern	int	linkbasepointer;
-extern	void	linksetexp(void);
-
-#pragma	varargck	type	"A"	int
-#pragma	varargck	type	"E"	uint
-#pragma	varargck	type	"D"	Addr*
-#pragma	varargck	type	"lD"	Addr*
-#pragma	varargck	type	"P"	Prog*
-#pragma	varargck	type	"R"	int
-#pragma	varargck	type	"^"	int // for 5l/9l, C_* classes (liblink internal)
-
-// TODO(ality): remove this workaround.
-//   It's here because Pconv in liblink/list?.c references %L.
-#pragma	varargck	type	"L"	int32
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
deleted file mode 100644
index a266a6b..0000000
--- a/src/cmd/5l/5.out.h
+++ /dev/null
@@ -1,336 +0,0 @@
-// Inferno utils/5c/5.out.h
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/5.out.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.
-
-enum
-{
-	NSNAME = 8,
-	NSYM = 50,
-	NREG = 16,
-};
-#include "../ld/textflag.h"
-
-/* -1 disables use of REGARG */
-#define	REGARG		-1
-/*c2go enum { REGARG = -1 }; */
-
-enum
-{
-	REG_R0 = 32, // must be 16-aligned
-	REG_R1,
-	REG_R2,
-	REG_R3,
-	REG_R4,
-	REG_R5,
-	REG_R6,
-	REG_R7,
-	REG_R8,
-	REG_R9,
-	REG_R10,
-	REG_R11,
-	REG_R12,
-	REG_R13,
-	REG_R14,
-	REG_R15,
-	
-	REG_F0, // must be 16-aligned
-	REG_F1,
-	REG_F2,
-	REG_F3,
-	REG_F4,
-	REG_F5,
-	REG_F6,
-	REG_F7,
-	REG_F8,
-	REG_F9,
-	REG_F10,
-	REG_F11,
-	REG_F12,
-	REG_F13,
-	REG_F14,
-	REG_F15,
-
-	REG_FPSR, // must be 2-aligned
-	REG_FPCR,
-
-	REG_CPSR, // must be 2-aligned
-	REG_SPSR,
-
-	REGRET = REG_R0,
-	/* compiler allocates R1 up as temps */
-	/* compiler allocates register variables R3 up */
-	/* compiler allocates external registers R10 down */
-	REGEXT = REG_R10,
-	/* these two registers are declared in runtime.h */
-	REGG = REGEXT-0,
-	REGM = REGEXT-1,
-
-	REGCTXT = REG_R7,
-	REGTMP = REG_R11,
-	REGSP = REG_R13,
-	REGLINK = REG_R14,
-	REGPC = REG_R15,
-	
-	NFREG = 16,
-	FREGRET = REG_F0,
-	FREGEXT = REG_F7,
-	FREGTMP = REG_F15,
-};
-/* compiler allocates register variables F0 up */
-/* compiler allocates external registers F7 down */
-
-enum
-{
-	C_NONE,
-	C_REG,
-	C_REGREG,
-	C_REGREG2,
-	C_SHIFT,
-	C_FREG,
-	C_PSR,
-	C_FCR,
-
-	C_RCON,		/* 0xff rotated */
-	C_NCON,		/* ~RCON */
-	C_SCON,		/* 0xffff */
-	C_LCON,
-	C_LCONADDR,
-	C_ZFCON,
-	C_SFCON,
-	C_LFCON,
-
-	C_RACON,
-	C_LACON,
-
-	C_SBRA,
-	C_LBRA,
-
-	C_HAUTO,	/* halfword insn offset (-0xff to 0xff) */
-	C_FAUTO,	/* float insn offset (0 to 0x3fc, word aligned) */
-	C_HFAUTO,	/* both H and F */
-	C_SAUTO,	/* -0xfff to 0xfff */
-	C_LAUTO,
-
-	C_HOREG,
-	C_FOREG,
-	C_HFOREG,
-	C_SOREG,
-	C_ROREG,
-	C_SROREG,	/* both nil and R */
-	C_LOREG,
-
-	C_PC,
-	C_SP,
-	C_HREG,
-
-	C_ADDR,		/* reference to relocatable address */
-	C_TEXTSIZE,
-
-	C_GOK,
-
-	C_NCLASS,	/* must be the last */
-};
-
-enum
-{
-	AAND = A_ARCHSPECIFIC,
-	AEOR,
-	ASUB,
-	ARSB,
-	AADD,
-	AADC,
-	ASBC,
-	ARSC,
-	ATST,
-	ATEQ,
-	ACMP,
-	ACMN,
-	AORR,
-	ABIC,
-
-	AMVN,
-
-/*
- * Do not reorder or fragment the conditional branch
- * opcodes, or the predication code will break
- */
-	ABEQ,
-	ABNE,
-	ABCS,
-	ABHS,
-	ABCC,
-	ABLO,
-	ABMI,
-	ABPL,
-	ABVS,
-	ABVC,
-	ABHI,
-	ABLS,
-	ABGE,
-	ABLT,
-	ABGT,
-	ABLE,
-
-	AMOVWD,
-	AMOVWF,
-	AMOVDW,
-	AMOVFW,
-	AMOVFD,
-	AMOVDF,
-	AMOVF,
-	AMOVD,
-
-	ACMPF,
-	ACMPD,
-	AADDF,
-	AADDD,
-	ASUBF,
-	ASUBD,
-	AMULF,
-	AMULD,
-	ADIVF,
-	ADIVD,
-	ASQRTF,
-	ASQRTD,
-	AABSF,
-	AABSD,
-
-	ASRL,
-	ASRA,
-	ASLL,
-	AMULU,
-	ADIVU,
-	AMUL,
-	ADIV,
-	AMOD,
-	AMODU,
-
-	AMOVB,
-	AMOVBS,
-	AMOVBU,
-	AMOVH,
-	AMOVHS,
-	AMOVHU,
-	AMOVW,
-	AMOVM,
-	ASWPBU,
-	ASWPW,
-
-	ARFE,
-	ASWI,
-	AMULA,
-
-	AWORD,
-	ABCASE,
-	ACASE,
-
-
-	AMULL,
-	AMULAL,
-	AMULLU,
-	AMULALU,
-
-	ABX,
-	ABXRET,
-	ADWORD,
-
-
-	ALDREX,
-	ASTREX,
-	
-	ALDREXD,
-	ASTREXD,
-
-	APLD,
-
-
-	ACLZ,
-
-	AMULWT,
-	AMULWB,
-	AMULAWT,
-	AMULAWB,
-	
-	ADATABUNDLE,
-	ADATABUNDLEEND,
-
-	AMRC, // MRC/MCR
-
-	ALAST,
-	
-	// aliases
-	AB = AJMP,
-	ABL = ACALL,
-};
-
-/* scond byte */
-enum
-{
-	C_SCOND = (1<<4)-1,
-	C_SBIT = 1<<4,
-	C_PBIT = 1<<5,
-	C_WBIT = 1<<6,
-	C_FBIT = 1<<7,	/* psr flags-only */
-	C_UBIT = 1<<7,	/* up bit, unsigned bit */
-
-	// These constants are the ARM condition codes encodings,
-	// XORed with 14 so that C_SCOND_NONE has value 0,
-	// so that a zeroed Prog.scond means "always execute".
-	C_SCOND_XOR = 14,
-
-	C_SCOND_EQ = 0 ^ C_SCOND_XOR,
-	C_SCOND_NE = 1 ^ C_SCOND_XOR,
-	C_SCOND_HS = 2 ^ C_SCOND_XOR,
-	C_SCOND_LO = 3 ^ C_SCOND_XOR,
-	C_SCOND_MI = 4 ^ C_SCOND_XOR,
-	C_SCOND_PL = 5 ^ C_SCOND_XOR,
-	C_SCOND_VS = 6 ^ C_SCOND_XOR,
-	C_SCOND_VC = 7 ^ C_SCOND_XOR,
-	C_SCOND_HI = 8 ^ C_SCOND_XOR,
-	C_SCOND_LS = 9 ^ C_SCOND_XOR,
-	C_SCOND_GE = 10 ^ C_SCOND_XOR,
-	C_SCOND_LT = 11 ^ C_SCOND_XOR,
-	C_SCOND_GT = 12 ^ C_SCOND_XOR,
-	C_SCOND_LE = 13 ^ C_SCOND_XOR,
-	C_SCOND_NONE = 14 ^ C_SCOND_XOR,
-	C_SCOND_NV = 15 ^ C_SCOND_XOR,
-
-	/* D_SHIFT type */
-	SHIFT_LL = 0<<5,
-	SHIFT_LR = 1<<5,
-	SHIFT_AR = 2<<5,
-	SHIFT_RR = 3<<5,
-};
-
-
-/*
- * this is the ranlib header
- */
-#define	SYMDEF	"__.GOSYMDEF"
-/*c2go extern char SYMDEF[]; */
diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h
index b32b89b..0258d5a 100644
--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -57,7 +57,6 @@
 void	asmb(void);
 int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
-void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
 
 /* Used by ../ld/dwarf.c */
diff --git a/src/cmd/5l/list.c b/src/cmd/5l/list.c
deleted file mode 100644
index d4cc8ac..0000000
--- a/src/cmd/5l/list.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// Inferno utils/5l/list.h
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.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.
-
-// Printing.
-
-#include "l.h"
-#include "../ld/lib.h"
-
-void
-listinit(void)
-{
-	listinit5();
-}
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
index a7bd0f4..887cc5a 100644
--- a/src/cmd/5l/obj.c
+++ b/src/cmd/5l/obj.c
@@ -70,7 +70,6 @@
 	thearch.elfreloc1 = elfreloc1;
 	thearch.elfsetupplt = elfsetupplt;
 	thearch.gentext = gentext;
-	thearch.listinit = listinit;
 	thearch.machoreloc1 = machoreloc1;
 	thearch.lput = lputl;
 	thearch.wput = wputl;
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
deleted file mode 100644
index e25c6ef..0000000
--- a/src/cmd/6l/6.out.h
+++ /dev/null
@@ -1,855 +0,0 @@
-// Inferno utils/6c/6.out.h
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/6.out.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	NSYM	50
-#define	NSNAME	8
-#include "../ld/textflag.h"
-
-/*
- *	amd64
- */
-
-enum
-{
-	AAAA = A_ARCHSPECIFIC,
-	AAAD,
-	AAAM,
-	AAAS,
-	AADCB,
-	AADCL,
-	AADCW,
-	AADDB,
-	AADDL,
-	AADDW,
-	AADJSP,
-	AANDB,
-	AANDL,
-	AANDW,
-	AARPL,
-	ABOUNDL,
-	ABOUNDW,
-	ABSFL,
-	ABSFW,
-	ABSRL,
-	ABSRW,
-	ABTL,
-	ABTW,
-	ABTCL,
-	ABTCW,
-	ABTRL,
-	ABTRW,
-	ABTSL,
-	ABTSW,
-	ABYTE,
-	ACLC,
-	ACLD,
-	ACLI,
-	ACLTS,
-	ACMC,
-	ACMPB,
-	ACMPL,
-	ACMPW,
-	ACMPSB,
-	ACMPSL,
-	ACMPSW,
-	ADAA,
-	ADAS,
-	ADECB,
-	ADECL,
-	ADECQ,
-	ADECW,
-	ADIVB,
-	ADIVL,
-	ADIVW,
-	AENTER,
-	AHLT,
-	AIDIVB,
-	AIDIVL,
-	AIDIVW,
-	AIMULB,
-	AIMULL,
-	AIMULW,
-	AINB,
-	AINL,
-	AINW,
-	AINCB,
-	AINCL,
-	AINCQ,
-	AINCW,
-	AINSB,
-	AINSL,
-	AINSW,
-	AINT,
-	AINTO,
-	AIRETL,
-	AIRETW,
-	AJCC,
-	AJCS,
-	AJCXZL,
-	AJEQ,
-	AJGE,
-	AJGT,
-	AJHI,
-	AJLE,
-	AJLS,
-	AJLT,
-	AJMI,
-	AJNE,
-	AJOC,
-	AJOS,
-	AJPC,
-	AJPL,
-	AJPS,
-	ALAHF,
-	ALARL,
-	ALARW,
-	ALEAL,
-	ALEAW,
-	ALEAVEL,
-	ALEAVEW,
-	ALOCK,
-	ALODSB,
-	ALODSL,
-	ALODSW,
-	ALONG,
-	ALOOP,
-	ALOOPEQ,
-	ALOOPNE,
-	ALSLL,
-	ALSLW,
-	AMOVB,
-	AMOVL,
-	AMOVW,
-	AMOVBLSX,
-	AMOVBLZX,
-	AMOVBQSX,
-	AMOVBQZX,
-	AMOVBWSX,
-	AMOVBWZX,
-	AMOVWLSX,
-	AMOVWLZX,
-	AMOVWQSX,
-	AMOVWQZX,
-	AMOVSB,
-	AMOVSL,
-	AMOVSW,
-	AMULB,
-	AMULL,
-	AMULW,
-	ANEGB,
-	ANEGL,
-	ANEGW,
-	ANOTB,
-	ANOTL,
-	ANOTW,
-	AORB,
-	AORL,
-	AORW,
-	AOUTB,
-	AOUTL,
-	AOUTW,
-	AOUTSB,
-	AOUTSL,
-	AOUTSW,
-	APAUSE,
-	APOPAL,
-	APOPAW,
-	APOPFL,
-	APOPFW,
-	APOPL,
-	APOPW,
-	APUSHAL,
-	APUSHAW,
-	APUSHFL,
-	APUSHFW,
-	APUSHL,
-	APUSHW,
-	ARCLB,
-	ARCLL,
-	ARCLW,
-	ARCRB,
-	ARCRL,
-	ARCRW,
-	AREP,
-	AREPN,
-	AROLB,
-	AROLL,
-	AROLW,
-	ARORB,
-	ARORL,
-	ARORW,
-	ASAHF,
-	ASALB,
-	ASALL,
-	ASALW,
-	ASARB,
-	ASARL,
-	ASARW,
-	ASBBB,
-	ASBBL,
-	ASBBW,
-	ASCASB,
-	ASCASL,
-	ASCASW,
-	ASETCC,
-	ASETCS,
-	ASETEQ,
-	ASETGE,
-	ASETGT,
-	ASETHI,
-	ASETLE,
-	ASETLS,
-	ASETLT,
-	ASETMI,
-	ASETNE,
-	ASETOC,
-	ASETOS,
-	ASETPC,
-	ASETPL,
-	ASETPS,
-	ACDQ,
-	ACWD,
-	ASHLB,
-	ASHLL,
-	ASHLW,
-	ASHRB,
-	ASHRL,
-	ASHRW,
-	ASTC,
-	ASTD,
-	ASTI,
-	ASTOSB,
-	ASTOSL,
-	ASTOSW,
-	ASUBB,
-	ASUBL,
-	ASUBW,
-	ASYSCALL,
-	ATESTB,
-	ATESTL,
-	ATESTW,
-	AVERR,
-	AVERW,
-	AWAIT,
-	AWORD,
-	AXCHGB,
-	AXCHGL,
-	AXCHGW,
-	AXLAT,
-	AXORB,
-	AXORL,
-	AXORW,
-
-	AFMOVB,
-	AFMOVBP,
-	AFMOVD,
-	AFMOVDP,
-	AFMOVF,
-	AFMOVFP,
-	AFMOVL,
-	AFMOVLP,
-	AFMOVV,
-	AFMOVVP,
-	AFMOVW,
-	AFMOVWP,
-	AFMOVX,
-	AFMOVXP,
-
-	AFCOMB,
-	AFCOMBP,
-	AFCOMD,
-	AFCOMDP,
-	AFCOMDPP,
-	AFCOMF,
-	AFCOMFP,
-	AFCOML,
-	AFCOMLP,
-	AFCOMW,
-	AFCOMWP,
-	AFUCOM,
-	AFUCOMP,
-	AFUCOMPP,
-
-	AFADDDP,
-	AFADDW,
-	AFADDL,
-	AFADDF,
-	AFADDD,
-
-	AFMULDP,
-	AFMULW,
-	AFMULL,
-	AFMULF,
-	AFMULD,
-
-	AFSUBDP,
-	AFSUBW,
-	AFSUBL,
-	AFSUBF,
-	AFSUBD,
-
-	AFSUBRDP,
-	AFSUBRW,
-	AFSUBRL,
-	AFSUBRF,
-	AFSUBRD,
-
-	AFDIVDP,
-	AFDIVW,
-	AFDIVL,
-	AFDIVF,
-	AFDIVD,
-
-	AFDIVRDP,
-	AFDIVRW,
-	AFDIVRL,
-	AFDIVRF,
-	AFDIVRD,
-
-	AFXCHD,
-	AFFREE,
-
-	AFLDCW,
-	AFLDENV,
-	AFRSTOR,
-	AFSAVE,
-	AFSTCW,
-	AFSTENV,
-	AFSTSW,
-
-	AF2XM1,
-	AFABS,
-	AFCHS,
-	AFCLEX,
-	AFCOS,
-	AFDECSTP,
-	AFINCSTP,
-	AFINIT,
-	AFLD1,
-	AFLDL2E,
-	AFLDL2T,
-	AFLDLG2,
-	AFLDLN2,
-	AFLDPI,
-	AFLDZ,
-	AFNOP,
-	AFPATAN,
-	AFPREM,
-	AFPREM1,
-	AFPTAN,
-	AFRNDINT,
-	AFSCALE,
-	AFSIN,
-	AFSINCOS,
-	AFSQRT,
-	AFTST,
-	AFXAM,
-	AFXTRACT,
-	AFYL2X,
-	AFYL2XP1,
-
-
-
-
-	/* extra 32-bit operations */
-	ACMPXCHGB,
-	ACMPXCHGL,
-	ACMPXCHGW,
-	ACMPXCHG8B,
-	ACPUID,
-	AINVD,
-	AINVLPG,
-	ALFENCE,
-	AMFENCE,
-	AMOVNTIL,
-	ARDMSR,
-	ARDPMC,
-	ARDTSC,
-	ARSM,
-	ASFENCE,
-	ASYSRET,
-	AWBINVD,
-	AWRMSR,
-	AXADDB,
-	AXADDL,
-	AXADDW,
-
-	/* conditional move */
-	ACMOVLCC,
-	ACMOVLCS,
-	ACMOVLEQ,
-	ACMOVLGE,
-	ACMOVLGT,
-	ACMOVLHI,
-	ACMOVLLE,
-	ACMOVLLS,
-	ACMOVLLT,
-	ACMOVLMI,
-	ACMOVLNE,
-	ACMOVLOC,
-	ACMOVLOS,
-	ACMOVLPC,
-	ACMOVLPL,
-	ACMOVLPS,
-	ACMOVQCC,
-	ACMOVQCS,
-	ACMOVQEQ,
-	ACMOVQGE,
-	ACMOVQGT,
-	ACMOVQHI,
-	ACMOVQLE,
-	ACMOVQLS,
-	ACMOVQLT,
-	ACMOVQMI,
-	ACMOVQNE,
-	ACMOVQOC,
-	ACMOVQOS,
-	ACMOVQPC,
-	ACMOVQPL,
-	ACMOVQPS,
-	ACMOVWCC,
-	ACMOVWCS,
-	ACMOVWEQ,
-	ACMOVWGE,
-	ACMOVWGT,
-	ACMOVWHI,
-	ACMOVWLE,
-	ACMOVWLS,
-	ACMOVWLT,
-	ACMOVWMI,
-	ACMOVWNE,
-	ACMOVWOC,
-	ACMOVWOS,
-	ACMOVWPC,
-	ACMOVWPL,
-	ACMOVWPS,
-
-	/* 64-bit */
-	AADCQ,
-	AADDQ,
-	AANDQ,
-	ABSFQ,
-	ABSRQ,
-	ABTCQ,
-	ABTQ,
-	ABTRQ,
-	ABTSQ,
-	ACMPQ,
-	ACMPSQ,
-	ACMPXCHGQ,
-	ACQO,
-	ADIVQ,
-	AIDIVQ,
-	AIMULQ,
-	AIRETQ,
-	AJCXZQ,
-	ALEAQ,
-	ALEAVEQ,
-	ALODSQ,
-	AMOVQ,
-	AMOVLQSX,
-	AMOVLQZX,
-	AMOVNTIQ,
-	AMOVSQ,
-	AMULQ,
-	ANEGQ,
-	ANOTQ,
-	AORQ,
-	APOPFQ,
-	APOPQ,
-	APUSHFQ,
-	APUSHQ,
-	ARCLQ,
-	ARCRQ,
-	AROLQ,
-	ARORQ,
-	AQUAD,
-	ASALQ,
-	ASARQ,
-	ASBBQ,
-	ASCASQ,
-	ASHLQ,
-	ASHRQ,
-	ASTOSQ,
-	ASUBQ,
-	ATESTQ,
-	AXADDQ,
-	AXCHGQ,
-	AXORQ,
-
-	/* media */
-	AADDPD,
-	AADDPS,
-	AADDSD,
-	AADDSS,
-	AANDNPD,
-	AANDNPS,
-	AANDPD,
-	AANDPS,
-	ACMPPD,
-	ACMPPS,
-	ACMPSD,
-	ACMPSS,
-	ACOMISD,
-	ACOMISS,
-	ACVTPD2PL,
-	ACVTPD2PS,
-	ACVTPL2PD,
-	ACVTPL2PS,
-	ACVTPS2PD,
-	ACVTPS2PL,
-	ACVTSD2SL,
-	ACVTSD2SQ,
-	ACVTSD2SS,
-	ACVTSL2SD,
-	ACVTSL2SS,
-	ACVTSQ2SD,
-	ACVTSQ2SS,
-	ACVTSS2SD,
-	ACVTSS2SL,
-	ACVTSS2SQ,
-	ACVTTPD2PL,
-	ACVTTPS2PL,
-	ACVTTSD2SL,
-	ACVTTSD2SQ,
-	ACVTTSS2SL,
-	ACVTTSS2SQ,
-	ADIVPD,
-	ADIVPS,
-	ADIVSD,
-	ADIVSS,
-	AEMMS,
-	AFXRSTOR,
-	AFXRSTOR64,
-	AFXSAVE,
-	AFXSAVE64,
-	ALDMXCSR,
-	AMASKMOVOU,
-	AMASKMOVQ,
-	AMAXPD,
-	AMAXPS,
-	AMAXSD,
-	AMAXSS,
-	AMINPD,
-	AMINPS,
-	AMINSD,
-	AMINSS,
-	AMOVAPD,
-	AMOVAPS,
-	AMOVOU,
-	AMOVHLPS,
-	AMOVHPD,
-	AMOVHPS,
-	AMOVLHPS,
-	AMOVLPD,
-	AMOVLPS,
-	AMOVMSKPD,
-	AMOVMSKPS,
-	AMOVNTO,
-	AMOVNTPD,
-	AMOVNTPS,
-	AMOVNTQ,
-	AMOVO,
-	AMOVQOZX,
-	AMOVSD,
-	AMOVSS,
-	AMOVUPD,
-	AMOVUPS,
-	AMULPD,
-	AMULPS,
-	AMULSD,
-	AMULSS,
-	AORPD,
-	AORPS,
-	APACKSSLW,
-	APACKSSWB,
-	APACKUSWB,
-	APADDB,
-	APADDL,
-	APADDQ,
-	APADDSB,
-	APADDSW,
-	APADDUSB,
-	APADDUSW,
-	APADDW,
-	APANDB,
-	APANDL,
-	APANDSB,
-	APANDSW,
-	APANDUSB,
-	APANDUSW,
-	APANDW,
-	APAND,
-	APANDN,
-	APAVGB,
-	APAVGW,
-	APCMPEQB,
-	APCMPEQL,
-	APCMPEQW,
-	APCMPGTB,
-	APCMPGTL,
-	APCMPGTW,
-	APEXTRW,
-	APFACC,
-	APFADD,
-	APFCMPEQ,
-	APFCMPGE,
-	APFCMPGT,
-	APFMAX,
-	APFMIN,
-	APFMUL,
-	APFNACC,
-	APFPNACC,
-	APFRCP,
-	APFRCPIT1,
-	APFRCPI2T,
-	APFRSQIT1,
-	APFRSQRT,
-	APFSUB,
-	APFSUBR,
-	APINSRW,
-	APINSRD,
-	APINSRQ,
-	APMADDWL,
-	APMAXSW,
-	APMAXUB,
-	APMINSW,
-	APMINUB,
-	APMOVMSKB,
-	APMULHRW,
-	APMULHUW,
-	APMULHW,
-	APMULLW,
-	APMULULQ,
-	APOR,
-	APSADBW,
-	APSHUFHW,
-	APSHUFL,
-	APSHUFLW,
-	APSHUFW,
-	APSHUFB,
-	APSLLO,
-	APSLLL,
-	APSLLQ,
-	APSLLW,
-	APSRAL,
-	APSRAW,
-	APSRLO,
-	APSRLL,
-	APSRLQ,
-	APSRLW,
-	APSUBB,
-	APSUBL,
-	APSUBQ,
-	APSUBSB,
-	APSUBSW,
-	APSUBUSB,
-	APSUBUSW,
-	APSUBW,
-	APSWAPL,
-	APUNPCKHBW,
-	APUNPCKHLQ,
-	APUNPCKHQDQ,
-	APUNPCKHWL,
-	APUNPCKLBW,
-	APUNPCKLLQ,
-	APUNPCKLQDQ,
-	APUNPCKLWL,
-	APXOR,
-	ARCPPS,
-	ARCPSS,
-	ARSQRTPS,
-	ARSQRTSS,
-	ASHUFPD,
-	ASHUFPS,
-	ASQRTPD,
-	ASQRTPS,
-	ASQRTSD,
-	ASQRTSS,
-	ASTMXCSR,
-	ASUBPD,
-	ASUBPS,
-	ASUBSD,
-	ASUBSS,
-	AUCOMISD,
-	AUCOMISS,
-	AUNPCKHPD,
-	AUNPCKHPS,
-	AUNPCKLPD,
-	AUNPCKLPS,
-	AXORPD,
-	AXORPS,
-
-	APF2IW,
-	APF2IL,
-	API2FW,
-	API2FL,
-	ARETFW,
-	ARETFL,
-	ARETFQ,
-	ASWAPGS,
-
-	AMODE,
-	ACRC32B,
-	ACRC32Q,
-	AIMUL3Q,
-	
-	APREFETCHT0,
-	APREFETCHT1,
-	APREFETCHT2,
-	APREFETCHNTA,
-	
-	AMOVQL,
-	ABSWAPL,
-	ABSWAPQ,
-	
-
-	AAESENC,
-	AAESENCLAST,
-	AAESDEC,
-	AAESDECLAST,
-	AAESIMC,
-	AAESKEYGENASSIST,
-
-	APSHUFD,
-	APCLMULQDQ,
-	
-	
-	ALAST
-};
-
-enum
-{
-	REG_NONE	= 0,
-
-	REG_AL		= 0+16,
-	REG_CL,
-	REG_DL,
-	REG_BL,
-	REG_SPB,
-	REG_BPB,
-	REG_SIB,
-	REG_DIB,
-	REG_R8B,
-	REG_R9B,
-	REG_R10B,
-	REG_R11B,
-	REG_R12B,
-	REG_R13B,
-	REG_R14B,
-	REG_R15B,
-
-	REG_AX		= 16+16,
-	REG_CX,
-	REG_DX,
-	REG_BX,
-	REG_SP,
-	REG_BP,
-	REG_SI,
-	REG_DI,
-	REG_R8,
-	REG_R9,
-	REG_R10,
-	REG_R11,
-	REG_R12,
-	REG_R13,
-	REG_R14,
-	REG_R15,
-
-	REG_AH		= 32+16,
-	REG_CH,
-	REG_DH,
-	REG_BH,
-
-	REG_F0		= 36+16,
-
-	REG_M0		= 44+16,
-
-	REG_X0		= 52+16,
-	REG_X1,
-	REG_X2,
-	REG_X3,
-	REG_X4,
-	REG_X5,
-	REG_X6,
-	REG_X7,
-	REG_X8,
-	REG_X9,
-	REG_X10,
-	REG_X11,
-	REG_X12,
-	REG_X13,
-	REG_X14,
-	REG_X15,
-
-	REG_CS		= 68+16,
-	REG_SS,
-	REG_DS,
-	REG_ES,
-	REG_FS,
-	REG_GS,
-
-	REG_GDTR,		/* global descriptor table register */
-	REG_IDTR,		/* interrupt descriptor table register */
-	REG_LDTR,		/* local descriptor table register */
-	REG_MSW,		/* machine status word */
-	REG_TASK,		/* task register */
-
-	REG_CR		= 79+16,
-	REG_DR		= 95+16,
-	REG_TR		= 103+16,
-
-	REG_TLS		= 111+16,
-	MAXREG,
-
-	REGARG		= -1,
-	REGRET		= REG_AX,
-	FREGRET		= REG_X0,
-	REGSP		= REG_SP,
-	REGTMP		= REG_DI,
-	REGCTXT		= REG_DX,
-	REGEXT		= REG_R15,	/* compiler allocates external registers R15 down */
-	FREGMIN		= REG_X0+5,	/* first register variable */
-	FREGEXT		= REG_X0+15,	/* first external register */
-
-	T_TYPE		= 1<<0,
-	T_INDEX		= 1<<1,
-	T_OFFSET	= 1<<2,
-	T_FCONST	= 1<<3,
-	T_SYM		= 1<<4,
-	T_SCONST	= 1<<5,
-	T_64		= 1<<6,
-	T_GOTYPE	= 1<<7,
-};
-
-/*
- * this is the ranlib header
- */
-#define	SYMDEF	"__.GOSYMDEF"
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index acc97d9..b314e25 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -58,7 +58,6 @@
 void	asmb(void);
 int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
-void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
 
 /* Used by ../ld/dwarf.c */
diff --git a/src/cmd/6l/list.c b/src/cmd/6l/list.c
deleted file mode 100644
index 6c4ea79..0000000
--- a/src/cmd/6l/list.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// Inferno utils/6l/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/list.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.
-
-// Printing.
-
-#include	"l.h"
-#include	"../ld/lib.h"
-
-void
-listinit(void)
-{
-	listinit6();
-}
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c
index 0a2b2cb..ebd4bae 100644
--- a/src/cmd/6l/obj.c
+++ b/src/cmd/6l/obj.c
@@ -72,7 +72,6 @@
 	thearch.elfreloc1 = elfreloc1;
 	thearch.elfsetupplt = elfsetupplt;
 	thearch.gentext = gentext;
-	thearch.listinit = listinit;
 	thearch.machoreloc1 = machoreloc1;
 	thearch.lput = lputl;
 	thearch.wput = wputl;
diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h
deleted file mode 100644
index 273a8ad..0000000
--- a/src/cmd/8l/8.out.h
+++ /dev/null
@@ -1,643 +0,0 @@
-// Inferno utils/8c/8.out.h
-// http://code.google.com/p/inferno-os/source/browse/utils/8c/8.out.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	NSYM	50
-#define	NSNAME	8
-#include "../ld/textflag.h"
-
-enum
-{
-	AAAA = A_ARCHSPECIFIC,
-	AAAD,
-	AAAM,
-	AAAS,
-	AADCB,
-	AADCL,
-	AADCW,
-	AADDB,
-	AADDL,
-	AADDW,
-	AADJSP,
-	AANDB,
-	AANDL,
-	AANDW,
-	AARPL,
-	ABOUNDL,
-	ABOUNDW,
-	ABSFL,
-	ABSFW,
-	ABSRL,
-	ABSRW,
-	ABTL,
-	ABTW,
-	ABTCL,
-	ABTCW,
-	ABTRL,
-	ABTRW,
-	ABTSL,
-	ABTSW,
-	ABYTE,
-	ACLC,
-	ACLD,
-	ACLI,
-	ACLTS,
-	ACMC,
-	ACMPB,
-	ACMPL,
-	ACMPW,
-	ACMPSB,
-	ACMPSL,
-	ACMPSW,
-	ADAA,
-	ADAS,
-	ADECB,
-	ADECL,
-	ADECW,
-	ADIVB,
-	ADIVL,
-	ADIVW,
-	AENTER,
-	AHLT,
-	AIDIVB,
-	AIDIVL,
-	AIDIVW,
-	AIMULB,
-	AIMULL,
-	AIMULW,
-	AINB,
-	AINL,
-	AINW,
-	AINCB,
-	AINCL,
-	AINCW,
-	AINSB,
-	AINSL,
-	AINSW,
-	AINT,
-	AINTO,
-	AIRETL,
-	AIRETW,
-	AJCC,
-	AJCS,
-	AJCXZL,
-	AJCXZW,
-	AJEQ,
-	AJGE,
-	AJGT,
-	AJHI,
-	AJLE,
-	AJLS,
-	AJLT,
-	AJMI,
-	AJNE,
-	AJOC,
-	AJOS,
-	AJPC,
-	AJPL,
-	AJPS,
-	ALAHF,
-	ALARL,
-	ALARW,
-	ALEAL,
-	ALEAW,
-	ALEAVEL,
-	ALEAVEW,
-	ALOCK,
-	ALODSB,
-	ALODSL,
-	ALODSW,
-	ALONG,
-	ALOOP,
-	ALOOPEQ,
-	ALOOPNE,
-	ALSLL,
-	ALSLW,
-	AMOVB,
-	AMOVL,
-	AMOVW,
-	AMOVQ,
-	AMOVBLSX,
-	AMOVBLZX,
-	AMOVBWSX,
-	AMOVBWZX,
-	AMOVWLSX,
-	AMOVWLZX,
-	AMOVSB,
-	AMOVSL,
-	AMOVSW,
-	AMULB,
-	AMULL,
-	AMULW,
-	ANEGB,
-	ANEGL,
-	ANEGW,
-	ANOTB,
-	ANOTL,
-	ANOTW,
-	AORB,
-	AORL,
-	AORW,
-	AOUTB,
-	AOUTL,
-	AOUTW,
-	AOUTSB,
-	AOUTSL,
-	AOUTSW,
-	APAUSE,
-	APOPAL,
-	APOPAW,
-	APOPFL,
-	APOPFW,
-	APOPL,
-	APOPW,
-	APUSHAL,
-	APUSHAW,
-	APUSHFL,
-	APUSHFW,
-	APUSHL,
-	APUSHW,
-	ARCLB,
-	ARCLL,
-	ARCLW,
-	ARCRB,
-	ARCRL,
-	ARCRW,
-	AREP,
-	AREPN,
-	AROLB,
-	AROLL,
-	AROLW,
-	ARORB,
-	ARORL,
-	ARORW,
-	ASAHF,
-	ASALB,
-	ASALL,
-	ASALW,
-	ASARB,
-	ASARL,
-	ASARW,
-	ASBBB,
-	ASBBL,
-	ASBBW,
-	ASCASB,
-	ASCASL,
-	ASCASW,
-	ASETCC,
-	ASETCS,
-	ASETEQ,
-	ASETGE,
-	ASETGT,
-	ASETHI,
-	ASETLE,
-	ASETLS,
-	ASETLT,
-	ASETMI,
-	ASETNE,
-	ASETOC,
-	ASETOS,
-	ASETPC,
-	ASETPL,
-	ASETPS,
-	ACDQ,
-	ACWD,
-	ASHLB,
-	ASHLL,
-	ASHLW,
-	ASHRB,
-	ASHRL,
-	ASHRW,
-	ASTC,
-	ASTD,
-	ASTI,
-	ASTOSB,
-	ASTOSL,
-	ASTOSW,
-	ASUBB,
-	ASUBL,
-	ASUBW,
-	ASYSCALL,
-	ATESTB,
-	ATESTL,
-	ATESTW,
-	AVERR,
-	AVERW,
-	AWAIT,
-	AWORD,
-	AXCHGB,
-	AXCHGL,
-	AXCHGW,
-	AXLAT,
-	AXORB,
-	AXORL,
-	AXORW,
-
-	AFMOVB,
-	AFMOVBP,
-	AFMOVD,
-	AFMOVDP,
-	AFMOVF,
-	AFMOVFP,
-	AFMOVL,
-	AFMOVLP,
-	AFMOVV,
-	AFMOVVP,
-	AFMOVW,
-	AFMOVWP,
-	AFMOVX,
-	AFMOVXP,
-
-	AFCOMB,
-	AFCOMBP,
-	AFCOMD,
-	AFCOMDP,
-	AFCOMDPP,
-	AFCOMF,
-	AFCOMFP,
-	AFCOMI,
-	AFCOMIP,
-	AFCOML,
-	AFCOMLP,
-	AFCOMW,
-	AFCOMWP,
-	AFUCOM,
-	AFUCOMI,
-	AFUCOMIP,
-	AFUCOMP,
-	AFUCOMPP,
-
-	AFADDDP,
-	AFADDW,
-	AFADDL,
-	AFADDF,
-	AFADDD,
-
-	AFMULDP,
-	AFMULW,
-	AFMULL,
-	AFMULF,
-	AFMULD,
-
-	AFSUBDP,
-	AFSUBW,
-	AFSUBL,
-	AFSUBF,
-	AFSUBD,
-
-	AFSUBRDP,
-	AFSUBRW,
-	AFSUBRL,
-	AFSUBRF,
-	AFSUBRD,
-
-	AFDIVDP,
-	AFDIVW,
-	AFDIVL,
-	AFDIVF,
-	AFDIVD,
-
-	AFDIVRDP,
-	AFDIVRW,
-	AFDIVRL,
-	AFDIVRF,
-	AFDIVRD,
-
-	AFXCHD,
-	AFFREE,
-
-	AFLDCW,
-	AFLDENV,
-	AFRSTOR,
-	AFSAVE,
-	AFSTCW,
-	AFSTENV,
-	AFSTSW,
-
-	AF2XM1,
-	AFABS,
-	AFCHS,
-	AFCLEX,
-	AFCOS,
-	AFDECSTP,
-	AFINCSTP,
-	AFINIT,
-	AFLD1,
-	AFLDL2E,
-	AFLDL2T,
-	AFLDLG2,
-	AFLDLN2,
-	AFLDPI,
-	AFLDZ,
-	AFNOP,
-	AFPATAN,
-	AFPREM,
-	AFPREM1,
-	AFPTAN,
-	AFRNDINT,
-	AFSCALE,
-	AFSIN,
-	AFSINCOS,
-	AFSQRT,
-	AFTST,
-	AFXAM,
-	AFXTRACT,
-	AFYL2X,
-	AFYL2XP1,
-
-
-
-
-	ACMPXCHGB,
-	ACMPXCHGL,
-	ACMPXCHGW,
-	ACMPXCHG8B,
-
-	ACPUID,
-	ARDTSC,
-
-	AXADDB,
-	AXADDL,
-	AXADDW,
-
-	/* conditional move */
-	ACMOVLCC,
-	ACMOVLCS,
-	ACMOVLEQ,
-	ACMOVLGE,
-	ACMOVLGT,
-	ACMOVLHI,
-	ACMOVLLE,
-	ACMOVLLS,
-	ACMOVLLT,
-	ACMOVLMI,
-	ACMOVLNE,
-	ACMOVLOC,
-	ACMOVLOS,
-	ACMOVLPC,
-	ACMOVLPL,
-	ACMOVLPS,
-	ACMOVWCC,
-	ACMOVWCS,
-	ACMOVWEQ,
-	ACMOVWGE,
-	ACMOVWGT,
-	ACMOVWHI,
-	ACMOVWLE,
-	ACMOVWLS,
-	ACMOVWLT,
-	ACMOVWMI,
-	ACMOVWNE,
-	ACMOVWOC,
-	ACMOVWOS,
-	ACMOVWPC,
-	ACMOVWPL,
-	ACMOVWPS,
-
-	AFCMOVCC,
-	AFCMOVCS,
-	AFCMOVEQ,
-	AFCMOVHI,
-	AFCMOVLS,
-	AFCMOVNE,
-	AFCMOVNU,
-	AFCMOVUN,
-
-	ALFENCE,
-	AMFENCE,
-	ASFENCE,
-
-	AEMMS,
-	
-	APREFETCHT0,
-	APREFETCHT1,
-	APREFETCHT2,
-	APREFETCHNTA,
-	
-	ABSWAPL,
-	
-
-	// SSE2
-	AADDPD,
-	AADDPS,
-	AADDSD,
-	AADDSS,
-	AANDNPD,
-	AANDNPS,
-	AANDPD,
-	AANDPS,
-	ACMPPD,
-	ACMPPS,
-	ACMPSD,
-	ACMPSS,
-	ACOMISD,
-	ACOMISS,
-	ACVTPL2PD,
-	ACVTPL2PS,
-	ACVTPD2PL,
-	ACVTPD2PS,
-	ACVTPS2PL,
-	ACVTPS2PD,
-	ACVTSD2SL,
-	ACVTSD2SS,
-	ACVTSL2SD,
-	ACVTSL2SS,
-	ACVTSS2SD,
-	ACVTSS2SL,
-	ACVTTPD2PL,
-	ACVTTPS2PL,
-	ACVTTSD2SL,
-	ACVTTSS2SL,
-	ADIVPD,
-	ADIVPS,
-	ADIVSD,
-	ADIVSS,
-	AMASKMOVOU,
-	AMAXPD,
-	AMAXPS,
-	AMAXSD,
-	AMAXSS,
-	AMINPD,
-	AMINPS,
-	AMINSD,
-	AMINSS,
-	AMOVAPD,
-	AMOVAPS,
-	AMOVO,
-	AMOVOU,
-	AMOVHLPS,
-	AMOVHPD,
-	AMOVHPS,
-	AMOVLHPS,
-	AMOVLPD,
-	AMOVLPS,
-	AMOVMSKPD,
-	AMOVMSKPS,
-	AMOVNTO,
-	AMOVNTPD,
-	AMOVNTPS,
-	AMOVSD,
-	AMOVSS,
-	AMOVUPD,
-	AMOVUPS,
-	AMULPD,
-	AMULPS,
-	AMULSD,
-	AMULSS,
-	AORPD,
-	AORPS,
-	APADDQ,
-	APAND,
-	APCMPEQB,
-	APMAXSW,
-	APMAXUB,
-	APMINSW,
-	APMINUB,
-	APMOVMSKB,
-	APSADBW,
-	APSUBB,
-	APSUBL,
-	APSUBQ,
-	APSUBSB,
-	APSUBSW,
-	APSUBUSB,
-	APSUBUSW,
-	APSUBW,
-	APUNPCKHQDQ,
-	APUNPCKLQDQ,
-	APXOR,
-	ARCPPS,
-	ARCPSS,
-	ARSQRTPS,
-	ARSQRTSS,
-	ASQRTPD,
-	ASQRTPS,
-	ASQRTSD,
-	ASQRTSS,
-	ASUBPD,
-	ASUBPS,
-	ASUBSD,
-	ASUBSS,
-	AUCOMISD,
-	AUCOMISS,
-	AUNPCKHPD,
-	AUNPCKHPS,
-	AUNPCKLPD,
-	AUNPCKLPS,
-	AXORPD,
-	AXORPS,
-	APSHUFHW,
-	APSHUFL,
-	APSHUFLW,
-
-	/* SSE 3+ */
-	AAESENC,
-	APINSRD,
-	APSHUFB,
-
-	
-	ALAST
-};
-
-enum
-{
-	REG_NONE	= 0,
-
-	REG_AL		= 0+16,
-	REG_CL,
-	REG_DL,
-	REG_BL,
-
-	REG_AH		= 4+16,
-	REG_CH,
-	REG_DH,
-	REG_BH,
-
-	REG_AX		= 8+16,
-	REG_CX,
-	REG_DX,
-	REG_BX,
-	REG_SP,
-	REG_BP,
-	REG_SI,
-	REG_DI,
-
-	REG_F0		= 16+16,
-	REG_F7		= REG_F0 + 7+16,
-
-	REG_CS		= 24+16,
-	REG_SS,
-	REG_DS,
-	REG_ES,
-	REG_FS,
-	REG_GS,
-
-	REG_GDTR,		/* global descriptor table register */
-	REG_IDTR,		/* interrupt descriptor table register */
-	REG_LDTR,		/* local descriptor table register */
-	REG_MSW,		/* machine status word */
-	REG_TASK,		/* task register */
-
-	REG_CR		= 35+16,
-	REG_DR		= 43+16,
-	REG_TR		= 51+16,
-
-	REG_X0		= 59+16,
-	REG_X1,
-	REG_X2,
-	REG_X3,
-	REG_X4,
-	REG_X5,
-	REG_X6,
-	REG_X7,
-	
-	REG_TLS		= 67+16,
-	MAXREG		= 68+16,
-
-	T_TYPE		= 1<<0,
-	T_INDEX		= 1<<1,
-	T_OFFSET	= 1<<2,
-	T_FCONST	= 1<<3,
-	T_SYM		= 1<<4,
-	T_SCONST	= 1<<5,
-	T_OFFSET2	= 1<<6,
-	T_GOTYPE	= 1<<7,
-
-	REGARG		= -1,
-	REGRET		= REG_AX,
-	FREGRET		= REG_F0,
-	REGSP		= REG_SP,
-	REGTMP		= REG_DI,
-	REGCTXT		= REG_DX,
-};
-
-/*
- * this is the ranlib header
- */
-#define	SYMDEF	"__.GOSYMDEF"
diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h
index e844bc4..77c06b3 100644
--- a/src/cmd/8l/l.h
+++ b/src/cmd/8l/l.h
@@ -57,7 +57,6 @@
 void	asmb(void);
 int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
-void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
 
 /* Used by ../ld/dwarf.c */
diff --git a/src/cmd/8l/list.c b/src/cmd/8l/list.c
deleted file mode 100644
index 4cd8f08..0000000
--- a/src/cmd/8l/list.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// Inferno utils/8l/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/list.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.
-
-// Printing.
-
-#include	"l.h"
-#include	"../ld/lib.h"
-
-void
-listinit(void)
-{
-	listinit8();
-}
diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c
index 41900d6..767db33 100644
--- a/src/cmd/8l/obj.c
+++ b/src/cmd/8l/obj.c
@@ -70,7 +70,6 @@
 	thearch.elfreloc1 = elfreloc1;
 	thearch.elfsetupplt = elfsetupplt;
 	thearch.gentext = gentext;
-	thearch.listinit = listinit;
 	thearch.machoreloc1 = machoreloc1;
 	thearch.lput = lputl;
 	thearch.wput = wputl;
diff --git a/src/cmd/9l/9.out.h b/src/cmd/9l/9.out.h
deleted file mode 100644
index 6e95698..0000000
--- a/src/cmd/9l/9.out.h
+++ /dev/null
@@ -1,611 +0,0 @@
-// cmd/9c/9.out.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.
-
-/*
- * powerpc 64
- */
-enum
-{
-	NSNAME = 8,
-	NSYM = 50,
-	NREG = 32,	/* number of general registers */
-	NFREG = 32,	/* number of floating point registers */
-};
-
-#include "../ld/textflag.h"
-
-// avoid conflict with ucontext.h. sigh.
-#undef REG_R0
-#undef REG_R1
-#undef REG_R2
-#undef REG_R3
-#undef REG_R4
-#undef REG_R5
-#undef REG_R6
-#undef REG_R7
-#undef REG_R8
-#undef REG_R9
-#undef REG_R10
-#undef REG_R11
-#undef REG_R12
-#undef REG_R13
-#undef REG_R14
-#undef REG_R15
-#undef REG_R16
-#undef REG_R17
-#undef REG_R18
-#undef REG_R19
-#undef REG_R20
-#undef REG_R21
-#undef REG_R22
-#undef REG_R23
-#undef REG_R24
-#undef REG_R25
-#undef REG_R26
-#undef REG_R27
-#undef REG_R28
-#undef REG_R29
-#undef REG_R30
-#undef REG_R31
-#define REG_R0 GO_REG_R0
-#define REG_R1 GO_REG_R1
-#define REG_R2 GO_REG_R2
-#define REG_R3 GO_REG_R3
-#define REG_R4 GO_REG_R4
-#define REG_R5 GO_REG_R5
-#define REG_R6 GO_REG_R6
-#define REG_R7 GO_REG_R7
-#define REG_R8 GO_REG_R8
-#define REG_R9 GO_REG_R9
-#define REG_R10 GO_REG_R10
-#define REG_R11 GO_REG_R11
-#define REG_R12 GO_REG_R12
-#define REG_R13 GO_REG_R13
-#define REG_R14 GO_REG_R14
-#define REG_R15 GO_REG_R15
-#define REG_R16 GO_REG_R16
-#define REG_R17 GO_REG_R17
-#define REG_R18 GO_REG_R18
-#define REG_R19 GO_REG_R19
-#define REG_R20 GO_REG_R20
-#define REG_R21 GO_REG_R21
-#define REG_R22 GO_REG_R22
-#define REG_R23 GO_REG_R23
-#define REG_R24 GO_REG_R24
-#define REG_R25 GO_REG_R25
-#define REG_R26 GO_REG_R26
-#define REG_R27 GO_REG_R27
-#define REG_R28 GO_REG_R28
-#define REG_R29 GO_REG_R29
-#define REG_R30 GO_REG_R30
-#define REG_R31 GO_REG_R31
-
-enum
-{
-	REG_R0 = 32,
-	REG_R1,
-	REG_R2,
-	REG_R3,
-	REG_R4,
-	REG_R5,
-	REG_R6,
-	REG_R7,
-	REG_R8,
-	REG_R9,
-	REG_R10,
-	REG_R11,
-	REG_R12,
-	REG_R13,
-	REG_R14,
-	REG_R15,
-	REG_R16,
-	REG_R17,
-	REG_R18,
-	REG_R19,
-	REG_R20,
-	REG_R21,
-	REG_R22,
-	REG_R23,
-	REG_R24,
-	REG_R25,
-	REG_R26,
-	REG_R27,
-	REG_R28,
-	REG_R29,
-	REG_R30,
-	REG_R31,
-
-	REG_F0 = 64,
-	REG_F1,
-	REG_F2,
-	REG_F3,
-	REG_F4,
-	REG_F5,
-	REG_F6,
-	REG_F7,
-	REG_F8,
-	REG_F9,
-	REG_F10,
-	REG_F11,
-	REG_F12,
-	REG_F13,
-	REG_F14,
-	REG_F15,
-	REG_F16,
-	REG_F17,
-	REG_F18,
-	REG_F19,
-	REG_F20,
-	REG_F21,
-	REG_F22,
-	REG_F23,
-	REG_F24,
-	REG_F25,
-	REG_F26,
-	REG_F27,
-	REG_F28,
-	REG_F29,
-	REG_F30,
-	REG_F31,
-	
-	REG_SPECIAL = 96,
-
-	REG_C0 = 96,
-	REG_C1,
-	REG_C2,
-	REG_C3,
-	REG_C4,
-	REG_C5,
-	REG_C6,
-	REG_C7,
-	
-	REG_MSR = 104,
-	REG_FPSCR,
-	REG_CR,
-
-	REG_SPR0 = 1024, // first of 1024 registers
-	REG_DCR0 = 2048, // first of 1024 registers
-	
-	REG_XER = REG_SPR0 + 1,
-	REG_LR = REG_SPR0 + 8,
-	REG_CTR = REG_SPR0 + 9,
-
-	REGZERO		= REG_R0,	/* set to zero */
-	REGSP		= REG_R1,
-	REGSB		= REG_R2,
-	REGRET		= REG_R3,
-	REGARG		= -1,	/* -1 disables passing the first argument in register */
-	REGRT1		= REG_R3,	/* reserved for runtime, duffzero and duffcopy */
-	REGRT2		= REG_R4,	/* reserved for runtime, duffcopy */
-	REGMIN		= REG_R7,	/* register variables allocated from here to REGMAX */
-	REGCTXT		= REG_R11,	/* context for closures */
-	REGTLS		= REG_R13,	/* C ABI TLS base pointer */
-	REGMAX		= REG_R27,
-	REGEXT		= REG_R30,	/* external registers allocated from here down */
-	REGG		= REG_R30,	/* G */
-	REGTMP		= REG_R31,	/* used by the linker */
-
-	FREGRET		= REG_F0,
-	FREGMIN		= REG_F17,	/* first register variable */
-	FREGMAX		= REG_F26,	/* last register variable for 9g only */
-	FREGEXT		= REG_F26,	/* first external register */
-	FREGCVI		= REG_F27,	/* floating conversion constant */
-	FREGZERO	= REG_F28,	/* both float and double */
-	FREGHALF	= REG_F29,	/* double */
-	FREGONE		= REG_F30,	/* double */
-	FREGTWO		= REG_F31	/* double */
-/*
- * GENERAL:
- *
- * compiler allocates R3 up as temps
- * compiler allocates register variables R7-R27
- * compiler allocates external registers R30 down
- *
- * compiler allocates register variables F17-F26
- * compiler allocates external registers F26 down
- */
-};
-
-enum {
-	BIG = 32768-8,
-};
-
-enum {
-/* mark flags */
-	LABEL		= 1<<0,
-	LEAF		= 1<<1,
-	FLOAT		= 1<<2,
-	BRANCH		= 1<<3,
-	LOAD		= 1<<4,
-	FCMP		= 1<<5,
-	SYNC		= 1<<6,
-	LIST		= 1<<7,
-	FOLL		= 1<<8,
-	NOSCHED		= 1<<9,
-};
-
-enum
-{
-	C_NONE,
-	C_REG,
-	C_FREG,
-	C_CREG,
-	C_SPR,		/* special processor register */
-	C_ZCON,
-	C_SCON,		/* 16 bit signed */
-	C_UCON,		/* 32 bit signed, low 16 bits 0 */
-	C_ADDCON,	/* -0x8000 <= v < 0 */
-	C_ANDCON,	/* 0 < v <= 0xFFFF */
-	C_LCON,		/* other 32 */
-	C_DCON,		/* other 64 (could subdivide further) */
-	C_SACON,	/* $n(REG) where n <= int16 */
-	C_SECON,
-	C_LACON,	/* $n(REG) where int16 < n <= int32 */
-	C_LECON,
-	C_DACON,	/* $n(REG) where int32 < n */
-	C_SBRA,
-	C_LBRA,
-	C_SAUTO,
-	C_LAUTO,
-	C_SEXT,
-	C_LEXT,
-	C_ZOREG,
-	C_SOREG,
-	C_LOREG,
-	C_FPSCR,
-	C_MSR,
-	C_XER,
-	C_LR,
-	C_CTR,
-	C_ANY,
-	C_GOK,
-	C_ADDR,
-	C_TEXTSIZE,
-
-	C_NCLASS,	/* must be the last */
-};
-
-enum
-{
-	AADD = A_ARCHSPECIFIC,
-	AADDCC,
-	AADDV,
-	AADDVCC,
-	AADDC,
-	AADDCCC,
-	AADDCV,
-	AADDCVCC,
-	AADDME,
-	AADDMECC,
-	AADDMEVCC,
-	AADDMEV,
-	AADDE,
-	AADDECC,
-	AADDEVCC,
-	AADDEV,
-	AADDZE,
-	AADDZECC,
-	AADDZEVCC,
-	AADDZEV,
-	AAND,
-	AANDCC,
-	AANDN,
-	AANDNCC,
-	ABC,
-	ABCL,
-	ABEQ,
-	ABGE,
-	ABGT,
-	ABLE,
-	ABLT,
-	ABNE,
-	ABVC,
-	ABVS,
-	ACMP,
-	ACMPU,
-	ACNTLZW,
-	ACNTLZWCC,
-	ACRAND,
-	ACRANDN,
-	ACREQV,
-	ACRNAND,
-	ACRNOR,
-	ACROR,
-	ACRORN,
-	ACRXOR,
-	ADIVW,
-	ADIVWCC,
-	ADIVWVCC,
-	ADIVWV,
-	ADIVWU,
-	ADIVWUCC,
-	ADIVWUVCC,
-	ADIVWUV,
-	AEQV,
-	AEQVCC,
-	AEXTSB,
-	AEXTSBCC,
-	AEXTSH,
-	AEXTSHCC,
-	AFABS,
-	AFABSCC,
-	AFADD,
-	AFADDCC,
-	AFADDS,
-	AFADDSCC,
-	AFCMPO,
-	AFCMPU,
-	AFCTIW,
-	AFCTIWCC,
-	AFCTIWZ,
-	AFCTIWZCC,
-	AFDIV,
-	AFDIVCC,
-	AFDIVS,
-	AFDIVSCC,
-	AFMADD,
-	AFMADDCC,
-	AFMADDS,
-	AFMADDSCC,
-	AFMOVD,
-	AFMOVDCC,
-	AFMOVDU,
-	AFMOVS,
-	AFMOVSU,
-	AFMSUB,
-	AFMSUBCC,
-	AFMSUBS,
-	AFMSUBSCC,
-	AFMUL,
-	AFMULCC,
-	AFMULS,
-	AFMULSCC,
-	AFNABS,
-	AFNABSCC,
-	AFNEG,
-	AFNEGCC,
-	AFNMADD,
-	AFNMADDCC,
-	AFNMADDS,
-	AFNMADDSCC,
-	AFNMSUB,
-	AFNMSUBCC,
-	AFNMSUBS,
-	AFNMSUBSCC,
-	AFRSP,
-	AFRSPCC,
-	AFSUB,
-	AFSUBCC,
-	AFSUBS,
-	AFSUBSCC,
-	AMOVMW,
-	ALSW,
-	ALWAR,
-	AMOVWBR,
-	AMOVB,
-	AMOVBU,
-	AMOVBZ,
-	AMOVBZU,
-	AMOVH,
-	AMOVHBR,
-	AMOVHU,
-	AMOVHZ,
-	AMOVHZU,
-	AMOVW,
-	AMOVWU,
-	AMOVFL,
-	AMOVCRFS,
-	AMTFSB0,
-	AMTFSB0CC,
-	AMTFSB1,
-	AMTFSB1CC,
-	AMULHW,
-	AMULHWCC,
-	AMULHWU,
-	AMULHWUCC,
-	AMULLW,
-	AMULLWCC,
-	AMULLWVCC,
-	AMULLWV,
-	ANAND,
-	ANANDCC,
-	ANEG,
-	ANEGCC,
-	ANEGVCC,
-	ANEGV,
-	ANOR,
-	ANORCC,
-	AOR,
-	AORCC,
-	AORN,
-	AORNCC,
-	AREM,
-	AREMCC,
-	AREMV,
-	AREMVCC,
-	AREMU,
-	AREMUCC,
-	AREMUV,
-	AREMUVCC,
-	ARFI,
-	ARLWMI,
-	ARLWMICC,
-	ARLWNM,
-	ARLWNMCC,
-	ASLW,
-	ASLWCC,
-	ASRW,
-	ASRAW,
-	ASRAWCC,
-	ASRWCC,
-	ASTSW,
-	ASTWCCC,
-	ASUB,
-	ASUBCC,
-	ASUBVCC,
-	ASUBC,
-	ASUBCCC,
-	ASUBCV,
-	ASUBCVCC,
-	ASUBME,
-	ASUBMECC,
-	ASUBMEVCC,
-	ASUBMEV,
-	ASUBV,
-	ASUBE,
-	ASUBECC,
-	ASUBEV,
-	ASUBEVCC,
-	ASUBZE,
-	ASUBZECC,
-	ASUBZEVCC,
-	ASUBZEV,
-	ASYNC,
-	AXOR,
-	AXORCC,
-
-	ADCBF,
-	ADCBI,
-	ADCBST,
-	ADCBT,
-	ADCBTST,
-	ADCBZ,
-	AECIWX,
-	AECOWX,
-	AEIEIO,
-	AICBI,
-	AISYNC,
-	APTESYNC,
-	ATLBIE,
-	ATLBIEL,
-	ATLBSYNC,
-	ATW,
-
-	ASYSCALL,
-	AWORD,
-
-	ARFCI,
-
-	/* optional on 32-bit */
-	AFRES,
-	AFRESCC,
-	AFRSQRTE,
-	AFRSQRTECC,
-	AFSEL,
-	AFSELCC,
-	AFSQRT,
-	AFSQRTCC,
-	AFSQRTS,
-	AFSQRTSCC,
-
-	/* 64-bit */
-	
-	ACNTLZD,
-	ACNTLZDCC,
-	ACMPW,	/* CMP with L=0 */
-	ACMPWU,
-	ADIVD,
-	ADIVDCC,
-	ADIVDVCC,
-	ADIVDV,
-	ADIVDU,
-	ADIVDUCC,
-	ADIVDUVCC,
-	ADIVDUV,
-	AEXTSW,
-	AEXTSWCC,
-	/* AFCFIW; AFCFIWCC */
-	AFCFID,
-	AFCFIDCC,
-	AFCTID,
-	AFCTIDCC,
-	AFCTIDZ,
-	AFCTIDZCC,
-	ALDAR,
-	AMOVD,
-	AMOVDU,
-	AMOVWZ,
-	AMOVWZU,
-	AMULHD,
-	AMULHDCC,
-	AMULHDU,
-	AMULHDUCC,
-	AMULLD,
-	AMULLDCC,
-	AMULLDVCC,
-	AMULLDV,
-	ARFID,
-	ARLDMI,
-	ARLDMICC,
-	ARLDC,
-	ARLDCCC,
-	ARLDCR,
-	ARLDCRCC,
-	ARLDCL,
-	ARLDCLCC,
-	ASLBIA,
-	ASLBIE,
-	ASLBMFEE,
-	ASLBMFEV,
-	ASLBMTE,
-	ASLD,
-	ASLDCC,
-	ASRD,
-	ASRAD,
-	ASRADCC,
-	ASRDCC,
-	ASTDCCC,
-	ATD,
-
-	/* 64-bit pseudo operation */
-	ADWORD,
-	AREMD,
-	AREMDCC,
-	AREMDV,
-	AREMDVCC,
-	AREMDU,
-	AREMDUCC,
-	AREMDUV,
-	AREMDUVCC,
-
-	/* more 64-bit operations */
-	AHRFID,
-
-	ALAST,
-	
-	// aliases
-	ABR = AJMP,
-	ABL = ACALL,
-	ARETURN = ARET,
-};
-
-/*
- * this is the ranlib header
- */
-#define	SYMDEF	"__.GOSYMDEF"
diff --git a/src/cmd/9l/l.h b/src/cmd/9l/l.h
index a634cf8..5c048d2 100644
--- a/src/cmd/9l/l.h
+++ b/src/cmd/9l/l.h
@@ -31,7 +31,6 @@
 #include	<libc.h>
 #include	<bio.h>
 #include	<link.h>
-#include	"9.out.h"
 
 #ifndef	EXTERN
 #define	EXTERN	extern
@@ -57,7 +56,6 @@
 void	asmb(void);
 int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
-void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
 
 /* Used by ../ld/dwarf.c */
diff --git a/src/cmd/9l/list.c b/src/cmd/9l/list.c
deleted file mode 100644
index af8dc15..0000000
--- a/src/cmd/9l/list.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// Inferno utils/5l/list.h
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.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.
-
-// Printing.
-
-#include "l.h"
-#include "../ld/lib.h"
-
-void
-listinit(void)
-{
-	listinit9();
-}
diff --git a/src/cmd/9l/obj.c b/src/cmd/9l/obj.c
index 17dd5ca..5449319 100644
--- a/src/cmd/9l/obj.c
+++ b/src/cmd/9l/obj.c
@@ -71,7 +71,6 @@
 	thearch.elfreloc1 = elfreloc1;
 	thearch.elfsetupplt = elfsetupplt;
 	thearch.gentext = gentext;
-	thearch.listinit = listinit;
 	thearch.machoreloc1 = machoreloc1;
 	if(thelinkarch == &linkppc64le) {
 		thearch.lput = lputl;
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index a9b4988..00d289c 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -475,7 +475,6 @@
 	"-Wno-switch",
 	"-Wno-comment",
 	"-Wno-missing-field-initializers",
-	"-Werror",
 	"-fno-common",
 	"-ggdb",
 	"-pipe",
@@ -531,10 +530,6 @@
 		"$GOROOT/include/bio.h",
 		"$GOROOT/include/ar.h",
 		"$GOROOT/include/link.h",
-		"anames5.c",
-		"anames6.c",
-		"anames8.c",
-		"anames9.c",
 	}},
 	{"cmd/5l", []string{
 		"$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
@@ -574,15 +569,15 @@
 	nameprefix string
 	gen        func(string, string)
 }{
-	{"anames5.c", mkanames},
-	{"anames6.c", mkanames},
-	{"anames8.c", mkanames},
-	{"anames9.c", mkanames},
 	{"zdefaultcc.go", mkzdefaultcc},
 	{"zversion.go", mkzversion},
 
 	// not generated anymore, but delete the file if we see it
 	{"enam.c", nil},
+	{"anames5.c", nil},
+	{"anames6.c", nil},
+	{"anames8.c", nil},
+	{"anames9.c", nil},
 }
 
 // install installs the library, package, or binary associated with dir,
diff --git a/src/cmd/dist/buildgc.go b/src/cmd/dist/buildgc.go
deleted file mode 100644
index b59aa5b..0000000
--- a/src/cmd/dist/buildgc.go
+++ /dev/null
@@ -1,117 +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.
-
-package main
-
-import (
-	"bytes"
-	"fmt"
-	"strings"
-)
-
-/*
- * Helpers for building cmd/gc.
- */
-
-// gcopnames creates opnames.h from go.h.
-// It finds the OXXX enum, pulls out all the constants
-// from OXXX to OEND, and writes a table mapping
-// op to string.
-func gcopnames(dir, file string) {
-	var out bytes.Buffer
-	fmt.Fprintf(&out, "// auto generated by go tool dist\n")
-	fmt.Fprintf(&out, "static char *opnames[] = {\n")
-
-	in := readfile(pathf("%s/go.h", dir))
-	lines := splitlines(in)
-	i := 0
-	for i < len(lines) && !strings.Contains(lines[i], "OXXX") {
-		i++
-	}
-	for _, line := range lines[i:] {
-		if i := strings.Index(line, "//"); i >= 0 {
-			line = line[:i]
-		}
-		for _, field := range splitfields(line) {
-			field = strings.TrimPrefix(field, "O")
-			field = strings.TrimSuffix(field, ",")
-			fmt.Fprintf(&out, "\t[O%s] = \"%s\",\n", field, field)
-		}
-		if strings.Contains(line, "OEND") {
-			break
-		}
-	}
-	fmt.Fprintf(&out, "};\n")
-
-	writefile(out.String(), file, 0)
-}
-
-// mkanames reads [5689].out.h and writes anames[5689].c
-// The format is much the same as the Go opcodes above.
-// It also writes out cnames array for C_* constants.
-func mkanames(dir, file string) {
-	ch := file[len(file)-3]
-	targ := pathf("%s/../cmd/%cl/%c.out.h", dir, ch, ch)
-	in := readfile(pathf("%s/../../include/link.h", dir)) + readfile(targ)
-	lines := splitlines(in)
-
-	// Include link.h so that the extern declaration there is
-	// checked against the non-extern declaration we are generating.
-	var out bytes.Buffer
-	fmt.Fprintf(&out, "// auto generated by go tool dist\n")
-	fmt.Fprintf(&out, "#include <u.h>\n")
-	fmt.Fprintf(&out, "#include <libc.h>\n")
-	fmt.Fprintf(&out, "#include <bio.h>\n")
-	fmt.Fprintf(&out, "#include <link.h>\n")
-	fmt.Fprintf(&out, "#include \"../cmd/%cl/%c.out.h\"\n", ch, ch)
-	fmt.Fprintf(&out, "\n")
-
-	fmt.Fprintf(&out, "char*	anames%c[] = {\n", ch)
-	for _, line := range lines {
-		// Use all A names found in the headers,
-		// except don't use A_ARCHSPECIFIC (left to arch to define),
-		// and don't use any aliases (= A...),
-		// except do use the arch-defined alias for A_ARCHSPECIFIC.
-		if strings.Contains(line, ";") {
-			continue
-		}
-		if strings.HasPrefix(line, "\tA") && !strings.Contains(line, "\tA_") && (!strings.Contains(line, "= A") || strings.Contains(line, "= A_ARCHSPECIFIC")) {
-			if i := strings.Index(line, ","); i >= 0 {
-				line = line[:i]
-			}
-			if i := strings.Index(line, "="); i >= 0 {
-				line = line[:i]
-			}
-			if i := strings.Index(line, "\n"); i >= 0 {
-				line = line[:i]
-			}
-			line = line[2:]
-			fmt.Fprintf(&out, "\t\"%s\",\n", strings.TrimSpace(line))
-		}
-	}
-	fmt.Fprintf(&out, "};\n")
-
-	j := 0
-	var out2 bytes.Buffer
-	fmt.Fprintf(&out2, "char*	cnames%c[] = {\n", ch)
-	for _, line := range lines {
-		if strings.HasPrefix(line, "\tC_") {
-			if i := strings.Index(line, ","); i >= 0 {
-				line = line[:i]
-			}
-			if i := strings.Index(line, "\n"); i >= 0 {
-				line = line[:i]
-			}
-			line = line[3:]
-			fmt.Fprintf(&out2, "\t\"%s\",\n", line)
-			j++
-		}
-	}
-	fmt.Fprintf(&out2, "};\n")
-	if j > 0 {
-		out.Write(out2.Bytes())
-	}
-
-	writefile(out.String(), file, 0)
-}
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index 4990a80..6a36c9a 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -60,7 +60,6 @@
 	int	(*elfreloc1)(Reloc*, vlong);
 	void	(*elfsetupplt)(void);
 	void	(*gentext)(void);
-	void	(*listinit)(void);
 	int	(*machoreloc1)(Reloc*, vlong);
 	
 	void	(*lput)(uint32);
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
index 0a48eb3..1e9a127 100644
--- a/src/cmd/ld/pobj.c
+++ b/src/cmd/ld/pobj.c
@@ -57,7 +57,6 @@
 	ctxt->bso = &bso;
 
 	Binit(&bso, 1, OWRITE);
-	thearch.listinit();
 	memset(debug, 0, sizeof(debug));
 	nerrors = 0;
 	outfile = nil;
@@ -128,12 +127,6 @@
 	
 	flagparse(&argc, &argv, usage);
 	ctxt->bso = &bso;
-	ctxt->debugdivmod = debug['M'];
-	ctxt->debugfloat = debug['F'];
-	ctxt->debughist = debug['O'];
-	ctxt->debugpcln = debug['O'];
-	ctxt->debugread = debug['W'];
-	ctxt->debugstack = debug['K'];
 	ctxt->debugvlog = debug['v'];
 
 	if(argc != 1)
@@ -154,7 +147,6 @@
 		headstring = headstr(HEADTYPE);
 
 	thearch.archinit();
-	ctxt->debugfloat = debug['F'];
 
 	if(debug['v'])
 		Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
@@ -201,8 +193,6 @@
 	if(debug['v']) {
 		Bprint(&bso, "%5.2f cpu time\n", cputime());
 		Bprint(&bso, "%d symbols\n", ctxt->nsymbol);
-		Bprint(&bso, "%d sizeof adr\n", sizeof(Addr));
-		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
 		Bprint(&bso, "%lld liveness data\n", liveness);
 	}
 	Bflush(&bso);
diff --git a/src/liblink/arch.c b/src/liblink/arch.c
new file mode 100644
index 0000000..2e425a6
--- /dev/null
+++ b/src/liblink/arch.c
@@ -0,0 +1,68 @@
+// 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.
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <link.h>
+
+LinkArch linkarm = {
+	.name = "arm",
+	.thechar = '5',
+	.endian = LittleEndian,
+
+	.minlc = 4,
+	.ptrsize = 4,
+	.regsize = 4,
+};
+
+LinkArch linkamd64 = {
+	.name = "amd64",
+	.thechar = '6',
+	.endian = LittleEndian,
+
+	.minlc = 1,
+	.ptrsize = 8,
+	.regsize = 8,
+};
+
+LinkArch linkamd64p32 = {
+	.name = "amd64p32",
+	.thechar = '6',
+	.endian = LittleEndian,
+
+	.minlc = 1,
+	.ptrsize = 4,
+	.regsize = 8,
+};
+
+LinkArch link386 = {
+	.name = "386",
+	.thechar = '8',
+	.endian = LittleEndian,
+
+	.minlc = 1,
+	.ptrsize = 4,
+	.regsize = 4,
+};
+
+LinkArch linkppc64 = {
+	.name = "ppc64",
+	.thechar = '9',
+	.endian = BigEndian,
+
+	.minlc = 4,
+	.ptrsize = 8,
+	.regsize = 8,
+};
+
+LinkArch linkppc64le = {
+	.name = "ppc64le",
+	.thechar = '9',
+	.endian = LittleEndian,
+
+	.minlc = 4,
+	.ptrsize = 8,
+	.regsize = 8,
+};
diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c
deleted file mode 100644
index 398b784..0000000
--- a/src/liblink/asm5.c
+++ /dev/null
@@ -1,2689 +0,0 @@
-// Inferno utils/5l/span.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/span.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.
-
-// Instruction layout.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/5l/5.out.h"
-#include "../runtime/stack.h"
-
-typedef	struct	Optab	Optab;
-typedef	struct	Oprang	Oprang;
-typedef	uchar	Opcross[32][2][32];
-
-struct	Optab
-{
-	uchar	as;
-	uchar	a1;
-	char	a2;
-	uchar	a3;
-	uchar	type;
-	char	size;
-	char	param;
-	char	flag;
-	uchar	pcrelsiz;
-};
-struct	Oprang
-{
-	Optab*	start;
-	Optab*	stop;
-};
-
-enum
-{
-	LFROM		= 1<<0,
-	LTO		= 1<<1,
-	LPOOL		= 1<<2,
-	LPCREL		= 1<<3,
-};
-
-static Optab	optab[] =
-{
-	/* struct Optab:
-	  OPCODE,	from, prog->reg, to,		 type,size,param,flag */
-	{ ATEXT,	C_ADDR,	C_NONE,	C_TEXTSIZE, 	 0, 0, 0 },
-
-	{ AADD,		C_REG,	C_REG,	C_REG,		 1, 4, 0 },
-	{ AADD,		C_REG,	C_NONE,	C_REG,		 1, 4, 0 },
-	{ AMOVW,	C_REG,	C_NONE,	C_REG,		 1, 4, 0 },
-	{ AMVN,		C_REG,	C_NONE,	C_REG,		 1, 4, 0 },
-	{ ACMP,		C_REG,	C_REG,	C_NONE,		 1, 4, 0 },
-
-	{ AADD,		C_RCON,	C_REG,	C_REG,		 2, 4, 0 },
-	{ AADD,		C_RCON,	C_NONE,	C_REG,		 2, 4, 0 },
-	{ AMOVW,	C_RCON,	C_NONE,	C_REG,		 2, 4, 0 },
-	{ AMVN,		C_RCON,	C_NONE,	C_REG,		 2, 4, 0 },
-	{ ACMP,		C_RCON,	C_REG,	C_NONE,		 2, 4, 0 },
-
-	{ AADD,		C_SHIFT,C_REG,	C_REG,		 3, 4, 0 },
-	{ AADD,		C_SHIFT,C_NONE,	C_REG,		 3, 4, 0 },
-	{ AMVN,		C_SHIFT,C_NONE,	C_REG,		 3, 4, 0 },
-	{ ACMP,		C_SHIFT,C_REG,	C_NONE,		 3, 4, 0 },
-
-	{ AMOVW,	C_RACON,C_NONE,	C_REG,		 4, 4, REGSP },
-
-	{ AB,		C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0,	LPOOL },
-	{ ABL,		C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },
-	{ ABX,		C_NONE,	C_NONE,	C_SBRA,		 74, 20, 0 },
-	{ ABEQ,		C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },
-	{ ABEQ,		C_RCON,	C_NONE,	C_SBRA,		 5, 4, 0 }, // prediction hinted form, hint ignored
-
-	{ AB,		C_NONE,	C_NONE,	C_ROREG,	 6, 4, 0,	LPOOL },
-	{ ABL,		C_NONE,	C_NONE,	C_ROREG,	 7, 4, 0 },
-	{ ABL,		C_REG,	C_NONE,	C_ROREG,	 7, 4, 0 },
-	{ ABX,		C_NONE,	C_NONE,	C_ROREG,	 75, 12, 0 },
-	{ ABXRET,	C_NONE,	C_NONE,	C_ROREG,	 76, 4, 0 },
-
-	{ ASLL,		C_RCON,	C_REG,	C_REG,		 8, 4, 0 },
-	{ ASLL,		C_RCON,	C_NONE,	C_REG,		 8, 4, 0 },
-
-	{ ASLL,		C_REG,	C_NONE,	C_REG,		 9, 4, 0 },
-	{ ASLL,		C_REG,	C_REG,	C_REG,		 9, 4, 0 },
-
-	{ ASWI,		C_NONE,	C_NONE,	C_NONE,		10, 4, 0 },
-	{ ASWI,		C_NONE,	C_NONE,	C_LOREG,	10, 4, 0 },
-	{ ASWI,		C_NONE,	C_NONE,	C_LCON,		10, 4, 0 },
-
-	{ AWORD,	C_NONE,	C_NONE,	C_LCON,		11, 4, 0 },
-	{ AWORD,	C_NONE,	C_NONE,	C_LCONADDR,	11, 4, 0 },
-	{ AWORD,	C_NONE,	C_NONE,	C_ADDR,		11, 4, 0 },
-
-	{ AMOVW,	C_NCON,	C_NONE,	C_REG,		12, 4, 0 },
-	{ AMOVW,	C_LCON,	C_NONE,	C_REG,		12, 4, 0,	LFROM },
-	{ AMOVW,	C_LCONADDR,	C_NONE,	C_REG,	12, 4, 0,	LFROM | LPCREL, 4},
-
-	{ AADD,		C_NCON,	C_REG,	C_REG,		13, 8, 0 },
-	{ AADD,		C_NCON,	C_NONE,	C_REG,		13, 8, 0 },
-	{ AMVN,		C_NCON,	C_NONE,	C_REG,		13, 8, 0 },
-	{ ACMP,		C_NCON,	C_REG,	C_NONE,		13, 8, 0 },
-	{ AADD,		C_LCON,	C_REG,	C_REG,		13, 8, 0,	LFROM },
-	{ AADD,		C_LCON,	C_NONE,	C_REG,		13, 8, 0,	LFROM },
-	{ AMVN,		C_LCON,	C_NONE,	C_REG,		13, 8, 0,	LFROM },
-	{ ACMP,		C_LCON,	C_REG,	C_NONE,		13, 8, 0,	LFROM },
-
-	{ AMOVB,	C_REG,	C_NONE,	C_REG,		 1, 4, 0 },
-	{ AMOVBS,	C_REG,	C_NONE,	C_REG,		14, 8, 0 },
-	{ AMOVBU,	C_REG,	C_NONE,	C_REG,		58, 4, 0 },
-	{ AMOVH,	C_REG,	C_NONE,	C_REG,		 1, 4, 0 },
-	{ AMOVHS,	C_REG,	C_NONE,	C_REG,		14, 8, 0 },
-	{ AMOVHU,	C_REG,	C_NONE,	C_REG,		14, 8, 0 },
-
-	{ AMUL,		C_REG,	C_REG,	C_REG,		15, 4, 0 },
-	{ AMUL,		C_REG,	C_NONE,	C_REG,		15, 4, 0 },
-
-	{ ADIV,		C_REG,	C_REG,	C_REG,		16, 4, 0 },
-	{ ADIV,		C_REG,	C_NONE,	C_REG,		16, 4, 0 },
-
-	{ AMULL,	C_REG,	C_REG,	C_REGREG,	17, 4, 0 },
-	{ AMULA,	C_REG,	C_REG,	C_REGREG2,	17, 4, 0 },
-
-	{ AMOVW,	C_REG,	C_NONE,	C_SAUTO,	20, 4, REGSP },
-	{ AMOVW,	C_REG,	C_NONE,	C_SOREG,	20, 4, 0 },
-	{ AMOVB,	C_REG,	C_NONE,	C_SAUTO,	20, 4, REGSP },
-	{ AMOVB,	C_REG,	C_NONE,	C_SOREG,	20, 4, 0 },
-	{ AMOVBS,	C_REG,	C_NONE,	C_SAUTO,	20, 4, REGSP },
-	{ AMOVBS,	C_REG,	C_NONE,	C_SOREG,	20, 4, 0 },
-	{ AMOVBU,	C_REG,	C_NONE,	C_SAUTO,	20, 4, REGSP },
-	{ AMOVBU,	C_REG,	C_NONE,	C_SOREG,	20, 4, 0 },
-
-	{ AMOVW,	C_SAUTO,C_NONE,	C_REG,		21, 4, REGSP },
-	{ AMOVW,	C_SOREG,C_NONE,	C_REG,		21, 4, 0 },
-	{ AMOVBU,	C_SAUTO,C_NONE,	C_REG,		21, 4, REGSP },
-	{ AMOVBU,	C_SOREG,C_NONE,	C_REG,		21, 4, 0 },
-
-	{ AMOVW,	C_REG,	C_NONE,	C_LAUTO,	30, 8, REGSP,	LTO },
-	{ AMOVW,	C_REG,	C_NONE,	C_LOREG,	30, 8, 0,	LTO },
-	{ AMOVW,	C_REG,	C_NONE,	C_ADDR,		64, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVB,	C_REG,	C_NONE,	C_LAUTO,	30, 8, REGSP,	LTO },
-	{ AMOVB,	C_REG,	C_NONE,	C_LOREG,	30, 8, 0,	LTO },
-	{ AMOVB,	C_REG,	C_NONE,	C_ADDR,		64, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVBS,	C_REG,	C_NONE,	C_LAUTO,	30, 8, REGSP,	LTO },
-	{ AMOVBS,	C_REG,	C_NONE,	C_LOREG,	30, 8, 0,	LTO },
-	{ AMOVBS,	C_REG,	C_NONE,	C_ADDR,		64, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVBU,	C_REG,	C_NONE,	C_LAUTO,	30, 8, REGSP,	LTO },
-	{ AMOVBU,	C_REG,	C_NONE,	C_LOREG,	30, 8, 0,	LTO },
-	{ AMOVBU,	C_REG,	C_NONE,	C_ADDR,		64, 8, 0,	LTO | LPCREL, 4 },
-
-	{ AMOVW,	C_LAUTO,C_NONE,	C_REG,		31, 8, REGSP,	LFROM },
-	{ AMOVW,	C_LOREG,C_NONE,	C_REG,		31, 8, 0,	LFROM },
-	{ AMOVW,	C_ADDR,	C_NONE,	C_REG,		65, 8, 0,	LFROM | LPCREL, 4 },
-	{ AMOVBU,	C_LAUTO,C_NONE,	C_REG,		31, 8, REGSP,	LFROM },
-	{ AMOVBU,	C_LOREG,C_NONE,	C_REG,		31, 8, 0,	LFROM },
-	{ AMOVBU,	C_ADDR,	C_NONE,	C_REG,		65, 8, 0,	LFROM | LPCREL, 4 },
-
-	{ AMOVW,	C_LACON,C_NONE,	C_REG,		34, 8, REGSP,	LFROM },
-
-	{ AMOVW,	C_PSR,	C_NONE,	C_REG,		35, 4, 0 },
-	{ AMOVW,	C_REG,	C_NONE,	C_PSR,		36, 4, 0 },
-	{ AMOVW,	C_RCON,	C_NONE,	C_PSR,		37, 4, 0 },
-
-	{ AMOVM,	C_LCON,	C_NONE,	C_SOREG,	38, 4, 0 },
-	{ AMOVM,	C_SOREG,C_NONE,	C_LCON,		39, 4, 0 },
-
-	{ ASWPW,	C_SOREG,C_REG,	C_REG,		40, 4, 0 },
-
-	{ ARFE,		C_NONE,	C_NONE,	C_NONE,		41, 4, 0 },
-
-	{ AMOVF,	C_FREG,	C_NONE,	C_FAUTO,	50, 4, REGSP },
-	{ AMOVF,	C_FREG,	C_NONE,	C_FOREG,	50, 4, 0 },
-
-	{ AMOVF,	C_FAUTO,C_NONE,	C_FREG,		51, 4, REGSP },
-	{ AMOVF,	C_FOREG,C_NONE,	C_FREG,		51, 4, 0 },
-
-	{ AMOVF,	C_FREG,	C_NONE,	C_LAUTO,	52, 12, REGSP,	LTO },
-	{ AMOVF,	C_FREG,	C_NONE,	C_LOREG,	52, 12, 0,	LTO },
-
-	{ AMOVF,	C_LAUTO,C_NONE,	C_FREG,		53, 12, REGSP,	LFROM },
-	{ AMOVF,	C_LOREG,C_NONE,	C_FREG,		53, 12, 0,	LFROM },
-
-	{ AMOVF,	C_FREG,	C_NONE,	C_ADDR,		68, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVF,	C_ADDR,	C_NONE,	C_FREG,		69, 8, 0,	LFROM | LPCREL, 4},
-
-	{ AADDF,	C_FREG,	C_NONE,	C_FREG,		54, 4, 0 },
-	{ AADDF,	C_FREG,	C_REG,	C_FREG,		54, 4, 0 },
-	{ AMOVF,	C_FREG, C_NONE, C_FREG,		54, 4, 0 },
-
-	{ AMOVW,	C_REG,	C_NONE,	C_FCR,		56, 4, 0 },
-	{ AMOVW,	C_FCR,	C_NONE,	C_REG,		57, 4, 0 },
-
-	{ AMOVW,	C_SHIFT,C_NONE,	C_REG,		59, 4, 0 },
-	{ AMOVBU,	C_SHIFT,C_NONE,	C_REG,		59, 4, 0 },
-
-	{ AMOVB,	C_SHIFT,C_NONE,	C_REG,		60, 4, 0 },
-	{ AMOVBS,	C_SHIFT,C_NONE,	C_REG,		60, 4, 0 },
-
-	{ AMOVW,	C_REG,	C_NONE,	C_SHIFT,	61, 4, 0 },
-	{ AMOVB,	C_REG,	C_NONE,	C_SHIFT,	61, 4, 0 },
-	{ AMOVBS,	C_REG,	C_NONE,	C_SHIFT,	61, 4, 0 },
-	{ AMOVBU,	C_REG,	C_NONE,	C_SHIFT,	61, 4, 0 },
-
-	{ ACASE,	C_REG,	C_NONE,	C_NONE,		62, 4, 0, LPCREL, 8 },
-	{ ABCASE,	C_NONE, C_NONE, C_SBRA,		63, 4, 0, LPCREL, 0 },
-
-	{ AMOVH,	C_REG,	C_NONE, C_HAUTO,	70, 4, REGSP,	0 },
-	{ AMOVH,	C_REG,	C_NONE,	C_HOREG,	70, 4, 0,	0 },
-	{ AMOVHS,	C_REG,	C_NONE, C_HAUTO,	70, 4, REGSP,	0 },
-	{ AMOVHS,	C_REG,	C_NONE,	C_HOREG,	70, 4, 0,	0 },
-	{ AMOVHU,	C_REG,	C_NONE, C_HAUTO,	70, 4, REGSP,	0 },
-	{ AMOVHU,	C_REG,	C_NONE,	C_HOREG,	70, 4, 0,	0 },
-
-	{ AMOVB,	C_HAUTO,C_NONE,	C_REG,		71, 4, REGSP,	0 },
-	{ AMOVB,	C_HOREG,C_NONE,	C_REG,		71, 4, 0,	0 },
-	{ AMOVBS,	C_HAUTO,C_NONE,	C_REG,		71, 4, REGSP,	0 },
-	{ AMOVBS,	C_HOREG,C_NONE,	C_REG,		71, 4, 0,	0 },
-	{ AMOVH,	C_HAUTO,C_NONE, C_REG,		71, 4, REGSP,	0 },
-	{ AMOVH,	C_HOREG,C_NONE,	C_REG,		71, 4, 0,	0 },
-	{ AMOVHS,	C_HAUTO,C_NONE, C_REG,		71, 4, REGSP,	0 },
-	{ AMOVHS,	C_HOREG,C_NONE,	C_REG,		71, 4, 0,	0 },
-	{ AMOVHU,	C_HAUTO,C_NONE, C_REG,		71, 4, REGSP,	0 },
-	{ AMOVHU,	C_HOREG,C_NONE,	C_REG,		71, 4, 0,	0 },
-
-	{ AMOVH,	C_REG,	C_NONE, C_LAUTO,	72, 8, REGSP,	LTO },
-	{ AMOVH,	C_REG,	C_NONE,	C_LOREG,	72, 8, 0,	LTO },
-	{ AMOVH,	C_REG,	C_NONE,	C_ADDR,	94, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVHS,	C_REG,	C_NONE, C_LAUTO,	72, 8, REGSP,	LTO },
-	{ AMOVHS,	C_REG,	C_NONE,	C_LOREG,	72, 8, 0,	LTO },
-	{ AMOVHS,	C_REG,	C_NONE,	C_ADDR,	94, 8, 0,	LTO | LPCREL, 4 },
-	{ AMOVHU,	C_REG,	C_NONE, C_LAUTO,	72, 8, REGSP,	LTO },
-	{ AMOVHU,	C_REG,	C_NONE,	C_LOREG,	72, 8, 0,	LTO },
-	{ AMOVHU,	C_REG,	C_NONE,	C_ADDR,	94, 8, 0,	LTO | LPCREL, 4 },
-
-	{ AMOVB,	C_LAUTO,C_NONE,	C_REG,		73, 8, REGSP,	LFROM },
-	{ AMOVB,	C_LOREG,C_NONE,	C_REG,		73, 8, 0,	LFROM },
-	{ AMOVB,	C_ADDR,	C_NONE,	C_REG,		93, 8, 0,	LFROM | LPCREL, 4 },
-	{ AMOVBS,	C_LAUTO,C_NONE,	C_REG,		73, 8, REGSP,	LFROM },
-	{ AMOVBS,	C_LOREG,C_NONE,	C_REG,		73, 8, 0,	LFROM },
-	{ AMOVBS,	C_ADDR,	C_NONE,	C_REG,		93, 8, 0,	LFROM | LPCREL, 4 },
-	{ AMOVH,	C_LAUTO,C_NONE, C_REG,		73, 8, REGSP,	LFROM },
-	{ AMOVH,	C_LOREG,C_NONE,	C_REG,		73, 8, 0,	LFROM },
-	{ AMOVH,	C_ADDR,	C_NONE,	C_REG,		93, 8, 0,	LFROM | LPCREL, 4 },
-	{ AMOVHS,	C_LAUTO,C_NONE, C_REG,		73, 8, REGSP,	LFROM },
-	{ AMOVHS,	C_LOREG,C_NONE,	C_REG,		73, 8, 0,	LFROM },
-	{ AMOVHS,	C_ADDR,	C_NONE,	C_REG,		93, 8, 0,	LFROM | LPCREL, 4 },
-	{ AMOVHU,	C_LAUTO,C_NONE, C_REG,		73, 8, REGSP,	LFROM },
-	{ AMOVHU,	C_LOREG,C_NONE,	C_REG,		73, 8, 0,	LFROM },
-	{ AMOVHU,	C_ADDR,	C_NONE,	C_REG,		93, 8, 0,	LFROM | LPCREL, 4 },
-
-	{ ALDREX,	C_SOREG,C_NONE,	C_REG,		77, 4, 0 },
-	{ ASTREX,	C_SOREG,C_REG,	C_REG,		78, 4, 0 },
-
-	{ AMOVF,	C_ZFCON,C_NONE,	C_FREG,		80, 8, 0 },
-	{ AMOVF,	C_SFCON,C_NONE,	C_FREG,		81, 4, 0 },
-
-	{ ACMPF,	C_FREG,	C_REG,	C_NONE,		82, 8, 0 },
-	{ ACMPF,	C_FREG, C_NONE,	C_NONE,		83, 8, 0 },
-
-	{ AMOVFW,	C_FREG,	C_NONE,	C_FREG,		84, 4, 0 },
-	{ AMOVWF,	C_FREG,	C_NONE,	C_FREG,		85, 4, 0 },
-
-	{ AMOVFW,	C_FREG,	C_NONE,	C_REG,		86, 8, 0 },
-	{ AMOVWF,	C_REG,	C_NONE,	C_FREG,		87, 8, 0 },
-
-	{ AMOVW,	C_REG,	C_NONE,	C_FREG,		88, 4, 0 },
-	{ AMOVW,	C_FREG,	C_NONE,	C_REG,		89, 4, 0 },
-
-	{ ATST,		C_REG,	C_NONE,	C_NONE,		90, 4, 0 },
-
-	{ ALDREXD,	C_SOREG,C_NONE,	C_REG,		91, 4, 0 },
-	{ ASTREXD,	C_SOREG,C_REG,	C_REG,		92, 4, 0 },
-
-	{ APLD,		C_SOREG,C_NONE,	C_NONE,		95, 4, 0 },
-	
-	{ AUNDEF,		C_NONE,	C_NONE,	C_NONE,		96, 4, 0 },
-
-	{ ACLZ,		C_REG,	C_NONE,	C_REG,		97, 4, 0 },
-
-	{ AMULWT,	C_REG,	C_REG,	C_REG,		98, 4, 0 },
-	{ AMULAWT,	C_REG,	C_REG,	C_REGREG2,		99, 4, 0 },
-
-	{ AUSEFIELD,	C_ADDR,	C_NONE,	C_NONE, 	 0, 0, 0 },
-	{ APCDATA,	C_LCON,	C_NONE,	C_LCON,		0, 0, 0 },
-	{ AFUNCDATA,	C_LCON,	C_NONE,	C_ADDR,	0, 0, 0 },
-	{ ANOP,		C_NONE,	C_NONE,	C_NONE,		0, 0, 0 },
-
-	{ ADUFFZERO,	C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },  // same as ABL
-	{ ADUFFCOPY,	C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },  // same as ABL
-
-	{ ADATABUNDLE,	C_NONE, C_NONE, C_NONE,		100, 4, 0 },
-	{ ADATABUNDLEEND,	C_NONE, C_NONE, C_NONE,		100, 0, 0 },
-
-	{ AXXX,		C_NONE,	C_NONE,	C_NONE,		 0, 4, 0 },
-};
-
-static struct {
-	uint32	start;
-	uint32	size;
-	uint32	extra;
-} pool;
-
-static int	checkpool(Link*, Prog*, int);
-static int 	flushpool(Link*, Prog*, int, int);
-static void	addpool(Link*, Prog*, Addr*);
-static void	asmout(Link*, Prog*, Optab*, uint32*);
-static int	asmoutnacl(Link*, int32, Prog*, Optab*, uint32*);
-static Optab*	oplook(Link*, Prog*);
-static uint32	oprrr(Link*, int, int);
-static uint32	olr(Link*, int32, int, int, int);
-static uint32	olhr(Link*, int32, int, int, int);
-static uint32	olrr(Link*, int, int, int, int);
-static uint32	olhrr(Link*, int, int, int, int);
-static uint32	osr(Link*, int, int, int32, int, int);
-static uint32	oshr(Link*, int, int32, int, int);
-static uint32	ofsr(Link*, int, int, int32, int, int, Prog*);
-static uint32	osrr(Link*, int, int, int, int);
-static uint32	oshrr(Link*, int, int, int, int);
-static uint32	omvl(Link*, Prog*, Addr*, int);
-static int32	immaddr(int32);
-static int	aclass(Link*, Addr*);
-static int32	immrot(uint32);
-static int32	immaddr(int32);
-static uint32	opbra(Link*, int, int);
-
-static	Oprang	oprange[ALAST];
-static	uchar	xcmp[C_GOK+1][C_GOK+1];
-
-static LSym *deferreturn;
-
-/* size of a case statement including jump table */
-static int32
-casesz(Link *ctxt, Prog *p)
-{
-	int jt = 0;
-	int32 n = 0;
-	Optab *o;
-
-	for( ; p != nil; p = p->link){
-		if(p->as == ABCASE)
-			jt = 1;
-		else if(jt)
-			break;
-		o = oplook(ctxt, p);
-		n += o->size;
-	}
-	return n;
-}
-
-static void buildop(Link*);
-
-// Note about encoding: Prog.scond holds the condition encoding,
-// but XOR'ed with C_SCOND_XOR, so that C_SCOND_NONE == 0.
-// The code that shifts the value << 28 has the responsibility
-// for XORing with C_SCOND_XOR too.
-
-// asmoutnacl assembles the instruction p. It replaces asmout for NaCl.
-// It returns the total number of bytes put in out, and it can change
-// p->pc if extra padding is necessary.
-// In rare cases, asmoutnacl might split p into two instructions.
-// origPC is the PC for this Prog (no padding is taken into account).
-static int
-asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
-{
-	int size, reg;
-	Prog *q;
-	Addr *a, *a2;
-
-	size = o->size;
-
-	// instruction specific
-	switch(p->as) {
-	default:
-		if(out != nil)
-			asmout(ctxt, p, o, out);
-		break;
-	case ADATABUNDLE: // align to 16-byte boundary
-	case ADATABUNDLEEND: // zero width instruction, just to align next instruction to 16-byte boundary
-		p->pc = (p->pc+15) & ~15;
-		if(out != nil)
-			asmout(ctxt, p, o, out);
-		break;
-	case AUNDEF:
-	case APLD:
-		size = 4;
-		if(out != nil) {
-			switch(p->as) {
-			case AUNDEF:
-				out[0] = 0xe7fedef0; // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0)
-				break;
-			case APLD:
-				out[0] = 0xe1a01001; // (MOVW R1, R1)
-				break;
-			}
-		}
-		break;
-	case AB:
-	case ABL:
-		if(p->to.type != TYPE_MEM) {
-			if(out != nil)
-				asmout(ctxt, p, o, out);
-		} else {
-			if(p->to.offset != 0 || size != 4 || p->to.reg > REG_R15 || p->to.reg < REG_R0)
-				ctxt->diag("unsupported instruction: %P", p);
-			if((p->pc&15) == 12)
-				p->pc += 4;
-			if(out != nil) {
-				out[0] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x03c0013f | ((p->to.reg&15) << 12) | ((p->to.reg&15) << 16); // BIC $0xc000000f, Rx
-				if(p->as == AB)
-					out[1] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x012fff10 | (p->to.reg&15)<<0; // BX Rx
-				else // ABL
-					out[1] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x012fff30 | (p->to.reg&15)<<0; // BLX Rx
-			}
-			size = 8;
-		}
-		// align the last instruction (the actual BL) to the last instruction in a bundle
-		if(p->as == ABL) {
-			if(deferreturn == nil)
-				deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
-			if(p->to.sym == deferreturn)
-				p->pc = ((origPC+15) & ~15) + 16 - size;
-			else
-				p->pc += (16 - ((p->pc+size)&15)) & 15;
-		}
-		break;
-	case ALDREX:
-	case ALDREXD:
-	case AMOVB:
-	case AMOVBS:
-	case AMOVBU:
-	case AMOVD:
-	case AMOVF:
-	case AMOVH:
-	case AMOVHS:
-	case AMOVHU:
-	case AMOVM:
-	case AMOVW:
-	case ASTREX:
-	case ASTREXD:
-		if(p->to.type == TYPE_REG && p->to.reg == REG_R15 && p->from.reg == REG_R13) { // MOVW.W x(R13), PC
-			if(out != nil)
-				asmout(ctxt, p, o, out);
-			if(size == 4) {
-				if(out != nil) {
-					// Note: 5c and 5g reg.c know that DIV/MOD smashes R12
-					// so that this return instruction expansion is valid.
-					out[0] = out[0] & ~0x3000; // change PC to R12
-					out[1] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x03ccc13f; // BIC $0xc000000f, R12
-					out[2] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x012fff1c; // BX R12
-				}
-				size += 8;
-				if(((p->pc+size) & 15) == 4)
-					p->pc += 4;
-				break;
-			} else {
-				// if the instruction used more than 4 bytes, then it must have used a very large
-				// offset to update R13, so we need to additionally mask R13.
-				if(out != nil) {
-					out[size/4-1] &= ~0x3000; // change PC to R12
-					out[size/4] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x03cdd103; // BIC $0xc0000000, R13
-					out[size/4+1] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x03ccc13f; // BIC $0xc000000f, R12
-					out[size/4+2] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x012fff1c; // BX R12
-				}
-				// p->pc+size is only ok at 4 or 12 mod 16.
-				if((p->pc+size)%8 == 0)
-					p->pc += 4;
-				size += 12;
-				break;
-			}
-		}
-
-		if(p->to.type == TYPE_REG && p->to.reg == REG_R15)
-			ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p);
-
-		if(p->to.type == TYPE_MEM && p->to.reg == REG_R13 && (p->scond & C_WBIT) && size > 4) {
-			// function prolog with very large frame size: MOVW.W R14,-100004(R13)
-			// split it into two instructions:
-			// 	ADD $-100004, R13
-			// 	MOVW R14, 0(R13)
-			q = emallocz(sizeof(Prog));
-			p->scond &= ~C_WBIT;
-			*q = *p;
-			a = &p->to;
-			if(p->to.type == TYPE_MEM)
-				a2 = &q->to;
-			else
-				a2 = &q->from;
-			nocache(q);
-			nocache(p);
-			// insert q after p
-			q->link = p->link;
-			p->link = q;
-			q->pcond = nil;
-			// make p into ADD $X, R13
-			p->as = AADD;
-			p->from = *a;
-			p->from.reg = 0;
-			p->from.type = TYPE_CONST;
-			p->to = zprog.to;
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_R13;
-			// make q into p but load/store from 0(R13)
-			q->spadj = 0;
-			*a2 = zprog.from;
-			a2->type = TYPE_MEM;
-			a2->reg = REG_R13;
-			a2->sym = nil;
-			a2->offset = 0;
-			size = oplook(ctxt, p)->size;
-			break;
-		}
-
-		if((p->to.type == TYPE_MEM && p->to.reg != REG_R13 && p->to.reg != REG_R9) || // MOVW Rx, X(Ry), y != 13 && y != 9
-		   (p->from.type == TYPE_MEM && p->from.reg != REG_R13 && p->from.reg != REG_R9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
-			if(p->to.type == TYPE_MEM)
-				a = &p->to;
-			else
-				a = &p->from;
-			reg = a->reg;
-			if(size == 4) {
-				// if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
-				if(reg == 0) {
-					if(out != nil)
-						asmout(ctxt, p, o, out);
-				} else {
-					if(out != nil)
-						out[0] = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | 0x03c00103 | ((reg&15) << 16) | ((reg&15) << 12); // BIC $0xc0000000, Rx
-					if((p->pc&15) == 12)
-						p->pc += 4;
-					size += 4;
-					if(out != nil)
-						asmout(ctxt, p, o, &out[1]);
-				}
-				break;
-			} else {
-				// if a load/store instruction takes more than 1 word to implement, then
-				// we need to seperate the instruction into two:
-				// 1. explicitly load the address into R11.
-				// 2. load/store from R11.
-				// This won't handle .W/.P, so we should reject such code.
-				if(p->scond & (C_PBIT|C_WBIT))
-					ctxt->diag("unsupported instruction (.P/.W): %P", p);
-				q = emallocz(sizeof(Prog));
-				*q = *p;
-				if(p->to.type == TYPE_MEM)
-					a2 = &q->to;
-				else
-					a2 = &q->from;
-				nocache(q);
-				nocache(p);
-				// insert q after p
-				q->link = p->link;
-				p->link = q;
-				q->pcond = nil;
-				// make p into MOVW $X(R), R11
-				p->as = AMOVW;
-				p->from = *a;
-				p->from.type = TYPE_ADDR;
-				p->to = zprog.to;
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_R11;
-				// make q into p but load/store from 0(R11)
-				*a2 = zprog.from;
-				a2->type = TYPE_MEM;
-				a2->reg = REG_R11;
-				a2->sym = nil;
-				a2->offset = 0;
-				size = oplook(ctxt, p)->size;
-				break;
-			}
-		} else if(out != nil)
-			asmout(ctxt, p, o, out);
-		break;
-	}
-
-	// destination register specific
-	if(p->to.type == TYPE_REG) {
-		switch(p->to.reg) {
-		case REG_R9:
-			ctxt->diag("invalid instruction, cannot write to R9: %P", p);
-			break;
-		case REG_R13:
-			if(out != nil)
-				out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13
-			if(((p->pc+size) & 15) == 0)
-				p->pc += 4;
-			size += 4;
-			break;
-		}
-	}
-	return size;
-}
-
-void
-span5(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *op;
-	Optab *o;
-	int m, bflag, i, v, times;
-	int32 c, opc;
-	uint32 out[6+3];
-	uchar *bp;
-
-	p = cursym->text;
-	if(p == nil || p->link == nil) // handle external functions and ELF section symbols
-		return;
- 
- 	if(oprange[AAND].start == nil)
- 		buildop(ctxt);
-
- 	ctxt->cursym = cursym;
-
-	ctxt->autosize = p->to.offset + 4;
-	c = 0;
-
-	for(op = p, p = p->link; p != nil || ctxt->blitrl != nil; op = p, p = p->link) {
-		if(p == nil) {
-		       	if(checkpool(ctxt, op, 0)) {
-				p = op;
-				continue;
-			}
-			// can't happen: blitrl is not nil, but checkpool didn't flushpool
-			ctxt->diag("internal inconsistency");
-			break;
-		}
-		ctxt->curp = p;
-		p->pc = c;
-		o = oplook(ctxt, p);
-		if(ctxt->headtype != Hnacl) {
-			m = o->size;
-		} else {
-			m = asmoutnacl(ctxt, c, p, o, nil);
-			c = p->pc; // asmoutnacl might change pc for alignment
-			o = oplook(ctxt, p); // asmoutnacl might change p in rare cases
-		}
-		if(m % 4 != 0 || p->pc % 4 != 0) {
-			ctxt->diag("!pc invalid: %P size=%d", p, m);
-		}
-		// must check literal pool here in case p generates many instructions
-		if(ctxt->blitrl){
-			i = m;
-			if(p->as == ACASE)
-				i = casesz(ctxt, p);
-			if(checkpool(ctxt, op, i)) {
-				p = op;
-				continue;
-			}
-		}
-		if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA && p->as != ADATABUNDLEEND && p->as != ANOP)) {
-			ctxt->diag("zero-width instruction\n%P", p);
-			continue;
-		}
-		switch(o->flag & (LFROM|LTO|LPOOL)) {
-		case LFROM:
-			addpool(ctxt, p, &p->from);
-			break;
-		case LTO:
-			addpool(ctxt, p, &p->to);
-			break;
-		case LPOOL:
-			if ((p->scond&C_SCOND) == C_SCOND_NONE)
-				flushpool(ctxt, p, 0, 0);
-			break;
-		}
-		if(p->as==AMOVW && p->to.type==TYPE_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
-			flushpool(ctxt, p, 0, 0);
-		c += m;
-	}
-	cursym->size = c;
-
-	/*
-	 * if any procedure is large enough to
-	 * generate a large SBRA branch, then
-	 * generate extra passes putting branches
-	 * around jmps to fix. this is rare.
-	 */
-	times = 0;
-	do {
-		if(ctxt->debugvlog)
-			Bprint(ctxt->bso, "%5.2f span1\n", cputime());
-		bflag = 0;
-		c = 0;
-		times++;
-		cursym->text->pc = 0; // force re-layout the code.
-		for(p = cursym->text; p != nil; p = p->link) {
-			ctxt->curp = p;
-			o = oplook(ctxt,p);
-			if(c > p->pc)
-				p->pc = c;
-/* very large branches
-			if(o->type == 6 && p->pcond) {
-				otxt = p->pcond->pc - c;
-				if(otxt < 0)
-					otxt = -otxt;
-				if(otxt >= (1L<<17) - 10) {
-					q = emallocz(sizeof(Prog));
-					q->link = p->link;
-					p->link = q;
-					q->as = AB;
-					q->to.type = TYPE_BRANCH;
-					q->pcond = p->pcond;
-					p->pcond = q;
-					q = emallocz(sizeof(Prog));
-					q->link = p->link;
-					p->link = q;
-					q->as = AB;
-					q->to.type = TYPE_BRANCH;
-					q->pcond = q->link->link;
-					bflag = 1;
-				}
-			}
- */
-			opc = p->pc;
-			if(ctxt->headtype != Hnacl)
-				m = o->size;
-			else
-				m = asmoutnacl(ctxt, c, p, o, nil);
-			if(p->pc != opc) {
-				bflag = 1;
-				//print("%P pc changed %d to %d in iter. %d\n", p, opc, (int32)p->pc, times);
-			}
-			c = p->pc + m;
-			if(m % 4 != 0 || p->pc % 4 != 0) {
-				ctxt->diag("pc invalid: %P size=%d", p, m);
-			}
-			if(m/4 > nelem(out))
-				ctxt->diag("instruction size too large: %d > %d", m/4, nelem(out));
-			if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA && p->as != ADATABUNDLEEND && p->as != ANOP)) {
-				if(p->as == ATEXT) {
-					ctxt->autosize = p->to.offset + 4;
-					continue;
-				}
-				ctxt->diag("zero-width instruction\n%P", p);
-				continue;
-			}
-		}
-		cursym->size = c;
-	} while(bflag);
-	if(c % 4 != 0) {
-		ctxt->diag("sym->size=%d, invalid", c);
-	}
-
-	/*
-	 * lay out the code.  all the pc-relative code references,
-	 * even cross-function, are resolved now;
-	 * only data references need to be relocated.
-	 * with more work we could leave cross-function
-	 * code references to be relocated too, and then
-	 * perhaps we'd be able to parallelize the span loop above.
-	 */
-	if(ctxt->tlsg == nil)
-		ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
-
-	p = cursym->text;
-	ctxt->autosize = p->to.offset + 4;
-	symgrow(ctxt, cursym, cursym->size);
-
-	bp = cursym->p;
-	c = p->pc; // even p->link might need extra padding
-	for(p = p->link; p != nil; p = p->link) {
-		ctxt->pc = p->pc;
-		ctxt->curp = p;
-		o = oplook(ctxt, p);
-		opc = p->pc;
-		if(ctxt->headtype != Hnacl) {
-			asmout(ctxt, p, o, out);
-			m = o->size;
-		} else {
-			m = asmoutnacl(ctxt, c, p, o, out);
-			if(opc != p->pc)
-				ctxt->diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %P", opc, (int32)p->pc, p);
-		}
-		if(m % 4 != 0 || p->pc % 4 != 0) {
-			ctxt->diag("final stage: pc invalid: %P size=%d", p, m);
-		}
-		if(c > p->pc)
-			ctxt->diag("PC padding invalid: want %#lld, has %#d: %P", p->pc, c, p);
-		while(c != p->pc) {
-			// emit 0xe1a00000 (MOVW R0, R0)
-			*bp++ = 0x00;
-			*bp++ = 0x00;
-			*bp++ = 0xa0;
-			*bp++ = 0xe1;
-			c += 4;
-		}
-		for(i=0; i<m/4; i++) {
-			v = out[i];
-			*bp++ = v;
-			*bp++ = v>>8;
-			*bp++ = v>>16;
-			*bp++ = v>>24;
-		}
-		c += m;
-	}
-}
-
-/*
- * when the first reference to the literal pool threatens
- * to go out of range of a 12-bit PC-relative offset,
- * drop the pool now, and branch round it.
- * this happens only in extended basic blocks that exceed 4k.
- */
-static int
-checkpool(Link *ctxt, Prog *p, int sz)
-{
-	if(pool.size >= 0xff0 || immaddr((p->pc+sz+4)+4+(12+pool.size) - (pool.start+8)) == 0)
-		return flushpool(ctxt, p, 1, 0);
-	else if(p->link == nil)
-		return flushpool(ctxt, p, 2, 0);
-	return 0;
-}
-
-static int
-flushpool(Link *ctxt, Prog *p, int skip, int force)
-{
-	Prog *q;
-
-	if(ctxt->blitrl) {
-		if(skip){
-			if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
-			q = emallocz(sizeof(Prog));
-			q->as = AB;
-			q->to.type = TYPE_BRANCH;
-			q->pcond = p->link;
-			q->link = ctxt->blitrl;
-			q->lineno = p->lineno;
-			ctxt->blitrl = q;
-		}
-		else if(!force && (p->pc+(12+pool.size)-pool.start < 2048)) // 12 take into account the maximum nacl literal pool alignment padding size
-			return 0;
-		if(ctxt->headtype == Hnacl && pool.size % 16 != 0) {
-			// if pool is not multiple of 16 bytes, add an alignment marker
-			q = emallocz(sizeof(Prog));
-			q->as = ADATABUNDLEEND;
-			ctxt->elitrl->link = q;
-			ctxt->elitrl = q;
-		}
-		ctxt->elitrl->link = p->link;
-		p->link = ctxt->blitrl;
-		// BUG(minux): how to correctly handle line number for constant pool entries?
-		// for now, we set line number to the last instruction preceding them at least
-		// this won't bloat the .debug_line tables
-		while(ctxt->blitrl) {
-			ctxt->blitrl->lineno = p->lineno;
-			ctxt->blitrl = ctxt->blitrl->link;
-		}
-		ctxt->blitrl = 0;	/* BUG: should refer back to values until out-of-range */
-		ctxt->elitrl = 0;
-		pool.size = 0;
-		pool.start = 0;
-		pool.extra = 0;
-		return 1;
-	}
-	return 0;
-}
-
-static void
-addpool(Link *ctxt, Prog *p, Addr *a)
-{
-	Prog *q, t;
-	int c;
-
-	c = aclass(ctxt, a);
-
-	t = zprog;
-	t.as = AWORD;
-
-	switch(c) {
-	default:
-		t.to.offset = a->offset;
-		t.to.sym = a->sym;
-		t.to.type = a->type;
-		t.to.name = a->name;
-		
-		if(ctxt->flag_shared && t.to.sym != nil)
-			t.pcrel = p;
-		break;
-
-	case C_SROREG:
-	case C_LOREG:
-	case C_ROREG:
-	case C_FOREG:
-	case C_SOREG:
-	case C_HOREG:
-	case C_FAUTO:
-	case C_SAUTO:
-	case C_LAUTO:
-	case C_LACON:
-		t.to.type = TYPE_CONST;
-		t.to.offset = ctxt->instoffset;
-		break;
-	}
-
-	if(t.pcrel == nil) {
-		for(q = ctxt->blitrl; q != nil; q = q->link)	/* could hash on t.t0.offset */
-			if(q->pcrel == nil && memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
-				p->pcond = q;
-				return;
-			}
-	}
-
-	if(ctxt->headtype == Hnacl && pool.size%16 == 0) {
-		// start a new data bundle
-		q = emallocz(sizeof(Prog));
-		*q = zprog;
-		q->as = ADATABUNDLE;
-		q->pc = pool.size;
-		pool.size += 4;
-		if(ctxt->blitrl == nil) {
-			ctxt->blitrl = q;
-			pool.start = p->pc;
-		} else {
-			ctxt->elitrl->link = q;
-		}
-		ctxt->elitrl = q;
-	}
-
-	q = emallocz(sizeof(Prog));
-	*q = t;
-	q->pc = pool.size;
-
-	if(ctxt->blitrl == nil) {
-		ctxt->blitrl = q;
-		pool.start = p->pc;
-	} else
-		ctxt->elitrl->link = q;
-	ctxt->elitrl = q;
-	pool.size += 4;
-
-	p->pcond = q;
-}
-
-static int32
-regoff(Link *ctxt, Addr *a)
-{
-
-	ctxt->instoffset = 0;
-	aclass(ctxt, a);
-	return ctxt->instoffset;
-}
-
-static int32
-immrot(uint32 v)
-{
-	int i;
-
-	for(i=0; i<16; i++) {
-		if((v & ~0xff) == 0)
-			return (i<<8) | v | (1<<25);
-		v = (v<<2) | (v>>30);
-	}
-	return 0;
-}
-
-static int32
-immaddr(int32 v)
-{
-	if(v >= 0 && v <= 0xfff)
-		return (v & 0xfff) |
-			(1<<24) |	/* pre indexing */
-			(1<<23);	/* pre indexing, up */
-	if(v >= -0xfff && v < 0)
-		return (-v & 0xfff) |
-			(1<<24);	/* pre indexing */
-	return 0;
-}
-
-static int
-immfloat(int32 v)
-{
-	return (v & 0xC03) == 0;	/* offset will fit in floating-point load/store */
-}
-
-static int
-immhalf(int32 v)
-{
-	if(v >= 0 && v <= 0xff)
-		return v|
-			(1<<24)|	/* pre indexing */
-			(1<<23);	/* pre indexing, up */
-	if(v >= -0xff && v < 0)
-		return (-v & 0xff)|
-			(1<<24);	/* pre indexing */
-	return 0;
-}
-
-static int aconsize(Link *ctxt);
-
-static int
-aclass(Link *ctxt, Addr *a)
-{
-	LSym *s;
-	int t;
-
-	switch(a->type) {
-	case TYPE_NONE:
-		return C_NONE;
-
-	case TYPE_REG:
-		if(REG_R0 <= a->reg && a->reg <= REG_R15)
-			return C_REG;
-		if(REG_F0 <= a->reg && a->reg <= REG_F15)
-			return C_FREG;
-		if(a->reg == REG_FPSR || a->reg == REG_FPCR)
-			return C_FCR;
-		if(a->reg == REG_CPSR || a->reg == REG_SPSR)
-			return C_PSR;
-		return C_GOK;
-
-	case TYPE_REGREG:
-		return C_REGREG;
-
-	case TYPE_REGREG2:
-		return C_REGREG2;
-
-	case TYPE_SHIFT:
-		return C_SHIFT;
-
-	case TYPE_MEM:
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			if(a->sym == 0 || a->sym->name == 0) {
-				print("null sym external\n");
-				return C_GOK;
-			}
-			ctxt->instoffset = 0;	// s.b. unused but just in case
-			return C_ADDR;
-
-		case NAME_AUTO:
-			ctxt->instoffset = ctxt->autosize + a->offset;
-			t = immaddr(ctxt->instoffset);
-			if(t){
-				if(immhalf(ctxt->instoffset)) {
-					if(immfloat(t))
-						return C_HFAUTO;
-					return C_HAUTO;
-				}
-				if(immfloat(t))
-					return C_FAUTO;
-				return C_SAUTO;
-			}
-			return C_LAUTO;
-
-		case NAME_PARAM:
-			ctxt->instoffset = ctxt->autosize + a->offset + 4L;
-			t = immaddr(ctxt->instoffset);
-			if(t){
-				if(immhalf(ctxt->instoffset)) {
-					if(immfloat(t))
-						return C_HFAUTO;
-					return C_HAUTO;
-				}
-				if(immfloat(t))
-					return C_FAUTO;
-				return C_SAUTO;
-			}
-			return C_LAUTO;
-		case TYPE_NONE:
-			ctxt->instoffset = a->offset;
-			t = immaddr(ctxt->instoffset);
-			if(t) {
-				if(immhalf(ctxt->instoffset)) {		 /* n.b. that it will also satisfy immrot */
-					if(immfloat(t))
-						return C_HFOREG;
-					return C_HOREG;
-				}
-				if(immfloat(t))
-					return C_FOREG; /* n.b. that it will also satisfy immrot */
-				t = immrot(ctxt->instoffset);
-				if(t)
-					return C_SROREG;
-				if(immhalf(ctxt->instoffset))
-					return C_HOREG;
-				return C_SOREG;
-			}
-			t = immrot(ctxt->instoffset);
-			if(t)
-				return C_ROREG;
-			return C_LOREG;
-		}
-		return C_GOK;
-
-	case TYPE_FCONST:
-		if(chipzero5(ctxt, a->u.dval) >= 0)
-			return C_ZFCON;
-		if(chipfloat5(ctxt, a->u.dval) >= 0)
-			return C_SFCON;
-		return C_LFCON;
-
-	case TYPE_TEXTSIZE:
-		return C_TEXTSIZE;
-
-	case TYPE_CONST:
-	case TYPE_ADDR:
-		switch(a->name) {
-
-		case TYPE_NONE:
-			ctxt->instoffset = a->offset;
-			if(a->reg != 0)
-				return aconsize(ctxt);
-
-			t = immrot(ctxt->instoffset);
-			if(t)
-				return C_RCON;
-			t = immrot(~ctxt->instoffset);
-			if(t)
-				return C_NCON;
-			return C_LCON;
-
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			s = a->sym;
-			if(s == nil)
-				break;
-			ctxt->instoffset = 0;	// s.b. unused but just in case
-			return C_LCONADDR;
-
-		case NAME_AUTO:
-			ctxt->instoffset = ctxt->autosize + a->offset;
-			return aconsize(ctxt);
-
-		case NAME_PARAM:
-			ctxt->instoffset = ctxt->autosize + a->offset + 4L;
-			return aconsize(ctxt);
-		}
-		return C_GOK;
-
-	case TYPE_BRANCH:
-		return C_SBRA;
-	}
-	return C_GOK;
-}
-
-static int
-aconsize(Link *ctxt)
-{
-	int t;
-
-	t = immrot(ctxt->instoffset);
-	if(t)
-		return C_RACON;
-	return C_LACON;
-}
-
-static void
-prasm(Prog *p)
-{
-	print("%P\n", p);
-}
-
-static Optab*
-oplook(Link *ctxt, Prog *p)
-{
-	int a1, a2, a3, r;
-	uchar *c1, *c3;
-	Optab *o, *e;
-
-	a1 = p->optab;
-	if(a1)
-		return optab+(a1-1);
-	a1 = p->from.class;
-	if(a1 == 0) {
-		a1 = aclass(ctxt, &p->from) + 1;
-		p->from.class = a1;
-	}
-	a1--;
-	a3 = p->to.class;
-	if(a3 == 0) {
-		a3 = aclass(ctxt, &p->to) + 1;
-		p->to.class = a3;
-	}
-	a3--;
-	a2 = C_NONE;
-	if(p->reg != 0)
-		a2 = C_REG;
-	r = p->as;
-	o = oprange[r].start;
-	if(o == 0) {
-		o = oprange[r].stop; /* just generate an error */
-	}
-	if(0 /*debug['O']*/) {
-		print("oplook %A %^ %^ %^\n",
-			(int)p->as, a1, a2, a3);
-		print("		%d %d\n", p->from.type, p->to.type);
-	}
-	e = oprange[r].stop;
-	c1 = xcmp[a1];
-	c3 = xcmp[a3];
-	for(; o<e; o++)
-		if(o->a2 == a2)
-		if(c1[o->a1])
-		if(c3[o->a3]) {
-			p->optab = (o-optab)+1;
-			return o;
-		}
-	ctxt->diag("illegal combination %P; %^ %^ %^, %d %d",
-		p, a1, a2, a3, p->from.type, p->to.type);
-	ctxt->diag("from %d %d to %d %d\n", p->from.type, p->from.name, p->to.type, p->to.name);
-	prasm(p);
-	if(o == 0)
-		o = optab;
-	return o;
-}
-
-static int
-cmp(int a, int b)
-{
-
-	if(a == b)
-		return 1;
-	switch(a) {
-	case C_LCON:
-		if(b == C_RCON || b == C_NCON)
-			return 1;
-		break;
-	case C_LACON:
-		if(b == C_RACON)
-			return 1;
-		break;
-	case C_LFCON:
-		if(b == C_ZFCON || b == C_SFCON)
-			return 1;
-		break;
-
-	case C_HFAUTO:
-		return b == C_HAUTO || b == C_FAUTO;
-	case C_FAUTO:
-	case C_HAUTO:
-		return b == C_HFAUTO;
-	case C_SAUTO:
-		return cmp(C_HFAUTO, b);
-	case C_LAUTO:
-		return cmp(C_SAUTO, b);
-
-	case C_HFOREG:
-		return b == C_HOREG || b == C_FOREG;
-	case C_FOREG:
-	case C_HOREG:
-		return b == C_HFOREG;
-	case C_SROREG:
-		return cmp(C_SOREG, b) || cmp(C_ROREG, b);
-	case C_SOREG:
-	case C_ROREG:
-		return b == C_SROREG || cmp(C_HFOREG, b);
-	case C_LOREG:
-		return cmp(C_SROREG, b);
-
-	case C_LBRA:
-		if(b == C_SBRA)
-			return 1;
-		break;
-
-	case C_HREG:
-		return cmp(C_SP, b) || cmp(C_PC, b);
-
-	}
-	return 0;
-}
-
-static int
-ocmp(const void *a1, const void *a2)
-{
-	Optab *p1, *p2;
-	int n;
-
-	p1 = (Optab*)a1;
-	p2 = (Optab*)a2;
-	n = p1->as - p2->as;
-	if(n)
-		return n;
-	n = p1->a1 - p2->a1;
-	if(n)
-		return n;
-	n = p1->a2 - p2->a2;
-	if(n)
-		return n;
-	n = p1->a3 - p2->a3;
-	if(n)
-		return n;
-	return 0;
-}
-
-static void
-buildop(Link *ctxt)
-{
-	int i, n, r;
-
-	for(i=0; i<C_GOK; i++)
-		for(n=0; n<C_GOK; n++)
-			xcmp[i][n] = cmp(n, i);
-	for(n=0; optab[n].as != AXXX; n++) {
-		if((optab[n].flag & LPCREL) != 0) {
-			if(ctxt->flag_shared)
-				optab[n].size += optab[n].pcrelsiz;
-			else
-				optab[n].flag &= ~LPCREL;
-		}
-	}
-	qsort(optab, n, sizeof(optab[0]), ocmp);
-	for(i=0; i<n; i++) {
-		r = optab[i].as;
-		oprange[r].start = optab+i;
-		while(optab[i].as == r)
-			i++;
-		oprange[r].stop = optab+i;
-		i--;
-
-		switch(r)
-		{
-		default:
-			ctxt->diag("unknown op in build: %A", r);
-			sysfatal("bad code");
-		case AADD:
-			oprange[AAND] = oprange[r];
-			oprange[AEOR] = oprange[r];
-			oprange[ASUB] = oprange[r];
-			oprange[ARSB] = oprange[r];
-			oprange[AADC] = oprange[r];
-			oprange[ASBC] = oprange[r];
-			oprange[ARSC] = oprange[r];
-			oprange[AORR] = oprange[r];
-			oprange[ABIC] = oprange[r];
-			break;
-		case ACMP:
-			oprange[ATEQ] = oprange[r];
-			oprange[ACMN] = oprange[r];
-			break;
-		case AMVN:
-			break;
-		case ABEQ:
-			oprange[ABNE] = oprange[r];
-			oprange[ABCS] = oprange[r];
-			oprange[ABHS] = oprange[r];
-			oprange[ABCC] = oprange[r];
-			oprange[ABLO] = oprange[r];
-			oprange[ABMI] = oprange[r];
-			oprange[ABPL] = oprange[r];
-			oprange[ABVS] = oprange[r];
-			oprange[ABVC] = oprange[r];
-			oprange[ABHI] = oprange[r];
-			oprange[ABLS] = oprange[r];
-			oprange[ABGE] = oprange[r];
-			oprange[ABLT] = oprange[r];
-			oprange[ABGT] = oprange[r];
-			oprange[ABLE] = oprange[r];
-			break;
-		case ASLL:
-			oprange[ASRL] = oprange[r];
-			oprange[ASRA] = oprange[r];
-			break;
-		case AMUL:
-			oprange[AMULU] = oprange[r];
-			break;
-		case ADIV:
-			oprange[AMOD] = oprange[r];
-			oprange[AMODU] = oprange[r];
-			oprange[ADIVU] = oprange[r];
-			break;
-		case AMOVW:
-		case AMOVB:
-		case AMOVBS:
-		case AMOVBU:
-		case AMOVH:
-		case AMOVHS:
-		case AMOVHU:
-			break;
-		case ASWPW:
-			oprange[ASWPBU] = oprange[r];
-			break;
-		case AB:
-		case ABL:
-		case ABX:
-		case ABXRET:
-		case ADUFFZERO:
-		case ADUFFCOPY:
-		case ASWI:
-		case AWORD:
-		case AMOVM:
-		case ARFE:
-		case ATEXT:
-		case AUSEFIELD:
-		case ACASE:
-		case ABCASE:
-		case ATYPE:
-			break;
-		case AADDF:
-			oprange[AADDD] = oprange[r];
-			oprange[ASUBF] = oprange[r];
-			oprange[ASUBD] = oprange[r];
-			oprange[AMULF] = oprange[r];
-			oprange[AMULD] = oprange[r];
-			oprange[ADIVF] = oprange[r];
-			oprange[ADIVD] = oprange[r];
-			oprange[ASQRTF] = oprange[r];
-			oprange[ASQRTD] = oprange[r];
-			oprange[AMOVFD] = oprange[r];
-			oprange[AMOVDF] = oprange[r];
-			oprange[AABSF] = oprange[r];
-			oprange[AABSD] = oprange[r];
-			break;
-
-		case ACMPF:
-			oprange[ACMPD] = oprange[r];
-			break;
-
-		case AMOVF:
-			oprange[AMOVD] = oprange[r];
-			break;
-
-		case AMOVFW:
-			oprange[AMOVDW] = oprange[r];
-			break;
-
-		case AMOVWF:
-			oprange[AMOVWD] = oprange[r];
-			break;
-
-		case AMULL:
-			oprange[AMULAL] = oprange[r];
-			oprange[AMULLU] = oprange[r];
-			oprange[AMULALU] = oprange[r];
-			break;
-
-		case AMULWT:
-			oprange[AMULWB] = oprange[r];
-			break;
-
-		case AMULAWT:
-			oprange[AMULAWB] = oprange[r];
-			break;
-
-		case AMULA:
-		case ALDREX:
-		case ASTREX:
-		case ALDREXD:
-		case ASTREXD:
-		case ATST:
-		case APLD:
-		case AUNDEF:
-		case ACLZ:
-		case AFUNCDATA:
-		case APCDATA:
-		case ANOP:
-		case ADATABUNDLE:
-		case ADATABUNDLEEND:
-			break;
-		}
-	}
-}
-
-static uint32 mov(Link*, Prog*);
-
-static void
-asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
-{
-	uint32 o1, o2, o3, o4, o5, o6;
-	int32 v;
-	int r, rf, rt, rt2;
-	Reloc *rel;
-
-ctxt->printp = p;
-	o1 = 0;
-	o2 = 0;
-	o3 = 0;
-	o4 = 0;
-	o5 = 0;
-	o6 = 0;
-	ctxt->armsize += o->size;
-if(0 /*debug['P']*/) print("%ux: %P	type %d\n", (uint32)(p->pc), p, o->type);
-	switch(o->type) {
-	default:
-		ctxt->diag("unknown asm %d", o->type);
-		prasm(p);
-		break;
-
-	case 0:		/* pseudo ops */
-if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p->from.sym->fnptr);
-		break;
-
-	case 1:		/* op R,[R],R */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		rf = p->from.reg;
-		rt = p->to.reg;
-		r = p->reg;
-		if(p->to.type == TYPE_NONE)
-			rt = 0;
-		if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN)
-			r = 0;
-		else
-		if(r == 0)
-			r = rt;
-		o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
-		break;
-
-	case 2:		/* movbu $I,[R],R */
-		aclass(ctxt, &p->from);
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= immrot(ctxt->instoffset);
-		rt = p->to.reg;
-		r = p->reg;
-		if(p->to.type == TYPE_NONE)
-			rt = 0;
-		if(p->as == AMOVW || p->as == AMVN)
-			r = 0;
-		else if(r == 0)
-			r = rt;
-		o1 |= ((r&15)<<16) | ((rt&15)<<12);
-		break;
-
-	case 3:		/* add R<<[IR],[R],R */
-		o1 = mov(ctxt, p);
-		break;
-
-	case 4:		/* add $I,[R],R */
-		aclass(ctxt, &p->from);
-		o1 = oprrr(ctxt, AADD, p->scond);
-		o1 |= immrot(ctxt->instoffset);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 |= (r&15) << 16;
-		o1 |= (p->to.reg&15) << 12;
-		break;
-
-	case 5:		/* bra s */
-		o1 = opbra(ctxt, p->as, p->scond);
-		v = -8;
-		if(p->to.sym != nil) {
-			rel = addrel(ctxt->cursym);
-			rel->off = ctxt->pc;
-			rel->siz = 4;
-			rel->sym = p->to.sym;
-			v += p->to.offset;
-			rel->add = o1 | ((v >> 2) & 0xffffff);
-			rel->type = R_CALLARM;
-			break;
-		}
-		if(p->pcond != nil)
-			v = (p->pcond->pc - ctxt->pc) - 8;
-		o1 |= (v >> 2) & 0xffffff;
-		break;
-
-	case 6:		/* b ,O(R) -> add $O,R,PC */
-		aclass(ctxt, &p->to);
-		o1 = oprrr(ctxt, AADD, p->scond);
-		o1 |= immrot(ctxt->instoffset);
-		o1 |= (p->to.reg&15) << 16;
-		o1 |= (REGPC&15) << 12;
-		break;
-
-	case 7:		/* bl (R) -> blx R */
-		aclass(ctxt, &p->to);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("%P: doesn't support BL offset(REG) where offset != 0", p);
-		o1 = oprrr(ctxt, ABL, p->scond);
-		o1 |= (p->to.reg&15) << 0;
-		rel = addrel(ctxt->cursym);
-		rel->off = ctxt->pc;
-		rel->siz = 0;
-		rel->type = R_CALLIND;
-		break;
-
-	case 8:		/* sll $c,[R],R -> mov (R<<$c),R */
-		aclass(ctxt, &p->from);
-		o1 = oprrr(ctxt, p->as, p->scond);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 |= (r&15) << 0;
-		o1 |= (ctxt->instoffset&31) << 7;
-		o1 |= (p->to.reg&15) << 12;
-		break;
-
-	case 9:		/* sll R,[R],R -> mov (R<<R),R */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 |= (r&15) << 0;
-		o1 |= ((p->from.reg&15) << 8) | (1<<4);
-		o1 |= (p->to.reg&15) << 12;
-		break;
-
-	case 10:	/* swi [$con] */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		if(p->to.type != TYPE_NONE) {
-			aclass(ctxt, &p->to);
-			o1 |= ctxt->instoffset & 0xffffff;
-		}
-		break;
-
-	case 11:	/* word */
-		aclass(ctxt, &p->to);
-		o1 = ctxt->instoffset;
-		if(p->to.sym != nil) {
-			// This case happens with words generated
-			// in the PC stream as part of the literal pool.
-			rel = addrel(ctxt->cursym);
-			rel->off = ctxt->pc;
-			rel->siz = 4;
-			rel->sym = p->to.sym;
-			rel->add = p->to.offset;
-			
-			// runtime.tlsg is special.
-			// Its "address" is the offset from the TLS thread pointer
-			// to the thread-local g and m pointers.
-			// Emit a TLS relocation instead of a standard one if its
-			// type is not explicitly set by runtime. This assumes that
-			// all references to runtime.tlsg should be accompanied with
-			// its type declaration if necessary.
-			if(rel->sym == ctxt->tlsg && ctxt->tlsg->type == 0) {
-				rel->type = R_TLS;
-				if(ctxt->flag_shared)
-					rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz;
-				rel->xadd = rel->add;
-				rel->xsym = rel->sym;
-			} else if(ctxt->flag_shared) {
-				rel->type = R_PCREL;
-				rel->add += ctxt->pc - p->pcrel->pc - 8;
-			} else
-				rel->type = R_ADDR;
-			o1 = 0;
-		}
-		break;
-
-	case 12:	/* movw $lcon, reg */
-		o1 = omvl(ctxt, p, &p->from, p->to.reg);
-		if(o->flag & LPCREL) {
-			o2 = oprrr(ctxt, AADD, p->scond) | (p->to.reg&15) << 0 | (REGPC&15) << 16 | (p->to.reg&15) << 12;
-		}
-		break;
-
-	case 13:	/* op $lcon, [R], R */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		o2 = oprrr(ctxt, p->as, p->scond);
-		o2 |= (REGTMP&15);
-		r = p->reg;
-		if(p->as == AMOVW || p->as == AMVN)
-			r = 0;
-		else if(r == 0)
-			r = p->to.reg;
-		o2 |= (r&15) << 16;
-		if(p->to.type != TYPE_NONE)
-			o2 |= (p->to.reg&15) << 12;
-		break;
-
-	case 14:	/* movb/movbu/movh/movhu R,R */
-		o1 = oprrr(ctxt, ASLL, p->scond);
-
-		if(p->as == AMOVBU || p->as == AMOVHU)
-			o2 = oprrr(ctxt, ASRL, p->scond);
-		else
-			o2 = oprrr(ctxt, ASRA, p->scond);
-
-		r = p->to.reg;
-		o1 |= ((p->from.reg&15)<<0)|((r&15)<<12);
-		o2 |= (r&15)|((r&15)<<12);
-		if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) {
-			o1 |= (24<<7);
-			o2 |= (24<<7);
-		} else {
-			o1 |= (16<<7);
-			o2 |= (16<<7);
-		}
-		break;
-
-	case 15:	/* mul r,[r,]r */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		rf = p->from.reg;
-		rt = p->to.reg;
-		r = p->reg;
-		if(r == 0)
-			r = rt;
-		if(rt == r) {
-			r = rf;
-			rf = rt;
-		}
-		if(0)
-		if(rt == r || rf == (REGPC&15) || r == (REGPC&15) || rt == (REGPC&15)) {
-			ctxt->diag("bad registers in MUL");
-			prasm(p);
-		}
-		o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16);
-		break;
-
-
-	case 16:	/* div r,[r,]r */
-		o1 = 0xf << 28;
-		o2 = 0;
-		break;
-
-	case 17:
-		o1 = oprrr(ctxt, p->as, p->scond);
-		rf = p->from.reg;
-		rt = p->to.reg;
-		rt2 = p->to.offset;
-		r = p->reg;
-		o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16) | ((rt2&15)<<12);
-		break;
-
-	case 20:	/* mov/movb/movbu R,O(R) */
-		aclass(ctxt, &p->to);
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = osr(ctxt, p->as, p->from.reg, ctxt->instoffset, r, p->scond);
-		break;
-
-	case 21:	/* mov/movbu O(R),R -> lr */
-		aclass(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = olr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
-		if(p->as != AMOVW)
-			o1 |= 1<<22;
-		break;
-
-	case 30:	/* mov/movb/movbu R,L(R) */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = osrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
-		if(p->as != AMOVW)
-			o2 |= 1<<22;
-		break;
-
-	case 31:	/* mov/movbu L(R),R -> lr[b] */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = olrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
-		if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
-			o2 |= 1<<22;
-		break;
-
-	case 34:	/* mov $lacon,R */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-
-		o2 = oprrr(ctxt, AADD, p->scond);
-		o2 |= (REGTMP&15);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o2 |= (r&15) << 16;
-		if(p->to.type != TYPE_NONE)
-			o2 |= (p->to.reg&15) << 12;
-		break;
-
-	case 35:	/* mov PSR,R */
-		o1 = (2<<23) | (0xf<<16) | (0<<0);
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		o1 |= (p->from.reg & 1) << 22;
-		o1 |= (p->to.reg&15) << 12;
-		break;
-
-	case 36:	/* mov R,PSR */
-		o1 = (2<<23) | (0x29f<<12) | (0<<4);
-		if(p->scond & C_FBIT)
-			o1 ^= 0x010 << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		o1 |= (p->to.reg & 1) << 22;
-		o1 |= (p->from.reg&15) << 0;
-		break;
-
-	case 37:	/* mov $con,PSR */
-		aclass(ctxt, &p->from);
-		o1 = (2<<23) | (0x29f<<12) | (0<<4);
-		if(p->scond & C_FBIT)
-			o1 ^= 0x010 << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		o1 |= immrot(ctxt->instoffset);
-		o1 |= (p->to.reg & 1) << 22;
-		o1 |= (p->from.reg&15) << 0;
-		break;
-
-	case 38:
-	case 39:
-		switch(o->type) {
-		case 38:	/* movm $con,oreg -> stm */
-			o1 = (0x4 << 25);
-			o1 |= p->from.offset & 0xffff;
-			o1 |= (p->to.reg&15) << 16;
-			aclass(ctxt, &p->to);
-			break;
-	
-		case 39:	/* movm oreg,$con -> ldm */
-			o1 = (0x4 << 25) | (1 << 20);
-			o1 |= p->to.offset & 0xffff;
-			o1 |= (p->from.reg&15) << 16;
-			aclass(ctxt, &p->from);
-			break;
-		}
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in MOVM; %P", p);
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		if(p->scond & C_PBIT)
-			o1 |= 1 << 24;
-		if(p->scond & C_UBIT)
-			o1 |= 1 << 23;
-		if(p->scond & C_SBIT)
-			o1 |= 1 << 22;
-		if(p->scond & C_WBIT)
-			o1 |= 1 << 21;
-		break;
-
-	case 40:	/* swp oreg,reg,reg */
-		aclass(ctxt, &p->from);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in SWP");
-		o1 = (0x2<<23) | (0x9<<4);
-		if(p->as != ASWPW)
-			o1 |= 1 << 22;
-		o1 |= (p->from.reg&15) << 16;
-		o1 |= (p->reg&15) << 0;
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-
-	case 41:	/* rfe -> movm.s.w.u 0(r13),[r15] */
-		o1 = 0xe8fd8000;
-		break;
-
-	case 50:	/* floating point store */
-		v = regoff(ctxt, &p->to);
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = ofsr(ctxt, p->as, p->from.reg, v, r, p->scond, p);
-		break;
-
-	case 51:	/* floating point load */
-		v = regoff(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = ofsr(ctxt, p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
-		break;
-
-	case 52:	/* floating point store, int32 offset UGLY */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
-		o3 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
-		break;
-
-	case 53:	/* floating point load, int32 offset UGLY */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
-		o3 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
-		break;
-
-	case 54:	/* floating point arith */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		rf = p->from.reg;
-		rt = p->to.reg;
-		r = p->reg;
-		if(r == 0) {
-			r = rt;
-			if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF ||
-				p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
-				r = 0;
-		}
-		o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
-		break;
-
-	case 56:	/* move to FP[CS]R */
-		o1 = (((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28) | (0xe << 24) | (1<<8) | (1<<4);
-		o1 |= (((p->to.reg&1)+1)<<21) | ((p->from.reg&15) << 12);
-		break;
-
-	case 57:	/* move from FP[CS]R */
-		o1 = (((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28) | (0xe << 24) | (1<<8) | (1<<4);
-		o1 |= (((p->from.reg&1)+1)<<21) | ((p->to.reg&15)<<12) | (1<<20);
-		break;
-	case 58:	/* movbu R,R */
-		o1 = oprrr(ctxt, AAND, p->scond);
-		o1 |= immrot(0xff);
-		rt = p->to.reg;
-		r = p->from.reg;
-		if(p->to.type == TYPE_NONE)
-			rt = 0;
-		if(r == 0)
-			r = rt;
-		o1 |= ((r&15)<<16) | ((rt&15)<<12);
-		break;
-
-	case 59:	/* movw/bu R<<I(R),R -> ldr indexed */
-		if(p->from.reg == 0) {
-			if(p->as != AMOVW)
-				ctxt->diag("byte MOV from shifter operand");
-			o1 = mov(ctxt, p);
-			break;
-		}
-		if(p->from.offset&(1<<4))
-			ctxt->diag("bad shift in LDR");
-		o1 = olrr(ctxt, p->from.offset, p->from.reg, p->to.reg, p->scond);
-		if(p->as == AMOVBU)
-			o1 |= 1<<22;
-		break;
-
-	case 60:	/* movb R(R),R -> ldrsb indexed */
-		if(p->from.reg == 0) {
-			ctxt->diag("byte MOV from shifter operand");
-			o1 = mov(ctxt, p);
-			break;
-		}
-		if(p->from.offset&(~0xf))
-			ctxt->diag("bad shift in LDRSB");
-		o1 = olhrr(ctxt, p->from.offset, p->from.reg, p->to.reg, p->scond);
-		o1 ^= (1<<5)|(1<<6);
-		break;
-
-	case 61:	/* movw/b/bu R,R<<[IR](R) -> str indexed */
-		if(p->to.reg == 0)
-			ctxt->diag("MOV to shifter operand");
-		o1 = osrr(ctxt, p->from.reg, p->to.offset, p->to.reg, p->scond);
-		if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU)
-			o1 |= 1<<22;
-		break;
-
-	case 62:	/* case R -> movw	R<<2(PC),PC */
-		if(o->flag & LPCREL) {
-			o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | (p->from.reg&15) << 16 | (REGTMP&15) << 12;
-			o2 = olrr(ctxt, REGTMP&15, REGPC, REGTMP, p->scond);
-			o2 |= 2<<7;
-			o3 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGPC&15) << 12;
-		} else {
-			o1 = olrr(ctxt, p->from.reg&15, REGPC, REGPC, p->scond);
-			o1 |= 2<<7;
-		}
-		break;
-
-	case 63:	/* bcase */
-		if(p->pcond != nil) {
-			rel = addrel(ctxt->cursym);
-			rel->off = ctxt->pc;
-			rel->siz = 4;
-			if(p->to.sym != nil && p->to.sym->type != 0) {
-				rel->sym = p->to.sym;
-				rel->add = p->to.offset;
-			} else {
-				rel->sym = ctxt->cursym;
-				rel->add = p->pcond->pc;
-			}
-			if(o->flag & LPCREL) {
-				rel->type = R_PCREL;
-				rel->add += ctxt->pc - p->pcrel->pc - 16 + rel->siz;
-			} else
-				rel->type = R_ADDR;
-			o1 = 0;
-		}
-		break;
-
-	/* reloc ops */
-	case 64:	/* mov/movb/movbu R,addr */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		o2 = osr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond);
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-
-	case 65:	/* mov/movbu addr,R */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		o2 = olr(ctxt, 0, REGTMP, p->to.reg, p->scond);
-		if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
-			o2 |= 1<<22;
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-
-	case 68:	/* floating point store -> ADDR */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		o2 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-
-	case 69:	/* floating point load <- ADDR */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		o2 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-
-	/* ArmV4 ops: */
-	case 70:	/* movh/movhu R,O(R) -> strh */
-		aclass(ctxt, &p->to);
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = oshr(ctxt, p->from.reg, ctxt->instoffset, r, p->scond);
-		break;
-	case 71:	/* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
-		aclass(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = olhr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
-		if(p->as == AMOVB || p->as == AMOVBS)
-			o1 ^= (1<<5)|(1<<6);
-		else if(p->as == AMOVH || p->as == AMOVHS)
-			o1 ^= (1<<6);
-		break;
-	case 72:	/* movh/movhu R,L(R) -> strh */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = oshrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
-		break;
-	case 73:	/* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o2 = olhrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
-		if(p->as == AMOVB || p->as == AMOVBS)
-			o2 ^= (1<<5)|(1<<6);
-		else if(p->as == AMOVH || p->as == AMOVHS)
-			o2 ^= (1<<6);
-		break;
-	case 74:	/* bx $I */
-		ctxt->diag("ABX $I");
-		break;
-	case 75:	/* bx O(R) */
-		aclass(ctxt, &p->to);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("non-zero offset in ABX");
-/*
-		o1 = 	oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12);	// mov PC, LR
-		o2 = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0);		// BX R
-*/
-		// p->to.reg may be REGLINK
-		o1 = oprrr(ctxt, AADD, p->scond);
-		o1 |= immrot(ctxt->instoffset);
-		o1 |= (p->to.reg&15) << 16;
-		o1 |= (REGTMP&15) << 12;
-		o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12);	// mov PC, LR
-		o3 = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | (0x12fff<<8) | (1<<4) | (REGTMP&15);		// BX Rtmp
-		break;
-	case 76:	/* bx O(R) when returning from fn*/
-		ctxt->diag("ABXRET");
-		break;
-	case 77:	/* ldrex oreg,reg */
-		aclass(ctxt, &p->from);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in LDREX");
-		o1 = (0x19<<20) | (0xf9f);
-		o1 |= (p->from.reg&15) << 16;
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 78:	/* strex reg,oreg,reg */
-		aclass(ctxt, &p->from);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in STREX");
-		o1 = (0x18<<20) | (0xf90);
-		o1 |= (p->from.reg&15) << 16;
-		o1 |= (p->reg&15) << 0;
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 80:	/* fmov zfcon,freg */
-		if(p->as == AMOVD) {
-			o1 = 0xeeb00b00;	// VMOV imm 64
-			o2 = oprrr(ctxt, ASUBD, p->scond);
-		} else {
-			o1 = 0x0eb00a00;	// VMOV imm 32
-			o2 = oprrr(ctxt, ASUBF, p->scond);
-		}
-		v = 0x70;	// 1.0
-		r = (p->to.reg&15) << 0;
-
-		// movf $1.0, r
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		o1 |= (r&15) << 12;
-		o1 |= (v&0xf) << 0;
-		o1 |= (v&0xf0) << 12;
-
-		// subf r,r,r
-		o2 |= ((r&15)<<0) | ((r&15)<<16) | ((r&15)<<12);
-		break;
-	case 81:	/* fmov sfcon,freg */
-		o1 = 0x0eb00a00;		// VMOV imm 32
-		if(p->as == AMOVD)
-			o1 = 0xeeb00b00;	// VMOV imm 64
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		o1 |= (p->to.reg&15) << 12;
-		v = chipfloat5(ctxt, p->from.u.dval);
-		o1 |= (v&0xf) << 0;
-		o1 |= (v&0xf0) << 12;
-		break;
-	case 82:	/* fcmp freg,freg, */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= ((p->reg&15)<<12) | ((p->from.reg&15)<<0);
-		o2 = 0x0ef1fa10;	// VMRS R15
-		o2 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 83:	/* fcmp freg,, */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= ((p->from.reg&15)<<12) | (1<<16);
-		o2 = 0x0ef1fa10;	// VMRS R15
-		o2 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 84:	/* movfw freg,freg - truncate float-to-fix */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= ((p->from.reg&15)<<0);
-		o1 |= ((p->to.reg&15)<<12);
-		break;
-	case 85:	/* movwf freg,freg - fix-to-float */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= ((p->from.reg&15)<<0);
-		o1 |= ((p->to.reg&15)<<12);
-		break;
-	case 86:	/* movfw freg,reg - truncate float-to-fix */
-		// macro for movfw freg,FTMP; movw FTMP,reg
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= ((p->from.reg&15)<<0);
-		o1 |= ((FREGTMP&15)<<12);
-		o2 = oprrr(ctxt, AMOVFW+ALAST, p->scond);
-		o2 |= ((FREGTMP&15)<<16);
-		o2 |= ((p->to.reg&15)<<12);
-		break;
-	case 87:	/* movwf reg,freg - fix-to-float */
-		// macro for movw reg,FTMP; movwf FTMP,freg
-		o1 = oprrr(ctxt, AMOVWF+ALAST, p->scond);
-		o1 |= ((p->from.reg&15)<<12);
-		o1 |= ((FREGTMP&15)<<16);
-		o2 = oprrr(ctxt, p->as, p->scond);
-		o2 |= ((FREGTMP&15)<<0);
-		o2 |= ((p->to.reg&15)<<12);
-		break;
-	case 88:	/* movw reg,freg  */
-		o1 = oprrr(ctxt, AMOVWF+ALAST, p->scond);
-		o1 |= ((p->from.reg&15)<<12);
-		o1 |= ((p->to.reg&15)<<16);
-		break;
-	case 89:	/* movw freg,reg  */
-		o1 = oprrr(ctxt, AMOVFW+ALAST, p->scond);
-		o1 |= ((p->from.reg&15)<<16);
-		o1 |= ((p->to.reg&15)<<12);
-		break;
-	case 90:	/* tst reg  */
-		o1 = oprrr(ctxt, ACMP+ALAST, p->scond);
-		o1 |= (p->from.reg&15)<<16;
-		break;
-	case 91:	/* ldrexd oreg,reg */
-		aclass(ctxt, &p->from);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in LDREX");
-		o1 = (0x1b<<20) | (0xf9f);
-		o1 |= (p->from.reg&15) << 16;
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 92:	/* strexd reg,oreg,reg */
-		aclass(ctxt, &p->from);
-		if(ctxt->instoffset != 0)
-			ctxt->diag("offset must be zero in STREX");
-		o1 = (0x1a<<20) | (0xf90);
-		o1 |= (p->from.reg&15) << 16;
-		o1 |= (p->reg&15) << 0;
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= ((p->scond & C_SCOND) ^ C_SCOND_XOR) << 28;
-		break;
-	case 93:	/* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
-		o1 = omvl(ctxt, p, &p->from, REGTMP);
-		if(!o1)
-			break;
-		o2 = olhr(ctxt, 0, REGTMP, p->to.reg, p->scond);
-		if(p->as == AMOVB || p->as == AMOVBS)
-			o2 ^= (1<<5)|(1<<6);
-		else if(p->as == AMOVH || p->as == AMOVHS)
-			o2 ^= (1<<6);
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-	case 94:	/* movh/movhu R,addr -> strh */
-		o1 = omvl(ctxt, p, &p->to, REGTMP);
-		if(!o1)
-			break;
-		o2 = oshr(ctxt, p->from.reg, 0, REGTMP, p->scond);
-		if(o->flag & LPCREL) {
-			o3 = o2;
-			o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
-		}
-		break;
-	case 95:	/* PLD off(reg) */
-		o1 = 0xf5d0f000;
-		o1 |= (p->from.reg&15) << 16;
-		if(p->from.offset < 0) {
-			o1 &= ~(1 << 23);
-			o1 |= (-p->from.offset) & 0xfff;
-		} else
-			o1 |= p->from.offset & 0xfff;
-		break;
-	case 96:	/* UNDEF */
-		// This is supposed to be something that stops execution.
-		// It's not supposed to be reached, ever, but if it is, we'd
-		// like to be able to tell how we got there.  Assemble as
-		// 0xf7fabcfd which is guaranteed to raise undefined instruction
-		// exception.
-		o1 = 0xf7fabcfd;
-		break;
-	case 97:	/* CLZ Rm, Rd */
- 		o1 = oprrr(ctxt, p->as, p->scond);
- 		o1 |= (p->to.reg&15) << 12;
- 		o1 |= (p->from.reg&15) << 0;
-		break;
-	case 98:	/* MULW{T,B} Rs, Rm, Rd */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= (p->to.reg&15) << 16;
-		o1 |= (p->from.reg&15) << 8;
-		o1 |= (p->reg&15) << 0;
-		break;
-	case 99:	/* MULAW{T,B} Rs, Rm, Rn, Rd */
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= (p->to.reg&15) << 12;
-		o1 |= (p->from.reg&15) << 8;
-		o1 |= (p->reg&15) << 0;
-		o1 |= (p->to.offset&15) << 16;
-		break;
-	case 100:
-		// DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle;
-		// DATABUNDLEEND: zero width alignment marker
-		if(p->as == ADATABUNDLE)
-			o1 = 0xe125be70;
-		break;
-	}
-	
-	out[0] = o1;
-	out[1] = o2;
-	out[2] = o3;
-	out[3] = o4;
-	out[4] = o5;
-	out[5] = o6;
-	return;
-}
-
-static uint32
-mov(Link *ctxt, Prog *p)
-{
-	uint32 o1;
-	int rt, r;
-
-	aclass(ctxt, &p->from);
-	o1 = oprrr(ctxt, p->as, p->scond);
-	o1 |= p->from.offset;
-	rt = p->to.reg;
-	if(p->to.type == TYPE_NONE)
-		rt = 0;
-	r = p->reg;
-	if(p->as == AMOVW || p->as == AMVN)
-		r = 0;
-	else if(r == 0)
-		r = rt;
-	o1 |= ((r&15)<<16) | ((rt&15)<<12);
-	return o1;
-}
-
-static uint32
-oprrr(Link *ctxt, int a, int sc)
-{
-	uint32 o;
-
-	o = ((sc & C_SCOND) ^ C_SCOND_XOR) << 28;
-	if(sc & C_SBIT)
-		o |= 1 << 20;
-	if(sc & (C_PBIT|C_WBIT))
-		ctxt->diag(".nil/.W on dp instruction");
-	switch(a) {
-	case AMULU:
-	case AMUL:	return o | (0x0<<21) | (0x9<<4);
-	case AMULA:	return o | (0x1<<21) | (0x9<<4);
-	case AMULLU:	return o | (0x4<<21) | (0x9<<4);
-	case AMULL:	return o | (0x6<<21) | (0x9<<4);
-	case AMULALU:	return o | (0x5<<21) | (0x9<<4);
-	case AMULAL:	return o | (0x7<<21) | (0x9<<4);
-	case AAND:	return o | (0x0<<21);
-	case AEOR:	return o | (0x1<<21);
-	case ASUB:	return o | (0x2<<21);
-	case ARSB:	return o | (0x3<<21);
-	case AADD:	return o | (0x4<<21);
-	case AADC:	return o | (0x5<<21);
-	case ASBC:	return o | (0x6<<21);
-	case ARSC:	return o | (0x7<<21);
-	case ATST:	return o | (0x8<<21) | (1<<20);
-	case ATEQ:	return o | (0x9<<21) | (1<<20);
-	case ACMP:	return o | (0xa<<21) | (1<<20);
-	case ACMN:	return o | (0xb<<21) | (1<<20);
-	case AORR:	return o | (0xc<<21);
-	case AMOVB:
-	case AMOVH:
-	case AMOVW:	return o | (0xd<<21);
-	case ABIC:	return o | (0xe<<21);
-	case AMVN:	return o | (0xf<<21);
-	case ASLL:	return o | (0xd<<21) | (0<<5);
-	case ASRL:	return o | (0xd<<21) | (1<<5);
-	case ASRA:	return o | (0xd<<21) | (2<<5);
-	case ASWI:	return o | (0xf<<24);
-
-	case AADDD:	return o | (0xe<<24) | (0x3<<20) | (0xb<<8) | (0<<4);
-	case AADDF:	return o | (0xe<<24) | (0x3<<20) | (0xa<<8) | (0<<4);
-	case ASUBD:	return o | (0xe<<24) | (0x3<<20) | (0xb<<8) | (4<<4);
-	case ASUBF:	return o | (0xe<<24) | (0x3<<20) | (0xa<<8) | (4<<4);
-	case AMULD:	return o | (0xe<<24) | (0x2<<20) | (0xb<<8) | (0<<4);
-	case AMULF:	return o | (0xe<<24) | (0x2<<20) | (0xa<<8) | (0<<4);
-	case ADIVD:	return o | (0xe<<24) | (0x8<<20) | (0xb<<8) | (0<<4);
-	case ADIVF:	return o | (0xe<<24) | (0x8<<20) | (0xa<<8) | (0<<4);
-	case ASQRTD:	return o | (0xe<<24) | (0xb<<20) | (1<<16) | (0xb<<8) | (0xc<<4);
-	case ASQRTF:	return o | (0xe<<24) | (0xb<<20) | (1<<16) | (0xa<<8) | (0xc<<4);
-	case AABSD:	return o | (0xe<<24) | (0xb<<20) | (0<<16) | (0xb<<8) | (0xc<<4);
-	case AABSF:	return o | (0xe<<24) | (0xb<<20) | (0<<16) | (0xa<<8) | (0xc<<4);
-	case ACMPD:	return o | (0xe<<24) | (0xb<<20) | (4<<16) | (0xb<<8) | (0xc<<4);
-	case ACMPF:	return o | (0xe<<24) | (0xb<<20) | (4<<16) | (0xa<<8) | (0xc<<4);
-
-	case AMOVF:	return o | (0xe<<24) | (0xb<<20) | (0<<16) | (0xa<<8) | (4<<4);
-	case AMOVD:	return o | (0xe<<24) | (0xb<<20) | (0<<16) | (0xb<<8) | (4<<4);
-
-	case AMOVDF:	return o | (0xe<<24) | (0xb<<20) | (7<<16) | (0xa<<8) | (0xc<<4) |
-			(1<<8);	// dtof
-	case AMOVFD:	return o | (0xe<<24) | (0xb<<20) | (7<<16) | (0xa<<8) | (0xc<<4) |
-			(0<<8);	// dtof
-
-	case AMOVWF:
-			if((sc & C_UBIT) == 0)
-				o |= 1<<7;	/* signed */
-			return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
-				(0<<18) | (0<<8);	// toint, double
-	case AMOVWD:
-			if((sc & C_UBIT) == 0)
-				o |= 1<<7;	/* signed */
-			return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
-				(0<<18) | (1<<8);	// toint, double
-
-	case AMOVFW:
-			if((sc & C_UBIT) == 0)
-				o |= 1<<16;	/* signed */
-			return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
-				(1<<18) | (0<<8) | (1<<7);	// toint, double, trunc
-	case AMOVDW:
-			if((sc & C_UBIT) == 0)
-				o |= 1<<16;	/* signed */
-			return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
-				(1<<18) | (1<<8) | (1<<7);	// toint, double, trunc
-
-	case AMOVWF+ALAST:	// copy WtoF
-		return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4);
-	case AMOVFW+ALAST:	// copy FtoW
-		return o | (0xe<<24) | (0x1<<20) | (0xb<<8) | (1<<4);
-	case ACMP+ALAST:	// cmp imm
-		return o | (0x3<<24) | (0x5<<20);
-
-	case ACLZ:
-		// CLZ doesn't support .nil
-		return (o & (0xf<<28)) | (0x16f<<16) | (0xf1<<4);
-
-	case AMULWT:
-		return (o & (0xf<<28)) | (0x12 << 20) | (0xe<<4);
-	case AMULWB:
-		return (o & (0xf<<28)) | (0x12 << 20) | (0xa<<4);
-	case AMULAWT:
-		return (o & (0xf<<28)) | (0x12 << 20) | (0xc<<4);
-	case AMULAWB:
-		return (o & (0xf<<28)) | (0x12 << 20) | (0x8<<4);
-
-	case ABL: // BLX REG
-		return (o & (0xf<<28)) | (0x12fff3 << 4);
-	}
-	ctxt->diag("bad rrr %d", a);
-	prasm(ctxt->curp);
-	return 0;
-}
-
-static uint32
-opbra(Link *ctxt, int a, int sc)
-{
-
-	if(sc & (C_SBIT|C_PBIT|C_WBIT))
-		ctxt->diag(".nil/.nil/.W on bra instruction");
-	sc &= C_SCOND;
-	sc ^= C_SCOND_XOR;
-	if(a == ABL || a == ADUFFZERO || a == ADUFFCOPY)
-		return (sc<<28)|(0x5<<25)|(0x1<<24);
-	if(sc != 0xe)
-		ctxt->diag(".COND on bcond instruction");
-	switch(a) {
-	case ABEQ:	return (0x0<<28)|(0x5<<25);
-	case ABNE:	return (0x1<<28)|(0x5<<25);
-	case ABCS:	return (0x2<<28)|(0x5<<25);
-	case ABHS:	return (0x2<<28)|(0x5<<25);
-	case ABCC:	return (0x3<<28)|(0x5<<25);
-	case ABLO:	return (0x3<<28)|(0x5<<25);
-	case ABMI:	return (0x4<<28)|(0x5<<25);
-	case ABPL:	return (0x5<<28)|(0x5<<25);
-	case ABVS:	return (0x6<<28)|(0x5<<25);
-	case ABVC:	return (0x7<<28)|(0x5<<25);
-	case ABHI:	return (0x8<<28)|(0x5<<25);
-	case ABLS:	return (0x9<<28)|(0x5<<25);
-	case ABGE:	return (0xa<<28)|(0x5<<25);
-	case ABLT:	return (0xb<<28)|(0x5<<25);
-	case ABGT:	return (0xc<<28)|(0x5<<25);
-	case ABLE:	return (0xd<<28)|(0x5<<25);
-	case AB:	return (0xe<<28)|(0x5<<25);
-	}
-	ctxt->diag("bad bra %A", a);
-	prasm(ctxt->curp);
-	return 0;
-}
-
-static uint32
-olr(Link *ctxt, int32 v, int b, int r, int sc)
-{
-	uint32 o;
-
-	if(sc & C_SBIT)
-		ctxt->diag(".nil on LDR/STR instruction");
-	o = ((sc & C_SCOND) ^ C_SCOND_XOR) << 28;
-	if(!(sc & C_PBIT))
-		o |= 1 << 24;
-	if(!(sc & C_UBIT))
-		o |= 1 << 23;
-	if(sc & C_WBIT)
-		o |= 1 << 21;
-	o |= (1<<26) | (1<<20);
-	if(v < 0) {
-		if(sc & C_UBIT)
-			ctxt->diag(".U on neg offset");
-		v = -v;
-		o ^= 1 << 23;
-	}
-	if(v >= (1<<12) || v < 0)
-		ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
-	o |= v;
-	o |= (b&15) << 16;
-	o |= (r&15) << 12;
-	return o;
-}
-
-static uint32
-olhr(Link *ctxt, int32 v, int b, int r, int sc)
-{
-	uint32 o;
-
-	if(sc & C_SBIT)
-		ctxt->diag(".nil on LDRH/STRH instruction");
-	o = ((sc & C_SCOND) ^ C_SCOND_XOR) << 28;
-	if(!(sc & C_PBIT))
-		o |= 1 << 24;
-	if(sc & C_WBIT)
-		o |= 1 << 21;
-	o |= (1<<23) | (1<<20)|(0xb<<4);
-	if(v < 0) {
-		v = -v;
-		o ^= 1 << 23;
-	}
-	if(v >= (1<<8) || v < 0)
-		ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
-	o |= (v&0xf)|((v>>4)<<8)|(1<<22);
-	o |= (b&15) << 16;
-	o |= (r&15) << 12;
-	return o;
-}
-
-static uint32
-osr(Link *ctxt, int a, int r, int32 v, int b, int sc)
-{
-	uint32 o;
-
-	o = olr(ctxt, v, b, r, sc) ^ (1<<20);
-	if(a != AMOVW)
-		o |= 1<<22;
-	return o;
-}
-
-static uint32
-oshr(Link *ctxt, int r, int32 v, int b, int sc)
-{
-	uint32 o;
-
-	o = olhr(ctxt, v, b, r, sc) ^ (1<<20);
-	return o;
-}
-
-
-static uint32
-osrr(Link *ctxt, int r, int i, int b, int sc)
-{
-
-	return olr(ctxt, i, b, r, sc) ^ ((1<<25) | (1<<20));
-}
-
-static uint32
-oshrr(Link *ctxt, int r, int i, int b, int sc)
-{
-	return olhr(ctxt, i, b, r, sc) ^ ((1<<22) | (1<<20));
-}
-
-static uint32
-olrr(Link *ctxt, int i, int b, int r, int sc)
-{
-
-	return olr(ctxt, i, b, r, sc) ^ (1<<25);
-}
-
-static uint32
-olhrr(Link *ctxt, int i, int b, int r, int sc)
-{
-	return olhr(ctxt, i, b, r, sc) ^ (1<<22);
-}
-
-static uint32
-ofsr(Link *ctxt, int a, int r, int32 v, int b, int sc, Prog *p)
-{
-	uint32 o;
-
-	if(sc & C_SBIT)
-		ctxt->diag(".nil on FLDR/FSTR instruction");
-	o = ((sc & C_SCOND) ^ C_SCOND_XOR) << 28;
-	if(!(sc & C_PBIT))
-		o |= 1 << 24;
-	if(sc & C_WBIT)
-		o |= 1 << 21;
-	o |= (6<<25) | (1<<24) | (1<<23) | (10<<8);
-	if(v < 0) {
-		v = -v;
-		o ^= 1 << 23;
-	}
-	if(v & 3)
-		ctxt->diag("odd offset for floating point op: %d\n%P", v, p);
-	else
-	if(v >= (1<<10) || v < 0)
-		ctxt->diag("literal span too large: %d\n%P", v, p);
-	o |= (v>>2) & 0xFF;
-	o |= (b&15) << 16;
-	o |= (r&15) << 12;
-
-	switch(a) {
-	default:
-		ctxt->diag("bad fst %A", a);
-	case AMOVD:
-		o |= 1 << 8;
-	case AMOVF:
-		break;
-	}
-	return o;
-}
-
-static uint32
-omvl(Link *ctxt, Prog *p, Addr *a, int dr)
-{
-	int32 v;
-	uint32 o1;
-	if(!p->pcond) {
-		aclass(ctxt, a);
-		v = immrot(~ctxt->instoffset);
-		if(v == 0) {
-			ctxt->diag("missing literal");
-			prasm(p);
-			return 0;
-		}
-		o1 = oprrr(ctxt, AMVN, p->scond&C_SCOND);
-		o1 |= v;
-		o1 |= (dr&15) << 12;
-	} else {
-		v = p->pcond->pc - p->pc - 8;
-		o1 = olr(ctxt, v, REGPC, dr, p->scond&C_SCOND);
-	}
-	return o1;
-}
-
-int
-chipzero5(Link *ctxt, float64 e)
-{
-	// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
-	if(ctxt->goarm < 7 || e != 0)
-		return -1;
-	return 0;
-}
-
-int
-chipfloat5(Link *ctxt, float64 e)
-{
-	int n;
-	ulong h1;
-	uint32 l, h;
-	uint64 ei;
-
-	// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
-	if(ctxt->goarm < 7)
-		goto no;
-
-	memmove(&ei, &e, 8);
-	l = (uint32)ei;
-	h = (uint32)(ei>>32);
-
-	if(l != 0 || (h&0xffff) != 0)
-		goto no;
-	h1 = h & 0x7fc00000;
-	if(h1 != 0x40000000 && h1 != 0x3fc00000)
-		goto no;
-	n = 0;
-
-	// sign bit (a)
-	if(h & 0x80000000)
-		n |= 1<<7;
-
-	// exp sign bit (b)
-	if(h1 == 0x3fc00000)
-		n |= 1<<6;
-
-	// rest of exp and mantissa (cd-efgh)
-	n |= (h >> 16) & 0x3f;
-
-//print("match %.8lux %.8lux %d\n", l, h, n);
-	return n;
-
-no:
-	return -1;
-}
diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c
deleted file mode 100644
index 8119f74..0000000
--- a/src/liblink/asm6.c
+++ /dev/null
@@ -1,3640 +0,0 @@
-// Inferno utils/6l/span.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.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.
-
-// Instruction layout.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/6l/6.out.h"
-#include "../runtime/stack.h"
-
-enum
-{
-	MaxAlign = 32,	// max data alignment
-	
-	// Loop alignment constants:
-	// want to align loop entry to LoopAlign-byte boundary,
-	// and willing to insert at most MaxLoopPad bytes of NOP to do so.
-	// We define a loop entry as the target of a backward jump.
-	//
-	// gcc uses MaxLoopPad = 10 for its 'generic x86-64' config,
-	// and it aligns all jump targets, not just backward jump targets.
-	//
-	// As of 6/1/2012, the effect of setting MaxLoopPad = 10 here
-	// is very slight but negative, so the alignment is disabled by
-	// setting MaxLoopPad = 0. The code is here for reference and
-	// for future experiments.
-	// 
-	LoopAlign = 16,
-	MaxLoopPad = 0,
-
-	FuncAlign = 16
-};
-
-typedef	struct	Optab	Optab;
-typedef	struct	Movtab	Movtab;
-
-struct	Optab
-{
-	short	as;
-	uchar*	ytab;
-	uchar	prefix;
-	uchar	op[23];
-};
-struct	Movtab
-{
-	short	as;
-	uchar	ft;
-	uchar	tt;
-	uchar	code;
-	uchar	op[4];
-};
-
-enum
-{
-	Yxxx		= 0,
-	Ynone,
-	Yi0,
-	Yi1,
-	Yi8,
-	Ys32,
-	Yi32,
-	Yi64,
-	Yiauto,
-	Yal,
-	Ycl,
-	Yax,
-	Ycx,
-	Yrb,
-	Yrl,
-	Yrf,
-	Yf0,
-	Yrx,
-	Ymb,
-	Yml,
-	Ym,
-	Ybr,
-	Ycol,
-
-	Ycs,	Yss,	Yds,	Yes,	Yfs,	Ygs,
-	Ygdtr,	Yidtr,	Yldtr,	Ymsw,	Ytask,
-	Ycr0,	Ycr1,	Ycr2,	Ycr3,	Ycr4,	Ycr5,	Ycr6,	Ycr7,	Ycr8,
-	Ydr0,	Ydr1,	Ydr2,	Ydr3,	Ydr4,	Ydr5,	Ydr6,	Ydr7,
-	Ytr0,	Ytr1,	Ytr2,	Ytr3,	Ytr4,	Ytr5,	Ytr6,	Ytr7,	Yrl32,	Yrl64,
-	Ymr, Ymm,
-	Yxr, Yxm,
-	Ytls,
-	Ytextsize,
-	Ymax,
-
-	Zxxx		= 0,
-
-	Zlit,
-	Zlitm_r,
-	Z_rp,
-	Zbr,
-	Zcall,
-	Zcallindreg,
-	Zib_,
-	Zib_rp,
-	Zibo_m,
-	Zibo_m_xm,
-	Zil_,
-	Zil_rp,
-	Ziq_rp,
-	Zilo_m,
-	Ziqo_m,
-	Zjmp,
-	Zloop,
-	Zo_iw,
-	Zm_o,
-	Zm_r,
-	Zm2_r,
-	Zm_r_xm,
-	Zm_r_i_xm,
-	Zm_r_3d,
-	Zm_r_xm_nr,
-	Zr_m_xm_nr,
-	Zibm_r,	/* mmx1,mmx2/mem64,imm8 */
-	Zmb_r,
-	Zaut_r,
-	Zo_m,
-	Zo_m64,
-	Zpseudo,
-	Zr_m,
-	Zr_m_xm,
-	Zr_m_i_xm,
-	Zrp_,
-	Z_ib,
-	Z_il,
-	Zm_ibo,
-	Zm_ilo,
-	Zib_rr,
-	Zil_rr,
-	Zclr,
-	Zbyte,
-	Zmax,
-
-	Px		= 0,
-	P32		= 0x32,	/* 32-bit only */
-	Pe		= 0x66,	/* operand escape */
-	Pm		= 0x0f,	/* 2byte opcode escape */
-	Pq		= 0xff,	/* both escapes: 66 0f */
-	Pb		= 0xfe,	/* byte operands */
-	Pf2		= 0xf2,	/* xmm escape 1: f2 0f */
-	Pf3		= 0xf3,	/* xmm escape 2: f3 0f */
-	Pq3		= 0x67, /* xmm escape 3: 66 48 0f */
-	Pw		= 0x48,	/* Rex.w */
-	Py		= 0x80,	/* defaults to 64-bit mode */
-
-	Rxf		= 1<<9,	/* internal flag for Rxr on from */
-	Rxt		= 1<<8,	/* internal flag for Rxr on to */
-	Rxw		= 1<<3,	/* =1, 64-bit operand size */
-	Rxr		= 1<<2,	/* extend modrm reg */
-	Rxx		= 1<<1,	/* extend sib index */
-	Rxb		= 1<<0,	/* extend modrm r/m, sib base, or opcode reg */
-
-	Maxand	= 10,		/* in -a output width of the byte codes */
-};
-
-static uchar ycover[Ymax*Ymax];
-static	int	reg[MAXREG];
-static	int	regrex[MAXREG+1];
-static	void	asmins(Link *ctxt, Prog *p);
-
-static uchar	ynone[] =
-{
-	Ynone,	Ynone,	Zlit,	1,
-	0
-};
-static uchar	ytext[] =
-{
-	Ymb,	Ytextsize,	Zpseudo,1,
-	0
-};
-static uchar	ynop[] =
-{
-	Ynone,	Ynone,	Zpseudo,0,
-	Ynone,	Yiauto,	Zpseudo,0,
-	Ynone,	Yml,	Zpseudo,0,
-	Ynone,	Yrf,	Zpseudo,0,
-	Ynone,	Yxr,	Zpseudo,0,
-	Yiauto,	Ynone,	Zpseudo,0,
-	Yml,	Ynone,	Zpseudo,0,
-	Yrf,	Ynone,	Zpseudo,0,
-	Yxr,	Ynone,	Zpseudo,1,
-	0
-};
-static uchar	yfuncdata[] =
-{
-	Yi32,	Ym,	Zpseudo,	0,
-	0
-};
-static uchar	ypcdata[] = 
-{
-	Yi32,	Yi32,	Zpseudo,	0,
-	0
-};
-static uchar	yxorb[] =
-{
-	Yi32,	Yal,	Zib_,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	yxorl[] =
-{
-	Yi8,	Yml,	Zibo_m,	2,
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yaddl[] =
-{
-	Yi8,	Yml,	Zibo_m,	2,
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yincb[] =
-{
-	Ynone,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yincw[] =
-{
-	Ynone,	Yml,	Zo_m,	2,
-	0
-};
-static uchar	yincl[] =
-{
-	Ynone,	Yml,	Zo_m,	2,
-	0
-};
-static uchar	ycmpb[] =
-{
-	Yal,	Yi32,	Z_ib,	1,
-	Ymb,	Yi32,	Zm_ibo,	2,
-	Ymb,	Yrb,	Zm_r,	1,
-	Yrb,	Ymb,	Zr_m,	1,
-	0
-};
-static uchar	ycmpl[] =
-{
-	Yml,	Yi8,	Zm_ibo,	2,
-	Yax,	Yi32,	Z_il,	1,
-	Yml,	Yi32,	Zm_ilo,	2,
-	Yml,	Yrl,	Zm_r,	1,
-	Yrl,	Yml,	Zr_m,	1,
-	0
-};
-static uchar	yshb[] =
-{
-	Yi1,	Ymb,	Zo_m,	2,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Ycx,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yshl[] =
-{
-	Yi1,	Yml,	Zo_m,	2,
-	Yi32,	Yml,	Zibo_m,	2,
-	Ycl,	Yml,	Zo_m,	2,
-	Ycx,	Yml,	Zo_m,	2,
-	0
-};
-static uchar	ytestb[] =
-{
-	Yi32,	Yal,	Zib_,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	ytestl[] =
-{
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	ymovb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	Yi32,	Yrb,	Zib_rp,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	0
-};
-static uchar	ymbs[] =
-{
-	Ymb,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ybtl[] =
-{
-	Yi8,	Yml,	Zibo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	0
-};
-static uchar	ymovw[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	Yi0,	Yrl,	Zclr,	1,
-	Yi32,	Yrl,	Zil_rp,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yiauto,	Yrl,	Zaut_r,	2,
-	0
-};
-static uchar	ymovl[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	Yi0,	Yrl,	Zclr,	1,
-	Yi32,	Yrl,	Zil_rp,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yml,	Ymr,	Zm_r_xm,	1,	// MMX MOVD
-	Ymr,	Yml,	Zr_m_xm,	1,	// MMX MOVD
-	Yml,	Yxr,	Zm_r_xm,	2,	// XMM MOVD (32 bit)
-	Yxr,	Yml,	Zr_m_xm,	2,	// XMM MOVD (32 bit)
-	Yiauto,	Yrl,	Zaut_r,	2,
-	0
-};
-static uchar	yret[] =
-{
-	Ynone,	Ynone,	Zo_iw,	1,
-	Yi32,	Ynone,	Zo_iw,	1,
-	0
-};
-static uchar	ymovq[] =
-{
-	Yrl,	Yml,	Zr_m,	1,	// 0x89
-	Yml,	Yrl,	Zm_r,	1,	// 0x8b
-	Yi0,	Yrl,	Zclr,	1,	// 0x31
-	Ys32,	Yrl,	Zilo_m,	2,	// 32 bit signed 0xc7,(0)
-	Yi64,	Yrl,	Ziq_rp,	1,	// 0xb8 -- 32/64 bit immediate
-	Yi32,	Yml,	Zilo_m,	2,	// 0xc7,(0)
-	Ym,	Ymr,	Zm_r_xm_nr,	1,	// MMX MOVQ (shorter encoding)
-	Ymr,	Ym,	Zr_m_xm_nr,	1,	// MMX MOVQ
-	Ymm,	Ymr,	Zm_r_xm,	1,	// MMX MOVD
-	Ymr,	Ymm,	Zr_m_xm,	1,	// MMX MOVD
-	Yxr,	Ymr,	Zm_r_xm_nr,	2,	// MOVDQ2Q
-	Yxm,	Yxr,	Zm_r_xm_nr,	2, // MOVQ xmm1/m64 -> xmm2
-	Yxr,	Yxm,	Zr_m_xm_nr,	2, // MOVQ xmm1 -> xmm2/m64
-	Yml,	Yxr,	Zm_r_xm,	2,	// MOVD xmm load
-	Yxr,	Yml,	Zr_m_xm,	2,	// MOVD xmm store
-	Yiauto,	Yrl,	Zaut_r,	2,	// built-in LEAQ
-	0
-};
-static uchar	ym_rl[] =
-{
-	Ym,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yrl_m[] =
-{
-	Yrl,	Ym,	Zr_m,	1,
-	0
-};
-static uchar	ymb_rl[] =
-{
-	Ymb,	Yrl,	Zmb_r,	1,
-	0
-};
-static uchar	yml_rl[] =
-{
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yrl_ml[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	0
-};
-static uchar	yml_mb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	yrb_mb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	0
-};
-static uchar	yxchg[] =
-{
-	Yax,	Yrl,	Z_rp,	1,
-	Yrl,	Yax,	Zrp_,	1,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	ydivl[] =
-{
-	Yml,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ydivb[] =
-{
-	Ymb,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	yimul[] =
-{
-	Yml,	Ynone,	Zm_o,	2,
-	Yi8,	Yrl,	Zib_rr,	1,
-	Yi32,	Yrl,	Zil_rr,	1,
-	Yml,	Yrl,	Zm_r,	2,
-	0
-};
-static uchar	yimul3[] =
-{
-	Yml,	Yrl,	Zibm_r,	2,
-	0
-};
-static uchar	ybyte[] =
-{
-	Yi64,	Ynone,	Zbyte,	1,
-	0
-};
-static uchar	yin[] =
-{
-	Yi32,	Ynone,	Zib_,	1,
-	Ynone,	Ynone,	Zlit,	1,
-	0
-};
-static uchar	yint[] =
-{
-	Yi32,	Ynone,	Zib_,	1,
-	0
-};
-static uchar	ypushl[] =
-{
-	Yrl,	Ynone,	Zrp_,	1,
-	Ym,	Ynone,	Zm_o,	2,
-	Yi8,	Ynone,	Zib_,	1,
-	Yi32,	Ynone,	Zil_,	1,
-	0
-};
-static uchar	ypopl[] =
-{
-	Ynone,	Yrl,	Z_rp,	1,
-	Ynone,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	ybswap[] =
-{
-	Ynone,	Yrl,	Z_rp,	2,
-	0,
-};
-static uchar	yscond[] =
-{
-	Ynone,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yjcond[] =
-{
-	Ynone,	Ybr,	Zbr,	0,
-	Yi0,	Ybr,	Zbr,	0,
-	Yi1,	Ybr,	Zbr,	1,
-	0
-};
-static uchar	yloop[] =
-{
-	Ynone,	Ybr,	Zloop,	1,
-	0
-};
-static uchar	ycall[] =
-{
-	Ynone,	Yml,	Zcallindreg,	0,
-	Yrx,	Yrx,	Zcallindreg,	2,
-	Ynone,	Ybr,	Zcall,	1,
-	0
-};
-static uchar	yduff[] =
-{
-	Ynone,	Yi32,	Zcall,	1,
-	0
-};
-static uchar	yjmp[] =
-{
-	Ynone,	Yml,	Zo_m64,	2,
-	Ynone,	Ybr,	Zjmp,	1,
-	0
-};
-
-static uchar	yfmvd[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yf0,	Ym,	Zo_m,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfmvdp[] =
-{
-	Yf0,	Ym,	Zo_m,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfmvf[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yf0,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	yfmvx[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	0
-};
-static uchar	yfmvp[] =
-{
-	Yf0,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	yfadd[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfaddp[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfxch[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	0
-};
-static uchar	ycompp[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,	/* botch is really f0,f1 */
-	0
-};
-static uchar	ystsw[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ynone,	Yax,	Zlit,	1,
-	0
-};
-static uchar	ystcw[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ym,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ysvrs[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ym,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ymm[] = 
-{
-	Ymm,	Ymr,	Zm_r_xm,	1,
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxm[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxcvm1[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	Yxm,	Ymr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxcvm2[] =
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	Ymm,	Yxr,	Zm_r_xm,	2,
-	0
-};
-/*
-static uchar	yxmq[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	0
-};
-*/
-static uchar	yxr[] = 
-{
-	Yxr,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxr_ml[] =
-{
-	Yxr,	Yml,	Zr_m_xm,	1,
-	0
-};
-static uchar	ymr[] =
-{
-	Ymr,	Ymr,	Zm_r,	1,
-	0
-};
-static uchar	ymr_ml[] =
-{
-	Ymr,	Yml,	Zr_m_xm,	1,
-	0
-};
-static uchar	yxcmp[] =
-{
-	Yxm,	Yxr, Zm_r_xm,	1,
-	0
-};
-static uchar	yxcmpi[] =
-{
-	Yxm,	Yxr, Zm_r_i_xm,	2,
-	0
-};
-static uchar	yxmov[] =
-{
-	Yxm,	Yxr,	Zm_r_xm,	1,
-	Yxr,	Yxm,	Zr_m_xm,	1,
-	0
-};
-static uchar	yxcvfl[] = 
-{
-	Yxm,	Yrl,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxcvlf[] =
-{
-	Yml,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxcvfq[] = 
-{
-	Yxm,	Yrl,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxcvqf[] =
-{
-	Yml,	Yxr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yps[] = 
-{
-	Ymm,	Ymr,	Zm_r_xm,	1,
-	Yi8,	Ymr,	Zibo_m_xm,	2,
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	Yi8,	Yxr,	Zibo_m_xm,	3,
-	0
-};
-static uchar	yxrrl[] =
-{
-	Yxr,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	ymfp[] =
-{
-	Ymm,	Ymr,	Zm_r_3d,	1,
-	0,
-};
-static uchar	ymrxr[] =
-{
-	Ymr,	Yxr,	Zm_r,	1,
-	Yxm,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	ymshuf[] =
-{
-	Ymm,	Ymr,	Zibm_r,	2,
-	0
-};
-static uchar	ymshufb[] =
-{
-	Yxm,	Yxr,	Zm2_r,	2,
-	0
-};
-static uchar	yxshuf[] =
-{
-	Yxm,	Yxr,	Zibm_r,	2,
-	0
-};
-static uchar	yextrw[] =
-{
-	Yxr,	Yrl,	Zibm_r,	2,
-	0
-};
-static uchar	yinsrw[] =
-{
-	Yml,	Yxr,	Zibm_r,	2,
-	0
-};
-static uchar	yinsr[] =
-{
-	Ymm,	Yxr,	Zibm_r,	3,
-	0
-};
-static uchar	ypsdq[] =
-{
-	Yi8,	Yxr,	Zibo_m,	2,
-	0
-};
-static uchar	ymskb[] =
-{
-	Yxr,	Yrl,	Zm_r_xm,	2,
-	Ymr,	Yrl,	Zm_r_xm,	1,
-	0
-};
-static uchar	ycrc32l[] =
-{
-	Yml,	Yrl,	Zlitm_r,	0,
-};
-static uchar	yprefetch[] =
-{
-	Ym,	Ynone,	Zm_o,	2,
-	0,
-};
-static uchar	yaes[] =
-{
-	Yxm,	Yxr,	Zlitm_r,	2,
-	0
-};
-static uchar	yaes2[] =
-{
-	Yxm,	Yxr,	Zibm_r,	2,
-	0
-};
-
-/*
- * You are doasm, holding in your hand a Prog* with p->as set to, say, ACRC32,
- * and p->from and p->to as operands (Addr*).  The linker scans optab to find
- * the entry with the given p->as and then looks through the ytable for that
- * instruction (the second field in the optab struct) for a line whose first
- * two values match the Ytypes of the p->from and p->to operands.  The function
- * oclass in span.c computes the specific Ytype of an operand and then the set
- * of more general Ytypes that it satisfies is implied by the ycover table, set
- * up in instinit.  For example, oclass distinguishes the constants 0 and 1
- * from the more general 8-bit constants, but instinit says
- *
- *        ycover[Yi0*Ymax + Ys32] = 1;
- *        ycover[Yi1*Ymax + Ys32] = 1;
- *        ycover[Yi8*Ymax + Ys32] = 1;
- *
- * which means that Yi0, Yi1, and Yi8 all count as Ys32 (signed 32)
- * if that's what an instruction can handle.
- *
- * In parallel with the scan through the ytable for the appropriate line, there
- * is a z pointer that starts out pointing at the strange magic byte list in
- * the Optab struct.  With each step past a non-matching ytable line, z
- * advances by the 4th entry in the line.  When a matching line is found, that
- * z pointer has the extra data to use in laying down the instruction bytes.
- * The actual bytes laid down are a function of the 3rd entry in the line (that
- * is, the Ztype) and the z bytes.
- *
- * For example, let's look at AADDL.  The optab line says:
- *        { AADDL,        yaddl,  Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
- *
- * and yaddl says
- *        uchar   yaddl[] =
- *        {
- *                Yi8,    Yml,    Zibo_m, 2,
- *                Yi32,   Yax,    Zil_,   1,
- *                Yi32,   Yml,    Zilo_m, 2,
- *                Yrl,    Yml,    Zr_m,   1,
- *                Yml,    Yrl,    Zm_r,   1,
- *                0
- *        };
- *
- * so there are 5 possible types of ADDL instruction that can be laid down, and
- * possible states used to lay them down (Ztype and z pointer, assuming z
- * points at {0x83,(00),0x05,0x81,(00),0x01,0x03}) are:
- *
- *        Yi8, Yml -> Zibo_m, z (0x83, 00)
- *        Yi32, Yax -> Zil_, z+2 (0x05)
- *        Yi32, Yml -> Zilo_m, z+2+1 (0x81, 0x00)
- *        Yrl, Yml -> Zr_m, z+2+1+2 (0x01)
- *        Yml, Yrl -> Zm_r, z+2+1+2+1 (0x03)
- *
- * The Pconstant in the optab line controls the prefix bytes to emit.  That's
- * relatively straightforward as this program goes.
- *
- * The switch on t[2] in doasm implements the various Z cases.  Zibo_m, for
- * example, is an opcode byte (z[0]) then an asmando (which is some kind of
- * encoded addressing mode for the Yml arg), and then a single immediate byte.
- * Zilo_m is the same but a long (32-bit) immediate.
- */
-static Optab optab[] =
-/*	as, ytab, andproto, opcode */
-{
-	{ AXXX },
-	{ AAAA,		ynone,	P32, {0x37} },
-	{ AAAD,		ynone,	P32, {0xd5,0x0a} },
-	{ AAAM,		ynone,	P32, {0xd4,0x0a} },
-	{ AAAS,		ynone,	P32, {0x3f} },
-	{ AADCB,	yxorb,	Pb, {0x14,0x80,(02),0x10,0x10} },
-	{ AADCL,	yxorl,	Px, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
-	{ AADCQ,	yxorl,	Pw, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
-	{ AADCW,	yxorl,	Pe, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
-	{ AADDB,	yxorb,	Pb, {0x04,0x80,(00),0x00,0x02} },
-	{ AADDL,	yaddl,	Px, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
-	{ AADDPD,	yxm,	Pq, {0x58} },
-	{ AADDPS,	yxm,	Pm, {0x58} },
-	{ AADDQ,	yaddl,	Pw, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
-	{ AADDSD,	yxm,	Pf2, {0x58} },
-	{ AADDSS,	yxm,	Pf3, {0x58} },
-	{ AADDW,	yaddl,	Pe, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
-	{ AADJSP },
-	{ AANDB,	yxorb,	Pb, {0x24,0x80,(04),0x20,0x22} },
-	{ AANDL,	yxorl,	Px, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
-	{ AANDNPD,	yxm,	Pq, {0x55} },
-	{ AANDNPS,	yxm,	Pm, {0x55} },
-	{ AANDPD,	yxm,	Pq, {0x54} },
-	{ AANDPS,	yxm,	Pq, {0x54} },
-	{ AANDQ,	yxorl,	Pw, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
-	{ AANDW,	yxorl,	Pe, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
-	{ AARPL,	yrl_ml,	P32, {0x63} },
-	{ ABOUNDL,	yrl_m,	P32, {0x62} },
-	{ ABOUNDW,	yrl_m,	Pe, {0x62} },
-	{ ABSFL,	yml_rl,	Pm, {0xbc} },
-	{ ABSFQ,	yml_rl,	Pw, {0x0f,0xbc} },
-	{ ABSFW,	yml_rl,	Pq, {0xbc} },
-	{ ABSRL,	yml_rl,	Pm, {0xbd} },
-	{ ABSRQ,	yml_rl,	Pw, {0x0f,0xbd} },
-	{ ABSRW,	yml_rl,	Pq, {0xbd} },
-	{ ABSWAPL,	ybswap,	Px, {0x0f,0xc8} },
-	{ ABSWAPQ,	ybswap,	Pw, {0x0f,0xc8} },
-	{ ABTCL,	ybtl,	Pm, {0xba,(07),0xbb} },
-	{ ABTCQ,	ybtl,	Pw, {0x0f,0xba,(07),0x0f,0xbb} },
-	{ ABTCW,	ybtl,	Pq, {0xba,(07),0xbb} },
-	{ ABTL,		ybtl,	Pm, {0xba,(04),0xa3} },
-	{ ABTQ,		ybtl,	Pw, {0x0f,0xba,(04),0x0f,0xa3}},
-	{ ABTRL,	ybtl,	Pm, {0xba,(06),0xb3} },
-	{ ABTRQ,	ybtl,	Pw, {0x0f,0xba,(06),0x0f,0xb3} },
-	{ ABTRW,	ybtl,	Pq, {0xba,(06),0xb3} },
-	{ ABTSL,	ybtl,	Pm, {0xba,(05),0xab } },
-	{ ABTSQ,	ybtl,	Pw, {0x0f,0xba,(05),0x0f,0xab} },
-	{ ABTSW,	ybtl,	Pq, {0xba,(05),0xab } },
-	{ ABTW,		ybtl,	Pq, {0xba,(04),0xa3} },
-	{ ABYTE,	ybyte,	Px, {1} },
-	{ ACALL,	ycall,	Px, {0xff,(02),0xe8} },
-	{ ACDQ,		ynone,	Px, {0x99} },
-	{ ACLC,		ynone,	Px, {0xf8} },
-	{ ACLD,		ynone,	Px, {0xfc} },
-	{ ACLI,		ynone,	Px, {0xfa} },
-	{ ACLTS,	ynone,	Pm, {0x06} },
-	{ ACMC,		ynone,	Px, {0xf5} },
-	{ ACMOVLCC,	yml_rl,	Pm, {0x43} },
-	{ ACMOVLCS,	yml_rl,	Pm, {0x42} },
-	{ ACMOVLEQ,	yml_rl,	Pm, {0x44} },
-	{ ACMOVLGE,	yml_rl,	Pm, {0x4d} },
-	{ ACMOVLGT,	yml_rl,	Pm, {0x4f} },
-	{ ACMOVLHI,	yml_rl,	Pm, {0x47} },
-	{ ACMOVLLE,	yml_rl,	Pm, {0x4e} },
-	{ ACMOVLLS,	yml_rl,	Pm, {0x46} },
-	{ ACMOVLLT,	yml_rl,	Pm, {0x4c} },
-	{ ACMOVLMI,	yml_rl,	Pm, {0x48} },
-	{ ACMOVLNE,	yml_rl,	Pm, {0x45} },
-	{ ACMOVLOC,	yml_rl,	Pm, {0x41} },
-	{ ACMOVLOS,	yml_rl,	Pm, {0x40} },
-	{ ACMOVLPC,	yml_rl,	Pm, {0x4b} },
-	{ ACMOVLPL,	yml_rl,	Pm, {0x49} },
-	{ ACMOVLPS,	yml_rl,	Pm, {0x4a} },
-	{ ACMOVQCC,	yml_rl,	Pw, {0x0f,0x43} },
-	{ ACMOVQCS,	yml_rl,	Pw, {0x0f,0x42} },
-	{ ACMOVQEQ,	yml_rl,	Pw, {0x0f,0x44} },
-	{ ACMOVQGE,	yml_rl,	Pw, {0x0f,0x4d} },
-	{ ACMOVQGT,	yml_rl,	Pw, {0x0f,0x4f} },
-	{ ACMOVQHI,	yml_rl,	Pw, {0x0f,0x47} },
-	{ ACMOVQLE,	yml_rl,	Pw, {0x0f,0x4e} },
-	{ ACMOVQLS,	yml_rl,	Pw, {0x0f,0x46} },
-	{ ACMOVQLT,	yml_rl,	Pw, {0x0f,0x4c} },
-	{ ACMOVQMI,	yml_rl,	Pw, {0x0f,0x48} },
-	{ ACMOVQNE,	yml_rl,	Pw, {0x0f,0x45} },
-	{ ACMOVQOC,	yml_rl,	Pw, {0x0f,0x41} },
-	{ ACMOVQOS,	yml_rl,	Pw, {0x0f,0x40} },
-	{ ACMOVQPC,	yml_rl,	Pw, {0x0f,0x4b} },
-	{ ACMOVQPL,	yml_rl,	Pw, {0x0f,0x49} },
-	{ ACMOVQPS,	yml_rl,	Pw, {0x0f,0x4a} },
-	{ ACMOVWCC,	yml_rl,	Pq, {0x43} },
-	{ ACMOVWCS,	yml_rl,	Pq, {0x42} },
-	{ ACMOVWEQ,	yml_rl,	Pq, {0x44} },
-	{ ACMOVWGE,	yml_rl,	Pq, {0x4d} },
-	{ ACMOVWGT,	yml_rl,	Pq, {0x4f} },
-	{ ACMOVWHI,	yml_rl,	Pq, {0x47} },
-	{ ACMOVWLE,	yml_rl,	Pq, {0x4e} },
-	{ ACMOVWLS,	yml_rl,	Pq, {0x46} },
-	{ ACMOVWLT,	yml_rl,	Pq, {0x4c} },
-	{ ACMOVWMI,	yml_rl,	Pq, {0x48} },
-	{ ACMOVWNE,	yml_rl,	Pq, {0x45} },
-	{ ACMOVWOC,	yml_rl,	Pq, {0x41} },
-	{ ACMOVWOS,	yml_rl,	Pq, {0x40} },
-	{ ACMOVWPC,	yml_rl,	Pq, {0x4b} },
-	{ ACMOVWPL,	yml_rl,	Pq, {0x49} },
-	{ ACMOVWPS,	yml_rl,	Pq, {0x4a} },
-	{ ACMPB,	ycmpb,	Pb, {0x3c,0x80,(07),0x38,0x3a} },
-	{ ACMPL,	ycmpl,	Px, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
-	{ ACMPPD,	yxcmpi,	Px, {Pe,0xc2} },
-	{ ACMPPS,	yxcmpi,	Pm, {0xc2,0} },
-	{ ACMPQ,	ycmpl,	Pw, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
-	{ ACMPSB,	ynone,	Pb, {0xa6} },
-	{ ACMPSD,	yxcmpi,	Px, {Pf2,0xc2} },
-	{ ACMPSL,	ynone,	Px, {0xa7} },
-	{ ACMPSQ,	ynone,	Pw, {0xa7} },
-	{ ACMPSS,	yxcmpi,	Px, {Pf3,0xc2} },
-	{ ACMPSW,	ynone,	Pe, {0xa7} },
-	{ ACMPW,	ycmpl,	Pe, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
-	{ ACOMISD,	yxcmp,	Pe, {0x2f} },
-	{ ACOMISS,	yxcmp,	Pm, {0x2f} },
-	{ ACPUID,	ynone,	Pm, {0xa2} },
-	{ ACVTPL2PD,	yxcvm2,	Px, {Pf3,0xe6,Pe,0x2a} },
-	{ ACVTPL2PS,	yxcvm2,	Pm, {0x5b,0,0x2a,0,} },
-	{ ACVTPD2PL,	yxcvm1,	Px, {Pf2,0xe6,Pe,0x2d} },
-	{ ACVTPD2PS,	yxm,	Pe, {0x5a} },
-	{ ACVTPS2PL,	yxcvm1, Px, {Pe,0x5b,Pm,0x2d} },
-	{ ACVTPS2PD,	yxm,	Pm, {0x5a} },
-	{ API2FW,	ymfp,	Px, {0x0c} },
-	{ ACVTSD2SL,	yxcvfl, Pf2, {0x2d} },
-	{ ACVTSD2SQ,	yxcvfq, Pw, {Pf2,0x2d} },
-	{ ACVTSD2SS,	yxm,	Pf2, {0x5a} },
-	{ ACVTSL2SD,	yxcvlf, Pf2, {0x2a} },
-	{ ACVTSQ2SD,	yxcvqf, Pw, {Pf2,0x2a} },
-	{ ACVTSL2SS,	yxcvlf, Pf3, {0x2a} },
-	{ ACVTSQ2SS,	yxcvqf, Pw, {Pf3,0x2a} },
-	{ ACVTSS2SD,	yxm,	Pf3, {0x5a} },
-	{ ACVTSS2SL,	yxcvfl, Pf3, {0x2d} },
-	{ ACVTSS2SQ,	yxcvfq, Pw, {Pf3,0x2d} },
-	{ ACVTTPD2PL,	yxcvm1,	Px, {Pe,0xe6,Pe,0x2c} },
-	{ ACVTTPS2PL,	yxcvm1,	Px, {Pf3,0x5b,Pm,0x2c} },
-	{ ACVTTSD2SL,	yxcvfl, Pf2, {0x2c} },
-	{ ACVTTSD2SQ,	yxcvfq, Pw, {Pf2,0x2c} },
-	{ ACVTTSS2SL,	yxcvfl,	Pf3, {0x2c} },
-	{ ACVTTSS2SQ,	yxcvfq, Pw, {Pf3,0x2c} },
-	{ ACWD,		ynone,	Pe, {0x99} },
-	{ ACQO,		ynone,	Pw, {0x99} },
-	{ ADAA,		ynone,	P32, {0x27} },
-	{ ADAS,		ynone,	P32, {0x2f} },
-	{ ADATA },
-	{ ADECB,	yincb,	Pb, {0xfe,(01)} },
-	{ ADECL,	yincl,	Px, {0xff,(01)} },
-	{ ADECQ,	yincl,	Pw, {0xff,(01)} },
-	{ ADECW,	yincw,	Pe, {0xff,(01)} },
-	{ ADIVB,	ydivb,	Pb, {0xf6,(06)} },
-	{ ADIVL,	ydivl,	Px, {0xf7,(06)} },
-	{ ADIVPD,	yxm,	Pe, {0x5e} },
-	{ ADIVPS,	yxm,	Pm, {0x5e} },
-	{ ADIVQ,	ydivl,	Pw, {0xf7,(06)} },
-	{ ADIVSD,	yxm,	Pf2, {0x5e} },
-	{ ADIVSS,	yxm,	Pf3, {0x5e} },
-	{ ADIVW,	ydivl,	Pe, {0xf7,(06)} },
-	{ AEMMS,	ynone,	Pm, {0x77} },
-	{ AENTER },				/* botch */
-	{ AFXRSTOR,	ysvrs,	Pm, {0xae,(01),0xae,(01)} },
-	{ AFXSAVE,	ysvrs,	Pm, {0xae,(00),0xae,(00)} },
-	{ AFXRSTOR64,	ysvrs,	Pw, {0x0f,0xae,(01),0x0f,0xae,(01)} },
-	{ AFXSAVE64,	ysvrs,	Pw, {0x0f,0xae,(00),0x0f,0xae,(00)} },
-	{ AGLOBL },
-	{ AHLT,		ynone,	Px, {0xf4} },
-	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
-	{ AIDIVL,	ydivl,	Px, {0xf7,(07)} },
-	{ AIDIVQ,	ydivl,	Pw, {0xf7,(07)} },
-	{ AIDIVW,	ydivl,	Pe, {0xf7,(07)} },
-	{ AIMULB,	ydivb,	Pb, {0xf6,(05)} },
-	{ AIMULL,	yimul,	Px, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
-	{ AIMULQ,	yimul,	Pw, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
-	{ AIMULW,	yimul,	Pe, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
-	{ AIMUL3Q,	yimul3,	Pw, {0x6b,(00)} },
-	{ AINB,		yin,	Pb, {0xe4,0xec} },
-	{ AINCB,	yincb,	Pb, {0xfe,(00)} },
-	{ AINCL,	yincl,	Px, {0xff,(00)} },
-	{ AINCQ,	yincl,	Pw, {0xff,(00)} },
-	{ AINCW,	yincw,	Pe, {0xff,(00)} },
-	{ AINL,		yin,	Px, {0xe5,0xed} },
-	{ AINSB,	ynone,	Pb, {0x6c} },
-	{ AINSL,	ynone,	Px, {0x6d} },
-	{ AINSW,	ynone,	Pe, {0x6d} },
-	{ AINT,		yint,	Px, {0xcd} },
-	{ AINTO,	ynone,	P32, {0xce} },
-	{ AINW,		yin,	Pe, {0xe5,0xed} },
-	{ AIRETL,	ynone,	Px, {0xcf} },
-	{ AIRETQ,	ynone,	Pw, {0xcf} },
-	{ AIRETW,	ynone,	Pe, {0xcf} },
-	{ AJCC,		yjcond,	Px, {0x73,0x83,(00)} },
-	{ AJCS,		yjcond,	Px, {0x72,0x82} },
-	{ AJCXZL,	yloop,	Px, {0xe3} },
-	{ AJCXZQ,	yloop,	Px, {0xe3} },
-	{ AJEQ,		yjcond,	Px, {0x74,0x84} },
-	{ AJGE,		yjcond,	Px, {0x7d,0x8d} },
-	{ AJGT,		yjcond,	Px, {0x7f,0x8f} },
-	{ AJHI,		yjcond,	Px, {0x77,0x87} },
-	{ AJLE,		yjcond,	Px, {0x7e,0x8e} },
-	{ AJLS,		yjcond,	Px, {0x76,0x86} },
-	{ AJLT,		yjcond,	Px, {0x7c,0x8c} },
-	{ AJMI,		yjcond,	Px, {0x78,0x88} },
-	{ AJMP,		yjmp,	Px, {0xff,(04),0xeb,0xe9} },
-	{ AJNE,		yjcond,	Px, {0x75,0x85} },
-	{ AJOC,		yjcond,	Px, {0x71,0x81,(00)} },
-	{ AJOS,		yjcond,	Px, {0x70,0x80,(00)} },
-	{ AJPC,		yjcond,	Px, {0x7b,0x8b} },
-	{ AJPL,		yjcond,	Px, {0x79,0x89} },
-	{ AJPS,		yjcond,	Px, {0x7a,0x8a} },
-	{ ALAHF,	ynone,	Px, {0x9f} },
-	{ ALARL,	yml_rl,	Pm, {0x02} },
-	{ ALARW,	yml_rl,	Pq, {0x02} },
-	{ ALDMXCSR,	ysvrs,	Pm, {0xae,(02),0xae,(02)} },
-	{ ALEAL,	ym_rl,	Px, {0x8d} },
-	{ ALEAQ,	ym_rl,	Pw, {0x8d} },
-	{ ALEAVEL,	ynone,	P32, {0xc9} },
-	{ ALEAVEQ,	ynone,	Py, {0xc9} },
-	{ ALEAVEW,	ynone,	Pe, {0xc9} },
-	{ ALEAW,	ym_rl,	Pe, {0x8d} },
-	{ ALOCK,	ynone,	Px, {0xf0} },
-	{ ALODSB,	ynone,	Pb, {0xac} },
-	{ ALODSL,	ynone,	Px, {0xad} },
-	{ ALODSQ,	ynone,	Pw, {0xad} },
-	{ ALODSW,	ynone,	Pe, {0xad} },
-	{ ALONG,	ybyte,	Px, {4} },
-	{ ALOOP,	yloop,	Px, {0xe2} },
-	{ ALOOPEQ,	yloop,	Px, {0xe1} },
-	{ ALOOPNE,	yloop,	Px, {0xe0} },
-	{ ALSLL,	yml_rl,	Pm, {0x03 } },
-	{ ALSLW,	yml_rl,	Pq, {0x03 } },
-	{ AMASKMOVOU,	yxr,	Pe, {0xf7} },
-	{ AMASKMOVQ,	ymr,	Pm, {0xf7} },
-	{ AMAXPD,	yxm,	Pe, {0x5f} },
-	{ AMAXPS,	yxm,	Pm, {0x5f} },
-	{ AMAXSD,	yxm,	Pf2, {0x5f} },
-	{ AMAXSS,	yxm,	Pf3, {0x5f} },
-	{ AMINPD,	yxm,	Pe, {0x5d} },
-	{ AMINPS,	yxm,	Pm, {0x5d} },
-	{ AMINSD,	yxm,	Pf2, {0x5d} },
-	{ AMINSS,	yxm,	Pf3, {0x5d} },
-	{ AMOVAPD,	yxmov,	Pe, {0x28,0x29} },
-	{ AMOVAPS,	yxmov,	Pm, {0x28,0x29} },
-	{ AMOVB,	ymovb,	Pb, {0x88,0x8a,0xb0,0xc6,(00)} },
-	{ AMOVBLSX,	ymb_rl,	Pm, {0xbe} },
-	{ AMOVBLZX,	ymb_rl,	Pm, {0xb6} },
-	{ AMOVBQSX,	ymb_rl,	Pw, {0x0f,0xbe} },
-	{ AMOVBQZX,	ymb_rl,	Pm, {0xb6} },
-	{ AMOVBWSX,	ymb_rl,	Pq, {0xbe} },
-	{ AMOVBWZX,	ymb_rl,	Pq, {0xb6} },
-	{ AMOVO,	yxmov,	Pe, {0x6f,0x7f} },
-	{ AMOVOU,	yxmov,	Pf3, {0x6f,0x7f} },
-	{ AMOVHLPS,	yxr,	Pm, {0x12} },
-	{ AMOVHPD,	yxmov,	Pe, {0x16,0x17} },
-	{ AMOVHPS,	yxmov,	Pm, {0x16,0x17} },
-	{ AMOVL,	ymovl,	Px, {0x89,0x8b,0x31,0xb8,0xc7,(00),0x6e,0x7e,Pe,0x6e,Pe,0x7e,0} },
-	{ AMOVLHPS,	yxr,	Pm, {0x16} },
-	{ AMOVLPD,	yxmov,	Pe, {0x12,0x13} },
-	{ AMOVLPS,	yxmov,	Pm, {0x12,0x13} },
-	{ AMOVLQSX,	yml_rl,	Pw, {0x63} },
-	{ AMOVLQZX,	yml_rl,	Px, {0x8b} },
-	{ AMOVMSKPD,	yxrrl,	Pq, {0x50} },
-	{ AMOVMSKPS,	yxrrl,	Pm, {0x50} },
-	{ AMOVNTO,	yxr_ml,	Pe, {0xe7} },
-	{ AMOVNTPD,	yxr_ml,	Pe, {0x2b} },
-	{ AMOVNTPS,	yxr_ml,	Pm, {0x2b} },
-	{ AMOVNTQ,	ymr_ml,	Pm, {0xe7} },
-	{ AMOVQ,	ymovq,	Pw, {0x89, 0x8b, 0x31, 0xc7,(00), 0xb8, 0xc7,(00), 0x6f, 0x7f, 0x6e, 0x7e, Pf2,0xd6, Pf3,0x7e, Pe,0xd6, Pe,0x6e, Pe,0x7e,0} },
-	{ AMOVQOZX,	ymrxr,	Pf3, {0xd6,0x7e} },
-	{ AMOVSB,	ynone,	Pb, {0xa4} },
-	{ AMOVSD,	yxmov,	Pf2, {0x10,0x11} },
-	{ AMOVSL,	ynone,	Px, {0xa5} },
-	{ AMOVSQ,	ynone,	Pw, {0xa5} },
-	{ AMOVSS,	yxmov,	Pf3, {0x10,0x11} },
-	{ AMOVSW,	ynone,	Pe, {0xa5} },
-	{ AMOVUPD,	yxmov,	Pe, {0x10,0x11} },
-	{ AMOVUPS,	yxmov,	Pm, {0x10,0x11} },
-	{ AMOVW,	ymovw,	Pe, {0x89,0x8b,0x31,0xb8,0xc7,(00),0} },
-	{ AMOVWLSX,	yml_rl,	Pm, {0xbf} },
-	{ AMOVWLZX,	yml_rl,	Pm, {0xb7} },
-	{ AMOVWQSX,	yml_rl,	Pw, {0x0f,0xbf} },
-	{ AMOVWQZX,	yml_rl,	Pw, {0x0f,0xb7} },
-	{ AMULB,	ydivb,	Pb, {0xf6,(04)} },
-	{ AMULL,	ydivl,	Px, {0xf7,(04)} },
-	{ AMULPD,	yxm,	Pe, {0x59} },
-	{ AMULPS,	yxm,	Ym, {0x59} },
-	{ AMULQ,	ydivl,	Pw, {0xf7,(04)} },
-	{ AMULSD,	yxm,	Pf2, {0x59} },
-	{ AMULSS,	yxm,	Pf3, {0x59} },
-	{ AMULW,	ydivl,	Pe, {0xf7,(04)} },
-	{ ANEGB,	yscond,	Pb, {0xf6,(03)} },
-	{ ANEGL,	yscond,	Px, {0xf7,(03)} },
-	{ ANEGQ,	yscond,	Pw, {0xf7,(03)} },
-	{ ANEGW,	yscond,	Pe, {0xf7,(03)} },
-	{ ANOP,		ynop,	Px, {0,0} },
-	{ ANOTB,	yscond,	Pb, {0xf6,(02)} },
-	{ ANOTL,	yscond,	Px, {0xf7,(02)} },
-	{ ANOTQ,	yscond,	Pw, {0xf7,(02)} },
-	{ ANOTW,	yscond,	Pe, {0xf7,(02)} },
-	{ AORB,		yxorb,	Pb, {0x0c,0x80,(01),0x08,0x0a} },
-	{ AORL,		yxorl,	Px, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
-	{ AORPD,	yxm,	Pq, {0x56} },
-	{ AORPS,	yxm,	Pm, {0x56} },
-	{ AORQ,		yxorl,	Pw, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
-	{ AORW,		yxorl,	Pe, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
-	{ AOUTB,	yin,	Pb, {0xe6,0xee} },
-	{ AOUTL,	yin,	Px, {0xe7,0xef} },
-	{ AOUTSB,	ynone,	Pb, {0x6e} },
-	{ AOUTSL,	ynone,	Px, {0x6f} },
-	{ AOUTSW,	ynone,	Pe, {0x6f} },
-	{ AOUTW,	yin,	Pe, {0xe7,0xef} },
-	{ APACKSSLW,	ymm,	Py, {0x6b,Pe,0x6b} },
-	{ APACKSSWB,	ymm,	Py, {0x63,Pe,0x63} },
-	{ APACKUSWB,	ymm,	Py, {0x67,Pe,0x67} },
-	{ APADDB,	ymm,	Py, {0xfc,Pe,0xfc} },
-	{ APADDL,	ymm,	Py, {0xfe,Pe,0xfe} },
-	{ APADDQ,	yxm,	Pe, {0xd4} },
-	{ APADDSB,	ymm,	Py, {0xec,Pe,0xec} },
-	{ APADDSW,	ymm,	Py, {0xed,Pe,0xed} },
-	{ APADDUSB,	ymm,	Py, {0xdc,Pe,0xdc} },
-	{ APADDUSW,	ymm,	Py, {0xdd,Pe,0xdd} },
-	{ APADDW,	ymm,	Py, {0xfd,Pe,0xfd} },
-	{ APAND,	ymm,	Py, {0xdb,Pe,0xdb} },
-	{ APANDN,	ymm,	Py, {0xdf,Pe,0xdf} },
-	{ APAUSE,	ynone,	Px, {0xf3,0x90} },
-	{ APAVGB,	ymm,	Py, {0xe0,Pe,0xe0} },
-	{ APAVGW,	ymm,	Py, {0xe3,Pe,0xe3} },
-	{ APCMPEQB,	ymm,	Py, {0x74,Pe,0x74} },
-	{ APCMPEQL,	ymm,	Py, {0x76,Pe,0x76} },
-	{ APCMPEQW,	ymm,	Py, {0x75,Pe,0x75} },
-	{ APCMPGTB,	ymm,	Py, {0x64,Pe,0x64} },
-	{ APCMPGTL,	ymm,	Py, {0x66,Pe,0x66} },
-	{ APCMPGTW,	ymm,	Py, {0x65,Pe,0x65} },
-	{ APEXTRW,	yextrw,	Pq, {0xc5,(00)} },
-	{ APF2IL,	ymfp,	Px, {0x1d} },
-	{ APF2IW,	ymfp,	Px, {0x1c} },
-	{ API2FL,	ymfp,	Px, {0x0d} },
-	{ APFACC,	ymfp,	Px, {0xae} },
-	{ APFADD,	ymfp,	Px, {0x9e} },
-	{ APFCMPEQ,	ymfp,	Px, {0xb0} },
-	{ APFCMPGE,	ymfp,	Px, {0x90} },
-	{ APFCMPGT,	ymfp,	Px, {0xa0} },
-	{ APFMAX,	ymfp,	Px, {0xa4} },
-	{ APFMIN,	ymfp,	Px, {0x94} },
-	{ APFMUL,	ymfp,	Px, {0xb4} },
-	{ APFNACC,	ymfp,	Px, {0x8a} },
-	{ APFPNACC,	ymfp,	Px, {0x8e} },
-	{ APFRCP,	ymfp,	Px, {0x96} },
-	{ APFRCPIT1,	ymfp,	Px, {0xa6} },
-	{ APFRCPI2T,	ymfp,	Px, {0xb6} },
-	{ APFRSQIT1,	ymfp,	Px, {0xa7} },
-	{ APFRSQRT,	ymfp,	Px, {0x97} },
-	{ APFSUB,	ymfp,	Px, {0x9a} },
-	{ APFSUBR,	ymfp,	Px, {0xaa} },
-	{ APINSRW,	yinsrw,	Pq, {0xc4,(00)} },
-	{ APINSRD,	yinsr,	Pq, {0x3a, 0x22, (00)} },
-	{ APINSRQ,	yinsr,	Pq3, {0x3a, 0x22, (00)} },
-	{ APMADDWL,	ymm,	Py, {0xf5,Pe,0xf5} },
-	{ APMAXSW,	yxm,	Pe, {0xee} },
-	{ APMAXUB,	yxm,	Pe, {0xde} },
-	{ APMINSW,	yxm,	Pe, {0xea} },
-	{ APMINUB,	yxm,	Pe, {0xda} },
-	{ APMOVMSKB,	ymskb,	Px, {Pe,0xd7,0xd7} },
-	{ APMULHRW,	ymfp,	Px, {0xb7} },
-	{ APMULHUW,	ymm,	Py, {0xe4,Pe,0xe4} },
-	{ APMULHW,	ymm,	Py, {0xe5,Pe,0xe5} },
-	{ APMULLW,	ymm,	Py, {0xd5,Pe,0xd5} },
-	{ APMULULQ,	ymm,	Py, {0xf4,Pe,0xf4} },
-	{ APOPAL,	ynone,	P32, {0x61} },
-	{ APOPAW,	ynone,	Pe, {0x61} },
-	{ APOPFL,	ynone,	P32, {0x9d} },
-	{ APOPFQ,	ynone,	Py, {0x9d} },
-	{ APOPFW,	ynone,	Pe, {0x9d} },
-	{ APOPL,	ypopl,	P32, {0x58,0x8f,(00)} },
-	{ APOPQ,	ypopl,	Py, {0x58,0x8f,(00)} },
-	{ APOPW,	ypopl,	Pe, {0x58,0x8f,(00)} },
-	{ APOR,		ymm,	Py, {0xeb,Pe,0xeb} },
-	{ APSADBW,	yxm,	Pq, {0xf6} },
-	{ APSHUFHW,	yxshuf,	Pf3, {0x70,(00)} },
-	{ APSHUFL,	yxshuf,	Pq, {0x70,(00)} },
-	{ APSHUFLW,	yxshuf,	Pf2, {0x70,(00)} },
-	{ APSHUFW,	ymshuf,	Pm, {0x70,(00)} },
-	{ APSHUFB,	ymshufb,Pq, {0x38, 0x00} },
-	{ APSLLO,	ypsdq,	Pq, {0x73,(07)} },
-	{ APSLLL,	yps,	Py, {0xf2, 0x72,(06), Pe,0xf2, Pe,0x72,(06)} },
-	{ APSLLQ,	yps,	Py, {0xf3, 0x73,(06), Pe,0xf3, Pe,0x73,(06)} },
-	{ APSLLW,	yps,	Py, {0xf1, 0x71,(06), Pe,0xf1, Pe,0x71,(06)} },
-	{ APSRAL,	yps,	Py, {0xe2, 0x72,(04), Pe,0xe2, Pe,0x72,(04)} },
-	{ APSRAW,	yps,	Py, {0xe1, 0x71,(04), Pe,0xe1, Pe,0x71,(04)} },
-	{ APSRLO,	ypsdq,	Pq, {0x73,(03)} },
-	{ APSRLL,	yps,	Py, {0xd2, 0x72,(02), Pe,0xd2, Pe,0x72,(02)} },
-	{ APSRLQ,	yps,	Py, {0xd3, 0x73,(02), Pe,0xd3, Pe,0x73,(02)} },
-	{ APSRLW,	yps,	Py, {0xd1, 0x71,(02), Pe,0xe1, Pe,0x71,(02)} },
-	{ APSUBB,	yxm,	Pe, {0xf8} },
-	{ APSUBL,	yxm,	Pe, {0xfa} },
-	{ APSUBQ,	yxm,	Pe, {0xfb} },
-	{ APSUBSB,	yxm,	Pe, {0xe8} },
-	{ APSUBSW,	yxm,	Pe, {0xe9} },
-	{ APSUBUSB,	yxm,	Pe, {0xd8} },
-	{ APSUBUSW,	yxm,	Pe, {0xd9} },
-	{ APSUBW,	yxm,	Pe, {0xf9} },
-	{ APSWAPL,	ymfp,	Px, {0xbb} },
-	{ APUNPCKHBW,	ymm,	Py, {0x68,Pe,0x68} },
-	{ APUNPCKHLQ,	ymm,	Py, {0x6a,Pe,0x6a} },
-	{ APUNPCKHQDQ,	yxm,	Pe, {0x6d} },
-	{ APUNPCKHWL,	ymm,	Py, {0x69,Pe,0x69} },
-	{ APUNPCKLBW,	ymm,	Py, {0x60,Pe,0x60} },
-	{ APUNPCKLLQ,	ymm,	Py, {0x62,Pe,0x62} },
-	{ APUNPCKLQDQ,	yxm,	Pe, {0x6c} },
-	{ APUNPCKLWL,	ymm,	Py, {0x61,Pe,0x61} },
-	{ APUSHAL,	ynone,	P32, {0x60} },
-	{ APUSHAW,	ynone,	Pe, {0x60} },
-	{ APUSHFL,	ynone,	P32, {0x9c} },
-	{ APUSHFQ,	ynone,	Py, {0x9c} },
-	{ APUSHFW,	ynone,	Pe, {0x9c} },
-	{ APUSHL,	ypushl,	P32, {0x50,0xff,(06),0x6a,0x68} },
-	{ APUSHQ,	ypushl,	Py, {0x50,0xff,(06),0x6a,0x68} },
-	{ APUSHW,	ypushl,	Pe, {0x50,0xff,(06),0x6a,0x68} },
-	{ APXOR,	ymm,	Py, {0xef,Pe,0xef} },
-	{ AQUAD,	ybyte,	Px, {8} },
-	{ ARCLB,	yshb,	Pb, {0xd0,(02),0xc0,(02),0xd2,(02)} },
-	{ ARCLL,	yshl,	Px, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
-	{ ARCLQ,	yshl,	Pw, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
-	{ ARCLW,	yshl,	Pe, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
-	{ ARCPPS,	yxm,	Pm, {0x53} },
-	{ ARCPSS,	yxm,	Pf3, {0x53} },
-	{ ARCRB,	yshb,	Pb, {0xd0,(03),0xc0,(03),0xd2,(03)} },
-	{ ARCRL,	yshl,	Px, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
-	{ ARCRQ,	yshl,	Pw, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
-	{ ARCRW,	yshl,	Pe, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
-	{ AREP,		ynone,	Px, {0xf3} },
-	{ AREPN,	ynone,	Px, {0xf2} },
-	{ ARET,		ynone,	Px, {0xc3} },
-	{ ARETFW,	yret,	Pe, {0xcb,0xca} },
-	{ ARETFL,	yret,	Px, {0xcb,0xca} },
-	{ ARETFQ,	yret,	Pw, {0xcb,0xca} },
-	{ AROLB,	yshb,	Pb, {0xd0,(00),0xc0,(00),0xd2,(00)} },
-	{ AROLL,	yshl,	Px, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
-	{ AROLQ,	yshl,	Pw, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
-	{ AROLW,	yshl,	Pe, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
-	{ ARORB,	yshb,	Pb, {0xd0,(01),0xc0,(01),0xd2,(01)} },
-	{ ARORL,	yshl,	Px, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
-	{ ARORQ,	yshl,	Pw, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
-	{ ARORW,	yshl,	Pe, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
-	{ ARSQRTPS,	yxm,	Pm, {0x52} },
-	{ ARSQRTSS,	yxm,	Pf3, {0x52} },
-	{ ASAHF,	ynone,	Px, {0x86,0xe0,0x50,0x9d} },	/* XCHGB AH,AL; PUSH AX; POPFL */
-	{ ASALB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
-	{ ASALL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASALQ,	yshl,	Pw, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASALW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASARB,	yshb,	Pb, {0xd0,(07),0xc0,(07),0xd2,(07)} },
-	{ ASARL,	yshl,	Px, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
-	{ ASARQ,	yshl,	Pw, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
-	{ ASARW,	yshl,	Pe, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
-	{ ASBBB,	yxorb,	Pb, {0x1c,0x80,(03),0x18,0x1a} },
-	{ ASBBL,	yxorl,	Px, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
-	{ ASBBQ,	yxorl,	Pw, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
-	{ ASBBW,	yxorl,	Pe, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
-	{ ASCASB,	ynone,	Pb, {0xae} },
-	{ ASCASL,	ynone,	Px, {0xaf} },
-	{ ASCASQ,	ynone,	Pw, {0xaf} },
-	{ ASCASW,	ynone,	Pe, {0xaf} },
-	{ ASETCC,	yscond,	Pb, {0x0f,0x93,(00)} },
-	{ ASETCS,	yscond,	Pb, {0x0f,0x92,(00)} },
-	{ ASETEQ,	yscond,	Pb, {0x0f,0x94,(00)} },
-	{ ASETGE,	yscond,	Pb, {0x0f,0x9d,(00)} },
-	{ ASETGT,	yscond,	Pb, {0x0f,0x9f,(00)} },
-	{ ASETHI,	yscond,	Pb, {0x0f,0x97,(00)} },
-	{ ASETLE,	yscond,	Pb, {0x0f,0x9e,(00)} },
-	{ ASETLS,	yscond,	Pb, {0x0f,0x96,(00)} },
-	{ ASETLT,	yscond,	Pb, {0x0f,0x9c,(00)} },
-	{ ASETMI,	yscond,	Pb, {0x0f,0x98,(00)} },
-	{ ASETNE,	yscond,	Pb, {0x0f,0x95,(00)} },
-	{ ASETOC,	yscond,	Pb, {0x0f,0x91,(00)} },
-	{ ASETOS,	yscond,	Pb, {0x0f,0x90,(00)} },
-	{ ASETPC,	yscond,	Pb, {0x0f,0x9b,(00)} },
-	{ ASETPL,	yscond,	Pb, {0x0f,0x99,(00)} },
-	{ ASETPS,	yscond,	Pb, {0x0f,0x9a,(00)} },
-	{ ASHLB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
-	{ ASHLL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASHLQ,	yshl,	Pw, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASHLW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASHRB,	yshb,	Pb, {0xd0,(05),0xc0,(05),0xd2,(05)} },
-	{ ASHRL,	yshl,	Px, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
-	{ ASHRQ,	yshl,	Pw, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
-	{ ASHRW,	yshl,	Pe, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
-	{ ASHUFPD,	yxshuf,	Pq, {0xc6,(00)} },
-	{ ASHUFPS,	yxshuf,	Pm, {0xc6,(00)} },
-	{ ASQRTPD,	yxm,	Pe, {0x51} },
-	{ ASQRTPS,	yxm,	Pm, {0x51} },
-	{ ASQRTSD,	yxm,	Pf2, {0x51} },
-	{ ASQRTSS,	yxm,	Pf3, {0x51} },
-	{ ASTC,		ynone,	Px, {0xf9} },
-	{ ASTD,		ynone,	Px, {0xfd} },
-	{ ASTI,		ynone,	Px, {0xfb} },
-	{ ASTMXCSR,	ysvrs,	Pm, {0xae,(03),0xae,(03)} },
-	{ ASTOSB,	ynone,	Pb, {0xaa} },
-	{ ASTOSL,	ynone,	Px, {0xab} },
-	{ ASTOSQ,	ynone,	Pw, {0xab} },
-	{ ASTOSW,	ynone,	Pe, {0xab} },
-	{ ASUBB,	yxorb,	Pb, {0x2c,0x80,(05),0x28,0x2a} },
-	{ ASUBL,	yaddl,	Px, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
-	{ ASUBPD,	yxm,	Pe, {0x5c} },
-	{ ASUBPS,	yxm,	Pm, {0x5c} },
-	{ ASUBQ,	yaddl,	Pw, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
-	{ ASUBSD,	yxm,	Pf2, {0x5c} },
-	{ ASUBSS,	yxm,	Pf3, {0x5c} },
-	{ ASUBW,	yaddl,	Pe, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
-	{ ASWAPGS,	ynone,	Pm, {0x01,0xf8} },
-	{ ASYSCALL,	ynone,	Px, {0x0f,0x05} },	/* fast syscall */
-	{ ATESTB,	ytestb,	Pb, {0xa8,0xf6,(00),0x84,0x84} },
-	{ ATESTL,	ytestl,	Px, {0xa9,0xf7,(00),0x85,0x85} },
-	{ ATESTQ,	ytestl,	Pw, {0xa9,0xf7,(00),0x85,0x85} },
-	{ ATESTW,	ytestl,	Pe, {0xa9,0xf7,(00),0x85,0x85} },
-	{ ATEXT,	ytext,	Px },
-	{ AUCOMISD,	yxcmp,	Pe, {0x2e} },
-	{ AUCOMISS,	yxcmp,	Pm, {0x2e} },
-	{ AUNPCKHPD,	yxm,	Pe, {0x15} },
-	{ AUNPCKHPS,	yxm,	Pm, {0x15} },
-	{ AUNPCKLPD,	yxm,	Pe, {0x14} },
-	{ AUNPCKLPS,	yxm,	Pm, {0x14} },
-	{ AVERR,	ydivl,	Pm, {0x00,(04)} },
-	{ AVERW,	ydivl,	Pm, {0x00,(05)} },
-	{ AWAIT,	ynone,	Px, {0x9b} },
-	{ AWORD,	ybyte,	Px, {2} },
-	{ AXCHGB,	yml_mb,	Pb, {0x86,0x86} },
-	{ AXCHGL,	yxchg,	Px, {0x90,0x90,0x87,0x87} },
-	{ AXCHGQ,	yxchg,	Pw, {0x90,0x90,0x87,0x87} },
-	{ AXCHGW,	yxchg,	Pe, {0x90,0x90,0x87,0x87} },
-	{ AXLAT,	ynone,	Px, {0xd7} },
-	{ AXORB,	yxorb,	Pb, {0x34,0x80,(06),0x30,0x32} },
-	{ AXORL,	yxorl,	Px, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
-	{ AXORPD,	yxm,	Pe, {0x57} },
-	{ AXORPS,	yxm,	Pm, {0x57} },
-	{ AXORQ,	yxorl,	Pw, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
-	{ AXORW,	yxorl,	Pe, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
-
-	{ AFMOVB,	yfmvx,	Px, {0xdf,(04)} },
-	{ AFMOVBP,	yfmvp,	Px, {0xdf,(06)} },
-	{ AFMOVD,	yfmvd,	Px, {0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02)} },
-	{ AFMOVDP,	yfmvdp,	Px, {0xdd,(03),0xdd,(03)} },
-	{ AFMOVF,	yfmvf,	Px, {0xd9,(00),0xd9,(02)} },
-	{ AFMOVFP,	yfmvp,	Px, {0xd9,(03)} },
-	{ AFMOVL,	yfmvf,	Px, {0xdb,(00),0xdb,(02)} },
-	{ AFMOVLP,	yfmvp,	Px, {0xdb,(03)} },
-	{ AFMOVV,	yfmvx,	Px, {0xdf,(05)} },
-	{ AFMOVVP,	yfmvp,	Px, {0xdf,(07)} },
-	{ AFMOVW,	yfmvf,	Px, {0xdf,(00),0xdf,(02)} },
-	{ AFMOVWP,	yfmvp,	Px, {0xdf,(03)} },
-	{ AFMOVX,	yfmvx,	Px, {0xdb,(05)} },
-	{ AFMOVXP,	yfmvp,	Px, {0xdb,(07)} },
-
-	{ AFCOMB },
-	{ AFCOMBP },
-	{ AFCOMD,	yfadd,	Px, {0xdc,(02),0xd8,(02),0xdc,(02)} },	/* botch */
-	{ AFCOMDP,	yfadd,	Px, {0xdc,(03),0xd8,(03),0xdc,(03)} },	/* botch */
-	{ AFCOMDPP,	ycompp,	Px, {0xde,(03)} },
-	{ AFCOMF,	yfmvx,	Px, {0xd8,(02)} },
-	{ AFCOMFP,	yfmvx,	Px, {0xd8,(03)} },
-	{ AFCOML,	yfmvx,	Px, {0xda,(02)} },
-	{ AFCOMLP,	yfmvx,	Px, {0xda,(03)} },
-	{ AFCOMW,	yfmvx,	Px, {0xde,(02)} },
-	{ AFCOMWP,	yfmvx,	Px, {0xde,(03)} },
-
-	{ AFUCOM,	ycompp,	Px, {0xdd,(04)} },
-	{ AFUCOMP,	ycompp, Px, {0xdd,(05)} },
-	{ AFUCOMPP,	ycompp,	Px, {0xda,(13)} },
-
-	{ AFADDDP,	yfaddp,	Px, {0xde,(00)} },
-	{ AFADDW,	yfmvx,	Px, {0xde,(00)} },
-	{ AFADDL,	yfmvx,	Px, {0xda,(00)} },
-	{ AFADDF,	yfmvx,	Px, {0xd8,(00)} },
-	{ AFADDD,	yfadd,	Px, {0xdc,(00),0xd8,(00),0xdc,(00)} },
-
-	{ AFMULDP,	yfaddp,	Px, {0xde,(01)} },
-	{ AFMULW,	yfmvx,	Px, {0xde,(01)} },
-	{ AFMULL,	yfmvx,	Px, {0xda,(01)} },
-	{ AFMULF,	yfmvx,	Px, {0xd8,(01)} },
-	{ AFMULD,	yfadd,	Px, {0xdc,(01),0xd8,(01),0xdc,(01)} },
-
-	{ AFSUBDP,	yfaddp,	Px, {0xde,(05)} },
-	{ AFSUBW,	yfmvx,	Px, {0xde,(04)} },
-	{ AFSUBL,	yfmvx,	Px, {0xda,(04)} },
-	{ AFSUBF,	yfmvx,	Px, {0xd8,(04)} },
-	{ AFSUBD,	yfadd,	Px, {0xdc,(04),0xd8,(04),0xdc,(05)} },
-
-	{ AFSUBRDP,	yfaddp,	Px, {0xde,(04)} },
-	{ AFSUBRW,	yfmvx,	Px, {0xde,(05)} },
-	{ AFSUBRL,	yfmvx,	Px, {0xda,(05)} },
-	{ AFSUBRF,	yfmvx,	Px, {0xd8,(05)} },
-	{ AFSUBRD,	yfadd,	Px, {0xdc,(05),0xd8,(05),0xdc,(04)} },
-
-	{ AFDIVDP,	yfaddp,	Px, {0xde,(07)} },
-	{ AFDIVW,	yfmvx,	Px, {0xde,(06)} },
-	{ AFDIVL,	yfmvx,	Px, {0xda,(06)} },
-	{ AFDIVF,	yfmvx,	Px, {0xd8,(06)} },
-	{ AFDIVD,	yfadd,	Px, {0xdc,(06),0xd8,(06),0xdc,(07)} },
-
-	{ AFDIVRDP,	yfaddp,	Px, {0xde,(06)} },
-	{ AFDIVRW,	yfmvx,	Px, {0xde,(07)} },
-	{ AFDIVRL,	yfmvx,	Px, {0xda,(07)} },
-	{ AFDIVRF,	yfmvx,	Px, {0xd8,(07)} },
-	{ AFDIVRD,	yfadd,	Px, {0xdc,(07),0xd8,(07),0xdc,(06)} },
-
-	{ AFXCHD,	yfxch,	Px, {0xd9,(01),0xd9,(01)} },
-	{ AFFREE },
-	{ AFLDCW,	ystcw,	Px, {0xd9,(05),0xd9,(05)} },
-	{ AFLDENV,	ystcw,	Px, {0xd9,(04),0xd9,(04)} },
-	{ AFRSTOR,	ysvrs,	Px, {0xdd,(04),0xdd,(04)} },
-	{ AFSAVE,	ysvrs,	Px, {0xdd,(06),0xdd,(06)} },
-	{ AFSTCW,	ystcw,	Px, {0xd9,(07),0xd9,(07)} },
-	{ AFSTENV,	ystcw,	Px, {0xd9,(06),0xd9,(06)} },
-	{ AFSTSW,	ystsw,	Px, {0xdd,(07),0xdf,0xe0} },
-	{ AF2XM1,	ynone,	Px, {0xd9, 0xf0} },
-	{ AFABS,	ynone,	Px, {0xd9, 0xe1} },
-	{ AFCHS,	ynone,	Px, {0xd9, 0xe0} },
-	{ AFCLEX,	ynone,	Px, {0xdb, 0xe2} },
-	{ AFCOS,	ynone,	Px, {0xd9, 0xff} },
-	{ AFDECSTP,	ynone,	Px, {0xd9, 0xf6} },
-	{ AFINCSTP,	ynone,	Px, {0xd9, 0xf7} },
-	{ AFINIT,	ynone,	Px, {0xdb, 0xe3} },
-	{ AFLD1,	ynone,	Px, {0xd9, 0xe8} },
-	{ AFLDL2E,	ynone,	Px, {0xd9, 0xea} },
-	{ AFLDL2T,	ynone,	Px, {0xd9, 0xe9} },
-	{ AFLDLG2,	ynone,	Px, {0xd9, 0xec} },
-	{ AFLDLN2,	ynone,	Px, {0xd9, 0xed} },
-	{ AFLDPI,	ynone,	Px, {0xd9, 0xeb} },
-	{ AFLDZ,	ynone,	Px, {0xd9, 0xee} },
-	{ AFNOP,	ynone,	Px, {0xd9, 0xd0} },
-	{ AFPATAN,	ynone,	Px, {0xd9, 0xf3} },
-	{ AFPREM,	ynone,	Px, {0xd9, 0xf8} },
-	{ AFPREM1,	ynone,	Px, {0xd9, 0xf5} },
-	{ AFPTAN,	ynone,	Px, {0xd9, 0xf2} },
-	{ AFRNDINT,	ynone,	Px, {0xd9, 0xfc} },
-	{ AFSCALE,	ynone,	Px, {0xd9, 0xfd} },
-	{ AFSIN,	ynone,	Px, {0xd9, 0xfe} },
-	{ AFSINCOS,	ynone,	Px, {0xd9, 0xfb} },
-	{ AFSQRT,	ynone,	Px, {0xd9, 0xfa} },
-	{ AFTST,	ynone,	Px, {0xd9, 0xe4} },
-	{ AFXAM,	ynone,	Px, {0xd9, 0xe5} },
-	{ AFXTRACT,	ynone,	Px, {0xd9, 0xf4} },
-	{ AFYL2X,	ynone,	Px, {0xd9, 0xf1} },
-	{ AFYL2XP1,	ynone,	Px, {0xd9, 0xf9} },
-
-	{ ACMPXCHGB,	yrb_mb,	Pb, {0x0f,0xb0} },
-	{ ACMPXCHGL,	yrl_ml,	Px, {0x0f,0xb1} },
-	{ ACMPXCHGW,	yrl_ml,	Pe, {0x0f,0xb1} },
-	{ ACMPXCHGQ,	yrl_ml,	Pw, {0x0f,0xb1} },
-	{ ACMPXCHG8B,	yscond,	Pm, {0xc7,(01)} },
-	{ AINVD,	ynone,	Pm, {0x08} },
-	{ AINVLPG,	ymbs,	Pm, {0x01,(07)} },
-	{ ALFENCE,	ynone,	Pm, {0xae,0xe8} },
-	{ AMFENCE,	ynone,	Pm, {0xae,0xf0} },
-	{ AMOVNTIL,	yrl_ml,	Pm, {0xc3} },
-	{ AMOVNTIQ,	yrl_ml, Pw, {0x0f,0xc3} },
-	{ ARDMSR,	ynone,	Pm, {0x32} },
-	{ ARDPMC,	ynone,	Pm, {0x33} },
-	{ ARDTSC,	ynone,	Pm, {0x31} },
-	{ ARSM,		ynone,	Pm, {0xaa} },
-	{ ASFENCE,	ynone,	Pm, {0xae,0xf8} },
-	{ ASYSRET,	ynone,	Pm, {0x07} },
-	{ AWBINVD,	ynone,	Pm, {0x09} },
-	{ AWRMSR,	ynone,	Pm, {0x30} },
-
-	{ AXADDB,	yrb_mb,	Pb, {0x0f,0xc0} },
-	{ AXADDL,	yrl_ml,	Px, {0x0f,0xc1} },
-	{ AXADDQ,	yrl_ml,	Pw, {0x0f,0xc1} },
-	{ AXADDW,	yrl_ml,	Pe, {0x0f,0xc1} },
-
-	{ ACRC32B,       ycrc32l,Px, {0xf2,0x0f,0x38,0xf0,0} },
-	{ ACRC32Q,       ycrc32l,Pw, {0xf2,0x0f,0x38,0xf1,0} },
-	
-	{ APREFETCHT0,	yprefetch,	Pm,	{0x18,(01)} },
-	{ APREFETCHT1,	yprefetch,	Pm,	{0x18,(02)} },
-	{ APREFETCHT2,	yprefetch,	Pm,	{0x18,(03)} },
-	{ APREFETCHNTA,	yprefetch,	Pm,	{0x18,(00)} },
-	
-	{ AMOVQL,	yrl_ml,	Px, {0x89} },
-
-	{ AUNDEF,		ynone,	Px, {0x0f, 0x0b} },
-
-	{ AAESENC,	yaes,	Pq, {0x38,0xdc,(0)} },
-	{ AAESENCLAST,	yaes,	Pq, {0x38,0xdd,(0)} },
-	{ AAESDEC,	yaes,	Pq, {0x38,0xde,(0)} },
-	{ AAESDECLAST,	yaes,	Pq, {0x38,0xdf,(0)} },
-	{ AAESIMC,	yaes,	Pq, {0x38,0xdb,(0)} },
-	{ AAESKEYGENASSIST,	yaes2,	Pq, {0x3a,0xdf,(0)} },
-
-	{ APSHUFD,	yaes2,	Pq,	{0x70,(0)} },
-	{ APCLMULQDQ,	yxshuf,	Pq, {0x3a,0x44,0} },
-
-	{ AUSEFIELD,	ynop,	Px, {0,0} },
-	{ ATYPE },
-	{ AFUNCDATA,	yfuncdata,	Px, {0,0} },
-	{ APCDATA,	ypcdata,	Px, {0,0} },
-	{ ACHECKNIL },
-	{ AVARDEF },
-	{ AVARKILL },
-	{ ADUFFCOPY,	yduff,	Px, {0xe8} },
-	{ ADUFFZERO,	yduff,	Px, {0xe8} },
-
-	{ AEND },
-	{0}
-};
-
-static Optab*	opindex[ALAST+1];
-static vlong	vaddr(Link*, Prog*, Addr*, Reloc*);
-
-// isextern reports whether s describes an external symbol that must avoid pc-relative addressing.
-// This happens on systems like Solaris that call .so functions instead of system calls.
-// It does not seem to be necessary for any other systems. This is probably working
-// around a Solaris-specific bug that should be fixed differently, but we don't know
-// what that bug is. And this does fix it.
-static int
-isextern(LSym *s)
-{
-	// All the Solaris dynamic imports from libc.so begin with "libc_".
-	return strncmp(s->name, "libc_", 5) == 0;
-}
-
-// single-instruction no-ops of various lengths.
-// constructed by hand and disassembled with gdb to verify.
-// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
-static uchar nop[][16] = {
-	{0x90},
-	{0x66, 0x90},
-	{0x0F, 0x1F, 0x00},
-	{0x0F, 0x1F, 0x40, 0x00},
-	{0x0F, 0x1F, 0x44, 0x00, 0x00},
-	{0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
-	{0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
-	{0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-	// Native Client rejects the repeated 0x66 prefix.
-	// {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-};
-
-static void
-fillnop(uchar *p, int n)
-{
-	int m;
-
-	while(n > 0) {
-		m = n;
-		if(m > nelem(nop))
-			m = nelem(nop);
-		memmove(p, nop[m-1], m);
-		p += m;
-		n -= m;
-	}
-}
-
-static void instinit(void);
-
-static int32
-naclpad(Link *ctxt, LSym *s, int32 c, int32 pad)
-{
-	symgrow(ctxt, s, c+pad);
-	fillnop(s->p+c, pad);
-	return c+pad;
-}
-
-static int
-spadjop(Link *ctxt, Prog *p, int l, int q)
-{
-	if(p->mode != 64 || ctxt->arch->ptrsize == 4)
-		return l;
-	return q;
-}
-
-void
-span6(Link *ctxt, LSym *s)
-{
-	Prog *p, *q;
-	int32 c, v, loop;
-	uchar *bp;
-	int n, m, i;
-
-	ctxt->cursym = s;
-	
-	if(s->p != nil)
-		return;
-	
-	if(ycover[0] == 0)
-		instinit();
-	
-	for(p = ctxt->cursym->text; p != nil; p = p->link) {
-		if(p->to.type == TYPE_BRANCH)
-			if(p->pcond == nil)
-				p->pcond = p;
-		if(p->as == AADJSP) {
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_SP;
-			v = -p->from.offset;
-			p->from.offset = v;
-			p->as = spadjop(ctxt, p, AADDL, AADDQ);
-			if(v < 0) {
-				p->as = spadjop(ctxt, p, ASUBL, ASUBQ);
-				v = -v;
-				p->from.offset = v;
-			}
-			if(v == 0)
-				p->as = ANOP;
-		}
-	}
-
-	for(p = s->text; p != nil; p = p->link) {
-		p->back = 2;	// use short branches first time through
-		if((q = p->pcond) != nil && (q->back & 2)) {
-			p->back |= 1;	// backward jump
-			q->back |= 4;   // loop head
-		}
-
-		if(p->as == AADJSP) {
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_SP;
-			v = -p->from.offset;
-			p->from.offset = v;
-			p->as = spadjop(ctxt, p, AADDL, AADDQ);
-			if(v < 0) {
-				p->as = spadjop(ctxt, p, ASUBL, ASUBQ);
-				v = -v;
-				p->from.offset = v;
-			}
-			if(v == 0)
-				p->as = ANOP;
-		}
-	}
-	
-	n = 0;
-	do {
-		loop = 0;
-		memset(s->r, 0, s->nr*sizeof s->r[0]);
-		s->nr = 0;
-		s->np = 0;
-		c = 0;
-		for(p = s->text; p != nil; p = p->link) {
-			if(ctxt->headtype == Hnacl && p->isize > 0) {
-				static LSym *deferreturn;
-				
-				if(deferreturn == nil)
-					deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
-
-				// pad everything to avoid crossing 32-byte boundary
-				if((c>>5) != ((c+p->isize-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-				// pad call deferreturn to start at 32-byte boundary
-				// so that subtracting 5 in jmpdefer will jump back
-				// to that boundary and rerun the call.
-				if(p->as == ACALL && p->to.sym == deferreturn)
-					c = naclpad(ctxt, s, c, -c&31);
-				// pad call to end at 32-byte boundary
-				if(p->as == ACALL)
-					c = naclpad(ctxt, s, c, -(c+p->isize)&31);
-				
-				// the linker treats REP and STOSQ as different instructions
-				// but in fact the REP is a prefix on the STOSQ.
-				// make sure REP has room for 2 more bytes, so that
-				// padding will not be inserted before the next instruction.
-				if((p->as == AREP || p->as == AREPN) && (c>>5) != ((c+3-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-				
-				// same for LOCK.
-				// various instructions follow; the longest is 4 bytes.
-				// give ourselves 8 bytes so as to avoid surprises.
-				if(p->as == ALOCK && (c>>5) != ((c+8-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-			}
-
-			if((p->back & 4) && (c&(LoopAlign-1)) != 0) {
-				// pad with NOPs
-				v = -c&(LoopAlign-1);
-				if(v <= MaxLoopPad) {
-					symgrow(ctxt, s, c+v);
-					fillnop(s->p+c, v);
-					c += v;
-				}
-			}
-
-			p->pc = c;
-
-			// process forward jumps to p
-			for(q = p->comefrom; q != nil; q = q->forwd) {
-				v = p->pc - (q->pc + q->mark);
-				if(q->back & 2)	{	// short
-					if(v > 127) {
-						loop++;
-						q->back ^= 2;
-					}
-					if(q->as == AJCXZL)
-						s->p[q->pc+2] = v;
-					else
-						s->p[q->pc+1] = v;
-				} else {
-					bp = s->p + q->pc + q->mark - 4;
-					*bp++ = v;
-					*bp++ = v>>8;
-					*bp++ = v>>16;
-					*bp = v>>24;
-				}	
-			}
-			p->comefrom = nil;
-
-			p->pc = c;
-			asmins(ctxt, p);
-			m = ctxt->andptr-ctxt->and;
-			if(p->isize != m) {
-				p->isize = m;
-				loop++;
-			}
-			symgrow(ctxt, s, p->pc+m);
-			memmove(s->p+p->pc, ctxt->and, m);
-			p->mark = m;
-			c += m;
-		}
-		if(++n > 20) {
-			ctxt->diag("span must be looping");
-			sysfatal("loop");
-		}
-	} while(loop);
-	
-	if(ctxt->headtype == Hnacl)
-		c = naclpad(ctxt, s, c, -c&31);
-	
-	c += -c&(FuncAlign-1);
-	s->size = c;
-
-	if(0 /* debug['a'] > 1 */) {
-		print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
-		for(i=0; i<s->np; i++) {
-			print(" %.2ux", s->p[i]);
-			if(i%16 == 15)
-				print("\n  %.6ux", i+1);
-		}
-		if(i%16)
-			print("\n");
-	
-		for(i=0; i<s->nr; i++) {
-			Reloc *r;
-			
-			r = &s->r[i];
-			print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
-		}
-	}
-}
-
-static void
-instinit(void)
-{
-	int c, i;
-
-	for(i=1; optab[i].as; i++) {
-		c = optab[i].as;
-		if(opindex[c] != nil)
-			sysfatal("phase error in optab: %d (%A)", i, c);
-		opindex[c] = &optab[i];
-	}
-
-	for(i=0; i<Ymax; i++)
-		ycover[i*Ymax + i] = 1;
-
-	ycover[Yi0*Ymax + Yi8] = 1;
-	ycover[Yi1*Ymax + Yi8] = 1;
-
-	ycover[Yi0*Ymax + Ys32] = 1;
-	ycover[Yi1*Ymax + Ys32] = 1;
-	ycover[Yi8*Ymax + Ys32] = 1;
-
-	ycover[Yi0*Ymax + Yi32] = 1;
-	ycover[Yi1*Ymax + Yi32] = 1;
-	ycover[Yi8*Ymax + Yi32] = 1;
-	ycover[Ys32*Ymax + Yi32] = 1;
-
-	ycover[Yi0*Ymax + Yi64] = 1;
-	ycover[Yi1*Ymax + Yi64] = 1;
-	ycover[Yi8*Ymax + Yi64] = 1;
-	ycover[Ys32*Ymax + Yi64] = 1;
-	ycover[Yi32*Ymax + Yi64] = 1;
-
-	ycover[Yal*Ymax + Yrb] = 1;
-	ycover[Ycl*Ymax + Yrb] = 1;
-	ycover[Yax*Ymax + Yrb] = 1;
-	ycover[Ycx*Ymax + Yrb] = 1;
-	ycover[Yrx*Ymax + Yrb] = 1;
-	ycover[Yrl*Ymax + Yrb] = 1;
-
-	ycover[Ycl*Ymax + Ycx] = 1;
-
-	ycover[Yax*Ymax + Yrx] = 1;
-	ycover[Ycx*Ymax + Yrx] = 1;
-
-	ycover[Yax*Ymax + Yrl] = 1;
-	ycover[Ycx*Ymax + Yrl] = 1;
-	ycover[Yrx*Ymax + Yrl] = 1;
-
-	ycover[Yf0*Ymax + Yrf] = 1;
-
-	ycover[Yal*Ymax + Ymb] = 1;
-	ycover[Ycl*Ymax + Ymb] = 1;
-	ycover[Yax*Ymax + Ymb] = 1;
-	ycover[Ycx*Ymax + Ymb] = 1;
-	ycover[Yrx*Ymax + Ymb] = 1;
-	ycover[Yrb*Ymax + Ymb] = 1;
-	ycover[Yrl*Ymax + Ymb] = 1;
-	ycover[Ym*Ymax + Ymb] = 1;
-
-	ycover[Yax*Ymax + Yml] = 1;
-	ycover[Ycx*Ymax + Yml] = 1;
-	ycover[Yrx*Ymax + Yml] = 1;
-	ycover[Yrl*Ymax + Yml] = 1;
-	ycover[Ym*Ymax + Yml] = 1;
-
-	ycover[Yax*Ymax + Ymm] = 1;
-	ycover[Ycx*Ymax + Ymm] = 1;
-	ycover[Yrx*Ymax + Ymm] = 1;
-	ycover[Yrl*Ymax + Ymm] = 1;
-	ycover[Ym*Ymax + Ymm] = 1;
-	ycover[Ymr*Ymax + Ymm] = 1;
-
-	ycover[Ym*Ymax + Yxm] = 1;
-	ycover[Yxr*Ymax + Yxm] = 1;
-
-	for(i=0; i<MAXREG; i++) {
-		reg[i] = -1;
-		if(i >= REG_AL && i <= REG_R15B) {
-			reg[i] = (i-REG_AL) & 7;
-			if(i >= REG_SPB && i <= REG_DIB)
-				regrex[i] = 0x40;
-			if(i >= REG_R8B && i <= REG_R15B)
-				regrex[i] = Rxr | Rxx | Rxb;
-		}
-		if(i >= REG_AH && i<= REG_BH)
-			reg[i] = 4 + ((i-REG_AH) & 7);
-		if(i >= REG_AX && i <= REG_R15) {
-			reg[i] = (i-REG_AX) & 7;
-			if(i >= REG_R8)
-				regrex[i] = Rxr | Rxx | Rxb;
-		}
-		if(i >= REG_F0 && i <= REG_F0+7)
-			reg[i] = (i-REG_F0) & 7;
-		if(i >= REG_M0 && i <= REG_M0+7)
-			reg[i] = (i-REG_M0) & 7;
-		if(i >= REG_X0 && i <= REG_X0+15) {
-			reg[i] = (i-REG_X0) & 7;
-			if(i >= REG_X0+8)
-				regrex[i] = Rxr | Rxx | Rxb;
-		}
-		if(i >= REG_CR+8 && i <= REG_CR+15)
-			regrex[i] = Rxr;
-	}
-}
-
-static int
-prefixof(Link *ctxt, Addr *a)
-{
-	if(a->type == TYPE_MEM && a->name == NAME_NONE) {
-		switch(a->reg) {
-		case REG_CS:
-			return 0x2e;
-		case REG_DS:
-			return 0x3e;
-		case REG_ES:
-			return 0x26;
-		case REG_FS:
-			return 0x64;
-		case REG_GS:
-			return 0x65;
-		case REG_TLS:
-			// NOTE: Systems listed here should be only systems that
-			// support direct TLS references like 8(TLS) implemented as
-			// direct references from FS or GS. Systems that require
-			// the initial-exec model, where you load the TLS base into
-			// a register and then index from that register, do not reach
-			// this code and should not be listed.
-			switch(ctxt->headtype) {
-			default:
-				sysfatal("unknown TLS base register for %s", headstr(ctxt->headtype));
-			case Hdragonfly:
-			case Hfreebsd:
-			case Hlinux:
-			case Hnetbsd:
-			case Hopenbsd:
-			case Hsolaris:
-				return 0x64; // FS
-			case Hdarwin:
-				return 0x65; // GS
-			}
-		}
-	}
-	switch(a->index) {
-	case REG_CS:
-		return 0x2e;
-	case REG_DS:
-		return 0x3e;
-	case REG_ES:
-		return 0x26;
-	case REG_FS:
-		return 0x64;
-	case REG_GS:
-		return 0x65;
-	}
-	return 0;
-}
-
-static int
-oclass(Link *ctxt, Prog *p, Addr *a)
-{
-	vlong v;
-	int32 l;
-	
-	USED(p);
-
-	// TODO(rsc): This special case is for SHRQ $3, AX:DX,
-	// which encodes as SHRQ $32(DX*0), AX.
-	// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
-	// Change encoding and remove.
-	if((a->type == TYPE_CONST || a->type == TYPE_REG) && a->index != REG_NONE && a->scale == 0)
-		return Ycol;
-
-	switch(a->type) {
-	case TYPE_NONE:
-		return Ynone;
-
-	case TYPE_BRANCH:
-		return Ybr;
-
-	case TYPE_MEM:
-		return Ym;
-
-	case TYPE_ADDR:
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			if(a->sym != nil && isextern(a->sym))
-				return Yi32;
-			return Yiauto; // use pc-relative addressing
-		case NAME_AUTO:
-		case NAME_PARAM:
-			return Yiauto;
-		}
-
-		// TODO(rsc): DUFFZERO/DUFFCOPY encoding forgot to set a->index
-		// and got Yi32 in an earlier version of this code.
-		// Keep doing that until we fix yduff etc.
-		if(a->sym != nil && strncmp(a->sym->name, "runtime.duff", 12) == 0)
-			return Yi32;
-		
-		if(a->sym != nil || a->name != NAME_NONE)
-			ctxt->diag("unexpected addr: %D", a);
-		// fall through
-
-	case TYPE_CONST:
-		if(a->sym != nil)
-			ctxt->diag("TYPE_CONST with symbol: %D", a);
-
-		v = a->offset;
-		if(v == 0)
-			return Yi0;
-		if(v == 1)
-			return Yi1;
-		if(v >= -128 && v <= 127)
-			return Yi8;
-		l = v;
-		if((vlong)l == v)
-			return Ys32;	/* can sign extend */
-		if((v>>32) == 0)
-			return Yi32;	/* unsigned */
-		return Yi64;
-
-	case TYPE_TEXTSIZE:
-		return Ytextsize;
-	}
-	
-	if(a->type != TYPE_REG) {
-		ctxt->diag("unexpected addr1: type=%d %D", a->type, a);
-		return Yxxx;
-	}
-
-	switch(a->reg) {
-	case REG_AL:
-		return Yal;
-
-	case REG_AX:
-		return Yax;
-
-/*
-	case REG_SPB:
-*/
-	case REG_BPB:
-	case REG_SIB:
-	case REG_DIB:
-	case REG_R8B:
-	case REG_R9B:
-	case REG_R10B:
-	case REG_R11B:
-	case REG_R12B:
-	case REG_R13B:
-	case REG_R14B:
-	case REG_R15B:
-		if(ctxt->asmode != 64)
-			return Yxxx;
-	case REG_DL:
-	case REG_BL:
-	case REG_AH:
-	case REG_CH:
-	case REG_DH:
-	case REG_BH:
-		return Yrb;
-
-	case REG_CL:
-		return Ycl;
-
-	case REG_CX:
-		return Ycx;
-
-	case REG_DX:
-	case REG_BX:
-		return Yrx;
-
-	case REG_R8:	/* not really Yrl */
-	case REG_R9:
-	case REG_R10:
-	case REG_R11:
-	case REG_R12:
-	case REG_R13:
-	case REG_R14:
-	case REG_R15:
-		if(ctxt->asmode != 64)
-			return Yxxx;
-	case REG_SP:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		return Yrl;
-
-	case REG_F0+0:
-		return	Yf0;
-
-	case REG_F0+1:
-	case REG_F0+2:
-	case REG_F0+3:
-	case REG_F0+4:
-	case REG_F0+5:
-	case REG_F0+6:
-	case REG_F0+7:
-		return	Yrf;
-
-	case REG_M0+0:
-	case REG_M0+1:
-	case REG_M0+2:
-	case REG_M0+3:
-	case REG_M0+4:
-	case REG_M0+5:
-	case REG_M0+6:
-	case REG_M0+7:
-		return	Ymr;
-
-	case REG_X0+0:
-	case REG_X0+1:
-	case REG_X0+2:
-	case REG_X0+3:
-	case REG_X0+4:
-	case REG_X0+5:
-	case REG_X0+6:
-	case REG_X0+7:
-	case REG_X0+8:
-	case REG_X0+9:
-	case REG_X0+10:
-	case REG_X0+11:
-	case REG_X0+12:
-	case REG_X0+13:
-	case REG_X0+14:
-	case REG_X0+15:
-		return	Yxr;
-
-	case REG_CS:	return	Ycs;
-	case REG_SS:	return	Yss;
-	case REG_DS:	return	Yds;
-	case REG_ES:	return	Yes;
-	case REG_FS:	return	Yfs;
-	case REG_GS:	return	Ygs;
-	case REG_TLS:	return	Ytls;
-
-	case REG_GDTR:	return	Ygdtr;
-	case REG_IDTR:	return	Yidtr;
-	case REG_LDTR:	return	Yldtr;
-	case REG_MSW:	return	Ymsw;
-	case REG_TASK:	return	Ytask;
-
-	case REG_CR+0:	return	Ycr0;
-	case REG_CR+1:	return	Ycr1;
-	case REG_CR+2:	return	Ycr2;
-	case REG_CR+3:	return	Ycr3;
-	case REG_CR+4:	return	Ycr4;
-	case REG_CR+5:	return	Ycr5;
-	case REG_CR+6:	return	Ycr6;
-	case REG_CR+7:	return	Ycr7;
-	case REG_CR+8:	return	Ycr8;
-
-	case REG_DR+0:	return	Ydr0;
-	case REG_DR+1:	return	Ydr1;
-	case REG_DR+2:	return	Ydr2;
-	case REG_DR+3:	return	Ydr3;
-	case REG_DR+4:	return	Ydr4;
-	case REG_DR+5:	return	Ydr5;
-	case REG_DR+6:	return	Ydr6;
-	case REG_DR+7:	return	Ydr7;
-
-	case REG_TR+0:	return	Ytr0;
-	case REG_TR+1:	return	Ytr1;
-	case REG_TR+2:	return	Ytr2;
-	case REG_TR+3:	return	Ytr3;
-	case REG_TR+4:	return	Ytr4;
-	case REG_TR+5:	return	Ytr5;
-	case REG_TR+6:	return	Ytr6;
-	case REG_TR+7:	return	Ytr7;
-
-	}
-	return Yxxx;
-}
-
-static void
-asmidx(Link *ctxt, int scale, int index, int base)
-{
-	int i;
-
-	switch(index) {
-	default:
-		goto bad;
-
-	case REG_NONE:
-		i = 4 << 3;
-		goto bas;
-
-	case REG_R8:
-	case REG_R9:
-	case REG_R10:
-	case REG_R11:
-	case REG_R12:
-	case REG_R13:
-	case REG_R14:
-	case REG_R15:
-		if(ctxt->asmode != 64)
-			goto bad;
-	case REG_AX:
-	case REG_CX:
-	case REG_DX:
-	case REG_BX:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		i = reg[index] << 3;
-		break;
-	}
-	switch(scale) {
-	default:
-		goto bad;
-	case 1:
-		break;
-	case 2:
-		i |= (1<<6);
-		break;
-	case 4:
-		i |= (2<<6);
-		break;
-	case 8:
-		i |= (3<<6);
-		break;
-	}
-bas:
-	switch(base) {
-	default:
-		goto bad;
-	case REG_NONE:	/* must be mod=00 */
-		i |= 5;
-		break;
-	case REG_R8:
-	case REG_R9:
-	case REG_R10:
-	case REG_R11:
-	case REG_R12:
-	case REG_R13:
-	case REG_R14:
-	case REG_R15:
-		if(ctxt->asmode != 64)
-			goto bad;
-	case REG_AX:
-	case REG_CX:
-	case REG_DX:
-	case REG_BX:
-	case REG_SP:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		i |= reg[base];
-		break;
-	}
-	*ctxt->andptr++ = i;
-	return;
-bad:
-	ctxt->diag("asmidx: bad address %d/%d/%d", scale, index, base);
-	*ctxt->andptr++ = 0;
-	return;
-}
-
-static void
-put4(Link *ctxt, int32 v)
-{
-	ctxt->andptr[0] = v;
-	ctxt->andptr[1] = v>>8;
-	ctxt->andptr[2] = v>>16;
-	ctxt->andptr[3] = v>>24;
-	ctxt->andptr += 4;
-}
-
-static void
-relput4(Link *ctxt, Prog *p, Addr *a)
-{
-	vlong v;
-	Reloc rel, *r;
-	
-	v = vaddr(ctxt, p, a, &rel);
-	if(rel.siz != 0) {
-		if(rel.siz != 4)
-			ctxt->diag("bad reloc");
-		r = addrel(ctxt->cursym);
-		*r = rel;
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-	}
-	put4(ctxt, v);
-}
-
-static void
-put8(Link *ctxt, vlong v)
-{
-	ctxt->andptr[0] = v;
-	ctxt->andptr[1] = v>>8;
-	ctxt->andptr[2] = v>>16;
-	ctxt->andptr[3] = v>>24;
-	ctxt->andptr[4] = v>>32;
-	ctxt->andptr[5] = v>>40;
-	ctxt->andptr[6] = v>>48;
-	ctxt->andptr[7] = v>>56;
-	ctxt->andptr += 8;
-}
-
-/*
-static void
-relput8(Prog *p, Addr *a)
-{
-	vlong v;
-	Reloc rel, *r;
-	
-	v = vaddr(ctxt, p, a, &rel);
-	if(rel.siz != 0) {
-		r = addrel(ctxt->cursym);
-		*r = rel;
-		r->siz = 8;
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-	}
-	put8(ctxt, v);
-}
-*/
-
-static vlong
-vaddr(Link *ctxt, Prog *p, Addr *a, Reloc *r)
-{
-	LSym *s;
-	
-	USED(p);
-
-	if(r != nil)
-		memset(r, 0, sizeof *r);
-
-	switch(a->name) {
-	case NAME_STATIC:
-	case NAME_EXTERN:
-		s = a->sym;
-		if(r == nil) {
-			ctxt->diag("need reloc for %D", a);
-			sysfatal("reloc");
-		}
-		if(isextern(s)) {
-			r->siz = 4;
-			r->type = R_ADDR;
-		} else {
-			r->siz = 4;
-			r->type = R_PCREL;
-		}
-		r->off = -1;	// caller must fill in
-		r->sym = s;
-		r->add = a->offset;
-		if(s->type == STLSBSS) {
-			r->xadd = r->add - r->siz;
-			r->type = R_TLS;
-			r->xsym = s;
-		}
-		return 0;
-	}
-	
-	if((a->type == TYPE_MEM || a->type == TYPE_ADDR) && a->reg == REG_TLS) {
-		if(r == nil) {
-			ctxt->diag("need reloc for %D", a);
-			sysfatal("reloc");
-		}
-		r->type = R_TLS_LE;
-		r->siz = 4;
-		r->off = -1;	// caller must fill in
-		r->add = a->offset;
-		return 0;
-	}
-
-	return a->offset;
-}
-
-static void
-asmandsz(Link *ctxt, Prog *p, Addr *a, int r, int rex, int m64)
-{
-	int32 v;
-	int base;
-	Reloc rel;
-
-	USED(m64);
-	USED(p);
-
-	rex &= (0x40 | Rxr);
-	v = a->offset;
-	rel.siz = 0;
-
-	switch(a->type) {
-	case TYPE_ADDR:
-		if(a->name == NAME_NONE)
-			ctxt->diag("unexpected TYPE_ADDR with NAME_NONE");
-		if(a->index == REG_TLS)
-			ctxt->diag("unexpected TYPE_ADDR with index==REG_TLS");
-		goto bad;
-	
-	case TYPE_REG:
-		if(a->reg < REG_AL || REG_X0+15 < a->reg)
-			goto bad;
-		if(v)
-			goto bad;
-		*ctxt->andptr++ = (3 << 6) | (reg[a->reg] << 0) | (r << 3);
-		ctxt->rexflag |= (regrex[a->reg] & (0x40 | Rxb)) | rex;
-		return;
-	}
-
-	if(a->type != TYPE_MEM)
-		goto bad;
-
-	if(a->index != REG_NONE && a->index != REG_TLS) {
-		base = a->reg;
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			if(!isextern(a->sym))
-				goto bad;
-			base = REG_NONE;
-			v = vaddr(ctxt, p, a, &rel);
-			break;
-		case NAME_AUTO:
-		case NAME_PARAM:
-			base = REG_SP;
-			break;
-		}
-		
-		ctxt->rexflag |= (regrex[(int)a->index] & Rxx) | (regrex[base] & Rxb) | rex;
-		if(base == REG_NONE) {
-			*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			goto putrelv;
-		}
-		if(v == 0 && rel.siz == 0 && base != REG_BP && base != REG_R13) {
-			*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			return;
-		}
-		if(v >= -128 && v < 128 && rel.siz == 0) {
-			*ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			*ctxt->andptr++ = v;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
-		asmidx(ctxt, a->scale, a->index, base);
-		goto putrelv;
-	}
-
-	base = a->reg;
-	switch(a->name) {
-	case NAME_STATIC:
-	case NAME_EXTERN:
-		if(a->sym == nil)
-			ctxt->diag("bad addr: %P", p);
-		base = REG_NONE;
-		v = vaddr(ctxt, p, a, &rel);
-		break;
-	case NAME_AUTO:
-	case NAME_PARAM:
-		base = REG_SP;
-		break;
-	}
-
-	if(base == REG_TLS)
-		v = vaddr(ctxt, p, a, &rel);
-	
-	ctxt->rexflag |= (regrex[base] & Rxb) | rex;
-	if(base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS) {
-		if((a->sym == nil || !isextern(a->sym)) && base == REG_NONE && (a->name == NAME_STATIC || a->name == NAME_EXTERN) || ctxt->asmode != 64) {
-			*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
-			goto putrelv;
-		}
-		/* temporary */
-		*ctxt->andptr++ = (0 <<  6) | (4 << 0) | (r << 3);	/* sib present */
-		*ctxt->andptr++ = (0 << 6) | (4 << 3) | (5 << 0);	/* DS:d32 */
-		goto putrelv;
-	}
-
-	if(base == REG_SP || base == REG_R12) {
-		if(v == 0) {
-			*ctxt->andptr++ = (0 << 6) | (reg[base] << 0) | (r << 3);
-			asmidx(ctxt, a->scale, REG_NONE, base);
-			return;
-		}
-		if(v >= -128 && v < 128) {
-			*ctxt->andptr++ = (1 << 6) | (reg[base] << 0) | (r << 3);
-			asmidx(ctxt, a->scale, REG_NONE, base);
-			*ctxt->andptr++ = v;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (reg[base] << 0) | (r << 3);
-		asmidx(ctxt, a->scale, REG_NONE, base);
-		goto putrelv;
-	}
-
-	if(REG_AX <= base && base <= REG_R15) {
-		if(a->index == REG_TLS) {
-			memset(&rel, 0, sizeof rel);
-			rel.type = R_TLS_IE;
-			rel.siz = 4;
-			rel.sym = nil;
-			rel.add = v;
-			v = 0;
-		}
-		if(v == 0 && rel.siz == 0 && base != REG_BP && base != REG_R13) {
-			*ctxt->andptr++ = (0 << 6) | (reg[base] << 0) | (r << 3);
-			return;
-		}
-		if(v >= -128 && v < 128 && rel.siz == 0) {
-			ctxt->andptr[0] = (1 << 6) | (reg[base] << 0) | (r << 3);
-			ctxt->andptr[1] = v;
-			ctxt->andptr += 2;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (reg[base] << 0) | (r << 3);
-		goto putrelv;
-	}
-
-	goto bad;
-	
-putrelv:
-	if(rel.siz != 0) {
-		Reloc *r;
-
-		if(rel.siz != 4) {
-			ctxt->diag("bad rel");
-			goto bad;
-		}
-		r = addrel(ctxt->cursym);
-		*r = rel;
-		r->off = ctxt->curp->pc + ctxt->andptr - ctxt->and;
-	}
-		
-	put4(ctxt, v);
-	return;
-
-bad:
-	ctxt->diag("asmand: bad address %D", a);
-	return;
-}
-
-static void
-asmand(Link *ctxt, Prog *p, Addr *a, Addr *ra)
-{
-	asmandsz(ctxt, p, a, reg[ra->reg], regrex[ra->reg], 0);
-}
-
-static void
-asmando(Link *ctxt, Prog *p, Addr *a, int o)
-{
-	asmandsz(ctxt, p, a, o, 0, 0);
-}
-
-static void
-bytereg(Addr *a, uint8 *t)
-{
-	if(a->type == TYPE_REG && a->index == REG_NONE && (REG_AX <= a->reg && a->reg <= REG_R15)) {
-		a->reg += REG_AL - REG_AX;
-		*t = 0;
-	}
-}
-
-enum {
-	E = 0xff,
-};
-static Movtab	ymovtab[] =
-{
-/* push */
-	{APUSHL,	Ycs,	Ynone,	0,	{0x0e,E,0,0}},
-	{APUSHL,	Yss,	Ynone,	0,	{0x16,E,0,0}},
-	{APUSHL,	Yds,	Ynone,	0,	{0x1e,E,0,0}},
-	{APUSHL,	Yes,	Ynone,	0,	{0x06,E,0,0}},
-	{APUSHL,	Yfs,	Ynone,	0,	{0x0f,0xa0,E,0}},
-	{APUSHL,	Ygs,	Ynone,	0,	{0x0f,0xa8,E,0}},
-	{APUSHQ,	Yfs,	Ynone,	0,	{0x0f,0xa0,E,0}},
-	{APUSHQ,	Ygs,	Ynone,	0,	{0x0f,0xa8,E,0}},
-
-	{APUSHW,	Ycs,	Ynone,	0,	{Pe,0x0e,E,0}},
-	{APUSHW,	Yss,	Ynone,	0,	{Pe,0x16,E,0}},
-	{APUSHW,	Yds,	Ynone,	0,	{Pe,0x1e,E,0}},
-	{APUSHW,	Yes,	Ynone,	0,	{Pe,0x06,E,0}},
-	{APUSHW,	Yfs,	Ynone,	0,	{Pe,0x0f,0xa0,E}},
-	{APUSHW,	Ygs,	Ynone,	0,	{Pe,0x0f,0xa8,E}},
-
-/* pop */
-	{APOPL,	Ynone,	Yds,	0,	{0x1f,E,0,0}},
-	{APOPL,	Ynone,	Yes,	0,	{0x07,E,0,0}},
-	{APOPL,	Ynone,	Yss,	0,	{0x17,E,0,0}},
-	{APOPL,	Ynone,	Yfs,	0,	{0x0f,0xa1,E,0}},
-	{APOPL,	Ynone,	Ygs,	0,	{0x0f,0xa9,E,0}},
-	{APOPQ,	Ynone,	Yfs,	0,	{0x0f,0xa1,E,0}},
-	{APOPQ,	Ynone,	Ygs,	0,	{0x0f,0xa9,E,0}},
-
-	{APOPW,	Ynone,	Yds,	0,	{Pe,0x1f,E,0}},
-	{APOPW,	Ynone,	Yes,	0,	{Pe,0x07,E,0}},
-	{APOPW,	Ynone,	Yss,	0,	{Pe,0x17,E,0}},
-	{APOPW,	Ynone,	Yfs,	0,	{Pe,0x0f,0xa1,E}},
-	{APOPW,	Ynone,	Ygs,	0,	{Pe,0x0f,0xa9,E}},
-
-/* mov seg */
-	{AMOVW,	Yes,	Yml,	1,	{0x8c,0,0,0}},
-	{AMOVW,	Ycs,	Yml,	1,	{0x8c,1,0,0}},
-	{AMOVW,	Yss,	Yml,	1,	{0x8c,2,0,0}},
-	{AMOVW,	Yds,	Yml,	1,	{0x8c,3,0,0}},
-	{AMOVW,	Yfs,	Yml,	1,	{0x8c,4,0,0}},
-	{AMOVW,	Ygs,	Yml,	1,	{0x8c,5,0,0}},
-
-	{AMOVW,	Yml,	Yes,	2,	{0x8e,0,0,0}},
-	{AMOVW,	Yml,	Ycs,	2,	{0x8e,1,0,0}},
-	{AMOVW,	Yml,	Yss,	2,	{0x8e,2,0,0}},
-	{AMOVW,	Yml,	Yds,	2,	{0x8e,3,0,0}},
-	{AMOVW,	Yml,	Yfs,	2,	{0x8e,4,0,0}},
-	{AMOVW,	Yml,	Ygs,	2,	{0x8e,5,0,0}},
-
-/* mov cr */
-	{AMOVL,	Ycr0,	Yml,	3,	{0x0f,0x20,0,0}},
-	{AMOVL,	Ycr2,	Yml,	3,	{0x0f,0x20,2,0}},
-	{AMOVL,	Ycr3,	Yml,	3,	{0x0f,0x20,3,0}},
-	{AMOVL,	Ycr4,	Yml,	3,	{0x0f,0x20,4,0}},
-	{AMOVL,	Ycr8,	Yml,	3,	{0x0f,0x20,8,0}},
-	{AMOVQ,	Ycr0,	Yml,	3,	{0x0f,0x20,0,0}},
-	{AMOVQ,	Ycr2,	Yml,	3,	{0x0f,0x20,2,0}},
-	{AMOVQ,	Ycr3,	Yml,	3,	{0x0f,0x20,3,0}},
-	{AMOVQ,	Ycr4,	Yml,	3,	{0x0f,0x20,4,0}},
-	{AMOVQ,	Ycr8,	Yml,	3,	{0x0f,0x20,8,0}},
-
-	{AMOVL,	Yml,	Ycr0,	4,	{0x0f,0x22,0,0}},
-	{AMOVL,	Yml,	Ycr2,	4,	{0x0f,0x22,2,0}},
-	{AMOVL,	Yml,	Ycr3,	4,	{0x0f,0x22,3,0}},
-	{AMOVL,	Yml,	Ycr4,	4,	{0x0f,0x22,4,0}},
-	{AMOVL,	Yml,	Ycr8,	4,	{0x0f,0x22,8,0}},
-	{AMOVQ,	Yml,	Ycr0,	4,	{0x0f,0x22,0,0}},
-	{AMOVQ,	Yml,	Ycr2,	4,	{0x0f,0x22,2,0}},
-	{AMOVQ,	Yml,	Ycr3,	4,	{0x0f,0x22,3,0}},
-	{AMOVQ,	Yml,	Ycr4,	4,	{0x0f,0x22,4,0}},
-	{AMOVQ,	Yml,	Ycr8,	4,	{0x0f,0x22,8,0}},
-
-/* mov dr */
-	{AMOVL,	Ydr0,	Yml,	3,	{0x0f,0x21,0,0}},
-	{AMOVL,	Ydr6,	Yml,	3,	{0x0f,0x21,6,0}},
-	{AMOVL,	Ydr7,	Yml,	3,	{0x0f,0x21,7,0}},
-	{AMOVQ,	Ydr0,	Yml,	3,	{0x0f,0x21,0,0}},
-	{AMOVQ,	Ydr6,	Yml,	3,	{0x0f,0x21,6,0}},
-	{AMOVQ,	Ydr7,	Yml,	3,	{0x0f,0x21,7,0}},
-
-	{AMOVL,	Yml,	Ydr0,	4,	{0x0f,0x23,0,0}},
-	{AMOVL,	Yml,	Ydr6,	4,	{0x0f,0x23,6,0}},
-	{AMOVL,	Yml,	Ydr7,	4,	{0x0f,0x23,7,0}},
-	{AMOVQ,	Yml,	Ydr0,	4,	{0x0f,0x23,0,0}},
-	{AMOVQ,	Yml,	Ydr6,	4,	{0x0f,0x23,6,0}},
-	{AMOVQ,	Yml,	Ydr7,	4,	{0x0f,0x23,7,0}},
-
-/* mov tr */
-	{AMOVL,	Ytr6,	Yml,	3,	{0x0f,0x24,6,0}},
-	{AMOVL,	Ytr7,	Yml,	3,	{0x0f,0x24,7,0}},
-
-	{AMOVL,	Yml,	Ytr6,	4,	{0x0f,0x26,6,E}},
-	{AMOVL,	Yml,	Ytr7,	4,	{0x0f,0x26,7,E}},
-
-/* lgdt, sgdt, lidt, sidt */
-	{AMOVL,	Ym,	Ygdtr,	4,	{0x0f,0x01,2,0}},
-	{AMOVL,	Ygdtr,	Ym,	3,	{0x0f,0x01,0,0}},
-	{AMOVL,	Ym,	Yidtr,	4,	{0x0f,0x01,3,0}},
-	{AMOVL,	Yidtr,	Ym,	3,	{0x0f,0x01,1,0}},
-	{AMOVQ,	Ym,	Ygdtr,	4,	{0x0f,0x01,2,0}},
-	{AMOVQ,	Ygdtr,	Ym,	3,	{0x0f,0x01,0,0}},
-	{AMOVQ,	Ym,	Yidtr,	4,	{0x0f,0x01,3,0}},
-	{AMOVQ,	Yidtr,	Ym,	3,	{0x0f,0x01,1,0}},
-
-/* lldt, sldt */
-	{AMOVW,	Yml,	Yldtr,	4,	{0x0f,0x00,2,0}},
-	{AMOVW,	Yldtr,	Yml,	3,	{0x0f,0x00,0,0}},
-
-/* lmsw, smsw */
-	{AMOVW,	Yml,	Ymsw,	4,	{0x0f,0x01,6,0}},
-	{AMOVW,	Ymsw,	Yml,	3,	{0x0f,0x01,4,0}},
-
-/* ltr, str */
-	{AMOVW,	Yml,	Ytask,	4,	{0x0f,0x00,3,0}},
-	{AMOVW,	Ytask,	Yml,	3,	{0x0f,0x00,1,0}},
-
-/* load full pointer */
-	{AMOVL,	Yml,	Ycol,	5,	{0,0,0,0}},
-	{AMOVW,	Yml,	Ycol,	5,	{Pe,0,0,0}},
-
-/* double shift */
-	{ASHLL,	Ycol,	Yml,	6,	{0xa4,0xa5,0,0}},
-	{ASHRL,	Ycol,	Yml,	6,	{0xac,0xad,0,0}},
-	{ASHLQ,	Ycol,	Yml,	6,	{Pw,0xa4,0xa5,0}},
-	{ASHRQ,	Ycol,	Yml,	6,	{Pw,0xac,0xad,0}},
-	{ASHLW,	Ycol,	Yml,	6,	{Pe,0xa4,0xa5,0}},
-	{ASHRW,	Ycol,	Yml,	6,	{Pe,0xac,0xad,0}},
-
-/* load TLS base */
-	{AMOVQ,	Ytls,	Yrl,	7,	{0,0,0,0}},
-
-	{0}
-};
-
-static int
-isax(Addr *a)
-{
-	switch(a->reg) {
-	case REG_AX:
-	case REG_AL:
-	case REG_AH:
-		return 1;
-	}
-	if(a->index == REG_AX)
-		return 1;
-	return 0;
-}
-
-static void
-subreg(Prog *p, int from, int to)
-{
-	if(0 /* debug['Q'] */)
-		print("\n%P	s/%R/%R/\n", p, from, to);
-
-	if(p->from.reg == from) {
-		p->from.reg = to;
-		p->ft = 0;
-	}
-	if(p->to.reg == from) {
-		p->to.reg = to;
-		p->tt = 0;
-	}
-
-	if(p->from.index == from) {
-		p->from.index = to;
-		p->ft = 0;
-	}
-	if(p->to.index == from) {
-		p->to.index = to;
-		p->tt = 0;
-	}
-
-	if(0 /* debug['Q'] */)
-		print("%P\n", p);
-}
-
-static int
-mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
-{
-	switch(op){
-	case Pm:
-	case Pe:
-	case Pf2:
-	case Pf3:
-		if(osize != 1){
-			if(op != Pm)
-				*ctxt->andptr++ = op;
-			*ctxt->andptr++ = Pm;
-			op = o->op[++z];
-			break;
-		}
-	default:
-		if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
-			*ctxt->andptr++ = Pm;
-		break;
-	}
-	*ctxt->andptr++ = op;
-	return z;
-}
-
-static void
-doasm(Link *ctxt, Prog *p)
-{
-	Optab *o;
-	Prog *q, pp;
-	uchar *t;
-	Movtab *mo;
-	int z, op, ft, tt, xo, l, pre;
-	vlong v;
-	Reloc rel, *r;
-	Addr *a;
-	
-	ctxt->curp = p;	// TODO
-
-	o = opindex[p->as];
-	if(o == nil) {
-		ctxt->diag("asmins: missing op %P", p);
-		return;
-	}
-
-	pre = prefixof(ctxt, &p->from);
-	if(pre)
-		*ctxt->andptr++ = pre;
-	pre = prefixof(ctxt, &p->to);
-	if(pre)
-		*ctxt->andptr++ = pre;
-
-	if(p->ft == 0)
-		p->ft = oclass(ctxt, p, &p->from);
-	if(p->tt == 0)
-		p->tt = oclass(ctxt, p, &p->to);
-
-	ft = p->ft * Ymax;
-	tt = p->tt * Ymax;
-
-	t = o->ytab;
-	if(t == 0) {
-		ctxt->diag("asmins: noproto %P", p);
-		return;
-	}
-	xo = o->op[0] == 0x0f;
-	for(z=0; *t; z+=t[3]+xo,t+=4)
-		if(ycover[ft+t[0]])
-		if(ycover[tt+t[1]])
-			goto found;
-	goto domov;
-
-found:
-	switch(o->prefix) {
-	case Pq:	/* 16 bit escape and opcode escape */
-		*ctxt->andptr++ = Pe;
-		*ctxt->andptr++ = Pm;
-		break;
-	case Pq3:	/* 16 bit escape, Rex.w, and opcode escape */
-		*ctxt->andptr++ = Pe;
-		*ctxt->andptr++ = Pw;
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pf2:	/* xmm opcode escape */
-	case Pf3:
-		*ctxt->andptr++ = o->prefix;
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pm:	/* opcode escape */
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pe:	/* 16 bit escape */
-		*ctxt->andptr++ = Pe;
-		break;
-
-	case Pw:	/* 64-bit escape */
-		if(p->mode != 64)
-			ctxt->diag("asmins: illegal 64: %P", p);
-		ctxt->rexflag |= Pw;
-		break;
-
-	case Pb:	/* botch */
-		bytereg(&p->from, &p->ft);
-		bytereg(&p->to, &p->tt);
-		break;
-
-	case P32:	/* 32 bit but illegal if 64-bit mode */
-		if(p->mode == 64)
-			ctxt->diag("asmins: illegal in 64-bit mode: %P", p);
-		break;
-
-	case Py:	/* 64-bit only, no prefix */
-		if(p->mode != 64)
-			ctxt->diag("asmins: illegal in %d-bit mode: %P", p->mode, p);
-		break;
-	}
-
-	if(z >= nelem(o->op))
-		sysfatal("asmins bad table %P", p);
-	op = o->op[z];
-	if(op == 0x0f) {
-		*ctxt->andptr++ = op;
-		op = o->op[++z];
-	}
-	switch(t[2]) {
-	default:
-		ctxt->diag("asmins: unknown z %d %P", t[2], p);
-		return;
-
-	case Zpseudo:
-		break;
-
-	case Zlit:
-		for(; op = o->op[z]; z++)
-			*ctxt->andptr++ = op;
-		break;
-
-	case Zlitm_r:
-		for(; op = o->op[z]; z++)
-			*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-
-	case Zmb_r:
-		bytereg(&p->from, &p->ft);
-		/* fall through */
-	case Zm_r:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-	case Zm2_r:
-		*ctxt->andptr++ = op;
-		*ctxt->andptr++ = o->op[z+1];
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-
-	case Zm_r_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-
-	case Zm_r_xm_nr:
-		ctxt->rexflag = 0;
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-
-	case Zm_r_i_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->from, &p->to);
-		*ctxt->andptr++ = p->to.offset;
-		break;
-
-	case Zm_r_3d:
-		*ctxt->andptr++ = 0x0f;
-		*ctxt->andptr++ = 0x0f;
-		asmand(ctxt, p, &p->from, &p->to);
-		*ctxt->andptr++ = op;
-		break;
-
-	case Zibm_r:
-		while ((op = o->op[z++]) != 0)
-			*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, &p->to);
-		*ctxt->andptr++ = p->to.offset;
-		break;
-
-	case Zaut_r:
-		*ctxt->andptr++ = 0x8d;	/* leal */
-		if(p->from.type != TYPE_ADDR)
-			ctxt->diag("asmins: Zaut sb type ADDR");
-		p->from.type = TYPE_MEM;
-		asmand(ctxt, p, &p->from, &p->to);
-		p->from.type = TYPE_ADDR;
-		break;
-
-	case Zm_o:
-		*ctxt->andptr++ = op;
-		asmando(ctxt, p, &p->from, o->op[z+1]);
-		break;
-
-	case Zr_m:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, &p->from);
-		break;
-
-	case Zr_m_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->to, &p->from);
-		break;
-
-	case Zr_m_xm_nr:
-		ctxt->rexflag = 0;
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->to, &p->from);
-		break;
-
-	case Zr_m_i_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->to, &p->from);
-		*ctxt->andptr++ = p->from.offset;
-		break;
-
-	case Zo_m:
-		*ctxt->andptr++ = op;
-		asmando(ctxt, p, &p->to, o->op[z+1]);
-		break;
-
-	case Zcallindreg:
-		r = addrel(ctxt->cursym);
-		r->off = p->pc;
-		r->type = R_CALLIND;
-		r->siz = 0;
-		// fallthrough
-	case Zo_m64:
-		*ctxt->andptr++ = op;
-		asmandsz(ctxt, p, &p->to, o->op[z+1], 0, 1);
-		break;
-
-	case Zm_ibo:
-		*ctxt->andptr++ = op;
-		asmando(ctxt, p, &p->from, o->op[z+1]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->to, nil);
-		break;
-
-	case Zibo_m:
-		*ctxt->andptr++ = op;
-		asmando(ctxt, p, &p->to, o->op[z+1]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Zibo_m_xm:
-		z = mediaop(ctxt, o, op, t[3], z);
-		asmando(ctxt, p, &p->to, o->op[z+1]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Z_ib:
-	case Zib_:
-		if(t[2] == Zib_)
-			a = &p->from;
-		else
-			a = &p->to;
-		*ctxt->andptr++ = op;
-		*ctxt->andptr++ = vaddr(ctxt, p, a, nil);
-		break;
-
-	case Zib_rp:
-		ctxt->rexflag |= regrex[p->to.reg] & (Rxb|0x40);
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Zil_rp:
-		ctxt->rexflag |= regrex[p->to.reg] & Rxb;
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, &p->from, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, &p->from);
-		break;
-
-	case Zo_iw:
-		*ctxt->andptr++ = op;
-		if(p->from.type != TYPE_NONE){
-			v = vaddr(ctxt, p, &p->from, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		break;
-
-	case Ziq_rp:
-		v = vaddr(ctxt, p, &p->from, &rel);
-		l = v>>32;
-		if(l == 0 && rel.siz != 8){
-			//p->mark |= 0100;
-			//print("zero: %llux %P\n", v, p);
-			ctxt->rexflag &= ~(0x40|Rxw);
-			ctxt->rexflag |= regrex[p->to.reg] & Rxb;
-			*ctxt->andptr++ = 0xb8 + reg[p->to.reg];
-			if(rel.type != 0) {
-				r = addrel(ctxt->cursym);
-				*r = rel;
-				r->off = p->pc + ctxt->andptr - ctxt->and;
-			}
-			put4(ctxt, v);
-		}else if(l == -1 && (v&((uvlong)1<<31))!=0){	/* sign extend */
-			//p->mark |= 0100;
-			//print("sign: %llux %P\n", v, p);
-			*ctxt->andptr ++ = 0xc7;
-			asmando(ctxt, p, &p->to, 0);
-			put4(ctxt, v);
-		}else{	/* need all 8 */
-			//print("all: %llux %P\n", v, p);
-			ctxt->rexflag |= regrex[p->to.reg] & Rxb;
-			*ctxt->andptr++ = op + reg[p->to.reg];
-			if(rel.type != 0) {
-				r = addrel(ctxt->cursym);
-				*r = rel;
-				r->off = p->pc + ctxt->andptr - ctxt->and;
-			}
-			put8(ctxt, v);
-		}
-		break;
-
-	case Zib_rr:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, &p->to);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Z_il:
-	case Zil_:
-		if(t[2] == Zil_)
-			a = &p->from;
-		else
-			a = &p->to;
-		*ctxt->andptr++ = op;
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, a, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, a);
-		break;
-
-	case Zm_ilo:
-	case Zilo_m:
-		*ctxt->andptr++ = op;
-		if(t[2] == Zilo_m) {
-			a = &p->from;
-			asmando(ctxt, p, &p->to, o->op[z+1]);
-		} else {
-			a = &p->to;
-			asmando(ctxt, p, &p->from, o->op[z+1]);
-		}
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, a, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, a);
-		break;
-
-	case Zil_rr:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, &p->to);
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, &p->from, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, &p->from);
-		break;
-
-	case Z_rp:
-		ctxt->rexflag |= regrex[p->to.reg] & (Rxb|0x40);
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		break;
-
-	case Zrp_:
-		ctxt->rexflag |= regrex[p->from.reg] & (Rxb|0x40);
-		*ctxt->andptr++ = op + reg[p->from.reg];
-		break;
-
-	case Zclr:
-		ctxt->rexflag &= ~Pw;
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, &p->to);
-		break;
-
-	case Zcall:
-		if(p->to.sym == nil) {
-			ctxt->diag("call without target");
-			sysfatal("bad code");
-		}
-		*ctxt->andptr++ = op;
-		r = addrel(ctxt->cursym);
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-		r->sym = p->to.sym;
-		r->add = p->to.offset;
-		r->type = R_CALL;
-		r->siz = 4;
-		put4(ctxt, 0);
-		break;
-
-	case Zbr:
-	case Zjmp:
-	case Zloop:
-		// TODO: jump across functions needs reloc
-		if(p->to.sym != nil) {
-			if(t[2] != Zjmp) {
-				ctxt->diag("branch to ATEXT");
-				sysfatal("bad code");
-			}
-			*ctxt->andptr++ = o->op[z+1];
-			r = addrel(ctxt->cursym);
-			r->off = p->pc + ctxt->andptr - ctxt->and;
-			r->sym = p->to.sym;
-			r->type = R_PCREL;
-			r->siz = 4;
-			put4(ctxt, 0);
-			break;
-		}
-		// Assumes q is in this function.
-		// TODO: Check in input, preserve in brchain.
-
-		// Fill in backward jump now.
-		q = p->pcond;
-		if(q == nil) {
-			ctxt->diag("jmp/branch/loop without target");
-			sysfatal("bad code");
-		}
-		if(p->back & 1) {
-			v = q->pc - (p->pc + 2);
-			if(v >= -128) {
-				if(p->as == AJCXZL)
-					*ctxt->andptr++ = 0x67;
-				*ctxt->andptr++ = op;
-				*ctxt->andptr++ = v;
-			} else if(t[2] == Zloop) {
-				ctxt->diag("loop too far: %P", p);
-			} else {
-				v -= 5-2;
-				if(t[2] == Zbr) {
-					*ctxt->andptr++ = 0x0f;
-					v--;
-				}
-				*ctxt->andptr++ = o->op[z+1];
-				*ctxt->andptr++ = v;
-				*ctxt->andptr++ = v>>8;
-				*ctxt->andptr++ = v>>16;
-				*ctxt->andptr++ = v>>24;
-			}
-			break;
-		}
-		
-		// Annotate target; will fill in later.
-		p->forwd = q->comefrom;
-		q->comefrom = p;
-		if(p->back & 2)	{ // short
-			if(p->as == AJCXZL)
-				*ctxt->andptr++ = 0x67;
-			*ctxt->andptr++ = op;
-			*ctxt->andptr++ = 0;
-		} else if(t[2] == Zloop) {
-			ctxt->diag("loop too far: %P", p);
-		} else {
-			if(t[2] == Zbr)
-				*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = o->op[z+1];
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-		}
-		break;
-				
-/*
-		v = q->pc - p->pc - 2;
-		if((v >= -128 && v <= 127) || p->pc == -1 || q->pc == -1) {
-			*ctxt->andptr++ = op;
-			*ctxt->andptr++ = v;
-		} else {
-			v -= 5-2;
-			if(t[2] == Zbr) {
-				*ctxt->andptr++ = 0x0f;
-				v--;
-			}
-			*ctxt->andptr++ = o->op[z+1];
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-			*ctxt->andptr++ = v>>16;
-			*ctxt->andptr++ = v>>24;
-		}
-*/
-		break;
-
-	case Zbyte:
-		v = vaddr(ctxt, p, &p->from, &rel);
-		if(rel.siz != 0) {
-			rel.siz = op;
-			r = addrel(ctxt->cursym);
-			*r = rel;
-			r->off = p->pc + ctxt->andptr - ctxt->and;
-		}
-		*ctxt->andptr++ = v;
-		if(op > 1) {
-			*ctxt->andptr++ = v>>8;
-			if(op > 2) {
-				*ctxt->andptr++ = v>>16;
-				*ctxt->andptr++ = v>>24;
-				if(op > 4) {
-					*ctxt->andptr++ = v>>32;
-					*ctxt->andptr++ = v>>40;
-					*ctxt->andptr++ = v>>48;
-					*ctxt->andptr++ = v>>56;
-				}
-			}
-		}
-		break;
-	}
-	return;
-
-domov:
-	for(mo=ymovtab; mo->as; mo++)
-		if(p->as == mo->as)
-		if(ycover[ft+mo->ft])
-		if(ycover[tt+mo->tt]){
-			t = mo->op;
-			goto mfound;
-		}
-bad:
-	if(p->mode != 64){
-		/*
-		 * here, the assembly has failed.
-		 * if its a byte instruction that has
-		 * unaddressable registers, try to
-		 * exchange registers and reissue the
-		 * instruction with the operands renamed.
-		 */
-		pp = *p;
-		z = p->from.reg;
-		if(p->from.type == TYPE_REG && z >= REG_BP && z <= REG_DI) {
-			if(isax(&p->to) || p->to.type == TYPE_NONE) {
-				// We certainly don't want to exchange
-				// with AX if the op is MUL or DIV.
-				*ctxt->andptr++ = 0x87;			/* xchg lhs,bx */
-				asmando(ctxt, p, &p->from, reg[REG_BX]);
-				subreg(&pp, z, REG_BX);
-				doasm(ctxt, &pp);
-				*ctxt->andptr++ = 0x87;			/* xchg lhs,bx */
-				asmando(ctxt, p, &p->from, reg[REG_BX]);
-			} else {
-				*ctxt->andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
-				subreg(&pp, z, REG_AX);
-				doasm(ctxt, &pp);
-				*ctxt->andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
-			}
-			return;
-		}
-		z = p->to.reg;
-		if(p->to.type == TYPE_REG && z >= REG_BP && z <= REG_DI) {
-			if(isax(&p->from)) {
-				*ctxt->andptr++ = 0x87;			/* xchg rhs,bx */
-				asmando(ctxt, p, &p->to, reg[REG_BX]);
-				subreg(&pp, z, REG_BX);
-				doasm(ctxt, &pp);
-				*ctxt->andptr++ = 0x87;			/* xchg rhs,bx */
-				asmando(ctxt, p, &p->to, reg[REG_BX]);
-			} else {
-				*ctxt->andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
-				subreg(&pp, z, REG_AX);
-				doasm(ctxt, &pp);
-				*ctxt->andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
-			}
-			return;
-		}
-	}
-	ctxt->diag("doasm: notfound ft=%d tt=%d %P %d %d", p->ft, p->tt, p, oclass(ctxt, p, &p->from), oclass(ctxt, p, &p->to));
-	return;
-
-mfound:
-	switch(mo->code) {
-	default:
-		ctxt->diag("asmins: unknown mov %d %P", mo->code, p);
-		break;
-
-	case 0:	/* lit */
-		for(z=0; t[z]!=E; z++)
-			*ctxt->andptr++ = t[z];
-		break;
-
-	case 1:	/* r,m */
-		*ctxt->andptr++ = t[0];
-		asmando(ctxt, p, &p->to, t[1]);
-		break;
-
-	case 2:	/* m,r */
-		*ctxt->andptr++ = t[0];
-		asmando(ctxt, p, &p->from, t[1]);
-		break;
-
-	case 3:	/* r,m - 2op */
-		*ctxt->andptr++ = t[0];
-		*ctxt->andptr++ = t[1];
-		asmando(ctxt, p, &p->to, t[2]);
-		ctxt->rexflag |= regrex[p->from.reg] & (Rxr|0x40);
-		break;
-
-	case 4:	/* m,r - 2op */
-		*ctxt->andptr++ = t[0];
-		*ctxt->andptr++ = t[1];
-		asmando(ctxt, p, &p->from, t[2]);
-		ctxt->rexflag |= regrex[p->to.reg] & (Rxr|0x40);
-		break;
-
-	case 5:	/* load full pointer, trash heap */
-		if(t[0])
-			*ctxt->andptr++ = t[0];
-		switch(p->to.index) {
-		default:
-			goto bad;
-		case REG_DS:
-			*ctxt->andptr++ = 0xc5;
-			break;
-		case REG_SS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb2;
-			break;
-		case REG_ES:
-			*ctxt->andptr++ = 0xc4;
-			break;
-		case REG_FS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb4;
-			break;
-		case REG_GS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb5;
-			break;
-		}
-		asmand(ctxt, p, &p->from, &p->to);
-		break;
-
-	case 6:	/* double shift */
-		if(t[0] == Pw){
-			if(p->mode != 64)
-				ctxt->diag("asmins: illegal 64: %P", p);
-			ctxt->rexflag |= Pw;
-			t++;
-		}else if(t[0] == Pe){
-			*ctxt->andptr++ = Pe;
-			t++;
-		}
-		switch(p->from.type) {
-		default:
-			goto bad;
-		case TYPE_CONST:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = t[0];
-			asmandsz(ctxt, p, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
-			*ctxt->andptr++ = p->from.offset;
-			break;
-		case TYPE_REG:
-			switch(p->from.reg) {
-			default:
-				goto bad;
-			case REG_CL:
-			case REG_CX:
-				*ctxt->andptr++ = 0x0f;
-				*ctxt->andptr++ = t[1];
-				asmandsz(ctxt, p, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
-				break;
-			}
-		}
-		break;
-	
-	case 7:	/* mov tls, r */
-		// NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
-		// where you load the TLS base register into a register and then index off that
-		// register to access the actual TLS variables. Systems that allow direct TLS access
-		// are handled in prefixof above and should not be listed here.
-		switch(ctxt->headtype) {
-		default:
-			sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
-
-		case Hplan9:
-			if(ctxt->plan9privates == nil)
-				ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
-			memset(&pp.from, 0, sizeof pp.from);
-			pp.from.type = TYPE_MEM;
-			pp.from.name = NAME_EXTERN;
-			pp.from.sym = ctxt->plan9privates;
-			pp.from.offset = 0;
-			pp.from.index = REG_NONE;
-			ctxt->rexflag |= Pw;
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, &p->to);
-			break;
-
-		case Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c.
-			// TLS base is 0(FS).
-			pp.from = p->from;
-			pp.from.type = TYPE_MEM;
-			pp.from.name = NAME_NONE;
-			pp.from.reg = REG_NONE;
-			pp.from.offset = 0;
-			pp.from.index = REG_NONE;
-			pp.from.scale = 0;
-			ctxt->rexflag |= Pw;
-			*ctxt->andptr++ = 0x64; // FS
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, &p->to);
-			break;
-		
-		case Hwindows:
-			// Windows TLS base is always 0x28(GS).
-			pp.from = p->from;
-			pp.from.type = TYPE_MEM;
-			pp.from.name = NAME_NONE;
-			pp.from.reg = REG_GS;
-			pp.from.offset = 0x28;
-			pp.from.index = REG_NONE;
-			pp.from.scale = 0;
-			ctxt->rexflag |= Pw;
-			*ctxt->andptr++ = 0x65; // GS
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, &p->to);
-			break;
-		}
-		break;
-	}
-}
-
-static uchar naclret[] = {
-	0x5e, // POPL SI
-	// 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging
-	0x83, 0xe6, 0xe0,	// ANDL $~31, SI
-	0x4c, 0x01, 0xfe,	// ADDQ R15, SI
-	0xff, 0xe6, // JMP SI
-};
-
-static uchar naclspfix[] = {
-	0x4c, 0x01, 0xfc, // ADDQ R15, SP
-};
-
-static uchar naclbpfix[] = {
-	0x4c, 0x01, 0xfd, // ADDQ R15, BP
-};
-
-static uchar naclmovs[] = {
-	0x89, 0xf6,	// MOVL SI, SI
-	0x49, 0x8d, 0x34, 0x37,	// LEAQ (R15)(SI*1), SI
-	0x89, 0xff,	// MOVL DI, DI
-	0x49, 0x8d, 0x3c, 0x3f,	// LEAQ (R15)(DI*1), DI
-};
-
-static uchar naclstos[] = {
-	0x89, 0xff,	// MOVL DI, DI
-	0x49, 0x8d, 0x3c, 0x3f,	// LEAQ (R15)(DI*1), DI
-};
-
-static void
-nacltrunc(Link *ctxt, int reg)
-{	
-	if(reg >= REG_R8)
-		*ctxt->andptr++ = 0x45;
-	reg = (reg - REG_AX) & 7;
-	*ctxt->andptr++ = 0x89;
-	*ctxt->andptr++ = (3<<6) | (reg<<3) | reg;
-}
-
-static void
-asmins(Link *ctxt, Prog *p)
-{
-	int i, n, np, c;
-	uchar *and0;
-	Reloc *r;
-	
-	ctxt->andptr = ctxt->and;
-	ctxt->asmode = p->mode;
-	
-	if(p->as == AUSEFIELD) {
-		r = addrel(ctxt->cursym);
-		r->off = 0;
-		r->siz = 0;
-		r->sym = p->from.sym;
-		r->type = R_USEFIELD;
-		return;
-	}
-	
-	if(ctxt->headtype == Hnacl) {
-		if(p->as == AREP) {
-			ctxt->rep++;
-			return;
-		}
-		if(p->as == AREPN) {
-			ctxt->repn++;
-			return;
-		}
-		if(p->as == ALOCK) {
-			ctxt->lock++;
-			return;
-		}
-		if(p->as != ALEAQ && p->as != ALEAL) {
-			if(p->from.index != TYPE_NONE && p->from.scale > 0)
-				nacltrunc(ctxt, p->from.index);
-			if(p->to.index != TYPE_NONE && p->to.scale > 0)
-				nacltrunc(ctxt, p->to.index);
-		}
-		switch(p->as) {
-		case ARET:
-			memmove(ctxt->andptr, naclret, sizeof naclret);
-			ctxt->andptr += sizeof naclret;
-			return;
-		case ACALL:
-		case AJMP:
-			if(p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
-				// ANDL $~31, reg
-				*ctxt->andptr++ = 0x83;
-				*ctxt->andptr++ = 0xe0 | (p->to.reg - REG_AX);
-				*ctxt->andptr++ = 0xe0;
-				// ADDQ R15, reg
-				*ctxt->andptr++ = 0x4c;
-				*ctxt->andptr++ = 0x01;
-				*ctxt->andptr++ = 0xf8 | (p->to.reg - REG_AX);
-			}
-			if(p->to.type == TYPE_REG && REG_R8 <= p->to.reg && p->to.reg <= REG_R15) {
-				// ANDL $~31, reg
-				*ctxt->andptr++ = 0x41;
-				*ctxt->andptr++ = 0x83;
-				*ctxt->andptr++ = 0xe0 | (p->to.reg - REG_R8);
-				*ctxt->andptr++ = 0xe0;
-				// ADDQ R15, reg
-				*ctxt->andptr++ = 0x4d;
-				*ctxt->andptr++ = 0x01;
-				*ctxt->andptr++ = 0xf8 | (p->to.reg - REG_R8);
-			}
-			break;
-		case AINT:
-			*ctxt->andptr++ = 0xf4;
-			return;
-		case ASCASB:
-		case ASCASW:
-		case ASCASL:
-		case ASCASQ:
-		case ASTOSB:
-		case ASTOSW:
-		case ASTOSL:
-		case ASTOSQ:
-			memmove(ctxt->andptr, naclstos, sizeof naclstos);
-			ctxt->andptr += sizeof naclstos;
-			break;
-		case AMOVSB:
-		case AMOVSW:
-		case AMOVSL:
-		case AMOVSQ:
-			memmove(ctxt->andptr, naclmovs, sizeof naclmovs);
-			ctxt->andptr += sizeof naclmovs;
-			break;
-		}
-		if(ctxt->rep) {
-			*ctxt->andptr++ = 0xf3;
-			ctxt->rep = 0;
-		}
-		if(ctxt->repn) {
-			*ctxt->andptr++ = 0xf2;
-			ctxt->repn = 0;
-		}
-		if(ctxt->lock) {
-			*ctxt->andptr++ = 0xf0;
-			ctxt->lock = 0;
-		}
-	}		
-
-	ctxt->rexflag = 0;
-	and0 = ctxt->andptr;
-	ctxt->asmode = p->mode;
-	doasm(ctxt, p);
-	if(ctxt->rexflag){
-		/*
-		 * as befits the whole approach of the architecture,
-		 * the rex prefix must appear before the first opcode byte
-		 * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but
-		 * before the 0f opcode escape!), or it might be ignored.
-		 * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'.
-		 */
-		if(p->mode != 64)
-			ctxt->diag("asmins: illegal in mode %d: %P", p->mode, p);
-		n = ctxt->andptr - and0;
-		for(np = 0; np < n; np++) {
-			c = and0[np];
-			if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26)
-				break;
-		}
-		memmove(and0+np+1, and0+np, n-np);
-		and0[np] = 0x40 | ctxt->rexflag;
-		ctxt->andptr++;
-	}
-	n = ctxt->andptr - ctxt->and;
-	for(i=ctxt->cursym->nr-1; i>=0; i--) {
-		r = ctxt->cursym->r+i;
-		if(r->off < p->pc)
-			break;
-		if(ctxt->rexflag)
-			r->off++;
-		if(r->type == R_PCREL || r->type == R_CALL)
-			r->add -= p->pc + n - (r->off + r->siz);
-	}
-
-	if(ctxt->headtype == Hnacl && p->as != ACMPL && p->as != ACMPQ && p->to.type == TYPE_REG) {
-		switch(p->to.reg) {
-		case REG_SP:
-			memmove(ctxt->andptr, naclspfix, sizeof naclspfix);
-			ctxt->andptr += sizeof naclspfix;
-			break;
-		case REG_BP:
-			memmove(ctxt->andptr, naclbpfix, sizeof naclbpfix);
-			ctxt->andptr += sizeof naclbpfix;
-			break;
-		}
-	}
-}
diff --git a/src/liblink/asm8.c b/src/liblink/asm8.c
deleted file mode 100644
index ed1e7bc0..0000000
--- a/src/liblink/asm8.c
+++ /dev/null
@@ -1,2822 +0,0 @@
-// Inferno utils/8l/span.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/span.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.
-
-// Instruction layout.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/8l/8.out.h"
-#include "../runtime/stack.h"
-
-enum
-{
-	MaxAlign = 32,	// max data alignment
-	FuncAlign = 16
-};
-
-typedef	struct	Optab	Optab;
-
-struct	Optab
-{
-	short	as;
-	uchar*	ytab;
-	uchar	prefix;
-	uchar	op[13];
-};
-
-static Optab*	opindex[ALAST+1];
-
-enum
-{
-	Yxxx		= 0,
-	Ynone,
-	Yi0,
-	Yi1,
-	Yi8,
-	Yi32,
-	Yiauto,
-	Yal,
-	Ycl,
-	Yax,
-	Ycx,
-	Yrb,
-	Yrl,
-	Yrf,
-	Yf0,
-	Yrx,
-	Ymb,
-	Yml,
-	Ym,
-	Ybr,
-	Ycol,
-	Ytextsize,
-	Ytls,
-
-	Ycs,	Yss,	Yds,	Yes,	Yfs,	Ygs,
-	Ygdtr,	Yidtr,	Yldtr,	Ymsw,	Ytask,
-	Ycr0,	Ycr1,	Ycr2,	Ycr3,	Ycr4,	Ycr5,	Ycr6,	Ycr7,
-	Ydr0,	Ydr1,	Ydr2,	Ydr3,	Ydr4,	Ydr5,	Ydr6,	Ydr7,
-	Ytr0,	Ytr1,	Ytr2,	Ytr3,	Ytr4,	Ytr5,	Ytr6,	Ytr7,
-	Ymr, Ymm,
-	Yxr, Yxm,
-	Ymax,
-
-	Zxxx		= 0,
-
-	Zlit,
-	Zlitm_r,
-	Z_rp,
-	Zbr,
-	Zcall,
-	Zcallcon,
-	Zcallind,
-	Zcallindreg,
-	Zib_,
-	Zib_rp,
-	Zibo_m,
-	Zil_,
-	Zil_rp,
-	Zilo_m,
-	Zjmp,
-	Zjmpcon,
-	Zloop,
-	Zm_o,
-	Zm_r,
-	Zm2_r,
-	Zm_r_xm,
-	Zm_r_i_xm,
-	Zaut_r,
-	Zo_m,
-	Zpseudo,
-	Zr_m,
-	Zr_m_xm,
-	Zr_m_i_xm,
-	Zrp_,
-	Z_ib,
-	Z_il,
-	Zm_ibo,
-	Zm_ilo,
-	Zib_rr,
-	Zil_rr,
-	Zclr,
-	Zibm_r,	/* mmx1,mmx2/mem64,imm8 */
-	Zbyte,
-	Zmov,
-	Zmax,
-
-	Px		= 0,
-	Pe		= 0x66,	/* operand escape */
-	Pm		= 0x0f,	/* 2byte opcode escape */
-	Pq		= 0xff,	/* both escape */
-	Pb		= 0xfe,	/* byte operands */
-	Pf2		= 0xf2,	/* xmm escape 1 */
-	Pf3		= 0xf3,	/* xmm escape 2 */
-};
-
-static	uchar	ycover[Ymax*Ymax];
-static	int	reg[MAXREG];
-static	void	asmins(Link *ctxt, Prog *p);
-
-static uchar	ynone[] =
-{
-	Ynone,	Ynone,	Zlit,	1,
-	0
-};
-static uchar	ytext[] =
-{
-	Ymb,	Ytextsize,	Zpseudo,1,
-	0
-};
-static uchar	ynop[] =
-{
-	Ynone,	Ynone,	Zpseudo,0,
-	Ynone,	Yiauto,	Zpseudo,0,
-	Ynone,	Yml,	Zpseudo,0,
-	Ynone,	Yrf,	Zpseudo,0,
-	Yiauto,	Ynone,	Zpseudo,0,
-	Ynone,	Yxr,	Zpseudo,0,
-	Yml,	Ynone,	Zpseudo,0,
-	Yrf,	Ynone,	Zpseudo,0,
-	Yxr,	Ynone,	Zpseudo,1,
-	0
-};
-static uchar	yfuncdata[] =
-{
-	Yi32,	Ym,	Zpseudo,	0,
-	0
-};
-static uchar	ypcdata[] =
-{
-	Yi32,	Yi32,	Zpseudo,	0,
-	0,
-};
-static uchar	yxorb[] =
-{
-	Yi32,	Yal,	Zib_,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	yxorl[] =
-{
-	Yi8,	Yml,	Zibo_m,	2,
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yaddl[] =
-{
-	Yi8,	Yml,	Zibo_m,	2,
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yincb[] =
-{
-	Ynone,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yincl[] =
-{
-	Ynone,	Yrl,	Z_rp,	1,
-	Ynone,	Yml,	Zo_m,	2,
-	0
-};
-static uchar	ycmpb[] =
-{
-	Yal,	Yi32,	Z_ib,	1,
-	Ymb,	Yi32,	Zm_ibo,	2,
-	Ymb,	Yrb,	Zm_r,	1,
-	Yrb,	Ymb,	Zr_m,	1,
-	0
-};
-static uchar	ycmpl[] =
-{
-	Yml,	Yi8,	Zm_ibo,	2,
-	Yax,	Yi32,	Z_il,	1,
-	Yml,	Yi32,	Zm_ilo,	2,
-	Yml,	Yrl,	Zm_r,	1,
-	Yrl,	Yml,	Zr_m,	1,
-	0
-};
-static uchar	yshb[] =
-{
-	Yi1,	Ymb,	Zo_m,	2,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Ycx,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yshl[] =
-{
-	Yi1,	Yml,	Zo_m,	2,
-	Yi32,	Yml,	Zibo_m,	2,
-	Ycl,	Yml,	Zo_m,	2,
-	Ycx,	Yml,	Zo_m,	2,
-	0
-};
-static uchar	ytestb[] =
-{
-	Yi32,	Yal,	Zib_,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	ytestl[] =
-{
-	Yi32,	Yax,	Zil_,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	ymovb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	Yi32,	Yrb,	Zib_rp,	1,
-	Yi32,	Ymb,	Zibo_m,	2,
-	0
-};
-static uchar	ymovw[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	Yi0,	Yrl,	Zclr,	1+2,
-//	Yi0,	Yml,	Zibo_m,	2,	// shorter but slower AND $0,dst
-	Yi32,	Yrl,	Zil_rp,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yiauto,	Yrl,	Zaut_r,	1,
-	0
-};
-static uchar	ymovl[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	Yi0,	Yrl,	Zclr,	1+2,
-//	Yi0,	Yml,	Zibo_m,	2,	// shorter but slower AND $0,dst
-	Yi32,	Yrl,	Zil_rp,	1,
-	Yi32,	Yml,	Zilo_m,	2,
-	Yml,	Yxr,	Zm_r_xm,	2,	// XMM MOVD (32 bit)
-	Yxr,	Yml,	Zr_m_xm,	2,	// XMM MOVD (32 bit)
-	Yiauto,	Yrl,	Zaut_r,	1,
-	0
-};
-static uchar	ymovq[] =
-{
-	Yml,	Yxr,	Zm_r_xm,	2,
-	0
-};
-static uchar	ym_rl[] =
-{
-	Ym,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yrl_m[] =
-{
-	Yrl,	Ym,	Zr_m,	1,
-	0
-};
-static uchar	ymb_rl[] =
-{
-	Ymb,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yml_rl[] =
-{
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yrb_mb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	0
-};
-static uchar	yrl_ml[] =
-{
-	Yrl,	Yml,	Zr_m,	1,
-	0
-};
-static uchar	yml_mb[] =
-{
-	Yrb,	Ymb,	Zr_m,	1,
-	Ymb,	Yrb,	Zm_r,	1,
-	0
-};
-static uchar	yxchg[] =
-{
-	Yax,	Yrl,	Z_rp,	1,
-	Yrl,	Yax,	Zrp_,	1,
-	Yrl,	Yml,	Zr_m,	1,
-	Yml,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	ydivl[] =
-{
-	Yml,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ydivb[] =
-{
-	Ymb,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	yimul[] =
-{
-	Yml,	Ynone,	Zm_o,	2,
-	Yi8,	Yrl,	Zib_rr,	1,
-	Yi32,	Yrl,	Zil_rr,	1,
-	0
-};
-static uchar	ybyte[] =
-{
-	Yi32,	Ynone,	Zbyte,	1,
-	0
-};
-static uchar	yin[] =
-{
-	Yi32,	Ynone,	Zib_,	1,
-	Ynone,	Ynone,	Zlit,	1,
-	0
-};
-static uchar	yint[] =
-{
-	Yi32,	Ynone,	Zib_,	1,
-	0
-};
-static uchar	ypushl[] =
-{
-	Yrl,	Ynone,	Zrp_,	1,
-	Ym,	Ynone,	Zm_o,	2,
-	Yi8,	Ynone,	Zib_,	1,
-	Yi32,	Ynone,	Zil_,	1,
-	0
-};
-static uchar	ypopl[] =
-{
-	Ynone,	Yrl,	Z_rp,	1,
-	Ynone,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	ybswap[] =
-{
-	Ynone,	Yrl,	Z_rp,	1,
-	0,
-};
-static uchar	yscond[] =
-{
-	Ynone,	Ymb,	Zo_m,	2,
-	0
-};
-static uchar	yjcond[] =
-{
-	Ynone,	Ybr,	Zbr,	0,
-	Yi0,	Ybr,	Zbr,	0,
-	Yi1,	Ybr,	Zbr,	1,
-	0
-};
-static uchar	yloop[] =
-{
-	Ynone,	Ybr,	Zloop,	1,
-	0
-};
-static uchar	ycall[] =
-{
-	Ynone,	Yml,	Zcallindreg,	0,
-	Yrx,	Yrx,	Zcallindreg,	2,
-	Ynone,	Ycol,	Zcallind,	2,
-	Ynone,	Ybr,	Zcall,	0,
-	Ynone,	Yi32,	Zcallcon,	1,
-	0
-};
-static uchar	yduff[] =
-{
-	Ynone,	Yi32,	Zcall,	1,
-	0
-};
-static uchar	yjmp[] =
-{
-	Ynone,	Yml,	Zo_m,	2,
-	Ynone,	Ybr,	Zjmp,	0,
-	Ynone,	Yi32,	Zjmpcon,	1,
-	0
-};
-
-static uchar	yfmvd[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yf0,	Ym,	Zo_m,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfmvdp[] =
-{
-	Yf0,	Ym,	Zo_m,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfmvf[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yf0,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	yfmvx[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	0
-};
-static uchar	yfmvp[] =
-{
-	Yf0,	Ym,	Zo_m,	2,
-	0
-};
-static uchar	yfcmv[] =
-{
-	Yrf,	Yf0,	Zm_o,	2,
-	0
-};
-static uchar	yfadd[] =
-{
-	Ym,	Yf0,	Zm_o,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfaddp[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,
-	0
-};
-static uchar	yfxch[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,
-	Yrf,	Yf0,	Zm_o,	2,
-	0
-};
-static uchar	ycompp[] =
-{
-	Yf0,	Yrf,	Zo_m,	2,	/* botch is really f0,f1 */
-	0
-};
-static uchar	ystsw[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ynone,	Yax,	Zlit,	1,
-	0
-};
-static uchar	ystcw[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ym,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ysvrs[] =
-{
-	Ynone,	Ym,	Zo_m,	2,
-	Ym,	Ynone,	Zm_o,	2,
-	0
-};
-static uchar	ymskb[] =
-{
-	Yxr,	Yrl,	Zm_r_xm,	2,
-	Ymr,	Yrl,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxm[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxcvm1[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	Yxm,	Ymr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxcvm2[] =
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	Ymm,	Yxr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxmq[] = 
-{
-	Yxm,	Yxr,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxr[] = 
-{
-	Yxr,	Yxr,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxr_ml[] =
-{
-	Yxr,	Yml,	Zr_m_xm,	1,
-	0
-};
-static uchar	yxcmp[] =
-{
-	Yxm,	Yxr, Zm_r_xm,	1,
-	0
-};
-static uchar	yxcmpi[] =
-{
-	Yxm,	Yxr, Zm_r_i_xm,	2,
-	0
-};
-static uchar	yxmov[] =
-{
-	Yxm,	Yxr,	Zm_r_xm,	1,
-	Yxr,	Yxm,	Zr_m_xm,	1,
-	0
-};
-static uchar	yxcvfl[] = 
-{
-	Yxm,	Yrl,	Zm_r_xm,	1,
-	0
-};
-static uchar	yxcvlf[] =
-{
-	Yml,	Yxr,	Zm_r_xm,	1,
-	0
-};
-/*
-static uchar	yxcvfq[] = 
-{
-	Yxm,	Yrl,	Zm_r_xm,	2,
-	0
-};
-static uchar	yxcvqf[] =
-{
-	Yml,	Yxr,	Zm_r_xm,	2,
-	0
-};
-*/
-static uchar	yxrrl[] =
-{
-	Yxr,	Yrl,	Zm_r,	1,
-	0
-};
-static uchar	yprefetch[] =
-{
-	Ym,	Ynone,	Zm_o,	2,
-	0,
-};
-static uchar	yaes[] =
-{
-	Yxm,	Yxr,	Zlitm_r,	2,
-	0
-};
-static uchar	yinsrd[] =
-{
-	Yml,	Yxr,	Zibm_r,	2,
-	0
-};
-static uchar	ymshufb[] =
-{
-	Yxm,	Yxr,	Zm2_r,	2,
-	0
-};
-
-static uchar   yxshuf[] =
-{
-	Yxm,    Yxr,    Zibm_r, 2,
-	0
-};
-
-static Optab optab[] =
-/*	as, ytab, andproto, opcode */
-{
-	{ AXXX },
-	{ AAAA,		ynone,	Px, {0x37} },
-	{ AAAD,		ynone,	Px, {0xd5,0x0a} },
-	{ AAAM,		ynone,	Px, {0xd4,0x0a} },
-	{ AAAS,		ynone,	Px, {0x3f} },
-	{ AADCB,	yxorb,	Pb, {0x14,0x80,(02),0x10,0x10} },
-	{ AADCL,	yxorl,	Px, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
-	{ AADCW,	yxorl,	Pe, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
-	{ AADDB,	yxorb,	Px, {0x04,0x80,(00),0x00,0x02} },
-	{ AADDL,	yaddl,	Px, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
-	{ AADDW,	yaddl,	Pe, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
-	{ AADJSP },
-	{ AANDB,	yxorb,	Pb, {0x24,0x80,(04),0x20,0x22} },
-	{ AANDL,	yxorl,	Px, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
-	{ AANDW,	yxorl,	Pe, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
-	{ AARPL,	yrl_ml,	Px, {0x63} },
-	{ ABOUNDL,	yrl_m,	Px, {0x62} },
-	{ ABOUNDW,	yrl_m,	Pe, {0x62} },
-	{ ABSFL,	yml_rl,	Pm, {0xbc} },
-	{ ABSFW,	yml_rl,	Pq, {0xbc} },
-	{ ABSRL,	yml_rl,	Pm, {0xbd} },
-	{ ABSRW,	yml_rl,	Pq, {0xbd} },
-	{ ABTL,		yml_rl,	Pm, {0xa3} },
-	{ ABTW,		yml_rl,	Pq, {0xa3} },
-	{ ABTCL,	yml_rl,	Pm, {0xbb} },
-	{ ABTCW,	yml_rl,	Pq, {0xbb} },
-	{ ABTRL,	yml_rl,	Pm, {0xb3} },
-	{ ABTRW,	yml_rl,	Pq, {0xb3} },
-	{ ABTSL,	yml_rl,	Pm, {0xab} },
-	{ ABTSW,	yml_rl,	Pq, {0xab} },
-	{ ABYTE,	ybyte,	Px, {1} },
-	{ ACALL,	ycall,	Px, {0xff,(02),0xff,(0x15),0xe8} },
-	{ ACLC,		ynone,	Px, {0xf8} },
-	{ ACLD,		ynone,	Px, {0xfc} },
-	{ ACLI,		ynone,	Px, {0xfa} },
-	{ ACLTS,	ynone,	Pm, {0x06} },
-	{ ACMC,		ynone,	Px, {0xf5} },
-	{ ACMPB,	ycmpb,	Pb, {0x3c,0x80,(07),0x38,0x3a} },
-	{ ACMPL,	ycmpl,	Px, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
-	{ ACMPW,	ycmpl,	Pe, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
-	{ ACMPSB,	ynone,	Pb, {0xa6} },
-	{ ACMPSL,	ynone,	Px, {0xa7} },
-	{ ACMPSW,	ynone,	Pe, {0xa7} },
-	{ ADAA,		ynone,	Px, {0x27} },
-	{ ADAS,		ynone,	Px, {0x2f} },
-	{ ADATA },
-	{ ADECB,	yincb,	Pb, {0xfe,(01)} },
-	{ ADECL,	yincl,	Px, {0x48,0xff,(01)} },
-	{ ADECW,	yincl,	Pe, {0x48,0xff,(01)} },
-	{ ADIVB,	ydivb,	Pb, {0xf6,(06)} },
-	{ ADIVL,	ydivl,	Px, {0xf7,(06)} },
-	{ ADIVW,	ydivl,	Pe, {0xf7,(06)} },
-	{ AENTER },				/* botch */
-	{ AGLOBL },
-	{ AHLT,		ynone,	Px, {0xf4} },
-	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
-	{ AIDIVL,	ydivl,	Px, {0xf7,(07)} },
-	{ AIDIVW,	ydivl,	Pe, {0xf7,(07)} },
-	{ AIMULB,	ydivb,	Pb, {0xf6,(05)} },
-	{ AIMULL,	yimul,	Px, {0xf7,(05),0x6b,0x69} },
-	{ AIMULW,	yimul,	Pe, {0xf7,(05),0x6b,0x69} },
-	{ AINB,		yin,	Pb, {0xe4,0xec} },
-	{ AINL,		yin,	Px, {0xe5,0xed} },
-	{ AINW,		yin,	Pe, {0xe5,0xed} },
-	{ AINCB,	yincb,	Pb, {0xfe,(00)} },
-	{ AINCL,	yincl,	Px, {0x40,0xff,(00)} },
-	{ AINCW,	yincl,	Pe, {0x40,0xff,(00)} },
-	{ AINSB,	ynone,	Pb, {0x6c} },
-	{ AINSL,	ynone,	Px, {0x6d} },
-	{ AINSW,	ynone,	Pe, {0x6d} },
-	{ AINT,		yint,	Px, {0xcd} },
-	{ AINTO,	ynone,	Px, {0xce} },
-	{ AIRETL,	ynone,	Px, {0xcf} },
-	{ AIRETW,	ynone,	Pe, {0xcf} },
-	{ AJCC,		yjcond,	Px, {0x73,0x83,(00)} },
-	{ AJCS,		yjcond,	Px, {0x72,0x82} },
-	{ AJCXZL,	yloop,	Px, {0xe3} },
-	{ AJCXZW,	yloop,	Px, {0xe3} },
-	{ AJEQ,		yjcond,	Px, {0x74,0x84} },
-	{ AJGE,		yjcond,	Px, {0x7d,0x8d} },
-	{ AJGT,		yjcond,	Px, {0x7f,0x8f} },
-	{ AJHI,		yjcond,	Px, {0x77,0x87} },
-	{ AJLE,		yjcond,	Px, {0x7e,0x8e} },
-	{ AJLS,		yjcond,	Px, {0x76,0x86} },
-	{ AJLT,		yjcond,	Px, {0x7c,0x8c} },
-	{ AJMI,		yjcond,	Px, {0x78,0x88} },
-	{ AJMP,		yjmp,	Px, {0xff,(04),0xeb,0xe9} },
-	{ AJNE,		yjcond,	Px, {0x75,0x85} },
-	{ AJOC,		yjcond,	Px, {0x71,0x81,(00)} },
-	{ AJOS,		yjcond,	Px, {0x70,0x80,(00)} },
-	{ AJPC,		yjcond,	Px, {0x7b,0x8b} },
-	{ AJPL,		yjcond,	Px, {0x79,0x89} },
-	{ AJPS,		yjcond,	Px, {0x7a,0x8a} },
-	{ ALAHF,	ynone,	Px, {0x9f} },
-	{ ALARL,	yml_rl,	Pm, {0x02} },
-	{ ALARW,	yml_rl,	Pq, {0x02} },
-	{ ALEAL,	ym_rl,	Px, {0x8d} },
-	{ ALEAW,	ym_rl,	Pe, {0x8d} },
-	{ ALEAVEL,	ynone,	Px, {0xc9} },
-	{ ALEAVEW,	ynone,	Pe, {0xc9} },
-	{ ALOCK,	ynone,	Px, {0xf0} },
-	{ ALODSB,	ynone,	Pb, {0xac} },
-	{ ALODSL,	ynone,	Px, {0xad} },
-	{ ALODSW,	ynone,	Pe, {0xad} },
-	{ ALONG,	ybyte,	Px, {4} },
-	{ ALOOP,	yloop,	Px, {0xe2} },
-	{ ALOOPEQ,	yloop,	Px, {0xe1} },
-	{ ALOOPNE,	yloop,	Px, {0xe0} },
-	{ ALSLL,	yml_rl,	Pm, {0x03 } },
-	{ ALSLW,	yml_rl,	Pq, {0x03 } },
-	{ AMOVB,	ymovb,	Pb, {0x88,0x8a,0xb0,0xc6,(00)} },
-	{ AMOVL,	ymovl,	Px, {0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),Pe,0x6e,Pe,0x7e,0} },
-	{ AMOVW,	ymovw,	Pe, {0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),0} },
-	{ AMOVQ,	ymovq,	Pf3, {0x7e} },
-	{ AMOVBLSX,	ymb_rl,	Pm, {0xbe} },
-	{ AMOVBLZX,	ymb_rl,	Pm, {0xb6} },
-	{ AMOVBWSX,	ymb_rl,	Pq, {0xbe} },
-	{ AMOVBWZX,	ymb_rl,	Pq, {0xb6} },
-	{ AMOVWLSX,	yml_rl,	Pm, {0xbf} },
-	{ AMOVWLZX,	yml_rl,	Pm, {0xb7} },
-	{ AMOVSB,	ynone,	Pb, {0xa4} },
-	{ AMOVSL,	ynone,	Px, {0xa5} },
-	{ AMOVSW,	ynone,	Pe, {0xa5} },
-	{ AMULB,	ydivb,	Pb, {0xf6,(04)} },
-	{ AMULL,	ydivl,	Px, {0xf7,(04)} },
-	{ AMULW,	ydivl,	Pe, {0xf7,(04)} },
-	{ ANEGB,	yscond,	Px, {0xf6,(03)} },
-	{ ANEGL,	yscond,	Px, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
-	{ ANEGW,	yscond,	Pe, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
-	{ ANOP,		ynop,	Px, {0,0} },
-	{ ANOTB,	yscond,	Px, {0xf6,(02)} },
-	{ ANOTL,	yscond,	Px, {0xf7,(02)} }, // TODO(rsc): yscond is wrong here.
-	{ ANOTW,	yscond,	Pe, {0xf7,(02)} }, // TODO(rsc): yscond is wrong here.
-	{ AORB,		yxorb,	Pb, {0x0c,0x80,(01),0x08,0x0a} },
-	{ AORL,		yxorl,	Px, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
-	{ AORW,		yxorl,	Pe, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
-	{ AOUTB,	yin,	Pb, {0xe6,0xee} },
-	{ AOUTL,	yin,	Px, {0xe7,0xef} },
-	{ AOUTW,	yin,	Pe, {0xe7,0xef} },
-	{ AOUTSB,	ynone,	Pb, {0x6e} },
-	{ AOUTSL,	ynone,	Px, {0x6f} },
-	{ AOUTSW,	ynone,	Pe, {0x6f} },
-	{ APAUSE,	ynone,	Px, {0xf3,0x90} },
-	{ APOPAL,	ynone,	Px, {0x61} },
-	{ APOPAW,	ynone,	Pe, {0x61} },
-	{ APOPFL,	ynone,	Px, {0x9d} },
-	{ APOPFW,	ynone,	Pe, {0x9d} },
-	{ APOPL,	ypopl,	Px, {0x58,0x8f,(00)} },
-	{ APOPW,	ypopl,	Pe, {0x58,0x8f,(00)} },
-	{ APUSHAL,	ynone,	Px, {0x60} },
-	{ APUSHAW,	ynone,	Pe, {0x60} },
-	{ APUSHFL,	ynone,	Px, {0x9c} },
-	{ APUSHFW,	ynone,	Pe, {0x9c} },
-	{ APUSHL,	ypushl,	Px, {0x50,0xff,(06),0x6a,0x68} },
-	{ APUSHW,	ypushl,	Pe, {0x50,0xff,(06),0x6a,0x68} },
-	{ ARCLB,	yshb,	Pb, {0xd0,(02),0xc0,(02),0xd2,(02)} },
-	{ ARCLL,	yshl,	Px, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
-	{ ARCLW,	yshl,	Pe, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
-	{ ARCRB,	yshb,	Pb, {0xd0,(03),0xc0,(03),0xd2,(03)} },
-	{ ARCRL,	yshl,	Px, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
-	{ ARCRW,	yshl,	Pe, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
-	{ AREP,		ynone,	Px, {0xf3} },
-	{ AREPN,	ynone,	Px, {0xf2} },
-	{ ARET,		ynone,	Px, {0xc3} },
-	{ AROLB,	yshb,	Pb, {0xd0,(00),0xc0,(00),0xd2,(00)} },
-	{ AROLL,	yshl,	Px, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
-	{ AROLW,	yshl,	Pe, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
-	{ ARORB,	yshb,	Pb, {0xd0,(01),0xc0,(01),0xd2,(01)} },
-	{ ARORL,	yshl,	Px, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
-	{ ARORW,	yshl,	Pe, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
-	{ ASAHF,	ynone,	Px, {0x9e} },
-	{ ASALB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
-	{ ASALL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASALW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASARB,	yshb,	Pb, {0xd0,(07),0xc0,(07),0xd2,(07)} },
-	{ ASARL,	yshl,	Px, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
-	{ ASARW,	yshl,	Pe, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
-	{ ASBBB,	yxorb,	Pb, {0x1c,0x80,(03),0x18,0x1a} },
-	{ ASBBL,	yxorl,	Px, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
-	{ ASBBW,	yxorl,	Pe, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
-	{ ASCASB,	ynone,	Pb, {0xae} },
-	{ ASCASL,	ynone,	Px, {0xaf} },
-	{ ASCASW,	ynone,	Pe, {0xaf} },
-	{ ASETCC,	yscond,	Pm, {0x93,(00)} },
-	{ ASETCS,	yscond,	Pm, {0x92,(00)} },
-	{ ASETEQ,	yscond,	Pm, {0x94,(00)} },
-	{ ASETGE,	yscond,	Pm, {0x9d,(00)} },
-	{ ASETGT,	yscond,	Pm, {0x9f,(00)} },
-	{ ASETHI,	yscond,	Pm, {0x97,(00)} },
-	{ ASETLE,	yscond,	Pm, {0x9e,(00)} },
-	{ ASETLS,	yscond,	Pm, {0x96,(00)} },
-	{ ASETLT,	yscond,	Pm, {0x9c,(00)} },
-	{ ASETMI,	yscond,	Pm, {0x98,(00)} },
-	{ ASETNE,	yscond,	Pm, {0x95,(00)} },
-	{ ASETOC,	yscond,	Pm, {0x91,(00)} },
-	{ ASETOS,	yscond,	Pm, {0x90,(00)} },
-	{ ASETPC,	yscond,	Pm, {0x9b,(00)} },
-	{ ASETPL,	yscond,	Pm, {0x99,(00)} },
-	{ ASETPS,	yscond,	Pm, {0x9a,(00)} },
-	{ ACDQ,		ynone,	Px, {0x99} },
-	{ ACWD,		ynone,	Pe, {0x99} },
-	{ ASHLB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
-	{ ASHLL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASHLW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
-	{ ASHRB,	yshb,	Pb, {0xd0,(05),0xc0,(05),0xd2,(05)} },
-	{ ASHRL,	yshl,	Px, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
-	{ ASHRW,	yshl,	Pe, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
-	{ ASTC,		ynone,	Px, {0xf9} },
-	{ ASTD,		ynone,	Px, {0xfd} },
-	{ ASTI,		ynone,	Px, {0xfb} },
-	{ ASTOSB,	ynone,	Pb, {0xaa} },
-	{ ASTOSL,	ynone,	Px, {0xab} },
-	{ ASTOSW,	ynone,	Pe, {0xab} },
-	{ ASUBB,	yxorb,	Pb, {0x2c,0x80,(05),0x28,0x2a} },
-	{ ASUBL,	yaddl,	Px, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
-	{ ASUBW,	yaddl,	Pe, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
-	{ ASYSCALL,	ynone,	Px, {0xcd,100} },
-	{ ATESTB,	ytestb,	Pb, {0xa8,0xf6,(00),0x84,0x84} },
-	{ ATESTL,	ytestl,	Px, {0xa9,0xf7,(00),0x85,0x85} },
-	{ ATESTW,	ytestl,	Pe, {0xa9,0xf7,(00),0x85,0x85} },
-	{ ATEXT,	ytext,	Px },
-	{ AVERR,	ydivl,	Pm, {0x00,(04)} },
-	{ AVERW,	ydivl,	Pm, {0x00,(05)} },
-	{ AWAIT,	ynone,	Px, {0x9b} },
-	{ AWORD,	ybyte,	Px, {2} },
-	{ AXCHGB,	yml_mb,	Pb, {0x86,0x86} },
-	{ AXCHGL,	yxchg,	Px, {0x90,0x90,0x87,0x87} },
-	{ AXCHGW,	yxchg,	Pe, {0x90,0x90,0x87,0x87} },
-	{ AXLAT,	ynone,	Px, {0xd7} },
-	{ AXORB,	yxorb,	Pb, {0x34,0x80,(06),0x30,0x32} },
-	{ AXORL,	yxorl,	Px, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
-	{ AXORW,	yxorl,	Pe, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
-
-	{ AFMOVB,	yfmvx,	Px, {0xdf,(04)} },
-	{ AFMOVBP,	yfmvp,	Px, {0xdf,(06)} },
-	{ AFMOVD,	yfmvd,	Px, {0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02)} },
-	{ AFMOVDP,	yfmvdp,	Px, {0xdd,(03),0xdd,(03)} },
-	{ AFMOVF,	yfmvf,	Px, {0xd9,(00),0xd9,(02)} },
-	{ AFMOVFP,	yfmvp,	Px, {0xd9,(03)} },
-	{ AFMOVL,	yfmvf,	Px, {0xdb,(00),0xdb,(02)} },
-	{ AFMOVLP,	yfmvp,	Px, {0xdb,(03)} },
-	{ AFMOVV,	yfmvx,	Px, {0xdf,(05)} },
-	{ AFMOVVP,	yfmvp,	Px, {0xdf,(07)} },
-	{ AFMOVW,	yfmvf,	Px, {0xdf,(00),0xdf,(02)} },
-	{ AFMOVWP,	yfmvp,	Px, {0xdf,(03)} },
-	{ AFMOVX,	yfmvx,	Px, {0xdb,(05)} },
-	{ AFMOVXP,	yfmvp,	Px, {0xdb,(07)} },
-
-	{ AFCOMB },
-	{ AFCOMBP },
-	{ AFCOMD,	yfadd,	Px, {0xdc,(02),0xd8,(02),0xdc,(02)} },	/* botch */
-	{ AFCOMDP,	yfadd,	Px, {0xdc,(03),0xd8,(03),0xdc,(03)} },	/* botch */
-	{ AFCOMDPP,	ycompp,	Px, {0xde,(03)} },
-	{ AFCOMF,	yfmvx,	Px, {0xd8,(02)} },
-	{ AFCOMFP,	yfmvx,	Px, {0xd8,(03)} },
-	{ AFCOMI,	yfmvx,	Px, {0xdb,(06)} },
-	{ AFCOMIP,	yfmvx,	Px, {0xdf,(06)} },
-	{ AFCOML,	yfmvx,	Px, {0xda,(02)} },
-	{ AFCOMLP,	yfmvx,	Px, {0xda,(03)} },
-	{ AFCOMW,	yfmvx,	Px, {0xde,(02)} },
-	{ AFCOMWP,	yfmvx,	Px, {0xde,(03)} },
-
-	{ AFUCOM,	ycompp,	Px, {0xdd,(04)} },
-	{ AFUCOMI,	ycompp,	Px, {0xdb,(05)} },
-	{ AFUCOMIP,	ycompp,	Px, {0xdf,(05)} },
-	{ AFUCOMP,	ycompp,	Px, {0xdd,(05)} },
-	{ AFUCOMPP,	ycompp,	Px, {0xda,(13)} },
-
-	{ AFADDDP,	yfaddp,	Px, {0xde,(00)} },
-	{ AFADDW,	yfmvx,	Px, {0xde,(00)} },
-	{ AFADDL,	yfmvx,	Px, {0xda,(00)} },
-	{ AFADDF,	yfmvx,	Px, {0xd8,(00)} },
-	{ AFADDD,	yfadd,	Px, {0xdc,(00),0xd8,(00),0xdc,(00)} },
-
-	{ AFMULDP,	yfaddp,	Px, {0xde,(01)} },
-	{ AFMULW,	yfmvx,	Px, {0xde,(01)} },
-	{ AFMULL,	yfmvx,	Px, {0xda,(01)} },
-	{ AFMULF,	yfmvx,	Px, {0xd8,(01)} },
-	{ AFMULD,	yfadd,	Px, {0xdc,(01),0xd8,(01),0xdc,(01)} },
-
-	{ AFSUBDP,	yfaddp,	Px, {0xde,(05)} },
-	{ AFSUBW,	yfmvx,	Px, {0xde,(04)} },
-	{ AFSUBL,	yfmvx,	Px, {0xda,(04)} },
-	{ AFSUBF,	yfmvx,	Px, {0xd8,(04)} },
-	{ AFSUBD,	yfadd,	Px, {0xdc,(04),0xd8,(04),0xdc,(05)} },
-
-	{ AFSUBRDP,	yfaddp,	Px, {0xde,(04)} },
-	{ AFSUBRW,	yfmvx,	Px, {0xde,(05)} },
-	{ AFSUBRL,	yfmvx,	Px, {0xda,(05)} },
-	{ AFSUBRF,	yfmvx,	Px, {0xd8,(05)} },
-	{ AFSUBRD,	yfadd,	Px, {0xdc,(05),0xd8,(05),0xdc,(04)} },
-
-	{ AFDIVDP,	yfaddp,	Px, {0xde,(07)} },
-	{ AFDIVW,	yfmvx,	Px, {0xde,(06)} },
-	{ AFDIVL,	yfmvx,	Px, {0xda,(06)} },
-	{ AFDIVF,	yfmvx,	Px, {0xd8,(06)} },
-	{ AFDIVD,	yfadd,	Px, {0xdc,(06),0xd8,(06),0xdc,(07)} },
-
-	{ AFDIVRDP,	yfaddp,	Px, {0xde,(06)} },
-	{ AFDIVRW,	yfmvx,	Px, {0xde,(07)} },
-	{ AFDIVRL,	yfmvx,	Px, {0xda,(07)} },
-	{ AFDIVRF,	yfmvx,	Px, {0xd8,(07)} },
-	{ AFDIVRD,	yfadd,	Px, {0xdc,(07),0xd8,(07),0xdc,(06)} },
-
-	{ AFXCHD,	yfxch,	Px, {0xd9,(01),0xd9,(01)} },
-	{ AFFREE },
-	{ AFLDCW,	ystcw,	Px, {0xd9,(05),0xd9,(05)} },
-	{ AFLDENV,	ystcw,	Px, {0xd9,(04),0xd9,(04)} },
-	{ AFRSTOR,	ysvrs,	Px, {0xdd,(04),0xdd,(04)} },
-	{ AFSAVE,	ysvrs,	Px, {0xdd,(06),0xdd,(06)} },
-	{ AFSTCW,	ystcw,	Px, {0xd9,(07),0xd9,(07)} },
-	{ AFSTENV,	ystcw,	Px, {0xd9,(06),0xd9,(06)} },
-	{ AFSTSW,	ystsw,	Px, {0xdd,(07),0xdf,0xe0} },
-	{ AF2XM1,	ynone,	Px, {0xd9, 0xf0} },
-	{ AFABS,	ynone,	Px, {0xd9, 0xe1} },
-	{ AFCHS,	ynone,	Px, {0xd9, 0xe0} },
-	{ AFCLEX,	ynone,	Px, {0xdb, 0xe2} },
-	{ AFCOS,	ynone,	Px, {0xd9, 0xff} },
-	{ AFDECSTP,	ynone,	Px, {0xd9, 0xf6} },
-	{ AFINCSTP,	ynone,	Px, {0xd9, 0xf7} },
-	{ AFINIT,	ynone,	Px, {0xdb, 0xe3} },
-	{ AFLD1,	ynone,	Px, {0xd9, 0xe8} },
-	{ AFLDL2E,	ynone,	Px, {0xd9, 0xea} },
-	{ AFLDL2T,	ynone,	Px, {0xd9, 0xe9} },
-	{ AFLDLG2,	ynone,	Px, {0xd9, 0xec} },
-	{ AFLDLN2,	ynone,	Px, {0xd9, 0xed} },
-	{ AFLDPI,	ynone,	Px, {0xd9, 0xeb} },
-	{ AFLDZ,	ynone,	Px, {0xd9, 0xee} },
-	{ AFNOP,	ynone,	Px, {0xd9, 0xd0} },
-	{ AFPATAN,	ynone,	Px, {0xd9, 0xf3} },
-	{ AFPREM,	ynone,	Px, {0xd9, 0xf8} },
-	{ AFPREM1,	ynone,	Px, {0xd9, 0xf5} },
-	{ AFPTAN,	ynone,	Px, {0xd9, 0xf2} },
-	{ AFRNDINT,	ynone,	Px, {0xd9, 0xfc} },
-	{ AFSCALE,	ynone,	Px, {0xd9, 0xfd} },
-	{ AFSIN,	ynone,	Px, {0xd9, 0xfe} },
-	{ AFSINCOS,	ynone,	Px, {0xd9, 0xfb} },
-	{ AFSQRT,	ynone,	Px, {0xd9, 0xfa} },
-	{ AFTST,	ynone,	Px, {0xd9, 0xe4} },
-	{ AFXAM,	ynone,	Px, {0xd9, 0xe5} },
-	{ AFXTRACT,	ynone,	Px, {0xd9, 0xf4} },
-	{ AFYL2X,	ynone,	Px, {0xd9, 0xf1} },
-	{ AFYL2XP1,	ynone,	Px, {0xd9, 0xf9} },
-	{ AEND },
-	{ ACMPXCHGB,	yrb_mb,	Pm, {0xb0} },
-	{ ACMPXCHGL,	yrl_ml,	Pm, {0xb1} },
-	{ ACMPXCHGW,	yrl_ml,	Pm, {0xb1} },
-	{ ACMPXCHG8B,	yscond,	Pm, {0xc7,(01)} }, // TODO(rsc): yscond is wrong here.
-
-	{ ACPUID,	ynone,	Pm, {0xa2} },
-	{ ARDTSC,	ynone,	Pm, {0x31} },
-
-	{ AXADDB,	yrb_mb,	Pb, {0x0f,0xc0} },
-	{ AXADDL,	yrl_ml,	Pm, {0xc1} },
-	{ AXADDW,	yrl_ml,	Pe, {0x0f,0xc1} },
-
-	{ ACMOVLCC,	yml_rl,	Pm, {0x43} },
-	{ ACMOVLCS,	yml_rl,	Pm, {0x42} },
-	{ ACMOVLEQ,	yml_rl,	Pm, {0x44} },
-	{ ACMOVLGE,	yml_rl,	Pm, {0x4d} },
-	{ ACMOVLGT,	yml_rl,	Pm, {0x4f} },
-	{ ACMOVLHI,	yml_rl,	Pm, {0x47} },
-	{ ACMOVLLE,	yml_rl,	Pm, {0x4e} },
-	{ ACMOVLLS,	yml_rl,	Pm, {0x46} },
-	{ ACMOVLLT,	yml_rl,	Pm, {0x4c} },
-	{ ACMOVLMI,	yml_rl,	Pm, {0x48} },
-	{ ACMOVLNE,	yml_rl,	Pm, {0x45} },
-	{ ACMOVLOC,	yml_rl,	Pm, {0x41} },
-	{ ACMOVLOS,	yml_rl,	Pm, {0x40} },
-	{ ACMOVLPC,	yml_rl,	Pm, {0x4b} },
-	{ ACMOVLPL,	yml_rl,	Pm, {0x49} },
-	{ ACMOVLPS,	yml_rl,	Pm, {0x4a} },
-	{ ACMOVWCC,	yml_rl,	Pq, {0x43} },
-	{ ACMOVWCS,	yml_rl,	Pq, {0x42} },
-	{ ACMOVWEQ,	yml_rl,	Pq, {0x44} },
-	{ ACMOVWGE,	yml_rl,	Pq, {0x4d} },
-	{ ACMOVWGT,	yml_rl,	Pq, {0x4f} },
-	{ ACMOVWHI,	yml_rl,	Pq, {0x47} },
-	{ ACMOVWLE,	yml_rl,	Pq, {0x4e} },
-	{ ACMOVWLS,	yml_rl,	Pq, {0x46} },
-	{ ACMOVWLT,	yml_rl,	Pq, {0x4c} },
-	{ ACMOVWMI,	yml_rl,	Pq, {0x48} },
-	{ ACMOVWNE,	yml_rl,	Pq, {0x45} },
-	{ ACMOVWOC,	yml_rl,	Pq, {0x41} },
-	{ ACMOVWOS,	yml_rl,	Pq, {0x40} },
-	{ ACMOVWPC,	yml_rl,	Pq, {0x4b} },
-	{ ACMOVWPL,	yml_rl,	Pq, {0x49} },
-	{ ACMOVWPS,	yml_rl,	Pq, {0x4a} },
-
-	{ AFCMOVCC,	yfcmv,	Px, {0xdb,(00)} },
-	{ AFCMOVCS,	yfcmv,	Px, {0xda,(00)} },
-	{ AFCMOVEQ,	yfcmv,	Px, {0xda,(01)} },
-	{ AFCMOVHI,	yfcmv,	Px, {0xdb,(02)} },
-	{ AFCMOVLS,	yfcmv,	Px, {0xda,(02)} },
-	{ AFCMOVNE,	yfcmv,	Px, {0xdb,(01)} },
-	{ AFCMOVNU,	yfcmv,	Px, {0xdb,(03)} },
-	{ AFCMOVUN,	yfcmv,	Px, {0xda,(03)} },
-
-	{ ALFENCE, ynone, Pm, {0xae,0xe8} },
-	{ AMFENCE, ynone, Pm, {0xae,0xf0} },
-	{ ASFENCE, ynone, Pm, {0xae,0xf8} },
-
-	{ AEMMS, ynone, Pm, {0x77} },
-
-	{ APREFETCHT0,	yprefetch,	Pm,	{0x18,(01)} },
-	{ APREFETCHT1,	yprefetch,	Pm,	{0x18,(02)} },
-	{ APREFETCHT2,	yprefetch,	Pm,	{0x18,(03)} },
-	{ APREFETCHNTA,	yprefetch,	Pm,	{0x18,(00)} },
-
-	{ ABSWAPL,	ybswap,	Pm,	{0xc8} },
-	
-	{ AUNDEF,		ynone,	Px,	{0x0f, 0x0b} },
-
-	{ AADDPD,	yxm,	Pq, {0x58} },
-	{ AADDPS,	yxm,	Pm, {0x58} },
-	{ AADDSD,	yxm,	Pf2, {0x58} },
-	{ AADDSS,	yxm,	Pf3, {0x58} },
-	{ AANDNPD,	yxm,	Pq, {0x55} },
-	{ AANDNPS,	yxm,	Pm, {0x55} },
-	{ AANDPD,	yxm,	Pq, {0x54} },
-	{ AANDPS,	yxm,	Pq, {0x54} },
-	{ ACMPPD,	yxcmpi,	Px, {Pe,0xc2} },
-	{ ACMPPS,	yxcmpi,	Pm, {0xc2,0} },
-	{ ACMPSD,	yxcmpi,	Px, {Pf2,0xc2} },
-	{ ACMPSS,	yxcmpi,	Px, {Pf3,0xc2} },
-	{ ACOMISD,	yxcmp,	Pe, {0x2f} },
-	{ ACOMISS,	yxcmp,	Pm, {0x2f} },
-	{ ACVTPL2PD,	yxcvm2,	Px, {Pf3,0xe6,Pe,0x2a} },
-	{ ACVTPL2PS,	yxcvm2,	Pm, {0x5b,0,0x2a,0,} },
-	{ ACVTPD2PL,	yxcvm1,	Px, {Pf2,0xe6,Pe,0x2d} },
-	{ ACVTPD2PS,	yxm,	Pe, {0x5a} },
-	{ ACVTPS2PL,	yxcvm1, Px, {Pe,0x5b,Pm,0x2d} },
-	{ ACVTPS2PD,	yxm,	Pm, {0x5a} },
-	{ ACVTSD2SL,	yxcvfl, Pf2, {0x2d} },
- 	{ ACVTSD2SS,	yxm,	Pf2, {0x5a} },
-	{ ACVTSL2SD,	yxcvlf, Pf2, {0x2a} },
-	{ ACVTSL2SS,	yxcvlf, Pf3, {0x2a} },
-	{ ACVTSS2SD,	yxm,	Pf3, {0x5a} },
-	{ ACVTSS2SL,	yxcvfl, Pf3, {0x2d} },
-	{ ACVTTPD2PL,	yxcvm1,	Px, {Pe,0xe6,Pe,0x2c} },
-	{ ACVTTPS2PL,	yxcvm1,	Px, {Pf3,0x5b,Pm,0x2c} },
-	{ ACVTTSD2SL,	yxcvfl, Pf2, {0x2c} },
-	{ ACVTTSS2SL,	yxcvfl,	Pf3, {0x2c} },
-	{ ADIVPD,	yxm,	Pe, {0x5e} },
-	{ ADIVPS,	yxm,	Pm, {0x5e} },
-	{ ADIVSD,	yxm,	Pf2, {0x5e} },
-	{ ADIVSS,	yxm,	Pf3, {0x5e} },
-	{ AMASKMOVOU,	yxr,	Pe, {0xf7} },
-	{ AMAXPD,	yxm,	Pe, {0x5f} },
-	{ AMAXPS,	yxm,	Pm, {0x5f} },
-	{ AMAXSD,	yxm,	Pf2, {0x5f} },
-	{ AMAXSS,	yxm,	Pf3, {0x5f} },
-	{ AMINPD,	yxm,	Pe, {0x5d} },
-	{ AMINPS,	yxm,	Pm, {0x5d} },
-	{ AMINSD,	yxm,	Pf2, {0x5d} },
-	{ AMINSS,	yxm,	Pf3, {0x5d} },
-	{ AMOVAPD,	yxmov,	Pe, {0x28,0x29} },
-	{ AMOVAPS,	yxmov,	Pm, {0x28,0x29} },
-	{ AMOVO,	yxmov,	Pe, {0x6f,0x7f} },
-	{ AMOVOU,	yxmov,	Pf3, {0x6f,0x7f} },
-	{ AMOVHLPS,	yxr,	Pm, {0x12} },
-	{ AMOVHPD,	yxmov,	Pe, {0x16,0x17} },
-	{ AMOVHPS,	yxmov,	Pm, {0x16,0x17} },
-	{ AMOVLHPS,	yxr,	Pm, {0x16} },
-	{ AMOVLPD,	yxmov,	Pe, {0x12,0x13} },
-	{ AMOVLPS,	yxmov,	Pm, {0x12,0x13} },
-	{ AMOVMSKPD,	yxrrl,	Pq, {0x50} },
-	{ AMOVMSKPS,	yxrrl,	Pm, {0x50} },
-	{ AMOVNTO,	yxr_ml,	Pe, {0xe7} },
-	{ AMOVNTPD,	yxr_ml,	Pe, {0x2b} },
-	{ AMOVNTPS,	yxr_ml,	Pm, {0x2b} },
-	{ AMOVSD,	yxmov,	Pf2, {0x10,0x11} },
-	{ AMOVSS,	yxmov,	Pf3, {0x10,0x11} },
-	{ AMOVUPD,	yxmov,	Pe, {0x10,0x11} },
-	{ AMOVUPS,	yxmov,	Pm, {0x10,0x11} },
-	{ AMULPD,	yxm,	Pe, {0x59} },
-	{ AMULPS,	yxm,	Ym, {0x59} },
-	{ AMULSD,	yxm,	Pf2, {0x59} },
-	{ AMULSS,	yxm,	Pf3, {0x59} },
-	{ AORPD,	yxm,	Pq, {0x56} },
-	{ AORPS,	yxm,	Pm, {0x56} },
-	{ APADDQ,	yxm,	Pe, {0xd4} },
-	{ APAND,	yxm,	Pe, {0xdb} },
-	{ APCMPEQB,	yxmq,	Pe, {0x74} },
-	{ APMAXSW,	yxm,	Pe, {0xee} },
-	{ APMAXUB,	yxm,	Pe, {0xde} },
-	{ APMINSW,	yxm,	Pe, {0xea} },
-	{ APMINUB,	yxm,	Pe, {0xda} },
-	{ APMOVMSKB,	ymskb,	Px, {Pe,0xd7,0xd7} },
-	{ APSADBW,	yxm,	Pq, {0xf6} },
-	{ APSUBB,	yxm,	Pe, {0xf8} },
-	{ APSUBL,	yxm,	Pe, {0xfa} },
-	{ APSUBQ,	yxm,	Pe, {0xfb} },
-	{ APSUBSB,	yxm,	Pe, {0xe8} },
-	{ APSUBSW,	yxm,	Pe, {0xe9} },
-	{ APSUBUSB,	yxm,	Pe, {0xd8} },
-	{ APSUBUSW,	yxm,	Pe, {0xd9} },
-	{ APSUBW,	yxm,	Pe, {0xf9} },
-	{ APUNPCKHQDQ,	yxm,	Pe, {0x6d} },
-	{ APUNPCKLQDQ,	yxm,	Pe, {0x6c} },
-	{ APXOR,	yxm,	Pe, {0xef} },
-	{ ARCPPS,	yxm,	Pm, {0x53} },
-	{ ARCPSS,	yxm,	Pf3, {0x53} },
-	{ ARSQRTPS,	yxm,	Pm, {0x52} },
-	{ ARSQRTSS,	yxm,	Pf3, {0x52} },
-	{ ASQRTPD,	yxm,	Pe, {0x51} },
-	{ ASQRTPS,	yxm,	Pm, {0x51} },
-	{ ASQRTSD,	yxm,	Pf2, {0x51} },
-	{ ASQRTSS,	yxm,	Pf3, {0x51} },
-	{ ASUBPD,	yxm,	Pe, {0x5c} },
-	{ ASUBPS,	yxm,	Pm, {0x5c} },
-	{ ASUBSD,	yxm,	Pf2, {0x5c} },
-	{ ASUBSS,	yxm,	Pf3, {0x5c} },
-	{ AUCOMISD,	yxcmp,	Pe, {0x2e} },
-	{ AUCOMISS,	yxcmp,	Pm, {0x2e} },
-	{ AUNPCKHPD,	yxm,	Pe, {0x15} },
-	{ AUNPCKHPS,	yxm,	Pm, {0x15} },
-	{ AUNPCKLPD,	yxm,	Pe, {0x14} },
-	{ AUNPCKLPS,	yxm,	Pm, {0x14} },
-	{ AXORPD,	yxm,	Pe, {0x57} },
-	{ AXORPS,	yxm,	Pm, {0x57} },
-	{ APSHUFHW,	yxshuf,	Pf3, {0x70,(00)} },
-	{ APSHUFL,	yxshuf,	Pq, {0x70,(00)} },
-	{ APSHUFLW,	yxshuf,	Pf2, {0x70,(00)} },
-
-
-	{ AAESENC,	yaes,	Pq, {0x38,0xdc,(0)} },
-	{ APINSRD,	yinsrd,	Pq, {0x3a, 0x22, (00)} },
-	{ APSHUFB,	ymshufb,Pq, {0x38, 0x00} },
-
-	{ AUSEFIELD,	ynop,	Px, {0,0} },
-	{ ATYPE },
-	{ AFUNCDATA,	yfuncdata,	Px, {0,0} },
-	{ APCDATA,	ypcdata,	Px, {0,0} },
-	{ ACHECKNIL },
-	{ AVARDEF },
-	{ AVARKILL },
-	{ ADUFFCOPY,	yduff,	Px, {0xe8} },
-	{ ADUFFZERO,	yduff,	Px, {0xe8} },
-
-	{0}
-};
-
-static int32	vaddr(Link*, Prog*, Addr*, Reloc*);
-
-// single-instruction no-ops of various lengths.
-// constructed by hand and disassembled with gdb to verify.
-// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
-static uchar nop[][16] = {
-	{0x90},
-	{0x66, 0x90},
-	{0x0F, 0x1F, 0x00},
-	{0x0F, 0x1F, 0x40, 0x00},
-	{0x0F, 0x1F, 0x44, 0x00, 0x00},
-	{0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
-	{0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
-	{0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-	// Native Client rejects the repeated 0x66 prefix.
-	// {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
-};
-
-static void
-fillnop(uchar *p, int n)
-{
-	int m;
-
-	while(n > 0) {
-		m = n;
-		if(m > nelem(nop))
-			m = nelem(nop);
-		memmove(p, nop[m-1], m);
-		p += m;
-		n -= m;
-	}
-}
-
-static int32
-naclpad(Link *ctxt, LSym *s, int32 c, int32 pad)
-{
-	symgrow(ctxt, s, c+pad);
-	fillnop(s->p+c, pad);
-	return c+pad;
-}
-
-static void instinit(void);
-
-void
-span8(Link *ctxt, LSym *s)
-{
-	Prog *p, *q;
-	int32 c, v, loop;
-	uchar *bp;
-	int n, m, i;
-
-	ctxt->cursym = s;
-
-	if(s->text == nil || s->text->link == nil)
-		return;
-
-	if(ycover[0] == 0)
-		instinit();
-
-	for(p = s->text; p != nil; p = p->link) {
-		if(p->to.type == TYPE_BRANCH)
-			if(p->pcond == nil)
-				p->pcond = p;
-		if(p->as == AADJSP) {
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_SP;
-			v = -p->from.offset;
-			p->from.offset = v;
-			p->as = AADDL;
-			if(v < 0) {
-				p->as = ASUBL;
-				v = -v;
-				p->from.offset = v;
-			}
-			if(v == 0)
-				p->as = ANOP;
-		}
-	}
-
-	for(p = s->text; p != nil; p = p->link) {
-		p->back = 2;	// use short branches first time through
-		if((q = p->pcond) != nil && (q->back & 2))
-			p->back |= 1;	// backward jump
-
-		if(p->as == AADJSP) {
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_SP;
-			v = -p->from.offset;
-			p->from.offset = v;
-			p->as = AADDL;
-			if(v < 0) {
-				p->as = ASUBL;
-				v = -v;
-				p->from.offset = v;
-			}
-			if(v == 0)
-				p->as = ANOP;
-		}
-	}
-	
-	n = 0;
-	do {
-		loop = 0;
-		memset(s->r, 0, s->nr*sizeof s->r[0]);
-		s->nr = 0;
-		s->np = 0;
-		c = 0;
-		for(p = s->text; p != nil; p = p->link) {
-			if(ctxt->headtype == Hnacl && p->isize > 0) {
-				static LSym *deferreturn;
-				
-				if(deferreturn == nil)
-					deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
-
-				// pad everything to avoid crossing 32-byte boundary
-				if((c>>5) != ((c+p->isize-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-				// pad call deferreturn to start at 32-byte boundary
-				// so that subtracting 5 in jmpdefer will jump back
-				// to that boundary and rerun the call.
-				if(p->as == ACALL && p->to.sym == deferreturn)
-					c = naclpad(ctxt, s, c, -c&31);
-				// pad call to end at 32-byte boundary
-				if(p->as == ACALL)
-					c = naclpad(ctxt, s, c, -(c+p->isize)&31);
-				
-				// the linker treats REP and STOSQ as different instructions
-				// but in fact the REP is a prefix on the STOSQ.
-				// make sure REP has room for 2 more bytes, so that
-				// padding will not be inserted before the next instruction.
-				if(p->as == AREP && (c>>5) != ((c+3-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-				
-				// same for LOCK.
-				// various instructions follow; the longest is 4 bytes.
-				// give ourselves 8 bytes so as to avoid surprises.
-				if(p->as == ALOCK && (c>>5) != ((c+8-1)>>5))
-					c = naclpad(ctxt, s, c, -c&31);
-			}
-			
-			p->pc = c;
-
-			// process forward jumps to p
-			for(q = p->comefrom; q != nil; q = q->forwd) {
-				v = p->pc - (q->pc + q->mark);
-				if(q->back & 2)	{	// short
-					if(v > 127) {
-						loop++;
-						q->back ^= 2;
-					}
-					if(q->as == AJCXZW)
-						s->p[q->pc+2] = v;
-					else
-						s->p[q->pc+1] = v;
-				} else {
-					bp = s->p + q->pc + q->mark - 4;
-					*bp++ = v;
-					*bp++ = v>>8;
-					*bp++ = v>>16;
-					*bp = v>>24;
-				}	
-			}
-			p->comefrom = nil;
-
-			p->pc = c;
-			asmins(ctxt, p);
-			m = ctxt->andptr-ctxt->and;
-			if(p->isize != m) {
-				p->isize = m;
-				loop++;
-			}
-			symgrow(ctxt, s, p->pc+m);
-			memmove(s->p+p->pc, ctxt->and, m);
-			p->mark = m;
-			c += m;
-		}
-		if(++n > 20) {
-			ctxt->diag("span must be looping");
-			sysfatal("bad code");
-		}
-	} while(loop);
-	
-	if(ctxt->headtype == Hnacl)
-		c = naclpad(ctxt, s, c, -c&31);
-	c += -c&(FuncAlign-1);
-	s->size = c;
-
-	if(0 /* debug['a'] > 1 */) {
-		print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
-		for(i=0; i<s->np; i++) {
-			print(" %.2ux", s->p[i]);
-			if(i%16 == 15)
-				print("\n  %.6ux", i+1);
-		}
-		if(i%16)
-			print("\n");
-	
-		for(i=0; i<s->nr; i++) {
-			Reloc *r;
-			
-			r = &s->r[i];
-			print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
-		}
-	}
-}
-
-static void
-instinit(void)
-{
-	int i, c;
-
-	for(i=1; optab[i].as; i++) {
-		c = optab[i].as;
-		if(opindex[c] != nil)
-			sysfatal("phase error in optab: %d (%A)", i, c);
-		opindex[c] = &optab[i];
-	}
-
-	for(i=0; i<Ymax; i++)
-		ycover[i*Ymax + i] = 1;
-
-	ycover[Yi0*Ymax + Yi8] = 1;
-	ycover[Yi1*Ymax + Yi8] = 1;
-
-	ycover[Yi0*Ymax + Yi32] = 1;
-	ycover[Yi1*Ymax + Yi32] = 1;
-	ycover[Yi8*Ymax + Yi32] = 1;
-
-	ycover[Yal*Ymax + Yrb] = 1;
-	ycover[Ycl*Ymax + Yrb] = 1;
-	ycover[Yax*Ymax + Yrb] = 1;
-	ycover[Ycx*Ymax + Yrb] = 1;
-	ycover[Yrx*Ymax + Yrb] = 1;
-
-	ycover[Yax*Ymax + Yrx] = 1;
-	ycover[Ycx*Ymax + Yrx] = 1;
-
-	ycover[Yax*Ymax + Yrl] = 1;
-	ycover[Ycx*Ymax + Yrl] = 1;
-	ycover[Yrx*Ymax + Yrl] = 1;
-
-	ycover[Yf0*Ymax + Yrf] = 1;
-
-	ycover[Yal*Ymax + Ymb] = 1;
-	ycover[Ycl*Ymax + Ymb] = 1;
-	ycover[Yax*Ymax + Ymb] = 1;
-	ycover[Ycx*Ymax + Ymb] = 1;
-	ycover[Yrx*Ymax + Ymb] = 1;
-	ycover[Yrb*Ymax + Ymb] = 1;
-	ycover[Ym*Ymax + Ymb] = 1;
-
-	ycover[Yax*Ymax + Yml] = 1;
-	ycover[Ycx*Ymax + Yml] = 1;
-	ycover[Yrx*Ymax + Yml] = 1;
-	ycover[Yrl*Ymax + Yml] = 1;
-	ycover[Ym*Ymax + Yml] = 1;
-
-	ycover[Yax*Ymax + Ymm] = 1;
-	ycover[Ycx*Ymax + Ymm] = 1;
-	ycover[Yrx*Ymax + Ymm] = 1;
-	ycover[Yrl*Ymax + Ymm] = 1;
-	ycover[Ym*Ymax + Ymm] = 1;
-	ycover[Ymr*Ymax + Ymm] = 1;
-
-	ycover[Ym*Ymax + Yxm] = 1;
-	ycover[Yxr*Ymax + Yxm] = 1;
-
-	for(i=0; i<MAXREG; i++) {
-		reg[i] = -1;
-		if(i >= REG_AL && i <= REG_BH)
-			reg[i] = (i-REG_AL) & 7;
-		if(i >= REG_AX && i <= REG_DI)
-			reg[i] = (i-REG_AX) & 7;
-		if(i >= REG_F0 && i <= REG_F0+7)
-			reg[i] = (i-REG_F0) & 7;
-		if(i >= REG_X0 && i <= REG_X0+7)
-			reg[i] = (i-REG_X0) & 7;
-	}
-}
-
-static int
-prefixof(Link *ctxt, Addr *a)
-{
-	if(a->type == TYPE_MEM && a->name == NAME_NONE) {
-		switch(a->reg) {
-		case REG_CS:
-			return 0x2e;
-		case REG_DS:
-			return 0x3e;
-		case REG_ES:
-			return 0x26;
-		case REG_FS:
-			return 0x64;
-		case REG_GS:
-			return 0x65;
-		case REG_TLS:
-			// NOTE: Systems listed here should be only systems that
-			// support direct TLS references like 8(TLS) implemented as
-			// direct references from FS or GS. Systems that require
-			// the initial-exec model, where you load the TLS base into
-			// a register and then index from that register, do not reach
-			// this code and should not be listed.
-			switch(ctxt->headtype) {
-			default:
-				sysfatal("unknown TLS base register for %s", headstr(ctxt->headtype));
-			case Hdarwin:
-			case Hdragonfly:
-			case Hfreebsd:
-			case Hnetbsd:
-			case Hopenbsd:
-				return 0x65; // GS
-			}
-		}
-	}
-	return 0;
-}
-
-static int
-oclass(Link *ctxt, Prog *p, Addr *a)
-{
-	int32 v;
-
-	USED(p);
-
-	// TODO(rsc): This special case is for SHRQ $3, AX:DX,
-	// which encodes as SHRQ $32(DX*0), AX.
-	// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
-	// Change encoding and remove.
-	if((a->type == TYPE_CONST || a->type == TYPE_REG) && a->index != REG_NONE && a->scale == 0)
-		return Ycol;
-
-	switch(a->type) {
-	case TYPE_NONE:
-		return Ynone;
-
-	case TYPE_BRANCH:
-		return Ybr;
-	
-	case TYPE_INDIR:
-		// TODO(rsc): Why this is also Ycol is a mystery. Should split the two meanings.
-		if(a->name != NAME_NONE && a->reg == REG_NONE && a->index == REG_NONE && a->scale == 0)
-			return Ycol;
-		return Yxxx;
-
-	case TYPE_MEM:
-		return Ym;
-
-	case TYPE_ADDR:
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			return Yi32;
-		case NAME_AUTO:
-		case NAME_PARAM:
-			return Yiauto;
-		}
-
-		// DUFFZERO/DUFFCOPY encoding forgot to set a->index
-		// and got Yi32 in an earlier version of this code.
-		// Keep doing that until we fix yduff etc.
-		if(a->sym != nil && strncmp(a->sym->name, "runtime.duff", 12) == 0)
-			return Yi32;
-		
-		if(a->sym != nil || a->name != NAME_NONE)
-			ctxt->diag("unexpected addr: %D", a);
-		// fall through
-
-	case TYPE_CONST:
-		if(a->sym != nil)
-			ctxt->diag("TYPE_CONST with symbol: %D", a);
-
-		v = a->offset;
-		if(v == 0)
-			return Yi0;
-		if(v == 1)
-			return Yi1;
-		if(v >= -128 && v <= 127)
-			return Yi8;
-		return Yi32;
-
-	case TYPE_TEXTSIZE:
-		return Ytextsize;
-	}
-
-	if(a->type != TYPE_REG) {
-		ctxt->diag("unexpected addr1: type=%d %D", a->type, a);
-		return Yxxx;
-	}
-
-	switch(a->reg) {
-	case REG_AL:
-		return Yal;
-
-	case REG_AX:
-		return Yax;
-
-	case REG_CL:
-	case REG_DL:
-	case REG_BL:
-	case REG_AH:
-	case REG_CH:
-	case REG_DH:
-	case REG_BH:
-		return Yrb;
-
-	case REG_CX:
-		return Ycx;
-
-	case REG_DX:
-	case REG_BX:
-		return Yrx;
-
-	case REG_SP:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		return Yrl;
-
-	case REG_F0+0:
-		return	Yf0;
-
-	case REG_F0+1:
-	case REG_F0+2:
-	case REG_F0+3:
-	case REG_F0+4:
-	case REG_F0+5:
-	case REG_F0+6:
-	case REG_F0+7:
-		return	Yrf;
-
-	case REG_X0+0:
-	case REG_X0+1:
-	case REG_X0+2:
-	case REG_X0+3:
-	case REG_X0+4:
-	case REG_X0+5:
-	case REG_X0+6:
-	case REG_X0+7:
-		return	Yxr;
-
-	case REG_CS:	return	Ycs;
-	case REG_SS:	return	Yss;
-	case REG_DS:	return	Yds;
-	case REG_ES:	return	Yes;
-	case REG_FS:	return	Yfs;
-	case REG_GS:	return	Ygs;
-	case REG_TLS:	return	Ytls;
-
-	case REG_GDTR:	return	Ygdtr;
-	case REG_IDTR:	return	Yidtr;
-	case REG_LDTR:	return	Yldtr;
-	case REG_MSW:	return	Ymsw;
-	case REG_TASK:	return	Ytask;
-
-	case REG_CR+0:	return	Ycr0;
-	case REG_CR+1:	return	Ycr1;
-	case REG_CR+2:	return	Ycr2;
-	case REG_CR+3:	return	Ycr3;
-	case REG_CR+4:	return	Ycr4;
-	case REG_CR+5:	return	Ycr5;
-	case REG_CR+6:	return	Ycr6;
-	case REG_CR+7:	return	Ycr7;
-
-	case REG_DR+0:	return	Ydr0;
-	case REG_DR+1:	return	Ydr1;
-	case REG_DR+2:	return	Ydr2;
-	case REG_DR+3:	return	Ydr3;
-	case REG_DR+4:	return	Ydr4;
-	case REG_DR+5:	return	Ydr5;
-	case REG_DR+6:	return	Ydr6;
-	case REG_DR+7:	return	Ydr7;
-
-	case REG_TR+0:	return	Ytr0;
-	case REG_TR+1:	return	Ytr1;
-	case REG_TR+2:	return	Ytr2;
-	case REG_TR+3:	return	Ytr3;
-	case REG_TR+4:	return	Ytr4;
-	case REG_TR+5:	return	Ytr5;
-	case REG_TR+6:	return	Ytr6;
-	case REG_TR+7:	return	Ytr7;
-
-	}
-	return Yxxx;
-}
-
-static void
-asmidx(Link *ctxt, int scale, int index, int base)
-{
-	int i;
-
-	switch(index) {
-	default:
-		goto bad;
-
-	case TYPE_NONE:
-		i = 4 << 3;
-		goto bas;
-
-	case REG_AX:
-	case REG_CX:
-	case REG_DX:
-	case REG_BX:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		i = reg[index] << 3;
-		break;
-	}
-	switch(scale) {
-	default:
-		goto bad;
-	case 1:
-		break;
-	case 2:
-		i |= (1<<6);
-		break;
-	case 4:
-		i |= (2<<6);
-		break;
-	case 8:
-		i |= (3<<6);
-		break;
-	}
-bas:
-	switch(base) {
-	default:
-		goto bad;
-	case REG_NONE:	/* must be mod=00 */
-		i |= 5;
-		break;
-	case REG_AX:
-	case REG_CX:
-	case REG_DX:
-	case REG_BX:
-	case REG_SP:
-	case REG_BP:
-	case REG_SI:
-	case REG_DI:
-		i |= reg[base];
-		break;
-	}
-	*ctxt->andptr++ = i;
-	return;
-bad:
-	ctxt->diag("asmidx: bad address %d,%d,%d", scale, index, base);
-	*ctxt->andptr++ = 0;
-	return;
-}
-
-static void
-put4(Link *ctxt, int32 v)
-{
-	ctxt->andptr[0] = v;
-	ctxt->andptr[1] = v>>8;
-	ctxt->andptr[2] = v>>16;
-	ctxt->andptr[3] = v>>24;
-	ctxt->andptr += 4;
-}
-
-static void
-relput4(Link *ctxt, Prog *p, Addr *a)
-{
-	vlong v;
-	Reloc rel, *r;
-	
-	v = vaddr(ctxt, p, a, &rel);
-	if(rel.siz != 0) {
-		if(rel.siz != 4)
-			ctxt->diag("bad reloc");
-		r = addrel(ctxt->cursym);
-		*r = rel;
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-	}
-	put4(ctxt, v);
-}
-
-static int32
-vaddr(Link *ctxt, Prog *p, Addr *a, Reloc *r)
-{
-	LSym *s;
-	
-	USED(p);
-
-	if(r != nil)
-		memset(r, 0, sizeof *r);
-
-	switch(a->name) {
-	case NAME_STATIC:
-	case NAME_EXTERN:
-		s = a->sym;
-		if(s != nil) {
-			if(r == nil) {
-				ctxt->diag("need reloc for %D", a);
-				sysfatal("bad code");
-			}
-			r->type = R_ADDR;
-			r->siz = 4;
-			r->off = -1;
-			r->sym = s;
-			r->add = a->offset;
-			return 0;
-		}
-		return a->offset;
-	}
-	
-	if((a->type == TYPE_MEM || a->type == TYPE_ADDR) && a->reg == REG_TLS) {
-		if(r == nil) {
-			ctxt->diag("need reloc for %D", a);
-			sysfatal("bad code");
-		}
-		r->type = R_TLS_LE;
-		r->siz = 4;
-		r->off = -1; // caller must fill in
-		r->add = a->offset;
-		return 0;
-	}
-
-	return a->offset;
-}
-
-static void
-asmand(Link *ctxt, Prog *p, Addr *a, int r)
-{
-	int32 v;
-	int base;
-	Reloc rel;
-	
-	USED(p);
-
-	v = a->offset;
-	rel.siz = 0;
-
-	switch(a->type) {
-	case TYPE_ADDR:
-		if(a->name == NAME_NONE)
-			ctxt->diag("unexpected TYPE_ADDR with NAME_NONE");
-		if(a->index == REG_TLS)
-			ctxt->diag("unexpected TYPE_ADDR with index==REG_TLS");
-		goto bad;
-	
-	case TYPE_REG:
-		if((a->reg < REG_AL || REG_F7 < a->reg) && (a->reg < REG_X0 || REG_X0+7 < a->reg))
-			goto bad;
-		if(v)
-			goto bad;
-		*ctxt->andptr++ = (3 << 6) | (reg[a->reg] << 0) | (r << 3);
-		return;
-	}
-
-	if(a->type != TYPE_MEM)
-		goto bad;
-
-	if(a->index != REG_NONE && a->index != REG_TLS) {
-		base = a->reg;
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			base = REG_NONE;
-			v = vaddr(ctxt, p, a, &rel);
-			break;
-		case NAME_AUTO:
-		case NAME_PARAM:
-			base = REG_SP;
-			break;
-		}
-
-		if(base == REG_NONE) {
-			*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			goto putrelv;
-		}
-		if(v == 0 && rel.siz == 0 && base != REG_BP) {
-			*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			return;
-		}
-		if(v >= -128 && v < 128 && rel.siz == 0) {
-			*ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, a->index, base);
-			*ctxt->andptr++ = v;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
-		asmidx(ctxt, a->scale, a->index, base);
-		goto putrelv;
-	}
-
-	base = a->reg;
-	switch(a->name) {
-	case NAME_STATIC:
-	case NAME_EXTERN:
-		base = REG_NONE;
-		v = vaddr(ctxt, p, a, &rel);
-		break;
-	case NAME_AUTO:
-	case NAME_PARAM:
-		base = REG_SP;
-		break;
-	}
-	
-	if(base == REG_TLS)
-		v = vaddr(ctxt, p, a, &rel);
-	
-	if(base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS) {
-		*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
-		goto putrelv;
-	}
-
-	if(base == REG_SP) {
-		if(v == 0 && rel.siz == 0) {
-			*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, REG_NONE, base);
-			return;
-		}
-		if(v >= -128 && v < 128 && rel.siz == 0) {
-			*ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
-			asmidx(ctxt, a->scale, REG_NONE, base);
-			*ctxt->andptr++ = v;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
-		asmidx(ctxt, a->scale, REG_NONE, base);
-		goto putrelv;
-	}
-
-	if(REG_AX <= base && base <= REG_DI) {
-		if(a->index == REG_TLS) {
-			memset(&rel, 0, sizeof rel);
-			rel.type = R_TLS_IE;
-			rel.siz = 4;
-			rel.sym = nil;
-			rel.add = v;
-			v = 0;
-		}
-		if(v == 0 && rel.siz == 0 && base != REG_BP) {
-			*ctxt->andptr++ = (0 << 6) | (reg[base] << 0) | (r << 3);
-			return;
-		}
-		if(v >= -128 && v < 128 && rel.siz == 0)  {
-			ctxt->andptr[0] = (1 << 6) | (reg[base] << 0) | (r << 3);
-			ctxt->andptr[1] = v;
-			ctxt->andptr += 2;
-			return;
-		}
-		*ctxt->andptr++ = (2 << 6) | (reg[base] << 0) | (r << 3);
-		goto putrelv;
-	}
-	goto bad;
-
-putrelv:
-	if(rel.siz != 0) {
-		Reloc *r;
-		
-		if(rel.siz != 4) {
-			ctxt->diag("bad rel");
-			goto bad;
-		}
-		r = addrel(ctxt->cursym);
-		*r = rel;
-		r->off = ctxt->curp->pc + ctxt->andptr - ctxt->and;
-	}
-
-	put4(ctxt, v);
-	return;
-
-bad:
-	ctxt->diag("asmand: bad address %D", a);
-	return;
-}
-
-enum
-{
-	E = 0xff,
-};
-
-static uchar	ymovtab[] =
-{
-/* push */
-	APUSHL,	Ycs,	Ynone,	0,	0x0e,E,0,0,
-	APUSHL,	Yss,	Ynone,	0,	0x16,E,0,0,
-	APUSHL,	Yds,	Ynone,	0,	0x1e,E,0,0,
-	APUSHL,	Yes,	Ynone,	0,	0x06,E,0,0,
-	APUSHL,	Yfs,	Ynone,	0,	0x0f,0xa0,E,0,
-	APUSHL,	Ygs,	Ynone,	0,	0x0f,0xa8,E,0,
-
-	APUSHW,	Ycs,	Ynone,	0,	Pe,0x0e,E,0,
-	APUSHW,	Yss,	Ynone,	0,	Pe,0x16,E,0,
-	APUSHW,	Yds,	Ynone,	0,	Pe,0x1e,E,0,
-	APUSHW,	Yes,	Ynone,	0,	Pe,0x06,E,0,
-	APUSHW,	Yfs,	Ynone,	0,	Pe,0x0f,0xa0,E,
-	APUSHW,	Ygs,	Ynone,	0,	Pe,0x0f,0xa8,E,
-
-/* pop */
-	APOPL,	Ynone,	Yds,	0,	0x1f,E,0,0,
-	APOPL,	Ynone,	Yes,	0,	0x07,E,0,0,
-	APOPL,	Ynone,	Yss,	0,	0x17,E,0,0,
-	APOPL,	Ynone,	Yfs,	0,	0x0f,0xa1,E,0,
-	APOPL,	Ynone,	Ygs,	0,	0x0f,0xa9,E,0,
-
-	APOPW,	Ynone,	Yds,	0,	Pe,0x1f,E,0,
-	APOPW,	Ynone,	Yes,	0,	Pe,0x07,E,0,
-	APOPW,	Ynone,	Yss,	0,	Pe,0x17,E,0,
-	APOPW,	Ynone,	Yfs,	0,	Pe,0x0f,0xa1,E,
-	APOPW,	Ynone,	Ygs,	0,	Pe,0x0f,0xa9,E,
-
-/* mov seg */
-	AMOVW,	Yes,	Yml,	1,	0x8c,0,0,0,
-	AMOVW,	Ycs,	Yml,	1,	0x8c,1,0,0,
-	AMOVW,	Yss,	Yml,	1,	0x8c,2,0,0,
-	AMOVW,	Yds,	Yml,	1,	0x8c,3,0,0,
-	AMOVW,	Yfs,	Yml,	1,	0x8c,4,0,0,
-	AMOVW,	Ygs,	Yml,	1,	0x8c,5,0,0,
-
-	AMOVW,	Yml,	Yes,	2,	0x8e,0,0,0,
-	AMOVW,	Yml,	Ycs,	2,	0x8e,1,0,0,
-	AMOVW,	Yml,	Yss,	2,	0x8e,2,0,0,
-	AMOVW,	Yml,	Yds,	2,	0x8e,3,0,0,
-	AMOVW,	Yml,	Yfs,	2,	0x8e,4,0,0,
-	AMOVW,	Yml,	Ygs,	2,	0x8e,5,0,0,
-
-/* mov cr */
-	AMOVL,	Ycr0,	Yml,	3,	0x0f,0x20,0,0,
-	AMOVL,	Ycr2,	Yml,	3,	0x0f,0x20,2,0,
-	AMOVL,	Ycr3,	Yml,	3,	0x0f,0x20,3,0,
-	AMOVL,	Ycr4,	Yml,	3,	0x0f,0x20,4,0,
-
-	AMOVL,	Yml,	Ycr0,	4,	0x0f,0x22,0,0,
-	AMOVL,	Yml,	Ycr2,	4,	0x0f,0x22,2,0,
-	AMOVL,	Yml,	Ycr3,	4,	0x0f,0x22,3,0,
-	AMOVL,	Yml,	Ycr4,	4,	0x0f,0x22,4,0,
-
-/* mov dr */
-	AMOVL,	Ydr0,	Yml,	3,	0x0f,0x21,0,0,
-	AMOVL,	Ydr6,	Yml,	3,	0x0f,0x21,6,0,
-	AMOVL,	Ydr7,	Yml,	3,	0x0f,0x21,7,0,
-
-	AMOVL,	Yml,	Ydr0,	4,	0x0f,0x23,0,0,
-	AMOVL,	Yml,	Ydr6,	4,	0x0f,0x23,6,0,
-	AMOVL,	Yml,	Ydr7,	4,	0x0f,0x23,7,0,
-
-/* mov tr */
-	AMOVL,	Ytr6,	Yml,	3,	0x0f,0x24,6,0,
-	AMOVL,	Ytr7,	Yml,	3,	0x0f,0x24,7,0,
-
-	AMOVL,	Yml,	Ytr6,	4,	0x0f,0x26,6,E,
-	AMOVL,	Yml,	Ytr7,	4,	0x0f,0x26,7,E,
-
-/* lgdt, sgdt, lidt, sidt */
-	AMOVL,	Ym,	Ygdtr,	4,	0x0f,0x01,2,0,
-	AMOVL,	Ygdtr,	Ym,	3,	0x0f,0x01,0,0,
-	AMOVL,	Ym,	Yidtr,	4,	0x0f,0x01,3,0,
-	AMOVL,	Yidtr,	Ym,	3,	0x0f,0x01,1,0,
-
-/* lldt, sldt */
-	AMOVW,	Yml,	Yldtr,	4,	0x0f,0x00,2,0,
-	AMOVW,	Yldtr,	Yml,	3,	0x0f,0x00,0,0,
-
-/* lmsw, smsw */
-	AMOVW,	Yml,	Ymsw,	4,	0x0f,0x01,6,0,
-	AMOVW,	Ymsw,	Yml,	3,	0x0f,0x01,4,0,
-
-/* ltr, str */
-	AMOVW,	Yml,	Ytask,	4,	0x0f,0x00,3,0,
-	AMOVW,	Ytask,	Yml,	3,	0x0f,0x00,1,0,
-
-/* load full pointer */
-	AMOVL,	Yml,	Ycol,	5,	0,0,0,0,
-	AMOVW,	Yml,	Ycol,	5,	Pe,0,0,0,
-
-/* double shift */
-	ASHLL,	Ycol,	Yml,	6,	0xa4,0xa5,0,0,
-	ASHRL,	Ycol,	Yml,	6,	0xac,0xad,0,0,
-
-/* extra imul */
-	AIMULW,	Yml,	Yrl,	7,	Pq,0xaf,0,0,
-	AIMULL,	Yml,	Yrl,	7,	Pm,0xaf,0,0,
-
-/* load TLS base pointer */
-	AMOVL,	Ytls,	Yrl,	8,	0,0,0,0,
-
-	0
-};
-
-// byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
-// which is not referenced in a.
-// If a is empty, it returns BX to account for MULB-like instructions
-// that might use DX and AX.
-static int
-byteswapreg(Link *ctxt, Addr *a)
-{
-	int cana, canb, canc, cand;
-
-	cana = canb = canc = cand = 1;
-
-	if(a->type == TYPE_NONE)
-		cana = cand = 0;
-
-	if(a->type == TYPE_REG || ((a->type == TYPE_MEM || a->type == TYPE_ADDR) && a->name == NAME_NONE)) {
-		switch(a->reg) {
-		case REG_NONE:
-			cana = cand = 0;
-			break;
-		case REG_AX:
-		case REG_AL:
-		case REG_AH:
-			cana = 0;
-			break;
-		case REG_BX:
-		case REG_BL:
-		case REG_BH:
-			canb = 0;
-			break;
-		case REG_CX:
-		case REG_CL:
-		case REG_CH:
-			canc = 0;
-			break;
-		case REG_DX:
-		case REG_DL:
-		case REG_DH:
-			cand = 0;
-			break;
-		}
-	}
-	if(a->type == TYPE_MEM || a->type == TYPE_ADDR) {
-		switch(a->index) {
-		case REG_AX:
-			cana = 0;
-			break;
-		case REG_BX:
-			canb = 0;
-			break;
-		case REG_CX:
-			canc = 0;
-			break;
-		case REG_DX:
-			cand = 0;
-			break;
-		}
-	}
-	if(cana)
-		return REG_AX;
-	if(canb)
-		return REG_BX;
-	if(canc)
-		return REG_CX;
-	if(cand)
-		return REG_DX;
-
-	ctxt->diag("impossible byte register");
-	sysfatal("bad code");
-	return 0;
-}
-
-static void
-subreg(Prog *p, int from, int to)
-{
-	if(0 /* debug['Q'] */)
-		print("\n%P	s/%R/%R/\n", p, from, to);
-
-	if(p->from.reg == from) {
-		p->from.reg = to;
-		p->ft = 0;
-	}
-	if(p->to.reg == from) {
-		p->to.reg = to;
-		p->tt = 0;
-	}
-
-	if(p->from.index == from) {
-		p->from.index = to;
-		p->ft = 0;
-	}
-	if(p->to.index == from) {
-		p->to.index = to;
-		p->tt = 0;
-	}
-
-	if(0 /* debug['Q'] */)
-		print("%P\n", p);
-}
-
-static int
-mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
-{
-	switch(op){
-	case Pm:
-	case Pe:
-	case Pf2:
-	case Pf3:
-		if(osize != 1){
-			if(op != Pm)
-				*ctxt->andptr++ = op;
-			*ctxt->andptr++ = Pm;
-			op = o->op[++z];
-			break;
-		}
-	default:
-		if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
-			*ctxt->andptr++ = Pm;
-		break;
-	}
-	*ctxt->andptr++ = op;
-	return z;
-}
-
-static void
-doasm(Link *ctxt, Prog *p)
-{
-	Optab *o;
-	Prog *q, pp;
-	uchar *t;
-	int z, op, ft, tt, breg;
-	int32 v, pre;
-	Reloc rel, *r;
-	Addr *a;
-	
-	ctxt->curp = p;	// TODO
-
-	pre = prefixof(ctxt, &p->from);
-	if(pre)
-		*ctxt->andptr++ = pre;
-	pre = prefixof(ctxt, &p->to);
-	if(pre)
-		*ctxt->andptr++ = pre;
-
-	if(p->ft == 0)
-		p->ft = oclass(ctxt, p, &p->from);
-	if(p->tt == 0)
-		p->tt = oclass(ctxt, p, &p->to);
-
-	ft = p->ft * Ymax;
-	tt = p->tt * Ymax;
-	o = opindex[p->as];
-	t = o->ytab;
-	if(t == 0) {
-		ctxt->diag("asmins: noproto %P", p);
-		return;
-	}
-	for(z=0; *t; z+=t[3],t+=4)
-		if(ycover[ft+t[0]])
-		if(ycover[tt+t[1]])
-			goto found;
-	goto domov;
-
-found:
-	switch(o->prefix) {
-	case Pq:	/* 16 bit escape and opcode escape */
-		*ctxt->andptr++ = Pe;
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pf2:	/* xmm opcode escape */
-	case Pf3:
-		*ctxt->andptr++ = o->prefix;
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pm:	/* opcode escape */
-		*ctxt->andptr++ = Pm;
-		break;
-
-	case Pe:	/* 16 bit escape */
-		*ctxt->andptr++ = Pe;
-		break;
-
-	case Pb:	/* botch */
-		break;
-	}
-
-	op = o->op[z];
-	switch(t[2]) {
-	default:
-		ctxt->diag("asmins: unknown z %d %P", t[2], p);
-		return;
-
-	case Zpseudo:
-		break;
-
-	case Zlit:
-		for(; op = o->op[z]; z++)
-			*ctxt->andptr++ = op;
-		break;
-
-	case Zlitm_r:
-		for(; op = o->op[z]; z++)
-			*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-
-	case Zm_r:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-
-	case Zm2_r:
-		*ctxt->andptr++ = op;
-		*ctxt->andptr++ = o->op[z+1];
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-
-	case Zm_r_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-
-	case Zm_r_i_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		*ctxt->andptr++ = p->to.offset;
-		break;
-
-	case Zibm_r:
-		while ((op = o->op[z++]) != 0)
-			*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		*ctxt->andptr++ = p->to.offset;
-		break;
-
-	case Zaut_r:
-		*ctxt->andptr++ = 0x8d;	/* leal */
-		if(p->from.type != TYPE_ADDR)
-			ctxt->diag("asmins: Zaut sb type ADDR");
-		p->from.type = TYPE_MEM;
-		p->ft = 0;
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		p->from.type = TYPE_ADDR;
-		p->ft = 0;
-		break;
-
-	case Zm_o:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, o->op[z+1]);
-		break;
-
-	case Zr_m:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, reg[p->from.reg]);
-		break;
-
-	case Zr_m_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->to, reg[p->from.reg]);
-		break;
-
-	case Zr_m_i_xm:
-		mediaop(ctxt, o, op, t[3], z);
-		asmand(ctxt, p, &p->to, reg[p->from.reg]);
-		*ctxt->andptr++ = p->from.offset;
-		break;
-
-	case Zcallindreg:
-		r = addrel(ctxt->cursym);
-		r->off = p->pc;
-		r->type = R_CALLIND;
-		r->siz = 0;
-		// fallthrough
-	case Zo_m:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, o->op[z+1]);
-		break;
-
-	case Zm_ibo:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->from, o->op[z+1]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->to, nil);
-		break;
-
-	case Zibo_m:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, o->op[z+1]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Z_ib:
-	case Zib_:
-		if(t[2] == Zib_)
-			a = &p->from;
-		else
-			a = &p->to;
-		v = vaddr(ctxt, p, a, nil);
-		*ctxt->andptr++ = op;
-		*ctxt->andptr++ = v;
-		break;
-
-	case Zib_rp:
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Zil_rp:
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, &p->from, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, &p->from);
-		break;
-
-	case Zib_rr:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, reg[p->to.reg]);
-		*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
-		break;
-
-	case Z_il:
-	case Zil_:
-		if(t[2] == Zil_)
-			a = &p->from;
-		else
-			a = &p->to;
-		*ctxt->andptr++ = op;
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, a, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, a);
-		break;
-
-	case Zm_ilo:
-	case Zilo_m:
-		*ctxt->andptr++ = op;
-		if(t[2] == Zilo_m) {
-			a = &p->from;
-			asmand(ctxt, p, &p->to, o->op[z+1]);
-		} else {
-			a = &p->to;
-			asmand(ctxt, p, &p->from, o->op[z+1]);
-		}
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, a, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, a);
-		break;
-
-	case Zil_rr:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, reg[p->to.reg]);
-		if(o->prefix == Pe) {
-			v = vaddr(ctxt, p, &p->from, nil);
-			*ctxt->andptr++ = v;
-			*ctxt->andptr++ = v>>8;
-		}
-		else
-			relput4(ctxt, p, &p->from);
-		break;
-
-	case Z_rp:
-		*ctxt->andptr++ = op + reg[p->to.reg];
-		break;
-
-	case Zrp_:
-		*ctxt->andptr++ = op + reg[p->from.reg];
-		break;
-
-	case Zclr:
-		*ctxt->andptr++ = op;
-		asmand(ctxt, p, &p->to, reg[p->to.reg]);
-		break;
-	
-	case Zcall:
-		if(p->to.sym == nil) {
-			ctxt->diag("call without target");
-			sysfatal("bad code");
-		}
-		*ctxt->andptr++ = op;
-		r = addrel(ctxt->cursym);
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-		r->type = R_CALL;
-		r->siz = 4;
-		r->sym = p->to.sym;
-		r->add = p->to.offset;
-		put4(ctxt, 0);
-		break;
-
-	case Zbr:
-	case Zjmp:
-	case Zloop:
-		if(p->to.sym != nil) {
-			if(t[2] != Zjmp) {
-				ctxt->diag("branch to ATEXT");
-				sysfatal("bad code");
-			}
-			*ctxt->andptr++ = o->op[z+1];
-			r = addrel(ctxt->cursym);
-			r->off = p->pc + ctxt->andptr - ctxt->and;
-			r->sym = p->to.sym;
-			r->type = R_PCREL;
-			r->siz = 4;
-			put4(ctxt, 0);
-			break;
-		}
-
-		// Assumes q is in this function.
-		// Fill in backward jump now.
-		q = p->pcond;
-		if(q == nil) {
-			ctxt->diag("jmp/branch/loop without target");
-			sysfatal("bad code");
-		}
-		if(p->back & 1) {
-			v = q->pc - (p->pc + 2);
-			if(v >= -128) {
-				if(p->as == AJCXZW)
-					*ctxt->andptr++ = 0x67;
-				*ctxt->andptr++ = op;
-				*ctxt->andptr++ = v;
-			} else if(t[2] == Zloop) {
-				ctxt->diag("loop too far: %P", p);
-			} else {
-				v -= 5-2;
-				if(t[2] == Zbr) {
-					*ctxt->andptr++ = 0x0f;
-					v--;
-				}
-				*ctxt->andptr++ = o->op[z+1];
-				*ctxt->andptr++ = v;
-				*ctxt->andptr++ = v>>8;
-				*ctxt->andptr++ = v>>16;
-				*ctxt->andptr++ = v>>24;
-			}
-			break;
-		}
-
-		// Annotate target; will fill in later.
-		p->forwd = q->comefrom;
-		q->comefrom = p;
-		if(p->back & 2)	{ // short
-			if(p->as == AJCXZW)
-				*ctxt->andptr++ = 0x67;
-			*ctxt->andptr++ = op;
-			*ctxt->andptr++ = 0;
-		} else if(t[2] == Zloop) {
-			ctxt->diag("loop too far: %P", p);
-		} else {
-			if(t[2] == Zbr)
-				*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = o->op[z+1];
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-			*ctxt->andptr++ = 0;
-		}
-		break;
-
-	case Zcallcon:
-	case Zjmpcon:
-		if(t[2] == Zcallcon)
-			*ctxt->andptr++ = op;
-		else
-			*ctxt->andptr++ = o->op[z+1];
-		r = addrel(ctxt->cursym);
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-		r->type = R_PCREL;
-		r->siz = 4;
-		r->add = p->to.offset;
-		put4(ctxt, 0);
-		break;
-	
-	case Zcallind:
-		*ctxt->andptr++ = op;
-		*ctxt->andptr++ = o->op[z+1];
-		r = addrel(ctxt->cursym);
-		r->off = p->pc + ctxt->andptr - ctxt->and;
-		r->type = R_ADDR;
-		r->siz = 4;
-		r->add = p->to.offset;
-		r->sym = p->to.sym;
-		put4(ctxt, 0);
-		break;
-
-	case Zbyte:
-		v = vaddr(ctxt, p, &p->from, &rel);
-		if(rel.siz != 0) {
-			rel.siz = op;
-			r = addrel(ctxt->cursym);
-			*r = rel;
-			r->off = p->pc + ctxt->andptr - ctxt->and;
-		}
-		*ctxt->andptr++ = v;
-		if(op > 1) {
-			*ctxt->andptr++ = v>>8;
-			if(op > 2) {
-				*ctxt->andptr++ = v>>16;
-				*ctxt->andptr++ = v>>24;
-			}
-		}
-		break;
-
-	case Zmov:
-		goto domov;
-	}
-	return;
-
-domov:
-	for(t=ymovtab; *t; t+=8)
-		if(p->as == t[0])
-		if(ycover[ft+t[1]])
-		if(ycover[tt+t[2]])
-			goto mfound;
-bad:
-	/*
-	 * here, the assembly has failed.
-	 * if its a byte instruction that has
-	 * unaddressable registers, try to
-	 * exchange registers and reissue the
-	 * instruction with the operands renamed.
-	 */
-	pp = *p;
-	z = p->from.reg;
-	if(p->from.type == TYPE_REG && z >= REG_BP && z <= REG_DI) {
-		if((breg = byteswapreg(ctxt, &p->to)) != REG_AX) {
-			*ctxt->andptr++ = 0x87;			/* xchg lhs,bx */
-			asmand(ctxt, p, &p->from, reg[breg]);
-			subreg(&pp, z, breg);
-			doasm(ctxt, &pp);
-			*ctxt->andptr++ = 0x87;			/* xchg lhs,bx */
-			asmand(ctxt, p, &p->from, reg[breg]);
-		} else {
-			*ctxt->andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
-			subreg(&pp, z, REG_AX);
-			doasm(ctxt, &pp);
-			*ctxt->andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
-		}
-		return;
-	}
-	z = p->to.reg;
-	if(p->to.type == TYPE_REG && z >= REG_BP && z <= REG_DI) {
-		if((breg = byteswapreg(ctxt, &p->from)) != REG_AX) {
-			*ctxt->andptr++ = 0x87;			/* xchg rhs,bx */
-			asmand(ctxt, p, &p->to, reg[breg]);
-			subreg(&pp, z, breg);
-			doasm(ctxt, &pp);
-			*ctxt->andptr++ = 0x87;			/* xchg rhs,bx */
-			asmand(ctxt, p, &p->to, reg[breg]);
-		} else {
-			*ctxt->andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
-			subreg(&pp, z, REG_AX);
-			doasm(ctxt, &pp);
-			*ctxt->andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
-		}
-		return;
-	}
-	ctxt->diag("doasm: notfound t2=%d from=%d to=%d %P", t[2], p->ft, p->tt, p);
-	return;
-
-mfound:
-	switch(t[3]) {
-	default:
-		ctxt->diag("asmins: unknown mov %d %P", t[3], p);
-		break;
-
-	case 0:	/* lit */
-		for(z=4; t[z]!=E; z++)
-			*ctxt->andptr++ = t[z];
-		break;
-
-	case 1:	/* r,m */
-		*ctxt->andptr++ = t[4];
-		asmand(ctxt, p, &p->to, t[5]);
-		break;
-
-	case 2:	/* m,r */
-		*ctxt->andptr++ = t[4];
-		asmand(ctxt, p, &p->from, t[5]);
-		break;
-
-	case 3:	/* r,m - 2op */
-		*ctxt->andptr++ = t[4];
-		*ctxt->andptr++ = t[5];
-		asmand(ctxt, p, &p->to, t[6]);
-		break;
-
-	case 4:	/* m,r - 2op */
-		*ctxt->andptr++ = t[4];
-		*ctxt->andptr++ = t[5];
-		asmand(ctxt, p, &p->from, t[6]);
-		break;
-
-	case 5:	/* load full pointer, trash heap */
-		if(t[4])
-			*ctxt->andptr++ = t[4];
-		switch(p->to.index) {
-		default:
-			goto bad;
-		case REG_DS:
-			*ctxt->andptr++ = 0xc5;
-			break;
-		case REG_SS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb2;
-			break;
-		case REG_ES:
-			*ctxt->andptr++ = 0xc4;
-			break;
-		case REG_FS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb4;
-			break;
-		case REG_GS:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = 0xb5;
-			break;
-		}
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-
-	case 6:	/* double shift */
-		switch(p->from.type) {
-		default:
-			goto bad;
-
-		case TYPE_CONST:
-			*ctxt->andptr++ = 0x0f;
-			*ctxt->andptr++ = t[4];
-			asmand(ctxt, p, &p->to, reg[p->from.index]);
-			*ctxt->andptr++ = p->from.offset;
-			break;
-		
-		case TYPE_REG:
-			switch(p->from.reg) {
-			default:
-				goto bad;
-			case REG_CL:
-			case REG_CX:
-				*ctxt->andptr++ = 0x0f;
-				*ctxt->andptr++ = t[5];
-				asmand(ctxt, p, &p->to, reg[p->from.index]);
-				break;
-			}
-			break;
-		}
-		break;
-
-	case 7: /* imul rm,r */
-		if(t[4] == Pq) {
-			*ctxt->andptr++ = Pe;
-			*ctxt->andptr++ = Pm;
-		} else
-			*ctxt->andptr++ = t[4];
-		*ctxt->andptr++ = t[5];
-		asmand(ctxt, p, &p->from, reg[p->to.reg]);
-		break;
-	
-	case 8: /* mov tls, r */
-		// NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
-		// where you load the TLS base register into a register and then index off that
-		// register to access the actual TLS variables. Systems that allow direct TLS access
-		// are handled in prefixof above and should not be listed here.
-		switch(ctxt->headtype) {
-		default:
-			sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
-
-		case Hlinux:
-		case Hnacl:
-			// ELF TLS base is 0(GS).
-			pp.from = p->from;
-			pp.from.type = TYPE_MEM;
-			pp.from.reg = REG_GS;
-			pp.from.offset = 0;
-			pp.from.index = REG_NONE;
-			pp.from.scale = 0;
-			*ctxt->andptr++ = 0x65; // GS
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, reg[p->to.reg]);
-			break;
-		
-		case Hplan9:
-			if(ctxt->plan9privates == nil)
-				ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
-			memset(&pp.from, 0, sizeof pp.from);
-			pp.from.type = TYPE_MEM;
-			pp.from.name = NAME_EXTERN;
-			pp.from.sym = ctxt->plan9privates;
-			pp.from.offset = 0;
-			pp.from.index = REG_NONE;
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, reg[p->to.reg]);
-			break;
-
-		case Hwindows:
-			// Windows TLS base is always 0x14(FS).
-			pp.from = p->from;
-			pp.from.type = TYPE_MEM;
-			pp.from.reg = REG_FS;
-			pp.from.offset = 0x14;
-			pp.from.index = REG_NONE;
-			pp.from.scale = 0;
-			*ctxt->andptr++ = 0x64; // FS
-			*ctxt->andptr++ = 0x8B;
-			asmand(ctxt, p, &pp.from, reg[p->to.reg]);
-			break;
-		}
-		break;
-	}
-}
-
-static uchar naclret[] = {
-	0x5d, // POPL BP
-	// 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging
-	0x83, 0xe5, 0xe0,	// ANDL $~31, BP
-	0xff, 0xe5, // JMP BP
-};
-
-static void
-asmins(Link *ctxt, Prog *p)
-{
-	Reloc *r;
-
-	ctxt->andptr = ctxt->and;
-	
-	if(p->as == AUSEFIELD) {
-		r = addrel(ctxt->cursym);
-		r->off = 0;
-		r->sym = p->from.sym;
-		r->type = R_USEFIELD;
-		r->siz = 0;
-		return;
-	}
-
-	if(ctxt->headtype == Hnacl) {
-		switch(p->as) {
-		case ARET:
-			memmove(ctxt->andptr, naclret, sizeof naclret);
-			ctxt->andptr += sizeof naclret;
-			return;
-		case ACALL:
-		case AJMP:
-			if(p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
-				*ctxt->andptr++ = 0x83;
-				*ctxt->andptr++ = 0xe0 | (p->to.reg - REG_AX);
-				*ctxt->andptr++ = 0xe0;
-			}
-			break;
-		case AINT:
-			*ctxt->andptr++ = 0xf4;
-			return;
-		}
-	}
-
-	doasm(ctxt, p);
-	if(ctxt->andptr > ctxt->and+sizeof ctxt->and) {
-		print("and[] is too short - %ld byte instruction\n", ctxt->andptr - ctxt->and);
-		sysfatal("bad code");
-	}
-}
diff --git a/src/liblink/asm9.c b/src/liblink/asm9.c
deleted file mode 100644
index 742d204..0000000
--- a/src/liblink/asm9.c
+++ /dev/null
@@ -1,2836 +0,0 @@
-// cmd/9l/optab.c, cmd/9l/asmout.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.
-
-// Instruction layout.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/9l/9.out.h"
-#include "../runtime/stack.h"
-
-enum {
-	FuncAlign = 8,
-};
-
-enum {
-	r0iszero = 1,
-};
-
-typedef	struct	Optab	Optab;
-
-struct	Optab
-{
-	short	as;
-	uchar	a1;
-	uchar	a2;
-	uchar	a3;
-	uchar	a4;
-	char	type;
-	char	size;
-	char	param;
-};
-
-static Optab	optab[] = {
-	{ ATEXT,	C_LEXT,	C_NONE, C_NONE, 	C_TEXTSIZE, 	 0, 0, 0 },
-	{ ATEXT,	C_LEXT,	C_NONE, C_LCON, 	C_TEXTSIZE, 	 0, 0, 0 },
-	{ ATEXT,	C_ADDR,	C_NONE, C_NONE, 	C_TEXTSIZE, 	 0, 0, 0 },
-	{ ATEXT,	C_ADDR,	C_NONE, C_LCON, 	C_TEXTSIZE, 	 0, 0, 0 },
-
-	/* move register */
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_REG,		 1, 4, 0 },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_REG,		12, 4, 0 },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_REG,		13, 4, 0 },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_REG,		 12, 4, 0 },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_REG,		 13, 4, 0 },
-
-	{ AADD,		C_REG,	C_REG, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AADD,		C_REG,	C_NONE, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AADD,		C_ADDCON,C_REG, C_NONE, 	C_REG,		 4, 4, 0 },
-	{ AADD,		C_ADDCON,C_NONE, C_NONE, C_REG,		 4, 4, 0 },
-	{ AADD,		C_UCON,	C_REG, C_NONE, 	C_REG,		20, 4, 0 },
-	{ AADD,		C_UCON,	C_NONE, C_NONE, 	C_REG,		20, 4, 0 },
-	{ AADD,		C_LCON,	C_REG, C_NONE, 	C_REG,		22, 12, 0 },
-	{ AADD,		C_LCON,	C_NONE, C_NONE, 	C_REG,		22, 12, 0 },
-
-	{ AADDC,	C_REG,	C_REG, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AADDC,	C_REG,	C_NONE, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AADDC,	C_ADDCON,C_REG, C_NONE, 	C_REG,		 4, 4, 0 },
-	{ AADDC,	C_ADDCON,C_NONE, C_NONE, C_REG,		 4, 4, 0 },
-	{ AADDC,	C_LCON,	C_REG, C_NONE, 	C_REG,		22, 12, 0 },
-	{ AADDC,	C_LCON,	C_NONE, C_NONE, 	C_REG,		22, 12, 0 },
-
-	{ AAND,		C_REG,	C_REG, C_NONE, 	C_REG,		6, 4, 0 },	/* logical, no literal */
-	{ AAND,		C_REG,	C_NONE, C_NONE, 	C_REG,		6, 4, 0 },
-	{ AANDCC,	C_REG,	C_REG, C_NONE, 	C_REG,		6, 4, 0 },
-	{ AANDCC,	C_REG,	C_NONE, C_NONE, 	C_REG,		6, 4, 0 },
-
-	{ AANDCC,	C_ANDCON,C_NONE, C_NONE, C_REG,		58, 4, 0 },
-	{ AANDCC,	C_ANDCON,C_REG, C_NONE, 	C_REG,		58, 4, 0 },
-	{ AANDCC,	C_UCON,	C_NONE, C_NONE, 	C_REG,		59, 4, 0 },
-	{ AANDCC,	C_UCON,	C_REG, C_NONE, 	C_REG,		59, 4, 0 },
-	{ AANDCC,	C_LCON,	C_NONE, C_NONE, 	C_REG,		23, 12, 0 },
-	{ AANDCC,	C_LCON,	C_REG, C_NONE, 	C_REG,		23, 12, 0 },
-
-	{ AMULLW,	C_REG,	C_REG, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AMULLW,	C_REG,	C_NONE, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ AMULLW,	C_ADDCON,C_REG, C_NONE, 	C_REG,		 4, 4, 0 },
-	{ AMULLW,	C_ADDCON,C_NONE, C_NONE, C_REG,		 4, 4, 0 },
-	{ AMULLW,	C_ANDCON,C_REG, C_NONE, 	C_REG,		 4, 4, 0 },
-	{ AMULLW,	C_ANDCON,	C_NONE, C_NONE,	C_REG,	 4, 4, 0 },
-	{ AMULLW,	C_LCON,	C_REG,	C_NONE,	C_REG,		22, 12, 0},
-	{ AMULLW,	C_LCON,	C_NONE,	C_NONE,	C_REG,		22, 12, 0},
-
-	{ ASUBC,	C_REG,	C_REG, C_NONE, 	C_REG,		 10, 4, 0 },
-	{ ASUBC,	C_REG,	C_NONE, C_NONE, 	C_REG,		 10, 4, 0 },
-	{ ASUBC,	C_REG,	C_NONE, C_ADDCON, 	C_REG,	 27, 4, 0 },
-	{ ASUBC,	C_REG,	C_NONE,	C_LCON,	C_REG,		28, 12, 0},
-
-	{ AOR,		C_REG,	C_REG, C_NONE, 	C_REG,		6, 4, 0 },	/* logical, literal not cc (or/xor) */
-	{ AOR,		C_REG,	C_NONE, C_NONE, 	C_REG,		6, 4, 0 },
-	{ AOR,		C_ANDCON, C_NONE, C_NONE,  C_REG,	58, 4, 0 },
-	{ AOR,		C_ANDCON, C_REG, C_NONE,  C_REG,		58, 4, 0 },
-	{ AOR,		C_UCON, C_NONE, C_NONE,  C_REG,		59, 4, 0 },
-	{ AOR,		C_UCON, C_REG, C_NONE,  C_REG,		59, 4, 0 },
-	{ AOR,		C_LCON,	C_NONE, C_NONE, 	C_REG,		23, 12, 0 },
-	{ AOR,		C_LCON,	C_REG, C_NONE, 	C_REG,		23, 12, 0 },
-
-	{ ADIVW,	C_REG,	C_REG, C_NONE, 	C_REG,		 2, 4, 0 },	/* op r1[,r2],r3 */
-	{ ADIVW,	C_REG,	C_NONE, C_NONE, 	C_REG,		 2, 4, 0 },
-	{ ASUB,	C_REG,	C_REG, C_NONE, 	C_REG,		 10, 4, 0 },	/* op r2[,r1],r3 */
-	{ ASUB,	C_REG,	C_NONE, C_NONE, 	C_REG,		 10, 4, 0 },
-
-	{ ASLW,	C_REG,	C_NONE, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASLW,	C_REG,	C_REG, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASLD,	C_REG,	C_NONE, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASLD,	C_REG,	C_REG, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASLD,	C_SCON,	C_REG, C_NONE,	C_REG,		25, 4, 0 },
-	{ ASLD,	C_SCON,	C_NONE, C_NONE,	C_REG,		25, 4, 0 },
-	{ ASLW,	C_SCON,	C_REG, C_NONE, 	C_REG,		57, 4, 0 },
-	{ ASLW,	C_SCON,	C_NONE, C_NONE, 	C_REG,		57, 4, 0 },
-
-	{ ASRAW,	C_REG,	C_NONE, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASRAW,	C_REG,	C_REG, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASRAW,	C_SCON,	C_REG, C_NONE, 	C_REG,		56, 4, 0 },
-	{ ASRAW,	C_SCON,	C_NONE, C_NONE, 	C_REG,		56, 4, 0 },
-	{ ASRAD,	C_REG,	C_NONE, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASRAD,	C_REG,	C_REG, C_NONE, 	C_REG,		 6, 4, 0 },
-	{ ASRAD,	C_SCON,	C_REG, C_NONE, 	C_REG,		56, 4, 0 },
-	{ ASRAD,	C_SCON,	C_NONE, C_NONE, 	C_REG,		56, 4, 0 },
-
-	{ ARLWMI,	C_SCON, C_REG, C_LCON, 	C_REG,		62, 4, 0 },
-	{ ARLWMI,	C_REG,	C_REG, C_LCON, 	C_REG,		63, 4, 0 },
-	{ ARLDMI,	C_SCON,	C_REG, C_LCON,	C_REG,		30, 4, 0 },
-
-	{ ARLDC,	C_SCON,	C_REG, C_LCON,	C_REG,		29, 4, 0 },
-	{ ARLDCL,	C_SCON,	C_REG, C_LCON,	C_REG,		29, 4, 0 },
-	{ ARLDCL,	C_REG,	C_REG,	C_LCON,	C_REG,		14, 4, 0 },
-	{ ARLDCL, C_REG,	C_NONE,	C_LCON,	C_REG,		14, 4, 0 },
-
-	{ AFADD,	C_FREG,	C_NONE, C_NONE, 	C_FREG,		 2, 4, 0 },
-	{ AFADD,	C_FREG,	C_REG, C_NONE, 	C_FREG,		 2, 4, 0 },
-	{ AFABS,	C_FREG,	C_NONE, C_NONE, 	C_FREG,		33, 4, 0 },
-	{ AFABS,	C_NONE,	C_NONE, C_NONE, 	C_FREG,		33, 4, 0 },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_FREG,		33, 4, 0 },
-
-	{ AFMADD,	C_FREG,	C_REG, C_FREG, 	C_FREG,		 34, 4, 0 },
-	{ AFMUL,	C_FREG,	C_NONE, C_NONE, 	C_FREG,		 32, 4, 0 },
-	{ AFMUL,	C_FREG,	C_REG, C_NONE, 	C_FREG,		 32, 4, 0 },
-
-	/* store, short offset */
-	{ AMOVD,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVW,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVWZ,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVBZ,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVBZU,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVB,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVBU,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	 7, 4, REGZERO },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_SEXT,		 7, 4, REGSB },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_SEXT,		 7, 4, REGSB },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_SEXT,		 7, 4, REGSB },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_SEXT,		 7, 4, REGSB },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_SEXT,		 7, 4, REGSB },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_SAUTO,	 7, 4, REGSP },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_SAUTO,	 7, 4, REGSP },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_SAUTO,	 7, 4, REGSP },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_SAUTO,	 7, 4, REGSP },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_SAUTO,	 7, 4, REGSP },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVBZU,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-	{ AMOVBU,	C_REG,	C_NONE, C_NONE, 	C_SOREG,	 7, 4, REGZERO },
-
-	/* load, short offset */
-	{ AMOVD,	C_ZOREG,C_REG, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVW,	C_ZOREG,C_REG, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVWZ,	C_ZOREG,C_REG, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVBZ,	C_ZOREG,C_REG, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVBZU,	C_ZOREG,C_REG, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVB,	C_ZOREG,C_REG, C_NONE, 	C_REG,		9, 8, REGZERO },
-	{ AMOVBU,	C_ZOREG,C_REG, C_NONE, 	C_REG,		9, 8, REGZERO },
-	{ AMOVD,	C_SEXT,	C_NONE, C_NONE, 	C_REG,		 8, 4, REGSB },
-	{ AMOVW,	C_SEXT,	C_NONE, C_NONE, 	C_REG,		 8, 4, REGSB },
-	{ AMOVWZ,	C_SEXT,	C_NONE, C_NONE, 	C_REG,		 8, 4, REGSB },
-	{ AMOVBZ,	C_SEXT,	C_NONE, C_NONE, 	C_REG,		 8, 4, REGSB },
-	{ AMOVB,	C_SEXT,	C_NONE, C_NONE, 	C_REG,		9, 8, REGSB },
-	{ AMOVD,	C_SAUTO,C_NONE, C_NONE, 	C_REG,		 8, 4, REGSP },
-	{ AMOVW,	C_SAUTO,C_NONE, C_NONE, 	C_REG,		 8, 4, REGSP },
-	{ AMOVWZ,	C_SAUTO,C_NONE, C_NONE, 	C_REG,		 8, 4, REGSP },
-	{ AMOVBZ,	C_SAUTO,C_NONE, C_NONE, 	C_REG,		 8, 4, REGSP },
-	{ AMOVB,	C_SAUTO,C_NONE, C_NONE, 	C_REG,		9, 8, REGSP },
-	{ AMOVD,	C_SOREG,C_NONE, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVW,	C_SOREG,C_NONE, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVWZ,	C_SOREG,C_NONE, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVBZ,	C_SOREG,C_NONE, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVBZU,	C_SOREG,C_NONE, C_NONE, 	C_REG,		 8, 4, REGZERO },
-	{ AMOVB,	C_SOREG,C_NONE, C_NONE, 	C_REG,		9, 8, REGZERO },
-	{ AMOVBU,	C_SOREG,C_NONE, C_NONE, 	C_REG,		9, 8, REGZERO },
-
-	/* store, long offset */
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-	{ AMOVBZ,	C_REG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-	{ AMOVB,	C_REG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-
-	/* load, long offset */
-	{ AMOVD,	C_LEXT,	C_NONE, C_NONE, 	C_REG,		36, 8, REGSB },
-	{ AMOVW,	C_LEXT,	C_NONE, C_NONE, 	C_REG,		36, 8, REGSB },
-	{ AMOVWZ,	C_LEXT,	C_NONE, C_NONE, 	C_REG,		36, 8, REGSB },
-	{ AMOVBZ,	C_LEXT,	C_NONE, C_NONE, 	C_REG,		36, 8, REGSB },
-	{ AMOVB,	C_LEXT,	C_NONE, C_NONE, 	C_REG,		37, 12, REGSB },
-	{ AMOVD,	C_LAUTO,C_NONE, C_NONE, 	C_REG,		36, 8, REGSP },
-	{ AMOVW,	C_LAUTO,C_NONE, C_NONE, 	C_REG,		36, 8, REGSP },
-	{ AMOVWZ,	C_LAUTO,C_NONE, C_NONE, 	C_REG,		36, 8, REGSP },
-	{ AMOVBZ,	C_LAUTO,C_NONE, C_NONE, 	C_REG,		36, 8, REGSP },
-	{ AMOVB,	C_LAUTO,C_NONE, C_NONE, 	C_REG,		37, 12, REGSP },
-	{ AMOVD,	C_LOREG,C_NONE, C_NONE, 	C_REG,		36, 8, REGZERO },
-	{ AMOVW,	C_LOREG,C_NONE, C_NONE, 	C_REG,		36, 8, REGZERO },
-	{ AMOVWZ,	C_LOREG,C_NONE, C_NONE, 	C_REG,		36, 8, REGZERO },
-	{ AMOVBZ,	C_LOREG,C_NONE, C_NONE, 	C_REG,		36, 8, REGZERO },
-	{ AMOVB,	C_LOREG,C_NONE, C_NONE, 	C_REG,		37, 12, REGZERO },
-	{ AMOVD,	C_ADDR,	C_NONE, C_NONE, 	C_REG,		75, 8, 0 },
-	{ AMOVW,	C_ADDR,	C_NONE, C_NONE, 	C_REG,		75, 8, 0 },
-	{ AMOVWZ,	C_ADDR,	C_NONE, C_NONE, 	C_REG,		75, 8, 0 },
-	{ AMOVBZ,	C_ADDR,	C_NONE, C_NONE, 	C_REG,		75, 8, 0 },
-	{ AMOVB,	C_ADDR,	C_NONE, C_NONE, 	C_REG,		76, 12, 0 },
-
-	/* load constant */
-	{ AMOVD,	C_SECON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSB },
-	{ AMOVD,	C_SACON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSP },
-	{ AMOVD,	C_LECON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSB }, 
-	{ AMOVD,	C_LACON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSP },
-	{ AMOVD,	C_ADDCON,C_NONE, C_NONE, C_REG,		 3, 4, REGZERO },
-	{ AMOVW,	C_SECON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSB },	/* TO DO: check */
-	{ AMOVW,	C_SACON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSP },
-	{ AMOVW,	C_LECON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSB }, 
-	{ AMOVW,	C_LACON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSP },
-	{ AMOVW,	C_ADDCON,C_NONE, C_NONE, C_REG,		 3, 4, REGZERO },
-	{ AMOVWZ,	C_SECON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSB },	/* TO DO: check */
-	{ AMOVWZ,	C_SACON,C_NONE, C_NONE, 	C_REG,		 3, 4, REGSP },
-	{ AMOVWZ,	C_LECON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSB }, 
-	{ AMOVWZ,	C_LACON,C_NONE, C_NONE, 	C_REG,		26, 8, REGSP },
-	{ AMOVWZ,	C_ADDCON,C_NONE, C_NONE, C_REG,		 3, 4, REGZERO },
-
-	/* load unsigned/long constants (TO DO: check) */
-	{ AMOVD,	C_UCON, C_NONE, C_NONE,  C_REG,		3, 4, REGZERO },
-	{ AMOVD,	C_LCON,	C_NONE, C_NONE, 	C_REG,		19, 8, 0 },
-	{ AMOVW,	C_UCON, C_NONE, C_NONE,  C_REG,		3, 4, REGZERO },
-	{ AMOVW,	C_LCON,	C_NONE, C_NONE, 	C_REG,		19, 8, 0 },
-	{ AMOVWZ,	C_UCON, C_NONE, C_NONE,  C_REG,		3, 4, REGZERO },
-	{ AMOVWZ,	C_LCON,	C_NONE, C_NONE, 	C_REG,		19, 8, 0 },
-
-	{ AMOVHBR,	C_ZOREG,	C_REG, C_NONE, C_REG,		45, 4, 0 },
-	{ AMOVHBR,	C_ZOREG, C_NONE, C_NONE, C_REG,	45, 4, 0 },
-	{ AMOVHBR,	C_REG,	C_REG, C_NONE,	C_ZOREG,		44, 4, 0 },
-	{ AMOVHBR,	C_REG,	C_NONE, C_NONE,	C_ZOREG,		44, 4, 0 },
-
-	{ ASYSCALL,	C_NONE,	C_NONE, C_NONE, 	C_NONE,		 5, 4, 0 },
-	{ ASYSCALL,	C_REG,	C_NONE, C_NONE, 	C_NONE,		 77, 12, 0 },
-	{ ASYSCALL,	C_SCON,	C_NONE, C_NONE, 	C_NONE,		 77, 12, 0 },
-
-	{ ABEQ,		C_NONE,	C_NONE, C_NONE, 	C_SBRA,		16, 4, 0 },
-	{ ABEQ,		C_CREG,	C_NONE, C_NONE, 	C_SBRA,		16, 4, 0 },
-
-	{ ABR,		C_NONE,	C_NONE, C_NONE, 	C_LBRA,		11, 4, 0 },
-
-	{ ABC,		C_SCON,	C_REG, C_NONE, 	C_SBRA,		16, 4, 0 },
-	{ ABC,		C_SCON, C_REG, C_NONE, 	C_LBRA,		17, 4, 0 },
-
-	{ ABR,		C_NONE,	C_NONE, C_NONE, 	C_LR,		18, 4, 0 },
-	{ ABR,		C_NONE,	C_NONE, C_NONE, 	C_CTR,		18, 4, 0 },
-	{ ABR,		C_REG,	C_NONE, C_NONE, 	C_CTR,		18, 4, 0 },
-	{ ABR,		C_NONE,	C_NONE, C_NONE, 	C_ZOREG,		15, 8, 0 },
-
-	{ ABC,		C_NONE,	C_REG, C_NONE, 	C_LR,		18, 4, 0 },
-	{ ABC,		C_NONE,	C_REG, C_NONE, 	C_CTR,		18, 4, 0 },
-	{ ABC,		C_SCON,	C_REG, C_NONE, 	C_LR,		18, 4, 0 },
-	{ ABC,		C_SCON,	C_REG, C_NONE, 	C_CTR,		18, 4, 0 },
-	{ ABC,		C_NONE,	C_NONE, C_NONE, 	C_ZOREG,		15, 8, 0 },
-
-	{ AFMOVD,	C_SEXT,	C_NONE, C_NONE, 	C_FREG,		8, 4, REGSB },
-	{ AFMOVD,	C_SAUTO,C_NONE, C_NONE, 	C_FREG,		8, 4, REGSP },
-	{ AFMOVD,	C_SOREG,C_NONE, C_NONE, 	C_FREG,		8, 4, REGZERO },
-
-	{ AFMOVD,	C_LEXT,	C_NONE, C_NONE, 	C_FREG,		36, 8, REGSB },
-	{ AFMOVD,	C_LAUTO,C_NONE, C_NONE, 	C_FREG,		36, 8, REGSP },
-	{ AFMOVD,	C_LOREG,C_NONE, C_NONE, 	C_FREG,		36, 8, REGZERO },
-	{ AFMOVD,	C_ADDR,	C_NONE, C_NONE, 	C_FREG,		75, 8, 0 },
-
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_SEXT,		7, 4, REGSB },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_SAUTO,	7, 4, REGSP },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_SOREG,	7, 4, REGZERO },
-
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_LEXT,		35, 8, REGSB },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_LAUTO,	35, 8, REGSP },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_LOREG,	35, 8, REGZERO },
-	{ AFMOVD,	C_FREG,	C_NONE, C_NONE, 	C_ADDR,		74, 8, 0 },
-
-	{ ASYNC,		C_NONE,	C_NONE, C_NONE, 	C_NONE,		46, 4, 0 },
-	{ AWORD,	C_LCON,	C_NONE, C_NONE, 	C_NONE,		40, 4, 0 },
-	{ ADWORD,	C_LCON,	C_NONE, C_NONE, C_NONE,	31, 8, 0 },
-	{ ADWORD,	C_DCON,	C_NONE, C_NONE, C_NONE,	31, 8, 0 },
-
-	{ AADDME,	C_REG,	C_NONE, C_NONE, 	C_REG,		47, 4, 0 },
-
-	{ AEXTSB,	C_REG,	C_NONE, C_NONE, 	C_REG,		48, 4, 0 },
-	{ AEXTSB,	C_NONE,	C_NONE, C_NONE, 	C_REG,		48, 4, 0 },
-
-	{ ANEG,		C_REG,	C_NONE, C_NONE, 	C_REG,		47, 4, 0 },
-	{ ANEG,		C_NONE,	C_NONE, C_NONE, 	C_REG,		47, 4, 0 },
-
-	{ AREM,		C_REG,	C_NONE, C_NONE, 	C_REG,		50, 12, 0 },
-	{ AREM,		C_REG,	C_REG, C_NONE, 	C_REG,		50, 12, 0 },
-	{ AREMU,		C_REG,	C_NONE, C_NONE, 	C_REG,		50, 16, 0 },
-	{ AREMU,		C_REG,	C_REG, C_NONE, 	C_REG,		50, 16, 0 },
-	{ AREMD,		C_REG,	C_NONE, C_NONE, 	C_REG,		51, 12, 0 },
-	{ AREMD,		C_REG,	C_REG, C_NONE, 	C_REG,		51, 12, 0 },
-	{ AREMDU,		C_REG,	C_NONE, C_NONE, 	C_REG,		51, 12, 0 },
-	{ AREMDU,		C_REG,	C_REG, C_NONE, 	C_REG,		51, 12, 0 },
-
-	{ AMTFSB0,	C_SCON,	C_NONE, C_NONE, 	C_NONE,		52, 4, 0 },
-	{ AMOVFL, C_FPSCR, C_NONE, C_NONE,	C_FREG,		53, 4, 0 },
-	{ AMOVFL, C_FREG, C_NONE, C_NONE,	C_FPSCR,		64, 4, 0 },
-	{ AMOVFL, C_FREG, C_NONE, C_LCON,	C_FPSCR,		64, 4, 0 },
-	{ AMOVFL,	C_LCON, C_NONE, C_NONE,	C_FPSCR,		65, 4, 0 },
-
-	{ AMOVD,	C_MSR,	C_NONE, C_NONE, 	C_REG,		54, 4, 0 },		/* mfmsr */
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_MSR,		54, 4, 0 },		/* mtmsrd */
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_MSR,		54, 4, 0 },		/* mtmsr */
-
-	/* 64-bit special registers */
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_SPR,		66, 4, 0 },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_LR,		66, 4, 0 },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_CTR,		66, 4, 0 },
-	{ AMOVD,	C_REG,	C_NONE, C_NONE, 	C_XER,		66, 4, 0 },
-	{ AMOVD,	C_SPR,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-	{ AMOVD,	C_LR,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-	{ AMOVD,	C_CTR,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-	{ AMOVD,	C_XER,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-
-	/* 32-bit special registers (gloss over sign-extension or not?) */
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_SPR,		66, 4, 0 },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_CTR,		66, 4, 0 },
-	{ AMOVW,	C_REG,	C_NONE, C_NONE, 	C_XER,		66, 4, 0 },
-	{ AMOVW,	C_SPR,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-	{ AMOVW,	C_XER,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_SPR,		66, 4, 0 },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_CTR,		66, 4, 0 },
-	{ AMOVWZ,	C_REG,	C_NONE, C_NONE, 	C_XER,		66, 4, 0 },
-	{ AMOVWZ,	C_SPR,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-	{ AMOVWZ,	C_XER,	C_NONE, C_NONE, 	C_REG,		66, 4, 0 },
-
-	{ AMOVFL,	C_FPSCR, C_NONE, C_NONE, 	C_CREG,		73, 4, 0 },
-	{ AMOVFL,	C_CREG,	C_NONE, C_NONE, 	C_CREG,		67, 4, 0 },
-	{ AMOVW,	C_CREG,	C_NONE,	C_NONE,		C_REG,		68, 4, 0 },
-	{ AMOVWZ,	C_CREG,	C_NONE,	C_NONE,		C_REG,		68, 4, 0 },
-	{ AMOVFL,	C_REG, C_NONE, C_LCON, C_CREG,		69, 4, 0 },
-	{ AMOVFL,	C_REG, C_NONE, C_NONE, C_CREG,		69, 4, 0 },
-	{ AMOVW,	C_REG, C_NONE, C_NONE, C_CREG,		69, 4, 0 },
-	{ AMOVWZ,	C_REG, C_NONE, C_NONE, C_CREG,		69, 4, 0 },
-
-	{ ACMP,	C_REG,	C_NONE, C_NONE, 	C_REG,	70, 4, 0 },
-	{ ACMP,	C_REG,	C_REG, C_NONE, 	C_REG,	70, 4, 0 },
-	{ ACMP,	C_REG,	C_NONE, C_NONE,	C_ADDCON,	71, 4, 0 },
-	{ ACMP,	C_REG,	C_REG, C_NONE,	C_ADDCON,	71, 4, 0 },
-
-	{ ACMPU,	C_REG,	C_NONE, C_NONE, 	C_REG,	70, 4, 0 },
-	{ ACMPU,	C_REG,	C_REG, C_NONE, 	C_REG,	70, 4, 0 },
-	{ ACMPU,	C_REG,	C_NONE, C_NONE,	C_ANDCON,	71, 4, 0 },
-	{ ACMPU,	C_REG,	C_REG, C_NONE,	C_ANDCON,	71, 4, 0 },
-
-	{ AFCMPO,	C_FREG,	C_NONE, C_NONE, 	C_FREG,	70, 4, 0 },
-	{ AFCMPO,	C_FREG,	C_REG, C_NONE, 	C_FREG,	70, 4, 0 },
-
-	{ ATW,		C_LCON,	C_REG, C_NONE, 	C_REG,		60, 4, 0 },
-	{ ATW,		C_LCON,	C_REG, C_NONE, 	C_ADDCON,	61, 4, 0 },
-
-	{ ADCBF,	C_ZOREG, C_NONE, C_NONE,  C_NONE,	43, 4, 0 },
-	{ ADCBF,	C_ZOREG, C_REG, C_NONE,  C_NONE,	43, 4, 0 },
-
-	{ AECOWX,	C_REG,	C_REG, C_NONE, 	C_ZOREG,	44, 4, 0 },
-	{ AECIWX,	C_ZOREG, C_REG, C_NONE,  C_REG,		45, 4, 0 },
-	{ AECOWX,	C_REG,	C_NONE, C_NONE, 	C_ZOREG,	44, 4, 0 },
-	{ AECIWX,	C_ZOREG, C_NONE, C_NONE,  C_REG,		45, 4, 0 },
-
-	{ AEIEIO,	C_NONE,	C_NONE, C_NONE, 	C_NONE,		46, 4, 0 },
-	{ ATLBIE,	C_REG, C_NONE, C_NONE,		C_NONE,		49, 4, 0 },
-	{ ATLBIE,	C_SCON, C_NONE, C_NONE,	C_REG,	49, 4, 0 },
-	{ ASLBMFEE, C_REG, C_NONE, C_NONE,	C_REG,	55, 4, 0 },
-	{ ASLBMTE, C_REG, C_NONE, C_NONE,	C_REG,	55, 4, 0 },
-
-	{ ASTSW,	C_REG,	C_NONE, C_NONE, 	C_ZOREG,	44, 4, 0 },
-	{ ASTSW,	C_REG,	C_NONE, C_LCON, 	C_ZOREG,	41, 4, 0 },
-	{ ALSW,	C_ZOREG, C_NONE, C_NONE,  C_REG,		45, 4, 0 },
-	{ ALSW,	C_ZOREG, C_NONE, C_LCON,  C_REG,		42, 4, 0 },
-
-	{ AUNDEF,	C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0 },
-	{ AUSEFIELD,	C_ADDR,	C_NONE,	C_NONE, C_NONE,	0, 0, 0 },
-	{ APCDATA,	C_LCON,	C_NONE,	C_NONE, C_LCON,	0, 0, 0 },
-	{ AFUNCDATA,	C_SCON,	C_NONE,	C_NONE, C_ADDR,	0, 0, 0 },
-	{ ANOP,		C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
-
-	{ ADUFFZERO,	C_NONE,	C_NONE, C_NONE,	C_LBRA,	11, 4, 0 },  // same as ABR/ABL
-	{ ADUFFCOPY,	C_NONE,	C_NONE, C_NONE,	C_LBRA,	11, 4, 0 },  // same as ABR/ABL
-
-	{ AXXX,		C_NONE,	C_NONE, C_NONE, 	C_NONE,		 0, 4, 0 },
-};
-
-static int ocmp(const void *, const void *);
-static int cmp(int, int);
-static void buildop(Link*);
-static void prasm(Prog *);
-static int isint32(vlong);
-static int isuint32(uvlong);
-static int aclass(Link*, Addr*);
-static Optab* oplook(Link*, Prog*);
-static void asmout(Link*, Prog*, Optab*, uint32*);
-static vlong vregoff(Link*, Addr*);
-static int32 regoff(Link*, Addr*);
-static int32 oprrr(Link*, int);
-static int32 opirr(Link*, int);
-static int32 opload(Link*, int);
-static int32 opstore(Link*, int);
-static int32 oploadx(Link*, int);
-static int32 opstorex(Link*, int);
-static int getmask(uchar*, uint32);
-static void maskgen(Link*, Prog*, uchar*, uint32);
-static int getmask64(uchar*, uvlong);
-static void maskgen64(Link*, Prog*, uchar*, uvlong);
-static uint32 loadu32(int, vlong);
-static void addaddrreloc(Link*, LSym*, uint32*, uint32*);
-
-typedef struct Oprang Oprang;
-struct Oprang
-{
-	Optab*	start;
-	Optab*	stop;
-};
-
-static Oprang oprange[ALAST];
-
-static uchar	xcmp[C_NCLASS][C_NCLASS];
-
-
-void
-span9(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *q;
-	Optab *o;
-	int m, bflag;
-	vlong c, otxt;
-	uint32 out[6];
-	int32 i, j;
-	uchar *bp, *cast;
-
-	p = cursym->text;
-	if(p == nil || p->link == nil) // handle external functions and ELF section symbols
-		return;
-	ctxt->cursym = cursym;
-	ctxt->autosize = p->to.offset + 8;
-
-	if(oprange[AANDN].start == nil)
- 		buildop(ctxt);
-
-	c = 0;	
-	p->pc = c;
-
-	for(p = p->link; p != nil; p = p->link) {
-		ctxt->curp = p;
-		p->pc = c;
-		o = oplook(ctxt, p);
-		m = o->size;
-		if(m == 0) {
-			if(p->as != ANOP && p->as != AFUNCDATA && p->as != APCDATA)
-				ctxt->diag("zero-width instruction\n%P", p);
-			continue;
-		}
-		c += m;
-	}
-	cursym->size = c;
-
-	/*
-	 * if any procedure is large enough to
-	 * generate a large SBRA branch, then
-	 * generate extra passes putting branches
-	 * around jmps to fix. this is rare.
-	 */
-	bflag = 1;
-	while(bflag) {
-		if(ctxt->debugvlog)
-			Bprint(ctxt->bso, "%5.2f span1\n", cputime());
-		bflag = 0;
-		c = 0;
-		for(p = cursym->text->link; p != nil; p = p->link) {
-			p->pc = c;
-			o = oplook(ctxt, p);
-
-			// very large conditional branches
-			if((o->type == 16 || o->type == 17) && p->pcond) {
-				otxt = p->pcond->pc - c;
-				if(otxt < -(1L<<15)+10 || otxt >= (1L<<15)-10) {
-					q = emallocz(sizeof(Prog));
-					q->link = p->link;
-					p->link = q;
-					q->as = ABR;
-					q->to.type = TYPE_BRANCH;
-					q->pcond = p->pcond;
-					p->pcond = q;
-					q = emallocz(sizeof(Prog));
-					q->link = p->link;
-					p->link = q;
-					q->as = ABR;
-					q->to.type = TYPE_BRANCH;
-					q->pcond = q->link->link;
-					//addnop(p->link);
-					//addnop(p);
-					bflag = 1;
-				}
-			}
-
-			m = o->size;
-			if(m == 0) {
-				if(p->as != ANOP && p->as != AFUNCDATA && p->as != APCDATA)
-					ctxt->diag("zero-width instruction\n%P", p);
-				continue;
-			}
-			c += m;
-		}
-		cursym->size = c;
-	}
-
-	c += -c&(FuncAlign-1);
-	cursym->size = c;
-
-	/*
-	 * lay out the code, emitting code and data relocations.
-	 */
-	if(ctxt->tlsg == nil)
-		ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
-
-	symgrow(ctxt, cursym, cursym->size);
-
-	bp = cursym->p;
-	for(p = cursym->text->link; p != nil; p = p->link) {
-		ctxt->pc = p->pc;
-		ctxt->curp = p;
-		o = oplook(ctxt, p);
-		if(o->size > 4*nelem(out))
-			sysfatal("out array in span9 is too small, need at least %d for %P", o->size/4, p);
-		asmout(ctxt, p, o, out);
-		for(i=0; i<o->size/4; i++) {
-			cast = (uchar*)&out[i];
-			for(j=0; j<4; j++)
-				*bp++ = cast[inuxi4[j]];
-		}
-	}
-}
-
-static int
-isint32(vlong v)
-{
-	return (int32)v == v;
-}
-
-static int
-isuint32(uvlong v)
-{
-	return (uint32)v == v;
-}
-
-static int
-aclass(Link *ctxt, Addr *a)
-{
-	LSym *s;
-
-	switch(a->type) {
-	case TYPE_NONE:
-		return C_NONE;
-
-	case TYPE_REG:
-		if(REG_R0 <= a->reg && a->reg <= REG_R31)
-			return C_REG;
-		if(REG_F0 <= a->reg && a->reg <= REG_F31)
-			return C_FREG;
-		if(REG_C0 <= a->reg && a->reg <= REG_C7 || a->reg == REG_CR)
-			return C_CREG;
-		if(REG_SPR0 <= a->reg && a->reg <= REG_SPR0+1023) {
-			switch(a->reg) {
-			case REG_LR:
-				return C_LR;
-			case REG_XER:
-				return C_XER;
-			case REG_CTR:
-				return C_CTR;
-			}
-			return C_SPR;
-		}
-		if(REG_DCR0 <= a->reg && a->reg <= REG_DCR0+1023)
-			return C_SPR;
-		if(a->reg == REG_FPSCR)
-			return C_FPSCR;
-		if(a->reg == REG_MSR)
-			return C_MSR;
-		return C_GOK;
-
-	case TYPE_MEM:
-		switch(a->name) {
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			if(a->sym == nil)
-				break;
-			ctxt->instoffset = a->offset;
-			if(a->sym != nil) // use relocation
-				return C_ADDR;
-			return C_LEXT;
-		case NAME_AUTO:
-			ctxt->instoffset = ctxt->autosize + a->offset;
-			if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
-				return C_SAUTO;
-			return C_LAUTO;
-		case NAME_PARAM:
-			ctxt->instoffset = ctxt->autosize + a->offset + 8L;
-			if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
-				return C_SAUTO;
-			return C_LAUTO;
-		case TYPE_NONE:
-			ctxt->instoffset = a->offset;
-			if(ctxt->instoffset == 0)
-				return C_ZOREG;
-			if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
-				return C_SOREG;
-			return C_LOREG;
-		}
-		return C_GOK;
-
-	case TYPE_TEXTSIZE:
-		return C_TEXTSIZE;
-
-	case TYPE_CONST:
-	case TYPE_ADDR:
-		switch(a->name) {
-		case TYPE_NONE:
-			ctxt->instoffset = a->offset;
-			if(a->reg != 0) {
-				if(-BIG <= ctxt->instoffset && ctxt->instoffset <= BIG)
-					return C_SACON;
-				if(isint32(ctxt->instoffset))
-					return C_LACON;
-				return C_DACON;
-			}
-			goto consize;
-
-		case NAME_EXTERN:
-		case NAME_STATIC:
-			s = a->sym;
-			if(s == nil)
-				break;
-			if(s->type == SCONST) {
-				ctxt->instoffset = s->value + a->offset;
-				goto consize;
-			}
-			ctxt->instoffset = s->value + a->offset;
-			/* not sure why this barfs */
-			return C_LCON;
-
-		case NAME_AUTO:
-			ctxt->instoffset = ctxt->autosize + a->offset;
-			if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
-				return C_SACON;
-			return C_LACON;
-
-		case NAME_PARAM:
-			ctxt->instoffset = ctxt->autosize + a->offset + 8L;
-			if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
-				return C_SACON;
-			return C_LACON;
-		}
-		return C_GOK;
-
-	consize:
-		if(ctxt->instoffset >= 0) {
-			if(ctxt->instoffset == 0)
-				return C_ZCON;
-			if(ctxt->instoffset <= 0x7fff)
-				return C_SCON;
-			if(ctxt->instoffset <= 0xffff)
-				return C_ANDCON;
-			if((ctxt->instoffset & 0xffff) == 0 && isuint32(ctxt->instoffset))	/* && (instoffset & (1<<31)) == 0) */
-				return C_UCON;
-			if(isint32(ctxt->instoffset) || isuint32(ctxt->instoffset))
-				return C_LCON;
-			return C_DCON;
-		}
-		if(ctxt->instoffset >= -0x8000)
-			return C_ADDCON;
-		if((ctxt->instoffset & 0xffff) == 0 && isint32(ctxt->instoffset))
-			return C_UCON;
-		if(isint32(ctxt->instoffset))
-			return C_LCON;
-		return C_DCON;
-
-	case TYPE_BRANCH:
-		return C_SBRA;
-	}
-	return C_GOK;
-}
-
-static void
-prasm(Prog *p)
-{
-	print("%P\n", p);
-}
-
-static Optab*
-oplook(Link *ctxt, Prog *p)
-{
-	int a1, a2, a3, a4, r;
-	uchar *c1, *c3, *c4;
-	Optab *o, *e;
-
-	a1 = p->optab;
-	if(a1)
-		return optab+(a1-1);
-	a1 = p->from.class;
-	if(a1 == 0) {
-		a1 = aclass(ctxt, &p->from) + 1;
-		p->from.class = a1;
-	}
-	a1--;
-	a3 = p->from3.class;
-	if(a3 == 0) {
-		a3 = aclass(ctxt, &p->from3) + 1;
-		p->from3.class = a3;
-	}
-	a3--;
-	a4 = p->to.class;
-	if(a4 == 0) {
-		a4 = aclass(ctxt, &p->to) + 1;
-		p->to.class = a4;
-	}
-	a4--;
-	a2 = C_NONE;
-	if(p->reg != 0)
-		a2 = C_REG;
-//print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4);
-	r = p->as;
-	o = oprange[r].start;
-	if(o == 0)
-		o = oprange[r].stop; /* just generate an error */
-	e = oprange[r].stop;
-	c1 = xcmp[a1];
-	c3 = xcmp[a3];
-	c4 = xcmp[a4];
-	for(; o<e; o++)
-		if(o->a2 == a2)
-		if(c1[o->a1])
-		if(c3[o->a3])
-		if(c4[o->a4]) {
-			p->optab = (o-optab)+1;
-			return o;
-		}
-	ctxt->diag("illegal combination %A %^ %^ %^ %^",
-		p->as, a1, a2, a3, a4);
-	prasm(p);
-	if(o == 0)
-		o = optab;
-	return o;
-}
-
-static int
-cmp(int a, int b)
-{
-
-	if(a == b)
-		return 1;
-	switch(a) {
-	case C_LCON:
-		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
-			return 1;
-		break;
-	case C_ADDCON:
-		if(b == C_ZCON || b == C_SCON)
-			return 1;
-		break;
-	case C_ANDCON:
-		if(b == C_ZCON || b == C_SCON)
-			return 1;
-		break;
-	case C_SPR:
-		if(b == C_LR || b == C_XER || b == C_CTR)
-			return 1;
-		break;
-	case C_UCON:
-		if(b == C_ZCON)
-			return 1;
-		break;
-	case C_SCON:
-		if(b == C_ZCON)
-			return 1;
-		break;
-	case C_LACON:
-		if(b == C_SACON)
-			return 1;
-		break;
-	case C_LBRA:
-		if(b == C_SBRA)
-			return 1;
-		break;
-	case C_LEXT:
-		if(b == C_SEXT)
-			return 1;
-		break;
-	case C_LAUTO:
-		if(b == C_SAUTO)
-			return 1;
-		break;
-	case C_REG:
-		if(b == C_ZCON)
-			return r0iszero;
-		break;
-	case C_LOREG:
-		if(b == C_ZOREG || b == C_SOREG)
-			return 1;
-		break;
-	case C_SOREG:
-		if(b == C_ZOREG)
-			return 1;
-		break;
-
-	case C_ANY:
-		return 1;
-	}
-	return 0;
-}
-
-static int
-ocmp(const void *a1, const void *a2)
-{
-	const Optab *p1, *p2;
-	int n;
-
-	p1 = a1;
-	p2 = a2;
-	n = p1->as - p2->as;
-	if(n)
-		return n;
-	n = p1->a1 - p2->a1;
-	if(n)
-		return n;
-	n = p1->a2 - p2->a2;
-	if(n)
-		return n;
-	n = p1->a3 - p2->a3;
-	if(n)
-		return n;
-	n = p1->a4 - p2->a4;
-	if(n)
-		return n;
-	return 0;
-}
-
-static void
-buildop(Link *ctxt)
-{
-	int i, n, r;
-
-	for(i=0; i<C_NCLASS; i++)
-		for(n=0; n<C_NCLASS; n++)
-			xcmp[i][n] = cmp(n, i);
-	for(n=0; optab[n].as != AXXX; n++)
-		;
-	qsort(optab, n, sizeof(optab[0]), ocmp);
-	for(i=0; i<n; i++) {
-		r = optab[i].as;
-		oprange[r].start = optab+i;
-		while(optab[i].as == r)
-			i++;
-		oprange[r].stop = optab+i;
-		i--;
-		
-		switch(r)
-		{
-		default:
-			ctxt->diag("unknown op in build: %A", r);
-			sysfatal("bad code");
-		case ADCBF:	/* unary indexed: op (b+a); op (b) */
-			oprange[ADCBI] = oprange[r];
-			oprange[ADCBST] = oprange[r];
-			oprange[ADCBT] = oprange[r];
-			oprange[ADCBTST] = oprange[r];
-			oprange[ADCBZ] = oprange[r];
-			oprange[AICBI] = oprange[r];
-			break;
-		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
-			oprange[ASTWCCC] = oprange[r];
-			oprange[ASTDCCC] = oprange[r];
-			break;
-		case AREM:	/* macro */
-			oprange[AREMCC] = oprange[r];
-			oprange[AREMV] = oprange[r];
-			oprange[AREMVCC] = oprange[r];
-			break;
-		case AREMU:
-			oprange[AREMU] = oprange[r];
-			oprange[AREMUCC] = oprange[r];
-			oprange[AREMUV] = oprange[r];
-			oprange[AREMUVCC] = oprange[r];
-			break;
-		case AREMD:
-			oprange[AREMDCC] = oprange[r];
-			oprange[AREMDV] = oprange[r];
-			oprange[AREMDVCC] = oprange[r];
-			break;
-		case AREMDU:
-			oprange[AREMDU] = oprange[r];
-			oprange[AREMDUCC] = oprange[r];
-			oprange[AREMDUV] = oprange[r];
-			oprange[AREMDUVCC] = oprange[r];
-			break;
-		case ADIVW:	/* op Rb[,Ra],Rd */
-			oprange[AMULHW] = oprange[r];
-			oprange[AMULHWCC] = oprange[r];
-			oprange[AMULHWU] = oprange[r];
-			oprange[AMULHWUCC] = oprange[r];
-			oprange[AMULLWCC] = oprange[r];
-			oprange[AMULLWVCC] = oprange[r];
-			oprange[AMULLWV] = oprange[r];
-			oprange[ADIVWCC] = oprange[r];
-			oprange[ADIVWV] = oprange[r];
-			oprange[ADIVWVCC] = oprange[r];
-			oprange[ADIVWU] = oprange[r];
-			oprange[ADIVWUCC] = oprange[r];
-			oprange[ADIVWUV] = oprange[r];
-			oprange[ADIVWUVCC] = oprange[r];
-			oprange[AADDCC] = oprange[r];
-			oprange[AADDCV] = oprange[r];
-			oprange[AADDCVCC] = oprange[r];
-			oprange[AADDV] = oprange[r];
-			oprange[AADDVCC] = oprange[r];
-			oprange[AADDE] = oprange[r];
-			oprange[AADDECC] = oprange[r];
-			oprange[AADDEV] = oprange[r];
-			oprange[AADDEVCC] = oprange[r];
-			oprange[ACRAND] = oprange[r];
-			oprange[ACRANDN] = oprange[r];
-			oprange[ACREQV] = oprange[r];
-			oprange[ACRNAND] = oprange[r];
-			oprange[ACRNOR] = oprange[r];
-			oprange[ACROR] = oprange[r];
-			oprange[ACRORN] = oprange[r];
-			oprange[ACRXOR] = oprange[r];
-			oprange[AMULHD] = oprange[r];
-			oprange[AMULHDCC] = oprange[r];
-			oprange[AMULHDU] = oprange[r];
-			oprange[AMULHDUCC] = oprange[r];
-			oprange[AMULLD] = oprange[r];
-			oprange[AMULLDCC] = oprange[r];
-			oprange[AMULLDVCC] = oprange[r];
-			oprange[AMULLDV] = oprange[r];
-			oprange[ADIVD] = oprange[r];
-			oprange[ADIVDCC] = oprange[r];
-			oprange[ADIVDVCC] = oprange[r];
-			oprange[ADIVDV] = oprange[r];
-			oprange[ADIVDU] = oprange[r];
-			oprange[ADIVDUCC] = oprange[r];
-			oprange[ADIVDUVCC] = oprange[r];
-			oprange[ADIVDUCC] = oprange[r];
-			break;
-		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
-			oprange[AMOVH] = oprange[r];
-			oprange[AMOVHZ] = oprange[r];
-			break;
-		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
-			oprange[AMOVHU] = oprange[r];
-			oprange[AMOVHZU] = oprange[r];
-			oprange[AMOVWU] = oprange[r];
-			oprange[AMOVWZU] = oprange[r];
-			oprange[AMOVDU] = oprange[r];
-			oprange[AMOVMW] = oprange[r];
-			break;
-		case AAND:	/* logical op Rb,Rs,Ra; no literal */
-			oprange[AANDN] = oprange[r];
-			oprange[AANDNCC] = oprange[r];
-			oprange[AEQV] = oprange[r];
-			oprange[AEQVCC] = oprange[r];
-			oprange[ANAND] = oprange[r];
-			oprange[ANANDCC] = oprange[r];
-			oprange[ANOR] = oprange[r];
-			oprange[ANORCC] = oprange[r];
-			oprange[AORCC] = oprange[r];
-			oprange[AORN] = oprange[r];
-			oprange[AORNCC] = oprange[r];
-			oprange[AXORCC] = oprange[r];
-			break;
-		case AADDME:	/* op Ra, Rd */
-			oprange[AADDMECC] = oprange[r];
-			oprange[AADDMEV] = oprange[r];
-			oprange[AADDMEVCC] = oprange[r];
-			oprange[AADDZE] = oprange[r];
-			oprange[AADDZECC] = oprange[r];
-			oprange[AADDZEV] = oprange[r];
-			oprange[AADDZEVCC] = oprange[r];
-			oprange[ASUBME] = oprange[r];
-			oprange[ASUBMECC] = oprange[r];
-			oprange[ASUBMEV] = oprange[r];
-			oprange[ASUBMEVCC] = oprange[r];
-			oprange[ASUBZE] = oprange[r];
-			oprange[ASUBZECC] = oprange[r];
-			oprange[ASUBZEV] = oprange[r];
-			oprange[ASUBZEVCC] = oprange[r];
-			break;
-		case AADDC:
-			oprange[AADDCCC] = oprange[r];
-			break;
-		case ABEQ:
-			oprange[ABGE] = oprange[r];
-			oprange[ABGT] = oprange[r];
-			oprange[ABLE] = oprange[r];
-			oprange[ABLT] = oprange[r];
-			oprange[ABNE] = oprange[r];
-			oprange[ABVC] = oprange[r];
-			oprange[ABVS] = oprange[r];
-			break;
-		case ABR:
-			oprange[ABL] = oprange[r];
-			break;
-		case ABC:
-			oprange[ABCL] = oprange[r];
-			break;
-		case AEXTSB:	/* op Rs, Ra */
-			oprange[AEXTSBCC] = oprange[r];
-			oprange[AEXTSH] = oprange[r];
-			oprange[AEXTSHCC] = oprange[r];
-			oprange[ACNTLZW] = oprange[r];
-			oprange[ACNTLZWCC] = oprange[r];
-			oprange[ACNTLZD] = oprange[r];
-			oprange[AEXTSW] = oprange[r];
-			oprange[AEXTSWCC] = oprange[r];
-			oprange[ACNTLZDCC] = oprange[r];
-			break;
-		case AFABS:	/* fop [s,]d */
-			oprange[AFABSCC] = oprange[r];
-			oprange[AFNABS] = oprange[r];
-			oprange[AFNABSCC] = oprange[r];
-			oprange[AFNEG] = oprange[r];
-			oprange[AFNEGCC] = oprange[r];
-			oprange[AFRSP] = oprange[r];
-			oprange[AFRSPCC] = oprange[r];
-			oprange[AFCTIW] = oprange[r];
-			oprange[AFCTIWCC] = oprange[r];
-			oprange[AFCTIWZ] = oprange[r];
-			oprange[AFCTIWZCC] = oprange[r];
-			oprange[AFCTID] = oprange[r];
-			oprange[AFCTIDCC] = oprange[r];
-			oprange[AFCTIDZ] = oprange[r];
-			oprange[AFCTIDZCC] = oprange[r];
-			oprange[AFCFID] = oprange[r];
-			oprange[AFCFIDCC] = oprange[r];
-			oprange[AFRES] = oprange[r];
-			oprange[AFRESCC] = oprange[r];
-			oprange[AFRSQRTE] = oprange[r];
-			oprange[AFRSQRTECC] = oprange[r];
-			oprange[AFSQRT] = oprange[r];
-			oprange[AFSQRTCC] = oprange[r];
-			oprange[AFSQRTS] = oprange[r];
-			oprange[AFSQRTSCC] = oprange[r];
-			break;
-		case AFADD:
-			oprange[AFADDS] = oprange[r];
-			oprange[AFADDCC] = oprange[r];
-			oprange[AFADDSCC] = oprange[r];
-			oprange[AFDIV] = oprange[r];
-			oprange[AFDIVS] = oprange[r];
-			oprange[AFDIVCC] = oprange[r];
-			oprange[AFDIVSCC] = oprange[r];
-			oprange[AFSUB] = oprange[r];
-			oprange[AFSUBS] = oprange[r];
-			oprange[AFSUBCC] = oprange[r];
-			oprange[AFSUBSCC] = oprange[r];
-			break;
-		case AFMADD:
-			oprange[AFMADDCC] = oprange[r];
-			oprange[AFMADDS] = oprange[r];
-			oprange[AFMADDSCC] = oprange[r];
-			oprange[AFMSUB] = oprange[r];
-			oprange[AFMSUBCC] = oprange[r];
-			oprange[AFMSUBS] = oprange[r];
-			oprange[AFMSUBSCC] = oprange[r];
-			oprange[AFNMADD] = oprange[r];
-			oprange[AFNMADDCC] = oprange[r];
-			oprange[AFNMADDS] = oprange[r];
-			oprange[AFNMADDSCC] = oprange[r];
-			oprange[AFNMSUB] = oprange[r];
-			oprange[AFNMSUBCC] = oprange[r];
-			oprange[AFNMSUBS] = oprange[r];
-			oprange[AFNMSUBSCC] = oprange[r];
-			oprange[AFSEL] = oprange[r];
-			oprange[AFSELCC] = oprange[r];
-			break;
-		case AFMUL:
-			oprange[AFMULS] = oprange[r];
-			oprange[AFMULCC] = oprange[r];
-			oprange[AFMULSCC] = oprange[r];
-			break;
-		case AFCMPO:
-			oprange[AFCMPU] = oprange[r];
-			break;
-		case AMTFSB0:
-			oprange[AMTFSB0CC] = oprange[r];
-			oprange[AMTFSB1] = oprange[r];
-			oprange[AMTFSB1CC] = oprange[r];
-			break;
-		case ANEG:	/* op [Ra,] Rd */
-			oprange[ANEGCC] = oprange[r];
-			oprange[ANEGV] = oprange[r];
-			oprange[ANEGVCC] = oprange[r];
-			break;
-		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
-			oprange[AXOR] = oprange[r];
-			break;
-		case ASLW:
-			oprange[ASLWCC] = oprange[r];
-			oprange[ASRW] = oprange[r];
-			oprange[ASRWCC] = oprange[r];
-			break;
-		case ASLD:
-			oprange[ASLDCC] = oprange[r];
-			oprange[ASRD] = oprange[r];
-			oprange[ASRDCC] = oprange[r];
-			break;
-		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
-			oprange[ASRAWCC] = oprange[r];
-			break;
-		case ASRAD:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
-			oprange[ASRADCC] = oprange[r];
-			break;
-		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
-			oprange[ASUB] = oprange[r];
-			oprange[ASUBCC] = oprange[r];
-			oprange[ASUBV] = oprange[r];
-			oprange[ASUBVCC] = oprange[r];
-			oprange[ASUBCCC] = oprange[r];
-			oprange[ASUBCV] = oprange[r];
-			oprange[ASUBCVCC] = oprange[r];
-			oprange[ASUBE] = oprange[r];
-			oprange[ASUBECC] = oprange[r];
-			oprange[ASUBEV] = oprange[r];
-			oprange[ASUBEVCC] = oprange[r];
-			break;
-		case ASYNC:
-			oprange[AISYNC] = oprange[r];
-			oprange[APTESYNC] = oprange[r];
-			oprange[ATLBSYNC] = oprange[r];
-			break;
-		case ARLWMI:
-			oprange[ARLWMICC] = oprange[r];
-			oprange[ARLWNM] = oprange[r];
-			oprange[ARLWNMCC] = oprange[r];
-			break;
-		case ARLDMI:
-			oprange[ARLDMICC] = oprange[r];
-			break;
-		case ARLDC:
-			oprange[ARLDCCC] = oprange[r];
-			break;
-		case ARLDCL:
-			oprange[ARLDCR] = oprange[r];
-			oprange[ARLDCLCC] = oprange[r];
-			oprange[ARLDCRCC] = oprange[r];
-			break;
-		case AFMOVD:
-			oprange[AFMOVDCC] = oprange[r];
-			oprange[AFMOVDU] = oprange[r];
-			oprange[AFMOVS] = oprange[r];
-			oprange[AFMOVSU] = oprange[r];
-			break;
-		case AECIWX:
-			oprange[ALWAR] = oprange[r];
-			oprange[ALDAR] = oprange[r];
-			break;
-		case ASYSCALL:	/* just the op; flow of control */
-			oprange[ARFI] = oprange[r];
-			oprange[ARFCI] = oprange[r];
-			oprange[ARFID] = oprange[r];
-			oprange[AHRFID] = oprange[r];
-			break;
-		case AMOVHBR:
-			oprange[AMOVWBR] = oprange[r];
-			break;
-		case ASLBMFEE:
-			oprange[ASLBMFEV] = oprange[r];
-			break;
-		case ATW:
-			oprange[ATD] = oprange[r];
-			break;
-		case ATLBIE:
-			oprange[ASLBIE] = oprange[r];
-			oprange[ATLBIEL] = oprange[r];
-			break;
-		case AEIEIO:
-			oprange[ASLBIA] = oprange[r];
-			break;
-		case ACMP:
-			oprange[ACMPW] = oprange[r];
-			break;
-		case ACMPU:
-			oprange[ACMPWU] = oprange[r];
-			break;
-		case AADD:
-		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
-		case ALSW:
-		case AMOVW:	/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
-		case AMOVWZ:	/* load/store/move word with zero extension; move 32-bit literals  */
-		case AMOVD:	/* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
-		case AMOVB:	/* macro: move byte with sign extension */
-		case AMOVBU:	/* macro: move byte with sign extension & update */
-		case AMOVFL:
-		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
-		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
-		case ASTSW:
-		case ASLBMTE:
-		case AWORD:
-		case ADWORD:
-		case ANOP:
-		case ATEXT:
-		case AUNDEF:
-		case AUSEFIELD:
-		case AFUNCDATA:
-		case APCDATA:
-		case ADUFFZERO:
-		case ADUFFCOPY:
-			break;
-		}
-	}
-}
-
-uint32
-OPVCC(uint32 o, uint32 xo, uint32 oe, uint32 rc)
-{
-	return o<<26 | xo<<1 | oe<<10 | rc&1;
-}
-
-uint32
-OPCC(uint32 o, uint32 xo, uint32 rc)
-{
-	return OPVCC(o, xo, 0, rc);
-}
-
-uint32
-OP(uint32 o, uint32 xo)
-{
-	return OPVCC(o, xo, 0, 0);
-}
-
-/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
-uint32
-AOP_RRR(uint32 op, uint32 d, uint32 a, uint32 b)
-{
-	return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11;
-}
-
-uint32
-AOP_IRR(uint32 op, uint32 d, uint32 a, uint32 simm)
-{
-	return op | (d&31)<<21 | (a&31)<<16 | (simm&0xFFFF);
-}
-
-uint32
-LOP_RRR(uint32 op, uint32 a, uint32 s, uint32 b)
-{
-	return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11;
-}
-
-uint32
-LOP_IRR(uint32 op, uint32 a, uint32 s, uint32 uimm)
-{
-	return op | (s&31)<<21 | (a&31)<<16 | (uimm&0xFFFF);
-}
-
-uint32
-OP_BR(uint32 op, uint32 li, uint32 aa)
-{
-	return op | li&0x03FFFFFC | aa<<1;
-}
-
-uint32
-OP_BC(uint32 op, uint32 bo, uint32 bi, uint32 bd, uint32 aa)
-{
-	return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1;
-}
-
-uint32
-OP_BCR(uint32 op, uint32 bo, uint32 bi)
-{
-	return op | (bo&0x1F)<<21 | (bi&0x1F)<<16;
-}
-
-uint32
-OP_RLW(uint32 op, uint32 a, uint32 s, uint32 sh, uint32 mb, uint32 me)
-{
-	return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1;
-}
-
-enum {
-	/* each rhs is OPVCC(_, _, _, _) */
-	OP_ADD =	31<<26 | 266<<1 | 0<<10 | 0,
-	OP_ADDI =	14<<26 | 0<<1 | 0<<10 | 0,
-	OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0,
-	OP_ANDI =	28<<26 | 0<<1 | 0<<10 | 0,
-	OP_EXTSB =	31<<26 | 954<<1 | 0<<10 | 0,
-	OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0,
-	OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0,
-	OP_MCRF =	19<<26 | 0<<1 | 0<<10 | 0,
-	OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0,
-	OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0,
-	OP_MFCR =	31<<26 | 19<<1 | 0<<10 | 0,
-	OP_MFFS =	63<<26 | 583<<1 | 0<<10 | 0,
-	OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0,
-	OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0,
-	OP_MFSR =	31<<26 | 595<<1 | 0<<10 | 0,
-	OP_MFSRIN =	31<<26 | 659<<1 | 0<<10 | 0,
-	OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0,
-	OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0,
-	OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0,
-	OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0,
-	OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0,
-	OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0,
-	OP_MTSR =	31<<26 | 210<<1 | 0<<10 | 0,
-	OP_MTSRIN =	31<<26 | 242<<1 | 0<<10 | 0,
-	OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0,
-	OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0,
-	OP_OR =	31<<26 | 444<<1 | 0<<10 | 0,
-	OP_ORI =	24<<26 | 0<<1 | 0<<10 | 0,
-	OP_ORIS =	25<<26 | 0<<1 | 0<<10 | 0,
-	OP_RLWINM =	21<<26 | 0<<1 | 0<<10 | 0,
-	OP_SUBF =	31<<26 | 40<<1 | 0<<10 | 0,
-	OP_RLDIC =	30<<26 | 4<<1 | 0<<10 | 0,
-	OP_RLDICR =	30<<26 | 2<<1 | 0<<10 | 0,
-	OP_RLDICL =	30<<26 | 0<<1 | 0<<10 | 0,
-};
-
-int
-oclass(Addr *a)
-{
-	return a->class - 1;
-}
-
-// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
-static void
-addaddrreloc(Link *ctxt, LSym *s, uint32 *o1, uint32 *o2)
-{
-	Reloc *rel;
-
-	rel = addrel(ctxt->cursym);
-	rel->off = ctxt->pc;
-	rel->siz = 8;
-	rel->sym = s;
-	rel->add = ((uvlong)*o1<<32) | (uint32)*o2;
-	rel->type = R_ADDRPOWER;
-}
-
-/*
- * 32-bit masks
- */
-static int
-getmask(uchar *m, uint32 v)
-{
-	int i;
-
-	m[0] = m[1] = 0;
-	if(v != ~(uint32)0 && v & (1<<31) && v & 1){	/* MB > ME */
-		if(getmask(m, ~v)){
-			i = m[0]; m[0] = m[1]+1; m[1] = i-1;
-			return 1;
-		}
-		return 0;
-	}
-	for(i=0; i<32; i++)
-		if(v & (1<<(31-i))){
-			m[0] = i;
-			do {
-				m[1] = i;
-			} while(++i<32 && (v & (1<<(31-i))) != 0);
-			for(; i<32; i++)
-				if(v & (1<<(31-i)))
-					return 0;
-			return 1;
-		}
-	return 0;
-}
-
-static void
-maskgen(Link *ctxt, Prog *p, uchar *m, uint32 v)
-{
-	if(!getmask(m, v))
-		ctxt->diag("cannot generate mask #%lux\n%P", v, p);
-}
-
-/*
- * 64-bit masks (rldic etc)
- */
-static int
-getmask64(uchar *m, uvlong v)
-{
-	int i;
-
-	m[0] = m[1] = 0;
-	for(i=0; i<64; i++)
-		if(v & ((uvlong)1<<(63-i))){
-			m[0] = i;
-			do {
-				m[1] = i;
-			} while(++i<64 && (v & ((uvlong)1<<(63-i))) != 0);
-			for(; i<64; i++)
-				if(v & ((uvlong)1<<(63-i)))
-					return 0;
-			return 1;
-		}
-	return 0;
-}
-
-static void
-maskgen64(Link *ctxt, Prog *p, uchar *m, uvlong v)
-{
-	if(!getmask64(m, v))
-		ctxt->diag("cannot generate mask #%llux\n%P", v, p);
-}
-
-static uint32
-loadu32(int r, vlong d)
-{
-	int32 v;
-
-	v = d>>16;
-	if(isuint32(d))
-		return LOP_IRR(OP_ORIS, r, REGZERO, v);
-	return AOP_IRR(OP_ADDIS, r, REGZERO, v);
-}
-
-static uint16
-high16adjusted(int32 d)
-{
-	if(d & 0x8000)
-		return (d>>16) + 1;
-	return d>>16;
-}
-
-static void
-asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
-{
-	uint32 o1, o2, o3, o4, o5;
-	int32 v, t;
-	vlong d;
-	int r, a;
-	uchar mask[2];
-	Reloc *rel;
-
-	o1 = 0;
-	o2 = 0;
-	o3 = 0;
-	o4 = 0;
-	o5 = 0;
-
-//print("%P => case %d\n", p, o->type);
-	switch(o->type) {
-	default:
-		ctxt->diag("unknown type %d", o->type);
-		prasm(p);
-		break;
-
-	case 0:		/* pseudo ops */
-		break;
-
-	case 1:		/* mov r1,r2 ==> OR Rs,Rs,Ra */
-		if(p->to.reg == REGZERO && p->from.type == TYPE_CONST) {
-			v = regoff(ctxt, &p->from);
-			if(r0iszero && v != 0) {
-				//nerrors--;
-				ctxt->diag("literal operation on R0\n%P", p);
-			}
-			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
-			break;
-		}
-		o1 = LOP_RRR(OP_OR, p->to.reg, p->from.reg, p->from.reg);
-		break;
-
-	case 2:		/* int/cr/fp op Rb,[Ra],Rd */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
-		break;
-
-	case 3:		/* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
-		d = vregoff(ctxt, &p->from);
-		v = d;
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
-			ctxt->diag("literal operation on R0\n%P", p);
-		a = OP_ADDI;
-		if(o->a1 == C_UCON) {
-			if((d&0xffff) != 0)
-				sysfatal("invalid handling of %P", p);
-			v >>= 16;
-			if(r == REGZERO && isuint32(d)){
-				o1 = LOP_IRR(OP_ORIS, p->to.reg, REGZERO, v);
-				break;
-			}
-			a = OP_ADDIS;
-		} else {
-			if((int16)d != d)
-				sysfatal("invalid handling of %P", p);
-		}
-		o1 = AOP_IRR(a, p->to.reg, r, v);
-		break;
-
-	case 4:		/* add/mul $scon,[r1],r2 */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		if(r0iszero && p->to.reg == 0)
-			ctxt->diag("literal operation on R0\n%P", p);
-		if((int16)v != v)
-			sysfatal("mishandled instruction %P", p);
-		o1 = AOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
-		break;
-
-	case 5:		/* syscall */
-		o1 = oprrr(ctxt, p->as);
-		break;
-
-	case 6:		/* logical op Rb,[Rs,]Ra; no literal */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
-		break;
-
-	case 7:		/* mov r, soreg ==> stw o(r) */
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		v = regoff(ctxt, &p->to);
-		if(p->to.type == TYPE_MEM && p->reg != 0) {
-			if(v)
-				ctxt->diag("illegal indexed instruction\n%P", p);
-			o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, p->reg, r);
-		} else {
-			if((int16)v != v)
-				sysfatal("mishandled instruction %P", p);	
-			o1 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, r, v);
-		}
-		break;
-
-	case 8:		/* mov soreg, r ==> lbz/lhz/lwz o(r) */
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		v = regoff(ctxt, &p->from);
-		if(p->from.type == TYPE_MEM && p->reg != 0) {
-			if(v)
-				ctxt->diag("illegal indexed instruction\n%P", p);
-			o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
-		} else {
-			if((int16)v != v)
-				sysfatal("mishandled instruction %P", p);
-			o1 = AOP_IRR(opload(ctxt, p->as), p->to.reg, r, v);
-		}
-		break;
-
-	case 9:		/* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		v = regoff(ctxt, &p->from);
-		if(p->from.type == TYPE_MEM && p->reg != 0) {
-			if(v)
-				ctxt->diag("illegal indexed instruction\n%P", p);
-			o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
-		} else
-			o1 = AOP_IRR(opload(ctxt, p->as), p->to.reg, r, v);
-		o2 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
-		break;
-
-	case 10:		/* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, r);
-		break;
-
-	case 11:	/* br/bl lbra */
-		v = 0;
-		if(p->pcond) {
-			v = p->pcond->pc - p->pc;
-			if(v & 03) {
-				ctxt->diag("odd branch target address\n%P", p);
-				v &= ~03;
-			}
-			if(v < -(1L<<25) || v >= (1L<<24))
-				ctxt->diag("branch too far\n%P", p);
-		}
-		o1 = OP_BR(opirr(ctxt, p->as), v, 0);
-		if(p->to.sym != nil) {
-			rel = addrel(ctxt->cursym);
-			rel->off = ctxt->pc;
-			rel->siz = 4;
-			rel->sym = p->to.sym;
-			v += p->to.offset;
-			if(v & 03) {
-				ctxt->diag("odd branch target address\n%P", p);
-				v &= ~03;
-			}
-			rel->add = v;
-			rel->type = R_CALLPOWER;
-		}
-		break;
-
-	case 12:	/* movb r,r (extsb); movw r,r (extsw) */
-		if(p->to.reg == REGZERO && p->from.type == TYPE_CONST) {
-			v = regoff(ctxt, &p->from);
-			if(r0iszero && v != 0) {
-				ctxt->diag("literal operation on R0\n%P", p);
-			}
-			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
-			break;
-		}
-		if(p->as == AMOVW)
-			o1 = LOP_RRR(OP_EXTSW, p->to.reg, p->from.reg, 0);
-		else
-			o1 = LOP_RRR(OP_EXTSB, p->to.reg, p->from.reg, 0);
-		break;
-
-	case 13:	/* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
-		if(p->as == AMOVBZ)
-			o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 24, 31);
-		else if(p->as == AMOVH)
-			o1 = LOP_RRR(OP_EXTSH, p->to.reg, p->from.reg, 0);
-		else if(p->as == AMOVHZ)
-			o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 16, 31);
-		else if(p->as == AMOVWZ)
-			o1 = OP_RLW(OP_RLDIC, p->to.reg, p->from.reg, 0, 0, 0) | (1<<5);	/* MB=32 */
-		else
-			ctxt->diag("internal: bad mov[bhw]z\n%P", p);
-		break;
-
-	case 14:	/* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		d = vregoff(ctxt, &p->from3);
-		maskgen64(ctxt, p, mask, d);
-		switch(p->as){
-		case ARLDCL: case ARLDCLCC:
-			a = mask[0];	/* MB */
-			if(mask[1] != 63)
-				ctxt->diag("invalid mask for rotate: %llux (end != bit 63)\n%P", d, p);
-			break;
-		case ARLDCR: case ARLDCRCC:
-			a = mask[1];	/* ME */
-			if(mask[0] != 0)
-				ctxt->diag("invalid mask for rotate: %llux (start != 0)\n%P", d, p);
-			break;
-		default:
-			ctxt->diag("unexpected op in rldc case\n%P", p);
-			a = 0;
-		}
-		o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
-		o1 |= (a&31L)<<6;
-		if(a & 0x20)
-			o1 |= 1<<5;	/* mb[5] is top bit */
-		break;
-
-	case 17:	/* bc bo,bi,lbra (same for now) */
-	case 16:	/* bc bo,bi,sbra */
-		a = 0;
-		if(p->from.type == TYPE_CONST)
-			a = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		v = 0;
-		if(p->pcond)
-			v = p->pcond->pc - p->pc;
-		if(v & 03) {
-			ctxt->diag("odd branch target address\n%P", p);
-			v &= ~03;
-		}
-		if(v < -(1L<<16) || v >= (1L<<15))
-			ctxt->diag("branch too far\n%P", p);
-		o1 = OP_BC(opirr(ctxt, p->as), a, r, v, 0);
-		break;
-
-	case 15:	/* br/bl (r) => mov r,lr; br/bl (lr) */
-		if(p->as == ABC || p->as == ABCL)
-			v = regoff(ctxt, &p->to)&31L;
-		else
-			v = 20;	/* unconditional */
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((REG_LR&0x1f)<<16) | (((REG_LR>>5)&0x1f)<<11);
-		o2 = OPVCC(19, 16, 0, 0);
-		if(p->as == ABL || p->as == ABCL)
-			o2 |= 1;
-		o2 = OP_BCR(o2, v, r);
-		break;
-
-	case 18:	/* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
-		if(p->as == ABC || p->as == ABCL)
-			v = regoff(ctxt, &p->from)&31L;
-		else
-			v = 20;	/* unconditional */
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		switch(oclass(&p->to)) {
-		case C_CTR:
-			o1 = OPVCC(19, 528, 0, 0);
-			break;
-		case C_LR:
-			o1 = OPVCC(19, 16, 0, 0);
-			break;
-		default:
-			ctxt->diag("bad optab entry (18): %d\n%P", p->to.class, p);
-			v = 0;
-		}
-		if(p->as == ABL || p->as == ABCL)
-			o1 |= 1;
-		o1 = OP_BCR(o1, v, r);
-		break;
-
-	case 19:	/* mov $lcon,r ==> cau+or */
-		d = vregoff(ctxt, &p->from);
-		if(p->from.sym == nil) {
-			o1 = loadu32(p->to.reg, d);
-			o2 = LOP_IRR(OP_ORI, p->to.reg, p->to.reg, (int32)d);
-		} else {
-			o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(d));
-			o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, d);
-			addaddrreloc(ctxt, p->from.sym, &o1, &o2);
-		}
-		//if(dlm) reloc(&p->from, p->pc, 0);
-		break;
-
-	case 20:	/* add $ucon,,r */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
-			ctxt->diag("literal operation on R0\n%P", p);
-		o1 = AOP_IRR(opirr(ctxt, p->as+ALAST), p->to.reg, r, v>>16);
-		break;
-
-	case 22:	/* add $lcon,r1,r2 ==> cau+or+add */	/* could do add/sub more efficiently */
-		if(p->to.reg == REGTMP || p->reg == REGTMP)
-			ctxt->diag("cant synthesize large constant\n%P", p);
-		d = vregoff(ctxt, &p->from);
-		o1 = loadu32(REGTMP, d);
-		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o3 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
-		if(p->from.sym != nil)
-			ctxt->diag("%P is not supported", p);
-		//if(dlm) reloc(&p->from, p->pc, 0);
-		break;
-
-	case 23:	/* and $lcon,r1,r2 ==> cau+or+and */	/* masks could be done using rlnm etc. */
-		if(p->to.reg == REGTMP || p->reg == REGTMP)
-			ctxt->diag("cant synthesize large constant\n%P", p);
-		d = vregoff(ctxt, &p->from);
-		o1 = loadu32(REGTMP, d);
-		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o3 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
-		if(p->from.sym != nil)
-			ctxt->diag("%P is not supported", p);
-		//if(dlm) reloc(&p->from, p->pc, 0);
-		break;
-/*24*/
-
-	case 25:	/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
-		v = regoff(ctxt, &p->from);
-		if(v < 0)
-			v = 0;
-		else if(v > 63)
-			v = 63;
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		switch(p->as){
-		case ASLD: case ASLDCC:
-			a = 63-v;
-			o1 = OP_RLDICR;
-			break;
-		case ASRD: case ASRDCC:
-			a = v;
-			v = 64-v;
-			o1 = OP_RLDICL;
-			break;
-		default:
-			ctxt->diag("unexpected op in sldi case\n%P", p);
-			a = 0;
-			o1 = 0;
-		}
-		o1 = AOP_RRR(o1, r, p->to.reg, (v&0x1F));
-		o1 |= (a&31L)<<6;
-		if(v & 0x20)
-			o1 |= 1<<1;
-		if(a & 0x20)
-			o1 |= 1<<5;	/* mb[5] is top bit */
-		if(p->as == ASLDCC || p->as == ASRDCC)
-			o1 |= 1;	/* Rc */
-		break;
-
-	case 26:	/* mov $lsext/auto/oreg,,r2 ==> addis+addi */
-		if(p->to.reg == REGTMP)
-			ctxt->diag("can't synthesize large constant\n%P", p);
-		v = regoff(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
-		o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
-		break;
-
-	case 27:		/* subc ra,$simm,rd => subfic rd,ra,$simm */
-		v = regoff(ctxt, &p->from3);
-		r = p->from.reg;
-		o1 = AOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
-		break;
-
-	case 28:	/* subc r1,$lcon,r2 ==> cau+or+subfc */
-		if(p->to.reg == REGTMP || p->from.reg == REGTMP)
-			ctxt->diag("can't synthesize large constant\n%P", p);
-		v = regoff(ctxt, &p->from3);
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
-		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
-		o3 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, REGTMP);
-		if(p->from.sym != nil)
-			ctxt->diag("%P is not supported", p);
-		//if(dlm) reloc(&p->from3, p->pc, 0);
-		break;
-
-	case 29:	/* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
-		v = regoff(ctxt, &p->from);
-		d = vregoff(ctxt, &p->from3);
-		maskgen64(ctxt, p, mask, d);
-		switch(p->as){
-		case ARLDC: case ARLDCCC:
-			a = mask[0];	/* MB */
-			if(mask[1] != (63-v))
-				ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
-			break;
-		case ARLDCL: case ARLDCLCC:
-			a = mask[0];	/* MB */
-			if(mask[1] != 63)
-				ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
-			break;
-		case ARLDCR: case ARLDCRCC:
-			a = mask[1];	/* ME */
-			if(mask[0] != 0)
-				ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
-			break;
-		default:
-			ctxt->diag("unexpected op in rldic case\n%P", p);
-			a = 0;
-		}
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, (v&0x1F));
-		o1 |= (a&31L)<<6;
-		if(v & 0x20)
-			o1 |= 1<<1;
-		if(a & 0x20)
-			o1 |= 1<<5;	/* mb[5] is top bit */
-		break;
-
-	case 30:	/* rldimi $sh,s,$mask,a */
-		v = regoff(ctxt, &p->from);
-		d = vregoff(ctxt, &p->from3);
-		maskgen64(ctxt, p, mask, d);
-		if(mask[1] != (63-v))
-			ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, (v&0x1F));
-		o1 |= (mask[0]&31L)<<6;
-		if(v & 0x20)
-			o1 |= 1<<1;
-		if(mask[0] & 0x20)
-			o1 |= 1<<5;	/* mb[5] is top bit */
-		break;
-
-	case 31:	/* dword */
-		d = vregoff(ctxt, &p->from);
-		if(ctxt->arch->endian == BigEndian) {
-			o1 = d>>32;
-			o2 = d;
-		} else {
-			o1 = d;
-			o2 = d>>32;
-		}
-		if(p->from.sym != nil) {
-			rel = addrel(ctxt->cursym);
-			rel->off = ctxt->pc;
-			rel->siz = 8;
-			rel->sym = p->from.sym;
-			rel->add = p->from.offset;
-			rel->type = R_ADDR;
-			o1 = o2 = 0;
-		}
-		break;
-
-	case 32:	/* fmul frc,fra,frd */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
-		break;
-
-	case 33:	/* fabs [frb,]frd; fmr. frb,frd */
-		r = p->from.reg;
-		if(oclass(&p->from) == C_NONE)
-			r = p->to.reg;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, 0, r);
-		break;
-
-	case 34:	/* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6);
-		break;
-
-	case 35:	/* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
-		v = regoff(ctxt, &p->to);
-		r = p->to.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
-		o2 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, REGTMP, v);
-		break;
-
-	case 36:	/* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
-		v = regoff(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
-		o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
-		break;
-
-	case 37:	/* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
-		v = regoff(ctxt, &p->from);
-		r = p->from.reg;
-		if(r == 0)
-			r = o->param;
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
-		o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
-		o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
-		break;
-
-	case 40:	/* word */
-		o1 = regoff(ctxt, &p->from);
-		break;
-
-	case 41:	/* stswi */
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->from.reg, p->to.reg, 0) | ((regoff(ctxt, &p->from3)&0x7F)<<11);
-		break;
-
-	case 42:	/* lswi */
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->to.reg, p->from.reg, 0) | ((regoff(ctxt, &p->from3)&0x7F)<<11);
-		break;
-
-	case 43:	/* unary indexed source: dcbf (b); dcbf (a+b) */
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), 0, r, p->from.reg);
-		break;
-
-	case 44:	/* indexed store */
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, r, p->to.reg);
-		break;
-	case 45:	/* indexed load */
-		r = p->reg;
-		if(r == 0)
-			r = 0;
-		o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, r, p->from.reg);
-		break;
-
-	case 46:	/* plain op */
-		o1 = oprrr(ctxt, p->as);
-		break;
-
-	case 47:	/* op Ra, Rd; also op [Ra,] Rd */
-		r = p->from.reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
-		break;
-
-	case 48:	/* op Rs, Ra */
-		r = p->from.reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
-		break;
-
-	case 49:	/* op Rb; op $n, Rb */
-		if(p->from.type != TYPE_REG){	/* tlbie $L, rB */
-			v = regoff(ctxt, &p->from) & 1;
-			o1 = AOP_RRR(oprrr(ctxt, p->as), 0, 0, p->to.reg) | (v<<21);
-		}else
-			o1 = AOP_RRR(oprrr(ctxt, p->as), 0, 0, p->from.reg);
-		break;
-
-	case 50:	/* rem[u] r1[,r2],r3 */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		v = oprrr(ctxt, p->as);
-		t = v & ((1<<10)|1);	/* OE|Rc */
-		o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
-		o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
-		o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
-		if(p->as == AREMU) {
-			o4 = o3;
-			/* Clear top 32 bits */
-			o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | (1<<5);
-		}
-		break;
-
-	case 51:	/* remd[u] r1[,r2],r3 */
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		v = oprrr(ctxt, p->as);
-		t = v & ((1<<10)|1);	/* OE|Rc */
-		o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
-		o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, p->from.reg);
-		o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
-		break;
-
-	case 52:	/* mtfsbNx cr(n) */
-		v = regoff(ctxt, &p->from)&31L;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), v, 0, 0);
-		break;
-
-	case 53:	/* mffsX ,fr1 */
-		o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0);
-		break;
-
-	case 54:	/* mov msr,r1; mov r1, msr*/
-		if(oclass(&p->from) == C_REG){
-			if(p->as == AMOVD)
-				o1 = AOP_RRR(OP_MTMSRD, p->from.reg, 0, 0);
-			else
-				o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0);
-		}else
-			o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0);
-		break;
-
-	case 55:	/* op Rb, Rd */
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, 0, p->from.reg);
-		break;
-
-	case 56:	/* sra $sh,[s,]a; srd $sh,[s,]a */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = AOP_RRR(opirr(ctxt, p->as), r, p->to.reg, v&31L);
-		if(p->as == ASRAD && (v&0x20))
-			o1 |= 1<<1;	/* mb[5] */
-		break;
-
-	case 57:	/* slw $sh,[s,]a -> rlwinm ... */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		/*
-		 * Let user (gs) shoot himself in the foot. 
-		 * qc has already complained.
-		 *
-		if(v < 0 || v > 31)
-			ctxt->diag("illegal shift %ld\n%P", v, p);
-		 */
-		if(v < 0)
-			v = 0;
-		else if(v > 32)
-			v = 32;
-		if(p->as == ASRW || p->as == ASRWCC) {	/* shift right */
-			mask[0] = v;
-			mask[1] = 31;
-			v = 32-v;
-		} else {
-			mask[0] = 0;
-			mask[1] = 31-v;
-		}
-		o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]);
-		if(p->as == ASLWCC || p->as == ASRWCC)
-			o1 |= 1;	/* Rc */
-		break;
-
-	case 58:		/* logical $andcon,[s],a */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = LOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
-		break;
-
-	case 59:	/* or/and $ucon,,r */
-		v = regoff(ctxt, &p->from);
-		r = p->reg;
-		if(r == 0)
-			r = p->to.reg;
-		o1 = LOP_IRR(opirr(ctxt, p->as+ALAST), p->to.reg, r, v>>16);	/* oris, xoris, andis */
-		break;
-
-	case 60:	/* tw to,a,b */
-		r = regoff(ctxt, &p->from)&31L;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), r, p->reg, p->to.reg);
-		break;
-
-	case 61:	/* tw to,a,$simm */
-		r = regoff(ctxt, &p->from)&31L;
-		v = regoff(ctxt, &p->to);
-		o1 = AOP_IRR(opirr(ctxt, p->as), r, p->reg, v);
-		break;
-
-	case 62:	/* rlwmi $sh,s,$mask,a */
-		v = regoff(ctxt, &p->from);
-		maskgen(ctxt, p, mask, regoff(ctxt, &p->from3));
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, v);
-		o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
-		break;
-
-	case 63:	/* rlwmi b,s,$mask,a */
-		maskgen(ctxt, p, mask, regoff(ctxt, &p->from3));
-		o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, p->from.reg);
-		o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
-		break;
-
-	case 64:	/* mtfsf fr[, $m] {,fpcsr} */
-		if(p->from3.type != TYPE_NONE)
-			v = regoff(ctxt, &p->from3)&255L;
-		else
-			v = 255;
-		o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11);
-		break;
-
-	case 65:	/* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
-		if(p->to.reg == 0)
-			ctxt->diag("must specify FPSCR(n)\n%P", p);
-		o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(ctxt, &p->from)&31L)<<12);
-		break;
-
-	case 66:	/* mov spr,r1; mov r1,spr, also dcr */
-		if(REG_R0 <= p->from.reg && p->from.reg <= REG_R31) {
-			r = p->from.reg;
-			v = p->to.reg;
-			if(REG_DCR0 <= v && v <= REG_DCR0+1023)
-				o1 = OPVCC(31,451,0,0);	/* mtdcr */
-			else
-				o1 = OPVCC(31,467,0,0); /* mtspr */
-		} else {
-			r = p->to.reg;
-			v = p->from.reg;
-			if(REG_DCR0 <= v && v <= REG_DCR0+1023)
-				o1 = OPVCC(31,323,0,0);	/* mfdcr */
-			else
-				o1 = OPVCC(31,339,0,0);	/* mfspr */
-		}
-		o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
-		break;
-
-	case 67:	/* mcrf crfD,crfS */
-		if(p->from.type != TYPE_REG || p->from.reg < REG_C0 || REG_C7 < p->from.reg ||
-		   p->to.type != TYPE_REG || p->to.reg < REG_C0 || REG_C7 < p->to.reg)
-			ctxt->diag("illegal CR field number\n%P", p);
-		o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
-		break;
-
-	case 68:	/* mfcr rD; mfocrf CRM,rD */
-		if(p->from.type == TYPE_REG && REG_C0 <= p->from.reg && p->from.reg <= REG_C7) {
-			v = 1<<(7-(p->to.reg&7));	/* CR(n) */
-			o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0) | (1<<20) | (v<<12);	/* new form, mfocrf */
-		}else
-			o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0);	/* old form, whole register */
-		break;
-
-	case 69:	/* mtcrf CRM,rS */
-		if(p->from3.type != TYPE_NONE) {
-			if(p->to.reg != 0)
-				ctxt->diag("can't use both mask and CR(n)\n%P", p);
-			v = regoff(ctxt, &p->from3) & 0xff;
-		} else {
-			if(p->to.reg == 0)
-				v = 0xff;	/* CR */
-			else
-				v = 1<<(7-(p->to.reg&7));	/* CR(n) */
-		}
-		o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
-		break;
-
-	case 70:	/* [f]cmp r,r,cr*/
-		if(p->reg == 0)
-			r = 0;
-		else
-			r = (p->reg&7)<<2;
-		o1 = AOP_RRR(oprrr(ctxt, p->as), r, p->from.reg, p->to.reg);
-		break;
-
-	case 71:	/* cmp[l] r,i,cr*/
-		if(p->reg == 0)
-			r = 0;
-		else
-			r = (p->reg&7)<<2;
-		o1 = AOP_RRR(opirr(ctxt, p->as), r, p->from.reg, 0) | (regoff(ctxt, &p->to)&0xffff);
-		break;
-
-	case 72:	/* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
-		o1 = AOP_RRR(oprrr(ctxt, p->as), p->from.reg, 0, p->to.reg);
-		break;
-
-	case 73:	/* mcrfs crfD,crfS */
-		if(p->from.type != TYPE_REG || p->from.reg != REG_FPSCR ||
-		   p->to.type != TYPE_REG || p->to.reg < REG_C0 || REG_C7 < p->to.reg)
-			ctxt->diag("illegal FPSCR/CR field number\n%P", p);
-		o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((0&7)<<2), 0);
-		break;
-
-	case 77:	/* syscall $scon, syscall Rx */
-		if(p->from.type == TYPE_CONST) {
-			if(p->from.offset > BIG || p->from.offset < -BIG)
-				ctxt->diag("illegal syscall, sysnum too large: %P", p);
-			o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, p->from.offset);
-		} else if(p->from.type == TYPE_REG) {
-			o1 = LOP_RRR(OP_OR, REGZERO, p->from.reg, p->from.reg);
-		} else {
-			ctxt->diag("illegal syscall: %P", p);
-			o1 = 0x7fe00008; // trap always
-		}
-		o2 = oprrr(ctxt, p->as);
-		o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO); // XOR R0, R0
-		break;
-
-	case 78:	/* undef */
-		o1 = 0; /* "An instruction consisting entirely of binary 0s is guaranteed
-			   always to be an illegal instruction."  */
-		break;
-
-	/* relocation operations */
-
-	case 74:
-		v = regoff(ctxt, &p->to);
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
-		o2 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, REGTMP, v);
-		addaddrreloc(ctxt, p->to.sym, &o1, &o2);
-		//if(dlm) reloc(&p->to, p->pc, 1);
-		break;
-
-	case 75:
-		v = regoff(ctxt, &p->from);
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
-		o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
-		addaddrreloc(ctxt, p->from.sym, &o1, &o2);
-		//if(dlm) reloc(&p->from, p->pc, 1);
-		break;
-
-	case 76:
-		v = regoff(ctxt, &p->from);
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
-		o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
-		addaddrreloc(ctxt, p->from.sym, &o1, &o2);
-		o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
-		//if(dlm) reloc(&p->from, p->pc, 1);
-		break;
-
-	}
-
-	out[0] = o1;
-	out[1] = o2;
-	out[2] = o3;
-	out[3] = o4;
-	out[4] = o5;
-	return;
-}
-
-static vlong
-vregoff(Link *ctxt, Addr *a)
-{
-
-	ctxt->instoffset = 0;
-	aclass(ctxt, a);
-	return ctxt->instoffset;
-}
-
-static int32
-regoff(Link *ctxt, Addr *a)
-{
-	return vregoff(ctxt, a);
-}
-
-static int32
-oprrr(Link *ctxt, int a)
-{
-	switch(a) {
-	case AADD:	return OPVCC(31,266,0,0);
-	case AADDCC:	return OPVCC(31,266,0,1);
-	case AADDV:	return OPVCC(31,266,1,0);
-	case AADDVCC:	return OPVCC(31,266,1,1);
-	case AADDC:	return OPVCC(31,10,0,0);
-	case AADDCCC:	return OPVCC(31,10,0,1);
-	case AADDCV:	return OPVCC(31,10,1,0);
-	case AADDCVCC:	return OPVCC(31,10,1,1);
-	case AADDE:	return OPVCC(31,138,0,0);
-	case AADDECC:	return OPVCC(31,138,0,1);
-	case AADDEV:	return OPVCC(31,138,1,0);
-	case AADDEVCC:	return OPVCC(31,138,1,1);
-	case AADDME:	return OPVCC(31,234,0,0);
-	case AADDMECC:	return OPVCC(31,234,0,1);
-	case AADDMEV:	return OPVCC(31,234,1,0);
-	case AADDMEVCC:	return OPVCC(31,234,1,1);
-	case AADDZE:	return OPVCC(31,202,0,0);
-	case AADDZECC:	return OPVCC(31,202,0,1);
-	case AADDZEV:	return OPVCC(31,202,1,0);
-	case AADDZEVCC:	return OPVCC(31,202,1,1);
-
-	case AAND:	return OPVCC(31,28,0,0);
-	case AANDCC:	return OPVCC(31,28,0,1);
-	case AANDN:	return OPVCC(31,60,0,0);
-	case AANDNCC:	return OPVCC(31,60,0,1);
-
-	case ACMP:	return OPVCC(31,0,0,0)|(1<<21);	/* L=1 */
-	case ACMPU:	return OPVCC(31,32,0,0)|(1<<21);
-	case ACMPW:	return OPVCC(31,0,0,0);	/* L=0 */
-	case ACMPWU:	return OPVCC(31,32,0,0);
-
-	case ACNTLZW:	return OPVCC(31,26,0,0);
-	case ACNTLZWCC:	return OPVCC(31,26,0,1);
-	case ACNTLZD:		return OPVCC(31,58,0,0);
-	case ACNTLZDCC:	return OPVCC(31,58,0,1);
-
-	case ACRAND:	return OPVCC(19,257,0,0);
-	case ACRANDN:	return OPVCC(19,129,0,0);
-	case ACREQV:	return OPVCC(19,289,0,0);
-	case ACRNAND:	return OPVCC(19,225,0,0);
-	case ACRNOR:	return OPVCC(19,33,0,0);
-	case ACROR:	return OPVCC(19,449,0,0);
-	case ACRORN:	return OPVCC(19,417,0,0);
-	case ACRXOR:	return OPVCC(19,193,0,0);
-
-	case ADCBF:	return OPVCC(31,86,0,0);
-	case ADCBI:	return OPVCC(31,470,0,0);
-	case ADCBST:	return OPVCC(31,54,0,0);
-	case ADCBT:	return OPVCC(31,278,0,0);
-	case ADCBTST:	return OPVCC(31,246,0,0);
-	case ADCBZ:	return OPVCC(31,1014,0,0);
-
-	case AREM:
-	case ADIVW:	return OPVCC(31,491,0,0);
-	case AREMCC:
-	case ADIVWCC:	return OPVCC(31,491,0,1);
-	case AREMV:
-	case ADIVWV:	return OPVCC(31,491,1,0);
-	case AREMVCC:
-	case ADIVWVCC:	return OPVCC(31,491,1,1);
-	case AREMU:
-	case ADIVWU:	return OPVCC(31,459,0,0);
-	case AREMUCC:
-	case ADIVWUCC:	return OPVCC(31,459,0,1);
-	case AREMUV:
-	case ADIVWUV:	return OPVCC(31,459,1,0);
-	case AREMUVCC:
-	case ADIVWUVCC:	return OPVCC(31,459,1,1);
-
-	case AREMD:
-	case ADIVD:	return OPVCC(31,489,0,0);
-	case AREMDCC:
-	case ADIVDCC:	return OPVCC(31,489,0,1);
-	case AREMDV:
-	case ADIVDV:	return OPVCC(31,489,1,0);
-	case AREMDVCC:
-	case ADIVDVCC:	return OPVCC(31,489,1,1);
-	case AREMDU:
-	case ADIVDU:	return OPVCC(31,457,0,0);
-	case AREMDUCC:
-	case ADIVDUCC:	return OPVCC(31,457,0,1);
-	case AREMDUV:
-	case ADIVDUV:	return OPVCC(31,457,1,0);
-	case AREMDUVCC:
-	case ADIVDUVCC:	return OPVCC(31,457,1,1);
-
-	case AEIEIO:	return OPVCC(31,854,0,0);
-
-	case AEQV:	return OPVCC(31,284,0,0);
-	case AEQVCC:	return OPVCC(31,284,0,1);
-
-	case AEXTSB:	return OPVCC(31,954,0,0);
-	case AEXTSBCC:	return OPVCC(31,954,0,1);
-	case AEXTSH:	return OPVCC(31,922,0,0);
-	case AEXTSHCC:	return OPVCC(31,922,0,1);
-	case AEXTSW:	return OPVCC(31,986,0,0);
-	case AEXTSWCC:	return OPVCC(31,986,0,1);
-
-	case AFABS:	return OPVCC(63,264,0,0);
-	case AFABSCC:	return OPVCC(63,264,0,1);
-	case AFADD:	return OPVCC(63,21,0,0);
-	case AFADDCC:	return OPVCC(63,21,0,1);
-	case AFADDS:	return OPVCC(59,21,0,0);
-	case AFADDSCC:	return OPVCC(59,21,0,1);
-	case AFCMPO:	return OPVCC(63,32,0,0);
-	case AFCMPU:	return OPVCC(63,0,0,0);
-	case AFCFID:	return OPVCC(63,846,0,0);
-	case AFCFIDCC:	return OPVCC(63,846,0,1);
-	case AFCTIW:	return OPVCC(63,14,0,0);
-	case AFCTIWCC:	return OPVCC(63,14,0,1);
-	case AFCTIWZ:	return OPVCC(63,15,0,0);
-	case AFCTIWZCC:	return OPVCC(63,15,0,1);
-	case AFCTID:	return OPVCC(63,814,0,0);
-	case AFCTIDCC:	return OPVCC(63,814,0,1);
-	case AFCTIDZ:	return OPVCC(63,815,0,0);
-	case AFCTIDZCC:	return OPVCC(63,815,0,1);
-	case AFDIV:	return OPVCC(63,18,0,0);
-	case AFDIVCC:	return OPVCC(63,18,0,1);
-	case AFDIVS:	return OPVCC(59,18,0,0);
-	case AFDIVSCC:	return OPVCC(59,18,0,1);
-	case AFMADD:	return OPVCC(63,29,0,0);
-	case AFMADDCC:	return OPVCC(63,29,0,1);
-	case AFMADDS:	return OPVCC(59,29,0,0);
-	case AFMADDSCC:	return OPVCC(59,29,0,1);
-	case AFMOVS:
-	case AFMOVD:	return OPVCC(63,72,0,0);	/* load */
-	case AFMOVDCC:	return OPVCC(63,72,0,1);
-	case AFMSUB:	return OPVCC(63,28,0,0);
-	case AFMSUBCC:	return OPVCC(63,28,0,1);
-	case AFMSUBS:	return OPVCC(59,28,0,0);
-	case AFMSUBSCC:	return OPVCC(59,28,0,1);
-	case AFMUL:	return OPVCC(63,25,0,0);
-	case AFMULCC:	return OPVCC(63,25,0,1);
-	case AFMULS:	return OPVCC(59,25,0,0);
-	case AFMULSCC:	return OPVCC(59,25,0,1);
-	case AFNABS:	return OPVCC(63,136,0,0);
-	case AFNABSCC:	return OPVCC(63,136,0,1);
-	case AFNEG:	return OPVCC(63,40,0,0);
-	case AFNEGCC:	return OPVCC(63,40,0,1);
-	case AFNMADD:	return OPVCC(63,31,0,0);
-	case AFNMADDCC:	return OPVCC(63,31,0,1);
-	case AFNMADDS:	return OPVCC(59,31,0,0);
-	case AFNMADDSCC:	return OPVCC(59,31,0,1);
-	case AFNMSUB:	return OPVCC(63,30,0,0);
-	case AFNMSUBCC:	return OPVCC(63,30,0,1);
-	case AFNMSUBS:	return OPVCC(59,30,0,0);
-	case AFNMSUBSCC:	return OPVCC(59,30,0,1);
-	case AFRES:	return OPVCC(59,24,0,0);
-	case AFRESCC:	return OPVCC(59,24,0,1);
-	case AFRSP:	return OPVCC(63,12,0,0);
-	case AFRSPCC:	return OPVCC(63,12,0,1);
-	case AFRSQRTE:	return OPVCC(63,26,0,0);
-	case AFRSQRTECC:	return OPVCC(63,26,0,1);
-	case AFSEL:	return OPVCC(63,23,0,0);
-	case AFSELCC:	return OPVCC(63,23,0,1);
-	case AFSQRT:	return OPVCC(63,22,0,0);
-	case AFSQRTCC:	return OPVCC(63,22,0,1);
-	case AFSQRTS:	return OPVCC(59,22,0,0);
-	case AFSQRTSCC:	return OPVCC(59,22,0,1);
-	case AFSUB:	return OPVCC(63,20,0,0);
-	case AFSUBCC:	return OPVCC(63,20,0,1);
-	case AFSUBS:	return OPVCC(59,20,0,0);
-	case AFSUBSCC:	return OPVCC(59,20,0,1);
-
-	case AICBI:	return OPVCC(31,982,0,0);
-	case AISYNC:	return OPVCC(19,150,0,0);
-
-	case AMTFSB0:	return OPVCC(63,70,0,0);
-	case AMTFSB0CC:	return OPVCC(63,70,0,1);
-	case AMTFSB1:	return OPVCC(63,38,0,0);
-	case AMTFSB1CC:	return OPVCC(63,38,0,1);
-
-	case AMULHW:	return OPVCC(31,75,0,0);
-	case AMULHWCC:	return OPVCC(31,75,0,1);
-	case AMULHWU:	return OPVCC(31,11,0,0);
-	case AMULHWUCC:	return OPVCC(31,11,0,1);
-	case AMULLW:	return OPVCC(31,235,0,0);
-	case AMULLWCC:	return OPVCC(31,235,0,1);
-	case AMULLWV:	return OPVCC(31,235,1,0);
-	case AMULLWVCC:	return OPVCC(31,235,1,1);
-
-	case AMULHD:	return OPVCC(31,73,0,0);
-	case AMULHDCC:	return OPVCC(31,73,0,1);
-	case AMULHDU:	return OPVCC(31,9,0,0);
-	case AMULHDUCC:	return OPVCC(31,9,0,1);
-	case AMULLD:	return OPVCC(31,233,0,0);
-	case AMULLDCC:	return OPVCC(31,233,0,1);
-	case AMULLDV:	return OPVCC(31,233,1,0);
-	case AMULLDVCC:	return OPVCC(31,233,1,1);
-
-	case ANAND:	return OPVCC(31,476,0,0);
-	case ANANDCC:	return OPVCC(31,476,0,1);
-	case ANEG:	return OPVCC(31,104,0,0);
-	case ANEGCC:	return OPVCC(31,104,0,1);
-	case ANEGV:	return OPVCC(31,104,1,0);
-	case ANEGVCC:	return OPVCC(31,104,1,1);
-	case ANOR:	return OPVCC(31,124,0,0);
-	case ANORCC:	return OPVCC(31,124,0,1);
-	case AOR:	return OPVCC(31,444,0,0);
-	case AORCC:	return OPVCC(31,444,0,1);
-	case AORN:	return OPVCC(31,412,0,0);
-	case AORNCC:	return OPVCC(31,412,0,1);
-
-	case ARFI:	return OPVCC(19,50,0,0);
-	case ARFCI:	return OPVCC(19,51,0,0);
-	case ARFID:	return OPVCC(19,18,0,0);
-	case AHRFID: return OPVCC(19,274,0,0);
-
-	case ARLWMI:	return OPVCC(20,0,0,0);
-	case ARLWMICC: return OPVCC(20,0,0,1);
-	case ARLWNM:	return OPVCC(23,0,0,0);
-	case ARLWNMCC:	return OPVCC(23,0,0,1);
-
-	case ARLDCL:	return OPVCC(30,8,0,0);
-	case ARLDCR:	return OPVCC(30,9,0,0);
-
-	case ASYSCALL:	return OPVCC(17,1,0,0);
-
-	case ASLW:	return OPVCC(31,24,0,0);
-	case ASLWCC:	return OPVCC(31,24,0,1);
-	case ASLD:	return OPVCC(31,27,0,0);
-	case ASLDCC:	return OPVCC(31,27,0,1);
-
-	case ASRAW:	return OPVCC(31,792,0,0);
-	case ASRAWCC:	return OPVCC(31,792,0,1);
-	case ASRAD:	return OPVCC(31,794,0,0);
-	case ASRADCC:	return OPVCC(31,794,0,1);
-
-	case ASRW:	return OPVCC(31,536,0,0);
-	case ASRWCC:	return OPVCC(31,536,0,1);
-	case ASRD:	return OPVCC(31,539,0,0);
-	case ASRDCC:	return OPVCC(31,539,0,1);
-
-	case ASUB:	return OPVCC(31,40,0,0);
-	case ASUBCC:	return OPVCC(31,40,0,1);
-	case ASUBV:	return OPVCC(31,40,1,0);
-	case ASUBVCC:	return OPVCC(31,40,1,1);
-	case ASUBC:	return OPVCC(31,8,0,0);
-	case ASUBCCC:	return OPVCC(31,8,0,1);
-	case ASUBCV:	return OPVCC(31,8,1,0);
-	case ASUBCVCC:	return OPVCC(31,8,1,1);
-	case ASUBE:	return OPVCC(31,136,0,0);
-	case ASUBECC:	return OPVCC(31,136,0,1);
-	case ASUBEV:	return OPVCC(31,136,1,0);
-	case ASUBEVCC:	return OPVCC(31,136,1,1);
-	case ASUBME:	return OPVCC(31,232,0,0);
-	case ASUBMECC:	return OPVCC(31,232,0,1);
-	case ASUBMEV:	return OPVCC(31,232,1,0);
-	case ASUBMEVCC:	return OPVCC(31,232,1,1);
-	case ASUBZE:	return OPVCC(31,200,0,0);
-	case ASUBZECC:	return OPVCC(31,200,0,1);
-	case ASUBZEV:	return OPVCC(31,200,1,0);
-	case ASUBZEVCC:	return OPVCC(31,200,1,1);
-
-	case ASYNC:	return OPVCC(31,598,0,0);
-	case APTESYNC:	return OPVCC(31,598,0,0) | (2<<21);
-
-	case ATLBIE:	return OPVCC(31,306,0,0);
-	case ATLBIEL:	return OPVCC(31,274,0,0);
-	case ATLBSYNC:	return OPVCC(31,566,0,0);
-	case ASLBIA:	return OPVCC(31,498,0,0);
-	case ASLBIE:	return OPVCC(31,434,0,0);
-	case ASLBMFEE:	return OPVCC(31,915,0,0);
-	case ASLBMFEV:	return OPVCC(31,851,0,0);
-	case ASLBMTE:		return OPVCC(31,402,0,0);
-
-	case ATW:	return OPVCC(31,4,0,0);
-	case ATD:	return OPVCC(31,68,0,0);
-
-	case AXOR:	return OPVCC(31,316,0,0);
-	case AXORCC:	return OPVCC(31,316,0,1);
-	}
-	ctxt->diag("bad r/r opcode %A", a);
-	return 0;
-}
-
-static int32
-opirr(Link *ctxt, int a)
-{
-	switch(a) {
-	case AADD:	return OPVCC(14,0,0,0);
-	case AADDC:	return OPVCC(12,0,0,0);
-	case AADDCCC:	return OPVCC(13,0,0,0);
-	case AADD+ALAST:	return OPVCC(15,0,0,0);		/* ADDIS/CAU */
-
-	case AANDCC:	return OPVCC(28,0,0,0);
-	case AANDCC+ALAST:	return OPVCC(29,0,0,0);		/* ANDIS./ANDIU. */
-
-	case ABR:	return OPVCC(18,0,0,0);
-	case ABL:	return OPVCC(18,0,0,0) | 1;
-	case ADUFFZERO:	return OPVCC(18,0,0,0) | 1;
-	case ADUFFCOPY:	return OPVCC(18,0,0,0) | 1;
-	case ABC:	return OPVCC(16,0,0,0);
-	case ABCL:	return OPVCC(16,0,0,0) | 1;
-
-	case ABEQ:	return AOP_RRR(16<<26,12,2,0);
-	case ABGE:	return AOP_RRR(16<<26,4,0,0);
-	case ABGT:	return AOP_RRR(16<<26,12,1,0);
-	case ABLE:	return AOP_RRR(16<<26,4,1,0);
-	case ABLT:	return AOP_RRR(16<<26,12,0,0);
-	case ABNE:	return AOP_RRR(16<<26,4,2,0);
-	case ABVC:	return AOP_RRR(16<<26,4,3,0);
-	case ABVS:	return AOP_RRR(16<<26,12,3,0);
-
-	case ACMP:	return OPVCC(11,0,0,0)|(1<<21);	/* L=1 */
-	case ACMPU:	return OPVCC(10,0,0,0)|(1<<21);
-	case ACMPW:	return OPVCC(11,0,0,0);	/* L=0 */
-	case ACMPWU:	return OPVCC(10,0,0,0);
-	case ALSW:	return OPVCC(31,597,0,0);
-
-	case AMULLW:	return OPVCC(7,0,0,0);
-
-	case AOR:	return OPVCC(24,0,0,0);
-	case AOR+ALAST:	return OPVCC(25,0,0,0);		/* ORIS/ORIU */
-
-	case ARLWMI:	return OPVCC(20,0,0,0);		/* rlwimi */
-	case ARLWMICC:	return OPVCC(20,0,0,1);
-	case ARLDMI:	return OPVCC(30,0,0,0) | (3<<2);	/* rldimi */
-	case ARLDMICC:	return OPVCC(30,0,0,1) | (3<<2);
-
-	case ARLWNM:	return OPVCC(21,0,0,0);		/* rlwinm */
-	case ARLWNMCC:	return OPVCC(21,0,0,1);
-
-	case ARLDCL:	return OPVCC(30,0,0,0);		/* rldicl */
-	case ARLDCLCC:	return OPVCC(30,0,0,1);
-	case ARLDCR:	return OPVCC(30,1,0,0);		/* rldicr */
-	case ARLDCRCC:	return OPVCC(30,1,0,1);
-	case ARLDC:	return OPVCC(30,0,0,0) | (2<<2);
-	case ARLDCCC:	return OPVCC(30,0,0,1) | (2<<2);
-
-	case ASRAW:	return OPVCC(31,824,0,0);
-	case ASRAWCC:	return OPVCC(31,824,0,1);
-	case ASRAD:	return OPVCC(31,(413<<1),0,0);
-	case ASRADCC:	return OPVCC(31,(413<<1),0,1);
-
-	case ASTSW:	return OPVCC(31,725,0,0);
-
-	case ASUBC:	return OPVCC(8,0,0,0);
-
-	case ATW:	return OPVCC(3,0,0,0);
-	case ATD:	return OPVCC(2,0,0,0);
-
-	case AXOR:	return OPVCC(26,0,0,0);		/* XORIL */
-	case AXOR+ALAST:	return OPVCC(27,0,0,0);		/* XORIU */
-	}
-	ctxt->diag("bad opcode i/r %A", a);
-	return 0;
-}
-
-/*
- * load o(a),d
- */
-static int32
-opload(Link *ctxt, int a)
-{
-	switch(a) {
-	case AMOVD:	return OPVCC(58,0,0,0);	/* ld */
-	case AMOVDU:	return OPVCC(58,0,0,1);	/* ldu */
-	case AMOVWZ:	return OPVCC(32,0,0,0);		/* lwz */
-	case AMOVWZU:	return OPVCC(33,0,0,0);		/* lwzu */
-	case AMOVW:		return OPVCC(58,0,0,0)|(1<<1);	/* lwa */
-	/* no AMOVWU */
-	case AMOVB:
-	case AMOVBZ:	return OPVCC(34,0,0,0);		/* load */
-	case AMOVBU:
-	case AMOVBZU:	return OPVCC(35,0,0,0);
-	case AFMOVD:	return OPVCC(50,0,0,0);
-	case AFMOVDU:	return OPVCC(51,0,0,0);
-	case AFMOVS:	return OPVCC(48,0,0,0);
-	case AFMOVSU:	return OPVCC(49,0,0,0);
-	case AMOVH:	return OPVCC(42,0,0,0);
-	case AMOVHU:	return OPVCC(43,0,0,0);
-	case AMOVHZ:	return OPVCC(40,0,0,0);
-	case AMOVHZU:	return OPVCC(41,0,0,0);
-	case AMOVMW:	return OPVCC(46,0,0,0);	/* lmw */
-	}
-	ctxt->diag("bad load opcode %A", a);
-	return 0;
-}
-
-/*
- * indexed load a(b),d
- */
-static int32
-oploadx(Link *ctxt, int a)
-{
-	switch(a) {
-	case AMOVWZ: return OPVCC(31,23,0,0);	/* lwzx */
-	case AMOVWZU:	return OPVCC(31,55,0,0); /* lwzux */
-	case AMOVW:	return OPVCC(31,341,0,0);	/* lwax */
-	case AMOVWU:	return OPVCC(31,373,0,0);	/* lwaux */
-	case AMOVB:
-	case AMOVBZ: return OPVCC(31,87,0,0);	/* lbzx */
-	case AMOVBU:
-	case AMOVBZU: return OPVCC(31,119,0,0);	/* lbzux */
-	case AFMOVD:	return OPVCC(31,599,0,0);	/* lfdx */
-	case AFMOVDU:	return OPVCC(31,631,0,0);	/*  lfdux */
-	case AFMOVS:	return OPVCC(31,535,0,0);	/* lfsx */
-	case AFMOVSU:	return OPVCC(31,567,0,0);	/* lfsux */
-	case AMOVH:	return OPVCC(31,343,0,0);	/* lhax */
-	case AMOVHU:	return OPVCC(31,375,0,0);	/* lhaux */
-	case AMOVHBR:	return OPVCC(31,790,0,0);	/* lhbrx */
-	case AMOVWBR:	return OPVCC(31,534,0,0);	/* lwbrx */
-	case AMOVHZ:	return OPVCC(31,279,0,0);	/* lhzx */
-	case AMOVHZU:	return OPVCC(31,311,0,0);	/* lhzux */
-	case AECIWX:	return OPVCC(31,310,0,0);	/* eciwx */
-	case ALWAR:	return OPVCC(31,20,0,0);	/* lwarx */
-	case ALDAR:	return OPVCC(31,84,0,0);
-	case ALSW:	return OPVCC(31,533,0,0);	/* lswx */
-	case AMOVD:	return OPVCC(31,21,0,0);	/* ldx */
-	case AMOVDU:	return OPVCC(31,53,0,0);	/* ldux */
-	}
-	ctxt->diag("bad loadx opcode %A", a);
-	return 0;
-}
-
-/*
- * store s,o(d)
- */
-static int32
-opstore(Link *ctxt, int a)
-{
-	switch(a) {
-	case AMOVB:
-	case AMOVBZ:	return OPVCC(38,0,0,0);	/* stb */
-	case AMOVBU:
-	case AMOVBZU:	return OPVCC(39,0,0,0);	/* stbu */
-	case AFMOVD:	return OPVCC(54,0,0,0);	/* stfd */
-	case AFMOVDU:	return OPVCC(55,0,0,0);	/* stfdu */
-	case AFMOVS:	return OPVCC(52,0,0,0);	/* stfs */
-	case AFMOVSU:	return OPVCC(53,0,0,0);	/* stfsu */
-	case AMOVHZ:
-	case AMOVH:	return OPVCC(44,0,0,0);	/* sth */
-	case AMOVHZU:
-	case AMOVHU:	return OPVCC(45,0,0,0);	/* sthu */
-	case AMOVMW:	return OPVCC(47,0,0,0);	/* stmw */
-	case ASTSW:	return OPVCC(31,725,0,0);	/* stswi */
-	case AMOVWZ:
-	case AMOVW:	return OPVCC(36,0,0,0);	/* stw */
-	case AMOVWZU:
-	case AMOVWU:	return OPVCC(37,0,0,0);	/* stwu */
-	case AMOVD:	return OPVCC(62,0,0,0);	/* std */
-	case AMOVDU:	return OPVCC(62,0,0,1);	/* stdu */
-	}
-	ctxt->diag("unknown store opcode %A", a);
-	return 0;
-}
-
-/*
- * indexed store s,a(b)
- */
-static int32
-opstorex(Link *ctxt, int a)
-{
-	switch(a) {
-	case AMOVB:
-	case AMOVBZ:	return OPVCC(31,215,0,0);	/* stbx */
-	case AMOVBU:
-	case AMOVBZU:	return OPVCC(31,247,0,0);	/* stbux */
-	case AFMOVD:	return OPVCC(31,727,0,0);	/* stfdx */
-	case AFMOVDU:	return OPVCC(31,759,0,0);	/* stfdux */
-	case AFMOVS:	return OPVCC(31,663,0,0);	/* stfsx */
-	case AFMOVSU:	return OPVCC(31,695,0,0);	/* stfsux */
-	case AMOVHZ:
-	case AMOVH:	return OPVCC(31,407,0,0);	/* sthx */
-	case AMOVHBR:	return OPVCC(31,918,0,0);	/* sthbrx */
-	case AMOVHZU:
-	case AMOVHU:	return OPVCC(31,439,0,0);	/* sthux */
-	case AMOVWZ:
-	case AMOVW:	return OPVCC(31,151,0,0);	/* stwx */
-	case AMOVWZU:
-	case AMOVWU:	return OPVCC(31,183,0,0);	/* stwux */
-	case ASTSW:	return OPVCC(31,661,0,0);	/* stswx */
-	case AMOVWBR:	return OPVCC(31,662,0,0);	/* stwbrx */
-	case ASTWCCC:	return OPVCC(31,150,0,1);	/* stwcx. */
-	case ASTDCCC:	return OPVCC(31,214,0,1);	/* stwdx. */
-	case AECOWX:	return OPVCC(31,438,0,0);	/* ecowx */
-	case AMOVD:	return OPVCC(31,149,0,0);	/* stdx */
-	case AMOVDU:	return OPVCC(31,181,0,0);	/* stdux */
-	}
-	ctxt->diag("unknown storex opcode %A", a);
-	return 0;
-}
-
diff --git a/src/liblink/data.c b/src/liblink/data.c
index e9dbc96..06fe7e0 100644
--- a/src/liblink/data.c
+++ b/src/liblink/data.c
@@ -34,11 +34,6 @@
 #include <bio.h>
 #include <link.h>
 
-void
-mangle(char *file)
-{
-	sysfatal("%s: mangled input file", file);
-}
 
 void
 symgrow(Link *ctxt, LSym *s, vlong lsiz)
@@ -70,80 +65,6 @@
 	s->np = siz;
 }
 
-void
-savedata(Link *ctxt, LSym *s, Prog *p, char *pn)
-{
-	int32 off, siz, i, fl;
-	float32 flt;
-	uchar *cast;
-	vlong o;
-	Reloc *r;
-
-	off = p->from.offset;
-	siz = p->from3.offset;
-	if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100)
-		mangle(pn);
-	if(ctxt->enforce_data_order && off < s->np)
-		ctxt->diag("data out of order (already have %d)\n%P", p);
-	symgrow(ctxt, s, off+siz);
-
-	if(p->to.type == TYPE_FCONST) {
-		switch(siz) {
-		default:
-		case 4:
-			flt = p->to.u.dval;
-			cast = (uchar*)&flt;
-			for(i=0; i<4; i++)
-				s->p[off+i] = cast[fnuxi4[i]];
-			break;
-		case 8:
-			cast = (uchar*)&p->to.u.dval;
-			for(i=0; i<8; i++)
-				s->p[off+i] = cast[fnuxi8[i]];
-			break;
-		}
-	} else if(p->to.type == TYPE_SCONST) {
-		for(i=0; i<siz; i++)
-			s->p[off+i] = p->to.u.sval[i];
-	} else if(p->to.type == TYPE_CONST) {
-		if(p->to.sym)
-			goto addr;
-		o = p->to.offset;
-		fl = o;
-		cast = (uchar*)&fl;
-		switch(siz) {
-		default:
-			ctxt->diag("bad nuxi %d\n%P", siz, p);
-			break;
-		case 1:
-			s->p[off] = cast[inuxi1[0]];
-			break;
-		case 2:
-			for(i=0; i<2; i++)
-				s->p[off+i] = cast[inuxi2[i]];
-			break;
-		case 4:
-			for(i=0; i<4; i++)
-				s->p[off+i] = cast[inuxi4[i]];
-			break;
-		case 8:
-			cast = (uchar*)&o;
-			for(i=0; i<8; i++)
-				s->p[off+i] = cast[inuxi8[i]];
-			break;
-		}
-	} else if(p->to.type == TYPE_ADDR) {
-	addr:
-		r = addrel(s);
-		r->off = off;
-		r->siz = siz;
-		r->sym = p->to.sym;
-		r->type = R_ADDR;
-		r->add = p->to.offset;
-	} else {
-		ctxt->diag("bad data: %P", p);
-	}
-}
 
 Reloc*
 addrel(LSym *s)
@@ -237,11 +158,6 @@
 	return setuintxx(ctxt, s, r, v, 1);
 }
 
-vlong
-setuint16(Link *ctxt, LSym *s, vlong r, uint16 v)
-{
-	return setuintxx(ctxt, s, r, v, 2);
-}
 
 vlong
 setuint32(Link *ctxt, LSym *s, vlong r, uint32 v)
@@ -249,11 +165,6 @@
 	return setuintxx(ctxt, s, r, v, 4);
 }
 
-vlong
-setuint64(Link *ctxt, LSym *s, vlong r, uint64 v)
-{
-	return setuintxx(ctxt, s, r, v, 8);
-}
 
 vlong
 addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add)
diff --git a/src/liblink/go.c b/src/liblink/go.c
index 08ce82b..6dae3f4 100644
--- a/src/liblink/go.c
+++ b/src/liblink/go.c
@@ -9,67 +9,6 @@
 #include <bio.h>
 #include <link.h>
 
-int framepointer_enabled;
-int fieldtrack_enabled;
-Prog zprog;
-
-// Toolchain experiments.
-// These are controlled by the GOEXPERIMENT environment
-// variable recorded when the toolchain is built.
-// This list is also known to cmd/gc.
-static struct {
-	char *name;
-	int *val;
-} exper[] = {
-	{"fieldtrack", &fieldtrack_enabled},
-	{"framepointer", &framepointer_enabled},
-};
-
-static void
-addexp(char *s)
-{
-	int i;
-
-	for(i=0; i < nelem(exper); i++ ) {
-		if(strcmp(exper[i].name, s) == 0) {
-			if(exper[i].val != nil)
-				*exper[i].val = 1;
-			return;
-		}
-	}
-	
-	print("unknown experiment %s\n", s);
-	exits("unknown experiment");
-}
-
-void
-linksetexp(void)
-{
-	char *f[20];
-	int i, nf;
-
-	// cmd/dist #defines GOEXPERIMENT for us.
-	nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ",");
-	for(i=0; i<nf; i++)
-		addexp(f[i]);
-}
-
-char*
-expstring(void)
-{
-	int i;
-	static char buf[512];
-
-	strcpy(buf, "X");
-	for(i=0; i<nelem(exper); i++)
-		if(*exper[i].val)
-			seprint(buf+strlen(buf), buf+sizeof buf, ",%s", exper[i].name);
-	if(strlen(buf) == 1)
-		strcpy(buf, "X,none");
-	buf[1] = ':';
-	return buf;
-}
-
 // replace all "". with pkg.
 char*
 expandpkg(char *t0, char *pkg)
@@ -128,29 +67,6 @@
 	return p;
 }
 
-void
-double2ieee(uint64 *ieee, float64 f)
-{
-	memmove(ieee, &f, 8);
-}
 
-void
-nopout(Prog *p)
-{
-	p->as = ANOP;
-	p->scond = zprog.scond;
-	p->from = zprog.from;
-	p->from3 = zprog.from3;
-	p->reg = zprog.reg;
-	p->to = zprog.to;
-}
 
-void
-nocache(Prog *p)
-{
-	p->optab = 0;
-	p->from.class = 0;
-	p->from3.class = 0;
-	p->to.class = 0;
-}
 
diff --git a/src/liblink/ld.c b/src/liblink/ld.c
index e055829..5dfb4ef 100644
--- a/src/liblink/ld.c
+++ b/src/liblink/ld.c
@@ -176,66 +176,8 @@
 uchar	inuxi4[4];
 uchar	inuxi8[8];
 
-enum
-{
-	LOG = 5,
-};
-void
-mkfwd(LSym *sym)
-{
-	Prog *p;
-	int i;
-	int32 dwn[LOG], cnt[LOG];
-	Prog *lst[LOG];
 
-	for(i=0; i<LOG; i++) {
-		if(i == 0)
-			cnt[i] = 1;
-		else
-			cnt[i] = LOG * cnt[i-1];
-		dwn[i] = 1;
-		lst[i] = nil;
-	}
-	i = 0;
-	for(p = sym->text; p != nil && p->link != nil; p = p->link) {
-		i--;
-		if(i < 0)
-			i = LOG-1;
-		p->forwd = nil;
-		dwn[i]--;
-		if(dwn[i] <= 0) {
-			dwn[i] = cnt[i];
-			if(lst[i] != nil)
-				lst[i]->forwd = p;
-			lst[i] = p;
-		}
-	}
-}
 
-Prog*
-copyp(Link *ctxt, Prog *q)
-{
-	Prog *p;
-
-	USED(ctxt);
-	p = emallocz(sizeof(Prog));
-	*p = *q;
-	return p;
-}
-
-Prog*
-appendp(Link *ctxt, Prog *q)
-{
-	Prog *p;
-
-	USED(ctxt);
-	p = emallocz(sizeof(Prog));
-	p->link = q->link;
-	q->link = p;
-	p->lineno = q->lineno;
-	p->mode = q->mode;
-	return p;
-}
 
 vlong
 atolwhex(char *s)
diff --git a/src/liblink/list5.c b/src/liblink/list5.c
deleted file mode 100644
index 3ea411d..0000000
--- a/src/liblink/list5.c
+++ /dev/null
@@ -1,386 +0,0 @@
-// Inferno utils/5c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.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 <bio.h>
-#include <link.h>
-#include "../cmd/5l/5.out.h"
-#include "../runtime/funcdata.h"
-
-enum
-{
-	STRINGSZ = 1000
-};
-
-static int	Aconv(Fmt *fp);
-static int	Dconv(Fmt *fp);
-static int	Mconv(Fmt *fp);
-static int	Pconv(Fmt *fp);
-static int	Rconv(Fmt *fp);
-static int	RAconv(Fmt *fp);
-static int	DSconv(Fmt *fp);
-static int	DRconv(Fmt*);
-
-#pragma	varargck	type	"$"	char*
-#pragma	varargck	type	"M"	Addr*
-#pragma	varargck	type	"@"	Addr*
-
-void
-listinit5(void)
-{
-	fmtinstall('A', Aconv);
-	fmtinstall('D', Dconv);
-	fmtinstall('P', Pconv);
-	fmtinstall('R', Rconv);
-
-	// for liblink internal use
-	fmtinstall('^', DRconv);
-
-	// for internal use
-	fmtinstall('$', DSconv);
-	fmtinstall('M', Mconv);
-	fmtinstall('@', RAconv);
-}
-
-static char *extra [] = {
-	".EQ", ".NE", ".CS", ".CC",
-	".MI", ".PL", ".VS", ".VC",
-	".HI", ".LS", ".GE", ".LT",
-	".GT", ".LE", "", ".NV",
-};
-
-static	Prog*	bigP;
-
-static int
-Pconv(Fmt *fp)
-{
-	char str[STRINGSZ], sc[20];
-	Prog *p;
-	int a, s;
-
-	p = va_arg(fp->args, Prog*);
-	bigP = p;
-	a = p->as;
-	s = p->scond;
-	strcpy(sc, extra[(s & C_SCOND) ^ C_SCOND_XOR]);
-	if(s & C_SBIT)
-		strcat(sc, ".S");
-	if(s & C_PBIT)
-		strcat(sc, ".P");
-	if(s & C_WBIT)
-		strcat(sc, ".W");
-	if(s & C_UBIT)		/* ambiguous with FBIT */
-		strcat(sc, ".U");
-	if(a == AMOVM) {
-		if(p->from.type == TYPE_CONST)
-			sprint(str, "%.5lld (%L)	%A%s	%@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
-		else
-		if(p->to.type == TYPE_CONST)
-			sprint(str, "%.5lld (%L)	%A%s	%D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to);
-		else
-			sprint(str, "%.5lld (%L)	%A%s	%D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
-	} else
-	if(a == ADATA)
-		sprint(str, "%.5lld (%L)	%A	%D/%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
-	else
-	if(p->as == ATEXT)
-		sprint(str, "%.5lld (%L)	%A	%D,%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
-	else
-	if(p->reg == 0)
-		sprint(str, "%.5lld (%L)	%A%s	%D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
-	else
-		sprint(str, "%.5lld (%L)	%A%s	%D,%R,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
-	bigP = nil;
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Aconv(Fmt *fp)
-{
-	char *s;
-	int a;
-
-	a = va_arg(fp->args, int);
-	s = "???";
-	if(a >= AXXX && a < ALAST)
-		s = anames5[a];
-	return fmtstrcpy(fp, s);
-}
-
-static int
-Dconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Addr *a;
-	const char *op;
-	int v;
-
-	a = va_arg(fp->args, Addr*);
-	switch(a->type) {
-
-	default:
-		sprint(str, "GOK-type(%d)", a->type);
-		break;
-
-	case TYPE_NONE:
-		str[0] = 0;
-		if(a->name != TYPE_NONE || a->reg != 0 || a->sym != nil)
-			sprint(str, "%M(%R)(NONE)", a, a->reg);
-		break;
-
-	case TYPE_CONST:
-	case TYPE_ADDR:
-		if(a->reg != 0)
-			sprint(str, "$%M(%R)", a, a->reg);
-		else
-			sprint(str, "$%M", a);
-		break;
-
-	case TYPE_TEXTSIZE:
-		if(a->u.argsize == ArgsSizeUnknown)
-			sprint(str, "$%lld", a->offset);
-		else
-			sprint(str, "$%lld-%d", a->offset, a->u.argsize);
-		break;
-
-	case TYPE_SHIFT:
-		v = a->offset;
-		op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
-		if(v & (1<<4))
-			sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
-		else
-			sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
-		if(a->reg != 0)
-			sprint(str+strlen(str), "(%R)", a->reg);
-		break;
-
-	case TYPE_MEM:
-		if(a->reg != 0)
-			sprint(str, "%M(%R)", a, a->reg);
-		else
-			sprint(str, "%M", a);
-		break;
-
-	case TYPE_REG:
-		sprint(str, "%R", a->reg);
-		if(a->name != TYPE_NONE || a->sym != nil)
-			sprint(str, "%M(%R)(REG)", a, a->reg);
-		break;
-
-	case TYPE_BRANCH:
-		if(a->sym != nil)
-			sprint(str, "%s(SB)", a->sym->name);
-		else if(bigP != nil && bigP->pcond != nil)
-			sprint(str, "%lld", bigP->pcond->pc);
-		else if(a->u.branch != nil)
-			sprint(str, "%lld", a->u.branch->pc);
-		else
-			sprint(str, "%lld(PC)", a->offset/*-pc*/);
-		break;
-
-	case TYPE_FCONST:
-		sprint(str, "$%.17g", a->u.dval);
-		break;
-
-	case TYPE_SCONST:
-		sprint(str, "$\"%$\"", a->u.sval);
-		break;
-	
-	case TYPE_REGREG:
-		sprint(str, "(%R, %R)", a->reg, (int)a->offset);
-		break;
-	
-	case TYPE_REGREG2:
-		sprint(str, "%R, %R", a->reg, (int)a->offset);
-		break;
-	}
-	return fmtstrcpy(fp, str);
-}
-
-static int
-RAconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Addr *a;
-	int i, v;
-
-	a = va_arg(fp->args, Addr*);
-	sprint(str, "GOK-reglist");
-	switch(a->type) {
-	case TYPE_CONST:
-		if(a->reg != 0)
-			break;
-		if(a->sym != nil)
-			break;
-		v = a->offset;
-		strcpy(str, "");
-		for(i=0; i<NREG; i++) {
-			if(v & (1<<i)) {
-				if(str[0] == 0)
-					strcat(str, "[R");
-				else
-					strcat(str, ",R");
-				sprint(strchr(str, 0), "%d", i);
-			}
-		}
-		strcat(str, "]");
-	}
-	return fmtstrcpy(fp, str);
-}
-
-static int
-DSconv(Fmt *fp)
-{
-	int i, c;
-	char str[STRINGSZ], *p, *a;
-
-	a = va_arg(fp->args, char*);
-	p = str;
-	for(i=0; i<NSNAME; i++) {
-		c = a[i] & 0xff;
-		if(c >= 'a' && c <= 'z' ||
-		   c >= 'A' && c <= 'Z' ||
-		   c >= '0' && c <= '9' ||
-		   c == ' ' || c == '%') {
-			*p++ = c;
-			continue;
-		}
-		*p++ = '\\';
-		switch(c) {
-		case 0:
-			*p++ = 'z';
-			continue;
-		case '\\':
-		case '"':
-			*p++ = c;
-			continue;
-		case '\n':
-			*p++ = 'n';
-			continue;
-		case '\t':
-			*p++ = 't';
-			continue;
-		case '\r':
-			*p++ = 'r';
-			continue;
-		case '\f':
-			*p++ = 'f';
-			continue;
-		}
-		*p++ = (c>>6) + '0';
-		*p++ = ((c>>3) & 7) + '0';
-		*p++ = (c & 7) + '0';
-	}
-	*p = 0;
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Rconv(Fmt *fp)
-{
-	int r;
-
-	r = va_arg(fp->args, int);
-	if(r == 0)
-		return fmtstrcpy(fp, "NONE");
-	if(REG_R0 <= r && r <= REG_R15)
-		return fmtprint(fp, "R%d", r-REG_R0);
-	if(REG_F0 <= r && r <= REG_F15)
-		return fmtprint(fp, "F%d", r-REG_F0);
-
-	switch(r) {
-	case REG_FPSR:
-		return fmtstrcpy(fp, "FPSR");
-	case REG_FPCR:
-		return fmtstrcpy(fp, "FPCR");
-	case REG_CPSR:
-		return fmtstrcpy(fp, "CPSR");
-	case REG_SPSR:
-		return fmtstrcpy(fp, "SPSR");
-	}
-
-	return fmtprint(fp, "badreg(%d)", r);
-}
-
-static int
-DRconv(Fmt *fp)
-{
-	char *s;
-	int a;
-
-	a = va_arg(fp->args, int);
-	s = "C_??";
-	if(a >= C_NONE && a <= C_NCLASS)
-		s = cnames5[a];
-	return fmtstrcpy(fp, s);
-}
-
-static int
-Mconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Addr *a;
-	LSym *s;
-
-	a = va_arg(fp->args, Addr*);
-	s = a->sym;
-	if(s == nil) {
-		sprint(str, "%d", (int)a->offset);
-		goto out;
-	}
-	switch(a->name) {
-	default:
-		sprint(str, "GOK-name(%d)", a->name);
-		break;
-
-	case NAME_NONE:
-		sprint(str, "%lld", a->offset);
-		break;
-
-	case NAME_EXTERN:
-		sprint(str, "%s+%d(SB)", s->name, (int)a->offset);
-		break;
-
-	case NAME_STATIC:
-		sprint(str, "%s<>+%d(SB)", s->name, (int)a->offset);
-		break;
-
-	case NAME_AUTO:
-		sprint(str, "%s-%d(SP)", s->name, (int)-a->offset);
-		break;
-
-	case NAME_PARAM:
-		sprint(str, "%s+%d(FP)", s->name, (int)a->offset);
-		break;
-	}
-out:
-	return fmtstrcpy(fp, str);
-}
diff --git a/src/liblink/list6.c b/src/liblink/list6.c
deleted file mode 100644
index b324ec8..0000000
--- a/src/liblink/list6.c
+++ /dev/null
@@ -1,418 +0,0 @@
-// Inferno utils/6c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/list.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 <bio.h>
-#include <link.h>
-#include "../cmd/6l/6.out.h"
-#include "../runtime/funcdata.h"
-
-//
-// Format conversions
-//	%A int		Opcodes (instruction mnemonics)
-//
-//	%D Addr*	Addresses (instruction operands)
-//
-//	%P Prog*	Instructions
-//
-//	%R int		Registers
-//
-//	%$ char*	String constant addresses (for internal use only)
-
-static int	Aconv(Fmt *fp);
-static int	Dconv(Fmt *fp);
-static int	Pconv(Fmt *fp);
-static int	Rconv(Fmt *fp);
-static int	DSconv(Fmt *fp);
-
-enum
-{
-	STRINGSZ = 1000
-};
-
-#pragma	varargck	type	"$"	char*
-
-void
-listinit6(void)
-{
-	fmtinstall('A', Aconv);
-	fmtinstall('D', Dconv);
-	fmtinstall('P', Pconv);
-	fmtinstall('R', Rconv);
-
-	// for internal use
-	fmtinstall('$', DSconv);
-}
-
-static	Prog*	bigP;
-
-static int
-Pconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Prog *p;
-
-	p = va_arg(fp->args, Prog*);
-	bigP = p;
-
-	switch(p->as) {
-	case ADATA:
-		sprint(str, "%.5lld (%L)	%A	%D/%lld,%D",
-			p->pc, p->lineno, p->as, &p->from, p->from3.offset, &p->to);
-		break;
-
-	case ATEXT:
-		if(p->from3.offset) {
-			sprint(str, "%.5lld (%L)	%A	%D,%lld,%D",
-				p->pc, p->lineno, p->as, &p->from, p->from3.offset, &p->to);
-			break;
-		}
-		sprint(str, "%.5lld (%L)	%A	%D,%D",
-			p->pc, p->lineno, p->as, &p->from, &p->to);
-		break;
-
-	default:
-		sprint(str, "%.5lld (%L)	%A	%D,%D",
-			p->pc, p->lineno, p->as, &p->from, &p->to);
-		// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
-		//	SHRQ $32(DX*0), AX
-		// Remove.
-		if((p->from.type == TYPE_REG || p->from.type == TYPE_CONST) && p->from.index != REG_NONE)
-			sprint(strchr(str, 0), ":%R", p->from.index);
-		break;
-	}
-	bigP = nil;
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Aconv(Fmt *fp)
-{
-	int i;
-
-	i = va_arg(fp->args, int);
-	return fmtstrcpy(fp, anames6[i]);
-}
-
-static int
-Dconv(Fmt *fp)
-{
-	char str[STRINGSZ], s[STRINGSZ];
-	Addr *a;
-
-	a = va_arg(fp->args, Addr*);
-
-	switch(a->type) {
-	default:
-		sprint(str, "type=%d", a->type);
-		break;
-
-	case TYPE_NONE:
-		str[0] = 0;
-		break;
-	
-	case TYPE_REG:
-		// TODO(rsc): This special case is for instructions like
-		//	PINSRQ	CX,$1,X6
-		// where the $1 is included in the p->to Addr.
-		// Move into a new field.
-		if(a->offset != 0) {
-			sprint(str, "$%lld,%R", a->offset, a->reg);
-			break;
-		}
-		sprint(str, "%R", a->reg);
-		break;
-
-	case TYPE_BRANCH:
-		if(a->sym != nil)
-			sprint(str, "%s(SB)", a->sym->name);
-		else if(bigP != nil && bigP->pcond != nil)
-			sprint(str, "%lld", bigP->pcond->pc);
-		else if(a->u.branch != nil)
-			sprint(str, "%lld", a->u.branch->pc);
-		else
-			sprint(str, "%lld(PC)", a->offset);
-		break;
-
-	case TYPE_MEM:
-		switch(a->name) {
-		default:
-			sprint(str, "name=%d", a->name);
-			break;
-		case NAME_NONE:
-			if(a->offset)
-				sprint(str, "%lld(%R)", a->offset, a->reg);
-			else
-				sprint(str, "(%R)", a->reg);
-			break;
-		case NAME_EXTERN:
-			sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
-			break;
-		case NAME_STATIC:
-			sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
-			break;
-		case NAME_AUTO:
-			if(a->sym)
-				sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
-			else
-				sprint(str, "%lld(SP)", a->offset);
-			break;
-		case NAME_PARAM:
-			if(a->sym)
-				sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
-			else
-				sprint(str, "%lld(FP)", a->offset);
-			break;
-		}
-		if(a->index != REG_NONE) {
-			sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
-			strcat(str, s);
-		}
-		break;
-
-	case TYPE_CONST:
-		sprint(str, "$%lld", a->offset);
-		break;
-	
-	case TYPE_TEXTSIZE:
-		if(a->u.argsize == ArgsSizeUnknown)
-			sprint(str, "$%lld", a->offset);
-		else
-			sprint(str, "$%lld-%d", a->offset, a->u.argsize);
-		break;
-
-	case TYPE_FCONST:
-		sprint(str, "$(%.17g)", a->u.dval);
-		break;
-
-	case TYPE_SCONST:
-		sprint(str, "$\"%$\"", a->u.sval);
-		break;
-
-	case TYPE_ADDR:
-		a->type = TYPE_MEM;
-		sprint(str, "$%D", a);
-		a->type = TYPE_ADDR;
-		break;
-	}
-	return fmtstrcpy(fp, str);
-}
-
-static char*	regstr[] =
-{
-	"AL",	/* [D_AL] */
-	"CL",
-	"DL",
-	"BL",
-	"SPB",
-	"BPB",
-	"SIB",
-	"DIB",
-	"R8B",
-	"R9B",
-	"R10B",
-	"R11B",
-	"R12B",
-	"R13B",
-	"R14B",
-	"R15B",
-
-	"AX",	/* [D_AX] */
-	"CX",
-	"DX",
-	"BX",
-	"SP",
-	"BP",
-	"SI",
-	"DI",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-
-	"AH",
-	"CH",
-	"DH",
-	"BH",
-
-	"F0",	/* [D_F0] */
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-
-	"M0",
-	"M1",
-	"M2",
-	"M3",
-	"M4",
-	"M5",
-	"M6",
-	"M7",
-
-	"X0",
-	"X1",
-	"X2",
-	"X3",
-	"X4",
-	"X5",
-	"X6",
-	"X7",
-	"X8",
-	"X9",
-	"X10",
-	"X11",
-	"X12",
-	"X13",
-	"X14",
-	"X15",
-
-	"CS",	/* [D_CS] */
-	"SS",
-	"DS",
-	"ES",
-	"FS",
-	"GS",
-
-	"GDTR",	/* [D_GDTR] */
-	"IDTR",	/* [D_IDTR] */
-	"LDTR",	/* [D_LDTR] */
-	"MSW",	/* [D_MSW] */
-	"TASK",	/* [D_TASK] */
-
-	"CR0",	/* [D_CR] */
-	"CR1",
-	"CR2",
-	"CR3",
-	"CR4",
-	"CR5",
-	"CR6",
-	"CR7",
-	"CR8",
-	"CR9",
-	"CR10",
-	"CR11",
-	"CR12",
-	"CR13",
-	"CR14",
-	"CR15",
-
-	"DR0",	/* [D_DR] */
-	"DR1",
-	"DR2",
-	"DR3",
-	"DR4",
-	"DR5",
-	"DR6",
-	"DR7",
-
-	"TR0",	/* [D_TR] */
-	"TR1",
-	"TR2",
-	"TR3",
-	"TR4",
-	"TR5",
-	"TR6",
-	"TR7",
-
-	"TLS",	/* [D_TLS] */
-	"MAXREG",	/* [MAXREG] */
-};
-
-static int
-Rconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	int r;
-
-	r = va_arg(fp->args, int);
-	if(r == REG_NONE)
-		return fmtstrcpy(fp, "NONE");
-
-	if(REG_AL <= r && r-REG_AL < nelem(regstr))
-		sprint(str, "%s", regstr[r-REG_AL]);
-	else
-		sprint(str, "gok(%d)", r);
-
-	return fmtstrcpy(fp, str);
-}
-
-static int
-DSconv(Fmt *fp)
-{
-	int i, c;
-	char str[STRINGSZ], *p, *a;
-
-	a = va_arg(fp->args, char*);
-	p = str;
-	for(i=0; i<sizeof(double); i++) {
-		c = a[i] & 0xff;
-		if(c >= 'a' && c <= 'z' ||
-		   c >= 'A' && c <= 'Z' ||
-		   c >= '0' && c <= '9') {
-			*p++ = c;
-			continue;
-		}
-		*p++ = '\\';
-		switch(c) {
-		default:
-			if(c < 040 || c >= 0177)
-				break;	/* not portable */
-			p[-1] = c;
-			continue;
-		case 0:
-			*p++ = 'z';
-			continue;
-		case '\\':
-		case '"':
-			*p++ = c;
-			continue;
-		case '\n':
-			*p++ = 'n';
-			continue;
-		case '\t':
-			*p++ = 't';
-			continue;
-		}
-		*p++ = (c>>6) + '0';
-		*p++ = ((c>>3) & 7) + '0';
-		*p++ = (c & 7) + '0';
-	}
-	*p = 0;
-	return fmtstrcpy(fp, str);
-}
diff --git a/src/liblink/list8.c b/src/liblink/list8.c
deleted file mode 100644
index 07c1d7c..0000000
--- a/src/liblink/list8.c
+++ /dev/null
@@ -1,359 +0,0 @@
-// Inferno utils/8c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8c/list.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 <bio.h>
-#include <link.h>
-#include "../cmd/8l/8.out.h"
-#include "../runtime/funcdata.h"
-
-static int	Aconv(Fmt *fp);
-static int	Dconv(Fmt *fp);
-static int	Pconv(Fmt *fp);
-static int	Rconv(Fmt *fp);
-static int	DSconv(Fmt *fp);
-
-enum
-{
-	STRINGSZ = 1000
-};
-
-#pragma	varargck	type	"$"	char*
-
-void
-listinit8(void)
-{
-	fmtinstall('A', Aconv);
-	fmtinstall('D', Dconv);
-	fmtinstall('P', Pconv);
-	fmtinstall('R', Rconv);
-
-	// for internal use
-	fmtinstall('$', DSconv);
-}
-
-static	Prog*	bigP;
-
-static int
-Pconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Prog *p;
-
-	p = va_arg(fp->args, Prog*);
-	bigP = p;
-	switch(p->as) {
-	case ADATA:
-		sprint(str, "%.5lld (%L)	%A	%D/%lld,%D",
-			p->pc, p->lineno, p->as, &p->from, p->from3.offset, &p->to);
-		break;
-
-	case ATEXT:
-		if(p->from3.offset) {
-			sprint(str, "%.5lld (%L)	%A	%D,%lld,%D",
-				p->pc, p->lineno, p->as, &p->from, p->from3.offset, &p->to);
-			break;
-		}
-		sprint(str, "%.5lld (%L)	%A	%D,%D",
-			p->pc, p->lineno, p->as, &p->from, &p->to);
-		break;
-
-	default:
-		sprint(str, "%.5lld (%L)	%A	%D,%D",
-			p->pc, p->lineno, p->as, &p->from, &p->to);
-		// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
-		//	SHRQ $32(DX*0), AX
-		// Remove.
-		if((p->from.type == TYPE_REG || p->from.type == TYPE_CONST) && p->from.index != 0)
-			sprint(strchr(str, 0), ":%R", p->from.index);
-		break;
-	}
-	bigP = nil;
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Aconv(Fmt *fp)
-{
-	int i;
-
-	i = va_arg(fp->args, int);
-	return fmtstrcpy(fp, anames8[i]);
-}
-
-static int
-Dconv(Fmt *fp)
-{
-	char str[STRINGSZ], s[STRINGSZ];
-	Addr *a;
-
-	a = va_arg(fp->args, Addr*);
-	
-	switch(a->type) {
-	default:
-		sprint(str, "type=%d", a->type);
-		break;
-
-	case TYPE_NONE:
-		str[0] = 0;
-		break;
-	
-	case TYPE_REG:
-		// TODO(rsc): This special case is for instructions like
-		//	PINSRQ	CX,$1,X6
-		// where the $1 is included in the p->to Addr.
-		// Move into a new field.
-		if(a->offset != 0) {
-			sprint(str, "$%lld,%R", a->offset, a->reg);
-			break;
-		}
-		sprint(str, "%R", a->reg);
-		break;
-
-	case TYPE_BRANCH:
-		if(a->sym != nil)
-			sprint(str, "%s(SB)", a->sym->name);
-		else if(bigP != nil && bigP->pcond != nil)
-			sprint(str, "%lld", bigP->pcond->pc);
-		else if(a->u.branch != nil)
-			sprint(str, "%lld", a->u.branch->pc);
-		else
-			sprint(str, "%lld(PC)", a->offset);
-		break;
-
-	case TYPE_MEM:
-		switch(a->name) {
-		default:
-			sprint(str, "name=%d", a->name);
-			break;
-		case NAME_NONE:
-			if(a->offset)
-				sprint(str, "%lld(%R)", a->offset, a->reg);
-			else
-				sprint(str, "(%R)", a->reg);
-			break;
-		case NAME_EXTERN:
-			sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
-			break;
-		case NAME_STATIC:
-			sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
-			break;
-		case NAME_AUTO:
-			if(a->sym)
-				sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
-			else
-				sprint(str, "%lld(SP)", a->offset);
-			break;
-		case NAME_PARAM:
-			if(a->sym)
-				sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
-			else
-				sprint(str, "%lld(FP)", a->offset);
-			break;
-		}
-		if(a->index != REG_NONE) {
-			sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
-			strcat(str, s);
-		}
-		break;
-
-	case TYPE_CONST:
-		sprint(str, "$%lld", a->offset);
-		break;
-
-	case TYPE_TEXTSIZE:
-		if(a->u.argsize == ArgsSizeUnknown)
-			sprint(str, "$%lld", a->offset);
-		else
-			sprint(str, "$%lld-%d", a->offset, a->u.argsize);
-		break;
-
-	case TYPE_FCONST:
-		sprint(str, "$(%.17g)", a->u.dval);
-		break;
-
-	case TYPE_SCONST:
-		sprint(str, "$\"%$\"", a->u.sval);
-		break;
-
-	case TYPE_ADDR:
-		a->type = TYPE_MEM;
-		sprint(str, "$%D", a);
-		a->type = TYPE_ADDR;
-		break;
-	}
-
-	return fmtstrcpy(fp, str);
-}
-
-static char*	regstr[] =
-{
-	"AL",	/* [REG_AL] */
-	"CL",
-	"DL",
-	"BL",
-	"AH",
-	"CH",
-	"DH",
-	"BH",
-
-	"AX",	/* [REG_AX] */
-	"CX",
-	"DX",
-	"BX",
-	"SP",
-	"BP",
-	"SI",
-	"DI",
-
-	"F0",	/* [REG_F0] */
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-
-	"CS",	/* [REG_CS] */
-	"SS",
-	"DS",
-	"ES",
-	"FS",
-	"GS",
-
-	"GDTR",	/* [REG_GDTR] */
-	"IDTR",	/* [REG_IDTR] */
-	"LDTR",	/* [REG_LDTR] */
-	"MSW",	/* [REG_MSW] */
-	"TASK",	/* [REG_TASK] */
-
-	"CR0",	/* [REG_CR] */
-	"CR1",
-	"CR2",
-	"CR3",
-	"CR4",
-	"CR5",
-	"CR6",
-	"CR7",
-
-	"DR0",	/* [REG_DR] */
-	"DR1",
-	"DR2",
-	"DR3",
-	"DR4",
-	"DR5",
-	"DR6",
-	"DR7",
-
-	"TR0",	/* [REG_TR] */
-	"TR1",
-	"TR2",
-	"TR3",
-	"TR4",
-	"TR5",
-	"TR6",
-	"TR7",
-
-	"X0",	/* [REG_X0] */
-	"X1",
-	"X2",
-	"X3",
-	"X4",
-	"X5",
-	"X6",
-	"X7",
-
-	"TLS",	/* [REG_TLS] */
-	"MAXREG",	/* [MAXREG] */
-};
-
-static int
-Rconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	int r;
-
-	r = va_arg(fp->args, int);
-	if(r == REG_NONE)
-		return fmtstrcpy(fp, "NONE");
-	if(r >= REG_AL && r-REG_AL < nelem(regstr))
-		sprint(str, "%s", regstr[r-REG_AL]);
-	else
-		sprint(str, "gok(%d)", r);
-
-	return fmtstrcpy(fp, str);
-}
-
-static int
-DSconv(Fmt *fp)
-{
-	int i, c;
-	char str[STRINGSZ], *p, *a;
-
-	a = va_arg(fp->args, char*);
-	p = str;
-	for(i=0; i<sizeof(double); i++) {
-		c = a[i] & 0xff;
-		if(c >= 'a' && c <= 'z' ||
-		   c >= 'A' && c <= 'Z' ||
-		   c >= '0' && c <= '9') {
-			*p++ = c;
-			continue;
-		}
-		*p++ = '\\';
-		switch(c) {
-		default:
-			if(c < 040 || c >= 0177)
-				break;	/* not portable */
-			p[-1] = c;
-			continue;
-		case 0:
-			*p++ = 'z';
-			continue;
-		case '\\':
-		case '"':
-			*p++ = c;
-			continue;
-		case '\n':
-			*p++ = 'n';
-			continue;
-		case '\t':
-			*p++ = 't';
-			continue;
-		}
-		*p++ = (c>>6) + '0';
-		*p++ = ((c>>3) & 7) + '0';
-		*p++ = (c & 7) + '0';
-	}
-	*p = 0;
-	return fmtstrcpy(fp, str);
-}
diff --git a/src/liblink/list9.c b/src/liblink/list9.c
deleted file mode 100644
index ac37bb5..0000000
--- a/src/liblink/list9.c
+++ /dev/null
@@ -1,370 +0,0 @@
-// cmd/9l/list.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.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/9l/9.out.h"
-#include "../runtime/funcdata.h"
-
-enum
-{
-	STRINGSZ	= 1000,
-};
-
-static int	Aconv(Fmt*);
-static int	Dconv(Fmt*);
-static int	Pconv(Fmt*);
-static int	Rconv(Fmt*);
-static int	DSconv(Fmt*);
-static int	Mconv(Fmt*);
-static int	DRconv(Fmt*);
-
-//
-// Format conversions
-//	%A int		Opcodes (instruction mnemonics)
-//
-//	%D Addr*	Addresses (instruction operands)
-//
-//	%P Prog*	Instructions
-//
-//	%R int		Registers
-//
-//	%$ char*	String constant addresses (for internal use only)
-//	%^ int   	C_* classes (for liblink internal use)
-
-#pragma	varargck	type	"$"	char*
-#pragma	varargck	type	"M"	Addr*
-
-void
-listinit9(void)
-{
-	fmtinstall('A', Aconv);
-	fmtinstall('D', Dconv);
-	fmtinstall('P', Pconv);
-	fmtinstall('R', Rconv);
-
-	// for liblink internal use
-	fmtinstall('^', DRconv);
-
-	// for internal use
-	fmtinstall('$', DSconv);
-	fmtinstall('M', Mconv);
-}
-
-static Prog*	bigP;
-
-static int
-Pconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Prog *p;
-	int a;
-
-	p = va_arg(fp->args, Prog*);
-	bigP = p;
-	a = p->as;
-
-	str[0] = 0;
-	if(a == ADATA)
-		sprint(str, "%.5lld (%L)	%A	%D/%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
-	else if(a == ATEXT || a == AGLOBL) {
-		if(p->from3.offset != 0)
-			sprint(str, "%.5lld (%L)	%A	%D,%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
-		else
-			sprint(str, "%.5lld (%L)	%A	%D,%D", p->pc, p->lineno, a, &p->from, &p->to);
-	} else {
-		if(p->mark & NOSCHED)
-			sprint(strchr(str, 0), "*");
-		if(p->reg == 0 && p->from3.type == TYPE_NONE)
-			sprint(strchr(str, 0), "%.5lld (%L)	%A	%D,%D", p->pc, p->lineno, a, &p->from, &p->to);
-		else
-		if(a != ATEXT && p->from.type == TYPE_MEM) {
-			sprint(strchr(str, 0), "%.5lld (%L)	%A	%lld(%R+%R),%D", p->pc, p->lineno, a,
-				p->from.offset, p->from.reg, p->reg, &p->to);
-		} else
-		if(p->to.type == TYPE_MEM) {
-			sprint(strchr(str, 0), "%.5lld (%L)	%A	%D,%lld(%R+%R)", p->pc, p->lineno, a,
-					&p->from, p->to.offset, p->to.reg, p->reg);
-		} else {
-			sprint(strchr(str, 0), "%.5lld (%L)	%A	%D", p->pc, p->lineno, a, &p->from);
-			if(p->reg != 0)
-				sprint(strchr(str, 0), ",%R", p->reg);
-			if(p->from3.type != TYPE_NONE)
-				sprint(strchr(str, 0), ",%D", &p->from3);
-			sprint(strchr(str, 0), ",%D", &p->to);
-		}
-		if(p->spadj != 0)
-			return fmtprint(fp, "%s # spadj=%d", str, p->spadj);
-	}
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Aconv(Fmt *fp)
-{
-	char *s;
-	int a;
-
-	a = va_arg(fp->args, int);
-	s = "???";
-	if(a >= AXXX && a < ALAST)
-		s = anames9[a];
-	return fmtstrcpy(fp, s);
-}
-
-static int
-Dconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Addr *a;
-	int32 v;
-
-	a = va_arg(fp->args, Addr*);
-
-	switch(a->type) {
-	default:
-		sprint(str, "GOK-type(%d)", a->type);
-		break;
-
-	case TYPE_NONE:
-		str[0] = 0;
-		if(a->name != TYPE_NONE || a->reg != 0 || a->sym != nil)
-			sprint(str, "%M(%R)(NONE)", a, a->reg);
-		break;
-
-	case TYPE_CONST:
-	case TYPE_ADDR:
-		if(a->reg != 0)
-			sprint(str, "$%M(%R)", a, a->reg);
-		else
-			sprint(str, "$%M", a);
-		break;
-
-	case TYPE_TEXTSIZE:
-		if(a->u.argsize == ArgsSizeUnknown)
-			sprint(str, "$%lld", a->offset);
-		else
-			sprint(str, "$%lld-%d", a->offset, a->u.argsize);
-		break;
-
-	case TYPE_MEM:
-		if(a->reg != 0)
-			sprint(str, "%M(%R)", a, a->reg);
-		else
-			sprint(str, "%M", a);
-		break;
-
-	case TYPE_REG:
-		sprint(str, "%R", a->reg);
-		if(a->name != TYPE_NONE || a->sym != nil)
-			sprint(str, "%M(%R)(REG)", a, a->reg);
-		break;
-
-	case TYPE_BRANCH:
-		if(bigP->pcond != nil) {
-			v = bigP->pcond->pc;
-			//if(v >= INITTEXT)
-			//	v -= INITTEXT-HEADR;
-			if(a->sym != nil)
-				sprint(str, "%s+%.5ux(BRANCH)", a->sym->name, v);
-			else
-				sprint(str, "%.5ux(BRANCH)", v);
-		} else if(a->u.branch != nil)
-			sprint(str, "%lld", a->u.branch->pc);
-		else if(a->sym != nil)
-			sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
-		else
-			sprint(str, "%lld(APC)", a->offset);
-		break;
-
-	case TYPE_FCONST:
-		//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
-		sprint(str, "$%.17g", a->u.dval);
-		break;
-
-	case TYPE_SCONST:
-		sprint(str, "$\"%$\"", a->u.sval);
-		break;
-	}
-
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Mconv(Fmt *fp)
-{
-	char str[STRINGSZ];
-	Addr *a;
-	LSym *s;
-	int32 l;
-
-	a = va_arg(fp->args, Addr*);
-	s = a->sym;
-	//if(s == nil) {
-	//	l = a->offset;
-	//	if((vlong)l != a->offset)
-	//		sprint(str, "0x%llux", a->offset);
-	//	else
-	//		sprint(str, "%lld", a->offset);
-	//	goto out;
-	//}
-	switch(a->name) {
-	default:
-		sprint(str, "GOK-name(%d)", a->name);
-		break;
-
-	case TYPE_NONE:
-		l = a->offset;
-		if((vlong)l != a->offset)
-			sprint(str, "0x%llux", a->offset);
-		else
-			sprint(str, "%lld", a->offset);
-		break;
-
-	case NAME_EXTERN:
-		if(a->offset != 0)
-			sprint(str, "%s+%lld(SB)", s->name, a->offset);
-		else
-			sprint(str, "%s(SB)", s->name);
-		break;
-
-	case NAME_STATIC:
-		sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
-		break;
-
-	case NAME_AUTO:
-		if(s == nil)
-			sprint(str, "%lld(SP)", -a->offset);
-		else
-			sprint(str, "%s-%lld(SP)", s->name, -a->offset);
-		break;
-
-	case NAME_PARAM:
-		if(s == nil)
-			sprint(str, "%lld(FP)", a->offset);
-		else
-			sprint(str, "%s+%lld(FP)", s->name, a->offset);
-		break;
-	}
-//out:
-	return fmtstrcpy(fp, str);
-}
-
-static int
-Rconv(Fmt *fp)
-{
-	int r;
-
-	r = va_arg(fp->args, int);
-	if(r == 0)
-		return fmtstrcpy(fp, "NONE");
-	if(REG_R0 <= r && r <= REG_R31)
-		return fmtprint(fp, "R%d", r-REG_R0);
-	if(REG_F0 <= r && r <= REG_F31)
-		return fmtprint(fp, "F%d", r-REG_F0);
-	if(REG_C0 <= r && r <= REG_C7)
-		return fmtprint(fp, "C%d", r-REG_C0);
-	if(r == REG_CR)
-		return fmtstrcpy(fp, "CR");
-	if(REG_SPR0 <= r && r <= REG_SPR0+1023) {
-		switch(r) {
-		case REG_XER:
-			return fmtstrcpy(fp, "XER");
-		case REG_LR:
-			return fmtstrcpy(fp, "LR");
-		case REG_CTR:
-			return fmtstrcpy(fp, "CTR");
-		}
-		return fmtprint(fp, "SPR(%d)", r-REG_SPR0);
-	}
-	if(REG_DCR0 <= r && r <= REG_DCR0+1023)
-		return fmtprint(fp, "DCR(%d)", r-REG_DCR0);
-	if(r == REG_FPSCR)
-		return fmtstrcpy(fp, "FPSCR");
-	if(r == REG_MSR)
-		return fmtstrcpy(fp, "MSR");
-
-	return fmtprint(fp, "badreg(%d)", r);
-}
-
-static int
-DRconv(Fmt *fp)
-{
-	char *s;
-	int a;
-
-	a = va_arg(fp->args, int);
-	s = "C_??";
-	if(a >= C_NONE && a <= C_NCLASS)
-		s = cnames9[a];
-	return fmtstrcpy(fp, s);
-}
-
-static int
-DSconv(Fmt *fp)
-{
-	int i, c;
-	char str[STRINGSZ], *p, *a;
-
-	a = va_arg(fp->args, char*);
-	p = str;
-	for(i=0; i<sizeof(int32); i++) {
-		c = a[i] & 0xff;
-		if(c >= 'a' && c <= 'z' ||
-		   c >= 'A' && c <= 'Z' ||
-		   c >= '0' && c <= '9' ||
-		   c == ' ' || c == '%') {
-			*p++ = c;
-			continue;
-		}
-		*p++ = '\\';
-		switch(c) {
-		case 0:
-			*p++ = 'z';
-			continue;
-		case '\\':
-		case '"':
-			*p++ = c;
-			continue;
-		case '\n':
-			*p++ = 'n';
-			continue;
-		case '\t':
-			*p++ = 't';
-			continue;
-		}
-		*p++ = (c>>6) + '0';
-		*p++ = ((c>>3) & 7) + '0';
-		*p++ = (c & 7) + '0';
-	}
-	*p = 0;
-	return fmtstrcpy(fp, str);
-}
diff --git a/src/liblink/obj.c b/src/liblink/obj.c
deleted file mode 100644
index b8083b0..0000000
--- a/src/liblink/obj.c
+++ /dev/null
@@ -1,296 +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 <bio.h>
-#include <link.h>
-
-enum
-{
-	HISTSZ = 10,
-	NSYM = 50,
-};
-
-int
-linklinefmt(Link *ctxt, Fmt *fp)
-{
-	struct
-	{
-		Hist*	incl;	/* start of this include file */
-		int32	idel;	/* delta line number to apply to include */
-		Hist*	line;	/* start of this #line directive */
-		int32	ldel;	/* delta line number to apply to #line */
-	} a[HISTSZ];
-	int32 lno, d;
-	int i, n;
-	Hist *h;
-
-	lno = va_arg(fp->args, int32);
-
-	n = 0;
-	for(h=ctxt->hist; h!=nil; h=h->link) {
-		if(h->offset < 0)
-			continue;
-		if(lno < h->line)
-			break;
-		if(h->name) {
-			if(h->offset > 0) {
-				// #line directive
-				if(n > 0 && n < HISTSZ) {
-					a[n-1].line = h;
-					a[n-1].ldel = h->line - h->offset + 1;
-				}
-			} else {
-				// beginning of file
-				if(n < HISTSZ) {
-					a[n].incl = h;
-					a[n].idel = h->line;
-					a[n].line = 0;
-				}
-				n++;
-			}
-			continue;
-		}
-		n--;
-		if(n > 0 && n < HISTSZ) {
-			d = h->line - a[n].incl->line;
-			a[n-1].ldel += d;
-			a[n-1].idel += d;
-		}
-	}
-
-	if(n > HISTSZ)
-		n = HISTSZ;
-
-	for(i=n-1; i>=0; i--) {
-		if(i != n-1) {
-			if(fp->flags & ~(FmtWidth|FmtPrec))
-				break;
-			fmtprint(fp, " ");
-		}
-		if(ctxt->debugline || (fp->flags&FmtLong))
-			fmtprint(fp, "%s/", ctxt->pathname);
-		if(a[i].line)
-			fmtprint(fp, "%s:%d[%s:%d]",
-				a[i].line->name, lno-a[i].ldel+1,
-				a[i].incl->name, lno-a[i].idel+1);
-		else
-			fmtprint(fp, "%s:%d",
-				a[i].incl->name, lno-a[i].idel+1);
-		lno = a[i].incl->line - 1;	// now print out start of this file
-	}
-	if(n == 0)
-		fmtprint(fp, "<unknown line number>");
-
-	return 0;
-}
-
-// Does s have t as a path prefix?
-// That is, does s == t or does s begin with t followed by a slash?
-// For portability, we allow ASCII case folding, so that haspathprefix("a/b/c", "A/B") is true.
-// Similarly, we allow slash folding, so that haspathprefix("a/b/c", "a\\b") is true.
-static int
-haspathprefix(char *s, char *t)
-{
-	int i, cs, ct;
-
-	if(t == nil)
-		return 0;
-	for(i=0; t[i]; i++) {
-		cs = s[i];
-		ct = t[i];
-		if('A' <= cs && cs <= 'Z')
-			cs += 'a' - 'A';
-		if('A' <= ct && ct <= 'Z')
-			ct += 'a' - 'A';
-		if(cs == '\\')
-			cs = '/';
-		if(ct == '\\')
-			ct = '/';
-		if(cs != ct)
-			return 0;
-	}
-	return s[i] == '\0' || s[i] == '/' || s[i] == '\\';
-}
-
-// This is a simplified copy of linklinefmt above.
-// It doesn't allow printing the full stack, and it returns the file name and line number separately.
-// TODO: Unify with linklinefmt somehow.
-void
-linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l)
-{
-	struct
-	{
-		Hist*	incl;	/* start of this include file */
-		int32	idel;	/* delta line number to apply to include */
-		Hist*	line;	/* start of this #line directive */
-		int32	ldel;	/* delta line number to apply to #line */
-	} a[HISTSZ];
-	int32 lno, d, dlno;
-	int n;
-	Hist *h;
-	char buf[1024], buf1[1024], *file;
-
-	lno = line;
-	n = 0;
-	for(h=ctxt->hist; h!=nil; h=h->link) {
-		if(h->offset < 0)
-			continue;
-		if(lno < h->line)
-			break;
-		if(h->name) {
-			if(h->offset > 0) {
-				// #line directive
-				if(n > 0 && n < HISTSZ) {
-					a[n-1].line = h;
-					a[n-1].ldel = h->line - h->offset + 1;
-				}
-			} else {
-				// beginning of file
-				if(n < HISTSZ) {
-					a[n].incl = h;
-					a[n].idel = h->line;
-					a[n].line = 0;
-				}
-				n++;
-			}
-			continue;
-		}
-		n--;
-		if(n > 0 && n < HISTSZ) {
-			d = h->line - a[n].incl->line;
-			a[n-1].ldel += d;
-			a[n-1].idel += d;
-		}
-	}
-
-	if(n > HISTSZ)
-		n = HISTSZ;
-
-	if(n <= 0) {
-		*f = linklookup(ctxt, "??", HistVersion);
-		*l = 0;
-		return;
-	}
-	
-	n--;
-	if(a[n].line) {
-		file = a[n].line->name;
-		dlno = a[n].ldel-1;
-	} else {
-		file = a[n].incl->name;
-		dlno = a[n].idel-1;
-	}
-	if((!ctxt->windows && file[0] == '/') || (ctxt->windows && file[1] == ':') || file[0] == '<')
-		snprint(buf, sizeof buf, "%s", file);
-	else
-		snprint(buf, sizeof buf, "%s/%s", ctxt->pathname, file);
-
-	// Remove leading ctxt->trimpath, or else rewrite $GOROOT to $GOROOT_FINAL.
-	if(haspathprefix(buf, ctxt->trimpath)) {
-		if(strlen(buf) == strlen(ctxt->trimpath))
-			strcpy(buf, "??");
-		else {
-			snprint(buf1, sizeof buf1, "%s", buf+strlen(ctxt->trimpath)+1);
-			if(buf1[0] == '\0')
-				strcpy(buf1, "??");
-			strcpy(buf, buf1);
-		}
-	} else if(ctxt->goroot_final != nil && haspathprefix(buf, ctxt->goroot)) {
-		snprint(buf1, sizeof buf1, "%s%s", ctxt->goroot_final, buf+strlen(ctxt->goroot));
-		strcpy(buf, buf1);
-	}
-
-	lno -= dlno;
-	*f = linklookup(ctxt, buf, HistVersion);
-	*l = lno;
-}
-
-void
-linklinehist(Link *ctxt, int lineno, char *f, int offset)
-{
-	Hist *h;
-
-	if(0) // debug['f']
-		if(f) {
-			if(offset)
-				print("%4d: %s (#line %d)\n", lineno, f, offset);
-			else
-				print("%4d: %s\n", lineno, f);
-		} else
-			print("%4d: <pop>\n", lineno);
-
-	h = malloc(sizeof(Hist));
-	memset(h, 0, sizeof *h);
-	h->name = f;
-	h->line = lineno;
-	h->offset = offset;
-	h->link = nil;
-	if(ctxt->ehist == nil) {
-		ctxt->hist = h;
-		ctxt->ehist = h;
-		return;
-	}
-	ctxt->ehist->link = h;
-	ctxt->ehist = h;
-}
-
-void
-linkprfile(Link *ctxt, int32 l)
-{
-	int i, n;
-	Hist a[HISTSZ], *h;
-	int32 d;
-
-	n = 0;
-	for(h = ctxt->hist; h != nil; h = h->link) {
-		if(l < h->line)
-			break;
-		if(h->name) {
-			if(h->offset == 0) {
-				if(n >= 0 && n < HISTSZ)
-					a[n] = *h;
-				n++;
-				continue;
-			}
-			if(n > 0 && n < HISTSZ)
-				if(a[n-1].offset == 0) {
-					a[n] = *h;
-					n++;
-				} else
-					a[n-1] = *h;
-			continue;
-		}
-		n--;
-		if(n >= 0 && n < HISTSZ) {
-			d = h->line - a[n].line;
-			for(i=0; i<n; i++)
-				a[i].line += d;
-		}
-	}
-	if(n > HISTSZ)
-		n = HISTSZ;
-	for(i=0; i<n; i++)
-		print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-linknewplist(Link *ctxt)
-{
-	Plist *pl;
-
-	pl = malloc(sizeof(*pl));
-	memset(pl, 0, sizeof *pl);
-	if(ctxt->plist == nil)
-		ctxt->plist = pl;
-	else
-		ctxt->plast->link = pl;
-	ctxt->plast = pl;
-
-	return pl;
-}
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
deleted file mode 100644
index abddbc3..0000000
--- a/src/liblink/obj5.c
+++ /dev/null
@@ -1,998 +0,0 @@
-// Derived from Inferno utils/5c/swt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/swt.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 <bio.h>
-#include <link.h>
-#include "../cmd/5l/5.out.h"
-#include "../runtime/stack.h"
-
-static void
-progedit(Link *ctxt, Prog *p)
-{
-	char literal[64];
-	LSym *s;
-	static LSym *tlsfallback;
-
-	p->from.class = 0;
-	p->to.class = 0;
-
-	// Rewrite B/BL to symbol as TYPE_BRANCH.
-	switch(p->as) {
-	case AB:
-	case ABL:
-	case ADUFFZERO:
-	case ADUFFCOPY:
-		if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
-			p->to.type = TYPE_BRANCH;
-		break;
-	}
-
-	// Replace TLS register fetches on older ARM procesors.
-	switch(p->as) {
-	case AMRC:
-		// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
-		if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
-			// Because the instruction might be rewriten to a BL which returns in R0
-			// the register must be zero.
-		       	if ((p->to.offset & 0xf000) != 0)
-				ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno);
-
-			if(ctxt->goarm < 7) {
-				// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
-				if(tlsfallback == nil)
-					tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
-				// MOVW	LR, R11
-				p->as = AMOVW;
-				p->from.type = TYPE_REG;
-				p->from.reg = REGLINK;
-				p->to.type = TYPE_REG;
-				p->to.reg = REGTMP;
-
-				// BL	runtime.read_tls_fallback(SB)
-				p = appendp(ctxt, p);
-				p->as = ABL;
-				p->to.type = TYPE_BRANCH;
-				p->to.sym = tlsfallback;
-				p->to.offset = 0;
-
-				// MOVW	R11, LR
-				p = appendp(ctxt, p);
-				p->as = AMOVW;
-				p->from.type = TYPE_REG;
-				p->from.reg = REGTMP;
-				p->to.type = TYPE_REG;
-				p->to.reg = REGLINK;
-				break;
-			}
-		}
-		// Otherwise, MRC/MCR instructions need no further treatment.
-		p->as = AWORD;
-		break;
-	}
-
-	// Rewrite float constants to values stored in memory.
-	switch(p->as) {
-	case AMOVF:
-		if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
-		   (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
-			uint32 i32;
-			float32 f32;
-			f32 = p->from.u.dval;
-			memmove(&i32, &f32, 4);
-			sprint(literal, "$f32.%08ux", i32);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint32(ctxt, s, i32);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.sym = s;
-			p->from.name = NAME_EXTERN;
-			p->from.offset = 0;
-		}
-		break;
-
-	case AMOVD:
-		if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
-		   (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
-			uint64 i64;
-			memmove(&i64, &p->from.u.dval, 8);
-			sprint(literal, "$f64.%016llux", i64);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint64(ctxt, s, i64);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.sym = s;
-			p->from.name = NAME_EXTERN;
-			p->from.offset = 0;
-		}
-		break;
-	}
-
-	if(ctxt->flag_shared) {
-		// Shared libraries use R_ARM_TLS_IE32 instead of 
-		// R_ARM_TLS_LE32, replacing the link time constant TLS offset in
-		// runtime.tlsg with an address to a GOT entry containing the 
-		// offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to
-		// compensate.
-		if(ctxt->tlsg == nil)
-			ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
-
-		if(p->from.type == TYPE_ADDR && p->from.name == NAME_EXTERN && p->from.sym == ctxt->tlsg)
-			p->from.type = TYPE_MEM;
-		if(p->to.type == TYPE_ADDR && p->to.name == NAME_EXTERN && p->to.sym == ctxt->tlsg)
-			p->to.type = TYPE_MEM;
-	}
-}
-
-static	Prog*	stacksplit(Link*, Prog*, int32, int);
-static	void		initdiv(Link*);
-static	void	softfloat(Link*, LSym*);
-
-// Prog.mark
-enum
-{
-	FOLL = 1<<0,
-	LABEL = 1<<1,
-	LEAF = 1<<2,
-};
-
-static void
-linkcase(Prog *casep)
-{
-	Prog *p;
-
-	for(p = casep; p != nil; p = p->link){
-		if(p->as == ABCASE) {
-			for(; p != nil && p->as == ABCASE; p = p->link)
-				p->pcrel = casep;
-			break;
-		}
-	}
-}
-
-static void
-preprocess(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *pl, *p1, *p2, *q, *q1, *q2;
-	int o;
-	int32 autosize, autoffset;
-	
-	autosize = 0;
-
-	if(ctxt->symmorestack[0] == nil) {
-		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
-		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
-	}
-
-	q = nil;
-	
-	ctxt->cursym = cursym;
-
-	if(cursym->text == nil || cursym->text->link == nil)
-		return;				
-
-	softfloat(ctxt, cursym);
-
-	p = cursym->text;
-	autoffset = p->to.offset;
-	if(autoffset < 0)
-		autoffset = 0;
-	cursym->locals = autoffset;
-	cursym->args = p->to.u.argsize;
-
-	if(ctxt->debugzerostack) {
-		if(autoffset && !(p->from3.offset&NOSPLIT)) {
-			// MOVW $4(R13), R1
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->from.type = TYPE_ADDR;
-			p->from.reg = REG_R13;
-			p->from.offset = 4;
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_R1;
-	
-			// MOVW $n(R13), R2
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->from.type = TYPE_ADDR;
-			p->from.reg = REG_R13;
-			p->from.offset = 4 + autoffset;
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_R2;
-	
-			// MOVW $0, R3
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->from.type = TYPE_CONST;
-			p->from.offset = 0;
-			p->to.type = TYPE_REG;
-			p->to.reg = REG_R3;
-	
-			// L:
-			//	MOVW.nil R3, 0(R1) +4
-			//	CMP R1, R2
-			//	BNE L
-			p = pl = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->from.type = TYPE_REG;
-			p->from.reg = REG_R3;
-			p->to.type = TYPE_MEM;
-			p->to.reg = REG_R1;
-			p->to.offset = 4;
-			p->scond |= C_PBIT;
-	
-			p = appendp(ctxt, p);
-			p->as = ACMP;
-			p->from.type = TYPE_REG;
-			p->from.reg = REG_R1;
-			p->reg = REG_R2;
-	
-			p = appendp(ctxt, p);
-			p->as = ABNE;
-			p->to.type = TYPE_BRANCH;
-			p->pcond = pl;
-		}
-	}
-
-	/*
-	 * find leaf subroutines
-	 * strip NOPs
-	 * expand RET
-	 * expand BECOME pseudo
-	 */
-
-	for(p = cursym->text; p != nil; p = p->link) {
-		switch(p->as) {
-		case ACASE:
-			if(ctxt->flag_shared)
-				linkcase(p);
-			break;
-
-		case ATEXT:
-			p->mark |= LEAF;
-			break;
-
-		case ARET:
-			break;
-
-		case ADIV:
-		case ADIVU:
-		case AMOD:
-		case AMODU:
-			q = p;
-			if(ctxt->sym_div == nil)
-				initdiv(ctxt);
-			cursym->text->mark &= ~LEAF;
-			continue;
-
-		case ANOP:
-			q1 = p->link;
-			q->link = q1;		/* q is non-nop */
-			if(q1 != nil)
-				q1->mark |= p->mark;
-			continue;
-
-		case ABL:
-		case ABX:
-		case ADUFFZERO:
-		case ADUFFCOPY:
-			cursym->text->mark &= ~LEAF;
-
-		case ABCASE:
-		case AB:
-
-		case ABEQ:
-		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:
-			q1 = p->pcond;
-			if(q1 != nil) {
-				while(q1->as == ANOP) {
-					q1 = q1->link;
-					p->pcond = q1;
-				}
-			}
-			break;
-		}
-		q = p;
-	}
-
-	for(p = cursym->text; p != nil; p = p->link) {
-		o = p->as;
-		switch(o) {
-		case ATEXT:
-			autosize = p->to.offset + 4;
-			if(autosize <= 4)
-			if(cursym->text->mark & LEAF) {
-				p->to.offset = -4;
-				autosize = 0;
-			}
-
-			if(!autosize && !(cursym->text->mark & LEAF)) {
-				if(ctxt->debugvlog) {
-					Bprint(ctxt->bso, "save suppressed in: %s\n",
-						cursym->name);
-					Bflush(ctxt->bso);
-				}
-				cursym->text->mark |= LEAF;
-			}
-			if(cursym->text->mark & LEAF) {
-				cursym->leaf = 1;
-				if(!autosize)
-					break;
-			}
-
-			if(!(p->from3.offset & NOSPLIT))
-				p = stacksplit(ctxt, p, autosize, !(cursym->text->from3.offset&NEEDCTXT)); // emit split check
-			
-			// MOVW.W		R14,$-autosize(SP)
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->scond |= C_WBIT;
-			p->from.type = TYPE_REG;
-			p->from.reg = REGLINK;
-			p->to.type = TYPE_MEM;
-			p->to.offset = -autosize;
-			p->to.reg = REGSP;
-			p->spadj = autosize;
-			
-			if(cursym->text->from3.offset & WRAPPER) {
-				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
-				//
-				//	MOVW g_panic(g), R1
-				//	CMP $0, R1
-				//	B.EQ end
-				//	MOVW panic_argp(R1), R2
-				//	ADD $(autosize+4), R13, R3
-				//	CMP R2, R3
-				//	B.NE end
-				//	ADD $4, R13, R4
-				//	MOVW R4, panic_argp(R1)
-				// end:
-				//	NOP
-				//
-				// The NOP is needed to give the jumps somewhere to land.
-				// It is a liblink NOP, not an ARM NOP: it encodes to 0 instruction bytes.
-
-				p = appendp(ctxt, p);
-				p->as = AMOVW;
-				p->from.type = TYPE_MEM;
-				p->from.reg = REGG;
-				p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_R1;
-			
-				p = appendp(ctxt, p);
-				p->as = ACMP;
-				p->from.type = TYPE_CONST;
-				p->from.offset = 0;
-				p->reg = REG_R1;
-			
-				p = appendp(ctxt, p);
-				p->as = ABEQ;
-				p->to.type = TYPE_BRANCH;
-				p1 = p;
-				
-				p = appendp(ctxt, p);
-				p->as = AMOVW;
-				p->from.type = TYPE_MEM;
-				p->from.reg = REG_R1;
-				p->from.offset = 0; // Panic.argp
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_R2;
-			
-				p = appendp(ctxt, p);
-				p->as = AADD;
-				p->from.type = TYPE_CONST;
-				p->from.offset = autosize+4;
-				p->reg = REG_R13;
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_R3;
-
-				p = appendp(ctxt, p);
-				p->as = ACMP;
-				p->from.type = TYPE_REG;
-				p->from.reg = REG_R2;
-				p->reg = REG_R3;
-
-				p = appendp(ctxt, p);
-				p->as = ABNE;
-				p->to.type = TYPE_BRANCH;
-				p2 = p;
-			
-				p = appendp(ctxt, p);
-				p->as = AADD;
-				p->from.type = TYPE_CONST;
-				p->from.offset = 4;
-				p->reg = REG_R13;
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_R4;
-
-				p = appendp(ctxt, p);
-				p->as = AMOVW;
-				p->from.type = TYPE_REG;
-				p->from.reg = REG_R4;
-				p->to.type = TYPE_MEM;
-				p->to.reg = REG_R1;
-				p->to.offset = 0; // Panic.argp
-
-				p = appendp(ctxt, p);
-				p->as = ANOP;
-				p1->pcond = p;
-				p2->pcond = p;
-			}
-			break;
-
-		case ARET:
-			nocache(p);
-			if(cursym->text->mark & LEAF) {
-				if(!autosize) {
-					p->as = AB;
-					p->from = zprog.from;
-					if(p->to.sym) { // retjmp
-						p->to.type = TYPE_BRANCH;
-					} else {
-						p->to.type = TYPE_MEM;
-						p->to.offset = 0;
-						p->to.reg = REGLINK;
-					}
-					break;
-				}
-			}
-
-			p->as = AMOVW;
-			p->scond |= C_PBIT;
-			p->from.type = TYPE_MEM;
-			p->from.offset = autosize;
-			p->from.reg = REGSP;
-			p->to.type = TYPE_REG;
-			p->to.reg = REGPC;
-			// If there are instructions following
-			// this ARET, they come from a branch
-			// with the same stackframe, so no spadj.
-			
-			if(p->to.sym) { // retjmp
-				p->to.reg = REGLINK;
-				q2 = appendp(ctxt, p);
-				q2->as = AB;
-				q2->to.type = TYPE_BRANCH;
-				q2->to.sym = p->to.sym;
-				p->to.sym = nil;
-				p = q2;
-			}
-			break;
-
-		case AADD:
-			if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
-				p->spadj = -p->from.offset;
-			break;
-
-		case ASUB:
-			if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
-				p->spadj = p->from.offset;
-			break;
-
-		case ADIV:
-		case ADIVU:
-		case AMOD:
-		case AMODU:
-			if(ctxt->debugdivmod)
-				break;
-			if(p->from.type != TYPE_REG)
-				break;
-			if(p->to.type != TYPE_REG)
-				break;
-			q1 = p;
-
-			/* MOV a,4(SP) */
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->lineno = q1->lineno;
-			p->from.type = TYPE_REG;
-			p->from.reg = q1->from.reg;
-			p->to.type = TYPE_MEM;
-			p->to.reg = REGSP;
-			p->to.offset = 4;
-
-			/* MOV b,REGTMP */
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->lineno = q1->lineno;
-			p->from.type = TYPE_REG;
-			p->from.reg = q1->reg;
-			if(q1->reg == 0)
-				p->from.reg = q1->to.reg;
-			p->to.type = TYPE_REG;
-			p->to.reg = REGTMP;
-			p->to.offset = 0;
-
-			/* CALL appropriate */
-			p = appendp(ctxt, p);
-			p->as = ABL;
-			p->lineno = q1->lineno;
-			p->to.type = TYPE_BRANCH;
-			switch(o) {
-			case ADIV:
-				p->to.sym = ctxt->sym_div;
-				break;
-			case ADIVU:
-				p->to.sym = ctxt->sym_divu;
-				break;
-			case AMOD:
-				p->to.sym = ctxt->sym_mod;
-				break;
-			case AMODU:
-				p->to.sym = ctxt->sym_modu;
-				break;
-			}
-
-			/* MOV REGTMP, b */
-			p = appendp(ctxt, p);
-			p->as = AMOVW;
-			p->lineno = q1->lineno;
-			p->from.type = TYPE_REG;
-			p->from.reg = REGTMP;
-			p->from.offset = 0;
-			p->to.type = TYPE_REG;
-			p->to.reg = q1->to.reg;
-
-			/* ADD $8,SP */
-			p = appendp(ctxt, p);
-			p->as = AADD;
-			p->lineno = q1->lineno;
-			p->from.type = TYPE_CONST;
-			p->from.reg = 0;
-			p->from.offset = 8;
-			p->reg = 0;
-			p->to.type = TYPE_REG;
-			p->to.reg = REGSP;
-			p->spadj = -8;
-
-			/* Keep saved LR at 0(SP) after SP change. */
-			/* MOVW 0(SP), REGTMP; MOVW REGTMP, -8!(SP) */
-			/* TODO: Remove SP adjustments; see issue 6699. */
-			q1->as = AMOVW;
-			q1->from.type = TYPE_MEM;
-			q1->from.reg = REGSP;
-			q1->from.offset = 0;
-			q1->reg = 0;
-			q1->to.type = TYPE_REG;
-			q1->to.reg = REGTMP;
-
-			/* SUB $8,SP */
-			q1 = appendp(ctxt, q1);
-			q1->as = AMOVW;
-			q1->from.type = TYPE_REG;
-			q1->from.reg = REGTMP;
-			q1->reg = 0;
-			q1->to.type = TYPE_MEM;
-			q1->to.reg = REGSP;
-			q1->to.offset = -8;
-			q1->scond |= C_WBIT;
-			q1->spadj = 8;
-
-			break;
-		case AMOVW:
-			if((p->scond & C_WBIT) && p->to.type == TYPE_MEM && p->to.reg == REGSP)
-				p->spadj = -p->to.offset;
-			if((p->scond & C_PBIT) && p->from.type == TYPE_MEM && p->from.reg == REGSP && p->to.reg != REGPC)
-				p->spadj = -p->from.offset;
-			if(p->from.type == TYPE_ADDR && p->from.reg == REGSP && p->to.type == TYPE_REG && p->to.reg == REGSP)
-				p->spadj = -p->from.offset;
-			break;
-		}
-	}
-}
-
-static int
-isfloatreg(Addr *a)
-{
-	return a->type == TYPE_REG && REG_F0 <= a->reg && a->reg <= REG_F15;
-}
-
-static void
-softfloat(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *next;
-	LSym *symsfloat;
-	int wasfloat;
-
-	if(ctxt->goarm > 5)
-		return;
-
-	symsfloat = linklookup(ctxt, "_sfloat", 0);
-
-	wasfloat = 0;
-	for(p = cursym->text; p != nil; p = p->link)
-		if(p->pcond != nil)
-			p->pcond->mark |= LABEL;
-	for(p = cursym->text; p != nil; p = p->link) {
-		switch(p->as) {
-		case AMOVW:
-			if(isfloatreg(&p->to) || isfloatreg(&p->from))
-				goto soft;
-			goto notsoft;
-
-		case AMOVWD:
-		case AMOVWF:
-		case AMOVDW:
-		case AMOVFW:
-		case AMOVFD:
-		case AMOVDF:
-		case AMOVF:
-		case AMOVD:
-
-		case ACMPF:
-		case ACMPD:
-		case AADDF:
-		case AADDD:
-		case ASUBF:
-		case ASUBD:
-		case AMULF:
-		case AMULD:
-		case ADIVF:
-		case ADIVD:
-		case ASQRTF:
-		case ASQRTD:
-		case AABSF:
-		case AABSD:
-			goto soft;
-
-		default:
-			goto notsoft;
-		}
-
-	soft:
-		if (!wasfloat || (p->mark&LABEL)) {
-			next = emallocz(sizeof(Prog));
-			*next = *p;
-
-			// BL _sfloat(SB)
-			*p = zprog;
-			p->link = next;
-			p->as = ABL;
- 				p->to.type = TYPE_BRANCH;
-			p->to.sym = symsfloat;
-			p->lineno = next->lineno;
-
-			p = next;
-			wasfloat = 1;
-		}
-		continue;
-
-	notsoft:
-		wasfloat = 0;
-	}
-}
-
-static Prog*
-stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
-{
-	// MOVW			g_stackguard(g), R1
-	p = appendp(ctxt, p);
-	p->as = AMOVW;
-	p->from.type = TYPE_MEM;
-	p->from.reg = REGG;
-	p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-	if(ctxt->cursym->cfunc)
-		p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_R1;
-	
-	if(framesize <= StackSmall) {
-		// small stack: SP < stackguard
-		//	CMP	stackguard, SP
-		p = appendp(ctxt, p);
-		p->as = ACMP;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R1;
-		p->reg = REGSP;
-	} else if(framesize <= StackBig) {
-		// large stack: SP-framesize < stackguard-StackSmall
-		//	MOVW $-framesize(SP), R2
-		//	CMP stackguard, R2
-		p = appendp(ctxt, p);
-		p->as = AMOVW;
-		p->from.type = TYPE_ADDR;
-		p->from.reg = REGSP;
-		p->from.offset = -framesize;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R2;
-		
-		p = appendp(ctxt, p);
-		p->as = ACMP;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R1;
-		p->reg = REG_R2;
-	} else {
-		// Such a large stack we need to protect against wraparound
-		// if SP is close to zero.
-		//	SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//	CMP $StackPreempt, R1
-		//	MOVW.NE $StackGuard(SP), R2
-		//	SUB.NE R1, R2
-		//	MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
-		//	CMP.NE R3, R2
-		p = appendp(ctxt, p);
-		p->as = ACMP;
-		p->from.type = TYPE_CONST;
-		p->from.offset = (uint32)StackPreempt;
-		p->reg = REG_R1;
-
-		p = appendp(ctxt, p);
-		p->as = AMOVW;
-		p->from.type = TYPE_ADDR;
-		p->from.reg = REGSP;
-		p->from.offset = StackGuard;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R2;
-		p->scond = C_SCOND_NE;
-		
-		p = appendp(ctxt, p);
-		p->as = ASUB;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R1;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R2;
-		p->scond = C_SCOND_NE;
-		
-		p = appendp(ctxt, p);
-		p->as = AMOVW;
-		p->from.type = TYPE_ADDR;
-		p->from.offset = framesize + (StackGuard - StackSmall);
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R3;
-		p->scond = C_SCOND_NE;
-		
-		p = appendp(ctxt, p);
-		p->as = ACMP;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R3;
-		p->reg = REG_R2;
-		p->scond = C_SCOND_NE;
-	}
-	
-	// MOVW.LS	R14, R3
-	p = appendp(ctxt, p);
-	p->as = AMOVW;
-	p->scond = C_SCOND_LS;
-	p->from.type = TYPE_REG;
-	p->from.reg = REGLINK;
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_R3;
-
-	// BL.LS		runtime.morestack(SB) // modifies LR, returns with LO still asserted
-	p = appendp(ctxt, p);
-	p->as = ABL;
-	p->scond = C_SCOND_LS;
-	p->to.type = TYPE_BRANCH;
-	if(ctxt->cursym->cfunc)
-		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
-	else
-		p->to.sym = ctxt->symmorestack[noctxt];
-	
-	// BLS	start
-	p = appendp(ctxt, p);
-	p->as = ABLS;
-	p->to.type = TYPE_BRANCH;
-	p->pcond = ctxt->cursym->text->link;
-	
-	return p;
-}
-
-static void
-initdiv(Link *ctxt)
-{
-	if(ctxt->sym_div != nil)
-		return;
-	ctxt->sym_div = linklookup(ctxt, "_div", 0);
-	ctxt->sym_divu = linklookup(ctxt, "_divu", 0);
-	ctxt->sym_mod = linklookup(ctxt, "_mod", 0);
-	ctxt->sym_modu = linklookup(ctxt, "_modu", 0);
-}
-
-static void xfol(Link*, Prog*, Prog**);
-
-static void
-follow(Link *ctxt, LSym *s)
-{
-	Prog *firstp, *lastp;
-
-	ctxt->cursym = s;
-
-	firstp = emallocz(sizeof(Prog));
-	lastp = firstp;
-	xfol(ctxt, s->text, &lastp);
-	lastp->link = nil;
-	s->text = firstp->link;
-}
-
-static int
-relinv(int a)
-{
-	switch(a) {
-	case ABEQ:	return ABNE;
-	case ABNE:	return ABEQ;
-	case ABCS:	return ABCC;
-	case ABHS:	return ABLO;
-	case ABCC:	return ABCS;
-	case ABLO:	return ABHS;
-	case ABMI:	return ABPL;
-	case ABPL:	return ABMI;
-	case ABVS:	return ABVC;
-	case ABVC:	return ABVS;
-	case ABHI:	return ABLS;
-	case ABLS:	return ABHI;
-	case ABGE:	return ABLT;
-	case ABLT:	return ABGE;
-	case ABGT:	return ABLE;
-	case ABLE:	return ABGT;
-	}
-	sysfatal("unknown relation: %s", anames5[a]);
-	return 0;
-}
-
-static void
-xfol(Link *ctxt, Prog *p, Prog **last)
-{
-	Prog *q, *r;
-	int a, i;
-
-loop:
-	if(p == nil)
-		return;
-	a = p->as;
-	if(a == AB) {
-		q = p->pcond;
-		if(q != nil && q->as != ATEXT) {
-			p->mark |= FOLL;
-			p = q;
-			if(!(p->mark & FOLL))
-				goto loop;
-		}
-	}
-	if(p->mark & FOLL) {
-		for(i=0,q=p; i<4; i++,q=q->link) {
-			if(q == *last || q == nil)
-				break;
-			a = q->as;
-			if(a == ANOP) {
-				i--;
-				continue;
-			}
-			if(a == AB || (a == ARET && q->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF)
-				goto copy;
-			if(q->pcond == nil || (q->pcond->mark&FOLL))
-				continue;
-			if(a != ABEQ && a != ABNE)
-				continue;
-		copy:
-			for(;;) {
-				r = emallocz(sizeof(Prog));
-				*r = *p;
-				if(!(r->mark&FOLL))
-					print("can't happen 1\n");
-				r->mark |= FOLL;
-				if(p != q) {
-					p = p->link;
-					(*last)->link = r;
-					*last = r;
-					continue;
-				}
-				(*last)->link = r;
-				*last = r;
-				if(a == AB || (a == ARET && q->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF)
-					return;
-				r->as = ABNE;
-				if(a == ABNE)
-					r->as = ABEQ;
-				r->pcond = p->link;
-				r->link = p->pcond;
-				if(!(r->link->mark&FOLL))
-					xfol(ctxt, r->link, last);
-				if(!(r->pcond->mark&FOLL))
-					print("can't happen 2\n");
-				return;
-			}
-		}
-		a = AB;
-		q = emallocz(sizeof(Prog));
-		q->as = a;
-		q->lineno = p->lineno;
-		q->to.type = TYPE_BRANCH;
-		q->to.offset = p->pc;
-		q->pcond = p;
-		p = q;
-	}
-	p->mark |= FOLL;
-	(*last)->link = p;
-	*last = p;
-	if(a == AB || (a == ARET && p->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF){
-		return;
-	}
-	if(p->pcond != nil)
-	if(a != ABL && a != ABX && p->link != nil) {
-		q = brchain(ctxt, p->link);
-		if(a != ATEXT && a != ABCASE)
-		if(q != nil && (q->mark&FOLL)) {
-			p->as = relinv(a);
-			p->link = p->pcond;
-			p->pcond = q;
-		}
-		xfol(ctxt, p->link, last);
-		q = brchain(ctxt, p->pcond);
-		if(q == nil)
-			q = p->pcond;
-		if(q->mark&FOLL) {
-			p->pcond = q;
-			return;
-		}
-		p = q;
-		goto loop;
-	}
-	p = p->link;
-	goto loop;
-}
-
-LinkArch linkarm = {
-	.name = "arm",
-	.thechar = '5',
-	.endian = LittleEndian,
-
-	.preprocess = preprocess,
-	.assemble = span5,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 4,
-	.ptrsize = 4,
-	.regsize = 4,
-};
diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c
deleted file mode 100644
index 546c89d..0000000
--- a/src/liblink/obj6.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-// Inferno utils/6l/pass.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/pass.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 <bio.h>
-#include <link.h>
-#include "../cmd/6l/6.out.h"
-#include "../runtime/stack.h"
-
-static void nacladdr(Link*, Prog*, Addr*);
-
-static int
-canuselocaltls(Link *ctxt)
-{
-	switch(ctxt->headtype) {
-	case Hplan9:
-	case Hwindows:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-progedit(Link *ctxt, Prog *p)
-{
-	char literal[64];
-	LSym *s;
-	Prog *q;
-
-	// Thread-local storage references use the TLS pseudo-register.
-	// As a register, TLS refers to the thread-local storage base, and it
-	// can only be loaded into another register:
-	//
-	//         MOVQ TLS, AX
-	//
-	// An offset from the thread-local storage base is written off(reg)(TLS*1).
-	// Semantically it is off(reg), but the (TLS*1) annotation marks this as
-	// indexing from the loaded TLS base. This emits a relocation so that
-	// if the linker needs to adjust the offset, it can. For example:
-	//
-	//         MOVQ TLS, AX
-	//         MOVQ 8(AX)(TLS*1), CX // load m into CX
-	// 
-	// On systems that support direct access to the TLS memory, this
-	// pair of instructions can be reduced to a direct TLS memory reference:
-	// 
-	//         MOVQ 8(TLS), CX // load m into CX
-	//
-	// The 2-instruction and 1-instruction forms correspond roughly to
-	// ELF TLS initial exec mode and ELF TLS local exec mode, respectively.
-	// 
-	// We applies this rewrite on systems that support the 1-instruction form.
-	// The decision is made using only the operating system (and probably
-	// the -shared flag, eventually), not the link mode. If some link modes
-	// on a particular operating system require the 2-instruction form,
-	// then all builds for that operating system will use the 2-instruction
-	// form, so that the link mode decision can be delayed to link time.
-	//
-	// In this way, all supported systems use identical instructions to
-	// access TLS, and they are rewritten appropriately first here in
-	// liblink and then finally using relocations in the linker.
-
-	if(canuselocaltls(ctxt)) {
-		// Reduce TLS initial exec model to TLS local exec model.
-		// Sequences like
-		//	MOVQ TLS, BX
-		//	... off(BX)(TLS*1) ...
-		// become
-		//	NOP
-		//	... off(TLS) ...
-		//
-		// TODO(rsc): Remove the Hsolaris special case. It exists only to
-		// guarantee we are producing byte-identical binaries as before this code.
-		// But it should be unnecessary.
-		if((p->as == AMOVQ || p->as == AMOVL) && p->from.type == TYPE_REG && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_R15 && ctxt->headtype != Hsolaris)
-			nopout(p);
-		if(p->from.type == TYPE_MEM && p->from.index == REG_TLS && REG_AX <= p->from.reg && p->from.reg <= REG_R15) {
-			p->from.reg = REG_TLS;
-			p->from.scale = 0;
-			p->from.index = REG_NONE;
-		}
-		if(p->to.type == TYPE_MEM && p->to.index == REG_TLS && REG_AX <= p->to.reg && p->to.reg <= REG_R15) {
-			p->to.reg = REG_TLS;
-			p->to.scale = 0;
-			p->to.index = REG_NONE;
-		}
-	} else {
-		// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
-		// The instruction
-		//	MOVQ off(TLS), BX
-		// becomes the sequence
-		//	MOVQ TLS, BX
-		//	MOVQ off(BX)(TLS*1), BX
-		// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
-		if((p->as == AMOVQ || p->as == AMOVL) && p->from.type == TYPE_MEM && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_R15) {
-			q = appendp(ctxt, p);
-			q->as = p->as;
-			q->from = p->from;
-			q->from.type = TYPE_MEM;
-			q->from.reg = p->to.reg;
-			q->from.index = REG_TLS;
-			q->from.scale = 2; // TODO: use 1
-			q->to = p->to;
-			p->from.type = TYPE_REG;
-			p->from.reg = REG_TLS;
-			p->from.index = REG_NONE;
-			p->from.offset = 0;
-		}
-	}
-
-	// TODO: Remove.
-	if(ctxt->headtype == Hwindows || ctxt->headtype == Hplan9) {
-		if(p->from.scale == 1 && p->from.index == REG_TLS)
-			p->from.scale = 2;
-		if(p->to.scale == 1 && p->to.index == REG_TLS)
-			p->to.scale = 2;
-	}
-
-	if(ctxt->headtype == Hnacl) {
-		nacladdr(ctxt, p, &p->from);
-		nacladdr(ctxt, p, &p->to);
-	}
-
-	// Maintain information about code generation mode.
-	if(ctxt->mode == 0)
-		ctxt->mode = 64;
-	p->mode = ctxt->mode;
-	
-	switch(p->as) {
-	case AMODE:
-		if(p->from.type == TYPE_CONST || (p->from.type == TYPE_MEM && p->from.reg == REG_NONE)) {
-			switch((int)p->from.offset) {
-			case 16:
-			case 32:
-			case 64:
-				ctxt->mode = p->from.offset;
-				break;
-			}
-		}
-		nopout(p);
-		break;
-	}
-	
-	// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
-	switch(p->as) {
-	case ACALL:
-	case AJMP:
-	case ARET:
-		if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
-			p->to.type = TYPE_BRANCH;
-		break;
-	}
-
-	// Rewrite float constants to values stored in memory.
-	switch(p->as) {
-	case AMOVSS:
-		// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
-		if(p->from.type == TYPE_FCONST)
-		if(p->from.u.dval == 0)
-		if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X15) {
-			p->as = AXORPS;
-			p->from = p->to;
-			break;
-		}
-		// fallthrough
-
-	case AFMOVF:
-	case AFADDF:
-	case AFSUBF:
-	case AFSUBRF:
-	case AFMULF:
-	case AFDIVF:
-	case AFDIVRF:
-	case AFCOMF:
-	case AFCOMFP:
-	case AADDSS:
-	case ASUBSS:
-	case AMULSS:
-	case ADIVSS:
-	case ACOMISS:
-	case AUCOMISS:
-		if(p->from.type == TYPE_FCONST) {
-			uint32 i32;
-			float32 f32;
-			f32 = p->from.u.dval;
-			memmove(&i32, &f32, 4);
-			sprint(literal, "$f32.%08ux", i32);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint32(ctxt, s, i32);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.name = NAME_EXTERN;
-			p->from.sym = s;
-			p->from.offset = 0;
-		}
-		break;
-
-	case AMOVSD:
-		// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
-		if(p->from.type == TYPE_FCONST)
-		if(p->from.u.dval == 0)
-		if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X15) {
-			p->as = AXORPS;
-			p->from = p->to;
-			break;
-		}
-		// fallthrough
-	
-	case AFMOVD:
-	case AFADDD:
-	case AFSUBD:
-	case AFSUBRD:
-	case AFMULD:
-	case AFDIVD:
-	case AFDIVRD:
-	case AFCOMD:
-	case AFCOMDP:
-	case AADDSD:
-	case ASUBSD:
-	case AMULSD:
-	case ADIVSD:
-	case ACOMISD:
-	case AUCOMISD:
-		if(p->from.type == TYPE_FCONST) {
-			uint64 i64;
-			memmove(&i64, &p->from.u.dval, 8);
-			sprint(literal, "$f64.%016llux", i64);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint64(ctxt, s, i64);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.name = NAME_EXTERN;
-			p->from.sym = s;
-			p->from.offset = 0;
-		}
-		break;
-	}
-}
-
-static void
-nacladdr(Link *ctxt, Prog *p, Addr *a)
-{
-	if(p->as == ALEAL || p->as == ALEAQ)
-		return;
-	
-	if(a->reg == REG_BP) {
-		ctxt->diag("invalid address: %P", p);
-		return;
-	}
-	if(a->reg == REG_TLS)
-		a->reg = REG_BP;
-	if(a->type == TYPE_MEM && a->name == NAME_NONE) {
-		switch(a->reg) {
-		case REG_BP:
-		case REG_SP:
-		case REG_R15:
-			// all ok
-			break;
-		default:
-			if(a->index != REG_NONE)
-				ctxt->diag("invalid address %P", p);
-			a->index = a->reg;
-			if(a->index != REG_NONE)
-				a->scale = 1;
-			a->reg = REG_R15;
-			break;
-		}
-	}
-}
-
-static Prog*	load_g_cx(Link*, Prog*);
-static Prog*	stacksplit(Link*, Prog*, int32, int32, int, Prog**);
-static void	indir_cx(Link*, Addr*);
-
-static void
-preprocess(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *q, *p1, *p2;
-	int32 autoffset, deltasp;
-	int a, pcsize, bpsize;
-	vlong textarg;
-
-	if(ctxt->tlsg == nil)
-		ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
-	if(ctxt->symmorestack[0] == nil) {
-		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
-		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
-	}
-
-	if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
-		ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
-
-	ctxt->cursym = cursym;
-
-	if(cursym->text == nil || cursym->text->link == nil)
-		return;				
-
-	p = cursym->text;
-	autoffset = p->to.offset;
-	if(autoffset < 0)
-		autoffset = 0;
-	
-	if(framepointer_enabled && autoffset > 0) {
-		// Make room for to save a base pointer.  If autoffset == 0,
-		// this might do something special like a tail jump to
-		// another function, so in that case we omit this.
-		bpsize = ctxt->arch->ptrsize;
-		autoffset += bpsize;
-		p->to.offset += bpsize;
-	} else {
-		bpsize = 0;
-	}
-
-	textarg = p->to.u.argsize;
-	cursym->args = textarg;
-	cursym->locals = p->to.offset;
-
-	if(autoffset < StackSmall && !(p->from3.offset & NOSPLIT)) {
-		for(q = p; q != nil; q = q->link) {
-			if(q->as == ACALL)
-				goto noleaf;
-			if((q->as == ADUFFCOPY || q->as == ADUFFZERO) && autoffset >= StackSmall - 8)
-				goto noleaf;
-		}
-		p->from3.offset |= NOSPLIT;
-	noleaf:;
-	}
-
-	q = nil;
-	if(!(p->from3.offset & NOSPLIT) || (p->from3.offset & WRAPPER)) {
-		p = appendp(ctxt, p);
-		p = load_g_cx(ctxt, p); // load g into CX
-	}
-	if(!(cursym->text->from3.offset & NOSPLIT))
-		p = stacksplit(ctxt, p, autoffset, textarg, !(cursym->text->from3.offset&NEEDCTXT), &q); // emit split check
-
-	if(autoffset) {
-		if(autoffset%ctxt->arch->regsize != 0)
-			ctxt->diag("unaligned stack size %d", autoffset);
-		p = appendp(ctxt, p);
-		p->as = AADJSP;
-		p->from.type = TYPE_CONST;
-		p->from.offset = autoffset;
-		p->spadj = autoffset;
-	} else {
-		// zero-byte stack adjustment.
-		// Insert a fake non-zero adjustment so that stkcheck can
-		// recognize the end of the stack-splitting prolog.
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p->spadj = -ctxt->arch->ptrsize;
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p->spadj = ctxt->arch->ptrsize;
-	}
-	if(q != nil)
-		q->pcond = p;
-	deltasp = autoffset;
-
-	if(bpsize > 0) {
-		// Save caller's BP
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_BP;
-		p->to.type = TYPE_MEM;
-		p->to.reg = REG_SP;
-		p->to.scale = 1;
-		p->to.offset = autoffset - bpsize;
-
-		// Move current frame to BP
-		p = appendp(ctxt, p);
-		p->as = ALEAQ;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.scale = 1;
-		p->from.offset = autoffset - bpsize;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_BP;
-	}
-	
-	if(cursym->text->from3.offset & WRAPPER) {
-		// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
-		//
-		//	MOVQ g_panic(CX), BX
-		//	TESTQ BX, BX
-		//	JEQ end
-		//	LEAQ (autoffset+8)(SP), DI
-		//	CMPQ panic_argp(BX), DI
-		//	JNE end
-		//	MOVQ SP, panic_argp(BX)
-		// end:
-		//	NOP
-		//
-		// The NOP is needed to give the jumps somewhere to land.
-		// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
-
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_CX;
-		p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_BX;
-		if(ctxt->headtype == Hnacl) {
-			p->as = AMOVL;
-			p->from.type = TYPE_MEM;
-			p->from.reg = REG_R15;
-			p->from.scale = 1;
-			p->from.index = REG_CX;
-		}
-
-		p = appendp(ctxt, p);
-		p->as = ATESTQ;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_BX;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_BX;
-		if(ctxt->headtype == Hnacl)
-			p->as = ATESTL;
-
-		p = appendp(ctxt, p);
-		p->as = AJEQ;
-		p->to.type = TYPE_BRANCH;
-		p1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = ALEAQ;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = autoffset+8;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-		if(ctxt->headtype == Hnacl)
-			p->as = ALEAL;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPQ;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_BX;
-		p->from.offset = 0; // Panic.argp
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-		if(ctxt->headtype == Hnacl) {
-			p->as = ACMPL;
-			p->from.type = TYPE_MEM;
-			p->from.reg = REG_R15;
-			p->from.scale = 1;
-			p->from.index = REG_BX;
-		}
-
-		p = appendp(ctxt, p);
-		p->as = AJNE;
-		p->to.type = TYPE_BRANCH;
-		p2 = p;
-
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		p->to.type = TYPE_MEM;
-		p->to.reg = REG_BX;
-		p->to.offset = 0; // Panic.argp
-		if(ctxt->headtype == Hnacl) {
-			p->as = AMOVL;
-			p->to.type = TYPE_MEM;
-			p->to.reg = REG_R15;
-			p->to.scale = 1;
-			p->to.index = REG_BX;
-		}
-
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p1->pcond = p;
-		p2->pcond = p;
-	}
-
-	if(ctxt->debugzerostack && autoffset && !(cursym->text->from3.offset&NOSPLIT)) {
-		// 6l -Z means zero the stack frame on entry.
-		// This slows down function calls but can help avoid
-		// false positives in garbage collection.
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-		
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_CONST;
-		p->from.offset = autoffset/8;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_CX;
-		
-		p = appendp(ctxt, p);
-		p->as = AMOVQ;
-		p->from.type = TYPE_CONST;
-		p->from.offset = 0;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = AREP;
-		
-		p = appendp(ctxt, p);
-		p->as = ASTOSQ;
-	}
-	
-	for(; p != nil; p = p->link) {
-		pcsize = p->mode/8;
-		a = p->from.name;
-		if(a == NAME_AUTO)
-			p->from.offset += deltasp - bpsize;
-		if(a == NAME_PARAM)
-			p->from.offset += deltasp + pcsize;
-		a = p->to.name;
-		if(a == NAME_AUTO)
-			p->to.offset += deltasp - bpsize;
-		if(a == NAME_PARAM)
-			p->to.offset += deltasp + pcsize;
-
-		switch(p->as) {
-		default:
-			continue;
-		case APUSHL:
-		case APUSHFL:
-			deltasp += 4;
-			p->spadj = 4;
-			continue;
-		case APUSHQ:
-		case APUSHFQ:
-			deltasp += 8;
-			p->spadj = 8;
-			continue;
-		case APUSHW:
-		case APUSHFW:
-			deltasp += 2;
-			p->spadj = 2;
-			continue;
-		case APOPL:
-		case APOPFL:
-			deltasp -= 4;
-			p->spadj = -4;
-			continue;
-		case APOPQ:
-		case APOPFQ:
-			deltasp -= 8;
-			p->spadj = -8;
-			continue;
-		case APOPW:
-		case APOPFW:
-			deltasp -= 2;
-			p->spadj = -2;
-			continue;
-		case ARET:
-			break;
-		}
-
-		if(autoffset != deltasp)
-			ctxt->diag("unbalanced PUSH/POP");
-
-		if(autoffset) {
-			if(bpsize > 0) {
-				// Restore caller's BP
-				p->as = AMOVQ;
-				p->from.type = TYPE_MEM;
-				p->from.reg = REG_SP;
-				p->from.scale = 1;
-				p->from.offset = autoffset - bpsize;
-				p->to.type = TYPE_REG;
-				p->to.reg = REG_BP;
-				p = appendp(ctxt, p);
-			}
-
-			p->as = AADJSP;
-			p->from.type = TYPE_CONST;
-			p->from.offset = -autoffset;
-			p->spadj = -autoffset;
-			p = appendp(ctxt, p);
-			p->as = ARET;
-			// If there are instructions following
-			// this ARET, they come from a branch
-			// with the same stackframe, so undo
-			// the cleanup.
-			p->spadj = +autoffset;
-		}
-		if(p->to.sym) // retjmp
-			p->as = AJMP;
-	}
-}
-
-static void
-indir_cx(Link *ctxt, Addr *a)
-{
-	if(ctxt->headtype == Hnacl) {
-		a->type = TYPE_MEM;
-		a->reg = REG_R15;
-		a->index = REG_CX;
-		a->scale = 1;
-		return;
-	}
-
-	a->type = TYPE_MEM;
-	a->reg = REG_CX;
-}
-
-// Append code to p to load g into cx.
-// Overwrites p with the first instruction (no first appendp).
-// Overwriting p is unusual but it lets use this in both the
-// prologue (caller must call appendp first) and in the epilogue.
-// Returns last new instruction.
-static Prog*
-load_g_cx(Link *ctxt, Prog *p)
-{	
-	Prog *next;
-
-	p->as = AMOVQ;
-	if(ctxt->arch->ptrsize == 4)
-		p->as = AMOVL;
-	p->from.type = TYPE_MEM;
-	p->from.reg = REG_TLS;
-	p->from.offset = 0;
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_CX;
-	
-	next = p->link;
-	progedit(ctxt, p);
-	while(p->link != next)
-		p = p->link;
-	
-	if(p->from.index == REG_TLS)
-		p->from.scale = 2;
-
-	return p;
-}
-
-// Append code to p to check for stack split.
-// Appends to (does not overwrite) p.
-// Assumes g is in CX.
-// Returns last new instruction.
-// On return, *jmpok is the instruction that should jump
-// to the stack frame allocation if no split is needed.
-static Prog*
-stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog **jmpok)
-{
-	Prog *q, *q1;
-	int cmp, lea, mov, sub;
-
-	USED(textarg);
-	cmp = ACMPQ;
-	lea = ALEAQ;
-	mov = AMOVQ;
-	sub = ASUBQ;
-
-	if(ctxt->headtype == Hnacl) {
-		cmp = ACMPL;
-		lea = ALEAL;
-		mov = AMOVL;
-		sub = ASUBL;
-	}
-
-	q1 = nil;
-	if(framesize <= StackSmall) {
-		// small stack: SP <= stackguard
-		//	CMPQ SP, stackguard
-		p = appendp(ctxt, p);
-		p->as = cmp;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		indir_cx(ctxt, &p->to);
-		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	} else if(framesize <= StackBig) {
-		// large stack: SP-framesize <= stackguard-StackSmall
-		//	LEAQ -xxx(SP), AX
-		//	CMPQ AX, stackguard
-		p = appendp(ctxt, p);
-		p->as = lea;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = -(framesize-StackSmall);
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-
-		p = appendp(ctxt, p);
-		p->as = cmp;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_AX;
-		indir_cx(ctxt, &p->to);
-		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	MOVQ	stackguard, CX
-		//	CMPQ	CX, $StackPreempt
-		//	JEQ	label-of-call-to-morestack
-		//	LEAQ	StackGuard(SP), AX
-		//	SUBQ	CX, AX
-		//	CMPQ	AX, $(framesize+(StackGuard-StackSmall))
-
-		p = appendp(ctxt, p);
-		p->as = mov;
-		indir_cx(ctxt, &p->from);
-		p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_SI;
-
-		p = appendp(ctxt, p);
-		p->as = cmp;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SI;
-		p->to.type = TYPE_CONST;
-		p->to.offset = StackPreempt;
-
-		p = appendp(ctxt, p);
-		p->as = AJEQ;
-		p->to.type = TYPE_BRANCH;
-		q1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = lea;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = StackGuard;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = sub;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SI;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = cmp;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_AX;
-		p->to.type = TYPE_CONST;
-		p->to.offset = framesize+(StackGuard-StackSmall);
-	}					
-
-	// common
-	p = appendp(ctxt, p);
-	p->as = AJHI;
-	p->to.type = TYPE_BRANCH;
-	q = p;
-
-	p = appendp(ctxt, p);
-	p->as = ACALL;
-	p->to.type = TYPE_BRANCH;
-	if(ctxt->cursym->cfunc)
-		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
-	else
-		p->to.sym = ctxt->symmorestack[noctxt];
-	
-	p = appendp(ctxt, p);
-	p->as = AJMP;
-	p->to.type = TYPE_BRANCH;
-	p->pcond = ctxt->cursym->text->link;
-	
-	if(q != nil)
-		q->pcond = p->link;
-	if(q1 != nil)
-		q1->pcond = q->link;
-
-	*jmpok = q;
-	return p;
-}
-
-static void xfol(Link*, Prog*, Prog**);
-
-static void
-follow(Link *ctxt, LSym *s)
-{
-	Prog *firstp, *lastp;
-
-	ctxt->cursym = s;
-
-	firstp = emallocz(sizeof(Prog));
-	lastp = firstp;
-	xfol(ctxt, s->text, &lastp);
-	lastp->link = nil;
-	s->text = firstp->link;
-}
-
-static int
-nofollow(int a)
-{
-	switch(a) {
-	case AJMP:
-	case ARET:
-	case AIRETL:
-	case AIRETQ:
-	case AIRETW:
-	case ARETFL:
-	case ARETFQ:
-	case ARETFW:
-	case AUNDEF:
-		return 1;
-	}
-	return 0;
-}
-
-static int
-pushpop(int a)
-{
-	switch(a) {
-	case APUSHL:
-	case APUSHFL:
-	case APUSHQ:
-	case APUSHFQ:
-	case APUSHW:
-	case APUSHFW:
-	case APOPL:
-	case APOPFL:
-	case APOPQ:
-	case APOPFQ:
-	case APOPW:
-	case APOPFW:
-		return 1;
-	}
-	return 0;
-}
-
-static int
-relinv(int a)
-{
-	switch(a) {
-	case AJEQ:	return AJNE;
-	case AJNE:	return AJEQ;
-	case AJLE:	return AJGT;
-	case AJLS:	return AJHI;
-	case AJLT:	return AJGE;
-	case AJMI:	return AJPL;
-	case AJGE:	return AJLT;
-	case AJPL:	return AJMI;
-	case AJGT:	return AJLE;
-	case AJHI:	return AJLS;
-	case AJCS:	return AJCC;
-	case AJCC:	return AJCS;
-	case AJPS:	return AJPC;
-	case AJPC:	return AJPS;
-	case AJOS:	return AJOC;
-	case AJOC:	return AJOS;
-	}
-	sysfatal("unknown relation: %s", anames6[a]);
-	return 0;
-}
-
-static void
-xfol(Link *ctxt, Prog *p, Prog **last)
-{
-	Prog *q;
-	int i;
-	int a;
-
-loop:
-	if(p == nil)
-		return;
-	if(p->as == AJMP)
-	if((q = p->pcond) != nil && q->as != ATEXT) {
-		/* mark instruction as done and continue layout at target of jump */
-		p->mark = 1;
-		p = q;
-		if(p->mark == 0)
-			goto loop;
-	}
-	if(p->mark) {
-		/* 
-		 * p goes here, but already used it elsewhere.
-		 * copy up to 4 instructions or else branch to other copy.
-		 */
-		for(i=0,q=p; i<4; i++,q=q->link) {
-			if(q == nil)
-				break;
-			if(q == *last)
-				break;
-			a = q->as;
-			if(a == ANOP) {
-				i--;
-				continue;
-			}
-			if(nofollow(a) || pushpop(a))	
-				break;	// NOTE(rsc): arm does goto copy
-			if(q->pcond == nil || q->pcond->mark)
-				continue;
-			if(a == ACALL || a == ALOOP)
-				continue;
-			for(;;) {
-				if(p->as == ANOP) {
-					p = p->link;
-					continue;
-				}
-				q = copyp(ctxt, p);
-				p = p->link;
-				q->mark = 1;
-				(*last)->link = q;
-				*last = q;
-				if(q->as != a || q->pcond == nil || q->pcond->mark)
-					continue;
-
-				q->as = relinv(q->as);
-				p = q->pcond;
-				q->pcond = q->link;
-				q->link = p;
-				xfol(ctxt, q->link, last);
-				p = q->link;
-				if(p->mark)
-					return;
-				goto loop;
-			}
-		} /* */
-		q = emallocz(sizeof(Prog));
-		q->as = AJMP;
-		q->lineno = p->lineno;
-		q->to.type = TYPE_BRANCH;
-		q->to.offset = p->pc;
-		q->pcond = p;
-		p = q;
-	}
-	
-	/* emit p */
-	p->mark = 1;
-	(*last)->link = p;
-	*last = p;
-	a = p->as;
-
-	/* continue loop with what comes after p */
-	if(nofollow(a))
-		return;
-	if(p->pcond != nil && a != ACALL) {
-		/*
-		 * some kind of conditional branch.
-		 * recurse to follow one path.
-		 * continue loop on the other.
-		 */
-		if((q = brchain(ctxt, p->pcond)) != nil)
-			p->pcond = q;
-		if((q = brchain(ctxt, p->link)) != nil)
-			p->link = q;
-		if(p->from.type == TYPE_CONST) {
-			if(p->from.offset == 1) {
-				/*
-				 * expect conditional jump to be taken.
-				 * rewrite so that's the fall-through case.
-				 */
-				p->as = relinv(a);
-				q = p->link;
-				p->link = p->pcond;
-				p->pcond = q;
-			}
-		} else {			
-			q = p->link;
-			if(q->mark)
-			if(a != ALOOP) {
-				p->as = relinv(a);
-				p->link = p->pcond;
-				p->pcond = q;
-			}
-		}
-		xfol(ctxt, p->link, last);
-		if(p->pcond->mark)
-			return;
-		p = p->pcond;
-		goto loop;
-	}
-	p = p->link;
-	goto loop;
-}
-
-LinkArch linkamd64 = {
-	.name = "amd64",
-	.thechar = '6',
-	.endian = LittleEndian,
-
-	.preprocess = preprocess,
-	.assemble = span6,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 1,
-	.ptrsize = 8,
-	.regsize = 8,
-};
-
-LinkArch linkamd64p32 = {
-	.name = "amd64p32",
-	.thechar = '6',
-	.endian = LittleEndian,
-
-	.preprocess = preprocess,
-	.assemble = span6,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 1,
-	.ptrsize = 4,
-	.regsize = 8,
-};
diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c
deleted file mode 100644
index eb8e318..0000000
--- a/src/liblink/obj8.c
+++ /dev/null
@@ -1,842 +0,0 @@
-// Inferno utils/8l/pass.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/pass.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 <bio.h>
-#include <link.h>
-#include "../cmd/8l/8.out.h"
-#include "../runtime/stack.h"
-
-static int
-canuselocaltls(Link *ctxt)
-{
-	switch(ctxt->headtype) {
-	case Hlinux:
-	case Hnacl:
-	case Hplan9:
-	case Hwindows:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-progedit(Link *ctxt, Prog *p)
-{
-	char literal[64];
-	LSym *s;
-	Prog *q;
-	
-	// See obj6.c for discussion of TLS.
-	if(canuselocaltls(ctxt)) {
-		// Reduce TLS initial exec model to TLS local exec model.
-		// Sequences like
-		//	MOVL TLS, BX
-		//	... off(BX)(TLS*1) ...
-		// become
-		//	NOP
-		//	... off(TLS) ...
-		if(p->as == AMOVL && p->from.type == TYPE_REG && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
-			p->as = ANOP;
-			p->from.type = TYPE_NONE;
-			p->to.type = TYPE_NONE;
-		}
-		if(p->from.type == TYPE_MEM && p->from.index == REG_TLS && REG_AX <= p->from.reg && p->from.reg <= REG_DI) {
-			p->from.type = TYPE_MEM;
-			p->from.reg = REG_TLS;
-			p->from.scale = 0;
-			p->from.index = REG_NONE;
-		}
-		if(p->to.type == TYPE_MEM && p->to.index == REG_TLS && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
-			p->to.type = TYPE_MEM;
-			p->to.reg = REG_TLS;
-			p->to.scale = 0;
-			p->to.index = REG_NONE;
-		}
-	} else {
-		// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
-		// The instruction
-		//	MOVL off(TLS), BX
-		// becomes the sequence
-		//	MOVL TLS, BX
-		//	MOVL off(BX)(TLS*1), BX
-		// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
-		if(p->as == AMOVL && p->from.type == TYPE_MEM && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
-			q = appendp(ctxt, p);
-			q->as = p->as;
-			q->from.type = TYPE_MEM;
-			q->from.reg = p->to.reg;
-			q->from.index = REG_TLS;
-			q->from.scale = 2; // TODO: use 1
-			q->to = p->to;
-			p->from.type = TYPE_REG;
-			p->from.reg = REG_TLS;
-			p->from.index = REG_NONE;
-			p->from.offset = 0;
-		}
-	}
-
-	// TODO: Remove.
-	if(ctxt->headtype == Hplan9) {
-		if(p->from.scale == 1 && p->from.index == REG_TLS)
-			p->from.scale = 2;
-		if(p->to.scale == 1 && p->to.index == REG_TLS)
-			p->to.scale = 2;
-	}
-
-	// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
-	switch(p->as) {
-	case ACALL:
-	case AJMP:
-	case ARET:
-		if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
-			p->to.type = TYPE_BRANCH;
-		break;
-	}
-
-	// Rewrite float constants to values stored in memory.
-	switch(p->as) {
-	case AMOVSS:
-		// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
-		if(p->from.type == TYPE_FCONST)
-		if(p->from.u.dval == 0)
-		if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) {
-			p->as = AXORPS;
-			p->from = p->to;
-			break;
-		}
-		// fallthrough
-
-	case AFMOVF:
-	case AFADDF:
-	case AFSUBF:
-	case AFSUBRF:
-	case AFMULF:
-	case AFDIVF:
-	case AFDIVRF:
-	case AFCOMF:
-	case AFCOMFP:
-	case AADDSS:
-	case ASUBSS:
-	case AMULSS:
-	case ADIVSS:
-	case ACOMISS:
-	case AUCOMISS:
-		if(p->from.type == TYPE_FCONST) {
-			uint32 i32;
-			float32 f32;
-			f32 = p->from.u.dval;
-			memmove(&i32, &f32, 4);
-			sprint(literal, "$f32.%08ux", i32);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint32(ctxt, s, i32);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.name = NAME_EXTERN;
-			p->from.sym = s;
-			p->from.offset = 0;
-		}
-		break;
-
-	case AMOVSD:
-		// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
-		if(p->from.type == TYPE_FCONST)
-		if(p->from.u.dval == 0)
-		if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) {
-			p->as = AXORPS;
-			p->from = p->to;
-			break;
-		}
-		// fallthrough
-
-	case AFMOVD:
-	case AFADDD:
-	case AFSUBD:
-	case AFSUBRD:
-	case AFMULD:
-	case AFDIVD:
-	case AFDIVRD:
-	case AFCOMD:
-	case AFCOMDP:
-	case AADDSD:
-	case ASUBSD:
-	case AMULSD:
-	case ADIVSD:
-	case ACOMISD:
-	case AUCOMISD:
-		if(p->from.type == TYPE_FCONST) {
-			uint64 i64;
-			memmove(&i64, &p->from.u.dval, 8);
-			sprint(literal, "$f64.%016llux", i64);
-			s = linklookup(ctxt, literal, 0);
-			if(s->type == 0) {
-				s->type = SRODATA;
-				adduint64(ctxt, s, i64);
-				s->reachable = 0;
-			}
-			p->from.type = TYPE_MEM;
-			p->from.name = NAME_EXTERN;
-			p->from.sym = s;
-			p->from.offset = 0;
-		}
-		break;
-	}
-}
-
-static Prog*	load_g_cx(Link*, Prog*);
-static Prog*	stacksplit(Link*, Prog*, int32, int, Prog**);
-
-static void
-preprocess(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *q, *p1, *p2;
-	int32 autoffset, deltasp;
-	int a;
-
-	if(ctxt->symmorestack[0] == nil) {
-		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
-		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
-	}
-
-	if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
-		ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
-
-	ctxt->cursym = cursym;
-
-	if(cursym->text == nil || cursym->text->link == nil)
-		return;
-
-	p = cursym->text;
-	autoffset = p->to.offset;
-	if(autoffset < 0)
-		autoffset = 0;
-	
-	cursym->locals = autoffset;
-	cursym->args = p->to.u.argsize;
-
-	q = nil;
-
-	if(!(p->from3.offset & NOSPLIT) || (p->from3.offset & WRAPPER)) {
-		p = appendp(ctxt, p);
-		p = load_g_cx(ctxt, p); // load g into CX
-	}
-	if(!(cursym->text->from3.offset & NOSPLIT))
-		p = stacksplit(ctxt, p, autoffset, !(cursym->text->from3.offset&NEEDCTXT), &q); // emit split check
-
-	if(autoffset) {
-		p = appendp(ctxt, p);
-		p->as = AADJSP;
-		p->from.type = TYPE_CONST;
-		p->from.offset = autoffset;
-		p->spadj = autoffset;
-	} else {
-		// zero-byte stack adjustment.
-		// Insert a fake non-zero adjustment so that stkcheck can
-		// recognize the end of the stack-splitting prolog.
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p->spadj = -ctxt->arch->ptrsize;
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p->spadj = ctxt->arch->ptrsize;
-	}
-	if(q != nil)
-		q->pcond = p;
-	deltasp = autoffset;
-	
-	if(cursym->text->from3.offset & WRAPPER) {
-		// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
-		//
-		//	MOVL g_panic(CX), BX
-		//	TESTL BX, BX
-		//	JEQ end
-		//	LEAL (autoffset+4)(SP), DI
-		//	CMPL panic_argp(BX), DI
-		//	JNE end
-		//	MOVL SP, panic_argp(BX)
-		// end:
-		//	NOP
-		//
-		// The NOP is needed to give the jumps somewhere to land.
-		// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
-
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_CX;
-		p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_BX;
-
-		p = appendp(ctxt, p);
-		p->as = ATESTL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_BX;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_BX;
-
-		p = appendp(ctxt, p);
-		p->as = AJEQ;
-		p->to.type = TYPE_BRANCH;
-		p1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = ALEAL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = autoffset+4;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_BX;
-		p->from.offset = 0; // Panic.argp
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-
-		p = appendp(ctxt, p);
-		p->as = AJNE;
-		p->to.type = TYPE_BRANCH;
-		p2 = p;
-
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		p->to.type = TYPE_MEM;
-		p->to.reg = REG_BX;
-		p->to.offset = 0; // Panic.argp
-
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		p1->pcond = p;
-		p2->pcond = p;
-	}
-	
-	if(ctxt->debugzerostack && autoffset && !(cursym->text->from3.offset&NOSPLIT)) {
-		// 8l -Z means zero the stack frame on entry.
-		// This slows down function calls but can help avoid
-		// false positives in garbage collection.
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_DI;
-		
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_CONST;
-		p->from.offset = autoffset/4;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_CX;
-		
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_CONST;
-		p->from.offset = 0;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = AREP;
-		
-		p = appendp(ctxt, p);
-		p->as = ASTOSL;
-	}
-	
-	for(; p != nil; p = p->link) {
-		a = p->from.name;
-		if(a == NAME_AUTO)
-			p->from.offset += deltasp;
-		if(a == NAME_PARAM)
-			p->from.offset += deltasp + 4;
-		a = p->to.name;
-		if(a == NAME_AUTO)
-			p->to.offset += deltasp;
-		if(a == NAME_PARAM)
-			p->to.offset += deltasp + 4;
-
-		switch(p->as) {
-		default:
-			continue;
-		case APUSHL:
-		case APUSHFL:
-			deltasp += 4;
-			p->spadj = 4;
-			continue;
-		case APUSHW:
-		case APUSHFW:
-			deltasp += 2;
-			p->spadj = 2;
-			continue;
-		case APOPL:
-		case APOPFL:
-			deltasp -= 4;
-			p->spadj = -4;
-			continue;
-		case APOPW:
-		case APOPFW:
-			deltasp -= 2;
-			p->spadj = -2;
-			continue;
-		case ARET:
-			break;
-		}
-
-		if(autoffset != deltasp)
-			ctxt->diag("unbalanced PUSH/POP");
-
-		if(autoffset) {
-			p->as = AADJSP;
-			p->from.type = TYPE_CONST;
-			p->from.offset = -autoffset;
-			p->spadj = -autoffset;
-			p = appendp(ctxt, p);
-			p->as = ARET;
-			// If there are instructions following
-			// this ARET, they come from a branch
-			// with the same stackframe, so undo
-			// the cleanup.
-			p->spadj = +autoffset;
-		}
-		if(p->to.sym) // retjmp
-			p->as = AJMP;
-	}
-}
-
-// Append code to p to load g into cx.
-// Overwrites p with the first instruction (no first appendp).
-// Overwriting p is unusual but it lets use this in both the
-// prologue (caller must call appendp first) and in the epilogue.
-// Returns last new instruction.
-static Prog*
-load_g_cx(Link *ctxt, Prog *p)
-{
-	Prog *next;
-
-	p->as = AMOVL;
-	p->from.type = TYPE_MEM;
-	p->from.reg = REG_TLS;
-	p->from.offset = 0;
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_CX;
-
-	next = p->link;
-	progedit(ctxt, p);
-	while(p->link != next)
-		p = p->link;
-	
-	if(p->from.index == REG_TLS)
-		p->from.scale = 2;
-
-	return p;
-}
-
-// Append code to p to check for stack split.
-// Appends to (does not overwrite) p.
-// Assumes g is in CX.
-// Returns last new instruction.
-// On return, *jmpok is the instruction that should jump
-// to the stack frame allocation if no split is needed.
-static Prog*
-stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
-{
-	Prog *q, *q1;
-
-	if(ctxt->debugstack) {
-		// 8l -K means check not only for stack
-		// overflow but stack underflow.
-		// On underflow, INT 3 (breakpoint).
-		// Underflow itself is rare but this also
-		// catches out-of-sync stack guard info.
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_CX;
-		p->from.offset = 4;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_SP;
-
-		p = appendp(ctxt, p);
-		p->as = AJCC;
-		p->to.type = TYPE_BRANCH;
-		p->to.offset = 4;
-		q1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = AINT;
-		p->from.type = TYPE_CONST;
-		p->from.offset = 3;
-		
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		q1->pcond = p;
-	}
-	q1 = nil;
-
-	if(framesize <= StackSmall) {
-		// small stack: SP <= stackguard
-		//	CMPL SP, stackguard
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SP;
-		p->to.type = TYPE_MEM;
-		p->to.reg = REG_CX;
-		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	} else if(framesize <= StackBig) {
-		// large stack: SP-framesize <= stackguard-StackSmall
-		//	LEAL -(framesize-StackSmall)(SP), AX
-		//	CMPL AX, stackguard
-		p = appendp(ctxt, p);
-		p->as = ALEAL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = -(framesize-StackSmall);
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_AX;
-		p->to.type = TYPE_MEM;
-		p->to.reg = REG_CX;
-		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	} else {
-		// Such a large stack we need to protect against wraparound
-		// if SP is close to zero.
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	MOVL	stackguard, CX
-		//	CMPL	CX, $StackPreempt
-		//	JEQ	label-of-call-to-morestack
-		//	LEAL	StackGuard(SP), AX
-		//	SUBL	stackguard, AX
-		//	CMPL	AX, $(framesize+(StackGuard-StackSmall))
-		p = appendp(ctxt, p);
-		p->as = AMOVL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_CX;
-		p->from.offset = 0;
-		p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-		if(ctxt->cursym->cfunc)
-			p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_SI;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SI;
-		p->to.type = TYPE_CONST;
-		p->to.offset = (uint32)StackPreempt;
-
-		p = appendp(ctxt, p);
-		p->as = AJEQ;
-		p->to.type = TYPE_BRANCH;
-		q1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = ALEAL;
-		p->from.type = TYPE_MEM;
-		p->from.reg = REG_SP;
-		p->from.offset = StackGuard;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = ASUBL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_SI;
-		p->from.offset = 0;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_AX;
-		
-		p = appendp(ctxt, p);
-		p->as = ACMPL;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_AX;
-		p->to.type = TYPE_CONST;
-		p->to.offset = framesize+(StackGuard-StackSmall);
-	}		
-			
-	// common
-	p = appendp(ctxt, p);
-	p->as = AJHI;
-	p->to.type = TYPE_BRANCH;
-	p->to.offset = 4;
-	q = p;
-
-	p = appendp(ctxt, p);
-	p->as = ACALL;
-	p->to.type = TYPE_BRANCH;
-	if(ctxt->cursym->cfunc)
-		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
-	else
-		p->to.sym = ctxt->symmorestack[noctxt];
-
-	p = appendp(ctxt, p);
-	p->as = AJMP;
-	p->to.type = TYPE_BRANCH;
-	p->pcond = ctxt->cursym->text->link;
-
-	if(q != nil)
-		q->pcond = p->link;
-	if(q1 != nil)
-		q1->pcond = q->link;
-	
-	*jmpok = q;
-	return p;
-}
-
-static void xfol(Link*, Prog*, Prog**);
-
-static void
-follow(Link *ctxt, LSym *s)
-{
-	Prog *firstp, *lastp;
-
-	ctxt->cursym = s;
-
-	firstp = emallocz(sizeof(Prog));
-	lastp = firstp;
-	xfol(ctxt, s->text, &lastp);
-	lastp->link = nil;
-	s->text = firstp->link;
-}
-
-static int
-nofollow(int a)
-{
-	switch(a) {
-	case AJMP:
-	case ARET:
-	case AIRETL:
-	case AIRETW:
-	case AUNDEF:
-		return 1;
-	}
-	return 0;
-}
-
-static int
-pushpop(int a)
-{
-	switch(a) {
-	case APUSHL:
-	case APUSHFL:
-	case APUSHW:
-	case APUSHFW:
-	case APOPL:
-	case APOPFL:
-	case APOPW:
-	case APOPFW:
-		return 1;
-	}
-	return 0;
-}
-
-static int
-relinv(int a)
-{
-
-	switch(a) {
-	case AJEQ:	return AJNE;
-	case AJNE:	return AJEQ;
-	case AJLE:	return AJGT;
-	case AJLS:	return AJHI;
-	case AJLT:	return AJGE;
-	case AJMI:	return AJPL;
-	case AJGE:	return AJLT;
-	case AJPL:	return AJMI;
-	case AJGT:	return AJLE;
-	case AJHI:	return AJLS;
-	case AJCS:	return AJCC;
-	case AJCC:	return AJCS;
-	case AJPS:	return AJPC;
-	case AJPC:	return AJPS;
-	case AJOS:	return AJOC;
-	case AJOC:	return AJOS;
-	}
-	sysfatal("unknown relation: %s", anames8[a]);
-	return 0;
-}
-
-static void
-xfol(Link *ctxt, Prog *p, Prog **last)
-{
-	Prog *q;
-	int i;
-	int a;
-
-loop:
-	if(p == nil)
-		return;
-	if(p->as == AJMP)
-	if((q = p->pcond) != nil && q->as != ATEXT) {
-		/* mark instruction as done and continue layout at target of jump */
-		p->mark = 1;
-		p = q;
-		if(p->mark == 0)
-			goto loop;
-	}
-	if(p->mark) {
-		/* 
-		 * p goes here, but already used it elsewhere.
-		 * copy up to 4 instructions or else branch to other copy.
-		 */
-		for(i=0,q=p; i<4; i++,q=q->link) {
-			if(q == nil)
-				break;
-			if(q == *last)
-				break;
-			a = q->as;
-			if(a == ANOP) {
-				i--;
-				continue;
-			}
-			if(nofollow(a) || pushpop(a))	
-				break;	// NOTE(rsc): arm does goto copy
-			if(q->pcond == nil || q->pcond->mark)
-				continue;
-			if(a == ACALL || a == ALOOP)
-				continue;
-			for(;;) {
-				if(p->as == ANOP) {
-					p = p->link;
-					continue;
-				}
-				q = copyp(ctxt, p);
-				p = p->link;
-				q->mark = 1;
-				(*last)->link = q;
-				*last = q;
-				if(q->as != a || q->pcond == nil || q->pcond->mark)
-					continue;
-
-				q->as = relinv(q->as);
-				p = q->pcond;
-				q->pcond = q->link;
-				q->link = p;
-				xfol(ctxt, q->link, last);
-				p = q->link;
-				if(p->mark)
-					return;
-				goto loop;
-			}
-		} /* */
-		q = emallocz(sizeof(Prog));
-		q->as = AJMP;
-		q->lineno = p->lineno;
-		q->to.type = TYPE_BRANCH;
-		q->to.offset = p->pc;
-		q->pcond = p;
-		p = q;
-	}
-	
-	/* emit p */
-	p->mark = 1;
-	(*last)->link = p;
-	*last = p;
-	a = p->as;
-
-	/* continue loop with what comes after p */
-	if(nofollow(a))
-		return;
-	if(p->pcond != nil && a != ACALL) {
-		/*
-		 * some kind of conditional branch.
-		 * recurse to follow one path.
-		 * continue loop on the other.
-		 */
-		if((q = brchain(ctxt, p->pcond)) != nil)
-			p->pcond = q;
-		if((q = brchain(ctxt, p->link)) != nil)
-			p->link = q;
-		if(p->from.type == TYPE_CONST) {
-			if(p->from.offset == 1) {
-				/*
-				 * expect conditional jump to be taken.
-				 * rewrite so that's the fall-through case.
-				 */
-				p->as = relinv(a);
-				q = p->link;
-				p->link = p->pcond;
-				p->pcond = q;
-			}
-		} else {
-			q = p->link;
-			if(q->mark)
-			if(a != ALOOP) {
-				p->as = relinv(a);
-				p->link = p->pcond;
-				p->pcond = q;
-			}
-		}
-		xfol(ctxt, p->link, last);
-		if(p->pcond->mark)
-			return;
-		p = p->pcond;
-		goto loop;
-	}
-	p = p->link;
-	goto loop;
-}
-
-LinkArch link386 = {
-	.name = "386",
-	.thechar = '8',
-	.endian = LittleEndian,
-
-	.preprocess = preprocess,
-	.assemble = span8,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 1,
-	.ptrsize = 4,
-	.regsize = 4,
-};
diff --git a/src/liblink/obj9.c b/src/liblink/obj9.c
deleted file mode 100644
index 450ed00..0000000
--- a/src/liblink/obj9.c
+++ /dev/null
@@ -1,944 +0,0 @@
-// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.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.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "../cmd/9l/9.out.h"
-#include "../runtime/stack.h"
-#include "../runtime/funcdata.h"
-
-static void
-progedit(Link *ctxt, Prog *p)
-{
-	char literal[64];
-	LSym *s;
-
-	USED(ctxt);
-
-	p->from.class = 0;
-	p->to.class = 0;
-
-	// Rewrite BR/BL to symbol as TYPE_BRANCH.
-	switch(p->as) {
-	case ABR:
-	case ABL:
-	case ARETURN:
-	case ADUFFZERO:
-	case ADUFFCOPY:
-		if(p->to.sym != nil)
-			p->to.type = TYPE_BRANCH;
-		break;
-	}
-
-	// Rewrite float constants to values stored in memory.
-	switch(p->as) {
-	case AFMOVS:
-		if(p->from.type == TYPE_FCONST) {
-			uint32 i32;
-			float32 f32;
-			f32 = p->from.u.dval;
-			memmove(&i32, &f32, 4);
-			sprint(literal, "$f32.%08ux", i32);
-			s = linklookup(ctxt, literal, 0);
-			s->size = 4;
-			p->from.type = TYPE_MEM;
-			p->from.sym = s;
-			p->from.name = NAME_EXTERN;
-			p->from.offset = 0;
-		}
-		break;
-	case AFMOVD:
-		if(p->from.type == TYPE_FCONST) {
-			uint64 i64;
-			memmove(&i64, &p->from.u.dval, 8);
-			sprint(literal, "$f64.%016llux", i64);
-			s = linklookup(ctxt, literal, 0);
-			s->size = 8;
-			p->from.type = TYPE_MEM;
-			p->from.sym = s;
-			p->from.name = NAME_EXTERN;
-			p->from.offset = 0;
-		}
-		break;
-	case AMOVD:
-		// Put >32-bit constants in memory and load them
-		if(p->from.type == TYPE_CONST && p->from.name == NAME_NONE && p->from.reg == 0 && (int32)p->from.offset != p->from.offset) {
-			sprint(literal, "$i64.%016llux", (uvlong)p->from.offset);
-			s = linklookup(ctxt, literal, 0);
-			s->size = 8;
-			p->from.type = TYPE_MEM;
-			p->from.sym = s;
-			p->from.name = NAME_EXTERN;
-			p->from.offset = 0;
-		}
-	}
-
-	// Rewrite SUB constants into ADD.
-	switch(p->as) {
-	case ASUBC:
-		if(p->from.type == TYPE_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADDC;
-		}
-		break;
-
-	case ASUBCCC:
-		if(p->from.type == TYPE_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADDCCC;
-		}
-		break;
-
-	case ASUB:
-		if(p->from.type == TYPE_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADD;
-		}
-		break;
-	}
-}
-
-static Prog*	stacksplit(Link*, Prog*, int32, int);
-
-static void
-preprocess(Link *ctxt, LSym *cursym)
-{
-	Prog *p, *q, *p1, *p2, *q1;
-	int o, mov, aoffset;
-	vlong textstksiz;
-	int32 autosize;
-
-	if(ctxt->symmorestack[0] == nil) {
-		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
-		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
-		// TODO(minux): add morestack short-cuts with small fixed frame-size.
-	}
-
-	ctxt->cursym = cursym;
-
-	if(cursym->text == nil || cursym->text->link == nil)
-		return;				
-
-	p = cursym->text;
-	textstksiz = p->to.offset;
-	
-	cursym->args = p->to.u.argsize;
-	cursym->locals = textstksiz;
-
-	/*
-	 * find leaf subroutines
-	 * strip NOPs
-	 * expand RET
-	 * expand BECOME pseudo
-	 */
-
-	if(ctxt->debugvlog)
-		Bprint(ctxt->bso, "%5.2f noops\n", cputime());
-	Bflush(ctxt->bso);
-
-	q = nil;
-	for(p = cursym->text; p != nil; p = p->link) {
-		switch(p->as) {
-		/* too hard, just leave alone */
-		case ATEXT:
-			q = p;
-			p->mark |= LABEL|LEAF|SYNC;
-			if(p->link)
-				p->link->mark |= LABEL;
-			break;
-
-		case ANOR:
-			q = p;
-			if(p->to.type == TYPE_REG)
-				if(p->to.reg == REGZERO)
-					p->mark |= LABEL|SYNC;
-			break;
-
-		case ALWAR:
-		case ASTWCCC:
-		case AECIWX:
-		case AECOWX:
-		case AEIEIO:
-		case AICBI:
-		case AISYNC:
-		case ATLBIE:
-		case ATLBIEL:
-		case ASLBIA:
-		case ASLBIE:
-		case ASLBMFEE:
-		case ASLBMFEV:
-		case ASLBMTE:
-		case ADCBF:
-		case ADCBI:
-		case ADCBST:
-		case ADCBT:
-		case ADCBTST:
-		case ADCBZ:
-		case ASYNC:
-		case ATLBSYNC:
-		case APTESYNC:
-		case ATW:
-		case AWORD:
-		case ARFI:
-		case ARFCI:
-		case ARFID:
-		case AHRFID:
-			q = p;
-			p->mark |= LABEL|SYNC;
-			continue;
-
-		case AMOVW:
-		case AMOVWZ:
-		case AMOVD:
-			q = p;
-			if(p->from.reg >= REG_SPECIAL || p->to.reg >= REG_SPECIAL)
-				p->mark |= LABEL|SYNC;
-			continue;
-
-		case AFABS:
-		case AFABSCC:
-		case AFADD:
-		case AFADDCC:
-		case AFCTIW:
-		case AFCTIWCC:
-		case AFCTIWZ:
-		case AFCTIWZCC:
-		case AFDIV:
-		case AFDIVCC:
-		case AFMADD:
-		case AFMADDCC:
-		case AFMOVD:
-		case AFMOVDU:
-		/* case AFMOVDS: */
-		case AFMOVS:
-		case AFMOVSU:
-		/* case AFMOVSD: */
-		case AFMSUB:
-		case AFMSUBCC:
-		case AFMUL:
-		case AFMULCC:
-		case AFNABS:
-		case AFNABSCC:
-		case AFNEG:
-		case AFNEGCC:
-		case AFNMADD:
-		case AFNMADDCC:
-		case AFNMSUB:
-		case AFNMSUBCC:
-		case AFRSP:
-		case AFRSPCC:
-		case AFSUB:
-		case AFSUBCC:
-			q = p;
-			p->mark |= FLOAT;
-			continue;
-
-		case ABL:
-		case ABCL:
-		case ADUFFZERO:
-		case ADUFFCOPY:
-			cursym->text->mark &= ~LEAF;
-
-		case ABC:
-		case ABEQ:
-		case ABGE:
-		case ABGT:
-		case ABLE:
-		case ABLT:
-		case ABNE:
-		case ABR:
-		case ABVC:
-		case ABVS:
-			p->mark |= BRANCH;
-			q = p;
-			q1 = p->pcond;
-			if(q1 != nil) {
-				while(q1->as == ANOP) {
-					q1 = q1->link;
-					p->pcond = q1;
-				}
-				if(!(q1->mark & LEAF))
-					q1->mark |= LABEL;
-			} else
-				p->mark |= LABEL;
-			q1 = p->link;
-			if(q1 != nil)
-				q1->mark |= LABEL;
-			continue;
-
-		case AFCMPO:
-		case AFCMPU:
-			q = p;
-			p->mark |= FCMP|FLOAT;
-			continue;
-
-		case ARETURN:
-			q = p;
-			if(p->link != nil)
-				p->link->mark |= LABEL;
-			continue;
-
-		case ANOP:
-			q1 = p->link;
-			q->link = q1;		/* q is non-nop */
-			q1->mark |= p->mark;
-			continue;
-
-		default:
-			q = p;
-			continue;
-		}
-	}
-
-	autosize = 0;
-	for(p = cursym->text; p != nil; p = p->link) {
-		o = p->as;
-		switch(o) {
-		case ATEXT:
-			mov = AMOVD;
-			aoffset = 0;
-			autosize = textstksiz + 8;
-			if((p->mark & LEAF) && autosize <= 8)
-				autosize = 0;
-			else
-				if(autosize & 4)
-					autosize += 4;
-			p->to.offset = autosize-8;
-
-			if(!(p->from3.offset & NOSPLIT))
-				p = stacksplit(ctxt, p, autosize, !(cursym->text->from3.offset&NEEDCTXT)); // emit split check
-
-			q = p;
-			if(autosize) {
-				/* use MOVDU to adjust R1 when saving R31, if autosize is small */
-				if(!(cursym->text->mark & LEAF) && autosize >= -BIG && autosize <= BIG) {
-					mov = AMOVDU;
-					aoffset = -autosize;
-				} else {
-					q = appendp(ctxt, p);
-					q->as = AADD;
-					q->lineno = p->lineno;
-					q->from.type = TYPE_CONST;
-					q->from.offset = -autosize;
-					q->to.type = TYPE_REG;
-					q->to.reg = REGSP;
-					q->spadj = +autosize;
-				}
-			} else
-			if(!(cursym->text->mark & LEAF)) {
-				if(ctxt->debugvlog) {
-					Bprint(ctxt->bso, "save suppressed in: %s\n",
-						cursym->name);
-					Bflush(ctxt->bso);
-				}
-				cursym->text->mark |= LEAF;
-			}
-
-			if(cursym->text->mark & LEAF) {
-				cursym->leaf = 1;
-				break;
-			}
-
-			q = appendp(ctxt, q);
-			q->as = AMOVD;
-			q->lineno = p->lineno;
-			q->from.type = TYPE_REG;
-			q->from.reg = REG_LR;
-			q->to.type = TYPE_REG;
-			q->to.reg = REGTMP;
-
-			q = appendp(ctxt, q);
-			q->as = mov;
-			q->lineno = p->lineno;
-			q->from.type = TYPE_REG;
-			q->from.reg = REGTMP;
-			q->to.type = TYPE_MEM;
-			q->to.offset = aoffset;
-			q->to.reg = REGSP;
-			if(q->as == AMOVDU)
-				q->spadj = -aoffset;
-
-			if(cursym->text->from3.offset & WRAPPER) {
-				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
-				//
-				//	MOVD g_panic(g), R3
-				//	CMP R0, R3
-				//	BEQ end
-				//	MOVD panic_argp(R3), R4
-				//	ADD $(autosize+8), R1, R5
-				//	CMP R4, R5
-				//	BNE end
-				//	ADD $8, R1, R6
-				//	MOVD R6, panic_argp(R3)
-				// end:
-				//	NOP
-				//
-				// The NOP is needed to give the jumps somewhere to land.
-				// It is a liblink NOP, not a ppc64 NOP: it encodes to 0 instruction bytes.
-
-
-				q = appendp(ctxt, q);
-				q->as = AMOVD;
-				q->from.type = TYPE_MEM;
-				q->from.reg = REGG;
-				q->from.offset = 4*ctxt->arch->ptrsize; // G.panic
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R3;
-
-				q = appendp(ctxt, q);
-				q->as = ACMP;
-				q->from.type = TYPE_REG;
-				q->from.reg = REG_R0;
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R3;
-
-				q = appendp(ctxt, q);
-				q->as = ABEQ;
-				q->to.type = TYPE_BRANCH;
-				p1 = q;
-
-				q = appendp(ctxt, q);
-				q->as = AMOVD;
-				q->from.type = TYPE_MEM;
-				q->from.reg = REG_R3;
-				q->from.offset = 0; // Panic.argp
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R4;
-
-				q = appendp(ctxt, q);
-				q->as = AADD;
-				q->from.type = TYPE_CONST;
-				q->from.offset = autosize+8;
-				q->reg = REGSP;
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R5;
-
-				q = appendp(ctxt, q);
-				q->as = ACMP;
-				q->from.type = TYPE_REG;
-				q->from.reg = REG_R4;
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R5;
-
-				q = appendp(ctxt, q);
-				q->as = ABNE;
-				q->to.type = TYPE_BRANCH;
-				p2 = q;
-
-				q = appendp(ctxt, q);
-				q->as = AADD;
-				q->from.type = TYPE_CONST;
-				q->from.offset = 8;
-				q->reg = REGSP;
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_R6;
-
-				q = appendp(ctxt, q);
-				q->as = AMOVD;
-				q->from.type = TYPE_REG;
-				q->from.reg = REG_R6;
-				q->to.type = TYPE_MEM;
-				q->to.reg = REG_R3;
-				q->to.offset = 0; // Panic.argp
-
-				q = appendp(ctxt, q);
-				q->as = ANOP;
-				p1->pcond = q;
-				p2->pcond = q;
-			}
-
-			break;
-
-		case ARETURN:
-			if(p->from.type == TYPE_CONST) {
-				ctxt->diag("using BECOME (%P) is not supported!", p);
-				break;
-			}
-			if(p->to.sym) { // retjmp
-				p->as = ABR;
-				p->to.type = TYPE_BRANCH;
-				break;
-			}
-			if(cursym->text->mark & LEAF) {
-				if(!autosize) {
-					p->as = ABR;
-					p->from = zprog.from;
-					p->to.type = TYPE_REG;
-					p->to.reg = REG_LR;
-					p->mark |= BRANCH;
-					break;
-				}
-
-				p->as = AADD;
-				p->from.type = TYPE_CONST;
-				p->from.offset = autosize;
-				p->to.type = TYPE_REG;
-				p->to.reg = REGSP;
-				p->spadj = -autosize;
-
-				q = emallocz(sizeof(Prog));
-				q->as = ABR;
-				q->lineno = p->lineno;
-				q->to.type = TYPE_REG;
-				q->to.reg = REG_LR;
-				q->mark |= BRANCH;
-				q->spadj = +autosize;
-
-				q->link = p->link;
-				p->link = q;
-				break;
-			}
-
-			p->as = AMOVD;
-			p->from.type = TYPE_MEM;
-			p->from.offset = 0;
-			p->from.reg = REGSP;
-			p->to.type = TYPE_REG;
-			p->to.reg = REGTMP;
-
-			q = emallocz(sizeof(Prog));
-			q->as = AMOVD;
-			q->lineno = p->lineno;
-			q->from.type = TYPE_REG;
-			q->from.reg = REGTMP;
-			q->to.type = TYPE_REG;
-			q->to.reg = REG_LR;
-
-			q->link = p->link;
-			p->link = q;
-			p = q;
-
-			if(0) {
-				// Debug bad returns
-				q = emallocz(sizeof(Prog));
-				q->as = AMOVD;
-				q->lineno = p->lineno;
-				q->from.type = TYPE_MEM;
-				q->from.offset = 0;
-				q->from.reg = REGTMP;
-				q->to.type = TYPE_REG;
-				q->to.reg = REGTMP;
-
-				q->link = p->link;
-				p->link = q;
-				p = q;
-			}
-
-			if(autosize) {
-				q = emallocz(sizeof(Prog));
-				q->as = AADD;
-				q->lineno = p->lineno;
-				q->from.type = TYPE_CONST;
-				q->from.offset = autosize;
-				q->to.type = TYPE_REG;
-				q->to.reg = REGSP;
-				q->spadj = -autosize;
-
-				q->link = p->link;
-				p->link = q;
-			}
-
-			q1 = emallocz(sizeof(Prog));
-			q1->as = ABR;
-			q1->lineno = p->lineno;
-			q1->to.type = TYPE_REG;
-			q1->to.reg = REG_LR;
-			q1->mark |= BRANCH;
-			q1->spadj = +autosize;
-
-			q1->link = q->link;
-			q->link = q1;
-			break;
-
-		case AADD:
-			if(p->to.type == TYPE_REG && p->to.reg == REGSP && p->from.type == TYPE_CONST)
-				p->spadj = -p->from.offset;
-			break;
-		}
-	}
-
-/*
-// instruction scheduling
-	if(debug['Q'] == 0)
-		return;
-
-	curtext = nil;
-	q = nil;	// p - 1
-	q1 = firstp;	// top of block
-	o = 0;		// count of instructions
-	for(p = firstp; p != nil; p = p1) {
-		p1 = p->link;
-		o++;
-		if(p->mark & NOSCHED){
-			if(q1 != p){
-				sched(q1, q);
-			}
-			for(; p != nil; p = p->link){
-				if(!(p->mark & NOSCHED))
-					break;
-				q = p;
-			}
-			p1 = p;
-			q1 = p;
-			o = 0;
-			continue;
-		}
-		if(p->mark & (LABEL|SYNC)) {
-			if(q1 != p)
-				sched(q1, q);
-			q1 = p;
-			o = 1;
-		}
-		if(p->mark & (BRANCH|SYNC)) {
-			sched(q1, p);
-			q1 = p1;
-			o = 0;
-		}
-		if(o >= NSCHED) {
-			sched(q1, p);
-			q1 = p1;
-			o = 0;
-		}
-		q = p;
-	}
-*/
-}
-
-static Prog*
-stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
-{
-	Prog *q, *q1;
-
-	// MOVD	g_stackguard(g), R3
-	p = appendp(ctxt, p);
-	p->as = AMOVD;
-	p->from.type = TYPE_MEM;
-	p->from.reg = REGG;
-	p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
-	if(ctxt->cursym->cfunc)
-		p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_R3;
-
-	q = nil;
-	if(framesize <= StackSmall) {
-		// small stack: SP < stackguard
-		//	CMP	stackguard, SP
-		p = appendp(ctxt, p);
-		p->as = ACMPU;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R3;
-		p->to.type = TYPE_REG;
-		p->to.reg = REGSP;
-	} else if(framesize <= StackBig) {
-		// large stack: SP-framesize < stackguard-StackSmall
-		//	ADD $-framesize, SP, R4
-		//	CMP stackguard, R4
-		p = appendp(ctxt, p);
-		p->as = AADD;
-		p->from.type = TYPE_CONST;
-		p->from.offset = -framesize;
-		p->reg = REGSP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R4;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPU;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R3;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R4;
-	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	// stackguard is R3
-		//	CMP	R3, $StackPreempt
-		//	BEQ	label-of-call-to-morestack
-		//	ADD	$StackGuard, SP, R4
-		//	SUB	R3, R4
-		//	MOVD	$(framesize+(StackGuard-StackSmall)), R31
-		//	CMPU	R31, R4
-		p = appendp(ctxt, p);
-		p->as = ACMP;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R3;
-		p->to.type = TYPE_CONST;
-		p->to.offset = StackPreempt;
-
-		q = p = appendp(ctxt, p);
-		p->as = ABEQ;
-		p->to.type = TYPE_BRANCH;
-
-		p = appendp(ctxt, p);
-		p->as = AADD;
-		p->from.type = TYPE_CONST;
-		p->from.offset = StackGuard;
-		p->reg = REGSP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R4;
-
-		p = appendp(ctxt, p);
-		p->as = ASUB;
-		p->from.type = TYPE_REG;
-		p->from.reg = REG_R3;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R4;
-
-		p = appendp(ctxt, p);
-		p->as = AMOVD;
-		p->from.type = TYPE_CONST;
-		p->from.offset = framesize + StackGuard - StackSmall;
-		p->to.type = TYPE_REG;
-		p->to.reg = REGTMP;
-
-		p = appendp(ctxt, p);
-		p->as = ACMPU;
-		p->from.type = TYPE_REG;
-		p->from.reg = REGTMP;
-		p->to.type = TYPE_REG;
-		p->to.reg = REG_R4;
-	}
-
-	// q1: BLT	done
-	q1 = p = appendp(ctxt, p);
-	p->as = ABLT;
-	p->to.type = TYPE_BRANCH;
-
-	// MOVD	LR, R5
-	p = appendp(ctxt, p);
-	p->as = AMOVD;
-	p->from.type = TYPE_REG;
-	p->from.reg = REG_LR;
-	p->to.type = TYPE_REG;
-	p->to.reg = REG_R5;
-	if(q)
-		q->pcond = p;
-
-	// BL	runtime.morestack(SB)
-	p = appendp(ctxt, p);
-	p->as = ABL;
-	p->to.type = TYPE_BRANCH;
-	if(ctxt->cursym->cfunc)
-		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
-	else
-		p->to.sym = ctxt->symmorestack[noctxt];
-
-	// BR	start
-	p = appendp(ctxt, p);
-	p->as = ABR;
-	p->to.type = TYPE_BRANCH;
-	p->pcond = ctxt->cursym->text->link;
-
-	// placeholder for q1's jump target
-	p = appendp(ctxt, p);
-	p->as = ANOP; // zero-width place holder
-	q1->pcond = p;
-
-	return p;
-}
-
-static void xfol(Link*, Prog*, Prog**);
-
-static void
-follow(Link *ctxt, LSym *s)
-{
-	Prog *firstp, *lastp;
-
-	ctxt->cursym = s;
-
-	firstp = emallocz(sizeof(Prog));
-	lastp = firstp;
-	xfol(ctxt, s->text, &lastp);
-	lastp->link = nil;
-	s->text = firstp->link;
-}
-
-static int
-relinv(int a)
-{
-
-	switch(a) {
-	case ABEQ:	return ABNE;
-	case ABNE:	return ABEQ;
-
-	case ABGE:	return ABLT;
-	case ABLT:	return ABGE;
-
-	case ABGT:	return ABLE;
-	case ABLE:	return ABGT;
-
-	case ABVC:	return ABVS;
-	case ABVS:	return ABVC;
-	}
-	return 0;
-}
-
-static void
-xfol(Link *ctxt, Prog *p, Prog **last)
-{
-	Prog *q, *r;
-	int a, b, i;
-
-loop:
-	if(p == nil)
-		return;
-	a = p->as;
-	if(a == ABR) {
-		q = p->pcond;
-		if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
-			p->mark |= FOLL;
-			(*last)->link = p;
-			*last = p;
-			p = p->link;
-			xfol(ctxt, p, last);
-			p = q;
-			if(p && !(p->mark & FOLL))
-				goto loop;
-			return;
-		}
-		if(q != nil) {
-			p->mark |= FOLL;
-			p = q;
-			if(!(p->mark & FOLL))
-				goto loop;
-		}
-	}
-	if(p->mark & FOLL) {
-		for(i=0,q=p; i<4; i++,q=q->link) {
-			if(q == *last || (q->mark&NOSCHED))
-				break;
-			b = 0;		/* set */
-			a = q->as;
-			if(a == ANOP) {
-				i--;
-				continue;
-			}
-			if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
-				goto copy;
-			if(!q->pcond || (q->pcond->mark&FOLL))
-				continue;
-			b = relinv(a);
-			if(!b)
-				continue;
-		copy:
-			for(;;) {
-				r = emallocz(sizeof(Prog));
-				*r = *p;
-				if(!(r->mark&FOLL))
-					print("cant happen 1\n");
-				r->mark |= FOLL;
-				if(p != q) {
-					p = p->link;
-					(*last)->link = r;
-					*last = r;
-					continue;
-				}
-				(*last)->link = r;
-				*last = r;
-				if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
-					return;
-				r->as = b;
-				r->pcond = p->link;
-				r->link = p->pcond;
-				if(!(r->link->mark&FOLL))
-					xfol(ctxt, r->link, last);
-				if(!(r->pcond->mark&FOLL))
-					print("cant happen 2\n");
-				return;
-			}
-		}
-
-		a = ABR;
-		q = emallocz(sizeof(Prog));
-		q->as = a;
-		q->lineno = p->lineno;
-		q->to.type = TYPE_BRANCH;
-		q->to.offset = p->pc;
-		q->pcond = p;
-		p = q;
-	}
-	p->mark |= FOLL;
-	(*last)->link = p;
-	*last = p;
-	if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID){
-		if(p->mark & NOSCHED){
-			p = p->link;
-			goto loop;
-		}
-		return;
-	}
-	if(p->pcond != nil)
-	if(a != ABL && p->link != nil) {
-		xfol(ctxt, p->link, last);
-		p = p->pcond;
-		if(p == nil || (p->mark&FOLL))
-			return;
-		goto loop;
-	}
-	p = p->link;
-	goto loop;
-}
-
-LinkArch linkppc64 = {
-	.name = "ppc64",
-	.thechar = '9',
-	.endian = BigEndian,
-
-	.preprocess = preprocess,
-	.assemble = span9,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 4,
-	.ptrsize = 8,
-	.regsize = 8,
-};
-
-LinkArch linkppc64le = {
-	.name = "ppc64le",
-	.thechar = '9',
-	.endian = LittleEndian,
-
-	.preprocess = preprocess,
-	.assemble = span9,
-	.follow = follow,
-	.progedit = progedit,
-
-	.minlc = 4,
-	.ptrsize = 8,
-	.regsize = 8,
-};
diff --git a/src/liblink/objfile.c b/src/liblink/objfile.c
index 99f5e97..ab88c45 100644
--- a/src/liblink/objfile.c
+++ b/src/liblink/objfile.c
@@ -105,442 +105,14 @@
 #include "../cmd/ld/textflag.h"
 #include "../runtime/funcdata.h"
 
-static void writesym(Link*, Biobuf*, LSym*);
-static void wrint(Biobuf*, int64);
-static void wrstring(Biobuf*, char*);
-static void wrpath(Link *, Biobuf*, char*);
-static void wrdata(Biobuf*, void*, int);
-static void wrsym(Biobuf*, LSym*);
-static void wrpathsym(Link *ctxt, Biobuf *b, LSym *s);
-
 static void readsym(Link*, Biobuf*, char*, char*);
 static int64 rdint(Biobuf*);
 static char *rdstring(Biobuf*);
 static void rddata(Biobuf*, uchar**, int*);
 static LSym *rdsym(Link*, Biobuf*, char*);
 
-void	writeobjdirect(Link *ctxt, Biobuf *b);
-
-void	writeobjgo1(Link*, char*);
-void	writeobjgo2(Link*, char*, int64);
-
 extern char *outfile;
 
-void
-writeobj(Link *ctxt, Biobuf *b)
-{
-	vlong start;
-	char *env;
-
-	// If $GOOBJ > 0, invoke the Go version of the liblink
-	// output routines via a subprocess.
-	// If $GOOBJ == 1, copy that subprocess's output to
-	// the actual output file.
-	// If $GOOBJ >= 2, generate output using the usual C version
-	// but then check that the subprocess wrote the same bytes.
-	// $GOOBJ is a temporary setting for the transition to a
-	// Go liblink back end. Once the C liblink back ends are deleted,
-	// we will hard code the GOOBJ=1 behavior.
-	env = getenv("GOOBJ");
-	if(env == nil)
-		env = "0";
-	if(atoi(env) == 0) {
-		writeobjdirect(ctxt, b);
-		return;
-	}
-
-	Bflush(b);
-	start = Boffset(b);
-	writeobjgo1(ctxt, outfile);
-	if(atoi(env) > 1) {
-		writeobjdirect(ctxt, b);
-		Bflush(b);
-	}
-	writeobjgo2(ctxt, outfile, start);
-	Bseek(b, 0, 2);
-}
-
-// The Go and C compilers, and the assembler, call writeobj to write
-// out a Go object file.  The linker does not call this; the linker
-// does not write out object files.
-void
-writeobjdirect(Link *ctxt, Biobuf *b)
-{
-	int flag, found;
-	Hist *h;
-	LSym *s, *text, *etext, *curtext, *data, *edata;
-	Plist *pl;
-	Prog *p, *plink;
-	Auto *a;
-
-	// Build list of symbols, and assign instructions to lists.
-	// Ignore ctxt->plist boundaries. There are no guarantees there,
-	// and the C compilers and assemblers just use one big list.
-	text = nil;
-	curtext = nil;
-	data = nil;
-	etext = nil;
-	edata = nil;
-	for(pl = ctxt->plist; pl != nil; pl = pl->link) {
-		for(p = pl->firstpc; p != nil; p = plink) {
-			if(ctxt->debugasm && ctxt->debugvlog)
-				print("obj: %P\n", p);
-			plink = p->link;
-			p->link = nil;
-
-			if(p->as == AEND)
-				continue;
-
-			if(p->as == ATYPE) {
-				// Assume each TYPE instruction describes
-				// a different local variable or parameter,
-				// so no dedup.
-				// Using only the TYPE instructions means
-				// that we discard location information about local variables
-				// in C and assembly functions; that information is inferred
-				// from ordinary references, because there are no TYPE
-				// instructions there. Without the type information, gdb can't
-				// use the locations, so we don't bother to save them.
-				// If something else could use them, we could arrange to
-				// preserve them.
-				if(curtext == nil)
-					continue;
-				a = emallocz(sizeof *a);
-				a->asym = p->from.sym;
-				a->aoffset = p->from.offset;
-				a->name = p->from.name;
-				a->gotype = p->from.gotype;
-				a->link = curtext->autom;
-				curtext->autom = a;
-				continue;
-			}
-
-			if(p->as == AGLOBL) {
-				s = p->from.sym;
-				if(s->seenglobl++)
-					print("duplicate %P\n", p);
-				if(s->onlist)
-					sysfatal("symbol %s listed multiple times", s->name);
-				s->onlist = 1;
-				if(data == nil)
-					data = s;
-				else
-					edata->next = s;
-				s->next = nil;
-				s->size = p->to.offset;
-				if(s->type == 0 || s->type == SXREF)
-					s->type = SBSS;
-				flag = p->from3.offset;
-				if(flag & DUPOK)
-					s->dupok = 1;
-				if(flag & RODATA)
-					s->type = SRODATA;
-				else if(flag & NOPTR)
-					s->type = SNOPTRBSS;
-				edata = s;
-				continue;
-			}
-
-			if(p->as == ADATA) {
-				savedata(ctxt, p->from.sym, p, "<input>");
-				continue;
-			}
-
-			if(p->as == ATEXT) {
-				s = p->from.sym;
-				if(s == nil) {
-					// func _() { }
-					curtext = nil;
-					continue;
-				}
-				if(s->text != nil)
-					sysfatal("duplicate TEXT for %s", s->name);
-				if(s->onlist)
-					sysfatal("symbol %s listed multiple times", s->name);
-				s->onlist = 1;
-				if(text == nil)
-					text = s;
-				else
-					etext->next = s;
-				etext = s;
-				flag = p->from3.offset;
-				if(flag & DUPOK)
-					s->dupok = 1;
-				if(flag & NOSPLIT)
-					s->nosplit = 1;
-				s->next = nil;
-				s->type = STEXT;
-				s->text = p;
-				s->etext = p;
-				curtext = s;
-				continue;
-			}
-			
-			if(p->as == AFUNCDATA) {
-				// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
-				if(curtext == nil) // func _() {}
-					continue;
-				if(strcmp(p->to.sym->name, "go_args_stackmap") == 0) {
-					if(p->from.type != TYPE_CONST || p->from.offset != FUNCDATA_ArgsPointerMaps)
-						ctxt->diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps");
-					p->to.sym = linklookup(ctxt, smprint("%s.args_stackmap", curtext->name), curtext->version);
-				}
-			}
-			
-			if(curtext == nil)
-				continue;
-			s = curtext;
-			s->etext->link = p;
-			s->etext = p;
-		}
-	}
-	
-	// Add reference to Go arguments for C or assembly functions without them.
-	for(s = text; s != nil; s = s->next) {
-		if(strncmp(s->name, "\"\".", 3) != 0)
-			continue;
-		found = 0;
-		for(p = s->text; p != nil; p = p->link) {
-			if(p->as == AFUNCDATA && p->from.type == TYPE_CONST && p->from.offset == FUNCDATA_ArgsPointerMaps) {
-				found = 1;
-				break;
-			}
-		}
-		if(!found) {
-			p = appendp(ctxt, s->text);
-			p->as = AFUNCDATA;
-			p->from.type = TYPE_CONST;
-			p->from.offset = FUNCDATA_ArgsPointerMaps;
-			p->to.type = TYPE_MEM;
-			p->to.name = NAME_EXTERN;
-			p->to.sym = linklookup(ctxt, smprint("%s.args_stackmap", s->name), s->version);
-		}
-	}
-
-	// Turn functions into machine code images.
-	for(s = text; s != nil; s = s->next) {
-		mkfwd(s);
-		linkpatch(ctxt, s);
-		ctxt->arch->follow(ctxt, s);
-		ctxt->arch->preprocess(ctxt, s);
-		ctxt->arch->assemble(ctxt, s);
-		linkpcln(ctxt, s);
-	}
-
-	// Emit header.
-	Bputc(b, 0);
-	Bputc(b, 0);
-	Bprint(b, "go13ld");
-	Bputc(b, 1); // version
-
-	// Emit autolib.
-	for(h = ctxt->hist; h != nil; h = h->link)
-		if(h->offset < 0)
-			wrstring(b, h->name);
-	wrstring(b, "");
-
-	// Emit symbols.
-	for(s = text; s != nil; s = s->next)
-		writesym(ctxt, b, s);
-	for(s = data; s != nil; s = s->next)
-		writesym(ctxt, b, s);
-
-	// Emit footer.
-	Bputc(b, 0xff);
-	Bputc(b, 0xff);
-	Bprint(b, "go13ld");
-}
-
-static void
-writesym(Link *ctxt, Biobuf *b, LSym *s)
-{
-	Reloc *r;
-	int i, j, c, n;
-	Pcln *pc;
-	Prog *p;
-	Auto *a;
-	char *name;
-
-	if(ctxt->debugasm) {
-		Bprint(ctxt->bso, "%s ", s->name);
-		if(s->version)
-			Bprint(ctxt->bso, "v=%d ", s->version);
-		if(s->type)
-			Bprint(ctxt->bso, "t=%d ", s->type);
-		if(s->dupok)
-			Bprint(ctxt->bso, "dupok ");
-		if(s->cfunc)
-			Bprint(ctxt->bso, "cfunc ");
-		if(s->nosplit)
-			Bprint(ctxt->bso, "nosplit ");
-		Bprint(ctxt->bso, "size=%lld value=%lld", (vlong)s->size, (vlong)s->value);
-		if(s->type == STEXT) {
-			Bprint(ctxt->bso, " args=%#llux locals=%#llux", (uvlong)s->args, (uvlong)s->locals);
-			if(s->leaf)
-				Bprint(ctxt->bso, " leaf");
-		}
-		Bprint(ctxt->bso, "\n");
-		for(p=s->text; p != nil; p = p->link)
-			Bprint(ctxt->bso, "\t%#06ux %P\n", (int)p->pc, p);
-		for(i=0; i<s->np; ) {
-			Bprint(ctxt->bso, "\t%#06ux", i);
-			for(j=i; j<i+16 && j<s->np; j++)
-				Bprint(ctxt->bso, " %02ux", s->p[j]);
-			for(; j<i+16; j++)
-				Bprint(ctxt->bso, "   ");
-			Bprint(ctxt->bso, "  ");
-			for(j=i; j<i+16 && j<s->np; j++) {
-				c = s->p[j];
-				if(' ' <= c && c <= 0x7e)
-					Bprint(ctxt->bso, "%c", c);
-				else
-					Bprint(ctxt->bso, ".");
-			}
-			Bprint(ctxt->bso, "\n");
-			i += 16;
-		}
-		for(i=0; i<s->nr; i++) {
-			r = &s->r[i];
-			name = "";
-			if(r->sym != nil)
-				name = r->sym->name;
-			if(ctxt->arch->thechar == '5' || ctxt->arch->thechar == '9')
-				Bprint(ctxt->bso, "\trel %d+%d t=%d %s+%llux\n", (int)r->off, r->siz, r->type, name, (vlong)r->add);
-			else
-				Bprint(ctxt->bso, "\trel %d+%d t=%d %s+%lld\n", (int)r->off, r->siz, r->type, name, (vlong)r->add);
-		}
-	}
-
-	Bputc(b, 0xfe);
-	wrint(b, s->type);
-	wrstring(b, s->name);
-	wrint(b, s->version);
-	wrint(b, s->dupok);
-	wrint(b, s->size);
-	wrsym(b, s->gotype);
-	wrdata(b, s->p, s->np);
-
-	wrint(b, s->nr);
-	for(i=0; i<s->nr; i++) {
-		r = &s->r[i];
-		wrint(b, r->off);
-		wrint(b, r->siz);
-		wrint(b, r->type);
-		wrint(b, r->add);
-		wrint(b, r->xadd);
-		wrsym(b, r->sym);
-		wrsym(b, r->xsym);
-	}
-	
-	if(s->type == STEXT) {
-		wrint(b, s->args);
-		wrint(b, s->locals);
-		wrint(b, s->nosplit);
-		wrint(b, s->leaf | s->cfunc<<1);
-		n = 0;
-		for(a = s->autom; a != nil; a = a->link)
-			n++;
-		wrint(b, n);
-		for(a = s->autom; a != nil; a = a->link) {
-			wrsym(b, a->asym);
-			wrint(b, a->aoffset);
-			if(a->name == NAME_AUTO)
-				wrint(b, A_AUTO);
-			else if(a->name == NAME_PARAM)
-				wrint(b, A_PARAM);
-			else
-				sysfatal("%s: invalid local variable type %d", s->name, a->name);
-			wrsym(b, a->gotype);
-		}
-
-		pc = s->pcln;
-		wrdata(b, pc->pcsp.p, pc->pcsp.n);
-		wrdata(b, pc->pcfile.p, pc->pcfile.n);
-		wrdata(b, pc->pcline.p, pc->pcline.n);
-		wrint(b, pc->npcdata);
-		for(i=0; i<pc->npcdata; i++)
-			wrdata(b, pc->pcdata[i].p, pc->pcdata[i].n);
-		wrint(b, pc->nfuncdata);
-		for(i=0; i<pc->nfuncdata; i++)
-			wrsym(b, pc->funcdata[i]);
-		for(i=0; i<pc->nfuncdata; i++)
-			wrint(b, pc->funcdataoff[i]);
-		wrint(b, pc->nfile);
-		for(i=0; i<pc->nfile; i++)
-			wrpathsym(ctxt, b, pc->file[i]);
-	}
-}
-
-static void
-wrint(Biobuf *b, int64 sval)
-{
-	uint64 uv, v;
-	uchar buf[10], *p;
-
-	uv = ((uint64)sval<<1) ^ (uint64)(int64)(sval>>63);
-
-	p = buf;
-	for(v = uv; v >= 0x80; v >>= 7)
-		*p++ = v | 0x80;
-	*p++ = v;
-	
-	Bwrite(b, buf, p - buf);
-}
-
-static void
-wrstring(Biobuf *b, char *s)
-{
-	wrdata(b, s, strlen(s));
-}
-
-// wrpath writes a path just like a string, but on windows, it
-// translates '\\' to '/' in the process.
-static void
-wrpath(Link *ctxt, Biobuf *b, char *p)
-{
-	int i, n;
-	if (!ctxt->windows || strchr(p, '\\') == nil) {
-		wrstring(b, p);
-		return;
-	} else {
-		n = strlen(p);
-		wrint(b, n);
-		for (i = 0; i < n; i++)
-			Bputc(b, p[i] == '\\' ? '/' : p[i]);
-	}
-}
-
-static void
-wrdata(Biobuf *b, void *v, int n)
-{
-	wrint(b, n);
-	Bwrite(b, v, n);
-}
-
-static void
-wrpathsym(Link *ctxt, Biobuf *b, LSym *s)
-{
-	if(s == nil) {
-		wrint(b, 0);
-		wrint(b, 0);
-		return;
-	}
-	wrpath(ctxt, b, s->name);
-	wrint(b, s->version);
-}
-
-static void
-wrsym(Biobuf *b, LSym *s)
-{
-	if(s == nil) {
-		wrint(b, 0);
-		wrint(b, 0);
-		return;
-	}
-	wrstring(b, s->name);
-	wrint(b, s->version);
-}
-
 static char startmagic[] = "\x00\x00go13ld";
 static char endmagic[] = "\xff\xffgo13ld";
 
diff --git a/src/liblink/objfilego.c b/src/liblink/objfilego.c
deleted file mode 100644
index 4060193..0000000
--- a/src/liblink/objfilego.c
+++ /dev/null
@@ -1,340 +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.
-
-// Writing of internal program representation to a serialized form
-// so that the Go translation of these routines can do the actual
-// program layout.
-// The serialized form and this code support the piecewise transition
-// from C to Go and will be removed along with the rest of the C code
-// when it is no longer needed.
-// There has been no attempt to make it particularly efficient, nor will there be.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-
-/*c2go
-
-char *mktempdir(void);
-int runcmd(char**);
-void removeall(char*);
-*/
-
-static void printtype(Link*, Biobuf*, int);
-static void printsym(Link*, Biobuf*, LSym*);
-static void printprog(Link*, Biobuf*, Prog*);
-static void printaddr(Link*, Biobuf*, Addr*);
-static void printhist(Link*, Biobuf*, Hist*);
-static void printint(Link*, Biobuf*, int64);
-static void printstr(Link*, Biobuf*, char*);
-static void printptr(Link*, Biobuf*, void*);
-
-#undef waitpid
-
-enum
-{
-	TypeEnd = 0,
-	TypeCtxt,
-	TypePlist,
-	TypeSym,
-	TypeProg,
-	TypeAddr,
-	TypeHist,
-};
-
-void
-writeobjgo1(Link *ctxt, char *outfile)
-{
-	int i;
-	char *p;
-	Biobuf *bw;
-	Plist *pl;
-	
-	p = smprint("%s.goliblink.in", outfile);
-	bw = Bopen(p, OWRITE);
-	if(bw == nil)
-		sysfatal("writing liblinktest input: %r");
-
-	printtype(ctxt, bw, TypeCtxt);
-	printstr(ctxt, bw, ctxt->arch->name);
-	printint(ctxt, bw, ctxt->goarm);
-	printint(ctxt, bw, ctxt->debugasm);
-	printstr(ctxt, bw, ctxt->trimpath);
-	printptr(ctxt, bw, ctxt->plist);
-	printptr(ctxt, bw, ctxt->plast);
-	printptr(ctxt, bw, ctxt->hist);
-	printptr(ctxt, bw, ctxt->ehist);
-	for(i = 0; i < LINKHASH; i++) {
-		if(ctxt->hash[i] != nil) {
-			printint(ctxt, bw, i);
-			printptr(ctxt, bw, ctxt->hash[i]);
-		}
-	}
-	printint(ctxt, bw, -1);
-
-	printhist(ctxt, bw, ctxt->hist);
-	printhist(ctxt, bw, ctxt->ehist);
-
-	for(pl=ctxt->plist; pl != nil; pl = pl->link) {
-		printtype(ctxt, bw, TypePlist);
-		printptr(ctxt, bw, pl);
-		printint(ctxt, bw, pl->recur);
-		printptr(ctxt, bw, pl->name);
-		printptr(ctxt, bw, pl->firstpc);
-		printptr(ctxt, bw, pl->link);
-		printsym(ctxt, bw, pl->name);
-		printprog(ctxt, bw, pl->firstpc);
-	}
-	
-	for(i = 0; i < LINKHASH; i++)
-		printsym(ctxt, bw, ctxt->hash[i]);
-
-	printtype(ctxt, bw, TypeEnd);
-	Bterm(bw);
-}
-
-void
-writeobjgo2(Link *ctxt, char *outfile, int64 offset)
-{
-	char *p, *env, *prog, *cmd[10];
-	char offsetbuf[20];
-	
-	USED(ctxt);
-
-	env = getenv("GOOBJWRITER");
-	if(env != nil && env[0] != '\0')
-		prog = env;
-	else
-		prog = smprint("%s/pkg/tool/%s_%s/objwriter", getgoroot(), getgohostos(), getgohostarch());
-
-	p = smprint("%s.goliblink.in", outfile);
-	
-	snprint(offsetbuf, sizeof offsetbuf, "%lld", offset);
-	
-	cmd[0] = prog;
-	cmd[1] = p;
-	cmd[2] = outfile;
-	cmd[3] = offsetbuf;
-	cmd[4] = ctxt->arch->name;
-	cmd[5] = nil;
-	if(runcmd(cmd) < 0)
-		sysfatal("running %s: %r", prog);
-
-	env = getenv("GOOBJ");
-	if(env == nil || atoi(env) <= 2)
-		remove(p);
-}
-
-static void
-printtype(Link *ctxt, Biobuf *bw, int t)
-{
-	printint(ctxt, bw, t);
-}
-
-static void
-printint(Link *ctxt, Biobuf *bw, int64 v)
-{
-	uint64 u;
-	
-	USED(ctxt);
-
-	u = (uint64)(v<<1) ^ (uint64)(v>>63);
-	while(u >= 0x80) {
-		Bputc(bw, u&0x7F | 0x80);
-		u >>= 7;
-	}
-	Bputc(bw, u);
-}
-
-static void
-printstr(Link *ctxt, Biobuf *bw, char *s)
-{
-	if(s == nil)
-		s = "";
-	printint(ctxt, bw, strlen(s));
-	Bwrite(bw, s, strlen(s));
-}
-
-static void
-printptr(Link *ctxt, Biobuf *bw, void *v)
-{
-	printint(ctxt, bw, (int64)(uintptr)v);
-}
-
-static void
-printsym(Link *ctxt, Biobuf *bw, LSym *s)
-{
-	int i;
-	Reloc *r;
-
-	if(s == nil || s->printed)
-		return;
-	s->printed = 1;
-	printtype(ctxt, bw, TypeSym);
-	printptr(ctxt, bw, s);
-	printstr(ctxt, bw, s->name);
-	printstr(ctxt, bw, s->extname);
-	printint(ctxt, bw, s->type);
-	printint(ctxt, bw, s->version);
-	printint(ctxt, bw, s->dupok);
-	printint(ctxt, bw, s->external);
-	printint(ctxt, bw, s->nosplit);
-	printint(ctxt, bw, s->reachable);
-	printint(ctxt, bw, s->cgoexport);
-	printint(ctxt, bw, s->special);
-	printint(ctxt, bw, s->stkcheck);
-	printint(ctxt, bw, s->hide);
-	printint(ctxt, bw, s->leaf);
-	printint(ctxt, bw, s->fnptr);
-	printint(ctxt, bw, s->seenglobl);
-	printint(ctxt, bw, s->onlist);
-	printint(ctxt, bw, s->symid);
-	printint(ctxt, bw, s->dynid);
-	printint(ctxt, bw, s->sig);
-	printint(ctxt, bw, s->plt);
-	printint(ctxt, bw, s->got);
-	printint(ctxt, bw, s->align);
-	printint(ctxt, bw, s->elfsym);
-	printint(ctxt, bw, s->args);
-	printint(ctxt, bw, s->locals);
-	printint(ctxt, bw, s->value);
-	printint(ctxt, bw, s->size);
-	printptr(ctxt, bw, s->hash);
-	printptr(ctxt, bw, s->allsym);
-	printptr(ctxt, bw, s->next);
-	printptr(ctxt, bw, s->sub);
-	printptr(ctxt, bw, s->outer);
-	printptr(ctxt, bw, s->gotype);
-	printptr(ctxt, bw, s->reachparent);
-	printptr(ctxt, bw, s->queue);
-	printstr(ctxt, bw, s->file);
-	printstr(ctxt, bw, s->dynimplib);
-	printstr(ctxt, bw, s->dynimpvers);
-	printptr(ctxt, bw, s->text);
-	printptr(ctxt, bw, s->etext);
-	printint(ctxt, bw, s->np);
-	Bwrite(bw, s->p, s->np);
-	printint(ctxt, bw, s->nr);
-	for(i=0; i<s->nr; i++) {
-		r = s->r+i;
-		printint(ctxt, bw, r->off);
-		printint(ctxt, bw, r->siz);
-		printint(ctxt, bw, r->done);
-		printint(ctxt, bw, r->type);
-		printint(ctxt, bw, r->add);
-		printint(ctxt, bw, r->xadd);
-		printptr(ctxt, bw, r->sym);
-		printptr(ctxt, bw, r->xsym);
-	}
-	
-	printsym(ctxt, bw, s->hash);
-	printsym(ctxt, bw, s->allsym);
-	printsym(ctxt, bw, s->next);
-	printsym(ctxt, bw, s->sub);
-	printsym(ctxt, bw, s->outer);
-	printsym(ctxt, bw, s->gotype);
-	printsym(ctxt, bw, s->reachparent);
-	printsym(ctxt, bw, s->queue);
-	printprog(ctxt, bw, s->text);
-	printprog(ctxt, bw, s->etext);
-	for(i=0; i<s->nr; i++) {
-		r = s->r+i;
-		printsym(ctxt, bw, r->sym);
-		printsym(ctxt, bw, r->xsym);
-	}
-}
-
-static void
-printprog(Link *ctxt, Biobuf *bw, Prog *p0)
-{
-	Prog *p, *q;
-
-	for(p = p0; p != nil && !p->printed; p=p->link) {
-		p->printed = 1;
-	
-		printtype(ctxt, bw, TypeProg);
-		printptr(ctxt, bw, p);
-		printint(ctxt, bw, p->pc);
-		printint(ctxt, bw, p->lineno);
-		printptr(ctxt, bw, p->link);
-		printint(ctxt, bw, p->as);
-		printint(ctxt, bw, p->reg);
-		printint(ctxt, bw, p->scond);
-		printint(ctxt, bw, p->width);
-		printaddr(ctxt, bw, &p->from);
-		printaddr(ctxt, bw, &p->from3);
-		printaddr(ctxt, bw, &p->to);
-		printsym(ctxt, bw, p->from.sym);
-		printsym(ctxt, bw, p->from.gotype);
-		printsym(ctxt, bw, p->to.sym);
-		printsym(ctxt, bw, p->to.gotype);
-	}
-	
-	q = p;
-	for(p=p0; p!=q; p=p->link) {
-		if(p->from.type == TYPE_BRANCH)
-			printprog(ctxt, bw, p->from.u.branch);
-		if(p->to.type == TYPE_BRANCH)
-			printprog(ctxt, bw, p->to.u.branch);
-	}
-}
-
-static void
-printaddr(Link *ctxt, Biobuf *bw, Addr *a)
-{
-	static char zero[8];
-
-	printtype(ctxt, bw, TypeAddr);
-	printint(ctxt, bw, a->offset);
-	if(a->type == TYPE_FCONST) {
-		uint64 u;
-		float64 f;
-		f = a->u.dval;
-		memmove(&u, &f, 8);
-		printint(ctxt, bw, u);
-	} else
-		printint(ctxt, bw, 0);
-	if(a->type == TYPE_SCONST)
-		Bwrite(bw, a->u.sval, 8);
-	else
-		Bwrite(bw, zero, 8);
-	if(a->type == TYPE_BRANCH)
-		printptr(ctxt, bw, a->u.branch);
-	else	
-		printptr(ctxt, bw, nil);
-	printptr(ctxt, bw, a->sym);
-	printptr(ctxt, bw, a->gotype);
-	printint(ctxt, bw, a->type);
-	printint(ctxt, bw, a->index);
-	printint(ctxt, bw, a->scale);
-	printint(ctxt, bw, a->reg);
-	printint(ctxt, bw, a->name);
-	printint(ctxt, bw, a->class);
-	printint(ctxt, bw, a->etype);
-	if(a->type == TYPE_TEXTSIZE)
-		printint(ctxt, bw, a->u.argsize);
-	else
-		printint(ctxt, bw, 0);
-	printint(ctxt, bw, a->width);
-}
-
-static void
-printhist(Link *ctxt, Biobuf *bw, Hist *h)
-{
-	if(h == nil || h->printed)
-		return;
-	h->printed = 1;
-
-	printtype(ctxt, bw, TypeHist);
-	printptr(ctxt, bw, h);
-	printptr(ctxt, bw, h->link);
-	if(h->name == nil)
-		printstr(ctxt, bw, "<pop>");
-	else
-		printstr(ctxt, bw, h->name);
-	printint(ctxt, bw, h->line);
-	printint(ctxt, bw, h->offset);
-	printhist(ctxt, bw, h->link);
-}
diff --git a/src/liblink/pass.c b/src/liblink/pass.c
deleted file mode 100644
index db5c4eb..0000000
--- a/src/liblink/pass.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// Inferno utils/6l/pass.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/pass.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.
-
-// Code and data passes.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-
-Prog*
-brchain(Link *ctxt, Prog *p)
-{
-	int i;
-
-	USED(ctxt);
-	for(i=0; i<20; i++) {
-		if(p == nil || p->as != AJMP || p->pcond == nil)
-			return p;
-		p = p->pcond;
-	}
-	return nil;
-}
-
-Prog*
-brloop(Link *ctxt, Prog *p)
-{
-	int c;
-	Prog *q;
-
-	USED(ctxt);
-	c = 0;
-	for(q = p; q != nil; q = q->pcond) {
-		if(q->as != AJMP || q->pcond == nil)
-			break;
-		c++;
-		if(c >= 5000)
-			return nil;
-	}
-	return q;
-}
-
-static void
-checkaddr(Link *ctxt, Prog *p, Addr *a)
-{
-	// Check expected encoding, especially TYPE_CONST vs TYPE_ADDR.
-	switch(a->type) {
-	case TYPE_NONE:
-		return;
-
-	case TYPE_BRANCH:
-		if(a->reg != 0 || a->index != 0 || a->scale != 0 || a->name != 0)
-			break;
-		return;
-
-	case TYPE_TEXTSIZE:
-		if(a->reg != 0 || a->index != 0 || a->scale != 0 || a->name != 0)
-			break;
-		return;
-
-	case TYPE_MEM:
-		//if(a->u.bits != 0)
-		//	break;
-		return;
-
-	case TYPE_CONST:
-		// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
-		if(a->name != 0 || a->sym != 0 || a->reg != 0) {
-			ctxt->diag("argument %D is TYPE_CONST, should be TYPE_ADDR, in %P", a, p);
-			return;
-		}
-		if(a->reg != 0 || a->scale != 0 || a->name != 0 || a->sym != nil || a->u.bits != 0)
-			break;
-		return;
-
-	case TYPE_FCONST:
-	case TYPE_SCONST:
-		if(a->reg != 0 || a->index != 0 || a->scale != 0 || a->name != 0 || a->offset != 0 || a->sym != nil)
-			break;
-		return;
-
-	case TYPE_REG:
-		// TODO(rsc): After fixing PINSRQ, check a->offset != 0 too.
-		// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
-		if(a->scale != 0 || a->name != 0 || a->sym != nil)
-			break;
-		return;
-
-	case TYPE_ADDR:
-		if(a->u.bits != 0)
-			break;
-		if(a->reg == 0 && a->index == 0 && a->scale == 0 && a->name == 0 && a->sym == nil)
-			ctxt->diag("argument %D is TYPE_ADDR, should be TYPE_CONST, in %P", a, p);
-		return;
-
-	case TYPE_SHIFT:
-		if(a->index != 0 || a->scale != 0 || a->name != 0 || a->sym != nil || a->u.bits != 0)
-			break;
-		return;
-
-	case TYPE_REGREG:
-		if(a->index != 0 || a->scale != 0 || a->name != 0 || a->sym != nil || a->u.bits != 0)
-			break;
-		return;
-
-	case TYPE_REGREG2:
-		return;
-
-	case TYPE_INDIR:
-		// Expect sym and name to be set, nothing else.
-		// Technically more is allowed, but this is only used for *name(SB).
-		if(a->reg != 0 || a->index != 0 || a->scale != 0 || a->name == 0 || a->offset != 0 || a->sym == nil || a->u.bits != 0)
-			break;
-		return;
-	}
-
-	ctxt->diag("invalid encoding for argument %D in %P", a, p);
-}
-
-void
-linkpatch(Link *ctxt, LSym *sym)
-{
-	int32 c;
-	char *name;
-	Prog *p, *q;
-
-	ctxt->cursym = sym;
-	
-	for(p = sym->text; p != nil; p = p->link) {
-		checkaddr(ctxt, p, &p->from);
-		checkaddr(ctxt, p, &p->from3);
-		checkaddr(ctxt, p, &p->to);
-
-		if(ctxt->arch->progedit)
-			ctxt->arch->progedit(ctxt, p);
-		if(p->to.type != TYPE_BRANCH)
-			continue;
-		if(p->to.u.branch != nil) {
-			// TODO: Remove to.u.branch in favor of p->pcond.
-			p->pcond = p->to.u.branch;
-			continue;
-		}
-		if(p->to.sym != nil)
-			continue;
-		c = p->to.offset;
-		for(q = sym->text; q != nil;) {
-			if(c == q->pc)
-				break;
-			if(q->forwd != nil && c >= q->forwd->pc)
-				q = q->forwd;
-			else
-				q = q->link;
-		}
-		if(q == nil) {
-			name = "<nil>";
-			if(p->to.sym)
-				name = p->to.sym->name;
-			ctxt->diag("branch out of range (%#ux)\n%P [%s]", c, p, name);
-			p->to.type = TYPE_NONE;
-		}
-		p->to.u.branch = q;
-		p->pcond = q;
-	}
-	
-	for(p = sym->text; p != nil; p = p->link) {
-		p->mark = 0;	/* initialization for follow */
-		if(p->pcond != nil) {
-			p->pcond = brloop(ctxt, p->pcond);
-			if(p->pcond != nil)
-			if(p->to.type == TYPE_BRANCH)
-				p->to.offset = p->pcond->pc;
-		}
-	}
-}
diff --git a/src/liblink/pcln.c b/src/liblink/pcln.c
index 93e4127..cdc11b8 100644
--- a/src/liblink/pcln.c
+++ b/src/liblink/pcln.c
@@ -7,31 +7,6 @@
 #include <bio.h>
 #include <link.h>
 
-static void
-addvarint(Link *ctxt, Pcdata *d, uint32 val)
-{
-	int32 n;
-	uint32 v;
-	uchar *p;
-
-	USED(ctxt);
-
-	n = 0;
-	for(v = val; v >= 0x80; v >>= 7)
-		n++;
-	n++;
-
-	if(d->n + n > d->m) {
-		d->m = (d->n + n)*2;
-		d->p = erealloc(d->p, d->m);
-	}
-
-	p = d->p + d->n;
-	for(v = val; v >= 0x80; v >>= 7)
-		*p++ = v | 0x80;
-	*p = v;
-	d->n += n;
-}
 
 // funcpctab writes to dst a pc-value table mapping the code in func to the values
 // returned by valfunc parameterized by arg. The invocation of valfunc to update the
@@ -43,263 +18,23 @@
 //
 // where func is the function, val is the current value, p is the instruction being
 // considered, and arg can be used to further parameterize valfunc.
-static void
-funcpctab(Link *ctxt, Pcdata *dst, LSym *func, char *desc, int32 (*valfunc)(Link*, LSym*, int32, Prog*, int32, void*), void* arg)
-{
-	int dbg, i;
-	int32 oldval, val, started;
-	uint32 delta;
-	vlong pc;
-	Prog *p;
-
-	// To debug a specific function, uncomment second line and change name.
-	dbg = 0;
-	//dbg = strcmp(func->name, "main.main") == 0;
-	//dbg = strcmp(desc, "pctofile") == 0;
-
-	ctxt->debugpcln += dbg;
-
-	dst->n = 0;
-
-	if(ctxt->debugpcln)
-		Bprint(ctxt->bso, "funcpctab %s [valfunc=%s]\n", func->name, desc);
-
-	val = -1;
-	oldval = val;
-	if(func->text == nil) {
-		ctxt->debugpcln -= dbg;
-		return;
-	}
-
-	pc = func->text->pc;
-	
-	if(ctxt->debugpcln)
-		Bprint(ctxt->bso, "%6llux %6d %P\n", pc, val, func->text);
-
-	started = 0;
-	for(p=func->text; p != nil; p = p->link) {
-		// Update val. If it's not changing, keep going.
-		val = valfunc(ctxt, func, val, p, 0, arg);
-		if(val == oldval && started) {
-			val = valfunc(ctxt, func, val, p, 1, arg);
-			if(ctxt->debugpcln)
-				Bprint(ctxt->bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
-			continue;
-		}
-
-		// If the pc of the next instruction is the same as the
-		// pc of this instruction, this instruction is not a real
-		// instruction. Keep going, so that we only emit a delta
-		// for a true instruction boundary in the program.
-		if(p->link && p->link->pc == p->pc) {
-			val = valfunc(ctxt, func, val, p, 1, arg);
-			if(ctxt->debugpcln)
-				Bprint(ctxt->bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
-			continue;
-		}
-
-		// The table is a sequence of (value, pc) pairs, where each
-		// pair states that the given value is in effect from the current position
-		// up to the given pc, which becomes the new current position.
-		// To generate the table as we scan over the program instructions,
-		// we emit a "(value" when pc == func->value, and then
-		// each time we observe a change in value we emit ", pc) (value".
-		// When the scan is over, we emit the closing ", pc)".
-		//
-		// The table is delta-encoded. The value deltas are signed and
-		// transmitted in zig-zag form, where a complement bit is placed in bit 0,
-		// and the pc deltas are unsigned. Both kinds of deltas are sent
-		// as variable-length little-endian base-128 integers,
-		// where the 0x80 bit indicates that the integer continues.
-
-		if(ctxt->debugpcln)
-			Bprint(ctxt->bso, "%6llux %6d %P\n", (vlong)p->pc, val, p);
-
-		if(started) {
-			addvarint(ctxt, dst, (p->pc - pc) / ctxt->arch->minlc);
-			pc = p->pc;
-		}
-		delta = val - oldval;
-		if(delta>>31)
-			delta = 1 | ~(delta<<1);
-		else
-			delta <<= 1;
-		addvarint(ctxt, dst, delta);
-		oldval = val;
-		started = 1;
-		val = valfunc(ctxt, func, val, p, 1, arg);
-	}
-
-	if(started) {
-		if(ctxt->debugpcln)
-			Bprint(ctxt->bso, "%6llux done\n", (vlong)func->text->pc+func->size);
-		addvarint(ctxt, dst, (func->value+func->size - pc) / ctxt->arch->minlc);
-		addvarint(ctxt, dst, 0); // terminator
-	}
-
-	if(ctxt->debugpcln) {
-		Bprint(ctxt->bso, "wrote %d bytes to %p\n", dst->n, dst);
-		for(i=0; i<dst->n; i++)
-			Bprint(ctxt->bso, " %02ux", dst->p[i]);
-		Bprint(ctxt->bso, "\n");
-	}
-
-	ctxt->debugpcln -= dbg;
-}
 
 // pctofileline computes either the file number (arg == 0)
 // or the line number (arg == 1) to use at p.
 // Because p->lineno applies to p, phase == 0 (before p)
 // takes care of the update.
-static int32
-pctofileline(Link *ctxt, LSym *sym, int32 oldval, Prog *p, int32 phase, void *arg)
-{
-	int32 i, l;
-	LSym *f;
-	Pcln *pcln;
-
-	USED(sym);
-
-	if(p->as == ATEXT || p->as == ANOP || p->as == AUSEFIELD || p->lineno == 0 || phase == 1)
-		return oldval;
-	linkgetline(ctxt, p->lineno, &f, &l);
-	if(f == nil) {
-	//	print("getline failed for %s %P\n", ctxt->cursym->name, p);
-		return oldval;
-	}
-	if(arg == nil)
-		return l;
-	pcln = arg;
-	
-	if(f == pcln->lastfile)
-		return pcln->lastindex;
-
-	for(i=0; i<pcln->nfile; i++) {
-		if(pcln->file[i] == f) {
-			pcln->lastfile = f;
-			pcln->lastindex = i;
-			return i;
-		}
-	}
-
-	if(pcln->nfile >= pcln->mfile) {
-		pcln->mfile = (pcln->nfile+1)*2;
-		pcln->file = erealloc(pcln->file, pcln->mfile*sizeof pcln->file[0]);
-	}
-	pcln->file[pcln->nfile++] = f;
-	pcln->lastfile = f;
-	pcln->lastindex = i;
-	return i;
-}
 
 // pctospadj computes the sp adjustment in effect.
 // It is oldval plus any adjustment made by p itself.
 // The adjustment by p takes effect only after p, so we
 // apply the change during phase == 1.
-static int32
-pctospadj(Link *ctxt, LSym *sym, int32 oldval, Prog *p, int32 phase, void *arg)
-{
-	USED(arg);
-	USED(sym);
-
-	if(oldval == -1) // starting
-		oldval = 0;
-	if(phase == 0)
-		return oldval;
-	if(oldval + p->spadj < -10000 || oldval + p->spadj > 1100000000) {
-		ctxt->diag("overflow in spadj: %d + %d = %d", oldval, p->spadj, oldval + p->spadj);
-		sysfatal("bad code");
-	}
-	return oldval + p->spadj;
-}
 
 // pctopcdata computes the pcdata value in effect at p.
 // A PCDATA instruction sets the value in effect at future
 // non-PCDATA instructions.
 // Since PCDATA instructions have no width in the final code,
 // it does not matter which phase we use for the update.
-static int32
-pctopcdata(Link *ctxt, LSym *sym, int32 oldval, Prog *p, int32 phase, void *arg)
-{
-	USED(sym);
 
-	if(phase == 0 || p->as != APCDATA || p->from.offset != (uintptr)arg)
-		return oldval;
-	if((int32)p->to.offset != p->to.offset) {
-		ctxt->diag("overflow in PCDATA instruction: %P", p);
-		sysfatal("bad code");
-	}
-	return p->to.offset;
-}
-
-void
-linkpcln(Link *ctxt, LSym *cursym)
-{
-	Prog *p;
-	Pcln *pcln;
-	int i, npcdata, nfuncdata, n;
-	uint32 *havepc, *havefunc;
-
-	ctxt->cursym = cursym;
-
-	pcln = emallocz(sizeof *pcln);
-	cursym->pcln = pcln;
-
-	npcdata = 0;
-	nfuncdata = 0;
-	for(p = cursym->text; p != nil; p = p->link) {
-		if(p->as == APCDATA && p->from.offset >= npcdata)
-			npcdata = p->from.offset+1;
-		if(p->as == AFUNCDATA && p->from.offset >= nfuncdata)
-			nfuncdata = p->from.offset+1;
-	}
-
-	pcln->pcdata = emallocz(npcdata*sizeof pcln->pcdata[0]);
-	pcln->npcdata = npcdata;
-	pcln->funcdata = emallocz(nfuncdata*sizeof pcln->funcdata[0]);
-	pcln->funcdataoff = emallocz(nfuncdata*sizeof pcln->funcdataoff[0]);
-	pcln->nfuncdata = nfuncdata;
-
-	funcpctab(ctxt, &pcln->pcsp, cursym, "pctospadj", pctospadj, nil);
-	funcpctab(ctxt, &pcln->pcfile, cursym, "pctofile", pctofileline, pcln);
-	funcpctab(ctxt, &pcln->pcline, cursym, "pctoline", pctofileline, nil);
-	
-	// tabulate which pc and func data we have.
-	n = ((npcdata+31)/32 + (nfuncdata+31)/32)*4;
-	havepc = emallocz(n);
-	havefunc = havepc + (npcdata+31)/32;
-	for(p = cursym->text; p != nil; p = p->link) {
-		if(p->as == AFUNCDATA) {
-			if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
-				ctxt->diag("multiple definitions for FUNCDATA $%d", p->from.offset);
-			havefunc[p->from.offset/32] |= 1<<(p->from.offset%32);
-		}
-		if(p->as == APCDATA)
-			havepc[p->from.offset/32] |= 1<<(p->from.offset%32);
-	}
-	// pcdata.
-	for(i=0; i<npcdata; i++) {
-		if(((havepc[i/32]>>(i%32))&1) == 0) 
-			continue;
-		funcpctab(ctxt, &pcln->pcdata[i], cursym, "pctopcdata", pctopcdata, (void*)(uintptr)i);
-	}
-	free(havepc);
-	
-	// funcdata
-	if(nfuncdata > 0) {
-		for(p = cursym->text; p != nil; p = p->link) {
-			if(p->as == AFUNCDATA) {
-				i = p->from.offset;
-				pcln->funcdataoff[i] = p->to.offset;
-				if(p->to.type != TYPE_CONST) {
-					// TODO: Dedup.
-					//funcdata_bytes += p->to.sym->size;
-					pcln->funcdata[i] = p->to.sym;
-				}
-			}
-		}
-	}
-}
 
 // iteration over encoded pcdata tables.
 
diff --git a/src/liblink/sym.c b/src/liblink/sym.c
index cae7e4a..9ee1797 100644
--- a/src/liblink/sym.c
+++ b/src/liblink/sym.c
@@ -90,16 +90,12 @@
 	char *p;
 	char buf[1024];
 
-	linksetexp();
 	nuxiinit(arch);
 	
 	ctxt = emallocz(sizeof *ctxt);
 	ctxt->arch = arch;
 	ctxt->version = HistVersion;
 	ctxt->goroot = getgoroot();
-	ctxt->goroot_final = getenv("GOROOT_FINAL");
-	if(ctxt->goroot_final != nil && ctxt->goroot_final[0] == '\0')
-		ctxt->goroot_final = nil;
 
 	p = getgoarch();
 	if(strcmp(p, arch->name) != 0)
@@ -116,7 +112,6 @@
 			if(*p == '\\')
 				*p = '/';
 	}
-	ctxt->pathname = strdup(buf);
 	
 	ctxt->headtype = headtype(getgoos());
 	if(ctxt->headtype < 0)
@@ -258,14 +253,3 @@
 	return _lookup(ctxt, name, v, 0);
 }
 
-int
-linksymfmt(Fmt *f)
-{
-	LSym *s;
-	
-	s = va_arg(f->args, LSym*);
-	if(s == nil)
-		return fmtstrcpy(f, "<nil>");
-	
-	return fmtstrcpy(f, s->name);
-}