]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: delete unused code
authorRuss Cox <rsc@golang.org>
Wed, 25 Feb 2015 02:40:57 +0000 (21:40 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 26 Feb 2015 19:44:08 +0000 (19:44 +0000)
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>
43 files changed:
include/link.h
src/cmd/5l/5.out.h [deleted file]
src/cmd/5l/l.h
src/cmd/5l/list.c [deleted file]
src/cmd/5l/obj.c
src/cmd/6l/6.out.h [deleted file]
src/cmd/6l/l.h
src/cmd/6l/list.c [deleted file]
src/cmd/6l/obj.c
src/cmd/8l/8.out.h [deleted file]
src/cmd/8l/l.h
src/cmd/8l/list.c [deleted file]
src/cmd/8l/obj.c
src/cmd/9l/9.out.h [deleted file]
src/cmd/9l/l.h
src/cmd/9l/list.c [deleted file]
src/cmd/9l/obj.c
src/cmd/dist/build.go
src/cmd/dist/buildgc.go [deleted file]
src/cmd/ld/lib.h
src/cmd/ld/pobj.c
src/liblink/arch.c [new file with mode: 0644]
src/liblink/asm5.c [deleted file]
src/liblink/asm6.c [deleted file]
src/liblink/asm8.c [deleted file]
src/liblink/asm9.c [deleted file]
src/liblink/data.c
src/liblink/go.c
src/liblink/ld.c
src/liblink/list5.c [deleted file]
src/liblink/list6.c [deleted file]
src/liblink/list8.c [deleted file]
src/liblink/list9.c [deleted file]
src/liblink/obj.c [deleted file]
src/liblink/obj5.c [deleted file]
src/liblink/obj6.c [deleted file]
src/liblink/obj8.c [deleted file]
src/liblink/obj9.c [deleted file]
src/liblink/objfile.c
src/liblink/objfilego.c [deleted file]
src/liblink/pass.c [deleted file]
src/liblink/pcln.c
src/liblink/sym.c

index 7fa136b0355ff2aeae0ee341d86179c391ffb35c..c511a95cf1a49ab5e7d2793db8417068ff0beb59 100644 (file)
 // 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  Pcln    Pcln;
 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 @@ struct      Reloc
        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 @@ struct      LSym
        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 @@ struct       LSym
        
        // STEXT
        Auto*   autom;
-       Prog*   text;
-       Prog*   etext;
        Pcln*   pcln;
 
        // SDATA, SBSS
@@ -454,23 +219,6 @@ enum
        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 @@ struct    Link
        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 @@ struct    Link
        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 @@ struct LinkArch
        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   inuxi2[2];
 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     adduint32(Link *ctxt, LSym *s, uint32 v);
 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        linkamd64p32;
 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 (file)
index a266a6b..0000000
+++ /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[]; */
index b32b89bb066e71b15e4a7391ba35b9310711fc23..0258d5a7765e9dd59834459033b18172d2d2ab37 100644 (file)
@@ -57,7 +57,6 @@ vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
 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 (file)
index d4cc8ac..0000000
+++ /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();
-}
index a7bd0f45ea523bc358c379f98eef7d12a9c90ef5..887cc5aef4e9aa84a1a7744937902562db2a6469 100644 (file)
@@ -70,7 +70,6 @@ linkarchinit(void)
        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 (file)
index e25c6ef..0000000
+++ /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"
index acc97d93d49c4148111944eaf86d19aa6d843f6a..b314e258362a76d59dd7543ff9af75489ed9ff37 100644 (file)
@@ -58,7 +58,6 @@ vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
 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 (file)
index 6c4ea79..0000000
+++ /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();
-}
index 0a2b2cb59e67d018bb1d79ca4106301451b402e9..ebd4bae89463bc726eba77ddec74639abcf3c5fb 100644 (file)
@@ -72,7 +72,6 @@ linkarchinit(void)
        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 (file)
index 273a8ad..0000000
+++ /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"
index e844bc4180ca26efc2a468d09c94a911ee70d26f..77c06b3656509b4d694565d60c2d88ee1e156394 100644 (file)
@@ -57,7 +57,6 @@ vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
 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 (file)
index 4cd8f08..0000000
+++ /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();
-}
index 41900d65431e9bfa89f8f5c0277f5de2e4ba7733..767db331da011fa8f59f18d13a83f52ce80c46d0 100644 (file)
@@ -70,7 +70,6 @@ linkarchinit(void)
        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 (file)
index 6e95698..0000000
+++ /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"
index a634cf80b4efb2aa502ec1ca9a8a8f528dab6b2d..5c048d2570af1b89d6a3068c9d88fa0d0df40bf4 100644 (file)
@@ -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 @@ vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
 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 (file)
index af8dc15..0000000
+++ /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();
-}
index 17dd5caacd94a3e573ac830c9c199a01416ca071..5449319f388e16aa6dfc0777bd292c2395739b47 100644 (file)
@@ -71,7 +71,6 @@ linkarchinit(void)
        thearch.elfreloc1 = elfreloc1;
        thearch.elfsetupplt = elfsetupplt;
        thearch.gentext = gentext;
-       thearch.listinit = listinit;
        thearch.machoreloc1 = machoreloc1;
        if(thelinkarch == &linkppc64le) {
                thearch.lput = lputl;
index a9b4988a38b0f710cb01bf33dec4a1543a7986f6..00d289cf29d95e18e9f527fd55a542cdce1067cd 100644 (file)
@@ -475,7 +475,6 @@ var proto_gccargs = []string{
        "-Wno-switch",
        "-Wno-comment",
        "-Wno-missing-field-initializers",
-       "-Werror",
        "-fno-common",
        "-ggdb",
        "-pipe",
@@ -531,10 +530,6 @@ var deptab = []struct {
                "$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 @@ var gentab = []struct {
        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 (file)
index b59aa5b..0000000
+++ /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)
-}
index 4990a805351e6d4bbcebee146d8147cba96d5875..6a36c9ac95755a604e4ee2ba89daadeec5326bec 100644 (file)
@@ -60,7 +60,6 @@ struct Arch {
        int     (*elfreloc1)(Reloc*, vlong);
        void    (*elfsetupplt)(void);
        void    (*gentext)(void);
-       void    (*listinit)(void);
        int     (*machoreloc1)(Reloc*, vlong);
        
        void    (*lput)(uint32);
index 0a48eb3a76eb1a9c32be8b3266540cb6079249f2..1e9a12747ae3c9c661a4e3c2ab9be8301d13abdf 100644 (file)
@@ -57,7 +57,6 @@ ldmain(int argc, char **argv)
        ctxt->bso = &bso;
 
        Binit(&bso, 1, OWRITE);
-       thearch.listinit();
        memset(debug, 0, sizeof(debug));
        nerrors = 0;
        outfile = nil;
@@ -128,12 +127,6 @@ ldmain(int argc, char **argv)
        
        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 @@ ldmain(int argc, char **argv)
                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 @@ ldmain(int argc, char **argv)
        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 (file)
index 0000000..2e425a6
--- /dev/null
@@ -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 (file)
index 398b784..0000000
+++ /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 (file)
index 8119f74..0000000
+++ /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 (file)
index ed1e7bc..0000000
+++ /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 (file)
index 742d204..0000000
+++ /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;
-}
-
index e9dbc966b9919171dab56411dcb2682c06841435..06fe7e047194e844a61e247f8ce4904007fde9fd 100644 (file)
 #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 @@ symgrow(Link *ctxt, LSym *s, vlong lsiz)
        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 @@ setuint8(Link *ctxt, LSym *s, vlong r, uint8 v)
        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 @@ setuint32(Link *ctxt, LSym *s, vlong r, uint32 v)
        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)
index 08ce82b30cc78fd05c97db2dc67e6c97766e1494..6dae3f438c20610854bc94edbddee33f7cdbaa44 100644 (file)
@@ -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 @@ erealloc(void *p, long n)
        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;
-}
 
index e055829142b6b439a66a61a60852f513081d9b53..5dfb4efc214a4df2458f528e4c4a8910f837eda4 100644 (file)
@@ -176,66 +176,8 @@ uchar      inuxi2[2];
 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 (file)
index 3ea411d..0000000
+++ /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 (file)
index b324ec8..0000000
+++ /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 (file)
index 07c1d7c..0000000
+++ /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 (file)
index ac37bb5..0000000
+++ /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 (file)
index b8083b0..0000000
+++ /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 (file)
index abddbc3..0000000
+++ /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 (file)
index 546c89d..0000000
+++ /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 (file)
index eb8e318..0000000
+++ /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 (file)
index 450ed00..0000000
+++ /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,
-};
index 99f5e97607b4757629b0518a17a18e0ad09e7596..ab88c45550f2267ea63fbdac2c822b4f16ea9c91 100644 (file)
 #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 (file)
index 4060193..0000000
+++ /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 (file)
index db5c4eb..0000000
+++ /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;
-               }
-       }
-}
index 93e4127a1e5f21929cfec3d3d7a0b744fc20d348..cdc11b85db7119cc51cb92da780a7375aa3ae595 100644 (file)
@@ -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 @@ addvarint(Link *ctxt, Pcdata *d, uint32 val)
 //
 // 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.
 
index cae7e4aafe71343af954adddcfc45ab51fc40d90..9ee179717a781c64ba0cd6f03b14afa26c3d1d5f 100644 (file)
@@ -90,16 +90,12 @@ linknew(LinkArch *arch)
        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 @@ linknew(LinkArch *arch)
                        if(*p == '\\')
                                *p = '/';
        }
-       ctxt->pathname = strdup(buf);
        
        ctxt->headtype = headtype(getgoos());
        if(ctxt->headtype < 0)
@@ -258,14 +253,3 @@ linkrlookup(Link *ctxt, char *name, int v)
        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);
-}